/**************************************************************
 * 
 * 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/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/text/TextContentAnchorType.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/text/XTextFrame.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/text/SizeType.hpp>
#include <com/sun/star/drawing/XShape.hpp>
#include <com/sun/star/document/XEventsSupplier.hpp>
#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/text/HoriOrientation.hpp>
#include <com/sun/star/text/VertOrientation.hpp>
#include <xmloff/xmlimp.hxx>
#include <xmloff/xmltoken.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/nmspmap.hxx>
#include <xmloff/xmluconv.hxx>
#include "XMLAnchorTypePropHdl.hxx"
#include "XMLEmbeddedObjectImportContext.hxx"
#include <xmloff/XMLBase64ImportContext.hxx>
#include "XMLReplacementImageContext.hxx"
#include <xmloff/prstylei.hxx>
#include "xmloff/i18nmap.hxx"
#include "xexptran.hxx"
#include <xmloff/shapeimport.hxx>
#include <xmloff/XMLEventsImportContext.hxx>
#include "XMLImageMapContext.hxx"
#include "XMLTextFrameContext.hxx"
#include "XMLTextListBlockContext.hxx"
#include "XMLTextListItemContext.hxx"
#include <xmloff/attrlist.hxx>
#include <comphelper/stl_types.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <map>

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

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::xml::sax;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::document;
using namespace ::xmloff::token;
using ::com::sun::star::document::XEventsSupplier;

#define XML_TEXT_FRAME_TEXTBOX 1
#define XML_TEXT_FRAME_GRAPHIC 2
#define XML_TEXT_FRAME_OBJECT 3
#define XML_TEXT_FRAME_OBJECT_OLE 4
#define XML_TEXT_FRAME_APPLET 5
#define XML_TEXT_FRAME_PLUGIN 6
#define XML_TEXT_FRAME_FLOATING_FRAME 7

typedef ::std::map < const ::rtl::OUString, ::rtl::OUString, ::comphelper::UStringLess> ParamMap;

class XMLTextFrameContextHyperlink_Impl
{
	OUString sHRef;
	OUString sName;
	OUString sTargetFrameName;
	sal_Bool bMap;

public:

	inline XMLTextFrameContextHyperlink_Impl( const OUString& rHRef,
					   const OUString& rName,
					   const OUString& rTargetFrameName,
					   sal_Bool bMap );

	const OUString& GetHRef() const { return sHRef; }
	const OUString& GetName() const { return sName; }
	const OUString& GetTargetFrameName() const { return sTargetFrameName; }
	sal_Bool GetMap() const { return bMap; }
};

inline XMLTextFrameContextHyperlink_Impl::XMLTextFrameContextHyperlink_Impl(
	const OUString& rHRef, const OUString& rName,
	const OUString& rTargetFrameName, sal_Bool bM ) :
	sHRef( rHRef ),
	sName( rName ),
	sTargetFrameName( rTargetFrameName ),
	bMap( bM )
{
}

// --> OD 2009-07-22 #i73249#
class XMLTextFrameTitleOrDescContext_Impl : public SvXMLImportContext
{
    OUString&   mrTitleOrDesc;

public:

    XMLTextFrameTitleOrDescContext_Impl( SvXMLImport& rImport,
                                         sal_uInt16 nPrfx,
                                         const ::rtl::OUString& rLName,
                                         OUString& rTitleOrDesc );
    virtual ~XMLTextFrameTitleOrDescContext_Impl();

	virtual void Characters( const OUString& rText );
};

XMLTextFrameTitleOrDescContext_Impl::XMLTextFrameTitleOrDescContext_Impl(
		SvXMLImport& rImport,
        sal_uInt16 nPrfx,
        const OUString& rLName,
        OUString& rTitleOrDesc )
    : SvXMLImportContext( rImport, nPrfx, rLName )
    , mrTitleOrDesc( rTitleOrDesc )
{
}

XMLTextFrameTitleOrDescContext_Impl::~XMLTextFrameTitleOrDescContext_Impl()
{
}

void XMLTextFrameTitleOrDescContext_Impl::Characters( const OUString& rText )
{
    mrTitleOrDesc += rText;
}
// <--

// ------------------------------------------------------------------------

class XMLTextFrameParam_Impl : public SvXMLImportContext
{
public:

	XMLTextFrameParam_Impl( SvXMLImport& rImport, sal_uInt16 nPrfx,
								  const ::rtl::OUString& rLName,
			const ::com::sun::star::uno::Reference<
				::com::sun::star::xml::sax::XAttributeList > & xAttrList,
			sal_uInt16 nType,
            ParamMap &rParamMap);
	virtual ~XMLTextFrameParam_Impl();
};

XMLTextFrameParam_Impl::~XMLTextFrameParam_Impl()
{
}

XMLTextFrameParam_Impl::XMLTextFrameParam_Impl(
		SvXMLImport& rImport, sal_uInt16 nPrfx,
	  	const ::rtl::OUString& rLName,
		const ::com::sun::star::uno::Reference<
				::com::sun::star::xml::sax::XAttributeList > & xAttrList,
		sal_uInt16 /*nType*/,
        ParamMap &rParamMap):
	SvXMLImportContext( rImport, nPrfx, rLName )
{
	OUString sName, sValue;
    sal_Bool bFoundValue = sal_False; // to allow empty values
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for( sal_Int16 i=0; i < nAttrCount; i++ )
	{
		const OUString& rAttrName = xAttrList->getNameByIndex( i );
		const OUString& rValue = xAttrList->getValueByIndex( i );

		OUString aLocalName;
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );
		if ( XML_NAMESPACE_DRAW == nPrefix )
		{
		   	if( IsXMLToken(aLocalName, XML_VALUE) )
			{
				sValue = rValue;
				bFoundValue=sal_True;
			}
			else if( IsXMLToken(aLocalName, XML_NAME) )
			{
				sName = rValue;
			}
		}
	}
	if (sName.getLength() && bFoundValue )
        rParamMap[sName] = sValue;
}
class XMLTextFrameContourContext_Impl : public SvXMLImportContext
{
	Reference < XPropertySet > xPropSet;

public:

	XMLTextFrameContourContext_Impl( SvXMLImport& rImport, sal_uInt16 nPrfx,
								  const ::rtl::OUString& rLName,
			const ::com::sun::star::uno::Reference<
				::com::sun::star::xml::sax::XAttributeList > & xAttrList,
			const Reference < XPropertySet >& rPropSet,
			sal_Bool bPath );
	virtual ~XMLTextFrameContourContext_Impl();
};

XMLTextFrameContourContext_Impl::XMLTextFrameContourContext_Impl(
        SvXMLImport& rImport,
        sal_uInt16 nPrfx, const OUString& rLName,
        const Reference< XAttributeList > & xAttrList,
        const Reference < XPropertySet >& rPropSet,
        sal_Bool bPath ) :
    SvXMLImportContext( rImport, nPrfx, rLName ),
    xPropSet( rPropSet )
{
    OUString sD, sPoints, sViewBox;
    sal_Bool bPixelWidth = sal_False, bPixelHeight = sal_False;
    sal_Bool bAuto = sal_False;
    sal_Int32 nWidth = 0;
    sal_Int32 nHeight = 0;

    const SvXMLTokenMap& rTokenMap =
        GetImport().GetTextImport()->GetTextContourAttrTokenMap();

    sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; i++ )
    {
        const OUString& rAttrName = xAttrList->getNameByIndex( i );
        const OUString& rValue = xAttrList->getValueByIndex( i );

        OUString aLocalName;
        sal_uInt16 nPrefix =
            GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
                                                            &aLocalName );
        switch( rTokenMap.Get( nPrefix, aLocalName ) )
        {
        case XML_TOK_TEXT_CONTOUR_VIEWBOX:
            sViewBox = rValue;
            break;
        case XML_TOK_TEXT_CONTOUR_D:
            if( bPath )
                sD = rValue;
            break;
        case XML_TOK_TEXT_CONTOUR_POINTS:
            if( !bPath )
                sPoints = rValue;
            break;
        case XML_TOK_TEXT_CONTOUR_WIDTH:
            if( GetImport().GetMM100UnitConverter().convertMeasurePx( nWidth,
                                                                      rValue) )
                bPixelWidth = sal_True;
            else
                GetImport().GetMM100UnitConverter().convertMeasure( nWidth,
                                                                rValue);
            break;
        case XML_TOK_TEXT_CONTOUR_HEIGHT:
            if( GetImport().GetMM100UnitConverter().convertMeasurePx( nHeight,
                                                                rValue) )
                bPixelHeight = sal_True;
            else
                GetImport().GetMM100UnitConverter().convertMeasure( nHeight,
                                                                    rValue);
            break;
        case XML_TOK_TEXT_CONTOUR_AUTO:
            bAuto = IsXMLToken(rValue, XML_TRUE);
            break;
        }
    }

    OUString sContourPolyPolygon(RTL_CONSTASCII_USTRINGPARAM("ContourPolyPolygon"));
    Reference < XPropertySetInfo > xPropSetInfo = rPropSet->getPropertySetInfo();

    if(xPropSetInfo->hasPropertyByName(sContourPolyPolygon) && nWidth > 0 && nHeight > 0 && bPixelWidth == bPixelHeight && (bPath ? sD : sPoints).getLength())
    {
        const SdXMLImExViewBox aViewBox( sViewBox, GetImport().GetMM100UnitConverter());
        basegfx::B2DPolyPolygon aPolyPolygon;
        Any aAny;

        if( bPath )
        {
            basegfx::tools::importFromSvgD(
                aPolyPolygon,
                sD, 
                true, 
                0);
        }
        else
        {
            basegfx::B2DPolygon aPolygon;

            if(basegfx::tools::importFromSvgPoints(aPolygon, sPoints))
            {
                aPolyPolygon = basegfx::B2DPolyPolygon(aPolygon);
            }
        }

        if(aPolyPolygon.count())
        {
            const basegfx::B2DRange aSourceRange(
                aViewBox.GetX(), aViewBox.GetY(), 
                aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight());
            const basegfx::B2DRange aTargetRange(
                0.0, 0.0, 
                nWidth, nHeight);

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

            com::sun::star::drawing::PointSequenceSequence aPointSequenceSequence;
            basegfx::tools::B2DPolyPolygonToUnoPointSequenceSequence(aPolyPolygon, aPointSequenceSequence);
            aAny <<= aPointSequenceSequence;
            xPropSet->setPropertyValue( sContourPolyPolygon, aAny );
        }

        const OUString sIsPixelContour(RTL_CONSTASCII_USTRINGPARAM("IsPixelContour"));

        if( xPropSetInfo->hasPropertyByName( sIsPixelContour ) )
        {
            aAny.setValue( &bPixelWidth, ::getBooleanCppuType() );
            xPropSet->setPropertyValue( sIsPixelContour, aAny );
        }

        const OUString sIsAutomaticContour(RTL_CONSTASCII_USTRINGPARAM("IsAutomaticContour") );

        if( xPropSetInfo->hasPropertyByName( sIsAutomaticContour ) )
        {
            aAny.setValue( &bAuto, ::getBooleanCppuType() );
            xPropSet->setPropertyValue( sIsAutomaticContour, aAny );
        }
    }
}

XMLTextFrameContourContext_Impl::~XMLTextFrameContourContext_Impl()
{
}

// ------------------------------------------------------------------------

class XMLTextFrameContext_Impl : public SvXMLImportContext
{
	::com::sun::star::uno::Reference <
		::com::sun::star::text::XTextCursor > xOldTextCursor;
	::com::sun::star::uno::Reference <
		::com::sun::star::beans::XPropertySet > xPropSet;
	::com::sun::star::uno::Reference <
		::com::sun::star::io::XOutputStream > xBase64Stream;

    /// old list item and block (#89891#)
    bool mbListContextPushed;

	const ::rtl::OUString sWidth;
	const ::rtl::OUString sWidthType;
	const ::rtl::OUString sRelativeWidth;
	const ::rtl::OUString sHeight;
	const ::rtl::OUString sRelativeHeight;
	const ::rtl::OUString sSizeType;
	const ::rtl::OUString sIsSyncWidthToHeight;
	const ::rtl::OUString sIsSyncHeightToWidth;
	const ::rtl::OUString sHoriOrient;
	const ::rtl::OUString sHoriOrientPosition;
	const ::rtl::OUString sVertOrient;
	const ::rtl::OUString sVertOrientPosition;
	const ::rtl::OUString sChainNextName;
	const ::rtl::OUString sAnchorType;
	const ::rtl::OUString sAnchorPageNo;
	const ::rtl::OUString sGraphicURL;
	const ::rtl::OUString sGraphicFilter;
    // --> OD 2009-07-22 #i73249#
//    const ::rtl::OUString sAlternativeText;
    const ::rtl::OUString sTitle;
    const ::rtl::OUString sDescription;
    // <--
	const ::rtl::OUString sFrameStyleName;
	const ::rtl::OUString sGraphicRotation;
	const ::rtl::OUString sTextBoxServiceName;
	const ::rtl::OUString sGraphicServiceName;

	::rtl::OUString	sName;
	::rtl::OUString	sStyleName;
	::rtl::OUString	sNextName;
	::rtl::OUString	sHRef;
	::rtl::OUString	sFilterName;
	::rtl::OUString	sCode;
	::rtl::OUString	sObject;
	::rtl::OUString	sArchive;
	::rtl::OUString	sMimeType;
	::rtl::OUString sFrameName;
	::rtl::OUString sAppletName;
	::rtl::OUString	sFilterService;
	::rtl::OUString sBase64CharsLeft;
	::rtl::OUString	sTblName;

    ParamMap aParamMap;

	sal_Int32	nX;
	sal_Int32	nY;
	sal_Int32	nWidth;
	sal_Int32	nHeight;
	sal_Int32	nZIndex;
	sal_Int16	nPage;
	sal_Int16	nRotation;
	sal_Int16	nRelWidth;
	sal_Int16	nRelHeight;

	sal_uInt16 nType;
	::com::sun::star::text::TextContentAnchorType 	eAnchorType;

	sal_Bool	bMayScript : 1;
	sal_Bool	bMinWidth : 1;
	sal_Bool	bMinHeight : 1;
	sal_Bool	bSyncWidth : 1;
	sal_Bool	bSyncHeight : 1;
	sal_Bool	bCreateFailed : 1;
	sal_Bool	bOwnBase64Stream : 1;
    bool        mbSetNameForFrame : 1; // #123261# remember if to set the NameForFrame

	void Create( sal_Bool bHRefOrBase64 );

public:

	sal_Bool CreateIfNotThere();
	const OUString& GetHRef() const { return sHRef; }

    XMLTextFrameContext_Impl( SvXMLImport& rImport,
        sal_uInt16 nPrfx,
        const ::rtl::OUString& rLName,
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::xml::sax::XAttributeList > & rAttrList,
        ::com::sun::star::text::TextContentAnchorType eAnchorType,
        sal_uInt16 nType,
        const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & rFrameAttrList,
        bool bSetNameForFrame); // #123261# control if to set the NameForFrame
    virtual ~XMLTextFrameContext_Impl();

	virtual void EndElement();

	virtual void Characters( const ::rtl::OUString& rChars );

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

	void SetHyperlink( const ::rtl::OUString& rHRef,
					   const ::rtl::OUString& rName,
					   const ::rtl::OUString& rTargetFrameName,
					   sal_Bool bMap );
    // --> OD 2009-07-22 #i73249#
    void SetTitle( const ::rtl::OUString& rTitle );
    // <--
    void SetDesc( const ::rtl::OUString& rDesc );

	::com::sun::star::text::TextContentAnchorType GetAnchorType() const { return eAnchorType; }

	const ::com::sun::star::uno::Reference <
		::com::sun::star::beans::XPropertySet >& GetPropSet() const { return xPropSet; }

    // #123261# helper to set the NameForFrame
    void SetNameForFrameFromPropSet();
};

void XMLTextFrameContext_Impl::SetNameForFrameFromPropSet()
{
    // set name
    UniReference < XMLTextImportHelper > xTextImportHelper = GetImport().GetTextImport();
    Reference < XNamed > xNamed( xPropSet, UNO_QUERY );

    if( xNamed.is() && xTextImportHelper.is() )
    {
        OUString sOrigName( xNamed->getName() );
        if( !sOrigName.getLength() ||
            (sName.getLength() && sOrigName != sName) )
        {
            OUString sOldName( sName );
            sal_Int32 i = 0;
            while( xTextImportHelper->HasFrameByName( sName ) )
            {
                sName = sOldName;
                sName += OUString::valueOf( ++i );
            }
            xNamed->setName( sName );
            if( sName != sOldName )
                xTextImportHelper->GetRenameMap().Add( XML_TEXT_RENAME_TYPE_FRAME,
                                             sOldName, sName );
        }
    }
}

void XMLTextFrameContext_Impl::Create( sal_Bool /*bHRefOrBase64*/ )
{
	UniReference < XMLTextImportHelper > xTextImportHelper =
		GetImport().GetTextImport();

    switch ( nType)
    {
        case XML_TEXT_FRAME_OBJECT:
        case XML_TEXT_FRAME_OBJECT_OLE:
			if( xBase64Stream.is() )
			{
				OUString sURL( GetImport().ResolveEmbeddedObjectURLFromBase64() );
				if( sURL.getLength() )
					xPropSet = GetImport().GetTextImport()
							->createAndInsertOLEObject( GetImport(), sURL,
														sStyleName,
														sTblName,
														nWidth, nHeight );
			}
			else if( sHRef.getLength() )
			{
				OUString sURL( GetImport().ResolveEmbeddedObjectURL( sHRef,
																OUString() ) );

				if( GetImport().IsPackageURL( sHRef ) )
				{
					xPropSet = GetImport().GetTextImport()
							->createAndInsertOLEObject( GetImport(), sURL,
														sStyleName,
														sTblName,
														nWidth, nHeight );
				}
				else
				{
					// it should be an own OOo link that has no storage persistence
					xPropSet = GetImport().GetTextImport()
							->createAndInsertOOoLink( GetImport(),
														sURL,
														sStyleName,
														sTblName,
														nWidth, nHeight );
				}
			}
			else
			{
				OUString sURL( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.ServiceName:") );
				sURL += sFilterService;
				xPropSet = GetImport().GetTextImport()
							->createAndInsertOLEObject( GetImport(), sURL,
														sStyleName,
														sTblName,
														nWidth, nHeight );

			}
			break;
        case XML_TEXT_FRAME_APPLET:
        {
            xPropSet = GetImport().GetTextImport()
							->createAndInsertApplet( sAppletName, sCode,
													 bMayScript, sHRef,
													 nWidth, nHeight);
            break;
        }
        case XML_TEXT_FRAME_PLUGIN:
        {
            if(sHRef.getLength())
                GetImport().GetAbsoluteReference(sHRef);
            xPropSet = GetImport().GetTextImport()
							->createAndInsertPlugin( sMimeType, sHRef,
								   				 	 nWidth, nHeight);

            break;
        }
        case XML_TEXT_FRAME_FLOATING_FRAME:
        {
            xPropSet = GetImport().GetTextImport()
							->createAndInsertFloatingFrame( sFrameName, sHRef,
															sStyleName,
															nWidth, nHeight);
            break;
        }
	    default:
        {
            Reference<XMultiServiceFactory> xFactory( GetImport().GetModel(),
                                                      UNO_QUERY );
            if( xFactory.is() )
            {
                OUString sServiceName;
                switch( nType )
                {
                    case XML_TEXT_FRAME_TEXTBOX: sServiceName = sTextBoxServiceName; break;
                    case XML_TEXT_FRAME_GRAPHIC: sServiceName = sGraphicServiceName; break;
                }
                Reference<XInterface> xIfc = xFactory->createInstance( sServiceName );
                DBG_ASSERT( xIfc.is(), "couldn't create frame" );
                if( xIfc.is() )
                    xPropSet = Reference < XPropertySet >( xIfc, UNO_QUERY );
            }
        }
    }

	if( !xPropSet.is() )
	{
		bCreateFailed = sal_True;
		return;
	}

	Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();

    // #123261# set name, but only if wanted, e.g. for MultiImageSupport, it will be set after
    // it is decided which image will be used. This is done e.g. to avoid double stuff and effects
    // for the target to avoid double names
    if(mbSetNameForFrame)
    {
        SetNameForFrameFromPropSet();
    }

	// frame style
	XMLPropStyleContext *pStyle = 0;
	if( sStyleName.getLength() )
	{
		pStyle = xTextImportHelper->FindAutoFrameStyle( sStyleName );
		if( pStyle )
            sStyleName = pStyle->GetParentName();
	}

	Any aAny;
	if( sStyleName.getLength() )
	{
		OUString sDisplayStyleName( GetImport().GetStyleDisplayName(
							XML_STYLE_FAMILY_SD_GRAPHICS_ID, sStyleName ) );
		const Reference < XNameContainer > & rStyles =
			xTextImportHelper->GetFrameStyles();
		if( rStyles.is() &&
			rStyles->hasByName( sDisplayStyleName ) )
		{
			aAny <<= sDisplayStyleName;
			xPropSet->setPropertyValue( sFrameStyleName, aAny );
		}
	}

	// anchor type (must be set before any other properties, because
	// otherwise some orientations cannot be set or will be changed
	// afterwards)
	aAny <<= eAnchorType;
	xPropSet->setPropertyValue( sAnchorType, aAny );

	// hard properties
	if( pStyle )
		pStyle->FillPropertySet( xPropSet );


	// x and y
	sal_Int16 nHoriOrient =  HoriOrientation::NONE;
	aAny = xPropSet->getPropertyValue( sHoriOrient );
	aAny >>= nHoriOrient;
	if( HoriOrientation::NONE == nHoriOrient )
	{
		aAny <<= nX;
		xPropSet->setPropertyValue( sHoriOrientPosition, aAny );
	}

	sal_Int16 nVertOrient =  VertOrientation::NONE;
	aAny = xPropSet->getPropertyValue( sVertOrient );
	aAny >>= nVertOrient;
	if( VertOrientation::NONE == nVertOrient )
	{
		aAny <<= nY;
		xPropSet->setPropertyValue( sVertOrientPosition, aAny );
	}

	// width
	if( nWidth > 0 )
	{
		aAny <<= nWidth;
		xPropSet->setPropertyValue( sWidth, aAny );
	}
	if( nRelWidth > 0 || nWidth > 0 )
	{
		aAny <<= nRelWidth;
		xPropSet->setPropertyValue( sRelativeWidth, aAny );
	}
	if( bSyncWidth || nWidth > 0 )
	{
		sal_Bool bTmp = bSyncWidth;
		aAny.setValue( &bTmp, ::getBooleanCppuType() );
		xPropSet->setPropertyValue( sIsSyncWidthToHeight, aAny );
	}
	if( xPropSetInfo->hasPropertyByName( sWidthType ) &&
		(bMinWidth || nWidth > 0 || nRelWidth > 0 ) )
	{
		sal_Int16 nSizeType =
			(bMinWidth && XML_TEXT_FRAME_TEXTBOX == nType) ? SizeType::MIN
                                                           : SizeType::FIX;
		aAny <<= nSizeType;
		xPropSet->setPropertyValue( sWidthType, aAny );
	}

	if( nHeight > 0 )
	{
		aAny <<= nHeight;
		xPropSet->setPropertyValue( sHeight, aAny );
	}
	if( nRelHeight > 0 || nHeight > 0 )
	{
		aAny <<= nRelHeight;
		xPropSet->setPropertyValue( sRelativeHeight, aAny );
	}
	if( bSyncHeight || nHeight > 0 )
	{
		sal_Bool bTmp = bSyncHeight;
		aAny.setValue( &bTmp, ::getBooleanCppuType() );
		xPropSet->setPropertyValue( sIsSyncHeightToWidth, aAny );
	}
	if( xPropSetInfo->hasPropertyByName( sSizeType ) &&
		(bMinHeight || nHeight > 0 || nRelHeight > 0 ) )
	{
		sal_Int16 nSizeType =
			(bMinHeight && XML_TEXT_FRAME_TEXTBOX == nType) ? SizeType::MIN
															: SizeType::FIX;
		aAny <<= nSizeType;
		xPropSet->setPropertyValue( sSizeType, aAny );
	}

	if( XML_TEXT_FRAME_GRAPHIC == nType )
	{
		// URL
		OSL_ENSURE( sHRef.getLength() > 0 || xBase64Stream.is(),
					"neither URL nor base64 image data given" );
		UniReference < XMLTextImportHelper > xTxtImport =
			GetImport().GetTextImport();
		if( sHRef.getLength() )
		{
			sal_Bool bForceLoad = xTxtImport->IsInsertMode() ||
								  xTxtImport->IsBlockMode() ||
								  xTxtImport->IsStylesOnlyMode() ||
								  xTxtImport->IsOrganizerMode();
			sHRef = GetImport().ResolveGraphicObjectURL( sHRef, !bForceLoad );
		}
		else if( xBase64Stream.is() )
		{
			sHRef = GetImport().ResolveGraphicObjectURLFromBase64( xBase64Stream );
			xBase64Stream = 0;
		}
		aAny <<= sHRef;
		xPropSet->setPropertyValue( sGraphicURL, aAny );

		// filter name
		aAny <<=sFilterName;
		xPropSet->setPropertyValue( sGraphicFilter, aAny );

		// rotation
		aAny <<= nRotation;
		xPropSet->setPropertyValue( sGraphicRotation, aAny );
	}

	// page number (must be set after the frame is inserted, because it
	// will be overwritten then inserting the frame.
	if( TextContentAnchorType_AT_PAGE == eAnchorType && nPage > 0 )
	{
		aAny <<= nPage;
		xPropSet->setPropertyValue( sAnchorPageNo, aAny );
	}

	if( XML_TEXT_FRAME_OBJECT != nType  &&
		XML_TEXT_FRAME_OBJECT_OLE != nType  &&
		XML_TEXT_FRAME_APPLET != nType &&
		XML_TEXT_FRAME_PLUGIN!= nType &&
		XML_TEXT_FRAME_FLOATING_FRAME != nType)
	{
		Reference < XTextContent > xTxtCntnt( xPropSet, UNO_QUERY );
		xTextImportHelper->InsertTextContent( xTxtCntnt );
	}

	// #107848#
	// Make adding the shepe to Z-Ordering dependent from if we are
	// inside a inside_deleted_section (redlining). That is necessary
	// since the shape will be removed again later. It would lead to
	// errors if it would stay inside the Z-Ordering. Thus, the
	// easiest way to solve that conflict is to not add it here.
	if(!GetImport().HasTextImport()
		|| !GetImport().GetTextImport()->IsInsideDeleteContext())
	{
    	Reference < XShape > xShape( xPropSet, UNO_QUERY );

        GetImport().GetShapeImport()->shapeWithZIndexAdded( xShape, nZIndex );
	}

	if( XML_TEXT_FRAME_TEXTBOX == nType )
	{
		xTextImportHelper->ConnectFrameChains( sName, sNextName, xPropSet );
		Reference < XTextFrame > xTxtFrame( xPropSet, UNO_QUERY );
		Reference < XText > xTxt = xTxtFrame->getText();
		xOldTextCursor = xTextImportHelper->GetCursor();
		xTextImportHelper->SetCursor( xTxt->createTextCursor() );

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

sal_Bool XMLTextFrameContext_Impl::CreateIfNotThere()
{
	if( !xPropSet.is() &&
		( XML_TEXT_FRAME_OBJECT_OLE == nType ||
		  XML_TEXT_FRAME_GRAPHIC == nType ) &&
		xBase64Stream.is() && !bCreateFailed )
	{
		if( bOwnBase64Stream )
			xBase64Stream->closeOutput();
		Create( sal_True );
	}

	return xPropSet.is();
}

XMLTextFrameContext_Impl::XMLTextFrameContext_Impl(
    SvXMLImport& rImport,
    sal_uInt16 nPrfx, const OUString& rLName,
    const Reference< XAttributeList > & rAttrList,
    TextContentAnchorType eATyp,
    sal_uInt16 nNewType,
    const Reference< XAttributeList > & rFrameAttrList, 
    bool bSetNameForFrame)
:   SvXMLImportContext( rImport, nPrfx, rLName )
,   mbListContextPushed( false )
,   sWidth(RTL_CONSTASCII_USTRINGPARAM("Width"))
,   sWidthType(RTL_CONSTASCII_USTRINGPARAM("WidthType"))
,   sRelativeWidth(RTL_CONSTASCII_USTRINGPARAM("RelativeWidth"))
,   sHeight(RTL_CONSTASCII_USTRINGPARAM("Height"))
,   sRelativeHeight(RTL_CONSTASCII_USTRINGPARAM("RelativeHeight"))
,   sSizeType(RTL_CONSTASCII_USTRINGPARAM("SizeType"))
,   sIsSyncWidthToHeight(RTL_CONSTASCII_USTRINGPARAM("IsSyncWidthToHeight"))
,   sIsSyncHeightToWidth(RTL_CONSTASCII_USTRINGPARAM("IsSyncHeightToWidth"))
,   sHoriOrient(RTL_CONSTASCII_USTRINGPARAM("HoriOrient"))
,   sHoriOrientPosition(RTL_CONSTASCII_USTRINGPARAM("HoriOrientPosition"))
,   sVertOrient(RTL_CONSTASCII_USTRINGPARAM("VertOrient"))
,   sVertOrientPosition(RTL_CONSTASCII_USTRINGPARAM("VertOrientPosition"))
,   sChainNextName(RTL_CONSTASCII_USTRINGPARAM("ChainNextName"))
,   sAnchorType(RTL_CONSTASCII_USTRINGPARAM("AnchorType"))
,   sAnchorPageNo(RTL_CONSTASCII_USTRINGPARAM("AnchorPageNo"))
,   sGraphicURL(RTL_CONSTASCII_USTRINGPARAM("GraphicURL"))
,   sGraphicFilter(RTL_CONSTASCII_USTRINGPARAM("GraphicFilter"))
// --> OD 2009-07-22 #i73249#
//,   sAlternativeText(RTL_CONSTASCII_USTRINGPARAM("AlternativeText"))
,   sTitle(RTL_CONSTASCII_USTRINGPARAM("Title"))
,   sDescription(RTL_CONSTASCII_USTRINGPARAM("Description"))
// <--
,   sFrameStyleName(RTL_CONSTASCII_USTRINGPARAM("FrameStyleName"))
,   sGraphicRotation(RTL_CONSTASCII_USTRINGPARAM("GraphicRotation"))
,   sTextBoxServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextFrame"))
,   sGraphicServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.GraphicObject"))
,   nType( nNewType )
,   eAnchorType( eATyp )
,   mbSetNameForFrame(bSetNameForFrame)
{
	nX = 0;
	nY = 0;
	nWidth = 0;
	nHeight = 0;
	nZIndex = -1;
	nPage = 0;
	nRotation = 0;
	nRelWidth = 0;
	nRelHeight = 0;
	bMayScript = sal_False;

	bMinHeight = sal_False;
	bMinWidth = sal_False;
	bSyncWidth = sal_False;
	bSyncHeight = sal_False;
	bCreateFailed = sal_False;
	bOwnBase64Stream = sal_False;

	UniReference < XMLTextImportHelper > xTxtImport =
		GetImport().GetTextImport();
	const SvXMLTokenMap& rTokenMap =
		xTxtImport->GetTextFrameAttrTokenMap();

	sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
	sal_Int16 nTotalAttrCount = nAttrCount + (rFrameAttrList.is() ? rFrameAttrList->getLength() : 0);
	for( sal_Int16 i=0; i < nTotalAttrCount; i++ )
	{
		const OUString& rAttrName =
			i < nAttrCount ? rAttrList->getNameByIndex( i ) : rFrameAttrList->getNameByIndex( i-nAttrCount );
		const OUString& rValue =
			i < nAttrCount ? rAttrList->getValueByIndex( i ): rFrameAttrList->getValueByIndex( i-nAttrCount );

		OUString aLocalName;
		sal_uInt16 nPrefix =
			GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
															&aLocalName );
		switch( rTokenMap.Get( nPrefix, aLocalName ) )
		{
		case XML_TOK_TEXT_FRAME_STYLE_NAME:
			sStyleName = rValue;
			break;
		case XML_TOK_TEXT_FRAME_NAME:
			sName = rValue;
			break;
		case XML_TOK_TEXT_FRAME_FRAME_NAME:
			sFrameName = rValue;
			break;
		case XML_TOK_TEXT_FRAME_APPLET_NAME:
			sAppletName = rValue;
			break;
		case XML_TOK_TEXT_FRAME_ANCHOR_TYPE:
			if( TextContentAnchorType_AT_PARAGRAPH == eAnchorType ||
				TextContentAnchorType_AT_CHARACTER == eAnchorType ||
				TextContentAnchorType_AS_CHARACTER == eAnchorType )
			{

				TextContentAnchorType eNew;
				if( XMLAnchorTypePropHdl::convert( rValue, eNew ) &&
					( TextContentAnchorType_AT_PARAGRAPH == eNew ||
					  TextContentAnchorType_AT_CHARACTER == eNew ||
					  TextContentAnchorType_AS_CHARACTER == eNew ||
					  TextContentAnchorType_AT_PAGE == eNew) )
					eAnchorType = eNew;
			}
			break;
		case XML_TOK_TEXT_FRAME_ANCHOR_PAGE_NUMBER:
			{
				sal_Int32 nTmp;
			   	if( GetImport().GetMM100UnitConverter().
								convertNumber( nTmp, rValue, 1, SHRT_MAX ) )
					nPage = (sal_Int16)nTmp;
			}
			break;
		case XML_TOK_TEXT_FRAME_X:
			GetImport().GetMM100UnitConverter().convertMeasure( nX, rValue );
			break;
		case XML_TOK_TEXT_FRAME_Y:
			GetImport().GetMM100UnitConverter().convertMeasure( nY, rValue );
			break;
		case XML_TOK_TEXT_FRAME_WIDTH:
			// relative widths are obsolete since SRC617. Remove them some day!
			if( rValue.indexOf( '%' ) != -1 )
			{
				sal_Int32 nTmp;
				GetImport().GetMM100UnitConverter().convertPercent( nTmp,
																	rValue );
				nRelWidth = (sal_Int16)nTmp;
			}
			else
			{
				GetImport().GetMM100UnitConverter().convertMeasure( nWidth,
																	rValue, 0 );
			}
			break;
		case XML_TOK_TEXT_FRAME_REL_WIDTH:
			if( IsXMLToken(rValue, XML_SCALE) )
			{
				bSyncWidth = sal_True;
			}
			else
			{
				sal_Int32 nTmp;
				if( GetImport().GetMM100UnitConverter().
						convertPercent( nTmp, rValue ) )
					nRelWidth = (sal_Int16)nTmp;
			}
			break;
		case XML_TOK_TEXT_FRAME_MIN_WIDTH:
			if( rValue.indexOf( '%' ) != -1 )
			{
				sal_Int32 nTmp;
				GetImport().GetMM100UnitConverter().convertPercent( nTmp,
																	rValue );
				nRelWidth = (sal_Int16)nTmp;
			}
			else
			{
				GetImport().GetMM100UnitConverter().convertMeasure( nWidth,
																	rValue, 0 );
			}
			bMinWidth = sal_True;
			break;
		case XML_TOK_TEXT_FRAME_HEIGHT:
			// relative heights are obsolete since SRC617. Remove them some day!
			if( rValue.indexOf( '%' ) != -1 )
			{
				sal_Int32 nTmp;
				GetImport().GetMM100UnitConverter().convertPercent( nTmp,
																	rValue );
				nRelHeight = (sal_Int16)nTmp;
			}
			else
			{
				GetImport().GetMM100UnitConverter().convertMeasure( nHeight,
																	rValue, 0 );
			}
			break;
		case XML_TOK_TEXT_FRAME_REL_HEIGHT:
			if( IsXMLToken( rValue, XML_SCALE ) )
			{
				bSyncHeight = sal_True;
			}
			else if( IsXMLToken( rValue, XML_SCALE_MIN ) )
			{
				bSyncHeight = sal_True;
				bMinHeight = sal_True;
			}
			else
			{
				sal_Int32 nTmp;
				if( GetImport().GetMM100UnitConverter().
						convertPercent( nTmp, rValue ) )
					nRelHeight = (sal_Int16)nTmp;
			}
			break;
		case XML_TOK_TEXT_FRAME_MIN_HEIGHT:
			if( rValue.indexOf( '%' ) != -1 )
			{
				sal_Int32 nTmp;
				GetImport().GetMM100UnitConverter().convertPercent( nTmp,
																	rValue );
				nRelHeight = (sal_Int16)nTmp;
			}
			else
			{
				GetImport().GetMM100UnitConverter().convertMeasure( nHeight,
																	rValue, 0 );
			}
			bMinHeight = sal_True;
			break;
		case XML_TOK_TEXT_FRAME_Z_INDEX:
			GetImport().GetMM100UnitConverter().convertNumber( nZIndex, rValue, -1 );
			break;
		case XML_TOK_TEXT_FRAME_NEXT_CHAIN_NAME:
			sNextName = rValue;
			break;
		case XML_TOK_TEXT_FRAME_HREF:
			sHRef = rValue;
			break;
		case XML_TOK_TEXT_FRAME_FILTER_NAME:
			sFilterName = rValue;
			break;
		case XML_TOK_TEXT_FRAME_TRANSFORM:
			{
				OUString sValue( rValue );
				sValue.trim();
                const OUString aRotate(GetXMLToken(XML_ROTATE));
				const sal_Int32 nRotateLen(aRotate.getLength());
				sal_Int32 nLen = sValue.getLength();
				if( nLen >= nRotateLen+3 &&
					0 == sValue.compareTo( aRotate, nRotateLen ) &&
					'(' == sValue[nRotateLen] &&
					')' == sValue[nLen-1] )
				{
					sValue = sValue.copy( nRotateLen+1, nLen-(nRotateLen+2) );
					sValue.trim();
					sal_Int32 nVal;
					if( GetImport().GetMM100UnitConverter().convertNumber( nVal, sValue ) )
						nRotation = (sal_Int16)(nVal % 360 );
				}
			}
			break;
		case XML_TOK_TEXT_FRAME_CODE:
			sCode = rValue;
			break;
		case XML_TOK_TEXT_FRAME_OBJECT:
			sObject = rValue;
			break;
		case XML_TOK_TEXT_FRAME_ARCHIVE:
			sArchive = rValue;
			break;
		case XML_TOK_TEXT_FRAME_MAY_SCRIPT:
			bMayScript = IsXMLToken( rValue, XML_TRUE );
			break;
		case XML_TOK_TEXT_FRAME_MIME_TYPE:
			sMimeType = rValue;
			break;
		case XML_TOK_TEXT_FRAME_NOTIFY_ON_UPDATE:
			sTblName = rValue;
			break;
		}
	}

	if( ( (XML_TEXT_FRAME_GRAPHIC == nType ||
		   XML_TEXT_FRAME_OBJECT == nType ||
		   XML_TEXT_FRAME_OBJECT_OLE == nType) &&
		  !sHRef.getLength() ) ||
		( XML_TEXT_FRAME_APPLET  == nType && !sCode.getLength() ) ||
        ( XML_TEXT_FRAME_PLUGIN == nType &&
          sHRef.getLength() == 0 && sMimeType.getLength() == 0 ) )
		return;	// no URL: no image or OLE object

	Create( sal_True );
}

XMLTextFrameContext_Impl::~XMLTextFrameContext_Impl()
{
}

void XMLTextFrameContext_Impl::EndElement()
{
	CreateIfNotThere();

	if( xOldTextCursor.is() )
	{
		GetImport().GetTextImport()->DeleteParagraph();
		GetImport().GetTextImport()->SetCursor( xOldTextCursor );
	}

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

	if (( nType == XML_TEXT_FRAME_APPLET || nType == XML_TEXT_FRAME_PLUGIN ) && xPropSet.is())
		GetImport().GetTextImport()->endAppletOrPlugin( xPropSet, aParamMap);
}

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

	if( XML_NAMESPACE_DRAW == nPrefix )
	{
		if ( (nType == XML_TEXT_FRAME_APPLET || nType == XML_TEXT_FRAME_PLUGIN) &&
			  IsXMLToken( rLocalName, XML_PARAM ) )
		{
			pContext = new XMLTextFrameParam_Impl( GetImport(),
											  nPrefix, rLocalName,
							 				  xAttrList, nType, aParamMap );
		}
	}
	else if( (XML_NAMESPACE_OFFICE == nPrefix) )
	{
		if( IsXMLToken( rLocalName, XML_BINARY_DATA ) )
		{
			if( !xPropSet.is() && !xBase64Stream.is() && !bCreateFailed )
			{
				switch( nType )
				{
				case XML_TEXT_FRAME_GRAPHIC:
					xBase64Stream =
						GetImport().GetStreamForGraphicObjectURLFromBase64();
					break;
				case XML_TEXT_FRAME_OBJECT_OLE:
					xBase64Stream =
						GetImport().GetStreamForEmbeddedObjectURLFromBase64();
					break;
				}
				if( xBase64Stream.is() )
					pContext = new XMLBase64ImportContext( GetImport(), nPrefix,
													rLocalName, xAttrList,
													xBase64Stream );
			}
		}
	}
    // --> OD 2009-08-17 #i100480#
    // correction of condition which also avoids warnings.
    if( !pContext &&
        ( XML_TEXT_FRAME_OBJECT == nType &&
          ( ( XML_NAMESPACE_OFFICE == nPrefix &&
              IsXMLToken( rLocalName, XML_DOCUMENT ) ) ||
            ( XML_NAMESPACE_MATH == nPrefix &&
              IsXMLToken( rLocalName, XML_MATH ) ) ) ) )
    // <--
	{
		if( !xPropSet.is() && !bCreateFailed )
		{
			XMLEmbeddedObjectImportContext *pEContext =
				new XMLEmbeddedObjectImportContext( GetImport(), nPrefix,
													rLocalName, xAttrList );
			sFilterService = pEContext->GetFilterServiceName();
			if( sFilterService.getLength() != 0 )
			{
				Create( sal_False );
				if( xPropSet.is() )
				{
					Reference < XEmbeddedObjectSupplier > xEOS( xPropSet,
																UNO_QUERY );
					OSL_ENSURE( xEOS.is(),
							"no embedded object supplier for own object" );
                    Reference<com::sun::star::lang::XComponent> aXComponent(xEOS->getEmbeddedObject());
					pEContext->SetComponent( aXComponent );
				}
			}
			pContext = pEContext;
		}
	}
	if( !pContext && xOldTextCursor.is() )	// text-box
		pContext = GetImport().GetTextImport()->CreateTextChildContext(
							GetImport(), nPrefix, rLocalName, xAttrList,
							XML_TEXT_TYPE_TEXTBOX );

	if( !pContext )
		pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );

	return pContext;
}

void XMLTextFrameContext_Impl::Characters( const OUString& rChars )
{
	if( ( XML_TEXT_FRAME_OBJECT_OLE == nType ||
		  XML_TEXT_FRAME_GRAPHIC == nType) &&
		!xPropSet.is() && !bCreateFailed )
	{
		OUString sTrimmedChars( rChars. trim() );
		if( sTrimmedChars.getLength() )
		{
			if( !xBase64Stream.is() )
			{
				if( XML_TEXT_FRAME_GRAPHIC == nType )
				{
					xBase64Stream =
						GetImport().GetStreamForGraphicObjectURLFromBase64();
				}
				else
				{
					xBase64Stream =
						GetImport().GetStreamForEmbeddedObjectURLFromBase64();
				}
				if( xBase64Stream.is() )
					bOwnBase64Stream = sal_True;
			}
			if( bOwnBase64Stream && xBase64Stream.is() )
			{
				OUString sChars;
				if( !sBase64CharsLeft.isEmpty() )
				{
					sChars = sBase64CharsLeft;
					sChars += sTrimmedChars;
					sBase64CharsLeft = OUString();
				}
				else
				{
					sChars = sTrimmedChars;
				}
				Sequence< sal_Int8 > aBuffer( (sChars.getLength() / 4) * 3 );
				sal_Int32 nCharsDecoded =
					GetImport().GetMM100UnitConverter().
						decodeBase64SomeChars( aBuffer, sChars );
				xBase64Stream->writeBytes( aBuffer );
				if( nCharsDecoded != sChars.getLength() )
					sBase64CharsLeft = sChars.copy( nCharsDecoded );
			}
		}
	}
}

void XMLTextFrameContext_Impl::SetHyperlink( const OUString& rHRef,
					   const OUString& rName,
					   const OUString& rTargetFrameName,
					   sal_Bool bMap )
{
    static ::rtl::OUString s_HyperLinkURL(
        RTL_CONSTASCII_USTRINGPARAM("HyperLinkURL"));
    static ::rtl::OUString s_HyperLinkName(
        RTL_CONSTASCII_USTRINGPARAM("HyperLinkName"));
    static ::rtl::OUString s_HyperLinkTarget(
        RTL_CONSTASCII_USTRINGPARAM("HyperLinkTarget"));
    static ::rtl::OUString s_ServerMap(
        RTL_CONSTASCII_USTRINGPARAM("ServerMap"));
	if( !xPropSet.is() )
		return;

	UniReference< XMLTextImportHelper > xTxtImp = GetImport().GetTextImport();
	Reference < XPropertySetInfo > xPropSetInfo =
		xPropSet->getPropertySetInfo();
	if( !xPropSetInfo.is() ||
        !xPropSetInfo->hasPropertyByName(s_HyperLinkURL))
		return;

	Any aAny;
	aAny <<= rHRef;
    xPropSet->setPropertyValue( s_HyperLinkURL, aAny );

    if (xPropSetInfo->hasPropertyByName(s_HyperLinkName))
	{
		aAny <<= rName;
        xPropSet->setPropertyValue(s_HyperLinkName, aAny);
	}

    if (xPropSetInfo->hasPropertyByName(s_HyperLinkTarget))
	{
		aAny <<= rTargetFrameName;
        xPropSet->setPropertyValue( s_HyperLinkTarget, aAny );
	}

    if (xPropSetInfo->hasPropertyByName(s_ServerMap))
	{
		aAny.setValue( &bMap, ::getBooleanCppuType() );
        xPropSet->setPropertyValue(s_ServerMap, aAny);
	}
}

// --> OD 2009-07-22 #i73249#
void XMLTextFrameContext_Impl::SetTitle( const OUString& rTitle )
{
    if ( xPropSet.is() )
    {
        Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
        if( xPropSetInfo->hasPropertyByName( sTitle ) )
        {
            xPropSet->setPropertyValue( sTitle, makeAny( rTitle ) );
        }
    }
}

void XMLTextFrameContext_Impl::SetDesc( const OUString& rDesc )
{
	if ( xPropSet.is() )
	{
        Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
        if( xPropSetInfo->hasPropertyByName( sDescription ) )
		{
            xPropSet->setPropertyValue( sDescription, makeAny( rDesc ) );
		}
	}
}
// <--

//-----------------------------------------------------------------------------------------------------

void XMLTextFrameContext::removeGraphicFromImportContext(const SvXMLImportContext& rContext) const
{
    const XMLTextFrameContext_Impl* pXMLTextFrameContext_Impl = dynamic_cast< const XMLTextFrameContext_Impl* >(&rContext);

    if(pXMLTextFrameContext_Impl)
    {
        try
        {
            // just dispose to delete
            uno::Reference< lang::XComponent > xComp(pXMLTextFrameContext_Impl->GetPropSet(), UNO_QUERY);

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

rtl::OUString XMLTextFrameContext::getGraphicURLFromImportContext(const SvXMLImportContext& rContext) const
{
    rtl::OUString aRetval;
    const XMLTextFrameContext_Impl* pXMLTextFrameContext_Impl = dynamic_cast< const XMLTextFrameContext_Impl* >(&rContext);

    if(pXMLTextFrameContext_Impl)
    {
        return pXMLTextFrameContext_Impl->GetHRef();
    }

    return aRetval;
}

sal_Bool XMLTextFrameContext::CreateIfNotThere()
{
	sal_Bool bRet = sal_False;
	SvXMLImportContext *pContext = &m_xImplContext;
	XMLTextFrameContext_Impl *pImpl = dynamic_cast< XMLTextFrameContext_Impl* >( pContext );
	if( pImpl )
		bRet = pImpl->CreateIfNotThere();

	return bRet;
}

sal_Bool XMLTextFrameContext::CreateIfNotThere( ::com::sun::star::uno::Reference <
		::com::sun::star::beans::XPropertySet >& rPropSet )
{
	SvXMLImportContext *pContext = &m_xImplContext;
	XMLTextFrameContext_Impl *pImpl = dynamic_cast< XMLTextFrameContext_Impl* >( pContext );
	if( pImpl )
	{
		if( pImpl->CreateIfNotThere() )
			rPropSet = pImpl->GetPropSet();
	}

	return rPropSet.is();
}

XMLTextFrameContext::XMLTextFrameContext(
		SvXMLImport& rImport,
		sal_uInt16 nPrfx, const OUString& rLName,
		const Reference< XAttributeList > & xAttrList,
		TextContentAnchorType eATyp )
:	SvXMLImportContext( rImport, nPrfx, rLName )
,   multiImageImportHelper()
,	m_xAttrList( new SvXMLAttributeList( xAttrList ) )
,	m_pHyperlink( 0 )
// --> OD 2009-07-22 #i73249#
,   m_sTitle()
,   m_sDesc()
// <--
,	m_eDefaultAnchorType( eATyp )
    // --> OD 2006-03-10 #i51726#
,   m_HasAutomaticStyleWithoutParentStyle( sal_False )
    // <--
,	m_bSupportsReplacement( sal_False )
{
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for( sal_Int16 i=0; i < nAttrCount; i++ )
	{
		const OUString& rAttrName = xAttrList->getNameByIndex( i );

		OUString aLocalName;
		sal_uInt16 nPrefix =
			GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );
        // --> OD 2006-03-10 #i51726#
        // New distinguish attribute between Writer objects and Draw objects is:
        // Draw objects have an automatic style without a parent style
        if ( XML_NAMESPACE_DRAW == nPrefix &&
             IsXMLToken( aLocalName, XML_STYLE_NAME ) )
		{
            OUString aStyleName = xAttrList->getValueByIndex( i );
            if( aStyleName.getLength() )
            {
                UniReference < XMLTextImportHelper > xTxtImport =
                                                    GetImport().GetTextImport();
                XMLPropStyleContext* pStyle( 0L );
                pStyle = xTxtImport->FindAutoFrameStyle( aStyleName );
                if ( pStyle && !pStyle->GetParentName().getLength() )
                {
                    m_HasAutomaticStyleWithoutParentStyle = sal_True;
                }
            }
        }
        // <--
        else if ( XML_NAMESPACE_TEXT == nPrefix &&
                  IsXMLToken( aLocalName, XML_ANCHOR_TYPE ) )
		{
			TextContentAnchorType eNew;
			if( XMLAnchorTypePropHdl::convert( xAttrList->getValueByIndex(i),
						eNew ) &&
				( TextContentAnchorType_AT_PARAGRAPH == eNew ||
				  TextContentAnchorType_AT_CHARACTER == eNew ||
				  TextContentAnchorType_AS_CHARACTER == eNew ||
				  TextContentAnchorType_AT_PAGE == eNew) )
				m_eDefaultAnchorType = eNew;
		}
	}
}

XMLTextFrameContext::~XMLTextFrameContext()
{
    delete m_pHyperlink;
}

void XMLTextFrameContext::EndElement()
{
    /// solve if multiple image child contexts were imported
    /// the winner is returned, if something has yet to be done with it
    const SvXMLImportContext* pWinner = solveMultipleImages();

    // #123261# see if the winner is a XMLTextFrameContext_Impl
    const XMLTextFrameContext_Impl* pImplWinner = dynamic_cast< const XMLTextFrameContext_Impl* >(pWinner);

    if(pImplWinner)
    {
        // #123261# if yes, set name now, after the winner is identified (setting at each
        // candidate may run into problems due to colliding with efforts in the target to
        // avoid double names, so only set one name at one image and not at each)
        const_cast< XMLTextFrameContext_Impl* >(pImplWinner)->SetNameForFrameFromPropSet();
    }

    SvXMLImportContext *pContext = &m_xImplContext;
    XMLTextFrameContext_Impl *pImpl = dynamic_cast< XMLTextFrameContext_Impl* >(pContext);

    if( pImpl )
    {
        pImpl->CreateIfNotThere();

        // --> OD 2009-07-22 #i73249#
//        // alternative text
//        if( m_sDesc.getLength() )
//            pImpl->SetDesc( m_sDesc );
        // svg:title
        if( m_sTitle.getLength() )
        {
            pImpl->SetTitle( m_sTitle );
        }
        if( m_sDesc.getLength() )
        {
            pImpl->SetDesc( m_sDesc );
        }
        // <--

		if( m_pHyperlink )
		{
			pImpl->SetHyperlink( m_pHyperlink->GetHRef(), m_pHyperlink->GetName(),
						  m_pHyperlink->GetTargetFrameName(), m_pHyperlink->GetMap() );
			delete m_pHyperlink;
			m_pHyperlink = 0;
		}

	}
}

SvXMLImportContext *XMLTextFrameContext::CreateChildContext(
		sal_uInt16 p_nPrefix,
		const OUString& rLocalName,
		const Reference< XAttributeList > & xAttrList )
{
	SvXMLImportContext *pContext = 0;

	if( !m_xImplContext.Is() )
	{
		// no child exists
		if( XML_NAMESPACE_DRAW == p_nPrefix )
		{
			sal_uInt16 nFrameType = USHRT_MAX;
			if( IsXMLToken( rLocalName, XML_TEXT_BOX ) )
				nFrameType = XML_TEXT_FRAME_TEXTBOX;
			else if( IsXMLToken( rLocalName, XML_IMAGE ) )
				nFrameType = XML_TEXT_FRAME_GRAPHIC;
			else if( IsXMLToken( rLocalName, XML_OBJECT ) )
				nFrameType = XML_TEXT_FRAME_OBJECT;
			else if( IsXMLToken( rLocalName, XML_OBJECT_OLE ) )
				nFrameType = XML_TEXT_FRAME_OBJECT_OLE;
			else if( IsXMLToken( rLocalName, XML_APPLET) )
				nFrameType = XML_TEXT_FRAME_APPLET;
			else if( IsXMLToken( rLocalName, XML_PLUGIN ) )
				nFrameType = XML_TEXT_FRAME_PLUGIN;
			else if( IsXMLToken( rLocalName, XML_FLOATING_FRAME ) )
				nFrameType = XML_TEXT_FRAME_FLOATING_FRAME;

			if( USHRT_MAX != nFrameType )
			{
                // --> OD 2006-03-10 #i51726#
                if ( ( XML_TEXT_FRAME_TEXTBOX == nFrameType ||
                       XML_TEXT_FRAME_GRAPHIC == nFrameType ) &&
                     m_HasAutomaticStyleWithoutParentStyle )
                // <--
				{
					Reference < XShapes > xShapes;
					pContext = GetImport().GetShapeImport()->CreateFrameChildContext(
									GetImport(), p_nPrefix, rLocalName, xAttrList, xShapes, m_xAttrList );
				}
				else if( XML_TEXT_FRAME_PLUGIN == nFrameType )
				{
				    bool bMedia = false;

				    // check, 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" ) )
				                bMedia = true;

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

	                if( bMedia )
	                {
	                    Reference < XShapes > xShapes;
					    pContext = GetImport().GetShapeImport()->CreateFrameChildContext(
									    GetImport(), p_nPrefix, rLocalName, xAttrList, xShapes, m_xAttrList );
					}
				}
				else if( XML_TEXT_FRAME_OBJECT == nFrameType ||
						 XML_TEXT_FRAME_OBJECT_OLE == nFrameType )
				{
					m_bSupportsReplacement = sal_True;
				}
                else if(XML_TEXT_FRAME_GRAPHIC == nFrameType)
                {
                    setSupportsMultipleContents(IsXMLToken(rLocalName, XML_IMAGE));
                }

                if( !pContext )
                {
                    pContext = new XMLTextFrameContext_Impl( 
                        GetImport(), 
                        p_nPrefix,
                        rLocalName, 
                        xAttrList,
                        m_eDefaultAnchorType,
                        nFrameType,
                        m_xAttrList,
                        !getSupportsMultipleContents());
                }

                m_xImplContext = pContext;

                if(getSupportsMultipleContents() && XML_TEXT_FRAME_GRAPHIC == nFrameType)
                {
                    addContent(*m_xImplContext);
                }
            }
        }
    }
    else if(getSupportsMultipleContents() && XML_NAMESPACE_DRAW == p_nPrefix && IsXMLToken(rLocalName, XML_IMAGE))
    {
        // read another image
        pContext = new XMLTextFrameContext_Impl(
            GetImport(), 
            p_nPrefix, 
            rLocalName, 
            xAttrList,
            m_eDefaultAnchorType, 
            XML_TEXT_FRAME_GRAPHIC, 
            m_xAttrList,
            false);

        m_xImplContext = pContext;
        addContent(*m_xImplContext);
    }
	else if( m_bSupportsReplacement && !m_xReplImplContext &&
			 XML_NAMESPACE_DRAW == p_nPrefix &&
			 IsXMLToken( rLocalName, XML_IMAGE ) )
	{
		// read replacement image
		Reference < XPropertySet > xPropSet;
		if( CreateIfNotThere( xPropSet ) )
		{
			pContext = new XMLReplacementImageContext( GetImport(),
								p_nPrefix, rLocalName, xAttrList, xPropSet );
			m_xReplImplContext = pContext;
		}
	}
	else if( dynamic_cast< XMLTextFrameContext_Impl* >(&m_xImplContext) )
	{
		// the child is a writer frame
		if( XML_NAMESPACE_SVG == p_nPrefix )
		{
            // --> OD 2009-07-22 #i73249#
//            bool bOld = SvXMLImport::OOo_2x >= GetImport().getGeneratorVersion();
//            if( IsXMLToken( rLocalName, bOld ? XML_DESC : XML_TITLE ) )
//                pContext = new XMLTextFrameDescContext_Impl( GetImport(), p_nPrefix, rLocalName,
//                                                         xAttrList, m_sDesc );
            const bool bOld = SvXMLImport::OOo_2x >= GetImport().getGeneratorVersion();
            if ( bOld )
            {
                if ( IsXMLToken( rLocalName, XML_DESC ) )
                {
                    pContext = new XMLTextFrameTitleOrDescContext_Impl( GetImport(),
                                                                        p_nPrefix,
                                                                        rLocalName,
                                                                        m_sTitle );
                }
            }
            else
            {
                if( IsXMLToken( rLocalName, XML_TITLE ) )
                {
                    pContext = new XMLTextFrameTitleOrDescContext_Impl( GetImport(),
                                                                        p_nPrefix,
                                                                        rLocalName,
                                                                        m_sTitle );
                }
                else if ( IsXMLToken( rLocalName, XML_DESC ) )
                {
                    pContext = new XMLTextFrameTitleOrDescContext_Impl( GetImport(),
                                                                        p_nPrefix,
                                                                        rLocalName,
                                                                        m_sDesc );
                }
            }
            // <--
		}
		else if( XML_NAMESPACE_DRAW == p_nPrefix )
		{
			Reference < XPropertySet > xPropSet;
			if( IsXMLToken( rLocalName, XML_CONTOUR_POLYGON ) )
			{
				if( CreateIfNotThere( xPropSet ) )
					pContext = new XMLTextFrameContourContext_Impl( GetImport(), p_nPrefix, rLocalName,
												  xAttrList, xPropSet, sal_False );
			}
			else if( IsXMLToken( rLocalName, XML_CONTOUR_PATH ) )
			{
				if( CreateIfNotThere( xPropSet ) )
					pContext = new XMLTextFrameContourContext_Impl( GetImport(), p_nPrefix, rLocalName,
												  xAttrList, xPropSet, sal_True );
			}
			else if( IsXMLToken( rLocalName, XML_IMAGE_MAP ) )
			{
				if( CreateIfNotThere( xPropSet ) )
					pContext = new XMLImageMapContext( GetImport(), p_nPrefix, rLocalName, xPropSet );
			}
		}
		else if( (XML_NAMESPACE_OFFICE == p_nPrefix) && IsXMLToken( rLocalName, XML_EVENT_LISTENERS ) )
		{
			// do we still have the frame object?
			Reference < XPropertySet > xPropSet;
			if( CreateIfNotThere( xPropSet ) )
			{
				// is it an event supplier?
				Reference<XEventsSupplier> xEventsSupplier(xPropSet, UNO_QUERY);
				if (xEventsSupplier.is())
				{
					// OK, we have the events, so create the context
					pContext = new XMLEventsImportContext(GetImport(), p_nPrefix,
													  rLocalName, xEventsSupplier);
				}
			}
		}
	}
	else if( p_nPrefix == XML_NAMESPACE_SVG &&	// #i68101#
				(IsXMLToken( rLocalName, XML_TITLE ) || IsXMLToken( rLocalName, XML_DESC ) ) )
	{
		pContext = m_xImplContext->CreateChildContext( p_nPrefix, rLocalName, xAttrList );
	}
	else
	{
		// the child is a drawing shape
		pContext = GetImport().GetShapeImport()->CreateFrameChildContext(
									&m_xImplContext, p_nPrefix, rLocalName, xAttrList );
	}

	if( !pContext )
		pContext = new SvXMLImportContext( GetImport(), p_nPrefix, rLocalName );

	return pContext;
}

void XMLTextFrameContext::SetHyperlink( const OUString& rHRef,
					   const OUString& rName,
					   const OUString& rTargetFrameName,
					   sal_Bool bMap )
{
	OSL_ENSURE( !m_pHyperlink, "recursive SetHyperlink call" );
	delete m_pHyperlink;
	m_pHyperlink = new XMLTextFrameContextHyperlink_Impl(
				rHRef, rName, rTargetFrameName, bMap );
}

TextContentAnchorType XMLTextFrameContext::GetAnchorType() const
{
	SvXMLImportContext *pContext = &m_xImplContext;
	XMLTextFrameContext_Impl *pImpl = dynamic_cast< XMLTextFrameContext_Impl* >( pContext );
	if( pImpl )
		return pImpl->GetAnchorType();
	else
		return m_eDefaultAnchorType;
}

Reference < XTextContent > XMLTextFrameContext::GetTextContent() const
{
	Reference < XTextContent > xTxtCntnt;
	SvXMLImportContext *pContext = &m_xImplContext;
	XMLTextFrameContext_Impl *pImpl = dynamic_cast< XMLTextFrameContext_Impl* >( pContext );
	if( pImpl )
		xTxtCntnt.set( pImpl->GetPropSet(), UNO_QUERY );

	return xTxtCntnt;
}

// --> OD 2004-08-24 #33242#
Reference < XShape > XMLTextFrameContext::GetShape() const
{
    Reference < XShape > xShape;
    SvXMLImportContext* pContext = &m_xImplContext;
    SvXMLShapeContext* pImpl = dynamic_cast< SvXMLShapeContext* >( pContext );
    if ( pImpl )
    {
        xShape = pImpl->getShape();
    }

    return xShape;
}
// <--
