/**************************************************************
 * 
 * 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 PropertyMap.hxx with this define
// to create the maps
#ifndef _PROPERTYMAP_HXX_
#define XML_SCH_CREATE_GLOBAL_MAPS
#include "PropertyMap.hxx"
#undef XML_SCH_CREATE_GLOBAL_MAPS
#endif

#include "XMLChartPropertySetMapper.hxx"
#include "SchXMLTools.hxx"
#include <xmloff/EnumPropertyHdl.hxx>
#include <xmloff/XMLConstantsPropertyHandler.hxx>
#include <xmloff/attrlist.hxx>
#include <xmloff/nmspmap.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/shapeimport.hxx>
#include <xmloff/NamedBoolPropertyHdl.hxx>
#include <xmloff/xmlexp.hxx>
#include <xmloff/xmltoken.hxx>
#include "XMLErrorIndicatorPropertyHdl.hxx"
#include "XMLErrorBarStylePropertyHdl.hxx"
#include "XMLTextOrientationHdl.hxx"
#include "XMLSymbolTypePropertyHdl.hxx"
#include "XMLAxisPositionPropertyHdl.hxx"
#include <com/sun/star/chart/ChartAxisMarks.hpp>
#include <com/sun/star/chart/ChartDataCaption.hpp>
#include <com/sun/star/chart/ChartSymbolType.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/drawing/LineJoint.hpp>
#include <com/sun/star/chart/ChartDataRowSource.hpp>
#include <com/sun/star/chart/ChartAxisPosition.hpp>

// header for any2enum
#include <comphelper/extract.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/math.hxx>

#define SCH_XML_SETFLAG( status, flag )   	(status)|= (flag)
#define SCH_XML_UNSETFLAG( status, flag )   (status) = ((status) | (flag)) - (flag)

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

// the following class implementations are in this file:
//
// * XMLChartPropHdlFactory
// * XMLChartPropertySetMapper
// * XMLChartExportPropertyMapper
// * XMLChartImportPropertyMapper
// * SchXMLStyleExport

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

XMLChartPropHdlFactory::~XMLChartPropHdlFactory()
{
}

const XMLPropertyHandler* XMLChartPropHdlFactory::GetPropertyHandler( sal_Int32 nType ) const
{
	const XMLPropertyHandler* pHdl = XMLPropertyHandlerFactory::GetPropertyHandler( nType );
	if( ! pHdl )
	{
		switch( nType )
		{
            case XML_SCH_TYPE_AXIS_POSITION:
                pHdl = new XMLAxisPositionPropertyHdl( false );
                break;
            case XML_SCH_TYPE_AXIS_POSITION_VALUE:
                pHdl = new XMLAxisPositionPropertyHdl( true );
                break;

            case XML_SCH_TYPE_AXIS_LABEL_POSITION:
                pHdl = new XMLEnumPropertyHdl( aXMLChartAxisLabelPositionEnumMap,
											   ::getCppuType((const chart::ChartAxisLabelPosition*)0) );
                break;

            case XML_SCH_TYPE_TICK_MARK_POSITION:
                pHdl = new XMLEnumPropertyHdl( aXMLChartAxisMarkPositionEnumMap,
											   ::getCppuType((const chart::ChartAxisMarkPosition*)0) );
                break;

			case XML_SCH_TYPE_AXIS_ARRANGEMENT:
				pHdl = new XMLEnumPropertyHdl( aXMLChartAxisArrangementEnumMap,
											   ::getCppuType((const chart::ChartAxisArrangeOrderType*)0) );
				break;

			case XML_SCH_TYPE_ERROR_BAR_STYLE:
				// here we have a constant rather than an enum
				pHdl = new XMLErrorBarStylePropertyHdl( aXMLChartErrorBarStyleEnumMap,
                                               ::getCppuType((const sal_Int32*)0) );
				break;

			case XML_SCH_TYPE_REGRESSION_TYPE:
				pHdl = new XMLEnumPropertyHdl( aXMLChartRegressionCurveTypeEnumMap,
											   ::getCppuType((const chart::ChartRegressionCurveType*)0) );
				break;

			case XML_SCH_TYPE_ERROR_INDICATOR_LOWER:
				pHdl = new XMLErrorIndicatorPropertyHdl( sal_False );
				break;
			case XML_SCH_TYPE_ERROR_INDICATOR_UPPER:
				pHdl = new XMLErrorIndicatorPropertyHdl( sal_True );
				break;

			case XML_SCH_TYPE_SOLID_TYPE:
				// here we have a constant rather than an enum
				pHdl = new XMLEnumPropertyHdl( aXMLChartSolidTypeEnumMap,
                                               ::getCppuType((const sal_Int32*)0) );
				break;
            case XML_SCH_TYPE_LABEL_PLACEMENT_TYPE:
                // here we have a constant rather than an enum
                pHdl = new XMLEnumPropertyHdl( aXMLChartDataLabelPlacementEnumMap,
                                                ::getCppuType((const sal_Int32*)0) );
                break;
            case XML_SCH_TYPE_DATAROWSOURCE:
                pHdl = new XMLEnumPropertyHdl( aXMLChartDataRowSourceTypeEnumMap,
                                               ::getCppuType((const chart::ChartDataRowSource*)0) );
                break;
            case XML_SCH_TYPE_TEXT_ORIENTATION:
                pHdl = new XMLTextOrientationHdl();
                break;

            case XML_SCH_TYPE_INTERPOLATION:
                pHdl = new XMLEnumPropertyHdl( aXMLChartInterpolationTypeEnumMap,
                                               ::getCppuType((const sal_Int32*)0) );
                break;
            case XML_SCH_TYPE_SYMBOL_TYPE:
                pHdl = new XMLSymbolTypePropertyHdl( false );
                break;

            case XML_SCH_TYPE_NAMED_SYMBOL:
                pHdl = new XMLSymbolTypePropertyHdl( true );
                break;

            case XML_SCH_TYPE_MISSING_VALUE_TREATMENT:
                pHdl = new XMLEnumPropertyHdl( aXMLChartMissingValueTreatmentEnumMap,
                                               ::getCppuType((const sal_Int32*)0) );
                break;
        }
		if( pHdl )
			PutHdlCache( nType, pHdl );
	}

	return pHdl;
}

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

XMLChartPropertySetMapper::XMLChartPropertySetMapper() :
		XMLPropertySetMapper( aXMLChartPropMap, new XMLChartPropHdlFactory )
{
}

XMLChartPropertySetMapper::~XMLChartPropertySetMapper()
{
}

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

XMLChartExportPropertyMapper::XMLChartExportPropertyMapper( const UniReference< XMLPropertySetMapper >& rMapper,
                                                            SvXMLExport& rExport) :
		SvXMLExportPropertyMapper( rMapper ),
		msTrue( GetXMLToken( XML_TRUE )),
		msFalse( GetXMLToken( XML_FALSE )),
        mrExport( rExport )
{
	// chain draw properties
	ChainExportMapper( XMLShapeExport::CreateShapePropMapper( rExport ));

	// chain text properties
	ChainExportMapper( XMLTextParagraphExport::CreateParaExtPropMapper( rExport ));
}

XMLChartExportPropertyMapper::~XMLChartExportPropertyMapper()
{
}

void XMLChartExportPropertyMapper::ContextFilter(
	std::vector< XMLPropertyState >& rProperties,
	uno::Reference< beans::XPropertySet > rPropSet ) const
{
	::rtl::OUString aAutoPropName;
	sal_Bool bCheckAuto = sal_False;

	// filter properties
	for( std::vector< XMLPropertyState >::iterator property = rProperties.begin();
		 property != rProperties.end();
		 property++ )
	{
		// find properties with context
		// to prevent writing this property set mnIndex member to -1
		switch( getPropertySetMapper()->GetEntryContextId( property->mnIndex ))
		{
			// if Auto... is set the corresponding properties mustn't be exported
			case XML_SCH_CONTEXT_MIN:
				bCheckAuto = sal_True;
				aAutoPropName = ::rtl::OUString::createFromAscii( "AutoMin" );
				break;
			case XML_SCH_CONTEXT_MAX:
				bCheckAuto = sal_True;
				aAutoPropName = ::rtl::OUString::createFromAscii( "AutoMax" );
				break;
			case XML_SCH_CONTEXT_STEP_MAIN:
				bCheckAuto = sal_True;
				aAutoPropName = ::rtl::OUString::createFromAscii( "AutoStepMain" );
				break;
            case XML_SCH_CONTEXT_STEP_HELP_COUNT:
                bCheckAuto = sal_True;
                aAutoPropName = ::rtl::OUString::createFromAscii( "AutoStepHelp" );
                break;

            case XML_SCH_CONTEXT_ORIGIN:
				bCheckAuto = sal_True;
				aAutoPropName = ::rtl::OUString::createFromAscii( "AutoOrigin" );
				break;

            // the following property is deprecated
            // elemet-item symbol-image is used now
            case XML_SCH_CONTEXT_SPECIAL_SYMBOL_IMAGE_NAME:
                property->mnIndex = -1;
                break;

            case XML_SCH_CONTEXT_STOCK_WITH_VOLUME:
            case XML_SCH_CONTEXT_LINES_USED:
                // note this avoids export of the properties in OASIS format,
                // but also for the OOo XML Flat format (used by binfilter),
                // because there, the transformation to OOo is done after the
                // complete export of the chart in OASIS format.
                if( mrExport.getExportFlags() & EXPORT_OASIS )
                    property->mnIndex = -1;
                break;
		}

		if( bCheckAuto )
		{
			if( rPropSet.is())
			{
				try
				{
					sal_Bool bAuto = false;
					uno::Any aAny = rPropSet->getPropertyValue( aAutoPropName );
					aAny >>= bAuto;
					if( bAuto )
						property->mnIndex = -1;
				}
				catch( beans::UnknownPropertyException )
				{
				}
			}
			bCheckAuto = sal_False;
		}
	}

	SvXMLExportPropertyMapper::ContextFilter(rProperties, rPropSet);
}

void XMLChartExportPropertyMapper::handleElementItem(
    SvXMLExport& rExport,
	const XMLPropertyState& rProperty, sal_uInt16 nFlags,
	const ::std::vector< XMLPropertyState > *pProperties,
	sal_uInt32 nIdx ) const
{
    switch( getPropertySetMapper()->GetEntryContextId( rProperty.mnIndex ))
    {
        case XML_SCH_CONTEXT_SPECIAL_SYMBOL_IMAGE:
            {
                ::rtl::OUString aURLStr;
                rProperty.maValue >>= aURLStr;

                // export as XLink reference into the package
                // if embedding is off
                ::rtl::OUString sTempURL( mrExport.AddEmbeddedGraphicObject( aURLStr ));
                if( sTempURL.getLength() )
                {
                    mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sTempURL );
                    mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE,
                                              XML_SIMPLE );
                    mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE,
                                              XML_ONLOAD );
                }

                {
                    sal_uInt32 nPropIndex = rProperty.mnIndex;
                    // this is the element that has to live until the next statement
                    SvXMLElementExport aElem( mrExport,
                                              getPropertySetMapper()->GetEntryNameSpace( nPropIndex ),
                                              getPropertySetMapper()->GetEntryXMLName( nPropIndex ),
                                              sal_True, sal_True );

                    // export as Base64 embedded graphic
                    // if embedding is on
                    if( aURLStr.getLength())
                        mrExport.AddEmbeddedGraphicObjectAsBase64( aURLStr );
                }
            }
            break;

        case XML_SCH_CONTEXT_SPECIAL_LABEL_SEPARATOR:
            {
                ::rtl::OUString aSeparator;
                rProperty.maValue >>= aSeparator;

                if( aSeparator.getLength() )
                {
                    sal_uInt32 nPropIndex = rProperty.mnIndex;
                    SvXMLElementExport aElem( mrExport,
                                              getPropertySetMapper()->GetEntryNameSpace( nPropIndex ),
                                              getPropertySetMapper()->GetEntryXMLName( nPropIndex ),
                                              sal_True, sal_True );

                    SchXMLTools::exportText( mrExport, aSeparator, true );
                }
            }
            break;

        default:
            // call parent
            SvXMLExportPropertyMapper::handleElementItem( rExport, rProperty,
                                                          nFlags, pProperties, nIdx );
            break;
    }
}

void XMLChartExportPropertyMapper::handleSpecialItem(
	SvXMLAttributeList& rAttrList, const XMLPropertyState& rProperty,
	const SvXMLUnitConverter& rUnitConverter,
	const SvXMLNamespaceMap& rNamespaceMap,
	const ::std::vector< XMLPropertyState > *pProperties,
	sal_uInt32 nIdx ) const
{
	sal_Bool bHandled = sal_False;

	sal_Int32 nContextId = maPropMapper->GetEntryContextId( rProperty.mnIndex );

	if( nContextId )
	{
		bHandled = sal_True;

		rtl::OUString sAttrName = maPropMapper->GetEntryXMLName( rProperty.mnIndex );
		sal_uInt16 nNameSpace = maPropMapper->GetEntryNameSpace( rProperty.mnIndex );
		rtl::OUStringBuffer sValueBuffer;
		rtl::OUString sValue;

		sal_Int32 nValue = 0;
		sal_Bool bValue = sal_False;

		switch( nContextId )
		{
			case XML_SCH_CONTEXT_SPECIAL_TICKS_MAJ_INNER:
			case XML_SCH_CONTEXT_SPECIAL_TICKS_MIN_INNER:
				rProperty.maValue >>= nValue;
				bValue = (( nValue & chart::ChartAxisMarks::INNER ) == chart::ChartAxisMarks::INNER );
				SvXMLUnitConverter::convertBool( sValueBuffer, bValue );
				break;
			case XML_SCH_CONTEXT_SPECIAL_TICKS_MAJ_OUTER:
			case XML_SCH_CONTEXT_SPECIAL_TICKS_MIN_OUTER:
				rProperty.maValue >>= nValue;
				bValue = (( nValue & chart::ChartAxisMarks::OUTER ) == chart::ChartAxisMarks::OUTER );
				SvXMLUnitConverter::convertBool( sValueBuffer, bValue );
				break;
			case XML_SCH_CONTEXT_SPECIAL_TEXT_ROTATION:
				{
					// convert from 100th degrees to degrees (double)
					rProperty.maValue >>= nValue;
					double fVal = (double)(nValue) / 100.0;
					SvXMLUnitConverter::convertDouble( sValueBuffer, fVal );
				}
				break;
			case XML_SCH_CONTEXT_SPECIAL_DATA_LABEL_NUMBER:
				{
					rProperty.maValue >>= nValue;
					if((( nValue & chart::ChartDataCaption::VALUE ) == chart::ChartDataCaption::VALUE ))
                    {
                        if( ( nValue & chart::ChartDataCaption::PERCENT ) == chart::ChartDataCaption::PERCENT )
                        {
                            const SvtSaveOptions::ODFDefaultVersion nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
                            if( nCurrentVersion < SvtSaveOptions::ODFVER_012 )
                                sValueBuffer.append( GetXMLToken( XML_PERCENTAGE ));
                            else
						        sValueBuffer.append( GetXMLToken( XML_VALUE_AND_PERCENTAGE ));
                        }
                        else
						    sValueBuffer.append( GetXMLToken( XML_VALUE ));
                    }
					else if(( nValue & chart::ChartDataCaption::PERCENT ) == chart::ChartDataCaption::PERCENT )
						sValueBuffer.append( GetXMLToken( XML_PERCENTAGE ));
					else
						sValueBuffer.append( GetXMLToken( XML_NONE ));
				}
				break;
			case XML_SCH_CONTEXT_SPECIAL_DATA_LABEL_TEXT:
				rProperty.maValue >>= nValue;
				bValue = (( nValue & chart::ChartDataCaption::TEXT ) == chart::ChartDataCaption::TEXT );
				SvXMLUnitConverter::convertBool( sValueBuffer, bValue );
				break;
			case XML_SCH_CONTEXT_SPECIAL_DATA_LABEL_SYMBOL:
				rProperty.maValue >>= nValue;
				bValue = (( nValue & chart::ChartDataCaption::SYMBOL ) == chart::ChartDataCaption::SYMBOL );
				SvXMLUnitConverter::convertBool( sValueBuffer, bValue );
				break;

            case XML_SCH_CONTEXT_SPECIAL_SYMBOL_WIDTH:
            case XML_SCH_CONTEXT_SPECIAL_SYMBOL_HEIGHT:
                {
                    awt::Size aSize;
                    rProperty.maValue >>= aSize;
                    rUnitConverter.convertMeasure( sValueBuffer,
                                                   nContextId == XML_SCH_CONTEXT_SPECIAL_SYMBOL_WIDTH
                                                   ? aSize.Width
                                                   : aSize.Height );
                }
                break;

			case XML_SCH_CONTEXT_SPECIAL_NUMBER_FORMAT:
				{
					// just for import
					break;
				}

			default:
				bHandled = sal_False;
				break;
		}

		if( sValueBuffer.getLength())
		{
			sValue = sValueBuffer.makeStringAndClear();
			sAttrName = rNamespaceMap.GetQNameByKey( nNameSpace, sAttrName );
			rAttrList.AddAttribute( sAttrName, sValue );
		}
	}

	if( !bHandled )
	{
		// call parent
		SvXMLExportPropertyMapper::handleSpecialItem( rAttrList, rProperty, rUnitConverter, rNamespaceMap, pProperties, nIdx );
	}
}

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

XMLChartImportPropertyMapper::XMLChartImportPropertyMapper( const UniReference< XMLPropertySetMapper >& rMapper,
                                                            const SvXMLImport& _rImport ) :
        SvXMLImportPropertyMapper( rMapper, const_cast< SvXMLImport & >( _rImport )),
        mrImport( const_cast< SvXMLImport & > ( _rImport ))
{
	// chain shape mapper for drawing properties

	// give an empty model. It is only used for numbering rules that don't exist in chart
	uno::Reference< frame::XModel > xEmptyModel;
	ChainImportMapper( XMLShapeImportHelper::CreateShapePropMapper( xEmptyModel, mrImport ));

    //#i14365# save and load writing-mode for chart elements
    //The property TextWritingMode is mapped wrongly in the underlying draw mapper, but for draw it is necessary
    //We remove that property here only for chart thus the chart can use the correct mapping from the writer paragraph settings (attribute 'writing-mode' <-> property 'WritingMode')
    sal_Int32 nUnwantedWrongEntry = maPropMapper->FindEntryIndex( "TextWritingMode", XML_NAMESPACE_STYLE, GetXMLToken(XML_WRITING_MODE) );
    maPropMapper->RemoveEntry(nUnwantedWrongEntry);

	// do not chain text properties: on import this is done by shape mapper
    // to import old documents
//  	ChainImportMapper( XMLTextImportHelper::CreateParaExtPropMapper());
}

XMLChartImportPropertyMapper::~XMLChartImportPropertyMapper()
{
}

sal_Bool XMLChartImportPropertyMapper::handleSpecialItem(
	XMLPropertyState& rProperty,
	::std::vector< XMLPropertyState >& rProperties,
	const ::rtl::OUString& rValue,
	const SvXMLUnitConverter& rUnitConverter,
	const SvXMLNamespaceMap& rNamespaceMap ) const
{
    static const ::rtl::OUString sPackageProtocol( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.Package:" ) );
	sal_Int32 nContextId = maPropMapper->GetEntryContextId( rProperty.mnIndex );
	sal_Bool bRet = (nContextId != 0);

	if( nContextId )
	{
		sal_Int32 nValue = 0;
		sal_Bool bValue = sal_False;

		switch( nContextId )
		{
			case XML_SCH_CONTEXT_SPECIAL_TICKS_MAJ_INNER:
			case XML_SCH_CONTEXT_SPECIAL_TICKS_MIN_INNER:
				SvXMLUnitConverter::convertBool( bValue, rValue );
				// modify old value
				rProperty.maValue >>= nValue;
				if( bValue )
					SCH_XML_SETFLAG( nValue, chart::ChartAxisMarks::INNER );
				else
					SCH_XML_UNSETFLAG( nValue, chart::ChartAxisMarks::INNER );
				rProperty.maValue <<= nValue;
				break;
			case XML_SCH_CONTEXT_SPECIAL_TICKS_MAJ_OUTER:
			case XML_SCH_CONTEXT_SPECIAL_TICKS_MIN_OUTER:
				SvXMLUnitConverter::convertBool( bValue, rValue );
				// modify old value
				rProperty.maValue >>= nValue;
				if( bValue )
					SCH_XML_SETFLAG( nValue, chart::ChartAxisMarks::OUTER );
				else
					SCH_XML_UNSETFLAG( nValue, chart::ChartAxisMarks::OUTER );
				rProperty.maValue <<= nValue;
				break;
			case XML_SCH_CONTEXT_SPECIAL_TEXT_ROTATION:
				{
					// convert from degrees (double) to 100th degrees (integer)
					double fVal;
					SvXMLUnitConverter::convertDouble( fVal, rValue );
					nValue = (sal_Int32)( fVal * 100.0 );
					rProperty.maValue <<= nValue;
				}
				break;
			case XML_SCH_CONTEXT_SPECIAL_DATA_LABEL_NUMBER:
				{
					// modify old value
					rProperty.maValue >>= nValue;
					if( IsXMLToken( rValue, XML_NONE ))
						SCH_XML_UNSETFLAG( nValue, chart::ChartDataCaption::VALUE | chart::ChartDataCaption::PERCENT );
                    else if( IsXMLToken( rValue, XML_VALUE_AND_PERCENTAGE ) )
						SCH_XML_SETFLAG( nValue, chart::ChartDataCaption::VALUE | chart::ChartDataCaption::PERCENT );
                    else if( IsXMLToken( rValue, XML_VALUE ) )
						SCH_XML_SETFLAG( nValue, chart::ChartDataCaption::VALUE );
					else // must be XML_PERCENTAGE
						SCH_XML_SETFLAG( nValue, chart::ChartDataCaption::PERCENT );
					rProperty.maValue <<= nValue;
				}
				break;
			case XML_SCH_CONTEXT_SPECIAL_DATA_LABEL_TEXT:
				rProperty.maValue >>= nValue;
				SvXMLUnitConverter::convertBool( bValue, rValue );
				if( bValue )
					SCH_XML_SETFLAG( nValue, chart::ChartDataCaption::TEXT );
				else
					SCH_XML_UNSETFLAG( nValue, chart::ChartDataCaption::TEXT );
				rProperty.maValue <<= nValue;
				break;
			case XML_SCH_CONTEXT_SPECIAL_DATA_LABEL_SYMBOL:
				rProperty.maValue >>= nValue;
				SvXMLUnitConverter::convertBool( bValue, rValue );
				if( bValue )
					SCH_XML_SETFLAG( nValue, chart::ChartDataCaption::SYMBOL );
				else
					SCH_XML_UNSETFLAG( nValue, chart::ChartDataCaption::SYMBOL );
				rProperty.maValue <<= nValue;
				break;
            case XML_SCH_CONTEXT_SPECIAL_SYMBOL_WIDTH:
            case XML_SCH_CONTEXT_SPECIAL_SYMBOL_HEIGHT:
                {
                    awt::Size aSize;
                    rProperty.maValue >>= aSize;
                    rUnitConverter.convertMeasure( nContextId == XML_SCH_CONTEXT_SPECIAL_SYMBOL_WIDTH
                                                   ? aSize.Width
                                                   : aSize.Height,
                                                   rValue );
                    rProperty.maValue <<= aSize;
                }
                break;

            // deprecated from 6.0 beta on
            case XML_SCH_CONTEXT_SPECIAL_SYMBOL_IMAGE_NAME:
                rProperty.maValue <<= mrImport.ResolveGraphicObjectURL( rValue, sal_False );
                break;

            default:
				bRet = sal_False;
				break;
		}
	}


	// if we didn't handle it, the parent should
	if( !bRet )
	{
		// call parent
		bRet = SvXMLImportPropertyMapper::handleSpecialItem( rProperty, rProperties, rValue, rUnitConverter, rNamespaceMap );
	}

	return bRet;
}

void XMLChartImportPropertyMapper::finished( ::std::vector< XMLPropertyState >& /*rProperties*/, sal_Int32 /*nStartIndex*/, sal_Int32 /*nEndIndex*/ ) const
{
}
