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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"
#include "unointerfacetouniqueidentifiermapper.hxx"
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/drawing/CircleKind.hpp>
#include <com/sun/star/drawing/ConnectorType.hpp>
#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
#include <com/sun/star/document/XEventsSupplier.hpp>
#include <com/sun/star/drawing/HomogenMatrix3.hpp>
#include <com/sun/star/media/ZoomLevel.hpp>
#include "anim.hxx"
#include <xmloff/shapeexport.hxx>
#include "sdpropls.hxx"
#include <tools/debug.hxx>
#include <tools/urlobj.hxx>
#include <rtl/ustrbuf.hxx>
#include <xmloff/xmlexp.hxx>
#include <xmloff/xmluconv.hxx>
#include "XMLImageMapExport.hxx"
#include "xexptran.hxx"
#include <tools/gen.hxx>		// FRound
#include <xmloff/xmltoken.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/tuple/b2dtuple.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>

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

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


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

void XMLShapeExport::ImpExportNewTrans(const uno::Reference< beans::XPropertySet >& xPropSet,
	sal_Int32 nFeatures, awt::Point* pRefPoint)
{
	// get matrix
	::basegfx::B2DHomMatrix aMatrix;
	ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);

	// decompose and correct abour pRefPoint
	::basegfx::B2DTuple aTRScale;
	double fTRShear(0.0);
	double fTRRotate(0.0);
	::basegfx::B2DTuple aTRTranslate;
	ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);

	// use features and write
	ImpExportNewTrans_FeaturesAndWrite(aTRScale, fTRShear, fTRRotate, aTRTranslate, nFeatures);
}

void XMLShapeExport::ImpExportNewTrans_GetB2DHomMatrix(::basegfx::B2DHomMatrix& rMatrix,
	const uno::Reference< beans::XPropertySet >& xPropSet)
{
    // --> OD 2004-08-09 #i28749# - Get <TransformationInHoriL2R>, if it exist
    // and if the document is exported into the OpenOffice.org file format.
    // This property only exists at service com::sun::star::text::Shape - the
    // Writer UNO service for shapes.
    // This code is needed, because the positioning attributes in the
    // OpenOffice.org file format are given in horizontal left-to-right layout
    // regardless the layout direction the shape is in. In the OASIS Open Office
    // file format the positioning attributes are correctly given in the layout
    // direction the shape is in. Thus, this code provides the conversion from
    // the OASIS Open Office file format to the OpenOffice.org file format.
    uno::Any aAny;
    if ( ( GetExport().getExportFlags() & EXPORT_OASIS ) == 0 &&
         xPropSet->getPropertySetInfo()->hasPropertyByName(
            OUString(RTL_CONSTASCII_USTRINGPARAM("TransformationInHoriL2R"))) )
    {
        aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("TransformationInHoriL2R")));
    }
    else
    {
        aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Transformation")));
    }
    // <--
	drawing::HomogenMatrix3 aMatrix;
	aAny >>= aMatrix;

	rMatrix.set(0, 0, aMatrix.Line1.Column1);
	rMatrix.set(0, 1, aMatrix.Line1.Column2);
	rMatrix.set(0, 2, aMatrix.Line1.Column3);
	rMatrix.set(1, 0, aMatrix.Line2.Column1);
	rMatrix.set(1, 1, aMatrix.Line2.Column2);
	rMatrix.set(1, 2, aMatrix.Line2.Column3);
	rMatrix.set(2, 0, aMatrix.Line3.Column1);
	rMatrix.set(2, 1, aMatrix.Line3.Column2);
	rMatrix.set(2, 2, aMatrix.Line3.Column3);
}

void XMLShapeExport::ImpExportNewTrans_DecomposeAndRefPoint(const ::basegfx::B2DHomMatrix& rMatrix, ::basegfx::B2DTuple& rTRScale,
	double& fTRShear, double& fTRRotate, ::basegfx::B2DTuple& rTRTranslate, com::sun::star::awt::Point* pRefPoint)
{
	// decompose matrix
	rMatrix.decompose(rTRScale, rTRTranslate, fTRRotate, fTRShear);

	// correct translation about pRefPoint
	if(pRefPoint)
	{
		rTRTranslate -= ::basegfx::B2DTuple(pRefPoint->X, pRefPoint->Y);
	}
}

void XMLShapeExport::ImpExportNewTrans_FeaturesAndWrite(::basegfx::B2DTuple& rTRScale, double fTRShear,
	double fTRRotate, ::basegfx::B2DTuple& rTRTranslate, const sal_Int32 nFeatures)
{
	// allways write Size (rTRScale) since this statement carries the union
	// of the object
	OUString aStr;
	OUStringBuffer sStringBuffer;
	::basegfx::B2DTuple aTRScale(rTRScale);

	// svg: width
	if(!(nFeatures & SEF_EXPORT_WIDTH))
	{
		aTRScale.setX(1.0);
	}
	else
	{
		if( aTRScale.getX() > 0.0 )
			aTRScale.setX(aTRScale.getX() - 1.0);
		else if( aTRScale.getX() < 0.0 )
			aTRScale.setX(aTRScale.getX() + 1.0);
	}

	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, FRound(aTRScale.getX()));
	aStr = sStringBuffer.makeStringAndClear();
	mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_WIDTH, aStr);

	// svg: height
	if(!(nFeatures & SEF_EXPORT_HEIGHT))
	{
		aTRScale.setY(1.0);
	}
	else
	{
		if( aTRScale.getY() > 0.0 )
			aTRScale.setY(aTRScale.getY() - 1.0);
		else if( aTRScale.getY() < 0.0 )
			aTRScale.setY(aTRScale.getY() + 1.0);
	}

	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, FRound(aTRScale.getY()));
	aStr = sStringBuffer.makeStringAndClear();
	mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_HEIGHT, aStr);

	// decide if transformation is neccessary
	sal_Bool bTransformationIsNeccessary(fTRShear != 0.0 || fTRRotate != 0.0);

	if(bTransformationIsNeccessary)
	{
		// write transformation, but WITHOUT scale which is exported as size above
		SdXMLImExTransform2D aTransform;

		aTransform.AddSkewX(atan(fTRShear));

        // #i78696# 
        // fTRRotate is mathematically correct, but due to the error
        // we export/import it mirrored. Since the API implementation is fixed and
        // uses the correctly oriented angle, it is necessary for compatibility to
        // mirror the angle here to stay at the old behaviour. There is a follow-up
        // task (#i78698#) to fix this in the next ODF FileFormat version
		aTransform.AddRotate(-fTRRotate);

        aTransform.AddTranslate(rTRTranslate);

		// does transformation need to be exported?
		if(aTransform.NeedsAction())
			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_TRANSFORM, aTransform.GetExportString(mrExport.GetMM100UnitConverter()));
	}
	else
	{
		// no shear, no rotate; just add object position to export and we are done
		if(nFeatures & SEF_EXPORT_X)
		{
			// svg: x
			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, FRound(rTRTranslate.getX()));
			aStr = sStringBuffer.makeStringAndClear();
			mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X, aStr);
		}

		if(nFeatures & SEF_EXPORT_Y)
		{
			// svg: y
			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, FRound(rTRTranslate.getY()));
			aStr = sStringBuffer.makeStringAndClear();
			mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y, aStr);
		}
	}
}

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

sal_Bool XMLShapeExport::ImpExportPresentationAttributes( const uno::Reference< beans::XPropertySet >& xPropSet, const rtl::OUString& rClass )
{
	sal_Bool bIsEmpty = sal_False;

	OUStringBuffer sStringBuffer;

	// write presentation class entry
	mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_CLASS, rClass);

	if( xPropSet.is() )
	{
		uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );

		sal_Bool bTemp = false;

		// is empty pes shape?
		if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject"))))
		{
			xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject"))) >>= bIsEmpty;
			if( bIsEmpty )
				mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_PLACEHOLDER, XML_TRUE);
		}

		// is user-transformed?
		if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent"))))
		{
			xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent"))) >>= bTemp;
			if(!bTemp)
				mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_USER_TRANSFORMED, XML_TRUE);
		}
	}

	return bIsEmpty;
}

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

void XMLShapeExport::ImpExportText( const uno::Reference< drawing::XShape >& xShape )
{
	uno::Reference< text::XText > xText( xShape, uno::UNO_QUERY );
	if( xText.is() )
	{
		uno::Reference< container::XEnumerationAccess > xEnumAccess( xShape, uno::UNO_QUERY );
		if( xEnumAccess.is() && xEnumAccess->hasElements() )
			mrExport.GetTextParagraphExport()->exportText( xText );
	}
}

//////////////////////////////////////////////////////////////////////////////
#include <com/sun/star/presentation/ClickAction.hpp>
#include <com/sun/star/presentation/AnimationSpeed.hpp>

namespace {

const sal_Int32 FOUND_CLICKACTION       = 0x00000001;
const sal_Int32 FOUND_BOOKMARK          = 0x00000002;
const sal_Int32 FOUND_EFFECT            = 0x00000004;
const sal_Int32 FOUND_PLAYFULL          = 0x00000008;
const sal_Int32 FOUND_VERB              = 0x00000010;
const sal_Int32 FOUND_SOUNDURL          = 0x00000020;
const sal_Int32 FOUND_SPEED             = 0x00000040;
const sal_Int32 FOUND_CLICKEVENTTYPE    = 0x00000080;
const sal_Int32 FOUND_MACRO             = 0x00000100;
const sal_Int32 FOUND_LIBRARY           = 0x00000200;
const sal_Int32 FOUND_ACTIONEVENTTYPE   = 0x00000400;
#ifdef ISSUE66550_HLINK_FOR_SHAPES
const sal_Int32 FOUND_URL               = 0x00000800;
#endif

} // namespace

void XMLShapeExport::ImpExportEvents( const uno::Reference< drawing::XShape >& xShape )
{
    uno::Reference< document::XEventsSupplier > xEventsSupplier( xShape, uno::UNO_QUERY );
    if( !xEventsSupplier.is() )
        return;

    uno::Reference< container::XNameAccess > xEvents( xEventsSupplier->getEvents(), uno::UNO_QUERY );
    DBG_ASSERT( xEvents.is(), "XEventsSupplier::getEvents() returned NULL" );
    if( !xEvents.is() )
        return;

    sal_Int32 nFound = 0;

    // extract properties from "OnClick" event --------------------------------

    OUString aClickEventType;
    presentation::ClickAction eClickAction = presentation::ClickAction_NONE;
    presentation::AnimationEffect eEffect = presentation::AnimationEffect_NONE;
    presentation::AnimationSpeed eSpeed = presentation::AnimationSpeed_SLOW;
    OUString aStrSoundURL;
    sal_Bool bPlayFull = false;
    sal_Int32 nVerb = 0;
    OUString aStrMacro;
    OUString aStrLibrary;
    OUString aStrBookmark;

    uno::Sequence< beans::PropertyValue > aClickProperties;
    if( xEvents->hasByName( msOnClick ) && (xEvents->getByName( msOnClick ) >>= aClickProperties) )
    {
        const beans::PropertyValue* pProperty = aClickProperties.getConstArray();
        const beans::PropertyValue* pPropertyEnd = pProperty + aClickProperties.getLength();
        for( ; pProperty != pPropertyEnd; ++pProperty )
        {
            if( ( ( nFound & FOUND_CLICKEVENTTYPE ) == 0 ) && pProperty->Name == msEventType )
            {
                if( pProperty->Value >>= aClickEventType )
                    nFound |= FOUND_CLICKEVENTTYPE;
            }
            else if( ( ( nFound & FOUND_CLICKACTION ) == 0 ) && pProperty->Name == msClickAction )
            {
                if( pProperty->Value >>= eClickAction )
                    nFound |= FOUND_CLICKACTION;
            }
            else if( ( ( nFound & FOUND_MACRO ) == 0 ) && ( pProperty->Name == msMacroName || pProperty->Name == msScript ) )
            {
                if( pProperty->Value >>= aStrMacro )
                    nFound |= FOUND_MACRO;
            }
            else if( ( ( nFound & FOUND_LIBRARY ) == 0 ) && pProperty->Name == msLibrary )
            {
                if( pProperty->Value >>= aStrLibrary )
                    nFound |= FOUND_LIBRARY;
            }
            else if( ( ( nFound & FOUND_EFFECT ) == 0 ) && pProperty->Name == msEffect )
            {
                if( pProperty->Value >>= eEffect )
                    nFound |= FOUND_EFFECT;
            }
            else if( ( ( nFound & FOUND_BOOKMARK ) == 0 ) && pProperty->Name == msBookmark )
            {
                if( pProperty->Value >>= aStrBookmark )
                    nFound |= FOUND_BOOKMARK;
            }
            else if( ( ( nFound & FOUND_SPEED ) == 0 ) && pProperty->Name == msSpeed )
            {
                if( pProperty->Value >>= eSpeed )
                    nFound |= FOUND_SPEED;
            }
            else if( ( ( nFound & FOUND_SOUNDURL ) == 0 ) && pProperty->Name == msSoundURL )
            {
                if( pProperty->Value >>= aStrSoundURL )
                    nFound |= FOUND_SOUNDURL;
            }
            else if( ( ( nFound & FOUND_PLAYFULL ) == 0 ) && pProperty->Name == msPlayFull )
            {
                if( pProperty->Value >>= bPlayFull )
                    nFound |= FOUND_PLAYFULL;
            }
            else if( ( ( nFound & FOUND_VERB ) == 0 ) && pProperty->Name == msVerb )
            {
                if( pProperty->Value >>= nVerb )
                    nFound |= FOUND_VERB;
            }
        }
    }

#ifdef ISSUE66550_HLINK_FOR_SHAPES
    // extract properties from "OnAction" event -------------------------------

    OUString aActionEventType;
    OUString aHyperURL;

    uno::Sequence< beans::PropertyValue > aActionProperties;
    if( xEvents->hasByName( msOnAction ) && (xEvents->getByName( msOnAction ) >>= aActionProperties) )
    {
        const beans::PropertyValue* pProperty = aActionProperties.getConstArray();
        const beans::PropertyValue* pPropertyEnd = pProperty + aActionProperties.getLength();
        for( ; pProperty != pPropertyEnd; ++pProperty )
        {
            if( ( ( nFound & FOUND_ACTIONEVENTTYPE ) == 0 ) && pProperty->Name == msEventType )
            {
                if( pProperty->Value >>= aActionEventType )
                    nFound |= FOUND_ACTIONEVENTTYPE;
            }
            else if( ( ( nFound & FOUND_URL ) == 0 ) && ( pProperty->Name == msURL  ) )
            {
                if( pProperty->Value >>= aHyperURL )
                    nFound |= FOUND_URL;
            }
        }
    }
#endif

    // create the XML elements

    if( aClickEventType == msPresentation )
    {
        if( ((nFound & FOUND_CLICKACTION) == 0) || (eClickAction == presentation::ClickAction_NONE) )
            return;

        SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, sal_True, sal_True);

        enum XMLTokenEnum eStrAction;

        switch( eClickAction )
        {
            case presentation::ClickAction_PREVPAGE:        eStrAction = XML_PREVIOUS_PAGE; break;
            case presentation::ClickAction_NEXTPAGE:        eStrAction = XML_NEXT_PAGE; break;
            case presentation::ClickAction_FIRSTPAGE:       eStrAction = XML_FIRST_PAGE; break;
            case presentation::ClickAction_LASTPAGE:        eStrAction = XML_LAST_PAGE; break;
            case presentation::ClickAction_INVISIBLE:       eStrAction = XML_HIDE; break;
            case presentation::ClickAction_STOPPRESENTATION:eStrAction = XML_STOP; break;
            case presentation::ClickAction_PROGRAM:         eStrAction = XML_EXECUTE; break;
            case presentation::ClickAction_BOOKMARK:        eStrAction = XML_SHOW; break;
            case presentation::ClickAction_DOCUMENT:        eStrAction = XML_SHOW; break;
            case presentation::ClickAction_MACRO:           eStrAction = XML_EXECUTE_MACRO; break;
            case presentation::ClickAction_VERB:            eStrAction = XML_VERB; break;
            case presentation::ClickAction_VANISH:          eStrAction = XML_FADE_OUT; break;
            case presentation::ClickAction_SOUND:           eStrAction = XML_SOUND; break;
            default:
                DBG_ERROR( "unknown presentation::ClickAction found!" );
                eStrAction = XML_UNKNOWN;
        }

        OUString aEventQName(
            mrExport.GetNamespaceMap().GetQNameByKey(
                    XML_NAMESPACE_DOM, OUString( RTL_CONSTASCII_USTRINGPARAM( "click" ) ) ) );
        mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_EVENT_NAME, aEventQName );
        mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_ACTION, eStrAction );

        if( eClickAction == presentation::ClickAction_VANISH )
        {
            if( nFound & FOUND_EFFECT )
            {
                XMLEffect eKind;
                XMLEffectDirection eDirection;
                sal_Int16 nStartScale;
                sal_Bool bIn;

                SdXMLImplSetEffect( eEffect, eKind, eDirection, nStartScale, bIn );

                if( eKind != EK_none )
                {
                    SvXMLUnitConverter::convertEnum( msBuffer, eKind, aXML_AnimationEffect_EnumMap );
                    mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_EFFECT, msBuffer.makeStringAndClear() );
                }

                if( eDirection != ED_none )
                {
                    SvXMLUnitConverter::convertEnum( msBuffer, eDirection, aXML_AnimationDirection_EnumMap );
                    mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_DIRECTION, msBuffer.makeStringAndClear() );
                }

                if( nStartScale != -1 )
                {
                    SvXMLUnitConverter::convertPercent( msBuffer, nStartScale );
                    mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_START_SCALE, msBuffer.makeStringAndClear() );
                }
            }

            if( nFound & FOUND_SPEED && eEffect != presentation::AnimationEffect_NONE )
            {
                 if( eSpeed != presentation::AnimationSpeed_MEDIUM )
                    {
                    SvXMLUnitConverter::convertEnum( msBuffer, eSpeed, aXML_AnimationSpeed_EnumMap );
                    mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_SPEED, msBuffer.makeStringAndClear() );
                }
            }
        }

        if( eClickAction == presentation::ClickAction_PROGRAM ||
            eClickAction == presentation::ClickAction_BOOKMARK ||
            eClickAction == presentation::ClickAction_DOCUMENT )
        {
            if( eClickAction == presentation::ClickAction_BOOKMARK )
                msBuffer.append( sal_Unicode('#') );

            msBuffer.append( aStrBookmark );
            mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(msBuffer.makeStringAndClear()) );
            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_ONREQUEST );
        }

        if( ( nFound & FOUND_VERB ) && eClickAction == presentation::ClickAction_VERB )
        {
            msBuffer.append( nVerb );
            mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_VERB, msBuffer.makeStringAndClear());
        }

        SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_PRESENTATION, XML_EVENT_LISTENER, sal_True, sal_True);

        if( eClickAction == presentation::ClickAction_VANISH || eClickAction == presentation::ClickAction_SOUND )
        {
            if( ( nFound & FOUND_SOUNDURL ) && aStrSoundURL.getLength() != 0 )
            {
                mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStrSoundURL) );
                mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
                mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_NEW );
                mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONREQUEST );
                if( nFound & FOUND_PLAYFULL && bPlayFull )
                    mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PLAY_FULL, XML_TRUE );

                SvXMLElementExport aElem( mrExport, XML_NAMESPACE_PRESENTATION, XML_SOUND, sal_True, sal_True );
            }
       }
    }
    else if( aClickEventType == msStarBasic )
    {
        if( nFound & FOUND_MACRO )
        {
            SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, sal_True, sal_True);

            mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_LANGUAGE,
                        mrExport.GetNamespaceMap().GetQNameByKey(
                            XML_NAMESPACE_OOO,
                            OUString( RTL_CONSTASCII_USTRINGPARAM(
                                            "starbasic" ) ) ) );
            OUString aEventQName(
                mrExport.GetNamespaceMap().GetQNameByKey(
                        XML_NAMESPACE_DOM, OUString( RTL_CONSTASCII_USTRINGPARAM( "click" ) ) ) );
            mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_EVENT_NAME, aEventQName );

            if( nFound & FOUND_LIBRARY )
            {
                OUString sLocation( GetXMLToken(
                    (aStrLibrary.equalsIgnoreAsciiCaseAscii("StarOffice") ||
                     aStrLibrary.equalsIgnoreAsciiCaseAscii("application") ) ? XML_APPLICATION
                                                                       : XML_DOCUMENT ) );
                OUStringBuffer sTmp( sLocation.getLength() + aStrMacro.getLength() + 1 );
                sTmp = sLocation;
                sTmp.append( sal_Unicode( ':' ) );
                sTmp.append( aStrMacro );
                mrExport.AddAttribute(XML_NAMESPACE_SCRIPT, XML_MACRO_NAME,
                                     sTmp.makeStringAndClear());
            }
            else
            {
                mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_MACRO_NAME, aStrMacro );
            }

            SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SCRIPT, XML_EVENT_LISTENER, sal_True, sal_True);
        }
    }
#ifdef ISSUE66550_HLINK_FOR_SHAPES
    else if( aClickEventType == msScript || aActionEventType == msAction )
    {
        if( nFound & ( FOUND_MACRO | FOUND_URL ) )
#else
    else if( aClickEventType == msScript )
    {
        if( nFound & FOUND_MACRO )
#endif
        {
            SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, sal_True, sal_True);
            if ( nFound & FOUND_MACRO )
            {
                mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_LANGUAGE, mrExport.GetNamespaceMap().GetQNameByKey(
                         XML_NAMESPACE_OOO, GetXMLToken(XML_SCRIPT) ) );
                OUString aEventQName(
                    mrExport.GetNamespaceMap().GetQNameByKey(
                            XML_NAMESPACE_DOM, OUString( RTL_CONSTASCII_USTRINGPARAM( "click" ) ) ) );
                mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_EVENT_NAME, aEventQName );
                mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, aStrMacro );

                SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SCRIPT, XML_EVENT_LISTENER, sal_True, sal_True);
            }
#ifdef ISSUE66550_HLINK_FOR_SHAPES
            if ( nFound & FOUND_URL )
            {
                OUString aEventQName(
                    mrExport.GetNamespaceMap().GetQNameByKey(
                            XML_NAMESPACE_DOM, OUString( RTL_CONSTASCII_USTRINGPARAM( "action" ) ) ) );
                mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_EVENT_NAME, aEventQName );
                mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, aHyperURL );

                SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_PRESENTATION, XML_EVENT_LISTENER, sal_True, sal_True);
            }
#endif
        }
    }
}

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

/** #i68101# export shape Title and Description */
void XMLShapeExport::ImpExportDescription( const uno::Reference< drawing::XShape >& xShape )
{
	try
	{
		OUString aTitle;
		OUString aDescription;

		uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY_THROW );
		xProps->getPropertyValue( OUString::createFromAscii( "Title" ) ) >>= aTitle;
		xProps->getPropertyValue( OUString::createFromAscii( "Description" ) ) >>= aDescription;

		if(aTitle.getLength())
		{
			SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_TITLE, sal_True, sal_False);
			mrExport.Characters( aTitle );
		}

		if(aDescription.getLength())
		{
			SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_DESC, sal_True, sal_False );
			mrExport.Characters( aDescription );
		}
	}
	catch( uno::Exception& )
	{
		DBG_ERROR( "could not export Title and/or Description for shape!" );
	}
}

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

void XMLShapeExport::ImpExportGroupShape( const uno::Reference< drawing::XShape >& xShape, XmlShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
{
	uno::Reference< drawing::XShapes > xShapes(xShape, uno::UNO_QUERY);
	if(xShapes.is() && xShapes->getCount())
	{
		// write group shape
		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
		SvXMLElementExport aPGR(mrExport, XML_NAMESPACE_DRAW, XML_G, bCreateNewline, sal_True);

		ImpExportDescription( xShape ); // #i68101#
		ImpExportEvents( xShape );
		ImpExportGluePoints( xShape );

		// #89764# if export of position is supressed for group shape,
		// positions of contained objects should be written relative to
		// the upper left edge of the group.
		awt::Point aUpperLeft;

		if(!(nFeatures & SEF_EXPORT_POSITION))
		{
			nFeatures |= SEF_EXPORT_POSITION;
			aUpperLeft = xShape->getPosition();
			pRefPoint = &aUpperLeft;
		}

		// write members
		exportShapes( xShapes, nFeatures, pRefPoint );
	}
}

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

void XMLShapeExport::ImpExportTextBoxShape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType eShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
{
	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
	if(xPropSet.is())
	{
		uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );

		// presentation attribute (if presentation)
		sal_Bool bIsPresShape(sal_False);
		sal_Bool bIsEmptyPresObj(sal_False);
		OUString aStr;

		switch(eShapeType)
		{
			case XmlShapeTypePresSubtitleShape:
			{
				aStr = GetXMLToken(XML_PRESENTATION_SUBTITLE);
				bIsPresShape = sal_True;
				break;
			}
			case XmlShapeTypePresTitleTextShape:
			{
				aStr = GetXMLToken(XML_PRESENTATION_TITLE);
				bIsPresShape = sal_True;
				break;
			}
			case XmlShapeTypePresOutlinerShape:
			{
				aStr = GetXMLToken(XML_PRESENTATION_OUTLINE);
				bIsPresShape = sal_True;
				break;
			}
			case XmlShapeTypePresNotesShape:
			{
				aStr = GetXMLToken(XML_PRESENTATION_NOTES);
				bIsPresShape = sal_True;
				break;
			}
			case XmlShapeTypePresHeaderShape:
			{
				aStr = GetXMLToken(XML_HEADER);
				bIsPresShape = sal_True;
				break;
			}
			case XmlShapeTypePresFooterShape:
			{
				aStr = GetXMLToken(XML_FOOTER);
				bIsPresShape = sal_True;
				break;
			}
			case XmlShapeTypePresSlideNumberShape:
			{
				aStr = GetXMLToken(XML_PAGE_NUMBER);
				bIsPresShape = sal_True;
				break;
			}
			case XmlShapeTypePresDateTimeShape:
			{
				aStr = GetXMLToken(XML_DATE_TIME);
				bIsPresShape = sal_True;
				break;
			}
			default:
				break;
		}

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

		if(bIsPresShape)
			bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, aStr );


		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
		SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
								  XML_FRAME, bCreateNewline, sal_True );

		// evtl. corner radius?
		sal_Int32 nCornerRadius(0L);
		xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CornerRadius"))) >>= nCornerRadius;
		if(nCornerRadius)
		{
			OUStringBuffer sStringBuffer;
			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nCornerRadius);
			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
		}

		{
			// write text-box
			SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_TEXT_BOX, sal_True, sal_True);
			if(!bIsEmptyPresObj)
				ImpExportText( xShape );
		}

		ImpExportDescription( xShape ); // #i68101#
		ImpExportEvents( xShape );
		ImpExportGluePoints( xShape );
	}
}

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

void XMLShapeExport::ImpExportRectangleShape(
	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())
	{
		// Transformation
		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);

		// evtl. corner radius?
		sal_Int32 nCornerRadius(0L);
		xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CornerRadius"))) >>= nCornerRadius;
		if(nCornerRadius)
		{
			OUStringBuffer sStringBuffer;
			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nCornerRadius);
			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
		}

		// write rectangle
		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
		SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_RECT, bCreateNewline, sal_True);

		ImpExportDescription( xShape ); // #i68101#
		ImpExportEvents( xShape );
		ImpExportGluePoints( xShape );
		ImpExportText( xShape );
	}
}

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

void XMLShapeExport::ImpExportLineShape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
{
	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
	if(xPropSet.is())
	{
		OUString aStr;
		OUStringBuffer sStringBuffer;
		awt::Point aStart(0,0);
		awt::Point aEnd(1,1);

		// #85920# use 'Geometry' to get the points of the line
		// since this slot take anchor pos into account.

		// get matrix
		::basegfx::B2DHomMatrix aMatrix;
		ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);

		// decompose and correct about pRefPoint
		::basegfx::B2DTuple aTRScale;
		double fTRShear(0.0);
		double fTRRotate(0.0);
		::basegfx::B2DTuple aTRTranslate;
		ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);

		// create base position
		awt::Point aBasePosition(FRound(aTRTranslate.getX()), FRound(aTRTranslate.getY()));

		// get the two points
		uno::Any aAny(xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry"))));
		drawing::PointSequenceSequence* pSourcePolyPolygon = (drawing::PointSequenceSequence*)aAny.getValue();

		if(pSourcePolyPolygon)
		{
		    drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->getArray();
			if(pOuterSequence)
			{
		        drawing::PointSequence* pInnerSequence = pOuterSequence++;
				if(pInnerSequence)
				{
				    awt::Point* pArray = pInnerSequence->getArray();
					if(pArray)
					{
						if(pInnerSequence->getLength() > 0)
						{
							aStart = awt::Point(
								pArray->X + aBasePosition.X,
								pArray->Y + aBasePosition.Y);
							pArray++;
						}

						if(pInnerSequence->getLength() > 1)
						{
							aEnd = awt::Point(
								pArray->X + aBasePosition.X,
								pArray->Y + aBasePosition.Y);
						}
					}
				}
			}
		}

		if( nFeatures & SEF_EXPORT_X )
		{
			// svg: x1
			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aStart.X);
			aStr = sStringBuffer.makeStringAndClear();
			mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X1, aStr);
		}
		else
		{
			aEnd.X -= aStart.X;
		}

		if( nFeatures & SEF_EXPORT_Y )
		{
			// svg: y1
			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aStart.Y);
			aStr = sStringBuffer.makeStringAndClear();
			mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y1, aStr);
		}
		else
		{
			aEnd.Y -= aStart.Y;
		}

		// svg: x2
		mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aEnd.X);
		aStr = sStringBuffer.makeStringAndClear();
		mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X2, aStr);

		// svg: y2
		mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aEnd.Y);
		aStr = sStringBuffer.makeStringAndClear();
		mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y2, aStr);

		// write line
		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
		SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_LINE, bCreateNewline, sal_True);

		ImpExportDescription( xShape ); // #i68101#
		ImpExportEvents( xShape );
		ImpExportGluePoints( xShape );
		ImpExportText( xShape );
	}
}

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

void XMLShapeExport::ImpExportEllipseShape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
{
	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
	if(xPropSet.is())
	{
		// get size to decide between Circle and Ellipse
		awt::Size aSize = xShape->getSize();
		sal_Int32 nRx((aSize.Width + 1) / 2);
		sal_Int32 nRy((aSize.Height + 1) / 2);
		sal_Bool bCircle(nRx == nRy);

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

		drawing::CircleKind eKind = drawing::CircleKind_FULL;
		xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("CircleKind")) ) >>= eKind;
		if( eKind != drawing::CircleKind_FULL )
		{
			OUStringBuffer sStringBuffer;
			sal_Int32 nStartAngle = 0;
			sal_Int32 nEndAngle = 0;
			xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("CircleStartAngle")) ) >>= nStartAngle;
			xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("CircleEndAngle")) ) >>= nEndAngle;

			const double dStartAngle = nStartAngle / 100.0;
			const double dEndAngle = nEndAngle / 100.0;

			// export circle kind
			SvXMLUnitConverter::convertEnum( sStringBuffer, (sal_uInt16)eKind, aXML_CircleKind_EnumMap );
			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_KIND, sStringBuffer.makeStringAndClear() );

			// export start angle
			SvXMLUnitConverter::convertDouble( sStringBuffer, dStartAngle );
			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_ANGLE, sStringBuffer.makeStringAndClear() );

			// export end angle
			SvXMLUnitConverter::convertDouble( sStringBuffer, dEndAngle );
			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_ANGLE, sStringBuffer.makeStringAndClear() );
		}

		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#

        // prepare name (with most used)
        enum ::xmloff::token::XMLTokenEnum eName(XML_CIRCLE);

        if(bCircle)
        {
            // name already set
        }
        else
        {
            // set name
            eName = XML_ELLIPSE;
        }

        // write ellipse or circle
        SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, eName, bCreateNewline, sal_True);

        ImpExportDescription( xShape ); // #i68101#
        ImpExportEvents( xShape );
        ImpExportGluePoints( xShape );
        ImpExportText( xShape );
    }
}

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

void XMLShapeExport::ImpExportPolygonShape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType eShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
{
	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
	if(xPropSet.is())
	{
		sal_Bool bBezier(eShapeType == XmlShapeTypeDrawClosedBezierShape
			|| eShapeType == XmlShapeTypeDrawOpenBezierShape);

		// get matrix
		::basegfx::B2DHomMatrix aMatrix;
		ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);

		// decompose and correct abour pRefPoint
		::basegfx::B2DTuple aTRScale;
		double fTRShear(0.0);
		double fTRRotate(0.0);
		::basegfx::B2DTuple aTRTranslate;
		ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);

		// use features and write
		ImpExportNewTrans_FeaturesAndWrite(aTRScale, fTRShear, fTRRotate, aTRTranslate, nFeatures);

		// create and export ViewBox
		awt::Point aPoint(0, 0);
		awt::Size aSize(FRound(aTRScale.getX()), FRound(aTRScale.getY()));
		SdXMLImExViewBox aViewBox(0, 0, aSize.Width, aSize.Height);
		mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString());

		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#

        // prepare name (with most used)
        enum ::xmloff::token::XMLTokenEnum eName(XML_PATH);

        if(bBezier)
        {
            // get PolygonBezier
            uno::Any aAny( xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry"))) );
            const basegfx::B2DPolyPolygon aPolyPolygon(
                basegfx::tools::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(*(drawing::PolyPolygonBezierCoords*)aAny.getValue()));

            if(aPolyPolygon.count())
            {
                // complex polygon shape, write as svg:d
                const ::rtl::OUString aPolygonString(
                    basegfx::tools::exportToSvgD(
                        aPolyPolygon,
                        true,       // bUseRelativeCoordinates
                        false,      // bDetectQuadraticBeziers: not used in old, but maybe activated now
                        true));     // bHandleRelativeNextPointCompatible

                // write point array
                mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
            }
        }
        else
        {
            // get non-bezier polygon
            uno::Any aAny( xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry"))) );
            const basegfx::B2DPolyPolygon aPolyPolygon(
                basegfx::tools::UnoPointSequenceSequenceToB2DPolyPolygon(*(drawing::PointSequenceSequence*)aAny.getValue()));

            if(!aPolyPolygon.areControlPointsUsed() && 1 == aPolyPolygon.count())
            {
                // simple polygon shape, can be written as svg:points sequence
                const basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(0));
                const ::rtl::OUString aPointString(basegfx::tools::exportToSvgPoints(aPolygon));

                // write point array
                mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_POINTS, aPointString);

                // set name
                eName = aPolygon.isClosed() ? XML_POLYGON : XML_POLYLINE;
            }
            else
            {
                // complex polygon shape, write as svg:d
                const ::rtl::OUString aPolygonString(
                    basegfx::tools::exportToSvgD(
                        aPolyPolygon,
                        true,       // bUseRelativeCoordinates
                        false,      // bDetectQuadraticBeziers: not used in old, but maybe activated now
                        true));     // bHandleRelativeNextPointCompatible

                // write point array
                mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
            }
        }

        // write object, but after attributes are added since this call will
        // consume all of these added attributes and the destructor will close the 
        // scope. Also before text is added; this may add sub-scopes as needed
        SvXMLElementExport aOBJ(
            mrExport, 
            XML_NAMESPACE_DRAW, 
            eName, 
            bCreateNewline, 
            sal_True);

        ImpExportDescription( xShape ); // #i68101#
        ImpExportEvents( xShape );
        ImpExportGluePoints( xShape );
        ImpExportText( xShape );
    }
}

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

void XMLShapeExport::ImpExportGraphicObjectShape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType eShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
{
	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
	if(xPropSet.is())
	{
		sal_Bool bIsEmptyPresObj = sal_False;
		uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );

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

		OUString sImageURL;

		if(eShapeType == XmlShapeTypePresGraphicObjectShape)
			bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_GRAPHIC) );

		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
		SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
								  XML_FRAME, bCreateNewline, sal_True );

		const bool bSaveBackwardsCompatible = ( mrExport.getExportFlags() & EXPORT_SAVEBACKWARDCOMPATIBLE );

		if( !bIsEmptyPresObj || bSaveBackwardsCompatible )
		{
			if( !bIsEmptyPresObj )
			{
                OUString aReplacementUrl;
                xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("ReplacementGraphicURL"))) >>= aReplacementUrl;

                // If there is no url, then then graphic is empty
                if(aReplacementUrl.getLength())
                {
                    const OUString aStr = mrExport.AddEmbeddedGraphicObject(aReplacementUrl);

                    if(aStr.getLength())
                    {
                        mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aStr);
                        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 );

                        // xlink:href for replacement, only written for Svg content
                        SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, sal_True, sal_True);

                        // optional office:binary-data
                        mrExport.AddEmbeddedGraphicObjectAsBase64(aReplacementUrl);
                    }
                }

                OUString aStreamURL;
				OUString aStr;

				xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicStreamURL"))) >>= aStreamURL;
				xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicURL"))) >>= sImageURL;

				OUString aResolveURL( sImageURL );				
				const rtl::OUString sPackageURL( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.Package:") );

					// sj: trying to preserve the filename
				if ( aStreamURL.match( sPackageURL, 0 ) )
				{
					rtl::OUString sRequestedName( aStreamURL.copy( sPackageURL.getLength(), aStreamURL.getLength() - sPackageURL.getLength() ) );
					sal_Int32 nLastIndex = sRequestedName.lastIndexOf( '/' ) + 1;
					if ( ( nLastIndex > 0 ) && ( nLastIndex < sRequestedName.getLength() ) )
						sRequestedName = sRequestedName.copy( nLastIndex, sRequestedName.getLength() - nLastIndex );
					nLastIndex = sRequestedName.lastIndexOf( '.' );
					if ( nLastIndex >= 0 )
						sRequestedName = sRequestedName.copy( 0, nLastIndex );
					if ( sRequestedName.getLength() )
					{
						aResolveURL = aResolveURL.concat( OUString(RTL_CONSTASCII_USTRINGPARAM("?requestedName=")));
						aResolveURL = aResolveURL.concat( sRequestedName );
					}
				}

				aStr = mrExport.AddEmbeddedGraphicObject( aResolveURL );
				mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aStr );

				if( aStr.getLength() )
				{
					if( aStr[ 0 ] == '#' )
					{
						aStreamURL = sPackageURL;
						aStreamURL = aStreamURL.concat( aStr.copy( 1, aStr.getLength() - 1 ) );
					}

					// update stream URL for load on demand
					uno::Any aAny;
					aAny <<= aStreamURL;
					xPropSet->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicStreamURL")), aAny );

					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 );
				}
			}
			else
			{
				OUString aStr;
				mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aStr );
				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 aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, sal_True, sal_True);

				if( sImageURL.getLength() )
				{
					// optional office:binary-data
					mrExport.AddEmbeddedGraphicObjectAsBase64( sImageURL );
				}
				if( !bIsEmptyPresObj )
					ImpExportText( xShape );
			}
		}

		ImpExportEvents( xShape );
		ImpExportGluePoints( xShape );

		// image map
		GetExport().GetImageMapExport().Export( xPropSet );
		ImpExportDescription( xShape ); // #i68101#
	}
}

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

void XMLShapeExport::ImpExportChartShape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType eShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint,
    SvXMLAttributeList* pAttrList )
{
	ImpExportOLE2Shape( xShape, eShapeType, nFeatures, pRefPoint, pAttrList );
}

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

void XMLShapeExport::ImpExportControlShape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
{
	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
	if(xPropSet.is())
	{
		// Transformation
		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
	}

	uno::Reference< drawing::XControlShape > xControl( xShape, uno::UNO_QUERY );
	DBG_ASSERT( xControl.is(), "Control shape is not supporting XControlShape" );
	if( xControl.is() )
	{
		uno::Reference< beans::XPropertySet > xControlModel( xControl->getControl(), uno::UNO_QUERY );
		DBG_ASSERT( xControlModel.is(), "Control shape has not XControlModel" );
		if( xControlModel.is() )
		{
			mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CONTROL, mrExport.GetFormExport()->getControlId( xControlModel ) );
		}
	}

	sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
	SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_CONTROL, bCreateNewline, sal_True);

	ImpExportDescription( xShape ); // #i68101#
}

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

void XMLShapeExport::ImpExportConnectorShape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType, sal_Int32 nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
{
	uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );

	OUString aStr;
	OUStringBuffer sStringBuffer;

	// export connection kind
	drawing::ConnectorType eType = drawing::ConnectorType_STANDARD;
	uno::Any aAny = xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EdgeKind")));
	aAny >>= eType;

	if( eType != drawing::ConnectorType_STANDARD )
	{
		SvXMLUnitConverter::convertEnum( sStringBuffer, (sal_uInt16)eType, aXML_ConnectionKind_EnumMap );
		aStr = sStringBuffer.makeStringAndClear();
		mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_TYPE, aStr);
	}

	// export line skew
	sal_Int32 nDelta1 = 0, nDelta2 = 0, nDelta3 = 0;

	aAny = xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EdgeLine1Delta")));
	aAny >>= nDelta1;
	aAny = xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EdgeLine2Delta")));
	aAny >>= nDelta2;
	aAny = xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EdgeLine3Delta")));
	aAny >>= nDelta3;

	if( nDelta1 != 0 || nDelta2 != 0 || nDelta3 != 0 )
	{
		mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nDelta1);
		if( nDelta2 != 0 || nDelta3 != 0 )
		{
			const char aSpace = ' ';
			sStringBuffer.appendAscii( &aSpace, 1 );
			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nDelta2);
			if( nDelta3 != 0 )
			{
				sStringBuffer.appendAscii( &aSpace, 1 );
				mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nDelta3);
			}
		}

		aStr = sStringBuffer.makeStringAndClear();
		mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_LINE_SKEW, aStr);
	}

	// export start and end point
	awt::Point aStart(0,0);
	awt::Point aEnd(1,1);

    // --> OD 2004-08-09 #i36248# - Get <StartPositionInHoriL2R> and
    // <EndPositionInHoriL2R>, if they exist and if the document is exported
    // into the OpenOffice.org file format.
    // These properties only exist at service com::sun::star::text::Shape - the
    // Writer UNO service for shapes.
    // This code is needed, because the positioning attributes in the
    // OpenOffice.org file format are given in horizontal left-to-right layout
    // regardless the layout direction the shape is in. In the OASIS Open Office
    // file format the positioning attributes are correctly given in the layout
    // direction the shape is in. Thus, this code provides the conversion from
    // the OASIS Open Office file format to the OpenOffice.org file format.
    if ( ( GetExport().getExportFlags() & EXPORT_OASIS ) == 0 &&
         xProps->getPropertySetInfo()->hasPropertyByName(
            OUString(RTL_CONSTASCII_USTRINGPARAM("StartPositionInHoriL2R"))) &&
         xProps->getPropertySetInfo()->hasPropertyByName(
            OUString(RTL_CONSTASCII_USTRINGPARAM("EndPositionInHoriL2R"))) )
    {
        xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("StartPositionInHoriL2R"))) >>= aStart;
        xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EndPositionInHoriL2R"))) >>= aEnd;
    }
    else
    {
        xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("StartPosition"))) >>= aStart;
        xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EndPosition"))) >>= aEnd;
    }
    // <--

	if( pRefPoint )
	{
		aStart.X -= pRefPoint->X;
		aStart.Y -= pRefPoint->Y;
		aEnd.X -= pRefPoint->X;
		aEnd.Y -= pRefPoint->Y;
	}

	if( nFeatures & SEF_EXPORT_X )
	{
		// svg: x1
		mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aStart.X);
		aStr = sStringBuffer.makeStringAndClear();
		mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X1, aStr);
	}
	else
	{
		aEnd.X -= aStart.X;
	}

	if( nFeatures & SEF_EXPORT_Y )
	{
		// svg: y1
		mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aStart.Y);
		aStr = sStringBuffer.makeStringAndClear();
		mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y1, aStr);
	}
	else
	{
		aEnd.Y -= aStart.Y;
	}

	// svg: x2
	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aEnd.X);
	aStr = sStringBuffer.makeStringAndClear();
	mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X2, aStr);

	// svg: y2
	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aEnd.Y);
	aStr = sStringBuffer.makeStringAndClear();
	mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y2, aStr);

	// #i39320#
	uno::Reference< uno::XInterface > xRefS;
	uno::Reference< uno::XInterface > xRefE;

	// export start connection
	xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("StartShape") ) ) >>= xRefS;
	if( xRefS.is() )
	{
		const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRefS );
		mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_SHAPE, rShapeId);

		aAny = xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("StartGluePointIndex")) );
		sal_Int32 nGluePointId = 0;
		if( aAny >>= nGluePointId )
		{
			if( nGluePointId != -1 )
			{
				mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_GLUE_POINT, OUString::valueOf( nGluePointId ));
			}
		}
	}

	// export end connection
	xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EndShape")) ) >>= xRefE;
	if( xRefE.is() )
	{
		const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRefE );
		mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_SHAPE, rShapeId);

		aAny = xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EndGluePointIndex")) );
		sal_Int32 nGluePointId = 0;
		if( aAny >>= nGluePointId )
		{
			if( nGluePointId != -1 )
			{
				mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_GLUE_POINT, OUString::valueOf( nGluePointId ));
			}
		}
	}

    if( xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("PolyPolygonBezier") ) ) >>= aAny )
    {
        // get PolygonBezier
        drawing::PolyPolygonBezierCoords* pSourcePolyPolygon = (drawing::PolyPolygonBezierCoords*)aAny.getValue();

        if(pSourcePolyPolygon && pSourcePolyPolygon->Coordinates.getLength())
        {
            const basegfx::B2DPolyPolygon aPolyPolygon(
                basegfx::tools::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(
                    *pSourcePolyPolygon));
            const ::rtl::OUString aPolygonString(
                basegfx::tools::exportToSvgD(
                    aPolyPolygon,
                    true,           // bUseRelativeCoordinates
                    false,          // bDetectQuadraticBeziers: not used in old, but maybe activated now
                    true));         // bHandleRelativeNextPointCompatible

            // write point array
            mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
        }
    }

	// write connector shape. Add Export later.
	sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
	SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_CONNECTOR, bCreateNewline, sal_True);

	ImpExportDescription( xShape ); // #i68101#
	ImpExportEvents( xShape );
	ImpExportGluePoints( xShape );
	ImpExportText( xShape );
}

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

void XMLShapeExport::ImpExportMeasureShape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType, sal_Int32 nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
{
	uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );

	OUString aStr;
	OUStringBuffer sStringBuffer;

	// export start and end point
	awt::Point aStart(0,0);
	awt::Point aEnd(1,1);

    // --> OD 2004-08-09 #i36248# - Get <StartPositionInHoriL2R> and
    // <EndPositionInHoriL2R>, if they exist and if the document is exported
    // into the OpenOffice.org file format.
    // These properties only exist at service com::sun::star::text::Shape - the
    // Writer UNO service for shapes.
    // This code is needed, because the positioning attributes in the
    // OpenOffice.org file format are given in horizontal left-to-right layout
    // regardless the layout direction the shape is in. In the OASIS Open Office
    // file format the positioning attributes are correctly given in the layout
    // direction the shape is in. Thus, this code provides the conversion from
    // the OASIS Open Office file format to the OpenOffice.org file format.
    if ( ( GetExport().getExportFlags() & EXPORT_OASIS ) == 0 &&
         xProps->getPropertySetInfo()->hasPropertyByName(
            OUString(RTL_CONSTASCII_USTRINGPARAM("StartPositionInHoriL2R"))) &&
         xProps->getPropertySetInfo()->hasPropertyByName(
            OUString(RTL_CONSTASCII_USTRINGPARAM("EndPositionInHoriL2R"))) )
    {
        xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("StartPositionInHoriL2R"))) >>= aStart;
        xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EndPositionInHoriL2R"))) >>= aEnd;
    }
    else
    {
        xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("StartPosition"))) >>= aStart;
        xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EndPosition"))) >>= aEnd;
    }
    // <--

	if( pRefPoint )
	{
		aStart.X -= pRefPoint->X;
		aStart.Y -= pRefPoint->Y;
		aEnd.X -= pRefPoint->X;
		aEnd.Y -= pRefPoint->Y;
	}

	if( nFeatures & SEF_EXPORT_X )
	{
		// svg: x1
		mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aStart.X);
		aStr = sStringBuffer.makeStringAndClear();
		mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X1, aStr);
	}
	else
	{
		aEnd.X -= aStart.X;
	}

	if( nFeatures & SEF_EXPORT_Y )
	{
		// svg: y1
		mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aStart.Y);
		aStr = sStringBuffer.makeStringAndClear();
		mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y1, aStr);
	}
	else
	{
		aEnd.Y -= aStart.Y;
	}

	// svg: x2
	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aEnd.X);
	aStr = sStringBuffer.makeStringAndClear();
	mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X2, aStr);

	// svg: y2
	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aEnd.Y);
	aStr = sStringBuffer.makeStringAndClear();
	mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y2, aStr);

	// write measure shape
	sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
	SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_MEASURE, bCreateNewline, sal_True);

	ImpExportDescription( xShape ); // #i68101#
	ImpExportEvents( xShape );
	ImpExportGluePoints( xShape );

	uno::Reference< text::XText > xText( xShape, uno::UNO_QUERY );
	if( xText.is() )
		mrExport.GetTextParagraphExport()->exportText( xText );
}

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

void XMLShapeExport::ImpExportOLE2Shape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType eShapeType, sal_Int32 nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */,
    SvXMLAttributeList* pAttrList /* = NULL */ )
{
	uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
	uno::Reference< container::XNamed > xNamed(xShape, uno::UNO_QUERY);

	DBG_ASSERT( xPropSet.is() && xNamed.is(), "ole shape is not implementing needed interfaces");
	if(xPropSet.is() && xNamed.is())
	{
		// Transformation
		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);

		sal_Bool bIsEmptyPresObj = sal_False;

		// presentation settings
		if(eShapeType == XmlShapeTypePresOLE2Shape)
			bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_OBJECT) );
		else if(eShapeType == XmlShapeTypePresChartShape)
			bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_CHART) );
		else if(eShapeType == XmlShapeTypePresSheetShape)
			bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_TABLE) );

		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
		sal_Bool bExportEmbedded(0 != (mrExport.getExportFlags() & EXPORT_EMBEDDED));
		OUString sPersistName;
		SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW,
								  XML_FRAME, bCreateNewline, sal_True );

		const bool bSaveBackwardsCompatible = ( mrExport.getExportFlags() & EXPORT_SAVEBACKWARDCOMPATIBLE );

		if( !bIsEmptyPresObj || bSaveBackwardsCompatible )
		{
            if (pAttrList)
            {
                mrExport.AddAttributeList(pAttrList);
            }

			OUString sClassId;
			OUString sURL;
			sal_Bool bInternal = false;
			xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("IsInternal"))) >>= bInternal;

			if( !bIsEmptyPresObj )
			{

				if ( bInternal )
				{
					// OOo internal links have no storage persistance, URL is stored in the XML file
					// the result LinkURL is empty in case the object is not a link
					xPropSet->getPropertyValue( OUString::createFromAscii( "LinkURL" ) ) >>= sURL;
				}

				xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM( "PersistName" ) ) ) >>= sPersistName;
				if ( !sURL.getLength() )
				{
					if( sPersistName.getLength() )
					{
						sURL = OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.EmbeddedObject:" ) );
						sURL += sPersistName;
					}
				}

				if( !bInternal )
					xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CLSID"))) >>= sClassId;

				if( sClassId.getLength() )
					mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CLASS_ID, sClassId );
				if(!bExportEmbedded)
				{
					// xlink:href
					if( sURL.getLength() )
					{
						// #96717# in theorie, if we don't have a url we shouldn't even
						// export this ole shape. But practical its to risky right now
						// to change this so we better dispose this on load
						sURL = mrExport.AddEmbeddedObject( sURL );

						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 );
					}
				}
			}
			else
			{
				// export empty href for empty placeholders to be valid odf
				OUString sEmptyURL;

				mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sEmptyURL );
				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 );
			}

			enum XMLTokenEnum eElem = sClassId.getLength() ? XML_OBJECT_OLE : XML_OBJECT;
			SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, eElem, sal_True, sal_True );

            // #i118485# Add text export, the draw OLE shape allows text now
            ImpExportText( xShape );

			if(bExportEmbedded && !bIsEmptyPresObj)
			{
				// #100592#
				if(bInternal)
				{
					// embedded XML
					uno::Reference< lang::XComponent > xComp;
					xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("Model") ) ) >>= xComp;
					DBG_ASSERT( xComp.is(), "no xModel for own OLE format" );
					mrExport.ExportEmbeddedOwnObject( xComp );
				}
				else
				{
					// embed as Base64
					// this is an alien object ( currently MSOLE is the only supported type of such objects )
					// in case it is not an OASIS format the object should be asked to store replacement image if possible

					::rtl::OUString sURLRequest( sURL );
    				if ( ( mrExport.getExportFlags() & EXPORT_OASIS ) == 0 )
						sURLRequest += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "?oasis=false" ) );
					mrExport.AddEmbeddedObjectAsBase64( sURLRequest );
				}
			}
		}
		if( !bIsEmptyPresObj )
		{
			OUString sURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) );
			sURL += sPersistName;
			if( !bExportEmbedded )
			{
				sURL = GetExport().AddEmbeddedObject( sURL );
				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 )
				GetExport().AddEmbeddedObjectAsBase64( sURL );
		}

        ImpExportEvents( xShape );
		ImpExportGluePoints( xShape );
		ImpExportDescription( xShape ); // #i68101#
	}
}

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

void XMLShapeExport::ImpExportPageShape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType eShapeType, sal_Int32 nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
{
	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
	if(xPropSet.is())
	{
		// #86163# Transformation
		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);

		// export page number used for this page
		uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
		const OUString aPageNumberStr(RTL_CONSTASCII_USTRINGPARAM("PageNumber"));
		if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(aPageNumberStr))
		{
			sal_Int32 nPageNumber = 0;
			xPropSet->getPropertyValue(aPageNumberStr) >>= nPageNumber;
			if( nPageNumber )
				mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_PAGE_NUMBER, OUString::valueOf(nPageNumber));
		}

		// a presentation page shape, normally used on notes pages only. If
		// it is used not as presentation shape, it may have been created with
		// copy-paste exchange between draw and impress (this IS possible...)
		if(eShapeType == XmlShapeTypePresPageShape)
		{
			mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_CLASS,
                                 XML_PRESENTATION_PAGE);
		}

		// write Page shape
		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
		SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PAGE_THUMBNAIL, bCreateNewline, sal_True);
	}
}

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

void XMLShapeExport::ImpExportCaptionShape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType, sal_Int32 nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
{
	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
	if(xPropSet.is())
	{
		// Transformation
		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);

		// evtl. corner radius?
		sal_Int32 nCornerRadius(0L);
		xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CornerRadius"))) >>= nCornerRadius;
		if(nCornerRadius)
		{
			OUStringBuffer sStringBuffer;
			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nCornerRadius);
			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
		}

		awt::Point aCaptionPoint;
		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" ) ) ) >>= aCaptionPoint;

		mrExport.GetMM100UnitConverter().convertMeasure(msBuffer, aCaptionPoint.X);
		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CAPTION_POINT_X, msBuffer.makeStringAndClear() );
		mrExport.GetMM100UnitConverter().convertMeasure(msBuffer, aCaptionPoint.Y);
		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CAPTION_POINT_Y, msBuffer.makeStringAndClear() );

		// write Caption shape. Add export later.
		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
		sal_Bool bAnnotation( (nFeatures & SEF_EXPORT_ANNOTATION) == SEF_EXPORT_ANNOTATION );

        SvXMLElementExport aObj( mrExport,
								 (bAnnotation ? XML_NAMESPACE_OFFICE
								 			  : XML_NAMESPACE_DRAW),
								 (bAnnotation ?	XML_ANNOTATION : XML_CAPTION),
								 bCreateNewline, sal_True );

		ImpExportDescription( xShape ); // #i68101#
		ImpExportEvents( xShape );
		ImpExportGluePoints( xShape );
		if( bAnnotation )
			mrExport.exportAnnotationMeta( xShape );
		ImpExportText( xShape );
	}
}

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

void XMLShapeExport::ImpExportFrameShape(
	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())
	{
		// Transformation
		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);

		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
		SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
								  XML_FRAME, bCreateNewline, sal_True );

		// export frame url
		OUString aStr;
		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "FrameURL" ) ) ) >>= aStr;
        mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
        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 );

		// export name
		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "FrameName" ) ) ) >>= aStr;
		if( aStr.getLength() )
			mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_FRAME_NAME, aStr );

		// write floating frame
		{
			SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_FLOATING_FRAME, sal_True, sal_True);
		}
	}
}

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

void XMLShapeExport::ImpExportAppletShape(
	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())
	{
		// Transformation
		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);

		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
		SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW,
								  XML_FRAME, bCreateNewline, sal_True );

		// export frame url
		OUString aStr;
		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletCodeBase" ) ) ) >>= aStr;
        mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
        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 );

		// export draw:applet-name
		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletName" ) ) ) >>= aStr;
		if( aStr.getLength() )
			mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_APPLET_NAME, aStr );

		// export draw:code
		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletCode" ) ) ) >>= aStr;
		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CODE, aStr );

		// export draw:may-script
		sal_Bool bIsScript = false;
		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletIsScript" ) ) ) >>= bIsScript;
		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MAY_SCRIPT, bIsScript ? XML_TRUE : XML_FALSE );

		{
			// write applet
			SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_APPLET, sal_True, sal_True);

			// export parameters
			uno::Sequence< beans::PropertyValue > aCommands;
			xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletCommands" ) ) ) >>= aCommands;
			const sal_Int32 nCount = aCommands.getLength();
			for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
			{
				aCommands[nIndex].Value >>= aStr;
				mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aCommands[nIndex].Name );
				mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, aStr );
				SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, sal_False, sal_True );
			}
		}
	}
}

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

void XMLShapeExport::ImpExportPluginShape(
	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())
	{
		// Transformation
		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);

		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
		SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW,
								  XML_FRAME, bCreateNewline, sal_True );

		// export plugin url
		OUString aStr;
		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "PluginURL" ) ) ) >>= aStr;
        mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
        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 );


		// export mime-type
		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "PluginMimeType" ) ) ) >>= aStr;
		if(aStr.getLength())
			mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIME_TYPE, aStr );

		{
			// write plugin
			SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, sal_True, sal_True);

			// export parameters
			uno::Sequence< beans::PropertyValue > aCommands;
			xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "PluginCommands" ) ) ) >>= aCommands;
			const sal_Int32 nCount = aCommands.getLength();
			for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
			{
				aCommands[nIndex].Value >>= aStr;
				mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aCommands[nIndex].Name );
				mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, aStr );
				SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, sal_False, sal_True );
			}
		}
	}
}

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

void XMLShapeExport::ImpExportMediaShape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType eShapeType, sal_Int32 nFeatures, com::sun::star::awt::Point* pRefPoint)
{
	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
	if(xPropSet.is())
	{
		// Transformation
		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);

		if(eShapeType == XmlShapeTypePresMediaShape)
			ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_OBJECT) );

		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
		SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
								  XML_FRAME, bCreateNewline, sal_True );

		// export media url
		OUString aMediaURL;
		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaURL" ) ) ) >>= aMediaURL;
        mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference( aMediaURL ) );
        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 );

		// export mime-type
		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIME_TYPE, OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.media" ) ) );

		// write plugin
		SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, !( nFeatures & SEF_EXPORT_NO_WS ), sal_True);

		// export parameters
		const OUString aFalseStr( RTL_CONSTASCII_USTRINGPARAM( "false" ) ), aTrueStr( RTL_CONSTASCII_USTRINGPARAM( "true" ) );

		sal_Bool bLoop = false;
		const OUString aLoopStr( RTL_CONSTASCII_USTRINGPARAM( "Loop" ) );
		xPropSet->getPropertyValue( aLoopStr ) >>= bLoop;
		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aLoopStr );
		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, bLoop ? aTrueStr : aFalseStr );
		delete( new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, sal_False, sal_True ) );

		sal_Bool bMute = false;
		const OUString aMuteStr( RTL_CONSTASCII_USTRINGPARAM( "Mute" ) );
		xPropSet->getPropertyValue( aMuteStr ) >>= bMute;
		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aMuteStr );
		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, bMute ? aTrueStr : aFalseStr );
		delete( new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, sal_False, sal_True ) );

		sal_Int16 nVolumeDB = 0;
		const OUString aVolumeDBStr( RTL_CONSTASCII_USTRINGPARAM( "VolumeDB" ) );
		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "VolumeDB" ) ) ) >>= nVolumeDB;
		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aVolumeDBStr );
		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, OUString::valueOf( static_cast< sal_Int32 >( nVolumeDB ) ) );
		delete( new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, sal_False, sal_True ) );

		media::ZoomLevel eZoom;
		const OUString aZoomStr( RTL_CONSTASCII_USTRINGPARAM( "Zoom" ) );
		OUString aZoomValue;
		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Zoom" ) ) ) >>= eZoom;
		switch( eZoom )
		{
			case( media::ZoomLevel_ZOOM_1_TO_4 ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "25%" ) ); break;
			case( media::ZoomLevel_ZOOM_1_TO_2 ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "50%" ) ); break;
			case( media::ZoomLevel_ORIGINAL ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "100%" ) ); break;
			case( media::ZoomLevel_ZOOM_2_TO_1 ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "200%" ) ); break;
			case( media::ZoomLevel_ZOOM_4_TO_1 ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "400%" ) ); break;
		    case( media::ZoomLevel_FIT_TO_WINDOW ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "fit" ) ); break;
		    case( media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "fixedfit" ) ); break;
		    case( media::ZoomLevel_FULLSCREEN ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "fullscreen" ) ); break;

			default:
			break;
		}

		if( aZoomValue.getLength() )
		{
			mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aZoomStr );
			mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, aZoomValue );
			delete( new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, sal_False, sal_True ) );
		}
	}
}
