/**************************************************************
 * 
 * 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 <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() )
	{
		awt::Point aPoint( 0,  0 );
		awt::Size aSize( nWidth, nHeight );
		SdXMLImExViewBox aViewBox( sViewBox,
								   GetImport().GetMM100UnitConverter());
		Any aAny;
		if( bPath )
		{
			SdXMLImExSvgDElement aPoints( sD, aViewBox, aPoint, aSize,
										  GetImport().GetMM100UnitConverter() );
			aAny <<= aPoints.GetPointSequenceSequence();
		}
		else
		{
			SdXMLImExPointsElement aPoints( sPoints, aViewBox, aPoint, aSize,
										GetImport().GetMM100UnitConverter() );
			aAny <<= aPoints.GetPointSequenceSequence();
		}

		OUString sIsPixelContour(
				RTL_CONSTASCII_USTRINGPARAM("IsPixelContour") );
		xPropSet->setPropertyValue( sContourPolyPolygon, aAny );

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

		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;

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

TYPEINIT1( XMLTextFrameContext_Impl, SvXMLImportContext );

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

	// set name
	Reference < XNamed > xNamed( xPropSet, UNO_QUERY );
	if( xNamed.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 );
		}
	}

	// 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 )
:	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 )
{
	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 )
				{
					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();

	SvXMLImportContext *pContext = &m_xImplContext;
	XMLTextFrameContext_Impl *pImpl = PTR_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	);
				}

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