/**************************************************************
 * 
 * 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 <xmlbahdl.hxx>
#include <xmloff/xmluconv.hxx>
#include <com/sun/star/uno/Any.hxx>
#include <xmloff/xmltoken.hxx>

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

using namespace ::com::sun::star::uno;
using namespace ::xmloff::token;

void lcl_xmloff_setAny( Any& rValue, sal_Int32 nValue, sal_Int8 nBytes )
{
	switch( nBytes )
	{
	case 1:
		if( nValue < SCHAR_MIN )
			nValue = SCHAR_MIN;
		else if( nValue > SCHAR_MAX )
			nValue = SCHAR_MAX;
		rValue <<= (sal_Int8)nValue;
		break;
	case 2:
		if( nValue < SHRT_MIN )
			nValue = SHRT_MIN;
		else if( nValue > SHRT_MAX )
			nValue = SHRT_MAX;
		rValue <<= (sal_Int16)nValue;
		break;
	case 4:
		rValue <<= nValue;
		break;
	}
}

sal_Bool lcl_xmloff_getAny( const Any& rValue, sal_Int32& nValue,
							sal_Int8 nBytes )
{
	sal_Bool bRet = sal_False;

	switch( nBytes )
	{
	case 1:
		{
			sal_Int8 nValue8 = 0;
			bRet = rValue >>= nValue8;
			nValue = nValue8;
		}
		break;
	case 2:
		{
			sal_Int16 nValue16 = 0;
			bRet = rValue >>= nValue16;
			nValue = nValue16;
		}
		break;
	case 4:
		bRet = rValue >>= nValue;
		break;
	}

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
//
// class XMLNumberPropHdl
//

XMLNumberPropHdl::~XMLNumberPropHdl()
{
	// nothing to do
}

sal_Bool XMLNumberPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	sal_Int32 nValue = 0;
	bRet = SvXMLUnitConverter::convertNumber( nValue, rStrImpValue );
	lcl_xmloff_setAny( rValue, nValue, nBytes );

	return bRet;
}

sal_Bool XMLNumberPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;
	sal_Int32 nValue;
  	OUStringBuffer aOut;

	if( lcl_xmloff_getAny( rValue, nValue, nBytes ) )
	{
	 	SvXMLUnitConverter::convertNumber( aOut, nValue );
		rStrExpValue = aOut.makeStringAndClear();

		bRet = sal_True;
	}

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
// class XMLNumberNonePropHdl
//

XMLNumberNonePropHdl::XMLNumberNonePropHdl( sal_Int8 nB ) :
	sZeroStr( GetXMLToken(XML_NO_LIMIT) ),
	nBytes( nB )
{
}

XMLNumberNonePropHdl::XMLNumberNonePropHdl( enum XMLTokenEnum eZeroString, sal_Int8 nB ) :
	sZeroStr( GetXMLToken( eZeroString ) ),
	nBytes( nB )
{
}

XMLNumberNonePropHdl::~XMLNumberNonePropHdl()
{
	// nothing to do
}

sal_Bool XMLNumberNonePropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	sal_Int32 nValue = 0;
	if( rStrImpValue == sZeroStr )
	{
		bRet = sal_True;
	}
	else
	{
		bRet = SvXMLUnitConverter::convertNumber( nValue, rStrImpValue );
	}
	lcl_xmloff_setAny( rValue, nValue, nBytes );

	return bRet;
}

sal_Bool XMLNumberNonePropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;
	sal_Int32 nValue;

	if( lcl_xmloff_getAny( rValue, nValue, nBytes ) )
	{
	  	OUStringBuffer aOut;

		if( nValue == 0 )
		{
			aOut.append( sZeroStr );
		}
		else
		{
	 		SvXMLUnitConverter::convertNumber( aOut, nValue );
		}

		rStrExpValue = aOut.makeStringAndClear();

		bRet = sal_True;
	}

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
//
// class XMLMeasurePropHdl
//

XMLMeasurePropHdl::~XMLMeasurePropHdl()
{
	// nothing to do
}

sal_Bool XMLMeasurePropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
{
	sal_Bool bRet = sal_False;

	sal_Int32 nValue = 0;
	bRet = rUnitConverter.convertMeasure( nValue, rStrImpValue );
	lcl_xmloff_setAny( rValue, nValue, nBytes );

	return bRet;
}

sal_Bool XMLMeasurePropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
{
	sal_Bool bRet = sal_False;
	sal_Int32 nValue;
  	OUStringBuffer aOut;

	if( lcl_xmloff_getAny( rValue, nValue, nBytes ) )
	{
	 	rUnitConverter.convertMeasure( aOut, nValue );
		rStrExpValue = aOut.makeStringAndClear();

		bRet = sal_True;
	}

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
//
// class XMLBoolPropHdl
//

XMLBoolPropHdl::~XMLBoolPropHdl()
{
	// nothing to do
}

sal_Bool XMLBoolPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	sal_Bool bValue;
	bRet = SvXMLUnitConverter::convertBool( bValue, rStrImpValue );
	rValue <<= sal_Bool(bValue);

	return bRet;
}

sal_Bool XMLBoolPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;
  	OUStringBuffer aOut;
	sal_Bool bValue = sal_Bool();

	if (rValue >>= bValue)
	{
		SvXMLUnitConverter::convertBool( aOut, bValue );
		rStrExpValue = aOut.makeStringAndClear();

		bRet = sal_True;
	}

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
//
// class XMLNBoolPropHdl
//

XMLNBoolPropHdl::~XMLNBoolPropHdl()
{
	// nothing to do
}

sal_Bool XMLNBoolPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	sal_Bool bValue;
	bRet = SvXMLUnitConverter::convertBool( bValue, rStrImpValue );
	rValue <<= sal_Bool(!bValue);

	return bRet;
}

sal_Bool XMLNBoolPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;
  	OUStringBuffer aOut;
	sal_Bool bValue = sal_Bool();

	if (rValue >>= bValue)
	{
		SvXMLUnitConverter::convertBool( aOut, !bValue );
		rStrExpValue = aOut.makeStringAndClear();

		bRet = sal_True;
	}

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
//
// class XMLPercentPropHdl
//

XMLPercentPropHdl::~XMLPercentPropHdl()
{
	// nothing to do
}

sal_Bool XMLPercentPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	sal_Int32 nValue = 0;
	bRet = SvXMLUnitConverter::convertPercent( nValue, rStrImpValue );
	lcl_xmloff_setAny( rValue, nValue, nBytes );

	return bRet;
}

sal_Bool XMLPercentPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;
	sal_Int32 nValue;
  	OUStringBuffer aOut;

	if( lcl_xmloff_getAny( rValue, nValue, nBytes ) )
	{
	 	SvXMLUnitConverter::convertPercent( aOut, nValue );
		rStrExpValue = aOut.makeStringAndClear();

		bRet = sal_True;
	}

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
//
// class XMLDoublePercentPropHdl
//

sal_Bool XMLDoublePercentPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	double fValue = 1.0;

	if( rStrImpValue.indexOf( (sal_Unicode)'%' ) == -1 )
	{
		fValue = rStrImpValue.toDouble();
	}
	else
	{
		sal_Int32 nValue = 0;
		bRet = SvXMLUnitConverter::convertPercent( nValue, rStrImpValue );
		fValue = ((double)nValue) / 100.0;
	}
	rValue <<= fValue;

	return bRet;
}

sal_Bool XMLDoublePercentPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;
	double fValue = 0;

	if( rValue >>= fValue )
	{
		fValue *= 100.0;
		if( fValue > 0 ) fValue += 0.5; else	fValue -= 0.5;

		sal_Int32 nValue = (sal_Int32)fValue;

		OUStringBuffer aOut;
	 	SvXMLUnitConverter::convertPercent( aOut, nValue );
		rStrExpValue = aOut.makeStringAndClear();

		bRet = sal_True;
	}

	return bRet;
}


///////////////////////////////////////////////////////////////////////////////
//
// class XMLNegPercentPropHdl
//

XMLNegPercentPropHdl::~XMLNegPercentPropHdl()
{
	// nothing to do
}

sal_Bool XMLNegPercentPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	sal_Int32 nValue = 0;
	bRet = SvXMLUnitConverter::convertPercent( nValue, rStrImpValue );
	lcl_xmloff_setAny( rValue, 100-nValue, nBytes );

	return bRet;
}

sal_Bool XMLNegPercentPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;
	sal_Int32 nValue;
  	OUStringBuffer aOut;

	if( lcl_xmloff_getAny( rValue, nValue, nBytes ) )
	{
	 	SvXMLUnitConverter::convertPercent( aOut, 100-nValue );
		rStrExpValue = aOut.makeStringAndClear();

		bRet = sal_True;
	}

	return bRet;
}


///////////////////////////////////////////////////////////////////////////////
//
// class XMLMeasurePxPropHdl
//

XMLMeasurePxPropHdl::~XMLMeasurePxPropHdl()
{
	// nothing to do
}

sal_Bool XMLMeasurePxPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	sal_Int32 nValue = 0;
	bRet = SvXMLUnitConverter::convertMeasurePx( nValue, rStrImpValue );
	lcl_xmloff_setAny( rValue, nValue, nBytes );

	return bRet;
}

sal_Bool XMLMeasurePxPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;
	sal_Int32 nValue;
  	OUStringBuffer aOut;

	if( lcl_xmloff_getAny( rValue, nValue, nBytes ) )
	{
	 	SvXMLUnitConverter::convertMeasurePx( aOut, nValue );
		rStrExpValue = aOut.makeStringAndClear();

		bRet = sal_True;
	}

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
//
// class XMLColorPropHdl
//

XMLColorPropHdl::~XMLColorPropHdl()
{
	// Nothing to do
}

sal_Bool XMLColorPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;
	Color aColor;

	const OUString astrHSL( RTL_CONSTASCII_USTRINGPARAM( "hsl" ) );
	if( rStrImpValue.matchIgnoreAsciiCase( astrHSL ) )
	{
		sal_Int32 nOpen = rStrImpValue.indexOf( '(' );
		sal_Int32 nClose = rStrImpValue.lastIndexOf( ')' );

		if( (nOpen != -1) && (nClose > nOpen) )
		{
			const OUString aTmp( rStrImpValue.copy( nOpen+1, nClose - nOpen-1) );

			sal_Int32 nIndex = 0;

			Sequence< double > aHSL(3);
            aHSL[0] = aTmp.getToken( 0, ',', nIndex ).toDouble();
            aHSL[1] = aTmp.getToken( 0, ',', nIndex ).toDouble() / 100.0;
            aHSL[2] = aTmp.getToken( 0, ',', nIndex ).toDouble() / 100.0;
			rValue <<= aHSL;
			bRet = true;
        }
	}
	else
	{
		bRet = SvXMLUnitConverter::convertColor( aColor, rStrImpValue );
		rValue <<= (sal_Int32)( aColor.GetColor() );
	}

	return bRet;
}

sal_Bool XMLColorPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;
	Color aColor;
	sal_Int32 nColor = 0;

	OUStringBuffer aOut;
	if( rValue >>= nColor )
	{
		aColor.SetColor( nColor );

		SvXMLUnitConverter::convertColor( aOut, aColor );
		rStrExpValue = aOut.makeStringAndClear();

		bRet = sal_True;
	}
	else
	{
		Sequence< double > aHSL;
		if( (rValue >>= aHSL) && (aHSL.getLength() == 3) )
		{
			aOut.append( OUString::createFromAscii("hsl(") );
			aOut.append( aHSL[0] );
			aOut.append( OUString::createFromAscii(",") );
			aOut.append( aHSL[1] * 100.0 );
			aOut.append( OUString::createFromAscii("%,") );
			aOut.append( aHSL[2] * 100.0 );
			aOut.append( OUString::createFromAscii("%)") );
			rStrExpValue = aOut.makeStringAndClear();

			bRet = sal_True;
		}
	}

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
//
// class XMLStringPropHdl
//

XMLStringPropHdl::~XMLStringPropHdl()
{
	// Nothing to do
}

sal_Bool XMLStringPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	rValue <<= rStrImpValue;
	bRet = sal_True;

	return bRet;
}

sal_Bool XMLStringPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	if( rValue >>= rStrExpValue )
		bRet = sal_True;

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
//
// class XMLStyleNamePropHdl
//

XMLStyleNamePropHdl::~XMLStyleNamePropHdl()
{
	// Nothing to do
}

sal_Bool XMLStyleNamePropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
{
	sal_Bool bRet = sal_False;

	if( rValue >>= rStrExpValue )
	{
		rStrExpValue = rUnitConverter.encodeStyleName( rStrExpValue );
		bRet = sal_True;
	}

	return bRet;
}


///////////////////////////////////////////////////////////////////////////////
//
// class XMLDoublePropHdl
//

XMLDoublePropHdl::~XMLDoublePropHdl()
{
	// Nothing to do
}

sal_Bool XMLDoublePropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	double fDblValue;
	sal_Bool bRet = SvXMLUnitConverter::convertDouble( fDblValue, rStrImpValue );
	rValue <<= fDblValue;
	return bRet;
}

sal_Bool XMLDoublePropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	double fValue = 0;

	if( rValue >>= fValue )
	{
		OUStringBuffer aOut;
		SvXMLUnitConverter::convertDouble( aOut, fValue );
		rStrExpValue = aOut.makeStringAndClear();
		bRet = sal_True;
	}

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
//
// class XMLColorTransparentPropHdl
//

XMLColorTransparentPropHdl::XMLColorTransparentPropHdl(
    enum XMLTokenEnum eTransparent ) :
	sTransparent( GetXMLToken( 
        eTransparent != XML_TOKEN_INVALID ? eTransparent : XML_TRANSPARENT ) )
{
	// Nothing to do
}

XMLColorTransparentPropHdl::~XMLColorTransparentPropHdl()
{
	// Nothing to do
}

sal_Bool XMLColorTransparentPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	if( rStrImpValue != sTransparent )
	{
		Color aColor;
		bRet = SvXMLUnitConverter::convertColor( aColor, rStrImpValue );
		rValue <<= (sal_Int32)( aColor.GetColor() );
	}

	return bRet;
}

sal_Bool XMLColorTransparentPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;
	sal_Int32 nColor = 0;

	if( rStrExpValue == sTransparent )
		bRet = sal_False;
	else if( rValue >>= nColor )
	{
		Color aColor( nColor );
		OUStringBuffer aOut;
		SvXMLUnitConverter::convertColor( aOut, aColor );
		rStrExpValue = aOut.makeStringAndClear();

		bRet = sal_True;
	}

	return bRet;
}


///////////////////////////////////////////////////////////////////////////////
//
// class XMLIsTransparentPropHdl
//

XMLIsTransparentPropHdl::XMLIsTransparentPropHdl(
	enum XMLTokenEnum eTransparent, sal_Bool bTransPropVal ) :
	sTransparent( GetXMLToken( 
        eTransparent != XML_TOKEN_INVALID ? eTransparent : XML_TRANSPARENT ) ),
	bTransPropValue( bTransPropVal )
{
}
	
XMLIsTransparentPropHdl::~XMLIsTransparentPropHdl()
{
	// Nothing to do
}

sal_Bool XMLIsTransparentPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bValue = ( (rStrImpValue == sTransparent) == bTransPropValue);
	rValue.setValue( &bValue, ::getBooleanCppuType() );

	return sal_True;
}

sal_Bool XMLIsTransparentPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	// MIB: This looks a bit strange, because bTransPropValue == bValue should
	// do the same, but this only applies if 'true' is represented by the same
	// 8 bit value in bValue and bTransPropValue. Who will ensure this?
	sal_Bool bValue = *(sal_Bool *)rValue.getValue();
	sal_Bool bIsTrans = bTransPropValue ? bValue : !bValue;

	if( bIsTrans )
	{
		rStrExpValue = sTransparent;
		bRet = sal_True;
	}

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
//
// class XMLColorAutoPropHdl
//

XMLColorAutoPropHdl::XMLColorAutoPropHdl()
{
	// Nothing to do
}

XMLColorAutoPropHdl::~XMLColorAutoPropHdl()
{
	// Nothing to do
}

sal_Bool XMLColorAutoPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	// This is a multi property: the value might be set to AUTO_COLOR
	// already by the XMLIsAutoColorPropHdl!
	sal_Int32 nColor = 0;
	if( !(rValue >>= nColor) || -1 != nColor )
	{
		Color aColor;
		bRet = SvXMLUnitConverter::convertColor( aColor, rStrImpValue );
		if( bRet )
			rValue <<= (sal_Int32)( aColor.GetColor() );
	}

	return bRet;
}

sal_Bool XMLColorAutoPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;

	sal_Int32 nColor = 0;
	if( (rValue >>= nColor) && -1 != nColor )
	{
		Color aColor( nColor );
		OUStringBuffer aOut;
		SvXMLUnitConverter::convertColor( aOut, aColor );
		rStrExpValue = aOut.makeStringAndClear();

		bRet = sal_True;
	}

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
//
// class XMLIsAutoColorPropHdl
//

XMLIsAutoColorPropHdl::XMLIsAutoColorPropHdl()
{
}
	
XMLIsAutoColorPropHdl::~XMLIsAutoColorPropHdl()
{
	// Nothing to do
}

sal_Bool XMLIsAutoColorPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bValue;

	// An auto color overrides any other color set!
	sal_Bool bRet = SvXMLUnitConverter::convertBool( bValue, rStrImpValue );
	if( bRet && bValue )
		rValue <<= (sal_Int32)-1;

	return sal_True;
}

sal_Bool XMLIsAutoColorPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
	sal_Bool bRet = sal_False;
	sal_Int32 nColor = 0;

	if( (rValue >>= nColor) && -1 == nColor )
	{
		OUStringBuffer aOut;
		SvXMLUnitConverter::convertBool( aOut, sal_True );
		rStrExpValue = aOut.makeStringAndClear();

		bRet = sal_True;
	}

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
//
// class XMLCompareOnlyPropHdl
//

XMLCompareOnlyPropHdl::~XMLCompareOnlyPropHdl()
{
	// Nothing to do
}

sal_Bool XMLCompareOnlyPropHdl::importXML( const OUString&, Any&, const SvXMLUnitConverter& ) const
{
	DBG_ASSERT( !this, "importXML called for compare-only-property" );
	return sal_False;
}

sal_Bool XMLCompareOnlyPropHdl::exportXML( OUString&, const Any&, const SvXMLUnitConverter& ) const
{
	DBG_ASSERT( !this, "exportXML called for compare-only-property" );
	return sal_False;
}

///////////////////////////////////////////////////////////////////////////////
// class XMLNumberWithoutZeroPropHdl
//

XMLNumberWithoutZeroPropHdl::XMLNumberWithoutZeroPropHdl( sal_Int8 nB ) :
	nBytes( nB )
{
}

XMLNumberWithoutZeroPropHdl::~XMLNumberWithoutZeroPropHdl()
{
}

sal_Bool XMLNumberWithoutZeroPropHdl::importXML( 
    const OUString& rStrImpValue, 
    Any& rValue, 
    const SvXMLUnitConverter& ) const
{
	sal_Int32 nValue = 0;
    sal_Bool bRet = SvXMLUnitConverter::convertNumber( nValue, rStrImpValue );
	if( bRet )
        lcl_xmloff_setAny( rValue, nValue, nBytes );
	return bRet;
}

sal_Bool XMLNumberWithoutZeroPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{

    sal_Int32 nValue = 0;
    sal_Bool bRet = lcl_xmloff_getAny( rValue, nValue, nBytes );
    bRet &= nValue != 0;

    if( bRet )
    {
	  	OUStringBuffer aBuffer;
        SvXMLUnitConverter::convertNumber( aBuffer, nValue );
		rStrExpValue = aBuffer.makeStringAndClear();
    }

    return bRet;
}

///////////////////////////////////////////////////////////////////////////////
// class XMLNumberWithAutoInsteadZeroPropHdl
//

XMLNumberWithAutoInsteadZeroPropHdl::~XMLNumberWithAutoInsteadZeroPropHdl()
{
}

sal_Bool XMLNumberWithAutoInsteadZeroPropHdl::importXML( 
    const OUString& rStrImpValue, 
    Any& rValue, 
    const SvXMLUnitConverter& ) const
{
	sal_Int32 nValue = 0;
    sal_Bool bRet = SvXMLUnitConverter::convertNumber( nValue, rStrImpValue );
	if( bRet )
        lcl_xmloff_setAny( rValue, nValue, 2 );
	else if( rStrImpValue == GetXMLToken( XML_AUTO ) )
	{
		rValue <<= (sal_Int16)nValue;
		bRet = sal_True;
	}
	return bRet;
}

sal_Bool XMLNumberWithAutoInsteadZeroPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{

    sal_Int32 nValue = 0;
    lcl_xmloff_getAny( rValue, nValue, 2 );

	if( 0 == nValue )
		rStrExpValue = GetXMLToken( XML_AUTO );
	else
    {
		OUStringBuffer aBuffer;
		SvXMLUnitConverter::convertNumber( aBuffer, nValue );
		rStrExpValue = aBuffer.makeStringAndClear();
    }

    return sal_True;
}

