/**************************************************************
 *
 * 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:

	TYPEINFO();

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

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

TYPEINIT1( XMLTextFrameTitleOrDescContext_Impl, SvXMLImportContext );

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:

	TYPEINFO();

	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();
};

TYPEINIT1( XMLTextFrameParam_Impl, SvXMLImportContext );

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:

	TYPEINFO();

	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();
};

TYPEINIT1( XMLTextFrameContourContext_Impl, SvXMLImportContext );

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:

	TYPEINFO();

	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();
};

TYPEINIT1( XMLTextFrameContext_Impl, SvXMLImportContext );

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 ) );
		}
	}
}
// <--

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

TYPEINIT1( XMLTextFrameContext, SvXMLImportContext );

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 = PTR_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 = PTR_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( m_xImplContext->ISA( XMLTextFrameContext_Impl ) )
	{
		// 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 = PTR_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 = PTR_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 = PTR_CAST( SvXMLShapeContext, pContext );
    if ( pImpl )
    {
        xShape = pImpl->getShape();
    }

    return xShape;
}
// <--
