/**************************************************************
 * 
 * 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>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/matrix/b2dhommatrixtools.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())
            {
                const SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter());
                basegfx::B2DVector aSize(aViewBox.GetWidth(), aViewBox.GetHeight());

                // Is this correct? It overrides ViewBox stuff; OTOH it makes no
                // sense to have the geometry content size different from object size
                if(maSize.Width != 0 && maSize.Height != 0)
                {
                    aSize = basegfx::B2DVector(maSize.Width, maSize.Height);
                }

                basegfx::B2DPolygon aPolygon;

                if(basegfx::tools::importFromSvgPoints(aPolygon, maPoints))
                {
                    if(aPolygon.count())
                    {
                        const basegfx::B2DRange aSourceRange(
                            aViewBox.GetX(), aViewBox.GetY(), 
                            aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight());
                        const basegfx::B2DRange aTargetRange(
                            aViewBox.GetX(), aViewBox.GetY(), 
                            aViewBox.GetX() + aSize.getX(), aViewBox.GetY() + aSize.getY());

                        if(!aSourceRange.equal(aTargetRange))
                        {
                            aPolygon.transform(
                                basegfx::tools::createSourceRangeTargetRangeTransform(
                                    aSourceRange,
                                    aTargetRange));
                        }

                        com::sun::star::drawing::PointSequenceSequence aPointSequenceSequence;
                        uno::Any aAny;

                        basegfx::tools::B2DPolyPolygonToUnoPointSequenceSequence(basegfx::B2DPolyPolygon(aPolygon), aPointSequenceSequence);
                        aAny <<= aPointSequenceSequence;
                        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())
    {
        const SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter());
        basegfx::B2DVector aSize(aViewBox.GetWidth(), aViewBox.GetHeight());

        // Is this correct? It overrides ViewBox stuff; OTOH it makes no
        // sense to have the geometry content size different from object size
        if(maSize.Width != 0 && maSize.Height != 0)
        {
            aSize = basegfx::B2DVector(maSize.Width, maSize.Height);
        }

        basegfx::B2DPolyPolygon aPolyPolygon;

        if(basegfx::tools::importFromSvgD(aPolyPolygon, maD, true, 0))
        {
            if(aPolyPolygon.count())
            {
                const basegfx::B2DRange aSourceRange(
                    aViewBox.GetX(), aViewBox.GetY(), 
                    aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight());
                const basegfx::B2DRange aTargetRange(
                    aViewBox.GetX(), aViewBox.GetY(), 
                    aViewBox.GetX() + aSize.getX(), aViewBox.GetY() + aSize.getY());

                if(!aSourceRange.equal(aTargetRange))
                {
                    aPolyPolygon.transform(
                        basegfx::tools::createSourceRangeTargetRangeTransform(
                            aSourceRange,
                            aTargetRange));
                }

                // create shape
                const char* pService;

                if(aPolyPolygon.areControlPointsUsed())
                {
                    if(aPolyPolygon.isClosed())
                    {
                        pService = "com.sun.star.drawing.ClosedBezierShape";
                    }
                    else
                    {
                        pService = "com.sun.star.drawing.OpenBezierShape";
                    }
                }
                else
                {
                    if(aPolyPolygon.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 polygon data
                        if(aPolyPolygon.areControlPointsUsed())
                        {
                            drawing::PolyPolygonBezierCoords aSourcePolyPolygon;

                            basegfx::tools::B2DPolyPolygonToUnoPolyPolygonBezierCoords(
                                aPolyPolygon,
                                aSourcePolyPolygon);
                            aAny <<= aSourcePolyPolygon;
                        }
                        else
                        {
                            drawing::PointSequenceSequence aSourcePolyPolygon;

                            basegfx::tools::B2DPolyPolygonToUnoPointSequenceSequence(
                                aPolyPolygon,
                                aSourcePolyPolygon);
                            aAny <<= aSourcePolyPolygon;
                        }

                        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 ) )
        {
            basegfx::B2DPolyPolygon aPolyPolygon;

            if(basegfx::tools::importFromSvgD(aPolyPolygon, rValue, true, 0))
            {
                if(aPolyPolygon.count())
                {
                    // set polygon data
                    if(aPolyPolygon.areControlPointsUsed())
                    {
                        drawing::PolyPolygonBezierCoords aSourcePolyPolygon;

                        basegfx::tools::B2DPolyPolygonToUnoPolyPolygonBezierCoords(
                            aPolyPolygon,
                            aSourcePolyPolygon);
                        maPath <<= aSourcePolyPolygon;
                    }
                    else
                    {
                        drawing::PointSequenceSequence aSourcePolyPolygon;

                        basegfx::tools::B2DPolyPolygonToUnoPointSequenceSequence(
                            aPolyPolygon,
                            aSourcePolyPolygon);
                        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);
}

