/**************************************************************
 * 
 * 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 <tools/debug.hxx>
#include <com/sun/star/document/XEventsSupplier.hpp>
#include <com/sun/star/container/XNameReplace.hpp>
#include <com/sun/star/presentation/ClickAction.hpp>
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>
#include "unointerfacetouniqueidentifiermapper.hxx"
#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
#include <com/sun/star/container/XIdentifierAccess.hpp>
#include <com/sun/star/drawing/GluePoint2.hpp>
#include <com/sun/star/drawing/Alignment.hpp>
#include <com/sun/star/drawing/EscapeDirection.hpp>
#include <com/sun/star/media/ZoomLevel.hpp>
#include <com/sun/star/awt/Rectangle.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <comphelper/extract.hxx>
#include "ximpshap.hxx"
#include <xmloff/XMLBase64ImportContext.hxx>
#include <xmloff/XMLShapeStyleContext.hxx>
#include <xmloff/xmluconv.hxx>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/drawing/CircleKind.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/awt/XControlModel.hpp>
#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/drawing/PointSequenceSequence.hpp>
#include <com/sun/star/drawing/PointSequence.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/util/XCloneable.hpp>
#include <com/sun/star/beans/XMultiPropertyStates.hpp>
#include "xexptran.hxx"
#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include <com/sun/star/drawing/ConnectorType.hpp>
#include <com/sun/star/drawing/HomogenMatrix3.hpp>
#include "PropertySetMerger.hxx"
#include <xmloff/families.hxx>
#include "ximpstyl.hxx"
#include"xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include "EnhancedCustomShapeToken.hxx"
#include "XMLReplacementImageContext.hxx"
#include "XMLImageMapContext.hxx"
#include "sdpropls.hxx"
#include "eventimp.hxx"
#include "descriptionimp.hxx"
#include "ximpcustomshape.hxx"
#include "XMLEmbeddedObjectImportContext.hxx"
#include "xmloff/xmlerror.hxx"
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <tools/string.hxx>
#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/text/XTextDocument.hpp>
#include <basegfx/vector/b2dvector.hxx>
#include <basegfx/point/b2dpoint.hxx>

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

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::document;
using namespace ::xmloff::token;
using namespace ::xmloff::EnhancedCustomShapeToken;

SvXMLEnumMapEntry aXML_GlueAlignment_EnumMap[] =
{
	{ XML_TOP_LEFT, 	drawing::Alignment_TOP_LEFT },
	{ XML_TOP,			drawing::Alignment_TOP },
	{ XML_TOP_RIGHT,	drawing::Alignment_TOP_RIGHT },
	{ XML_LEFT,		    drawing::Alignment_LEFT },
	{ XML_CENTER,		drawing::Alignment_CENTER },
	{ XML_RIGHT,		drawing::Alignment_RIGHT },
	{ XML_BOTTOM_LEFT,	drawing::Alignment_BOTTOM_LEFT },
	{ XML_BOTTOM,		drawing::Alignment_BOTTOM },
	{ XML_BOTTOM_RIGHT, drawing::Alignment_BOTTOM_RIGHT },
	{ XML_TOKEN_INVALID, 0 }
};

SvXMLEnumMapEntry aXML_GlueEscapeDirection_EnumMap[] =
{
	{ XML_AUTO, 		drawing::EscapeDirection_SMART },
	{ XML_LEFT,	    	drawing::EscapeDirection_LEFT },
    { XML_RIGHT,		drawing::EscapeDirection_RIGHT },
    { XML_UP,			drawing::EscapeDirection_UP },
    { XML_DOWN,		    drawing::EscapeDirection_DOWN },
    { XML_HORIZONTAL,	drawing::EscapeDirection_HORIZONTAL },
    { XML_VERTICAL,	    drawing::EscapeDirection_VERTICAL },
	{ XML_TOKEN_INVALID, 0 }
};

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

static bool ImpIsEmptyURL( const ::rtl::OUString& rURL )
{
    if( rURL.getLength() == 0 )
        return true;

    // #i13140# Also compare against 'toplevel' URLs. which also
    // result in empty filename strings.
    if( 0 == rURL.compareToAscii( "#./" ) )
        return true;

    return false;
}

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

TYPEINIT1( SvXMLShapeContext, SvXMLImportContext );
TYPEINIT1( SdXMLShapeContext, SvXMLShapeContext );

SdXMLShapeContext::SdXMLShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
:	SvXMLShapeContext( rImport, nPrfx, rLocalName, bTemporaryShape )
,	mxShapes( rShapes )
,	mxAttrList(xAttrList)
,	mbListContextPushed( false )
,	mnStyleFamily(XML_STYLE_FAMILY_SD_GRAPHICS_ID)
,	mbIsPlaceholder(sal_False)
,	mbClearDefaultAttributes( true )
,	mbIsUserTransformed(sal_False)
,	mnZOrder(-1)
,	maSize(1, 1)
,	maPosition(0, 0)
,   maUsedTransformation()
,	mbVisible(true)
,	mbPrintable(true)
{
}

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

SdXMLShapeContext::~SdXMLShapeContext()
{
}

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

SvXMLImportContext *SdXMLShapeContext::CreateChildContext( sal_uInt16 p_nPrefix,
	const OUString& rLocalName,
	const uno::Reference< xml::sax::XAttributeList>& xAttrList )
{
	SvXMLImportContext * pContext = NULL;

	// #i68101#
	if( p_nPrefix == XML_NAMESPACE_SVG &&	
		(IsXMLToken( rLocalName, XML_TITLE ) || IsXMLToken( rLocalName, XML_DESC ) ) )
	{
		pContext = new SdXMLDescriptionContext( GetImport(), p_nPrefix, rLocalName, xAttrList, mxShape );
	}
	else if( p_nPrefix == XML_NAMESPACE_OFFICE && IsXMLToken( rLocalName, XML_EVENT_LISTENERS ) )
	{
		pContext = new SdXMLEventsContext( GetImport(), p_nPrefix, rLocalName, xAttrList, mxShape );
	}
	else if( p_nPrefix == XML_NAMESPACE_DRAW && IsXMLToken( rLocalName, XML_GLUE_POINT ) )
	{
		addGluePoint( xAttrList );
	}
	else if( p_nPrefix == XML_NAMESPACE_DRAW && IsXMLToken( rLocalName, XML_THUMBNAIL ) )
	{
		// search attributes for xlink:href
		sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
		for(sal_Int16 i=0; i < nAttrCount; i++)
		{
			OUString sAttrName = xAttrList->getNameByIndex( i );
			OUString aLocalName;
			sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );

			if( nPrefix == XML_NAMESPACE_XLINK )
			{
				if( IsXMLToken( aLocalName, XML_HREF ) )
				{
					maThumbnailURL = xAttrList->getValueByIndex( i );
					break;
				}
			}
		}
	}
	else
	{
		// create text cursor on demand
		if( !mxCursor.is() )
		{
			uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
			if( xText.is() )
			{
				UniReference < XMLTextImportHelper > xTxtImport =
					GetImport().GetTextImport();
				mxOldCursor = xTxtImport->GetCursor();
				mxCursor = xText->createTextCursor();
				if( mxCursor.is() )
				{
					xTxtImport->SetCursor( mxCursor );
				}

				// remember old list item and block (#91964#) and reset them
				// for the text frame
                xTxtImport->PushListContext();
                mbListContextPushed = true;
			}
		}

		// if we have a text cursor, lets  try to import some text
		if( mxCursor.is() )
		{
			pContext = GetImport().GetTextImport()->CreateTextChildContext(
				GetImport(), p_nPrefix, rLocalName, xAttrList );
		}
	}

	// call parent for content
	if(!pContext)
		pContext = SvXMLImportContext::CreateChildContext( p_nPrefix, rLocalName, xAttrList );

	return pContext;
}

void SdXMLShapeContext::addGluePoint( const uno::Reference< xml::sax::XAttributeList>& xAttrList )
{
	// get the glue points container for this shape if its not already there
	if( !mxGluePoints.is() )
	{
		uno::Reference< drawing::XGluePointsSupplier > xSupplier( mxShape, uno::UNO_QUERY );
		if( !xSupplier.is() )
			return;

		mxGluePoints = uno::Reference< container::XIdentifierContainer >::query( xSupplier->getGluePoints() );

		if( !mxGluePoints.is() )
			return;
	}

	drawing::GluePoint2 aGluePoint;
	aGluePoint.IsUserDefined = sal_True;
	aGluePoint.Position.X = 0;
	aGluePoint.Position.Y = 0;
	aGluePoint.Escape = drawing::EscapeDirection_SMART;
	aGluePoint.PositionAlignment = drawing::Alignment_CENTER;
	aGluePoint.IsRelative = sal_True;

	sal_Int32 nId = -1;

	// read attributes for the 3DScene
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for(sal_Int16 i=0; i < nAttrCount; i++)
	{
		OUString sAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
		const OUString sValue( xAttrList->getValueByIndex( i ) );

		if( nPrefix == XML_NAMESPACE_SVG )
		{
			if( IsXMLToken( aLocalName, XML_X ) )
			{
				GetImport().GetMM100UnitConverter().convertMeasure(aGluePoint.Position.X, sValue);
			}
			else if( IsXMLToken( aLocalName, XML_Y ) )
			{
				GetImport().GetMM100UnitConverter().convertMeasure(aGluePoint.Position.Y, sValue);
			}
		}
		else if( nPrefix == XML_NAMESPACE_DRAW )
		{
			if( IsXMLToken( aLocalName, XML_ID ) )
			{
				nId = sValue.toInt32();
			}
			else if( IsXMLToken( aLocalName, XML_ALIGN ) )
			{
				sal_uInt16 eKind;
				if( SvXMLUnitConverter::convertEnum( eKind, sValue, aXML_GlueAlignment_EnumMap ) )
				{
					aGluePoint.PositionAlignment = (drawing::Alignment)eKind;
					aGluePoint.IsRelative = sal_False;
				}
			}
			else if( IsXMLToken( aLocalName, XML_ESCAPE_DIRECTION ) )
			{
				sal_uInt16 eKind;
				if( SvXMLUnitConverter::convertEnum( eKind, sValue, aXML_GlueEscapeDirection_EnumMap ) )
				{
					aGluePoint.Escape = (drawing::EscapeDirection)eKind;
				}
			}
		}
	}

	if( nId != -1 )
	{
		try
		{
			sal_Int32 nInternalId = mxGluePoints->insert( uno::makeAny( aGluePoint ) );
			GetImport().GetShapeImport()->addGluePointMapping( mxShape, nId, nInternalId );
		}
		catch( uno::Exception& )
		{
			DBG_ERROR( "exception during setting of glue points!");
		}
	}
}
//////////////////////////////////////////////////////////////////////////////

void SdXMLShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>&)
{
    GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
}

void SdXMLShapeContext::EndElement()
{
	if(mxCursor.is())
	{
		// delete addition newline
		const OUString aEmpty;
		mxCursor->gotoEnd( sal_False );
		mxCursor->goLeft( 1, sal_True );
		mxCursor->setString( aEmpty );

		// reset cursor
		GetImport().GetTextImport()->ResetCursor();
	}

	if(mxOldCursor.is())
		GetImport().GetTextImport()->SetCursor( mxOldCursor );

    // reinstall old list item (if necessary) #91964#
    if (mbListContextPushed) {
        GetImport().GetTextImport()->PopListContext();
    }

	if( msHyperlink.getLength() != 0 ) try
	{
		const OUString sBookmark( RTL_CONSTASCII_USTRINGPARAM( "Bookmark" ) );

        Reference< XEventsSupplier > xEventsSupplier( mxShape, UNO_QUERY );
		if( xEventsSupplier.is() )
		{
			const OUString sEventType( RTL_CONSTASCII_USTRINGPARAM( "EventType" ) );
			const OUString sClickAction( RTL_CONSTASCII_USTRINGPARAM( "ClickAction" ) );

			Reference< XNameReplace > xEvents( xEventsSupplier->getEvents(), UNO_QUERY_THROW );

			uno::Sequence< beans::PropertyValue > aProperties( 3 );
			aProperties[0].Name = sEventType;
			aProperties[0].Handle = -1;
			aProperties[0].Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM("Presentation") );
			aProperties[0].State = beans::PropertyState_DIRECT_VALUE;

			aProperties[1].Name = sClickAction;
			aProperties[1].Handle = -1;
			aProperties[1].Value <<= ::com::sun::star::presentation::ClickAction_DOCUMENT;
			aProperties[1].State = beans::PropertyState_DIRECT_VALUE;

			aProperties[2].Name = sBookmark;
			aProperties[2].Handle = -1;
			aProperties[2].Value <<= msHyperlink;
			aProperties[2].State = beans::PropertyState_DIRECT_VALUE;

			const OUString sAPIEventName( RTL_CONSTASCII_USTRINGPARAM( "OnClick" ) );
			xEvents->replaceByName( sAPIEventName, Any( aProperties ) );
		}
		else
		{
			// in draw use the Bookmark property
			Reference< beans::XPropertySet > xSet( mxShape, UNO_QUERY_THROW );
			xSet->setPropertyValue( sBookmark, Any( msHyperlink ) );
			xSet->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "OnClick" ) ), Any( ::com::sun::star::presentation::ClickAction_DOCUMENT ) );
		}
	}
	catch( Exception& )
	{
		DBG_ERROR("xmloff::SdXMLShapeContext::EndElement(), exception caught while setting hyperlink!");
	}

	if( mxLockable.is() )
		mxLockable->removeActionLock();
}

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

void SdXMLShapeContext::AddShape(uno::Reference< drawing::XShape >& xShape)
{
	if(xShape.is())
	{
		// set shape local
		mxShape = xShape;

		if(maShapeName.getLength())
		{
			uno::Reference< container::XNamed > xNamed( mxShape, uno::UNO_QUERY );
			if( xNamed.is() )
				xNamed->setName( maShapeName );
		}

		UniReference< XMLShapeImportHelper > xImp( GetImport().GetShapeImport() );
		xImp->addShape( xShape, mxAttrList, mxShapes );

		if( mbClearDefaultAttributes )
		{
	        uno::Reference<beans::XMultiPropertyStates> xMultiPropertyStates(xShape, uno::UNO_QUERY );
		    if (xMultiPropertyStates.is())
			    xMultiPropertyStates->setAllPropertiesToDefault();
		}

		if( !mbVisible || !mbPrintable ) try
		{
			uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY_THROW );
			if( !mbVisible )
				xSet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Visible" ) ), uno::Any( sal_False ) );

			if( !mbPrintable )
				xSet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Printable" ) ), uno::Any( sal_False ) );
		}
		catch( Exception& )
		{
			DBG_ERROR( "SdXMLShapeContext::AddShape(), exception caught!" );
		}

		// #107848#
		if(!mbTemporaryShape && (!GetImport().HasTextImport()
			|| !GetImport().GetTextImport()->IsInsideDeleteContext()))
		{
			xImp->shapeWithZIndexAdded( xShape, mnZOrder );
		}

		if( maShapeId.getLength() )
		{
            const SdXMLGraphicObjectShapeContext* pGSC = dynamic_cast< const SdXMLGraphicObjectShapeContext* >(this);

            /* avoid registering when LateRegister is needed. E.g. MultiImage support where in-between multiple
               xShapes with the same ID would be registered. Registration is done after deciding which image
               to keep, see calls to solveMultipleImages */
            if(!pGSC || !pGSC->getLateAddToIdentifierMapper())
            {
                uno::Reference< uno::XInterface > xRef( xShape, uno::UNO_QUERY );
                GetImport().getInterfaceToIdentifierMapper().registerReference( maShapeId, xRef );
            }
		}

		// #91065# count only if counting for shape import is enabled
		if(GetImport().GetShapeImport()->IsHandleProgressBarEnabled())
		{
			// #80365# increment progress bar at load once for each draw object
			GetImport().GetProgressBarHelper()->Increment();
		}
	}

	mxLockable = uno::Reference< document::XActionLockable >::query( xShape );

	if( mxLockable.is() )
		mxLockable->addActionLock();

}

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

void SdXMLShapeContext::AddShape(const char* pServiceName )
{
	uno::Reference< lang::XMultiServiceFactory > xServiceFact(GetImport().GetModel(), uno::UNO_QUERY);
	if(xServiceFact.is())
	{
        try
        {
            // --> OD 2006-02-22 #b6382898#
            // Since fix for issue i33294 the Writer model doesn't support
            // com.sun.star.drawing.OLE2Shape anymore.
            // To handle Draw OLE objects it's decided to import these
            // objects as com.sun.star.drawing.OLE2Shape and convert these
            // objects after the import into com.sun.star.drawing.GraphicObjectShape.
            uno::Reference< drawing::XShape > xShape;
            if ( OUString::createFromAscii(pServiceName).compareToAscii( "com.sun.star.drawing.OLE2Shape" ) == 0 &&
                 uno::Reference< text::XTextDocument >(GetImport().GetModel(), uno::UNO_QUERY).is() )
            {
                xShape = uno::Reference< drawing::XShape >(xServiceFact->createInstance(OUString::createFromAscii("com.sun.star.drawing.temporaryForXMLImportOLE2Shape")), uno::UNO_QUERY);
            }
            else
            {
                xShape = uno::Reference< drawing::XShape >(xServiceFact->createInstance(OUString::createFromAscii(pServiceName)), uno::UNO_QUERY);
            }
            // <--
            if( xShape.is() )
                AddShape( xShape );
        }
        catch( const uno::Exception& e )
        {
            uno::Sequence<rtl::OUString> aSeq( 1 );
            aSeq[0] = OUString::createFromAscii(pServiceName);
            GetImport().SetError( XMLERROR_FLAG_ERROR | XMLERROR_API,
                                  aSeq, e.Message, NULL );
        }
	}
}

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

void SdXMLShapeContext::SetTransformation()
{
	if(mxShape.is())
	{
		uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
		if(xPropSet.is())
		{
			maUsedTransformation.identity();

			if(maSize.Width != 1 || maSize.Height != 1)
			{
				// take care there are no zeros used by error
				if(0 == maSize.Width)
					maSize.Width = 1;
				if(0 == maSize.Height)
					maSize.Height = 1;

				// set global size. This should always be used.
				maUsedTransformation.scale(maSize.Width, maSize.Height);
			}

			if(maPosition.X != 0 || maPosition.Y != 0)
			{
				// if global position is used, add it to transformation
				maUsedTransformation.translate(maPosition.X, maPosition.Y);
			}

			if(mnTransform.NeedsAction())
			{
				// transformation is used, apply to object.
				// NOTICE: The transformation is applied AFTER evtl. used
				// global positioning and scaling is used, so any shear or
				// rotate used herein is applied around the (0,0) position
				// of the PAGE object !!!
				::basegfx::B2DHomMatrix aMat;
				mnTransform.GetFullTransform(aMat);

				// now add to transformation
				maUsedTransformation *= aMat;
			}

			// now set transformation for this object
			uno::Any aAny;
			drawing::HomogenMatrix3 aMatrix;

			aMatrix.Line1.Column1 = maUsedTransformation.get(0, 0);
			aMatrix.Line1.Column2 = maUsedTransformation.get(0, 1);
			aMatrix.Line1.Column3 = maUsedTransformation.get(0, 2);

			aMatrix.Line2.Column1 = maUsedTransformation.get(1, 0);
			aMatrix.Line2.Column2 = maUsedTransformation.get(1, 1);
			aMatrix.Line2.Column3 = maUsedTransformation.get(1, 2);

			aMatrix.Line3.Column1 = maUsedTransformation.get(2, 0);
			aMatrix.Line3.Column2 = maUsedTransformation.get(2, 1);
			aMatrix.Line3.Column3 = maUsedTransformation.get(2, 2);

			aAny <<= aMatrix;

			xPropSet->setPropertyValue(
				OUString(RTL_CONSTASCII_USTRINGPARAM("Transformation")), aAny);
        }
	}
}

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

void SdXMLShapeContext::SetStyle( bool bSupportsStyle /* = true */)
{
	try
	{
		uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
		if( !xPropSet.is() )
			return;

		do
		{
			XMLPropStyleContext* pDocStyle = NULL;

			// set style on shape
			if(maDrawStyleName.getLength() == 0)
				break;

			const SvXMLStyleContext* pStyle = 0L;
			sal_Bool bAutoStyle(sal_False);

			if(GetImport().GetShapeImport()->GetAutoStylesContext())
				pStyle = GetImport().GetShapeImport()->GetAutoStylesContext()->FindStyleChildContext(mnStyleFamily, maDrawStyleName);

			if(pStyle)
				bAutoStyle = sal_True;

			if(!pStyle && GetImport().GetShapeImport()->GetStylesContext())
				pStyle = GetImport().GetShapeImport()->GetStylesContext()->FindStyleChildContext(mnStyleFamily, maDrawStyleName);

			OUString aStyleName = maDrawStyleName;
			uno::Reference< style::XStyle > xStyle;

			if( pStyle && pStyle->ISA(XMLShapeStyleContext) )
			{
				pDocStyle = PTR_CAST( XMLShapeStyleContext, pStyle );

				if( pDocStyle->GetStyle().is() )
				{
					xStyle = pDocStyle->GetStyle();
				}
				else
				{
                    aStyleName = pDocStyle->GetParentName();
				}
			}

			if( !xStyle.is() && aStyleName.getLength() )
			{
				try
				{

					uno::Reference< style::XStyleFamiliesSupplier > xFamiliesSupplier( GetImport().GetModel(), uno::UNO_QUERY );

					if( xFamiliesSupplier.is() )
					{
						uno::Reference< container::XNameAccess > xFamilies( xFamiliesSupplier->getStyleFamilies() );
						if( xFamilies.is() )
						{

							uno::Reference< container::XNameAccess > xFamily;

							if( XML_STYLE_FAMILY_SD_PRESENTATION_ID == mnStyleFamily )
							{
								aStyleName = GetImport().GetStyleDisplayName(
									XML_STYLE_FAMILY_SD_PRESENTATION_ID,
									aStyleName );
								sal_Int32 nPos = aStyleName.lastIndexOf( sal_Unicode('-') );
								if( -1 != nPos )
								{
									OUString aFamily( aStyleName.copy( 0, nPos ) );

									xFamilies->getByName( aFamily ) >>= xFamily;
									aStyleName = aStyleName.copy( nPos + 1 );
								}
							}
							else
							{
								// get graphics familie
								xFamilies->getByName( OUString( RTL_CONSTASCII_USTRINGPARAM( "graphics" ) ) ) >>= xFamily;
								aStyleName = GetImport().GetStyleDisplayName(
									XML_STYLE_FAMILY_SD_GRAPHICS_ID,
									aStyleName );
							}

							if( xFamily.is() )
								xFamily->getByName( aStyleName ) >>= xStyle;
						}
					}
				}
				catch( uno::Exception& )
				{
					DBG_ERROR( "could not find style for shape!" );
				}
			}

			if( bSupportsStyle && xStyle.is() )
			{
				try
				{
					// set style on object
					uno::Any aAny;
					aAny <<= xStyle;
					xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Style")), aAny);
				}
				catch( uno::Exception& )
				{
					DBG_ERROR( "could not find style for shape!" );
				}
			}

			// if this is an auto style, set its properties
			if(bAutoStyle && pDocStyle)
			{
				// set PropertySet on object
				pDocStyle->FillPropertySet(xPropSet);
			}

		} while(0);

		// try to set text auto style
		do
		{
			// set style on shape
			if( 0 == maTextStyleName.getLength() )
				break;

			if( NULL == GetImport().GetShapeImport()->GetAutoStylesContext())
				break;

            const SvXMLStyleContext* pTempStyle = GetImport().GetShapeImport()->GetAutoStylesContext()->FindStyleChildContext(XML_STYLE_FAMILY_TEXT_PARAGRAPH, maTextStyleName);
			XMLPropStyleContext* pStyle = PTR_CAST( XMLPropStyleContext, pTempStyle ); // use temp var, PTR_CAST is a bad macro, FindStyleChildContext will be called twice
			if( pStyle == NULL )
				break;

			// set PropertySet on object
			pStyle->FillPropertySet(xPropSet);

		} while(0);
	}
	catch( uno::Exception& )
	{
	}
}

void SdXMLShapeContext::SetLayer()
{
	if( maLayerName.getLength() )
	{
		try
		{
			uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
			if(xPropSet.is() )
			{
				uno::Any aAny;
				aAny <<= maLayerName;

				xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("LayerName")), aAny);
				return;
			}
		}
		catch( uno::Exception e )
		{
		}
	}
}

void SdXMLShapeContext::SetThumbnail()
{
	if( 0 == maThumbnailURL.getLength() )
		return;

	try
	{
		uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
		if( !xPropSet.is() )
			return;

		const OUString sProperty(RTL_CONSTASCII_USTRINGPARAM("ThumbnailGraphicURL"));

		uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
		if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName( sProperty ) )
		{
			// load the thumbnail graphic and export it to a wmf stream so we can set
			// it at the api

			const OUString aInternalURL( GetImport().ResolveGraphicObjectURL( maThumbnailURL, sal_False ) );
			xPropSet->setPropertyValue( sProperty, uno::makeAny( aInternalURL ) );
		}
	}
	catch( uno::Exception e )
	{
	}
}

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
    bool bHaveXmlId( false );
	if( (XML_NAMESPACE_DRAW == nPrefix) || (XML_NAMESPACE_DRAW_EXT == nPrefix) )
	{
		if( IsXMLToken( rLocalName, XML_ZINDEX ) )
		{
			mnZOrder = rValue.toInt32();
		}
		else if( IsXMLToken( rLocalName, XML_ID ) )
        {
            if (!bHaveXmlId) { maShapeId = rValue; };
        }
		else if( IsXMLToken( rLocalName, XML_NAME ) )
		{
			maShapeName = rValue;
		}
		else if( IsXMLToken( rLocalName, XML_STYLE_NAME ) )
		{
			maDrawStyleName = rValue;
		}
		else if( IsXMLToken( rLocalName, XML_TEXT_STYLE_NAME ) )
		{
			maTextStyleName = rValue;
		}
		else if( IsXMLToken( rLocalName, XML_LAYER ) )
		{
			maLayerName = rValue;
		}
		else if( IsXMLToken( rLocalName, XML_TRANSFORM ) )
		{
			mnTransform.SetString(rValue, GetImport().GetMM100UnitConverter());
		}
		else if( IsXMLToken( rLocalName, XML_DISPLAY ) )
		{
			mbVisible = IsXMLToken( rValue, XML_ALWAYS ) || IsXMLToken( rValue, XML_SCREEN );
			mbPrintable = IsXMLToken( rValue, XML_ALWAYS ) || IsXMLToken( rValue, XML_PRINTER );
		}
	}
	else if( XML_NAMESPACE_PRESENTATION == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_USER_TRANSFORMED ) )
		{
			mbIsUserTransformed = IsXMLToken( rValue, XML_TRUE );
		}
		else if( IsXMLToken( rLocalName, XML_PLACEHOLDER ) )
		{
			mbIsPlaceholder = IsXMLToken( rValue, XML_TRUE );
			if( mbIsPlaceholder )
				mbClearDefaultAttributes = false;
		}
		else if( IsXMLToken( rLocalName, XML_CLASS ) )
		{
			maPresentationClass = rValue;
		}
		else if( IsXMLToken( rLocalName, XML_STYLE_NAME ) )
		{
			maDrawStyleName = rValue;
			mnStyleFamily = XML_STYLE_FAMILY_SD_PRESENTATION_ID;
		}
	}
	else if( XML_NAMESPACE_SVG == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_X ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(maPosition.X, rValue);
		}
		else if( IsXMLToken( rLocalName, XML_Y ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(maPosition.Y, rValue);
		}
		else if( IsXMLToken( rLocalName, XML_WIDTH ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(maSize.Width, rValue);
			if( maSize.Width > 0 )
				maSize.Width += 1;
			else if( maSize.Width < 0 )
				maSize.Width -= 1;
		}
		else if( IsXMLToken( rLocalName, XML_HEIGHT ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(maSize.Height, rValue);
			if( maSize.Height > 0 )
				maSize.Height += 1;
			else if( maSize.Height < 0 )
				maSize.Height -= 1;
		}
		else if( IsXMLToken( rLocalName, XML_TRANSFORM ) )
		{
			// because of #85127# take svg:transform into account and hanle like
			// draw:transform for compatibility
			mnTransform.SetString(rValue, GetImport().GetMM100UnitConverter());
		}

		// #i68101#
		else if( IsXMLToken( rLocalName, XML_TITLE ) )
		{
			maShapeTitle = rValue;
		}
		else if( IsXMLToken( rLocalName, XML_DESC ) )
		{
			maShapeDescription = rValue;
		}
	}
	else if( (XML_NAMESPACE_NONE == nPrefix) || (XML_NAMESPACE_XML == nPrefix) )
	{
		if( IsXMLToken( rLocalName, XML_ID ) )
		{
			maShapeId = rValue;
            bHaveXmlId = true;
        }
    }
}

sal_Bool SdXMLShapeContext::isPresentationShape() const
{
	if( maPresentationClass.getLength() && (const_cast<SdXMLShapeContext*>(this))->GetImport().GetShapeImport()->IsPresentationShapesSupported() )
	{
		if(XML_STYLE_FAMILY_SD_PRESENTATION_ID == mnStyleFamily)
		{
			return sal_True;
		}

		if( IsXMLToken( maPresentationClass, XML_HEADER ) || IsXMLToken( maPresentationClass, XML_FOOTER ) ||
			IsXMLToken( maPresentationClass, XML_PAGE_NUMBER ) || IsXMLToken( maPresentationClass, XML_DATE_TIME ) )
		{
			return sal_True;
		}
	}

	return sal_False;
}

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

TYPEINIT1( SdXMLRectShapeContext, SdXMLShapeContext );

SdXMLRectShapeContext::SdXMLRectShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
	mnRadius( 0L )
{
}

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

SdXMLRectShapeContext::~SdXMLRectShapeContext()
{
}

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

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLRectShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	if( XML_NAMESPACE_DRAW == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_CORNER_RADIUS ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(mnRadius, rValue);
			return;
		}
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

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

void SdXMLRectShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	// create rectangle shape
	AddShape("com.sun.star.drawing.RectangleShape");
	if(mxShape.is())
	{
		// Add, set Style and properties from base shape
		SetStyle();
		SetLayer();

		// set pos, size, shear and rotate
		SetTransformation();

		if(mnRadius)
		{
			uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
			if(xPropSet.is())
			{
				try
				{
					xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CornerRadius")), uno::makeAny( mnRadius ) );
				}
				catch( uno::Exception& )
				{
					DBG_ERROR( "exception during setting of corner radius!");
				}
			}
		}
		SdXMLShapeContext::StartElement(xAttrList);
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////3////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

TYPEINIT1( SdXMLLineShapeContext, SdXMLShapeContext );

SdXMLLineShapeContext::SdXMLLineShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
	mnX1( 0L ),
	mnY1( 0L ),
	mnX2( 1L ),
	mnY2( 1L )
{
}

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

SdXMLLineShapeContext::~SdXMLLineShapeContext()
{
}

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

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLLineShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	if( XML_NAMESPACE_SVG == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_X1 ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(mnX1, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_Y1 ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(mnY1, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_X2 ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(mnX2, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_Y2 ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(mnY2, rValue);
			return;
		}
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

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

void SdXMLLineShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	// #85920# use SetTransformation() to handle import of simple lines.
	// This is necessary to kake into account all anchor positions and
	// other things. All shape imports use the same import schemata now.
	// create necessary shape (Line Shape)
	AddShape("com.sun.star.drawing.PolyLineShape");

	if(mxShape.is())
	{
		// Add, set Style and properties from base shape
		SetStyle();
		SetLayer();

		// get sizes and offsets
		awt::Point aTopLeft(mnX1, mnY1);
		awt::Point aBottomRight(mnX2, mnY2);

		if(mnX1 > mnX2)
		{
			aTopLeft.X = mnX2;
			aBottomRight.X = mnX1;
		}

		if(mnY1 > mnY2)
		{
			aTopLeft.Y = mnY2;
			aBottomRight.Y = mnY1;
		}

		// set local parameters on shape
		uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
		if(xPropSet.is())
		{
			drawing::PointSequenceSequence aPolyPoly(1L);
			drawing::PointSequence* pOuterSequence = aPolyPoly.getArray();
			pOuterSequence->realloc(2L);
			awt::Point* pInnerSequence = pOuterSequence->getArray();
			uno::Any aAny;

			*pInnerSequence = awt::Point( mnX1 - aTopLeft.X, mnY1 - aTopLeft.Y);
			pInnerSequence++;
			*pInnerSequence = awt::Point( mnX2 - aTopLeft.X, mnY2 - aTopLeft.Y);

			aAny <<= aPolyPoly;
			xPropSet->setPropertyValue(
				OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry")), aAny);
		}

		// set sizes for transformation
		maSize.Width = aBottomRight.X - aTopLeft.X;
		maSize.Height = aBottomRight.Y - aTopLeft.Y;
		maPosition.X = aTopLeft.X;
		maPosition.Y = aTopLeft.Y;

		// set pos, size, shear and rotate and get copy of matrix
		SetTransformation();

		SdXMLShapeContext::StartElement(xAttrList);
	}
}

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

TYPEINIT1( SdXMLEllipseShapeContext, SdXMLShapeContext );

SdXMLEllipseShapeContext::SdXMLEllipseShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
	mnCX( 0L ),
	mnCY( 0L ),
	mnRX( 1L ),
	mnRY( 1L ),
	meKind( drawing::CircleKind_FULL ),
	mnStartAngle( 0 ),
	mnEndAngle( 0 )
{
}

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

SdXMLEllipseShapeContext::~SdXMLEllipseShapeContext()
{
}

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

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLEllipseShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	if( XML_NAMESPACE_SVG == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_RX ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(mnRX, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_RY ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(mnRY, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_CX ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(mnCX, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_CY ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(mnCY, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_R ) )
		{
			// single radius, it's a circle and both radii are the same
			GetImport().GetMM100UnitConverter().convertMeasure(mnRX, rValue);
			mnRY = mnRX;
			return;
		}
	}
	else if( XML_NAMESPACE_DRAW == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_KIND ) )
		{
			sal_uInt16 eKind;
			if( SvXMLUnitConverter::convertEnum( eKind, rValue, aXML_CircleKind_EnumMap ) )
			{
				meKind = eKind;
			}
			return;
		}
		if( IsXMLToken( rLocalName, XML_START_ANGLE ) )
		{
			double dStartAngle;
			if( SvXMLUnitConverter::convertDouble( dStartAngle, rValue ) )
				mnStartAngle = (sal_Int32)(dStartAngle * 100.0);
			return;
		}
		if( IsXMLToken( rLocalName, XML_END_ANGLE ) )
		{
			double dEndAngle;
			if( SvXMLUnitConverter::convertDouble( dEndAngle, rValue ) )
				mnEndAngle = (sal_Int32)(dEndAngle * 100.0);
			return;
		}
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

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

void SdXMLEllipseShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	// create rectangle shape
	AddShape("com.sun.star.drawing.EllipseShape");
	if(mxShape.is())
	{
		// Add, set Style and properties from base shape
		SetStyle();
		SetLayer();

        if(mnCX != 0 || mnCY != 0 || mnRX != 1 || mnRY != 1)
        {
            // #121972# center/radius is used, put to pos and size
            maSize.Width = 2 * mnRX;
            maSize.Height = 2 * mnRY;
            maPosition.X = mnCX - mnRX;
            maPosition.Y = mnCY - mnRY;
        }

		// set pos, size, shear and rotate
		SetTransformation();

		if( meKind != drawing::CircleKind_FULL )
		{
			uno::Reference< beans::XPropertySet > xPropSet( mxShape, uno::UNO_QUERY );
			if( xPropSet.is() )
			{
				uno::Any aAny;
				aAny <<= (drawing::CircleKind)meKind;
				xPropSet->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("CircleKind")), aAny );

				aAny <<= mnStartAngle;
				xPropSet->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("CircleStartAngle")), aAny );

				aAny <<= mnEndAngle;
				xPropSet->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("CircleEndAngle")), aAny );
			}
		}

		SdXMLShapeContext::StartElement(xAttrList);
	}
}

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

TYPEINIT1( SdXMLPolygonShapeContext, SdXMLShapeContext );

SdXMLPolygonShapeContext::SdXMLPolygonShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes, sal_Bool bClosed, sal_Bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
	mbClosed( bClosed )
{
}

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

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLPolygonShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	if( XML_NAMESPACE_SVG == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_VIEWBOX ) )
		{
			maViewBox = rValue;
			return;
		}
	}
	else if( XML_NAMESPACE_DRAW == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_POINTS ) )
		{
			maPoints = rValue;
			return;
		}
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

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

SdXMLPolygonShapeContext::~SdXMLPolygonShapeContext()
{
}

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

void SdXMLPolygonShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	// Add, set Style and properties from base shape
	if(mbClosed)
		AddShape("com.sun.star.drawing.PolyPolygonShape");
	else
		AddShape("com.sun.star.drawing.PolyLineShape");

	if( mxShape.is() )
	{
		SetStyle();
		SetLayer();

		// set local parameters on shape
		uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
		if(xPropSet.is())
		{
			// set polygon
			if(maPoints.getLength() && maViewBox.getLength())
			{
				SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter());
				awt::Size aSize(aViewBox.GetWidth(), aViewBox.GetHeight());
				if (maSize.Width != 0 && maSize.Height !=0)
				{
					aSize = maSize;
				}
				awt::Point aPosition(aViewBox.GetX(), aViewBox.GetY());
				SdXMLImExPointsElement aPoints(maPoints, aViewBox,
					aPosition, aSize, GetImport().GetMM100UnitConverter());

				uno::Any aAny;
				aAny <<= aPoints.GetPointSequenceSequence();
				xPropSet->setPropertyValue(
					OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry")), aAny);
			}
		}

		// set pos, size, shear and rotate and get copy of matrix
		SetTransformation();

		SdXMLShapeContext::StartElement(xAttrList);
	}
}

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

TYPEINIT1( SdXMLPathShapeContext, SdXMLShapeContext );

SdXMLPathShapeContext::SdXMLPathShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
	mbClosed( sal_True )
{
}

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

SdXMLPathShapeContext::~SdXMLPathShapeContext()
{
}

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

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLPathShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	if( XML_NAMESPACE_SVG == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_VIEWBOX ) )
		{
			maViewBox = rValue;
			return;
		}
		else if( IsXMLToken( rLocalName, XML_D ) )
		{
			maD = rValue;
			return;
		}
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

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

void SdXMLPathShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	// create polygon shape
	if(maD.getLength())
	{
		// prepare some of the parameters
		SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter());
		awt::Size aSize(aViewBox.GetWidth(), aViewBox.GetHeight());
		awt::Point aPosition(aViewBox.GetX(), aViewBox.GetY());
		if (maSize.Width != 0 && maSize.Height !=0)
		{
			aSize = maSize;
		}
		SdXMLImExSvgDElement aPoints(maD, aViewBox,
			aPosition, aSize, GetImport().GetMM100UnitConverter());

		const char* pService;
		// now create shape
		if(aPoints.IsCurve())
		{
			if(aPoints.IsClosed())
			{
				pService = "com.sun.star.drawing.ClosedBezierShape";
			}
			else
			{
				pService = "com.sun.star.drawing.OpenBezierShape";
			}
		}
		else
		{
			if(aPoints.IsClosed())
			{
				pService = "com.sun.star.drawing.PolyPolygonShape";
			}
			else
			{
				pService = "com.sun.star.drawing.PolyLineShape";
			}
		}

		// Add, set Style and properties from base shape
		AddShape(pService);

		// #89344# test for mxShape.is() and not for mxShapes.is() to support
		// shape import helper classes WITHOUT XShapes (member mxShapes). This
		// is used by the writer.
		if( mxShape.is() )
		{
			SetStyle();
			SetLayer();

			// set local parameters on shape
			uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
			if(xPropSet.is())
			{
				uno::Any aAny;

				// set svg:d
				if(maD.getLength())
				{
					if(aPoints.IsCurve())
					{
						drawing::PolyPolygonBezierCoords aSourcePolyPolygon(
							aPoints.GetPointSequenceSequence(),
							aPoints.GetFlagSequenceSequence());

						aAny <<= aSourcePolyPolygon;
						xPropSet->setPropertyValue(
							OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry")), aAny);
					}
					else
					{
						aAny <<= aPoints.GetPointSequenceSequence();
						xPropSet->setPropertyValue(
							OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry")), aAny);
					}
				}
			}

			// set pos, size, shear and rotate
			SetTransformation();

			SdXMLShapeContext::StartElement(xAttrList);
		}
	}
}

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

TYPEINIT1( SdXMLTextBoxShapeContext, SdXMLShapeContext );

SdXMLTextBoxShapeContext::SdXMLTextBoxShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
	mnRadius(0)
{
}

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

SdXMLTextBoxShapeContext::~SdXMLTextBoxShapeContext()
{
}

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

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLTextBoxShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	if( XML_NAMESPACE_DRAW == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_CORNER_RADIUS ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(mnRadius, rValue);
			return;
		}
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

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

void SdXMLTextBoxShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>&)
{
	// create textbox shape
	sal_Bool bIsPresShape = sal_False;
	bool bClearText = false;

	const char *pService = NULL;

	if( isPresentationShape() )
	{
		// check if the current document supports presentation shapes
		if( GetImport().GetShapeImport()->IsPresentationShapesSupported() )
		{
			if( IsXMLToken( maPresentationClass, XML_PRESENTATION_SUBTITLE ))
			{
				// XmlShapeTypePresSubtitleShape
				pService = "com.sun.star.presentation.SubtitleShape";
			}
			else if( IsXMLToken( maPresentationClass, XML_PRESENTATION_OUTLINE ) )
			{
				// XmlShapeTypePresOutlinerShape
				pService = "com.sun.star.presentation.OutlinerShape";
			}
			else if( IsXMLToken( maPresentationClass, XML_PRESENTATION_NOTES ) )
			{
				// XmlShapeTypePresNotesShape
				pService = "com.sun.star.presentation.NotesShape";
			}
			else if( IsXMLToken( maPresentationClass, XML_HEADER ) )
			{
				// XmlShapeTypePresHeaderShape
				pService = "com.sun.star.presentation.HeaderShape";
				bClearText = true;
			}
			else if( IsXMLToken( maPresentationClass, XML_FOOTER ) )
			{
				// XmlShapeTypePresFooterShape
				pService = "com.sun.star.presentation.FooterShape";
				bClearText = true;
			}
			else if( IsXMLToken( maPresentationClass, XML_PAGE_NUMBER ) )
			{
				// XmlShapeTypePresSlideNumberShape
				pService = "com.sun.star.presentation.SlideNumberShape";
				bClearText = true;
			}
			else if( IsXMLToken( maPresentationClass, XML_DATE_TIME ) )
			{
				// XmlShapeTypePresDateTimeShape
				pService = "com.sun.star.presentation.DateTimeShape";
				bClearText = true;
			}
			else //  IsXMLToken( maPresentationClass, XML_PRESENTATION_TITLE ) )
			{
				// XmlShapeTypePresTitleTextShape
				pService = "com.sun.star.presentation.TitleTextShape";
			}
			bIsPresShape = sal_True;
		}
	}

	if( NULL == pService )
	{
		// normal text shape
		pService = "com.sun.star.drawing.TextShape";
	}

	// Add, set Style and properties from base shape
	AddShape(pService);

	if( mxShape.is() )
	{
		SetStyle();
		SetLayer();

		if(bIsPresShape)
		{
			uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
			if(xProps.is())
			{
				uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
				if( xPropsInfo.is() )
				{
					if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") )))
						xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") ), ::cppu::bool2any( sal_False ) );

					if( mbIsUserTransformed && xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent") )))
						xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent") ), ::cppu::bool2any( sal_False ) );
				}
			}
		}

		if( bClearText )
		{
			uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
			OUString aEmpty;
			xText->setString( aEmpty );
		}

		// set parameters on shape
//A AW->CL: Eventually You need to strip scale and translate from the transformation
//A to reach the same goal again.
//A		if(!bIsPresShape || mbIsUserTransformed)
//A		{
//A			// set pos and size on shape, this should remove binding
//A			// to pres object on masterpage
//A			SetSizeAndPosition();
//A		}

		// set pos, size, shear and rotate
		SetTransformation();

		if(mnRadius)
		{
			uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
			if(xPropSet.is())
			{
				try
				{
					xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CornerRadius")), uno::makeAny( mnRadius ) );
				}
				catch( uno::Exception& )
				{
					DBG_ERROR( "exception during setting of corner radius!");
				}
			}
		}

		SdXMLShapeContext::StartElement(mxAttrList);
	}
}

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

TYPEINIT1( SdXMLControlShapeContext, SdXMLShapeContext );

SdXMLControlShapeContext::SdXMLControlShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape )
{
}

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

SdXMLControlShapeContext::~SdXMLControlShapeContext()
{
}

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

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLControlShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	if( XML_NAMESPACE_DRAW == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_CONTROL ) )
		{
			maFormId = rValue;
			return;
		}
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

void SdXMLControlShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	// create Control shape
	// add, set style and properties from base shape
	AddShape("com.sun.star.drawing.ControlShape");
	if( mxShape.is() )
	{
		DBG_ASSERT( maFormId.getLength(), "draw:control without a form:id attribute!" );
		if( maFormId.getLength() )
		{
#ifndef SVX_LIGHT
			if( GetImport().IsFormsSupported() )
			{
				uno::Reference< awt::XControlModel > xControlModel( GetImport().GetFormImport()->lookupControl( maFormId ), uno::UNO_QUERY );
				if( xControlModel.is() )
				{
					uno::Reference< drawing::XControlShape > xControl( mxShape, uno::UNO_QUERY );
					if( xControl.is() )
						xControl->setControl(  xControlModel );

				}
			}
#endif // #ifndef SVX_LIGHT
		}

		SetStyle();
		SetLayer();

		// set pos, size, shear and rotate
		SetTransformation();

		SdXMLShapeContext::StartElement(xAttrList);
	}
}

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

TYPEINIT1( SdXMLConnectorShapeContext, SdXMLShapeContext );

SdXMLConnectorShapeContext::SdXMLConnectorShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
	maStart(0,0),
	maEnd(1,1),
	mnType( (sal_uInt16)drawing::ConnectorType_STANDARD ),
	mnStartGlueId(-1),
	mnEndGlueId(-1),
	mnDelta1(0),
	mnDelta2(0),
	mnDelta3(0)
{
}

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

SdXMLConnectorShapeContext::~SdXMLConnectorShapeContext()
{
}

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

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLConnectorShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	switch( nPrefix )
	{
	case XML_NAMESPACE_DRAW:
	{
		if( IsXMLToken( rLocalName, XML_START_SHAPE ) )
		{
			maStartShapeId = rValue;
			return;
		}
		if( IsXMLToken( rLocalName, XML_START_GLUE_POINT ) )
		{
			mnStartGlueId = rValue.toInt32();
			return;
		}
		if( IsXMLToken( rLocalName, XML_END_SHAPE ) )
		{
			maEndShapeId = rValue;
			return;
		}
		if( IsXMLToken( rLocalName, XML_END_GLUE_POINT ) )
		{
			mnEndGlueId = rValue.toInt32();
			return;
		}
		if( IsXMLToken( rLocalName, XML_LINE_SKEW ) )
		{
			SvXMLTokenEnumerator aTokenEnum( rValue );
			OUString aToken;
			if( aTokenEnum.getNextToken( aToken ) )
			{
				GetImport().GetMM100UnitConverter().convertMeasure(mnDelta1, aToken);
				if( aTokenEnum.getNextToken( aToken ) )
				{
					GetImport().GetMM100UnitConverter().convertMeasure(mnDelta2, aToken);
					if( aTokenEnum.getNextToken( aToken ) )
					{
						GetImport().GetMM100UnitConverter().convertMeasure(mnDelta3, aToken);
					}
				}
			}
			return;
		}
		if( IsXMLToken( rLocalName, XML_TYPE ) )
		{
			SvXMLUnitConverter::convertEnum( mnType, rValue, aXML_ConnectionKind_EnumMap );
			return;
		}
        // #121965# draw:transform may be used in ODF1.2, e.g. exports from MS seem to use these
		else if( IsXMLToken( rLocalName, XML_TRANSFORM ) )
		{
			mnTransform.SetString(rValue, GetImport().GetMM100UnitConverter());
		}
	}
	case XML_NAMESPACE_SVG:
	{
		if( IsXMLToken( rLocalName, XML_X1 ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(maStart.X, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_Y1 ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(maStart.Y, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_X2 ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(maEnd.X, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_Y2 ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(maEnd.Y, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_D ) )
		{
			SdXMLImExViewBox aViewBox( 0, 0, 1, 1 );
			awt::Point aPoint( 0, 0 );
			awt::Size aSize( 1, 1 );		
			
			SdXMLImExSvgDElement aPoints( rValue, aViewBox,
				aPoint, aSize, GetImport().GetMM100UnitConverter() );

			if ( aPoints.IsCurve() )
			{
				drawing::PolyPolygonBezierCoords aSourcePolyPolygon(
					aPoints.GetPointSequenceSequence(),
					aPoints.GetFlagSequenceSequence());
				maPath <<= aSourcePolyPolygon;
			}
			else
			{
				const drawing::PointSequenceSequence& rOuterSeq = aPoints.GetPointSequenceSequence();
				drawing::FlagSequenceSequence aFlagSeqSeq( rOuterSeq.getLength() );
				for ( int a = 0; a < rOuterSeq.getLength(); a++ )
					aFlagSeqSeq[ a ] = drawing::FlagSequence( rOuterSeq[ a ].getLength() );

				drawing::PolyPolygonBezierCoords aSourcePolyPolygon(
					aPoints.GetPointSequenceSequence(),
					aFlagSeqSeq );
				maPath <<= aSourcePolyPolygon;
			}
		}
	}
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

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

void SdXMLConnectorShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	// #107928#
	// For security reasons, do not add empty connectors. There may have been an error in EA2
	// that created empty, far set off connectors (e.g. 63 meters below top of document). This
	// is not guaranteed, but it's definitely safe to not add empty connectors.
	sal_Bool bDoAdd(sal_True);

	if(    0 == maStartShapeId.getLength()
		&& 0 == maEndShapeId.getLength()
		&& maStart.X == maEnd.X
		&& maStart.Y == maEnd.Y
		&& 0 == mnDelta1
		&& 0 == mnDelta2
		&& 0 == mnDelta3
		)
	{
		bDoAdd = sal_False;
	}

	if(bDoAdd)
	{
		// create Connector shape
		// add, set style and properties from base shape
		AddShape("com.sun.star.drawing.ConnectorShape");
		if(mxShape.is())
		{
            // #121965# if draw:transform is used, apply directly to the start
            // and end positions before using these
            if(mnTransform.NeedsAction())
            {
                // transformation is used, apply to object.
                ::basegfx::B2DHomMatrix aMat;
                mnTransform.GetFullTransform(aMat);

                if(!aMat.isIdentity())
                {
                    basegfx::B2DPoint aStart(maStart.X, maStart.Y);
                    basegfx::B2DPoint aEnd(maEnd.X, maEnd.Y);

                    aStart = aMat * aStart;
                    aEnd = aMat * aEnd;

                    maStart.X = basegfx::fround(aStart.getX());
                    maStart.Y = basegfx::fround(aStart.getY());
                    maEnd.X = basegfx::fround(aEnd.getX());
                    maEnd.Y = basegfx::fround(aEnd.getY());
                }
            }

            // add connection ids
			if( maStartShapeId.getLength() )
				GetImport().GetShapeImport()->addShapeConnection( mxShape, sal_True, maStartShapeId, mnStartGlueId );
			if( maEndShapeId.getLength() )
				GetImport().GetShapeImport()->addShapeConnection( mxShape, sal_False, maEndShapeId, mnEndGlueId );

			uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
			if( xProps.is() )
			{
				uno::Any aAny;
				aAny <<= maStart;
				xProps->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("StartPosition")), aAny);

				aAny <<= maEnd;
				xProps->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EndPosition")), aAny );

				aAny <<= (drawing::ConnectorType)mnType;
				xProps->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EdgeKind")), aAny );

				aAny <<= mnDelta1;
				xProps->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EdgeLine1Delta")), aAny );

				aAny <<= mnDelta2;
				xProps->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EdgeLine2Delta")), aAny );

				aAny <<= mnDelta3;
				xProps->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EdgeLine3Delta")), aAny );
			}
			SetStyle();
			SetLayer();

			if ( maPath.hasValue() )
            {
                // --> OD #i115492#
                // Ignore svg:d attribute for text documents created by OpenOffice.org 
                // versions before OOo 3.3, because these OOo versions are storing
                // svg:d values not using the correct unit.
                bool bApplySVGD( true );
                if ( uno::Reference< text::XTextDocument >(GetImport().GetModel(), uno::UNO_QUERY).is() )
                {
                    sal_Int32 nUPD( 0 );
                    sal_Int32 nBuild( 0 );
                    const bool bBuildIdFound = GetImport().getBuildIds( nUPD, nBuild );
                    if ( GetImport().IsTextDocInOOoFileFormat() ||
                         ( bBuildIdFound &&
                           ( ( nUPD == 641 ) || ( nUPD == 645 ) ||  // prior OOo 2.0
                             ( nUPD == 680 ) ||                     // OOo 2.x
                             ( nUPD == 300 ) ||                     // OOo 3.0 - OOo 3.0.1
                             ( nUPD == 310 ) ||                     // OOo 3.1 - OOo 3.1.1
                             ( nUPD == 320 ) ) ) )                  // OOo 3.2 - OOo 3.2.1
                    {
                        bApplySVGD = false;
                    }    
                }            

                if ( bApplySVGD )
                {
                    xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("PolyPolygonBezier") ), maPath );
                }                                                                                        
                // <--
            }

			SdXMLShapeContext::StartElement(xAttrList);
		}
	}
}

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

TYPEINIT1( SdXMLMeasureShapeContext, SdXMLShapeContext );

SdXMLMeasureShapeContext::SdXMLMeasureShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
	maStart(0,0),
	maEnd(1,1)
{
}

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

SdXMLMeasureShapeContext::~SdXMLMeasureShapeContext()
{
}

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLMeasureShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	switch( nPrefix )
	{
	case XML_NAMESPACE_SVG:
	{
		if( IsXMLToken( rLocalName, XML_X1 ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(maStart.X, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_Y1 ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(maStart.Y, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_X2 ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(maEnd.X, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_Y2 ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(maEnd.Y, rValue);
			return;
		}
	}
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

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

void SdXMLMeasureShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	// create Measure shape
	// add, set style and properties from base shape
	AddShape("com.sun.star.drawing.MeasureShape");
	if(mxShape.is())
	{
		SetStyle();
		SetLayer();

		uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
		if( xProps.is() )
		{
			uno::Any aAny;
			aAny <<= maStart;
			xProps->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("StartPosition")), aAny);

			aAny <<= maEnd;
			xProps->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EndPosition")), aAny );
		}

		// delete pre created fields
		uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
		if( xText.is() )
		{
			const OUString aEmpty( RTL_CONSTASCII_USTRINGPARAM( " " ) );
			xText->setString( aEmpty );
		}

		SdXMLShapeContext::StartElement(xAttrList);
	}
}

void SdXMLMeasureShapeContext::EndElement()
{
	do
	{
		// delete pre created fields
		uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
		if( !xText.is() )
			break;

		uno::Reference< text::XTextCursor > xCursor( xText->createTextCursor() );
		if( !xCursor.is() )
			break;

		const OUString aEmpty;
		xCursor->collapseToStart();
		xCursor->goRight( 1, sal_True );
		xCursor->setString( aEmpty );
	}
	while(0);

	SdXMLShapeContext::EndElement();
}

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

TYPEINIT1( SdXMLPageShapeContext, SdXMLShapeContext );

SdXMLPageShapeContext::SdXMLPageShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ), mnPageNumber(0)
{
	mbClearDefaultAttributes = false;
}

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

SdXMLPageShapeContext::~SdXMLPageShapeContext()
{
}

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

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLPageShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	if( XML_NAMESPACE_DRAW == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_PAGE_NUMBER ) )
		{
			mnPageNumber = rValue.toInt32();
			return;
		}
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

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

void SdXMLPageShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	// create Page shape
	// add, set style and properties from base shape

	// #86163# take into account which type of PageShape needs to
	// be constructed. It's an pres shape if presentation:XML_CLASS == XML_PRESENTATION_PAGE.
	sal_Bool bIsPresentation = maPresentationClass.getLength() &&
		   GetImport().GetShapeImport()->IsPresentationShapesSupported();

	uno::Reference< lang::XServiceInfo > xInfo( mxShapes, uno::UNO_QUERY );
	const sal_Bool bIsOnHandoutPage = xInfo.is() && xInfo->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.HandoutMasterPage")) );

	if( bIsOnHandoutPage )
	{
		AddShape("com.sun.star.presentation.HandoutShape");
	}
	else
	{
		if(bIsPresentation && !IsXMLToken( maPresentationClass, XML_PRESENTATION_PAGE ) )
		{
			bIsPresentation = sal_False;
		}

		if(bIsPresentation)
		{
			AddShape("com.sun.star.presentation.PageShape");
		}
		else
		{
			AddShape("com.sun.star.drawing.PageShape");
		}
	}

	if(mxShape.is())
	{
		SetStyle();
		SetLayer();

		// set pos, size, shear and rotate
		SetTransformation();

		uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
		if(xPropSet.is())
		{
			uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
			const OUString aPageNumberStr(RTL_CONSTASCII_USTRINGPARAM("PageNumber"));
			if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(aPageNumberStr))
				xPropSet->setPropertyValue(aPageNumberStr, uno::makeAny( mnPageNumber ));
		}

		SdXMLShapeContext::StartElement(xAttrList);
	}
}

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

TYPEINIT1( SdXMLCaptionShapeContext, SdXMLShapeContext );

SdXMLCaptionShapeContext::SdXMLCaptionShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
	// #86616# for correct edge rounding import mnRadius needs to be initialized
	mnRadius( 0L )
{
}

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

SdXMLCaptionShapeContext::~SdXMLCaptionShapeContext()
{
}

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

void SdXMLCaptionShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	// create Caption shape
	// add, set style and properties from base shape
	AddShape("com.sun.star.drawing.CaptionShape");
	if( mxShape.is() )
	{
		SetStyle();
		SetLayer();

		uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );

		// SJ: If AutoGrowWidthItem is set, SetTransformation will lead to the wrong SnapRect
		// because NbcAdjustTextFrameWidthAndHeight() is called (text is set later and center alignment 
		// is the default setting, so the top left reference point that is used by the caption point is
		// no longer correct) There are two ways to solve this problem, temporarily disabling the
		// autogrowwith as we are doing here or to apply the CaptionPoint after setting text
		sal_Bool bIsAutoGrowWidth = sal_False;
		if ( xProps.is() )
		{
			uno::Any aAny( xProps->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("TextAutoGrowWidth") ) ) );
			aAny >>= bIsAutoGrowWidth;

			if ( bIsAutoGrowWidth )
				xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("TextAutoGrowWidth")), uno::makeAny( sal_False ) );
		}
			
		// set pos, size, shear and rotate
		SetTransformation();
		if( xProps.is() )
			xProps->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CaptionPoint")), uno::makeAny( maCaptionPoint ) );

		if ( bIsAutoGrowWidth )
			xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("TextAutoGrowWidth")), uno::makeAny( sal_True ) );

		if(mnRadius)
		{
			uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
			if(xPropSet.is())
			{
				try
				{
					xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CornerRadius")), uno::makeAny( mnRadius ) );
				}
				catch( uno::Exception& )
				{
					DBG_ERROR( "exception during setting of corner radius!");
				}
			}
		}

		SdXMLShapeContext::StartElement(xAttrList);
	}
}

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLCaptionShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	if( XML_NAMESPACE_DRAW == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_CAPTION_POINT_X ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(maCaptionPoint.X, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_CAPTION_POINT_Y ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(maCaptionPoint.Y, rValue);
			return;
		}
		if( IsXMLToken( rLocalName, XML_CORNER_RADIUS ) )
		{
			GetImport().GetMM100UnitConverter().convertMeasure(mnRadius, rValue);
			return;
		}
	}
	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

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

TYPEINIT1( SdXMLGraphicObjectShapeContext, SdXMLShapeContext );

SdXMLGraphicObjectShapeContext::SdXMLGraphicObjectShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
	maURL(),
    mbLateAddToIdentifierMapper(false)
{
}

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

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLGraphicObjectShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	if( XML_NAMESPACE_XLINK == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_HREF ) )
		{
			maURL = rValue;
			return;
		}
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

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

void SdXMLGraphicObjectShapeContext::StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& )
{
	// create graphic object shape
	const char *pService;

	if( IsXMLToken( maPresentationClass, XML_GRAPHIC ) && GetImport().GetShapeImport()->IsPresentationShapesSupported() )
	{
		pService = "com.sun.star.presentation.GraphicObjectShape";
	}
	else
	{
		pService = "com.sun.star.drawing.GraphicObjectShape";
	}

	AddShape( pService );

	if(mxShape.is())
	{
		SetStyle();
		SetLayer();

		uno::Reference< beans::XPropertySet > xPropset(mxShape, uno::UNO_QUERY);
		if(xPropset.is())
		{
			// since OOo 1.x had no line or fill style for graphics, but may create
			// documents with them, we have to override them here
			sal_Int32 nUPD, nBuildId;
			if( GetImport().getBuildIds( nUPD, nBuildId ) && (nUPD == 645) ) try
			{
				xPropset->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("FillStyle")), Any( FillStyle_NONE ) );
				xPropset->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("LineStyle")), Any( LineStyle_NONE ) );
			}
			catch( Exception& )
			{
			}

			uno::Reference< beans::XPropertySetInfo > xPropsInfo( xPropset->getPropertySetInfo() );
			if( xPropsInfo.is() && xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") )))
				xPropset->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") ), ::cppu::bool2any( mbIsPlaceholder ) );

			if( !mbIsPlaceholder )
			{
				if( maURL.getLength() )
				{
					uno::Any aAny;
					aAny <<= GetImport().ResolveGraphicObjectURL( maURL, GetImport().isGraphicLoadOnDemandSupported() );
					try
					{
						xPropset->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicURL") ), aAny );
						xPropset->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicStreamURL") ), aAny );
					}
					catch (lang::IllegalArgumentException const &)
					{
					}
				}
			}
		}

		if(mbIsUserTransformed)
		{
			uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
			if(xProps.is())
			{
				uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
				if( xPropsInfo.is() )
				{
					if( xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent") )))
						xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent") ), ::cppu::bool2any( sal_False ) );
				}
			}
		}

		// set pos, size, shear and rotate
		SetTransformation();

		SdXMLShapeContext::StartElement(mxAttrList);
	}
}

void SdXMLGraphicObjectShapeContext::EndElement()
{
	if( mxBase64Stream.is() )
	{
		OUString sURL( GetImport().ResolveGraphicObjectURLFromBase64( mxBase64Stream ) );
		if( sURL.getLength() )
		{
			try
			{
				uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
				if(xProps.is())
				{
					const uno::Any aAny( uno::makeAny( sURL ) );
					xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicURL") ), aAny );
					xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicStreamURL") ), aAny );
				}
			}
			catch (lang::IllegalArgumentException const &)
			{
			}
		}
	}

	SdXMLShapeContext::EndElement();
}


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

SvXMLImportContext* SdXMLGraphicObjectShapeContext::CreateChildContext(
	sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName,
	const uno::Reference<xml::sax::XAttributeList>& xAttrList )
{
	SvXMLImportContext* pContext = NULL;

	if( (XML_NAMESPACE_OFFICE == nPrefix) &&
			 xmloff::token::IsXMLToken( rLocalName, xmloff::token::XML_BINARY_DATA ) )
	{
		if( !maURL.getLength() && !mxBase64Stream.is() )
		{
			mxBase64Stream = GetImport().GetStreamForGraphicObjectURLFromBase64();
			if( mxBase64Stream.is() )
				pContext = new XMLBase64ImportContext( GetImport(), nPrefix,
													rLocalName, xAttrList,
													mxBase64Stream );
		}
	}

	// delegate to parent class if no context could be created
	if ( NULL == pContext )
		pContext = SdXMLShapeContext::CreateChildContext(nPrefix, rLocalName,
														 xAttrList);

	return pContext;
}

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

SdXMLGraphicObjectShapeContext::~SdXMLGraphicObjectShapeContext()
{

}

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

TYPEINIT1( SdXMLChartShapeContext, SdXMLShapeContext );

SdXMLChartShapeContext::SdXMLChartShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
	mpChartContext( NULL )
{
}

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

SdXMLChartShapeContext::~SdXMLChartShapeContext()
{
	if( mpChartContext )
		delete mpChartContext;
}

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

void SdXMLChartShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	const sal_Bool bIsPresentation = isPresentationShape();

	AddShape( bIsPresentation ? "com.sun.star.presentation.ChartShape" : "com.sun.star.drawing.OLE2Shape" );

	if(mxShape.is())
	{
		SetStyle();
		SetLayer();

		if( !mbIsPlaceholder )
		{
			uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
			if(xProps.is())
			{
				uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
				if( xPropsInfo.is() && xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") )))
					xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") ), ::cppu::bool2any( sal_False ) );

				uno::Any aAny;

				const OUString aCLSID( RTL_CONSTASCII_USTRINGPARAM("12DCAE26-281F-416F-a234-c3086127382e"));

				aAny <<= aCLSID;
				xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("CLSID") ), aAny );

#ifndef SVX_LIGHT
				aAny = xProps->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("Model") ) );
				uno::Reference< frame::XModel > xChartModel;
				if( aAny >>= xChartModel )
				{
					mpChartContext = GetImport().GetChartImport()->CreateChartContext( GetImport(), XML_NAMESPACE_SVG, GetXMLToken(XML_CHART), xChartModel, xAttrList );
				}
#endif
			}
		}

		if(mbIsUserTransformed)
		{
			uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
			if(xProps.is())
			{
				uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
				if( xPropsInfo.is() )
				{
					if( xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent") )))
						xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent") ), ::cppu::bool2any( sal_False ) );
				}
			}
		}


		// set pos, size, shear and rotate
		SetTransformation();

		SdXMLShapeContext::StartElement(xAttrList);

		if( mpChartContext )
			mpChartContext->StartElement( xAttrList );
	}
}

void SdXMLChartShapeContext::EndElement()
{
	if( mpChartContext )
		mpChartContext->EndElement();

	SdXMLShapeContext::EndElement();
}

void SdXMLChartShapeContext::Characters( const ::rtl::OUString& rChars )
{
	if( mpChartContext )
		mpChartContext->Characters( rChars );
}

SvXMLImportContext * SdXMLChartShapeContext::CreateChildContext( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName,
		const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList )
{
	if( mpChartContext )
		return mpChartContext->CreateChildContext( nPrefix, rLocalName, xAttrList );

	return NULL;
}

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

TYPEINIT1( SdXMLObjectShapeContext, SdXMLShapeContext );

SdXMLObjectShapeContext::SdXMLObjectShapeContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
		const rtl::OUString& rLocalName,
		const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
		com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rShapes,
        sal_Bool bTemporaryShape)
: SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape )
{
}

SdXMLObjectShapeContext::~SdXMLObjectShapeContext()
{
}

void SdXMLObjectShapeContext::StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& )
{
	// #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
	//if( !mbIsPlaceholder && ImpIsEmptyURL(maHref) )
	//	return;

	// #100592# this BugFix prevents that a shape is created. CL
	// is thinking about an alternative.
    // #i13140# Check for more than empty string in maHref, there are
    // other possibilities that maHref results in empty container
    // storage names
	if( !(GetImport().getImportFlags() & IMPORT_EMBEDDED) && !mbIsPlaceholder && ImpIsEmptyURL(maHref) )
		return;

	const char* pService = "com.sun.star.drawing.OLE2Shape";

	sal_Bool bIsPresShape = maPresentationClass.getLength() && GetImport().GetShapeImport()->IsPresentationShapesSupported();

	if( bIsPresShape )
	{
		if( IsXMLToken( maPresentationClass, XML_PRESENTATION_CHART ) )
		{
			pService = "com.sun.star.presentation.ChartShape";
		}
		else if( IsXMLToken( maPresentationClass, XML_PRESENTATION_TABLE ) )
		{
			pService = "com.sun.star.presentation.CalcShape";
		}
		else if( IsXMLToken( maPresentationClass, XML_PRESENTATION_OBJECT ) )
		{
			pService = "com.sun.star.presentation.OLE2Shape";
		}
	}

	AddShape( pService );

	if( mxShape.is() )
	{
		SetLayer();

		if(bIsPresShape)
		{
			uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
			if(xProps.is())
			{
				uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
				if( xPropsInfo.is() )
				{
					if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") )))
						xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") ), ::cppu::bool2any( sal_False ) );

					if( mbIsUserTransformed && xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent") )))
						xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent") ), ::cppu::bool2any( sal_False ) );
				}
			}
		}

		if( !mbIsPlaceholder && maHref.getLength() )
		{
        	uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );

            if( xProps.is() )
        	{
				OUString aPersistName = GetImport().ResolveEmbeddedObjectURL( maHref, maCLSID );

				if ( GetImport().IsPackageURL( maHref ) )
				{
					const OUString  sURL(RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.EmbeddedObject:" ));

					if ( aPersistName.compareTo( sURL, sURL.getLength() ) == 0 )
						aPersistName = aPersistName.copy( sURL.getLength() );

        			xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "PersistName" ) ),
											  uno::makeAny( aPersistName ) );
				}
				else
				{
					// this is OOo link object
					xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "LinkURL" ) ),
											  uno::makeAny( aPersistName ) );
				}
			}
		}

		// set pos, size, shear and rotate
		SetTransformation();

		SetStyle();

		GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
	}
}

void SdXMLObjectShapeContext::EndElement()
{
    // #i67705#
    const sal_uInt16 nGeneratorVersion(GetImport().getGeneratorVersion());

    if(nGeneratorVersion < SvXMLImport::OOo_34x)
    {
        // #i118485#
        // If it's an old file from us written before OOo3.4, we need to correct
        // FillStyle and LineStyle for OLE2 objects. The error was that the old paint
        // implementations just ignored added fill/linestyles completely, thus
        // those objects need to be corrected to not show blue and hairline which
        // always was the default, but would be shown now
		uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);

        if( xProps.is() )
        {
            xProps->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillStyle")), uno::makeAny(drawing::FillStyle_NONE));
            xProps->setPropertyValue(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("LineStyle")), uno::makeAny(drawing::LineStyle_NONE));
        }
    }

    // #100592#
	if( mxBase64Stream.is() )
	{
		OUString aPersistName( GetImport().ResolveEmbeddedObjectURLFromBase64() );
		const OUString  sURL(RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.EmbeddedObject:" ));

        aPersistName = aPersistName.copy( sURL.getLength() );

		uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
		if( xProps.is() )
			xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "PersistName" ) ), uno::makeAny( aPersistName ) );
	}

	SdXMLShapeContext::EndElement();
}

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLObjectShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	switch( nPrefix )
	{
	case XML_NAMESPACE_DRAW:
		if( IsXMLToken( rLocalName, XML_CLASS_ID ) )
		{
			maCLSID = rValue;
			return;
		}
		break;
	case XML_NAMESPACE_XLINK:
		if( IsXMLToken( rLocalName, XML_HREF ) )
		{
			maHref = rValue;
			return;
		}
		break;
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

SvXMLImportContext* SdXMLObjectShapeContext::CreateChildContext(
	sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName,
	const uno::Reference<xml::sax::XAttributeList>& xAttrList )
{
	// #100592#
	SvXMLImportContext* pContext = NULL;

	if((XML_NAMESPACE_OFFICE == nPrefix) && IsXMLToken(rLocalName, XML_BINARY_DATA))
	{
		mxBase64Stream = GetImport().GetStreamForEmbeddedObjectURLFromBase64();
		if( mxBase64Stream.is() )
			pContext = new XMLBase64ImportContext( GetImport(), nPrefix,
												rLocalName, xAttrList,
												mxBase64Stream );
	}
	else if( ((XML_NAMESPACE_OFFICE == nPrefix) && IsXMLToken(rLocalName, XML_DOCUMENT)) ||
				((XML_NAMESPACE_MATH == nPrefix) && IsXMLToken(rLocalName, XML_MATH)) )
	{
		XMLEmbeddedObjectImportContext *pEContext =
			new XMLEmbeddedObjectImportContext( GetImport(), nPrefix,
												rLocalName, xAttrList );
		maCLSID = pEContext->GetFilterCLSID();
		if( maCLSID.getLength() != 0 )
		{
			uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
			if( xPropSet.is() )
			{
				xPropSet->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("CLSID") ), uno::makeAny( maCLSID ) );

				uno::Reference< lang::XComponent > xComp;
				xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("Model") ) ) >>= xComp;
				DBG_ASSERT( xComp.is(), "no xModel for own OLE format" );
				pEContext->SetComponent( xComp );
			}
		}
		pContext = pEContext;
	}

	// delegate to parent class if no context could be created
	if(!pContext)
		pContext = SdXMLShapeContext::CreateChildContext(nPrefix, rLocalName, xAttrList);

	return pContext;
}

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

TYPEINIT1( SdXMLAppletShapeContext, SdXMLShapeContext );

SdXMLAppletShapeContext::SdXMLAppletShapeContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
		const rtl::OUString& rLocalName,
		const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
		com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rShapes,
        sal_Bool bTemporaryShape)
: SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
  mbIsScript( sal_False )
{
}

SdXMLAppletShapeContext::~SdXMLAppletShapeContext()
{
}

void SdXMLAppletShapeContext::StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& )
{
	const char* pService = "com.sun.star.drawing.AppletShape";
	AddShape( pService );

	if( mxShape.is() )
	{
		SetLayer();

		// set pos, size, shear and rotate
		SetTransformation();
		GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
	}
}

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLAppletShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	switch( nPrefix )
	{
	case XML_NAMESPACE_DRAW:
		if( IsXMLToken( rLocalName, XML_APPLET_NAME ) )
		{
			maAppletName = rValue;
			return;
		}
		if( IsXMLToken( rLocalName, XML_CODE ) )
		{
			maAppletCode = rValue;
			return;
		}
		if( IsXMLToken( rLocalName, XML_MAY_SCRIPT ) )
		{
			mbIsScript = IsXMLToken( rValue, XML_TRUE );
			return;
		}
		break;
	case XML_NAMESPACE_XLINK:
		if( IsXMLToken( rLocalName, XML_HREF ) )
		{
			maHref = GetImport().GetAbsoluteReference(rValue);
			return;
		}
		break;
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

void SdXMLAppletShapeContext::EndElement()
{
	uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
	if( xProps.is() )
	{
		uno::Any aAny;

		if ( maSize.Width && maSize.Height )
		{
			// the visual area for applet must be set on loading
			awt::Rectangle aRect( 0, 0, maSize.Width, maSize.Height );
			aAny <<= aRect;
			xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "VisibleArea" ) ), aAny );
		}
	
		if( maParams.getLength() )
		{
			aAny <<= maParams;
			xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletCommands" ) ), aAny );
		}

		if( maHref.getLength() )
		{
			aAny <<= maHref;
			xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletCodeBase" ) ), aAny );
		}

		if( maAppletName.getLength() )
		{
			aAny <<= maAppletName;
			xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletName" ) ), aAny );
		}

		if( mbIsScript )
		{
			aAny <<= mbIsScript;
			xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletIsScript" ) ), aAny );

		}

		if( maAppletCode.getLength() )
		{
			aAny <<= maAppletCode;
			xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletCode" ) ), aAny );
		}

        aAny <<= ::rtl::OUString( GetImport().GetDocumentBase() );
        xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletDocBase" ) ), aAny );

		SetThumbnail();
	}

	SdXMLShapeContext::EndElement();
}

SvXMLImportContext * SdXMLAppletShapeContext::CreateChildContext( sal_uInt16 p_nPrefix, const ::rtl::OUString& rLocalName, const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList )
{
	if( p_nPrefix == XML_NAMESPACE_DRAW && IsXMLToken( rLocalName, XML_PARAM ) )
	{
		OUString aParamName, aParamValue;
		const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
		// now parse the attribute list and look for draw:name and draw:value
		for(sal_Int16 a(0); a < nAttrCount; a++)
		{
			const OUString& rAttrName = xAttrList->getNameByIndex(a);
			OUString aLocalName;
			sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
			const OUString aValue( xAttrList->getValueByIndex(a) );

			if( nPrefix == XML_NAMESPACE_DRAW )
			{
				if( IsXMLToken( aLocalName, XML_NAME ) )
				{
					aParamName = aValue;
				}
				else if( IsXMLToken( aLocalName, XML_VALUE ) )
				{
					aParamValue = aValue;
				}
			}
		}

		if( aParamName.getLength() )
		{
			sal_Int32 nIndex = maParams.getLength();
			maParams.realloc( nIndex + 1 );
			maParams[nIndex].Name = aParamName;
			maParams[nIndex].Handle = -1;
			maParams[nIndex].Value <<= aParamValue;
			maParams[nIndex].State = beans::PropertyState_DIRECT_VALUE;
		}

		return new SvXMLImportContext( GetImport(), p_nPrefix, rLocalName );
	}

	return SdXMLShapeContext::CreateChildContext( p_nPrefix, rLocalName, xAttrList );
}

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

TYPEINIT1( SdXMLPluginShapeContext, SdXMLShapeContext );

SdXMLPluginShapeContext::SdXMLPluginShapeContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
		const rtl::OUString& rLocalName,
		const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
		com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rShapes,
        sal_Bool bTemporaryShape) :
SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
mbMedia( false )
{
}

SdXMLPluginShapeContext::~SdXMLPluginShapeContext()
{
}

void SdXMLPluginShapeContext::StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList)
{
	// watch for MimeType attribute to see if we have a media object
	for( sal_Int16 n = 0, nAttrCount = ( xAttrList.is() ? xAttrList->getLength() : 0 ); n < nAttrCount; ++n )
	{
		OUString 	aLocalName;
		sal_uInt16 	nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( n ), &aLocalName );

		if( nPrefix == XML_NAMESPACE_DRAW && IsXMLToken( aLocalName, XML_MIME_TYPE ) )
		{
			if( 0 == xAttrList->getValueByIndex( n ).compareToAscii( "application/vnd.sun.star.media" ) )
				mbMedia = true;

			// leave this loop
			n = nAttrCount - 1;
		}
	}

	const char* pService;

	sal_Bool bIsPresShape = sal_False;

	if( mbMedia )
	{
		pService = "com.sun.star.drawing.MediaShape";

		bIsPresShape = maPresentationClass.getLength() && GetImport().GetShapeImport()->IsPresentationShapesSupported();
		if( bIsPresShape )
		{
			if( IsXMLToken( maPresentationClass, XML_PRESENTATION_OBJECT ) )
			{
				pService = "com.sun.star.presentation.MediaShape";
			}
		}
	}
	else
		pService = "com.sun.star.drawing.PluginShape";

	AddShape( pService );

	if( mxShape.is() )
	{
		SetLayer();

		if(bIsPresShape)
		{
			uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
			if(xProps.is())
			{
				uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
				if( xPropsInfo.is() )
				{
					if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") )))
						xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") ), ::cppu::bool2any( sal_False ) );

					if( mbIsUserTransformed && xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent") )))
						xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent") ), ::cppu::bool2any( sal_False ) );
				}
			}
		}

		// set pos, size, shear and rotate
		SetTransformation();
		GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
	}
}

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLPluginShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	switch( nPrefix )
	{
	case XML_NAMESPACE_DRAW:
		if( IsXMLToken( rLocalName, XML_MIME_TYPE ) )
		{
			maMimeType = rValue;
			return;
		}
		break;
	case XML_NAMESPACE_XLINK:
		if( IsXMLToken( rLocalName, XML_HREF ) )
		{
			maHref = GetImport().GetAbsoluteReference(rValue);
			return;
		}
		break;
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

void SdXMLPluginShapeContext::EndElement()
{
	uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );

	if( xProps.is() )
	{
		uno::Any aAny;

		if ( maSize.Width && maSize.Height )
		{
			const rtl::OUString sVisibleArea( RTL_CONSTASCII_USTRINGPARAM( "VisibleArea" ) );
			uno::Reference< beans::XPropertySetInfo > aXPropSetInfo( xProps->getPropertySetInfo() );
            if ( !aXPropSetInfo.is() || aXPropSetInfo->hasPropertyByName( sVisibleArea ) )
			{
				// the visual area for a plugin must be set on loading
				awt::Rectangle aRect( 0, 0, maSize.Width, maSize.Height );
				aAny <<= aRect;
				xProps->setPropertyValue( sVisibleArea, aAny );
			}
		}

		if( !mbMedia )
		{
			// in case we have a plugin object
			if( maParams.getLength() )
			{
				aAny <<= maParams;
				xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "PluginCommands" ) ), aAny );
			}

			if( maMimeType.getLength() )
			{
				aAny <<= maMimeType;
				xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "PluginMimeType" ) ), aAny );
			}

			if( maHref.getLength() )
			{
				aAny <<= maHref;
				xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "PluginURL" ) ), aAny );
			}
		}
		else
		{
			// in case we have a media object
			
			OUString sTempRef;
			
			// check for package URL
			if( GetImport().IsPackageURL( maHref ) )
			{
			    sTempRef = OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.Package:" ) );			    
			}
			
			sTempRef += maHref;
			
			xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaURL" ) ), uno::makeAny( sTempRef ) );

			for( sal_Int32 nParam = 0; nParam < maParams.getLength(); ++nParam )
			{
				const OUString& rName = maParams[ nParam ].Name;

				if( 0 == rName.compareToAscii( "Loop" ) )
				{
					OUString aValueStr;
					maParams[ nParam ].Value >>= aValueStr;
					xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Loop" ) ),
						uno::makeAny( static_cast< sal_Bool >( 0 == aValueStr.compareToAscii( "true" ) ) ) );
				}
				else if( 0 == rName.compareToAscii( "Mute" ) )
				{
					OUString aValueStr;
					maParams[ nParam ].Value >>= aValueStr;
					xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Mute" ) ),
						uno::makeAny( static_cast< sal_Bool >( 0 == aValueStr.compareToAscii( "true" ) ) ) );
				}
				else if( 0 == rName.compareToAscii( "VolumeDB" ) )
				{
					OUString aValueStr;
					maParams[ nParam ].Value >>= aValueStr;
					xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "VolumeDB" ) ),
					                            uno::makeAny( static_cast< sal_Int16 >( aValueStr.toInt32() ) ) );
				}
				else if( 0 == rName.compareToAscii( "Zoom" ) )
				{
					OUString 			aZoomStr;
					media::ZoomLevel	eZoomLevel;

					maParams[ nParam ].Value >>= aZoomStr;

					if( 0 == aZoomStr.compareToAscii( "25%" ) )
						eZoomLevel = media::ZoomLevel_ZOOM_1_TO_4;
					else if( 0 == aZoomStr.compareToAscii( "50%" ) )
						eZoomLevel = media::ZoomLevel_ZOOM_1_TO_2;
					else if( 0 == aZoomStr.compareToAscii( "100%" ) )
						eZoomLevel = media::ZoomLevel_ORIGINAL;
					else if( 0 == aZoomStr.compareToAscii( "200%" ) )
						eZoomLevel = media::ZoomLevel_ZOOM_2_TO_1;
					else if( 0 == aZoomStr.compareToAscii( "400%" ) )
						eZoomLevel = media::ZoomLevel_ZOOM_4_TO_1;
					else if( 0 == aZoomStr.compareToAscii( "fit" ) )
						eZoomLevel = media::ZoomLevel_FIT_TO_WINDOW;
					else if( 0 == aZoomStr.compareToAscii( "fixedfit" ) )
						eZoomLevel = media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT;
					else if( 0 == aZoomStr.compareToAscii( "fullscreen" ) )
						eZoomLevel = media::ZoomLevel_FULLSCREEN;
					else
						eZoomLevel = media::ZoomLevel_NOT_AVAILABLE;

					xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Zoom" ) ), uno::makeAny( eZoomLevel ) );
				}
			}
		}

		SetThumbnail();
	}

	SdXMLShapeContext::EndElement();
}

SvXMLImportContext * SdXMLPluginShapeContext::CreateChildContext( sal_uInt16 p_nPrefix, const ::rtl::OUString& rLocalName, const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList )
{
	if( p_nPrefix == XML_NAMESPACE_DRAW && IsXMLToken( rLocalName, XML_PARAM ) )
	{
		OUString aParamName, aParamValue;
		const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
		// now parse the attribute list and look for draw:name and draw:value
		for(sal_Int16 a(0); a < nAttrCount; a++)
		{
			const OUString& rAttrName = xAttrList->getNameByIndex(a);
			OUString aLocalName;
			sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
			const OUString aValue( xAttrList->getValueByIndex(a) );

			if( nPrefix == XML_NAMESPACE_DRAW )
			{
				if( IsXMLToken( aLocalName, XML_NAME ) )
				{
					aParamName = aValue;
				}
				else if( IsXMLToken( aLocalName, XML_VALUE ) )
				{
					aParamValue = aValue;
				}
			}

			if( aParamName.getLength() )
			{
				sal_Int32 nIndex = maParams.getLength();
				maParams.realloc( nIndex + 1 );
				maParams[nIndex].Name = aParamName;
				maParams[nIndex].Handle = -1;
				maParams[nIndex].Value <<= aParamValue;
				maParams[nIndex].State = beans::PropertyState_DIRECT_VALUE;
			}
		}

		return new SvXMLImportContext( GetImport(), p_nPrefix, rLocalName );
	}

	return SdXMLShapeContext::CreateChildContext( p_nPrefix, rLocalName, xAttrList );
}

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

TYPEINIT1( SdXMLFloatingFrameShapeContext, SdXMLShapeContext );

SdXMLFloatingFrameShapeContext::SdXMLFloatingFrameShapeContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
		const rtl::OUString& rLocalName,
		const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
		com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rShapes,
        sal_Bool bTemporaryShape)
: SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape )
{
}

SdXMLFloatingFrameShapeContext::~SdXMLFloatingFrameShapeContext()
{
}

void SdXMLFloatingFrameShapeContext::StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& )
{
	const char* pService = "com.sun.star.drawing.FrameShape";
	AddShape( pService );

	if( mxShape.is() )
	{
		SetLayer();

		// set pos, size, shear and rotate
		SetTransformation();

		uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
		if( xProps.is() )
		{
			uno::Any aAny;

			if( maFrameName.getLength() )
			{
				aAny <<= maFrameName;
				xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "FrameName" ) ), aAny );
			}

			if( maHref.getLength() )
			{
				aAny <<= maHref;
				xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "FrameURL" ) ), aAny );
			}
		}

		SetStyle();

		GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
	}
}

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLFloatingFrameShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	switch( nPrefix )
	{
	case XML_NAMESPACE_DRAW:
		if( IsXMLToken( rLocalName, XML_FRAME_NAME ) )
		{
			maFrameName = rValue;
			return;
		}
		break;
	case XML_NAMESPACE_XLINK:
		if( IsXMLToken( rLocalName, XML_HREF ) )
		{
			maHref = GetImport().GetAbsoluteReference(rValue);
			return;
		}
		break;
	}

	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

void SdXMLFloatingFrameShapeContext::EndElement()
{
	uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );

	if( xProps.is() )
	{
		if ( maSize.Width && maSize.Height )
		{
			// the visual area for a floating frame must be set on loading
			awt::Rectangle aRect( 0, 0, maSize.Width, maSize.Height );
			uno::Any aAny;
			aAny <<= aRect;
			xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "VisibleArea" ) ), aAny );
		}
	}

	SetThumbnail();
	SdXMLShapeContext::EndElement();
}

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

TYPEINIT1( SdXMLFrameShapeContext, SdXMLShapeContext );

SdXMLFrameShapeContext::SdXMLFrameShapeContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
		const rtl::OUString& rLocalName,
		const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
		com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rShapes,
        sal_Bool bTemporaryShape)
: SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
    multiImageImportHelper(),
	mbSupportsReplacement( sal_False ),
    mxImplContext(),
    mxReplImplContext()
{
	uno::Reference < util::XCloneable > xClone( xAttrList, uno::UNO_QUERY );
	if( xClone.is() )
		mxAttrList.set( xClone->createClone(), uno::UNO_QUERY );
	else
		mxAttrList = new SvXMLAttributeList( xAttrList );

}

SdXMLFrameShapeContext::~SdXMLFrameShapeContext()
{
}

void SdXMLFrameShapeContext::removeGraphicFromImportContext(const SvXMLImportContext& rContext) const
{
    const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast< const SdXMLGraphicObjectShapeContext* >(&rContext);

    if(pSdXMLGraphicObjectShapeContext)
    {
        try
        {
            uno::Reference< container::XChild > xChild(pSdXMLGraphicObjectShapeContext->getShape(), uno::UNO_QUERY_THROW);

            if(xChild.is())
            {
                uno::Reference< drawing::XShapes > xParent(xChild->getParent(), uno::UNO_QUERY_THROW);
            
                if(xParent.is())
                {
                    // remove from parent
                    xParent->remove(pSdXMLGraphicObjectShapeContext->getShape());

                    // dispose
                    uno::Reference< lang::XComponent > xComp(pSdXMLGraphicObjectShapeContext->getShape(), UNO_QUERY);

                    if(xComp.is())
                    {
                        xComp->dispose();
                    }
                }
            }
        }
        catch( uno::Exception& )
        {
            DBG_ERROR( "Error in cleanup of multiple graphic object import (!)" );
        }
    }
}

rtl::OUString SdXMLFrameShapeContext::getGraphicURLFromImportContext(const SvXMLImportContext& rContext) const
{
    rtl::OUString aRetval;
    const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast< const SdXMLGraphicObjectShapeContext* >(&rContext);

    if(pSdXMLGraphicObjectShapeContext)
    {
        try
        {
            const uno::Reference< beans::XPropertySet > xPropSet(pSdXMLGraphicObjectShapeContext->getShape(), uno::UNO_QUERY_THROW);

            if(xPropSet.is())
            {
                xPropSet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicStreamURL"))) >>= aRetval;

                if(!aRetval.getLength())
                {
                    // it maybe a link, try GraphicURL
                    xPropSet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicURL"))) >>= aRetval;
                }
            }
        }
        catch( uno::Exception& )
        {
            DBG_ERROR( "Error in cleanup of multiple graphic object import (!)" );
        }
    }

    return aRetval;
}

SvXMLImportContext *SdXMLFrameShapeContext::CreateChildContext( sal_uInt16 nPrefix,
	const OUString& rLocalName,
	const uno::Reference< xml::sax::XAttributeList>& xAttrList )
{
	SvXMLImportContext * pContext = 0;

	if( !mxImplContext.Is() )
	{
        pContext = GetImport().GetShapeImport()->CreateFrameChildContext(
            GetImport(), nPrefix, rLocalName, xAttrList, mxShapes, mxAttrList);

        mxImplContext = pContext;
        mbSupportsReplacement = IsXMLToken(rLocalName, XML_OBJECT ) || IsXMLToken(rLocalName, XML_OBJECT_OLE);
        setSupportsMultipleContents(IsXMLToken(rLocalName, XML_IMAGE));

        if(getSupportsMultipleContents())
        {
            SdXMLGraphicObjectShapeContext* pGSC = dynamic_cast< SdXMLGraphicObjectShapeContext* >(pContext);

            if(pGSC)
            {
                // mark context as LateAdd to avoid conflicts with multiple objects registering with the same ID
                pGSC->setLateAddToIdentifierMapper(true);
                addContent(*mxImplContext);
            }
        }
    }
    else if(getSupportsMultipleContents() && XML_NAMESPACE_DRAW == nPrefix && IsXMLToken(rLocalName, XML_IMAGE))
    {
        // read another image
        pContext = GetImport().GetShapeImport()->CreateFrameChildContext(
            GetImport(), nPrefix, rLocalName, xAttrList, mxShapes, mxAttrList);
        mxImplContext = pContext;

        SdXMLGraphicObjectShapeContext* pGSC = dynamic_cast< SdXMLGraphicObjectShapeContext* >(pContext);

        if(pGSC)
        {
            // mark context as LateAdd to avoid conflicts with multiple objects registering with the same ID
            pGSC->setLateAddToIdentifierMapper(true);
            addContent(*mxImplContext);
        }
    }
	else if( mbSupportsReplacement && !mxReplImplContext &&
			 XML_NAMESPACE_DRAW == nPrefix &&
			 IsXMLToken( rLocalName, XML_IMAGE ) )
	{
		// read replacement image
		SvXMLImportContext *pImplContext = &mxImplContext;
		SdXMLShapeContext *pSContext =
			PTR_CAST( SdXMLShapeContext, pImplContext );
		if( pSContext )
		{
			uno::Reference < beans::XPropertySet > xPropSet(
					pSContext->getShape(), uno::UNO_QUERY );
			if( xPropSet.is() )
			{
				pContext = new XMLReplacementImageContext( GetImport(),
									nPrefix, rLocalName, xAttrList, xPropSet );
				mxReplImplContext = pContext;
			}
		}
	}
	else if( 
			( nPrefix == XML_NAMESPACE_SVG &&	// #i68101#
				(IsXMLToken( rLocalName, XML_TITLE ) || IsXMLToken( rLocalName, XML_DESC ) ) ) ||
			 (nPrefix == XML_NAMESPACE_OFFICE && IsXMLToken( rLocalName, XML_EVENT_LISTENERS ) ) ||
			 (nPrefix == XML_NAMESPACE_DRAW && (IsXMLToken( rLocalName, XML_GLUE_POINT ) ||
												IsXMLToken( rLocalName, XML_THUMBNAIL ) ) ) )
	{
		SvXMLImportContext *pImplContext = &mxImplContext;
		pContext = PTR_CAST( SdXMLShapeContext, pImplContext )->CreateChildContext( nPrefix,
																		rLocalName, xAttrList );
	}
	else if ( (XML_NAMESPACE_DRAW == nPrefix) && IsXMLToken( rLocalName, XML_IMAGE_MAP ) )
	{
		SdXMLShapeContext *pSContext = dynamic_cast< SdXMLShapeContext* >( &mxImplContext );
		if( pSContext )
		{
			uno::Reference < beans::XPropertySet > xPropSet( pSContext->getShape(), uno::UNO_QUERY );
			if (xPropSet.is())
			{
				pContext = new XMLImageMapContext(GetImport(), nPrefix, rLocalName, xPropSet);
			}
		}
	}

	// call parent for content
	if(!pContext)
		pContext = SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );

	return pContext;
}

void SdXMLFrameShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>&)
{
	// ignore
}

void SdXMLFrameShapeContext::EndElement()
{
    /// solve if multiple image child contexts were imported
    const SvXMLImportContext* pWinner = solveMultipleImages();
    const SdXMLGraphicObjectShapeContext* pGSCWinner = dynamic_cast< const SdXMLGraphicObjectShapeContext* >(pWinner);

    /// if we have a winner and it's on LateAdd, add it now
    if(pGSCWinner && pGSCWinner->getLateAddToIdentifierMapper() && pGSCWinner->getShapeId().getLength())
    {
        uno::Reference< uno::XInterface > xRef( pGSCWinner->getShape(), uno::UNO_QUERY );
        GetImport().getInterfaceToIdentifierMapper().registerReference( pGSCWinner->getShapeId(), xRef );
    }

	if( !mxImplContext.Is() )
	{
		// now check if this is an empty presentation object
		sal_Int16 nAttrCount = mxAttrList.is() ? mxAttrList->getLength() : 0;
		for(sal_Int16 a(0); a < nAttrCount; a++)
		{
			OUString aLocalName;
			sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName(mxAttrList->getNameByIndex(a), &aLocalName);

			if( nPrefix == XML_NAMESPACE_PRESENTATION )
			{
				if( IsXMLToken( aLocalName, XML_PLACEHOLDER ) )
				{
					mbIsPlaceholder = IsXMLToken( mxAttrList->getValueByIndex(a), XML_TRUE );
				}
				else if( IsXMLToken( aLocalName, XML_CLASS ) )
				{
					maPresentationClass = mxAttrList->getValueByIndex(a);
				}
			}
		}

		if( (maPresentationClass.getLength() != 0) && mbIsPlaceholder )
		{
			uno::Reference< xml::sax::XAttributeList> xEmpty;

			enum XMLTokenEnum eToken = XML_TEXT_BOX;

			if( IsXMLToken( maPresentationClass, XML_GRAPHIC ) )
			{
				eToken = XML_IMAGE;

			}
			else if( IsXMLToken( maPresentationClass, XML_PRESENTATION_PAGE ) )
			{
				eToken = XML_PAGE_THUMBNAIL;
			}
			else if( IsXMLToken( maPresentationClass, XML_PRESENTATION_CHART ) ||
					 IsXMLToken( maPresentationClass, XML_PRESENTATION_TABLE ) ||
					 IsXMLToken( maPresentationClass, XML_PRESENTATION_OBJECT ) )
			{
				eToken = XML_OBJECT;
			}

			mxImplContext = GetImport().GetShapeImport()->CreateFrameChildContext(
					GetImport(), XML_NAMESPACE_DRAW, GetXMLToken( eToken ), mxAttrList, mxShapes, xEmpty );

			if( mxImplContext.Is() )
			{
				mxImplContext->StartElement( mxAttrList );
				mxImplContext->EndElement();
			}
		}
	}

	mxImplContext = 0;
	SdXMLShapeContext::EndElement();
}

void SdXMLFrameShapeContext::processAttribute( sal_uInt16,
		const ::rtl::OUString&, const ::rtl::OUString& )
{
	// ignore
}

TYPEINIT1( SdXMLCustomShapeContext, SdXMLShapeContext );

SdXMLCustomShapeContext::SdXMLCustomShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape )
{
}

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

SdXMLCustomShapeContext::~SdXMLCustomShapeContext()
{
}

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

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLCustomShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	if( XML_NAMESPACE_DRAW == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_ENGINE ) )
		{
			maCustomShapeEngine = rValue;
			return;
		}
		if ( IsXMLToken( rLocalName, XML_DATA ) )
		{
			maCustomShapeData = rValue;
			return;
		}
	}
	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

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

void SdXMLCustomShapeContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
{
	// create rectangle shape
	AddShape("com.sun.star.drawing.CustomShape");
	if ( mxShape.is() )
	{
		// Add, set Style and properties from base shape
		SetStyle();
		SetLayer();

		// set pos, size, shear and rotate
		SetTransformation();

		try
		{
			uno::Reference< beans::XPropertySet > xPropSet( mxShape, uno::UNO_QUERY );
			if( xPropSet.is() )
			{
				if ( maCustomShapeEngine.getLength() )
				{
					uno::Any aAny;
					aAny <<= maCustomShapeEngine;
					xPropSet->setPropertyValue( EASGet( EAS_CustomShapeEngine ), aAny );
				}
				if ( maCustomShapeData.getLength() )
				{
					uno::Any aAny;
					aAny <<= maCustomShapeData;
					xPropSet->setPropertyValue( EASGet( EAS_CustomShapeData ), aAny );
				}
			}
		}
		catch( uno::Exception& )
		{
			DBG_ERROR( "could not set enhanced customshape geometry" );
		}
		SdXMLShapeContext::StartElement(xAttrList);
	}
}

void SdXMLCustomShapeContext::EndElement()
{
    // for backward compatibility, the above SetTransformation() may alraedy have
    // applied a call to SetMirroredX/SetMirroredY. This is not yet added to the
    // beans::PropertyValues in maCustomShapeGeometry. When applying these now, this 
    // would be lost again.
    // TTTT: Remove again after aw080
    if(!maUsedTransformation.isIdentity())
    {
        basegfx::B2DVector aScale, aTranslate;
        double fRotate, fShearX;

        maUsedTransformation.decompose(aScale, aTranslate, fRotate, fShearX);

        bool bFlippedX(aScale.getX() < 0.0);
        bool bFlippedY(aScale.getY() < 0.0);

        if(bFlippedX && bFlippedY)
        {
            // when both are used it is the same as 180 degree rotation; reset
            bFlippedX = bFlippedY = false;
        }

        if(bFlippedX || bFlippedY)
        {
            beans::PropertyValue aNewPoroperty;

            if(bFlippedX)
            {
                aNewPoroperty.Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MirroredX"));
            }
            else
            {
                aNewPoroperty.Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MirroredY"));
            }

            aNewPoroperty.Handle = -1;
            aNewPoroperty.Value <<= sal_True;
            aNewPoroperty.State = beans::PropertyState_DIRECT_VALUE;

            maCustomShapeGeometry.push_back(aNewPoroperty);
        }
    }

	if ( !maCustomShapeGeometry.empty() )
	{
		const rtl::OUString	sCustomShapeGeometry	( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeGeometry" ) );

		// converting the vector to a sequence
		uno::Sequence< beans::PropertyValue > aSeq( maCustomShapeGeometry.size() );
		beans::PropertyValue* pValues = aSeq.getArray();
		std::vector< beans::PropertyValue >::const_iterator aIter( maCustomShapeGeometry.begin() );
		std::vector< beans::PropertyValue >::const_iterator aEnd( maCustomShapeGeometry.end() );
		while ( aIter != aEnd )
			*pValues++ = *aIter++;

		try
		{
			uno::Reference< beans::XPropertySet > xPropSet( mxShape, uno::UNO_QUERY );
			if( xPropSet.is() )
			{
				uno::Any aAny;
				aAny <<= aSeq;
				xPropSet->setPropertyValue( sCustomShapeGeometry, aAny );
			}
		}
		catch( uno::Exception& )
		{
			DBG_ERROR( "could not set enhanced customshape geometry" );
		}

        sal_Int32 nUPD( 0 );
        sal_Int32 nBuild( 0 );
        GetImport().getBuildIds( nUPD, nBuild );
        if( ((nUPD >= 640 && nUPD <= 645) || (nUPD == 680)) && (nBuild <= 9221) )
		{
			Reference< drawing::XEnhancedCustomShapeDefaulter > xDefaulter( mxShape, UNO_QUERY );
			if( xDefaulter.is() )
			{
				rtl::OUString aEmptyType;
				xDefaulter->createCustomShapeDefaults( aEmptyType );
			}
		}
	}

	SdXMLShapeContext::EndElement();
}

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

SvXMLImportContext* SdXMLCustomShapeContext::CreateChildContext(
	sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName,
	const uno::Reference<xml::sax::XAttributeList>& xAttrList )
{
	SvXMLImportContext* pContext = NULL;
	if ( XML_NAMESPACE_DRAW == nPrefix )
	{
		if ( IsXMLToken( rLocalName, XML_ENHANCED_GEOMETRY ) )
		{
			uno::Reference< beans::XPropertySet > xPropSet( mxShape,uno::UNO_QUERY );
			if ( xPropSet.is() )
				pContext = new XMLEnhancedCustomShapeContext( GetImport(), mxShape, nPrefix, rLocalName, maCustomShapeGeometry );
		}
	}
	// delegate to parent class if no context could be created
	if ( NULL == pContext )
		pContext = SdXMLShapeContext::CreateChildContext( nPrefix, rLocalName,
														 xAttrList);
	return pContext;
}

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

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

TYPEINIT1( SdXMLTableShapeContext, SdXMLShapeContext );

SdXMLTableShapeContext::SdXMLTableShapeContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const rtl::OUString& rLocalName, const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList, com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rShapes )
: SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, sal_False )
{
	memset( &maTemplateStylesUsed, 0, sizeof( maTemplateStylesUsed ) );
}

SdXMLTableShapeContext::~SdXMLTableShapeContext()
{
}

void SdXMLTableShapeContext::StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList )
{
	const char* pService = "com.sun.star.drawing.TableShape";

	sal_Bool bIsPresShape = maPresentationClass.getLength() && GetImport().GetShapeImport()->IsPresentationShapesSupported();
	if( bIsPresShape )
	{
		if( IsXMLToken( maPresentationClass, XML_PRESENTATION_TABLE ) )
		{
			pService = "com.sun.star.presentation.TableShape";
		}
	}

	AddShape( pService );

	if( mxShape.is() )
	{
		SetLayer();

		uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);

		if(bIsPresShape)
		{
			if(xProps.is())
			{
				uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
				if( xPropsInfo.is() )
				{
					if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") )))
						xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") ), ::cppu::bool2any( sal_False ) );

					if( mbIsUserTransformed && xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent") )))
						xProps->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent") ), ::cppu::bool2any( sal_False ) );
				}
			}
		}

		SetStyle();

		if( xProps.is() )
		{
			if( msTemplateStyleName.getLength() ) try
			{
				Reference< XStyleFamiliesSupplier > xFamiliesSupp( GetImport().GetModel(), UNO_QUERY_THROW );
				Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
				const OUString sFamilyName( RTL_CONSTASCII_USTRINGPARAM("table" ) );
				Reference< XNameAccess > xTableFamily( xFamilies->getByName( sFamilyName ), UNO_QUERY_THROW );
				Reference< XStyle > xTableStyle( xTableFamily->getByName( msTemplateStyleName ), UNO_QUERY_THROW );
				xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TableTemplate" ) ), Any( xTableStyle ) );
			}
			catch( Exception& )
			{
				DBG_ERROR("SdXMLTableShapeContext::StartElement(), exception caught!");
			}

			const XMLPropertyMapEntry* pEntry = &aXMLTableShapeAttributes[0];
			for( int i = 0; pEntry->msApiName && (i < 6); i++, pEntry++ )
			{
			    try
			    {
				    const OUString sAPIPropertyName( OUString(pEntry->msApiName, pEntry->nApiNameLength, RTL_TEXTENCODING_ASCII_US ) );
				    xProps->setPropertyValue( sAPIPropertyName, Any( maTemplateStylesUsed[i] ) );
			    }
			    catch( Exception& )
			    {
				    DBG_ERROR("SdXMLTableShapeContext::StartElement(), exception caught!");
			    }			
            }
		}

		GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );

		const rtl::Reference< XMLTableImport >& xTableImport( GetImport().GetShapeImport()->GetShapeTableImport() );
		if( xTableImport.is() && xProps.is() )
		{
			uno::Reference< table::XColumnRowRange > xColumnRowRange(
				xProps->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("Model") ) ), uno::UNO_QUERY );

			if( xColumnRowRange.is() )
				mxTableImportContext = xTableImport->CreateTableContext( GetPrefix(), GetLocalName(), xColumnRowRange );

			if( mxTableImportContext.Is() )
				mxTableImportContext->StartElement( xAttrList );
		}
	}
}

void SdXMLTableShapeContext::EndElement()
{
	if( mxTableImportContext.Is() )
		mxTableImportContext->EndElement();

	SdXMLShapeContext::EndElement();

	if( mxShape.is() )
	{
		// set pos, size, shear and rotate
		SetTransformation();
	}
}

// this is called from the parent group for each unparsed attribute in the attribute list
void SdXMLTableShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
{
	if( nPrefix == XML_NAMESPACE_TABLE )
	{
		if( IsXMLToken( rLocalName, XML_TEMPLATE_NAME ) )
		{
			msTemplateStyleName = rValue;
		}
		else
		{
			int i = 0;
			const XMLPropertyMapEntry* pEntry = &aXMLTableShapeAttributes[0];
			while( pEntry->msApiName && (i < 6) )
			{
				if( IsXMLToken( rLocalName, pEntry->meXMLName ) )
				{
					if( IsXMLToken( rValue, XML_TRUE ) )
						maTemplateStylesUsed[i] = sal_True;
					break;
				}
				pEntry++;
				i++;
			}
		}
	}
	SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
}

SvXMLImportContext* SdXMLTableShapeContext::CreateChildContext( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const uno::Reference<xml::sax::XAttributeList>& xAttrList )
{
	if( mxTableImportContext.Is() && (nPrefix == XML_NAMESPACE_TABLE) )
		return mxTableImportContext->CreateChildContext(nPrefix, rLocalName, xAttrList);
	else
		return SdXMLShapeContext::CreateChildContext(nPrefix, rLocalName, xAttrList);
}

