/**************************************************************
 *
 * 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 <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/awt/Size.hpp>
#include <com/sun/star/awt/FontDescriptor.hpp>
#include <com/sun/star/document/XLinkAuthorizer.hpp>
#include <com/sun/star/text/HoriOrientation.hpp>
#include <com/sun/star/text/VertOrientation.hpp>
// --> OD 2008-01-16 #newlistlevelattrs#
#include <com/sun/star/text/PositionAndSpaceMode.hpp>
#include <com/sun/star/text/LabelFollow.hpp>
// <--
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/style/XStyle.hpp>
#include <com/sun/star/io/XOutputStream.hpp>

#include <rtl/ustrbuf.hxx>

#include <tools/urlobj.hxx>
#include <tools/debug.hxx>
#include <tools/fontenum.hxx>

#include <xmloff/xmltkmap.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmlimp.hxx>
#include <xmloff/XMLBase64ImportContext.hxx>
#include <xmloff/xmltoken.hxx>

#include <xmloff/i18nmap.hxx>
#include <xmloff/xmluconv.hxx>
#include "fonthdl.hxx"
#include <xmloff/XMLFontStylesContext.hxx>
#include <xmloff/families.hxx>
#include <xmloff/maptype.hxx>

#include <xmloff/xmlnumi.hxx>

#define _SVSTDARR_USHORTS
#include <svl/svstdarr.hxx>


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

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;
using namespace ::xmloff::token;
using namespace ::com::sun::star::io;

static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_SYMBOL_TEXT_DISTANCE[] =
		"SymbolTextDistance";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_PARENT_NUMBERING[] =
		"ParentNumbering";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_CHAR_STYLE_NAME[] =
		"CharStyleName";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_BULLET_CHAR[] ="BulletChar";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_BULLET_RELSIZE[] = "BulletRelSize";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_GRAPHIC_SIZE[] =
		"GraphicSize";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_VERT_ORIENT[] ="VertOrient";

static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_NUMBERINGTYPE[] = "NumberingType";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_PREFIX[] = "Prefix";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_SUFFIX[] = "Suffix";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_ADJUST[] = "Adjust";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_LEFT_MARGIN[] = "LeftMargin";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_FIRST_LINE_OFFSET[] =
	"FirstLineOffset";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_BULLET_FONT[] = "BulletFont";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_GRAPHICURL[] = "GraphicURL";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_START_WITH[] = "StartWith";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_BULLET_COLOR[] = "BulletColor";
// --> OD 2008-01-15 #newlistlevelattrs#
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_POSITION_AND_SPACE_MODE[] = "PositionAndSpaceMode";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_LABEL_FOLLOWED_BY[] = "LabelFollowedBy";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_LISTTAB_STOP_POSITION[] = "ListtabStopPosition";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_FIRST_LINE_INDENT[] = "FirstLineIndent";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_INDENT_AT[] = "IndentAt";
// <--

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

class SvxXMLListLevelStyleContext_Impl;

class SvxXMLListLevelStyleAttrContext_Impl : public SvXMLImportContext
{
	SvxXMLListLevelStyleContext_Impl&	rListLevel;

public:

	SvxXMLListLevelStyleAttrContext_Impl(
			SvXMLImport& rImport, sal_uInt16 nPrfx,
		 	const OUString& rLName,
		  	const Reference< xml::sax::XAttributeList >& xAttrList,
			SvxXMLListLevelStyleContext_Impl& rLLevel	);
	virtual ~SvxXMLListLevelStyleAttrContext_Impl();

    // --> OD 2008-01-16 #newlistlevelattrs#
    virtual SvXMLImportContext *CreateChildContext(
            sal_uInt16 nPrefix, const OUString& rLocalName,
            const Reference< xml::sax::XAttributeList > & xAttrList );
    // <--
};

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

// --> OD 2008-01-16 #newlistlevelattrs#
class SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl : public SvXMLImportContext
{
    SvxXMLListLevelStyleContext_Impl&   rListLevel;

public:

    SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl(
            SvXMLImport& rImport, sal_uInt16 nPrfx,
            const OUString& rLName,
            const Reference< xml::sax::XAttributeList >& xAttrList,
            SvxXMLListLevelStyleContext_Impl& rLLevel   );
    virtual ~SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl();
};
// <--

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

enum SvxXMLTextListLevelStyleAttrTokens
{
    XML_TOK_TEXT_LEVEL_ATTR_LEVEL,
    XML_TOK_TEXT_LEVEL_ATTR_STYLE_NAME,
    XML_TOK_TEXT_LEVEL_ATTR_BULLET_CHAR,
    XML_TOK_TEXT_LEVEL_ATTR_HREF,
    XML_TOK_TEXT_LEVEL_ATTR_TYPE,
    XML_TOK_TEXT_LEVEL_ATTR_SHOW,
    XML_TOK_TEXT_LEVEL_ATTR_ACTUATE,
    XML_TOK_TEXT_LEVEL_ATTR_NUM_FORMAT,
    XML_TOK_TEXT_LEVEL_ATTR_NUM_PREFIX,
    XML_TOK_TEXT_LEVEL_ATTR_NUM_SUFFIX,
    XML_TOK_TEXT_LEVEL_ATTR_NUM_LETTER_SYNC,
    XML_TOK_TEXT_LEVEL_ATTR_START_VALUE,
    XML_TOK_TEXT_LEVEL_ATTR_DISPLAY_LEVELS,

    XML_TOK_TEXT_LEVEL_ATTR_END=XML_TOK_UNKNOWN
};

const SvXMLTokenMapEntry* lcl_getLevelAttrTokenMap()
{
    static __FAR_DATA SvXMLTokenMapEntry aLevelAttrTokenMap[] =
    {
	    { XML_NAMESPACE_TEXT, XML_LEVEL, XML_TOK_TEXT_LEVEL_ATTR_LEVEL },
	    { XML_NAMESPACE_TEXT, XML_STYLE_NAME, XML_TOK_TEXT_LEVEL_ATTR_STYLE_NAME },
	    { XML_NAMESPACE_TEXT, XML_BULLET_CHAR, XML_TOK_TEXT_LEVEL_ATTR_BULLET_CHAR },
	    { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_TEXT_LEVEL_ATTR_HREF },
	    { XML_NAMESPACE_XLINK, XML_TYPE, XML_TOK_TEXT_LEVEL_ATTR_TYPE },
	    { XML_NAMESPACE_XLINK, XML_SHOW, XML_TOK_TEXT_LEVEL_ATTR_SHOW },
	    { XML_NAMESPACE_XLINK, XML_ACTUATE, XML_TOK_TEXT_LEVEL_ATTR_ACTUATE },

	    { XML_NAMESPACE_STYLE, XML_NUM_FORMAT, XML_TOK_TEXT_LEVEL_ATTR_NUM_FORMAT },
	    { XML_NAMESPACE_STYLE, XML_NUM_PREFIX, XML_TOK_TEXT_LEVEL_ATTR_NUM_PREFIX },
	    { XML_NAMESPACE_STYLE, XML_NUM_SUFFIX, XML_TOK_TEXT_LEVEL_ATTR_NUM_SUFFIX },
	    { XML_NAMESPACE_STYLE, XML_NUM_LETTER_SYNC, XML_TOK_TEXT_LEVEL_ATTR_NUM_LETTER_SYNC },
	    { XML_NAMESPACE_TEXT, XML_START_VALUE, XML_TOK_TEXT_LEVEL_ATTR_START_VALUE },
	    { XML_NAMESPACE_TEXT, XML_DISPLAY_LEVELS, XML_TOK_TEXT_LEVEL_ATTR_DISPLAY_LEVELS },

	    XML_TOKEN_MAP_END
    };
    return aLevelAttrTokenMap;
}

class SvxXMLListLevelStyleContext_Impl : public SvXMLImportContext
{
    friend class SvxXMLListLevelStyleAttrContext_Impl;
	const OUString 		sStarBats;
	const OUString 		sStarMath;

	OUString 			sPrefix;
	OUString			sSuffix;
	OUString			sTextStyleName;
	OUString			sNumFormat;
	OUString			sNumLetterSync;
	OUString			sBulletFontName;
	OUString			sBulletFontStyleName;
	OUString			sImageURL;

	Reference < XOutputStream > xBase64Stream;

	sal_Int32			nLevel;
	sal_Int32			nSpaceBefore;
	sal_Int32			nMinLabelWidth;
	sal_Int32			nMinLabelDist;
	sal_Int32			nImageWidth;
	sal_Int32			nImageHeight;
	sal_Int16			nNumStartValue;
	sal_Int16			nNumDisplayLevels;

	sal_Int16 			eAdjust;
	sal_Int16			eBulletFontFamily;
	sal_Int16			eBulletFontPitch;
	rtl_TextEncoding	eBulletFontEncoding;
	sal_Int16			eImageVertOrient;

	sal_Unicode			cBullet;

	sal_Int16			nRelSize;
	Color				aColor;

    // --> OD 2008-01-16 #newlistlevelattrs#
    sal_Int16           ePosAndSpaceMode;
    sal_Int16           eLabelFollowedBy;
    sal_Int32           nListtabStopPosition;
    sal_Int32           nFirstLineIndent;
    sal_Int32           nIndentAt;
    // <--

	sal_Bool			bBullet : 1;
	sal_Bool			bImage : 1;
	sal_Bool			bNum : 1;
	sal_Bool			bHasColor : 1;

	void SetRelSize( sal_Int16 nRel ) { nRelSize = nRel; }
	void SetColor( sal_Int32 _aColor ) { aColor = _aColor; bHasColor = sal_True; }
	void SetSpaceBefore( sal_Int32 nSet ) { nSpaceBefore = nSet; }
	void SetMinLabelWidth( sal_Int32 nSet ) { nMinLabelWidth = nSet; }
	void SetMinLabelDist( sal_Int32 nSet ) { nMinLabelDist = nSet; }
	void SetAdjust( sal_Int16 eSet ) { eAdjust = eSet; }

	void SetBulletFontName( const OUString& rSet ) { sBulletFontName = rSet; }
	void SetBulletFontStyleName( const OUString& rSet )
		 { sBulletFontStyleName = rSet; }
	void SetBulletFontFamily( sal_Int16 eSet ) { eBulletFontFamily = eSet; }
	void SetBulletFontPitch( sal_Int16 eSet ) { eBulletFontPitch = eSet; }
	void SetBulletFontEncoding( rtl_TextEncoding eSet )
		 { eBulletFontEncoding = eSet; }

	void SetImageWidth( sal_Int32 nSet ) { nImageWidth = nSet; }
	void SetImageHeight( sal_Int32 nSet ) { nImageHeight = nSet; }
	void SetImageVertOrient( sal_Int16 eSet )
		 { eImageVertOrient = eSet; }

public:

	SvxXMLListLevelStyleContext_Impl(
			SvXMLImport& rImport, sal_uInt16 nPrfx,
			const OUString& rLName,
			const Reference< xml::sax::XAttributeList > & xAttrList );
	virtual ~SvxXMLListLevelStyleContext_Impl();

	virtual SvXMLImportContext *CreateChildContext(
			sal_uInt16 nPrefix, const OUString& rLocalName,
			const Reference< xml::sax::XAttributeList > & xAttrList );

	sal_Int32 GetLevel() const { return nLevel; }
	Sequence<beans::PropertyValue> GetProperties(
			const SvI18NMap *pI18NMap=0 );

    // --> OD 2008-01-16 #newlistlevelattrs#
    inline void SetPosAndSpaceMode( sal_Int16 eValue )
    {
        ePosAndSpaceMode = eValue;
    }
    inline void SetLabelFollowedBy( sal_Int16 eValue )
    {
        eLabelFollowedBy = eValue;
    }
    inline void SetListtabStopPosition( sal_Int32 nValue )
    {
        nListtabStopPosition = nValue;
    }
    inline void SetFirstLineIndent( sal_Int32 nValue )
    {
        nFirstLineIndent = nValue;
    }
    inline void SetIndentAt( sal_Int32 nValue )
    {
        nIndentAt = nValue;
    }
    // <--
};

SvxXMLListLevelStyleContext_Impl::SvxXMLListLevelStyleContext_Impl(
		SvXMLImport& rImport, sal_uInt16 nPrfx,
		const OUString& rLName,
		const Reference< xml::sax::XAttributeList > & xAttrList )

:	SvXMLImportContext( rImport, nPrfx, rLName )
,	sStarBats( RTL_CONSTASCII_USTRINGPARAM( "StarBats" ) )
,	sStarMath( RTL_CONSTASCII_USTRINGPARAM( "StarMath" ) )
,	sNumFormat( OUString::createFromAscii( "1" ) )
,	nLevel( -1L )
,	nSpaceBefore( 0L )
,	nMinLabelWidth( 0L )
,	nMinLabelDist( 0L )
,	nImageWidth( 0L )
,	nImageHeight( 0L )
,	nNumStartValue( 1 )
,	nNumDisplayLevels( 1 )
,	eAdjust( HoriOrientation::LEFT )
,	eBulletFontFamily( FAMILY_DONTKNOW )
,	eBulletFontPitch( PITCH_DONTKNOW )
,	eBulletFontEncoding( RTL_TEXTENCODING_DONTKNOW )
,	eImageVertOrient(0)
,	cBullet( 0 )
,	nRelSize(0)
,	aColor( 0 )
// --> OD 2008-01-16 #newlistelevelattrs#
,   ePosAndSpaceMode( PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION )
,   eLabelFollowedBy( LabelFollow::LISTTAB )
,   nListtabStopPosition( 0 )
,   nFirstLineIndent( 0 )
,   nIndentAt( 0 )
// <--
,	bBullet( sal_False )
,	bImage( sal_False )
,	bNum( sal_False )
,	bHasColor( sal_False )
{
	if( IsXMLToken( rLName, XML_LIST_LEVEL_STYLE_NUMBER ) ||
		IsXMLToken( rLName, XML_OUTLINE_LEVEL_STYLE )        )
		bNum = sal_True;
	else if( IsXMLToken( rLName, XML_LIST_LEVEL_STYLE_BULLET ) )
		bBullet = sal_True;
	else if( IsXMLToken( rLName, XML_LIST_LEVEL_STYLE_IMAGE ) )
		bImage = sal_True;

	SvXMLTokenMap aTokenMap( lcl_getLevelAttrTokenMap() );
	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 );
		const OUString& rValue = xAttrList->getValueByIndex( i );

		switch( aTokenMap.Get( nPrefix, aLocalName ) )
		{
		case XML_TOK_TEXT_LEVEL_ATTR_LEVEL:
			nLevel = rValue.toInt32();
			if( nLevel >= 1L )
				nLevel--;
			else
                nLevel = 0;
			break;
		case XML_TOK_TEXT_LEVEL_ATTR_STYLE_NAME:
			sTextStyleName = rValue;
			break;
		case XML_TOK_TEXT_LEVEL_ATTR_BULLET_CHAR:
			cBullet = rValue[0];
			break;
		case XML_TOK_TEXT_LEVEL_ATTR_HREF:
			if( bImage )
				sImageURL = rValue;
			break;
		case XML_TOK_TEXT_LEVEL_ATTR_TYPE:
		case XML_TOK_TEXT_LEVEL_ATTR_SHOW:
		case XML_TOK_TEXT_LEVEL_ATTR_ACTUATE:
			// This properties will be ignored
			break;
		case XML_TOK_TEXT_LEVEL_ATTR_NUM_FORMAT:
			if( bNum )
				sNumFormat = rValue;
			break;
		case XML_TOK_TEXT_LEVEL_ATTR_NUM_PREFIX:
			sPrefix = rValue;
			break;
		case XML_TOK_TEXT_LEVEL_ATTR_NUM_SUFFIX:
			sSuffix = rValue;
			break;
		case XML_TOK_TEXT_LEVEL_ATTR_NUM_LETTER_SYNC:
			if( bNum )
				sNumLetterSync = rValue;
			break;
		case XML_TOK_TEXT_LEVEL_ATTR_START_VALUE:
			if( bNum )
			{
				sal_Int32 nTmp = rValue.toInt32();
				nNumStartValue =
					(nTmp < 0L) ? 1 : ( (nTmp>SHRT_MAX) ? SHRT_MAX
														: (sal_Int16)nTmp );
			}
			break;
		case XML_TOK_TEXT_LEVEL_ATTR_DISPLAY_LEVELS:
			if( bNum )
			{
				sal_Int32 nTmp = rValue.toInt32();
				nNumDisplayLevels =
					(nTmp < 1L) ? 1 : ( (nTmp>SHRT_MAX) ? SHRT_MAX
														: (sal_Int16)nTmp );
			}
			break;
		}
	}
}

SvxXMLListLevelStyleContext_Impl::~SvxXMLListLevelStyleContext_Impl()
{
}

SvXMLImportContext *SvxXMLListLevelStyleContext_Impl::CreateChildContext(
		sal_uInt16 nPrefix, const OUString& rLocalName,
		const Reference< xml::sax::XAttributeList > & xAttrList )
{
	SvXMLImportContext *pContext = 0;
	if( XML_NAMESPACE_STYLE == nPrefix &&
		( IsXMLToken( rLocalName, XML_LIST_LEVEL_PROPERTIES ) ||
	   	  IsXMLToken( rLocalName, XML_TEXT_PROPERTIES ) ) )
	{
		pContext = new SvxXMLListLevelStyleAttrContext_Impl( GetImport(),
															 nPrefix,
															 rLocalName,
														  	 xAttrList,
														     *this );
	}
	else if( (XML_NAMESPACE_OFFICE == nPrefix) && xmloff::token::IsXMLToken( rLocalName,
										xmloff::token::XML_BINARY_DATA ) )
	{
		if( bImage && !sImageURL.getLength() && !xBase64Stream.is() )
		{
			xBase64Stream = GetImport().GetStreamForGraphicObjectURLFromBase64();
			if( xBase64Stream.is() )
				pContext = new XMLBase64ImportContext( GetImport(), nPrefix,
													rLocalName, xAttrList,
													xBase64Stream );
		}
	}
	if( !pContext )
	{
		pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
	}

	return pContext;
}

Sequence<beans::PropertyValue> SvxXMLListLevelStyleContext_Impl::GetProperties(
		const SvI18NMap *pI18NMap )
{
	sal_Int16 eType = NumberingType::NUMBER_NONE;

    sal_Int32 nCount = 0;
	if( bBullet )
	{
		eType = NumberingType::CHAR_SPECIAL;
        nCount = cBullet ? 15 : 14;
	}
	if( bImage )
	{
		eType = NumberingType::BITMAP;
        nCount = 15;

		if( (sImageURL.getLength() > 0L) || xBase64Stream.is() )
			nCount++;
	}
	if( bNum )
	{
		eType = NumberingType::ARABIC;
		GetImport().GetMM100UnitConverter().convertNumFormat(
				eType, sNumFormat, sNumLetterSync, sal_True );
        nCount = 15;
	}

	if( ( bBullet || bNum ) && nRelSize )
		nCount++;

	if( !bImage && bHasColor )
	{
		nCount++;
	}

    if (bBullet && sSuffix.getLength())
    {
        sal_uInt16 const nVersion(GetImport().getGeneratorVersion());
        sal_Int32 nUPD;
        sal_Int32 nBuildId;
        if (GetImport().getBuildIds(nUPD, nBuildId)
            && (   (SvXMLImport::OOo_1x == nVersion)
                || (SvXMLImport::OOo_2x == nVersion)
                || (310 == nUPD) || (320 == nUPD) || (330 == nUPD)
                || ((300 == nUPD) && (nBuildId <= 9573))))
        {
            // #i93908# OOo < 3.4 wrote a bogus suffix for bullet chars
            sSuffix = ::rtl::OUString(); // clear it
        }
    }

	Sequence<beans::PropertyValue> aPropSeq( nCount );
	if( nCount > 0 )
	{
		beans::PropertyValue *pProps = aPropSeq.getArray();
        sal_Int32 nPos = 0;
		pProps[nPos].Name =
				OUString::createFromAscii( XML_UNO_NAME_NRULE_NUMBERINGTYPE );
		pProps[nPos++].Value <<= (sal_Int16)eType ;

		pProps[nPos].Name = OUString::createFromAscii( XML_UNO_NAME_NRULE_PREFIX );
		pProps[nPos++].Value <<= sPrefix;

		pProps[nPos].Name = OUString::createFromAscii( XML_UNO_NAME_NRULE_SUFFIX );
		pProps[nPos++].Value <<= sSuffix;

		pProps[nPos].Name = OUString::createFromAscii( XML_UNO_NAME_NRULE_ADJUST );
		pProps[nPos++].Value <<= eAdjust;

		sal_Int32 nLeftMargin = nSpaceBefore + nMinLabelWidth;
		pProps[nPos].Name =
			OUString::createFromAscii( XML_UNO_NAME_NRULE_LEFT_MARGIN );
		pProps[nPos++].Value <<= (sal_Int32)nLeftMargin;

		sal_Int32 nFirstLineOffset = -nMinLabelWidth;

		pProps[nPos].Name =
				OUString::createFromAscii( XML_UNO_NAME_NRULE_FIRST_LINE_OFFSET );
		pProps[nPos++].Value <<= (sal_Int32)nFirstLineOffset;

		pProps[nPos].Name =
			OUString::createFromAscii(XML_UNO_NAME_NRULE_SYMBOL_TEXT_DISTANCE);
		pProps[nPos++].Value <<= (sal_Int16)nMinLabelDist;

        // --> OD 2008-01-16 #newlistlevelattrs#
        pProps[nPos].Name =
            OUString::createFromAscii(XML_UNO_NAME_NRULE_POSITION_AND_SPACE_MODE);
        pProps[nPos++].Value <<= (sal_Int16)ePosAndSpaceMode;
        pProps[nPos].Name =
            OUString::createFromAscii(XML_UNO_NAME_NRULE_LABEL_FOLLOWED_BY);
        pProps[nPos++].Value <<= (sal_Int16)eLabelFollowedBy;
        pProps[nPos].Name =
            OUString::createFromAscii(XML_UNO_NAME_NRULE_LISTTAB_STOP_POSITION);
        pProps[nPos++].Value <<= (sal_Int32)nListtabStopPosition;
        pProps[nPos].Name =
            OUString::createFromAscii(XML_UNO_NAME_NRULE_FIRST_LINE_INDENT);
        pProps[nPos++].Value <<= (sal_Int32)nFirstLineIndent;
        pProps[nPos].Name =
            OUString::createFromAscii(XML_UNO_NAME_NRULE_INDENT_AT);
        pProps[nPos++].Value <<= (sal_Int32)nIndentAt;
        // <--

		OUString sDisplayTextStyleName = GetImport().GetStyleDisplayName(
								XML_STYLE_FAMILY_TEXT_TEXT, sTextStyleName	);
		OUString sStyleName = sDisplayTextStyleName;
		if( sStyleName.getLength() && pI18NMap )
			sStyleName = pI18NMap->Get( SFX_STYLE_FAMILY_CHAR, sStyleName );
		pProps[nPos].Name =
				OUString::createFromAscii( XML_UNO_NAME_NRULE_CHAR_STYLE_NAME );
		pProps[nPos++].Value <<= sDisplayTextStyleName;

		if( bBullet )
		{
			awt::FontDescriptor aFDesc;
			aFDesc.Name = sBulletFontName;
			if( sBulletFontName.getLength() )
			{
				aFDesc.StyleName = sBulletFontStyleName;
				aFDesc.Family = eBulletFontFamily;
				aFDesc.Pitch = eBulletFontPitch;
				aFDesc.CharSet = eBulletFontEncoding;
				aFDesc.Weight = WEIGHT_DONTKNOW;
				//aFDesc.Transparant = sal_True;
				sal_Bool bStarSymbol = sal_False;
				if( aFDesc.Name.equalsIgnoreAsciiCase( sStarBats ) )
				{
					cBullet = GetImport().ConvStarBatsCharToStarSymbol( cBullet );
					bStarSymbol = sal_True;
				}
				else if( aFDesc.Name.equalsIgnoreAsciiCase( sStarMath ) )
				{
					cBullet = GetImport().ConvStarMathCharToStarSymbol( cBullet );
					bStarSymbol = sal_True;
				}
				if( bStarSymbol )
					aFDesc.Name =
						OUString( RTL_CONSTASCII_USTRINGPARAM("StarSymbol" ) );
			}

			if( cBullet )
			{
				OUStringBuffer sTmp(1);
				sTmp.append( cBullet );
				pProps[nPos].Name =
						OUString::createFromAscii( XML_UNO_NAME_NRULE_BULLET_CHAR );
				pProps[nPos++].Value <<= sTmp.makeStringAndClear();
			}

			pProps[nPos].Name =
					OUString::createFromAscii( XML_UNO_NAME_NRULE_BULLET_FONT );
			pProps[nPos++].Value <<= aFDesc;

		}

		if( bImage )
		{
			OUString sStr( sImageURL );
			if( sImageURL.getLength() )
			{
				sStr = GetImport().ResolveGraphicObjectURL( sImageURL,
																 sal_False );
			}
			else if( xBase64Stream.is() )
			{
				sStr = GetImport().ResolveGraphicObjectURLFromBase64( xBase64Stream );
//				xBase64Stream = 0;
			}

			if( sStr.getLength() )
			{
				pProps[nPos].Name =
						OUString::createFromAscii( XML_UNO_NAME_NRULE_GRAPHICURL );
				pProps[nPos++].Value <<= sStr;
			}

			awt::Size aSize( nImageWidth, nImageHeight );
			pProps[nPos].Name =
				OUString::createFromAscii( XML_UNO_NAME_NRULE_GRAPHIC_SIZE );
			pProps[nPos++].Value <<= aSize;

			pProps[nPos].Name =
				OUString::createFromAscii( XML_UNO_NAME_NRULE_VERT_ORIENT );
			pProps[nPos++].Value <<= (sal_Int16)eImageVertOrient;
		}

		if( bNum )
		{
			pProps[nPos].Name =
					OUString::createFromAscii( XML_UNO_NAME_NRULE_START_WITH );
			pProps[nPos++].Value <<= (sal_Int16)nNumStartValue;

			pProps[nPos].Name =
				OUString::createFromAscii(XML_UNO_NAME_NRULE_PARENT_NUMBERING);
			pProps[nPos++].Value <<= (sal_Int16)nNumDisplayLevels;
		}

		if( ( bNum || bBullet ) && nRelSize )
		{
			pProps[nPos].Name =
				OUString::createFromAscii( XML_UNO_NAME_NRULE_BULLET_RELSIZE );
			pProps[nPos++].Value <<= nRelSize;
		}

		if( !bImage && bHasColor )
		{
			pProps[nPos].Name = OUString::createFromAscii( XML_UNO_NAME_NRULE_BULLET_COLOR );
			pProps[nPos++].Value <<= (sal_Int32)aColor.GetColor();
		}

		DBG_ASSERT( nPos == nCount, "array under/overflow" );
	}

	return aPropSeq;
}

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

enum SvxXMLStyleAttributesAttrTokens
{
	XML_TOK_STYLE_ATTRIBUTES_ATTR_SPACE_BEFORE,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_MIN_LABEL_WIDTH,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_MIN_LABEL_DIST,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_TEXT_ALIGN,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_NAME,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_FAMILY,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_FAMILY_GENERIC,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_STYLENAME,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_PITCH,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_CHARSET,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_VERTICAL_POS,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_VERTICAL_REL,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_WIDTH,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_HEIGHT,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_COLOR,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_WINDOW_FONT_COLOR,
	XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_SIZE,
    // --> OD 2008-01-16 #newlistlevelattrs#
    XML_TOK_STYLE_ATTRIBUTES_ATTR_POSITION_AND_SPACE_MODE,
    // <--

	XML_TOK_STYLE_ATTRIBUTES_ATTR_END=XML_TOK_UNKNOWN
};
const SvXMLTokenMapEntry* lcl_getStyleAttributesAttrTokenMap()
{
    static __FAR_DATA SvXMLTokenMapEntry aStyleAttributesAttrTokenMap[] =
    {
	    { XML_NAMESPACE_TEXT, XML_SPACE_BEFORE,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_SPACE_BEFORE },
	    { XML_NAMESPACE_TEXT, XML_MIN_LABEL_WIDTH,
	  		    XML_TOK_STYLE_ATTRIBUTES_ATTR_MIN_LABEL_WIDTH },
	    { XML_NAMESPACE_TEXT, XML_MIN_LABEL_DISTANCE,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_MIN_LABEL_DIST },
	    { XML_NAMESPACE_FO, XML_TEXT_ALIGN,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_TEXT_ALIGN },
	    { XML_NAMESPACE_STYLE, XML_FONT_NAME,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_NAME },
	    { XML_NAMESPACE_FO, XML_FONT_FAMILY,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_FAMILY },
	    { XML_NAMESPACE_STYLE, XML_FONT_FAMILY_GENERIC,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_FAMILY_GENERIC },
	    { XML_NAMESPACE_STYLE, XML_FONT_STYLE_NAME,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_STYLENAME },
	    { XML_NAMESPACE_STYLE, XML_FONT_PITCH,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_PITCH },
	    { XML_NAMESPACE_STYLE, XML_FONT_CHARSET,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_CHARSET },
	    { XML_NAMESPACE_STYLE, XML_VERTICAL_POS,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_VERTICAL_POS },
	    { XML_NAMESPACE_STYLE, XML_VERTICAL_REL,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_VERTICAL_REL },
	    { XML_NAMESPACE_FO, XML_WIDTH,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_WIDTH },
	    { XML_NAMESPACE_FO, XML_HEIGHT,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_HEIGHT },
	    { XML_NAMESPACE_FO, XML_COLOR,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_COLOR },
	    { XML_NAMESPACE_STYLE, XML_USE_WINDOW_FONT_COLOR,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_WINDOW_FONT_COLOR },
	    { XML_NAMESPACE_FO, XML_FONT_SIZE,
			    XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_SIZE },
        // --> OD 2008-01-16 #newlistlevelattrs#
        { XML_NAMESPACE_TEXT, XML_LIST_LEVEL_POSITION_AND_SPACE_MODE,
                XML_TOK_STYLE_ATTRIBUTES_ATTR_POSITION_AND_SPACE_MODE },
        // <--

	    XML_TOKEN_MAP_END
    };
    return aStyleAttributesAttrTokenMap;
}
SvxXMLListLevelStyleAttrContext_Impl::SvxXMLListLevelStyleAttrContext_Impl(
		SvXMLImport& rImport, sal_uInt16 nPrfx,
		const OUString& rLName,
		const Reference< xml::sax::XAttributeList > & xAttrList,
		SvxXMLListLevelStyleContext_Impl& rLLevel ) :
	SvXMLImportContext( rImport, nPrfx, rLName ),
	rListLevel( rLLevel )
{
	SvXMLTokenMap aTokenMap( lcl_getStyleAttributesAttrTokenMap() );
	SvXMLUnitConverter& rUnitConv = GetImport().GetMM100UnitConverter();

	OUString sFontName, sFontFamily, sFontStyleName, sFontFamilyGeneric,
			 sFontPitch, sFontCharset;
	OUString sVerticalPos, sVerticalRel;

	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 );
		const OUString& rValue = xAttrList->getValueByIndex( i );

		sal_Int32 nVal;
		switch( aTokenMap.Get( nPrefix, aLocalName ) )
		{
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_SPACE_BEFORE:
			if( rUnitConv.convertMeasure( nVal, rValue, SHRT_MIN, SHRT_MAX ) )
				rListLevel.SetSpaceBefore( nVal );
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_MIN_LABEL_WIDTH:
			if( rUnitConv.convertMeasure( nVal, rValue, 0, SHRT_MAX ) )
				rListLevel.SetMinLabelWidth( nVal );
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_MIN_LABEL_DIST:
			if( rUnitConv.convertMeasure( nVal, rValue, 0, USHRT_MAX ) )
				rListLevel.SetMinLabelDist( nVal );
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_TEXT_ALIGN:
			if( rValue.getLength() )
			{
				sal_Int16 eAdjust = HoriOrientation::LEFT;
				if( IsXMLToken( rValue, XML_CENTER ) )
					eAdjust = HoriOrientation::CENTER;
				else if( IsXMLToken( rValue, XML_END ) )
					eAdjust = HoriOrientation::RIGHT;
				rListLevel.SetAdjust( eAdjust );
			}
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_NAME:
			sFontName = rValue;
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_FAMILY:
			sFontFamily = rValue;
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_FAMILY_GENERIC:
			sFontFamilyGeneric = rValue;
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_STYLENAME:
			sFontStyleName = rValue;
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_PITCH:
			sFontPitch = rValue;
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_CHARSET:
			sFontCharset = rValue;
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_VERTICAL_POS:
			sVerticalPos = rValue;
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_VERTICAL_REL:
			sVerticalRel = rValue;
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_WIDTH:
			if( rUnitConv.convertMeasure( nVal, rValue, 0, SAL_MAX_INT32) )
				rListLevel.SetImageWidth( nVal );
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_HEIGHT:
			if( rUnitConv.convertMeasure( nVal, rValue, 0, SAL_MAX_INT32) )
				rListLevel.SetImageHeight( nVal );
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_COLOR:
			{
				Color aColor;
				if( SvXMLUnitConverter::convertColor( aColor, rValue ) )
					rListLevel.SetColor( (sal_Int32)aColor.GetColor() );
			}
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_WINDOW_FONT_COLOR:
			{
				if( IsXMLToken( rValue, XML_TRUE ) )
					rListLevel.SetColor( (sal_Int32)0xffffffff );
			}
			break;
		case XML_TOK_STYLE_ATTRIBUTES_ATTR_FONT_SIZE:
			if(SvXMLUnitConverter::convertPercent( nVal, rValue ) )
				rListLevel.SetRelSize( (sal_Int16)nVal );
			break;
        // --> OD 2008-01-16 #newlistlevelattrs#
        case XML_TOK_STYLE_ATTRIBUTES_ATTR_POSITION_AND_SPACE_MODE:
            {
                sal_Int16 ePosAndSpaceMode = PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION;
                if( IsXMLToken( rValue, XML_LABEL_ALIGNMENT ) )
                    ePosAndSpaceMode = PositionAndSpaceMode::LABEL_ALIGNMENT;
                rListLevel.SetPosAndSpaceMode( ePosAndSpaceMode );
            }
            break;
        // <--
		}
	}

	if( sFontName.getLength() )
	{
		const XMLFontStylesContext *pFontDecls =
			GetImport().GetTextImport()->GetFontDecls();
		if( pFontDecls )
		{
			::std::vector < XMLPropertyState > aProps;
			if( pFontDecls->FillProperties( sFontName, aProps, 0, 1, 2, 3, 4 ) )
			{
				OUString sTmp;
				sal_Int16 nTmp = 0;
				::std::vector< XMLPropertyState >::iterator i;
				for( i = aProps.begin(); i != aProps.end(); i++ )
				{
					switch( i->mnIndex )
					{
					case 0:
						i->maValue >>= sTmp;
						rListLevel.SetBulletFontName( sTmp);
						break;
					case 1:
						i->maValue >>= sTmp;
						rListLevel.SetBulletFontStyleName( sTmp );
						break;
					case 2:
						i->maValue >>= nTmp;
						rListLevel.SetBulletFontFamily( nTmp );
						break;
					case 3:
						i->maValue >>= nTmp;
						rListLevel.SetBulletFontPitch( nTmp );
						break;
					case 4:
						i->maValue >>= nTmp;
						rListLevel.SetBulletFontEncoding( nTmp );
						break;
					}
				}
			}
		}
	}
	if( sFontFamily.getLength() )
	{
		String sEmpty;
		Any aAny;

		XMLFontFamilyNamePropHdl aFamilyNameHdl;
		if( aFamilyNameHdl.importXML( sFontFamily, aAny, rUnitConv ) )
		{
			OUString sTmp;
			aAny >>= sTmp;
			rListLevel.SetBulletFontName( sTmp);
		}

		XMLFontFamilyPropHdl aFamilyHdl;
		if( sFontFamilyGeneric.getLength() &&
			aFamilyHdl.importXML( sFontFamilyGeneric, aAny, rUnitConv  ) )
		{
			sal_Int16 nTmp = 0;
			aAny >>= nTmp;
			rListLevel.SetBulletFontFamily( nTmp );
		}

		if( sFontStyleName.getLength() )
			rListLevel.SetBulletFontStyleName( sFontStyleName );

		XMLFontPitchPropHdl aPitchHdl;
		if( sFontPitch.getLength() &&
			aPitchHdl.importXML( sFontPitch, aAny, rUnitConv  ) )
		{
			sal_Int16 nTmp = 0;
			aAny >>= nTmp;
			rListLevel.SetBulletFontPitch( nTmp );
		}

		XMLFontEncodingPropHdl aEncHdl;
		if( sFontCharset.getLength() &&
			aEncHdl.importXML( sFontCharset, aAny, rUnitConv  ) )
		{
			sal_Int16 nTmp = 0;
			aAny >>= nTmp;
			rListLevel.SetBulletFontEncoding( nTmp );
		}
	}

	sal_Int16 eVertOrient = VertOrientation::LINE_CENTER;
	if( sVerticalPos.getLength() )
	{
		if( IsXMLToken( sVerticalPos, XML_TOP ) )
			eVertOrient = VertOrientation::LINE_TOP;
		else if( IsXMLToken( sVerticalPos, XML_BOTTOM ) )
			eVertOrient = VertOrientation::LINE_BOTTOM;
	}
	if( sVerticalRel.getLength() )
	{
		if( IsXMLToken( sVerticalRel, XML_BASELINE ) )
		{
			// TOP and BOTTOM are exchanged for a baseline relation
			switch( eVertOrient  )
			{
			case VertOrientation::LINE_TOP:
				eVertOrient = VertOrientation::BOTTOM;
				break;
			case VertOrientation::LINE_CENTER:
				eVertOrient = VertOrientation::CENTER;
				break;
			case VertOrientation::LINE_BOTTOM:
				eVertOrient = VertOrientation::TOP;
				break;
			}
		}
		else if( IsXMLToken( sVerticalRel, XML_CHAR ) )
		{
			switch( eVertOrient  )
			{
			case VertOrientation::LINE_TOP:
				eVertOrient = VertOrientation::CHAR_TOP;
				break;
			case VertOrientation::LINE_CENTER:
				eVertOrient = VertOrientation::CHAR_CENTER;
				break;
			case VertOrientation::LINE_BOTTOM:
				eVertOrient = VertOrientation::CHAR_BOTTOM;
				break;
			}
		}
	}
	rListLevel.SetImageVertOrient( eVertOrient );
}

SvxXMLListLevelStyleAttrContext_Impl::~SvxXMLListLevelStyleAttrContext_Impl()
{
}

// --> OD 2008-01-16 #newlistlevelattrs#
SvXMLImportContext* SvxXMLListLevelStyleAttrContext_Impl::CreateChildContext(
        sal_uInt16 nPrefix, const OUString& rLocalName,
        const Reference< xml::sax::XAttributeList > & xAttrList )
{
    SvXMLImportContext *pContext = 0;
    if ( XML_NAMESPACE_STYLE == nPrefix &&
         IsXMLToken( rLocalName, XML_LIST_LEVEL_LABEL_ALIGNMENT ) )
    {
        pContext = new SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl( GetImport(),
                                                             nPrefix,
                                                             rLocalName,
                                                             xAttrList,
                                                             rListLevel );
    }
    if( !pContext )
    {
        pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
    }

    return pContext;
}
// <--

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

// --> OD 2008-01-16 #newlistlevelattrs#
enum SvxXMLStyleAttributesLabelAlignmentAttrTokens
{
    XML_TOK_STYLE_ATTRIBUTES_ATTR_LABEL_FOLLOWED_BY,
    XML_TOK_STYLE_ATTRIBUTES_ATTR_LISTTAB_STOP_POSITION,
    XML_TOK_STYLE_ATTRIBUTES_ATTR_FIRST_LINE_INDENT,
    XML_TOK_STYLE_ATTRIBUTES_ATTR_INDENT_AT,

    XML_TOK_STYLE_ATTRIBUTES_LABEL_ALIGNMENT_ATTR_END=XML_TOK_UNKNOWN
};
const SvXMLTokenMapEntry* lcl_getStyleAlignmentAttributesAttrTokenMap()
{
    static __FAR_DATA SvXMLTokenMapEntry aStyleAlignmentAttributesAttrTokenMap[] =
    {
        { XML_NAMESPACE_TEXT, XML_LABEL_FOLLOWED_BY,
                XML_TOK_STYLE_ATTRIBUTES_ATTR_LABEL_FOLLOWED_BY },
        { XML_NAMESPACE_TEXT, XML_LIST_TAB_STOP_POSITION,
                XML_TOK_STYLE_ATTRIBUTES_ATTR_LISTTAB_STOP_POSITION },
        { XML_NAMESPACE_FO, XML_TEXT_INDENT,
                XML_TOK_STYLE_ATTRIBUTES_ATTR_FIRST_LINE_INDENT },
        { XML_NAMESPACE_FO, XML_MARGIN_LEFT,
                XML_TOK_STYLE_ATTRIBUTES_ATTR_INDENT_AT },

        XML_TOKEN_MAP_END
    };
    return aStyleAlignmentAttributesAttrTokenMap;
}
SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl::SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl(
        SvXMLImport& rImport, sal_uInt16 nPrfx,
        const OUString& rLName,
        const Reference< xml::sax::XAttributeList > & xAttrList,
        SvxXMLListLevelStyleContext_Impl& rLLevel ) :
    SvXMLImportContext( rImport, nPrfx, rLName ),
    rListLevel( rLLevel )
{
    SvXMLTokenMap aTokenMap( lcl_getStyleAlignmentAttributesAttrTokenMap() );
    SvXMLUnitConverter& rUnitConv = GetImport().GetMM100UnitConverter();

    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 );
        const OUString& rValue = xAttrList->getValueByIndex( i );

        sal_Int32 nVal;
        switch( aTokenMap.Get( nPrefix, aLocalName ) )
        {
        case XML_TOK_STYLE_ATTRIBUTES_ATTR_LABEL_FOLLOWED_BY:
            {
                sal_Int16 eLabelFollowedBy = LabelFollow::LISTTAB;
                if( IsXMLToken( rValue, XML_SPACE ) )
                    eLabelFollowedBy = LabelFollow::SPACE;
                else if( IsXMLToken( rValue, XML_NOTHING ) )
                    eLabelFollowedBy = LabelFollow::NOTHING;
                rListLevel.SetLabelFollowedBy( eLabelFollowedBy );
            }
            break;
        case XML_TOK_STYLE_ATTRIBUTES_ATTR_LISTTAB_STOP_POSITION:
            if( rUnitConv.convertMeasure( nVal, rValue, 0, SHRT_MAX ) )
                rListLevel.SetListtabStopPosition( nVal );
            break;
        case XML_TOK_STYLE_ATTRIBUTES_ATTR_FIRST_LINE_INDENT:
            if( rUnitConv.convertMeasure( nVal, rValue, SHRT_MIN, SHRT_MAX ) )
                rListLevel.SetFirstLineIndent( nVal );
            break;
        case XML_TOK_STYLE_ATTRIBUTES_ATTR_INDENT_AT:
            if( rUnitConv.convertMeasure( nVal, rValue, SHRT_MIN, SHRT_MAX ) )
                rListLevel.SetIndentAt( nVal );
            break;
        }
    }
}

SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl::~SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl()
{
}
// <--

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

typedef SvxXMLListLevelStyleContext_Impl *SvxXMLListLevelStyleContext_ImplPtr;
SV_DECL_PTRARR( SvxXMLListStyle_Impl, SvxXMLListLevelStyleContext_ImplPtr,
				10, 5 )

void SvxXMLListStyleContext::SetAttribute( sal_uInt16 nPrefixKey,
										   const OUString& rLocalName,
										   const OUString& rValue )
{
	if( XML_NAMESPACE_TEXT == nPrefixKey &&
		IsXMLToken( rLocalName, XML_CONSECUTIVE_NUMBERING ) )
	{
		bConsecutive = IsXMLToken( rValue, XML_TRUE );
	}
	else
	{
		SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
	}
}


SvxXMLListStyleContext::SvxXMLListStyleContext( SvXMLImport& rImport,
		sal_uInt16 nPrfx,
		const OUString& rLName,
		const Reference< xml::sax::XAttributeList > & xAttrList,
		sal_Bool bOutl )
:	SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, bOutl ? XML_STYLE_FAMILY_TEXT_OUTLINE : XML_STYLE_FAMILY_TEXT_LIST )
,	sIsPhysical( RTL_CONSTASCII_USTRINGPARAM( "IsPhysical" ) )
,	sNumberingRules( RTL_CONSTASCII_USTRINGPARAM( "NumberingRules" ) )
,	sName( RTL_CONSTASCII_USTRINGPARAM( "Name" ) )
,	sIsContinuousNumbering( RTL_CONSTASCII_USTRINGPARAM( "IsContinuousNumbering" ) )
,	pLevelStyles( 0 )
,	nLevels( 0 )
,	bConsecutive( sal_False )
,	bOutline( bOutl )
{
}

SvxXMLListStyleContext::~SvxXMLListStyleContext()
{
	if( pLevelStyles )
	{
		while( pLevelStyles->Count() )
		{
			sal_uInt16 n = pLevelStyles->Count() - 1;
			SvxXMLListLevelStyleContext_Impl *pStyle = (*pLevelStyles)[n];
			pLevelStyles->Remove( n, 1 );
			pStyle->ReleaseRef();
		}
	}

	delete pLevelStyles;
}

TYPEINIT1( SvxXMLListStyleContext, SvXMLStyleContext );

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

	if( XML_NAMESPACE_TEXT == nPrefix &&
		( bOutline
		  	? IsXMLToken( rLocalName, XML_OUTLINE_LEVEL_STYLE )
		  	: ( IsXMLToken( rLocalName, XML_LIST_LEVEL_STYLE_NUMBER ) ||
				IsXMLToken( rLocalName, XML_LIST_LEVEL_STYLE_BULLET ) ||
			 	IsXMLToken( rLocalName, XML_LIST_LEVEL_STYLE_IMAGE )    ) ) )
	{
		SvxXMLListLevelStyleContext_Impl *pLevelStyle =
			new SvxXMLListLevelStyleContext_Impl( GetImport(), nPrefix,
												  rLocalName, xAttrList );
		if( !pLevelStyles )
			pLevelStyles = new SvxXMLListStyle_Impl;
		pLevelStyles->Insert( pLevelStyle, pLevelStyles->Count() );
		pLevelStyle->AddRef();

		pContext = pLevelStyle;
	}
	else
	{
		pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
	}

	return pContext;
}

void SvxXMLListStyleContext::FillUnoNumRule(
		const Reference< container::XIndexReplace > & rNumRule,
		const SvI18NMap *pI18NMap ) const
{
	try
	{
		if( pLevelStyles && rNumRule.is() )
		{
			sal_uInt16 nCount = pLevelStyles->Count();
			sal_Int32 l_nLevels = rNumRule->getCount();
			for( sal_uInt16 i=0; i < nCount; i++ )
			{
				SvxXMLListLevelStyleContext_Impl *pLevelStyle =
					(*pLevelStyles)[i];
				sal_Int32 nLevel = pLevelStyle->GetLevel();
				if( nLevel >= 0 && nLevel < l_nLevels )
				{
					Sequence<beans::PropertyValue> aProps =
						pLevelStyle->GetProperties( pI18NMap );
					Any aAny;
					aAny <<= aProps;
					// Validate any URLs
					for( sal_Int32 j = 0; j < aProps.getLength(); j++ ) {
						if ( aProps[ j ].Name.equalsAscii( "GraphicURL" ) ) {
							OUString aURL;
							aProps[ j ].Value >>= aURL;
							uno::Reference< com::sun::star::document::XLinkAuthorizer > xLinkAuthorizer( GetImport().GetModel(), uno::UNO_QUERY );
							if ( xLinkAuthorizer.is() ) {
								if ( !xLinkAuthorizer->authorizeLinks( aURL ) )
									throw uno::RuntimeException();
							}
						}
					}
					rNumRule->replaceByIndex( nLevel, aAny );
				}
			}
		}

		Reference < XPropertySet > xPropSet( rNumRule, UNO_QUERY );
		Reference< XPropertySetInfo > xPropSetInfo;
		if (xPropSet.is())
			xPropSetInfo = xPropSet->getPropertySetInfo();
		if( xPropSetInfo.is() &&
			xPropSetInfo->hasPropertyByName( sIsContinuousNumbering ) )
		{
			Any aAny;
			sal_Bool bTmp = bConsecutive;
			aAny.setValue( &bTmp, ::getBooleanCppuType() );
			xPropSet->setPropertyValue( sIsContinuousNumbering, aAny );
		}
	}
	catch( Exception& )
	{
		DBG_ERROR( "SvxXMLListStyleContext::FillUnoNumRule - Exception catched" );
	}
}

void SvxXMLListStyleContext::CreateAndInsertLate( sal_Bool bOverwrite )
{
	if( bOutline )
	{
		if( bOverwrite )
		{
			const Reference< XIndexReplace >& rNumRule =
				GetImport().GetTextImport()->GetChapterNumbering();
			// We don't set xNumberingRules here, to avoid using them
			// as numbering rules.
			if( rNumRule.is() )
				FillUnoNumRule( rNumRule, 0 );
		}
	}
	else
	{
		Reference < XStyle > xStyle;
		const OUString& rName = GetDisplayName();
		if( 0 == rName.getLength() )
		{
			SetValid( sal_False );
			return;
		}

		const Reference < XNameContainer >& rNumStyles =
				GetImport().GetTextImport()->GetNumberingStyles();
		if( !rNumStyles.is() )
		{
			SetValid( sal_False );
			return;
		}

		sal_Bool bNew = sal_False;
		if( rNumStyles->hasByName( rName ) )
		{
			Any aAny = rNumStyles->getByName( rName );
			aAny >>= xStyle;
		}
		else
		{
			Reference< XMultiServiceFactory > xFactory( GetImport().GetModel(),
														UNO_QUERY );
			DBG_ASSERT( xFactory.is(), "no factory" );
			if( !xFactory.is() )
				return;

			Reference < XInterface > xIfc = xFactory->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.NumberingStyle")) );
			if( !xIfc.is() )
				return;
			Reference < XStyle > xTmp( xIfc, UNO_QUERY );
			xStyle = xTmp;
			if( !xStyle.is() )
				return;

			Any aAny;
			aAny <<= xStyle;
			rNumStyles->insertByName( rName, aAny );
			bNew = sal_True;
		}

		Reference < XPropertySet > xPropSet( xStyle, UNO_QUERY );
		Reference< XPropertySetInfo > xPropSetInfo =
			xPropSet->getPropertySetInfo();
		if( !bNew && xPropSetInfo->hasPropertyByName( sIsPhysical ) )
		{
			Any aAny = xPropSet->getPropertyValue( sIsPhysical );
			bNew = !*(sal_Bool *)aAny.getValue();
		}
		if( rName != GetName() )
			GetImport().AddStyleDisplayName( XML_STYLE_FAMILY_TEXT_LIST,
											 GetName(), rName );

		Any aAny = xPropSet->getPropertyValue( sNumberingRules );
		aAny >>= xNumRules;
		nLevels = xNumRules->getCount();
		if( bOverwrite || bNew )
		{
			FillUnoNumRule( xNumRules, 0 );
			aAny <<= xNumRules;
			xPropSet->setPropertyValue( sNumberingRules, aAny );
		}
		else
		{
			SetValid( sal_False );
		}

		SetNew( bNew );
	}
}

void SvxXMLListStyleContext::CreateAndInsertAuto() const
{
	DBG_ASSERT( !bOutline, "Outlines cannot be inserted here" );
	DBG_ASSERT( !xNumRules.is(), "Numbering Rule is existing already" );

	const OUString& rName = GetName();
	if( bOutline || xNumRules.is() || 0 == rName.getLength() )
	{
		((SvxXMLListStyleContext *)this)->SetValid( sal_False );
		return;
	}

	((SvxXMLListStyleContext *)this)->xNumRules = CreateNumRule(
		GetImport().GetModel() );
	((SvxXMLListStyleContext *)this)->nLevels = xNumRules->getCount();

	FillUnoNumRule( xNumRules, 0 );
}

Reference < XIndexReplace > SvxXMLListStyleContext::CreateNumRule(
								const Reference < XModel > & rModel )
{
	Reference<XIndexReplace> xNumRule;

	Reference< XMultiServiceFactory > xFactory( rModel, UNO_QUERY );
	DBG_ASSERT( xFactory.is(), "no factory" );
	if( !xFactory.is() )
		return xNumRule;

	Reference < XInterface > xIfc = xFactory->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.NumberingRules")) );
	if( !xIfc.is() )
		return xNumRule;

	xNumRule = Reference<XIndexReplace>( xIfc, UNO_QUERY );
	DBG_ASSERT( xNumRule.is(), "go no numbering rule" );

	return xNumRule;
}

void SvxXMLListStyleContext::SetDefaultStyle(
		const Reference < XIndexReplace > & rNumRule,
		sal_Int16 nLevel,
		sal_Bool bOrdered )
{
	Sequence<beans::PropertyValue> aPropSeq( bOrdered ? 1 : 4  );
	beans::PropertyValue *pProps = aPropSeq.getArray();

	pProps->Name =
				OUString::createFromAscii( XML_UNO_NAME_NRULE_NUMBERINGTYPE );
	(pProps++)->Value <<= (sal_Int16)(bOrdered ? NumberingType::ARABIC
									  		   : NumberingType::CHAR_SPECIAL );
	if( !bOrdered )
	{
		// TODO: Bullet-Font
		//aNumFmt.SetBulletFont( &SwNumRule::GetDefBulletFont() );
		awt::FontDescriptor aFDesc;
		aFDesc.Name = OUString(
#if defined UNX
						RTL_CONSTASCII_USTRINGPARAM( "starbats" )
#else
						RTL_CONSTASCII_USTRINGPARAM( "StarBats" )
#endif
										);
		aFDesc.Family = FAMILY_DONTKNOW ;
		aFDesc.Pitch = PITCH_DONTKNOW ;
		aFDesc.CharSet = RTL_TEXTENCODING_SYMBOL ;
		aFDesc.Weight = WEIGHT_DONTKNOW;
		//aFDesc.Transparant = sal_True;
		pProps->Name =
					OUString::createFromAscii( XML_UNO_NAME_NRULE_BULLET_FONT );
		(pProps++)->Value <<= aFDesc;

		OUStringBuffer sTmp(1);
		sTmp.append( (sal_Unicode)(0xF000 + 149) );
		pProps->Name =
					OUString::createFromAscii( XML_UNO_NAME_NRULE_BULLET_CHAR );
		(pProps++)->Value <<= sTmp.makeStringAndClear();
		pProps->Name =
				OUString::createFromAscii( XML_UNO_NAME_NRULE_CHAR_STYLE_NAME );
		(pProps++)->Value <<=
			OUString( RTL_CONSTASCII_USTRINGPARAM( "Numbering Symbols" ) );
	}

	Any aAny;
	aAny <<= aPropSeq;
	rNumRule->replaceByIndex( nLevel, aAny );
}
