/**************************************************************
 *
 * 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 "SchXMLChartContext.hxx"
#include "SchXMLImport.hxx"
#include "SchXMLLegendContext.hxx"
#include "SchXMLPlotAreaContext.hxx"
#include "SchXMLParagraphContext.hxx"
#include "SchXMLTableContext.hxx"
#include "SchXMLSeriesHelper.hxx"
#include "SchXMLSeries2Context.hxx"
#include "SchXMLTools.hxx"
#include <comphelper/mediadescriptor.hxx>
#include <tools/debug.hxx>
// header for class ByteString
#include <tools/string.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmlement.hxx>
#include <xmloff/xmltoken.hxx>
#include <xmloff/nmspmap.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmlstyle.hxx>
#include <xmloff/prstylei.hxx>

#include "vector"
#include <com/sun/star/chart/XChartDocument.hpp>
#include <com/sun/star/chart/XDiagram.hpp>
#include <com/sun/star/xml/sax/XAttributeList.hpp>
#include <com/sun/star/util/XStringMapping.hpp>
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
#include <com/sun/star/drawing/XDrawPage.hpp>
#include <com/sun/star/chart/ChartDataRowSource.hpp>
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/embed/Aspects.hpp>
#include <com/sun/star/embed/XVisualObject.hpp>

#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/data/XDataSink.hpp>
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#include <com/sun/star/chart2/XChartTypeContainer.hpp>
#include <com/sun/star/chart2/XTitled.hpp>

using namespace com::sun::star;
using namespace ::xmloff::token;
using ::rtl::OUString;
using com::sun::star::uno::Reference;
using namespace ::SchXMLTools;

namespace
{

void lcl_setRoleAtLabeledSequence(
    const uno::Reference< chart2::data::XLabeledDataSequence > & xLSeq,
    const ::rtl::OUString &rRole )
{
    // set role of sequence
    uno::Reference< chart2::data::XDataSequence > xValues( xLSeq->getValues());
    if( xValues.is())
    {
        uno::Reference< beans::XPropertySet > xProp( xValues, uno::UNO_QUERY );
        if( xProp.is())
            xProp->setPropertyValue(OUString::createFromAscii("Role"), uno::makeAny( rRole ));
    }
}

void lcl_MoveDataToCandleStickSeries(
    const uno::Reference< chart2::data::XDataSource > & xDataSource,
    const uno::Reference< chart2::XDataSeries > & xDestination,
    const OUString & rRole )
{
    try
    {
        uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledSeq(
            xDataSource->getDataSequences());
        if( aLabeledSeq.getLength())
        {
            lcl_setRoleAtLabeledSequence( aLabeledSeq[0], rRole );

            // add to data series
            uno::Reference< chart2::data::XDataSource > xSource( xDestination, uno::UNO_QUERY_THROW );
            // @todo: realloc only once outside this function
            uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aData( xSource->getDataSequences());
            aData.realloc( aData.getLength() + 1);
            aData[ aData.getLength() - 1 ] = aLabeledSeq[0];
            uno::Reference< chart2::data::XDataSink > xSink( xDestination, uno::UNO_QUERY_THROW );
            xSink->setData( aData );
        }
    }
    catch( uno::Exception & )
    {
        OSL_ENSURE( false, "Exception caught while moving data to candlestick series" );
    }
}

void lcl_setRoleAtFirstSequence(
    const uno::Reference< chart2::XDataSeries > & xSeries,
    const ::rtl::OUString & rRole )
{
    uno::Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
    if( xSource.is())
    {
        uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
        if( aSeq.getLength())
            lcl_setRoleAtLabeledSequence( aSeq[0], rRole );
    }
}

void lcl_removeEmptyChartTypeGroups( const uno::Reference< chart2::XChartDocument > & xDoc )
{
    if( ! xDoc.is())
        return;

    uno::Reference< chart2::XDiagram > xDia( xDoc->getFirstDiagram());
    if( ! xDia.is())
        return;

    try
    {
        // count all charttype groups to be able to leave at least one
        sal_Int32 nRemainingGroups = 0;
        uno::Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDia, uno::UNO_QUERY_THROW );
        uno::Sequence< uno::Reference< chart2::XCoordinateSystem > >
            aCooSysSeq( xCooSysCnt->getCoordinateSystems());
        for( sal_Int32 nI = aCooSysSeq.getLength(); nI--; )
        {
            uno::Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nI], uno::UNO_QUERY_THROW );
            nRemainingGroups += xCTCnt->getChartTypes().getLength();
        }

        // delete all empty groups, but leave at least  group (empty or not)
        for( sal_Int32 nI = aCooSysSeq.getLength(); nI-- && (nRemainingGroups > 1); )
        {
            uno::Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nI], uno::UNO_QUERY_THROW );
            uno::Sequence< uno::Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes());
            for( sal_Int32 nJ=aCTSeq.getLength(); nJ-- && (nRemainingGroups > 1); )
            {
                uno::Reference< chart2::XDataSeriesContainer > xDSCnt( aCTSeq[nJ], uno::UNO_QUERY_THROW );
                if( xDSCnt->getDataSeries().getLength() == 0 )
                {
                    // note: iterator stays valid as we have a local sequence
                    xCTCnt->removeChartType( aCTSeq[nJ] );
                    --nRemainingGroups;
                }
            }
        }
    }
    catch( uno::Exception & ex )
    {
        String aStr( ex.Message );
        ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US );
        DBG_ERROR1( "Exception caught while removing empty chart types: %s", aBStr.GetBuffer());
    }
}

uno::Sequence< sal_Int32 > lcl_getNumberSequenceFromString( const ::rtl::OUString& rStr, bool bAddOneToEachOldIndex )
{
    const sal_Unicode aSpace( ' ' );

    // count number of entries
    ::std::vector< sal_Int32 > aVec;
    sal_Int32 nLastPos = 0;
    sal_Int32 nPos = 0;
    while( nPos != -1 )
    {
        nPos = rStr.indexOf( aSpace, nLastPos );
        if( nPos > nLastPos )
        {
            aVec.push_back( rStr.copy( nLastPos, (nPos - nLastPos) ).toInt32() );
        }
        if( nPos != -1 )
            nLastPos = nPos + 1;
    }
    // last entry
    if( nLastPos != 0 &&
        rStr.getLength() > nLastPos )
    {
        aVec.push_back( rStr.copy( nLastPos, (rStr.getLength() - nLastPos) ).toInt32() );
    }

    const sal_Int32 nVecSize = aVec.size();
    uno::Sequence< sal_Int32 > aSeq( nVecSize );

    if(!bAddOneToEachOldIndex)
    {
        sal_Int32* pSeqArr = aSeq.getArray();
        for( nPos = 0; nPos < nVecSize; ++nPos )
        {
            pSeqArr[ nPos ] = aVec[ nPos ];
        }
    }
    else if( bAddOneToEachOldIndex )
    {
        aSeq.realloc( nVecSize+1 );
        aSeq[0]=0;

        sal_Int32* pSeqArr = aSeq.getArray();
        for( nPos = 0; nPos < nVecSize; ++nPos )
        {
            pSeqArr[ nPos+1 ] = aVec[ nPos ]+1;
        }
    }

    return aSeq;
}

} // anonymous namespace

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

SchXMLChartContext::SchXMLChartContext( SchXMLImportHelper& rImpHelper,
										SvXMLImport& rImport, const rtl::OUString& rLocalName ) :
		SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ),
		mrImportHelper( rImpHelper ),
        m_bHasRangeAtPlotArea( false ),
        m_bHasTableElement( false ),
        mbAllRangeAddressesAvailable( sal_True ),
        mbColHasLabels( sal_False ),
        mbRowHasLabels( sal_False ),
        meDataRowSource( chart::ChartDataRowSource_COLUMNS ),
        mbIsStockChart( false )
{
}

SchXMLChartContext::~SchXMLChartContext()
{}

void SchXMLChartContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
{
	// parse attributes
	sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
	const SvXMLTokenMap& rAttrTokenMap = mrImportHelper.GetChartAttrTokenMap();

    uno::Reference< embed::XVisualObject > xVisualObject( mrImportHelper.GetChartDocument(), uno::UNO_QUERY);
    DBG_ASSERT(xVisualObject.is(),"need xVisualObject for page size");
    if( xVisualObject.is() )
        maChartSize = xVisualObject->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ); //#i103460# take the size given from the parent frame as default

	// this flag is necessary for pie charts in the core
	sal_Bool bSetSwitchData = sal_False;

	::rtl::OUString sAutoStyleName;
    ::rtl::OUString aOldChartTypeName;
    bool bHasAddin = false;

	for( sal_Int16 i = 0; i < nAttrCount; i++ )
	{
		rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
		rtl::OUString aLocalName;
		rtl::OUString aValue = xAttrList->getValueByIndex( i );
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );

		switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
		{
            case XML_TOK_CHART_HREF:
                m_aXLinkHRefAttributeToIndicateDataProvider = aValue;
                break;

			case XML_TOK_CHART_CLASS:
				{
					rtl::OUString sClassName;
					sal_uInt16 nClassPrefix =
						GetImport().GetNamespaceMap().GetKeyByAttrName(
								aValue, &sClassName );
					if( XML_NAMESPACE_CHART == nClassPrefix )
					{
						SchXMLChartTypeEnum eChartTypeEnum = SchXMLTools::GetChartTypeEnum( sClassName );
                        if( eChartTypeEnum != XML_CHART_CLASS_UNKNOWN )
						{
                            aOldChartTypeName = SchXMLTools::GetChartTypeByClassName( sClassName, true /* bUseOldNames */ );
                            maChartTypeServiceName = SchXMLTools::GetChartTypeByClassName( sClassName, false /* bUseOldNames */ );
							switch( eChartTypeEnum )
							{
							case XML_CHART_CLASS_CIRCLE:
								bSetSwitchData = sal_True;
								break;
							case XML_CHART_CLASS_STOCK:
                                mbIsStockChart = true;
								break;
							default:
                                break;
							}
						}
					}
					else if( XML_NAMESPACE_OOO == nClassPrefix )
					{
                        // service is taken from add-in-name attribute
                        bHasAddin = true;

						aOldChartTypeName = sClassName;
						maChartTypeServiceName = sClassName;
					}
				}
				break;

			case XML_TOK_CHART_WIDTH:
				GetImport().GetMM100UnitConverter().convertMeasure( maChartSize.Width, aValue );
				break;

			case XML_TOK_CHART_HEIGHT:
				GetImport().GetMM100UnitConverter().convertMeasure( maChartSize.Height, aValue );
				break;

			case XML_TOK_CHART_STYLE_NAME:
				sAutoStyleName = aValue;
				break;

            case XML_TOK_CHART_COL_MAPPING:
                msColTrans = aValue;
                break;
            case XML_TOK_CHART_ROW_MAPPING:
                msRowTrans = aValue;
                break;
		}
	}

    if( aOldChartTypeName.getLength()<= 0 )
    {
        DBG_ERROR( "need a charttype to create a diagram" );
        //set a fallback value:
        ::rtl::OUString aChartClass_Bar( GetXMLToken(XML_BAR ) );
        aOldChartTypeName = SchXMLTools::GetChartTypeByClassName( aChartClass_Bar, true /* bUseOldNames */ );
        maChartTypeServiceName = SchXMLTools::GetChartTypeByClassName( aChartClass_Bar, false /* bUseOldNames */ );
    }

    //	Set the size of the draw page.
    if( xVisualObject.is() )
        xVisualObject->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, maChartSize );

	InitChart( aOldChartTypeName, bSetSwitchData);

    if( bHasAddin )
    {
        //correct charttype serveice name when having an addin
        //and don't refresh addin during load
        uno::Reference< beans::XPropertySet > xDocProp( mrImportHelper.GetChartDocument(), uno::UNO_QUERY );
        if( xDocProp.is() )
        {
            try
            {
                xDocProp->getPropertyValue( ::rtl::OUString::createFromAscii("BaseDiagram")) >>= aOldChartTypeName;
                maChartTypeServiceName =  SchXMLTools::GetNewChartTypeName( aOldChartTypeName );
                xDocProp->setPropertyValue( rtl::OUString::createFromAscii( "RefreshAddInAllowed" ) , uno::makeAny( sal_False) );
            }
            catch( uno::Exception & )
            {
                DBG_ERROR( "Exception during import SchXMLChartContext::StartElement" );
            }
        }
    }

	// set auto-styles for Area
	uno::Reference< beans::XPropertySet > xProp( mrImportHelper.GetChartDocument()->getArea(), uno::UNO_QUERY );
	if( xProp.is())
	{
		const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
		if( pStylesCtxt )
		{
			const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
				mrImportHelper.GetChartFamilyID(), sAutoStyleName );

			if( pStyle && pStyle->ISA( XMLPropStyleContext ))
				(( XMLPropStyleContext* )pStyle )->FillPropertySet( xProp );
		}
	}
}

namespace
{

struct NewDonutSeries
{
    ::com::sun::star::uno::Reference<
                ::com::sun::star::chart2::XDataSeries > m_xSeries;
    ::rtl::OUString msStyleName;
	sal_Int32 mnAttachedAxis;

    ::std::vector< ::rtl::OUString > m_aSeriesStyles;
    ::std::vector< ::rtl::OUString > m_aPointStyles;

    NewDonutSeries( const ::com::sun::star::uno::Reference<
                ::com::sun::star::chart2::XDataSeries >& xSeries, sal_Int32 nPointCount )
                    : m_xSeries( xSeries )
                    , mnAttachedAxis( 1 )
    {
        m_aPointStyles.resize(nPointCount);
        m_aSeriesStyles.resize(nPointCount);
    }

    void setSeriesStyleNameToPoint( const ::rtl::OUString& rStyleName, sal_Int32 nPointIndex )
    {
        DBG_ASSERT(nPointIndex < static_cast<sal_Int32>(m_aSeriesStyles.size()),"donut point <-> series count mismatch");
        if( nPointIndex < static_cast<sal_Int32>(m_aSeriesStyles.size()) )
            m_aSeriesStyles[nPointIndex]=rStyleName;
    }

    void setPointStyleNameToPoint( const ::rtl::OUString& rStyleName, sal_Int32 nPointIndex )
    {
        DBG_ASSERT(nPointIndex < static_cast<sal_Int32>(m_aPointStyles.size()),"donut point <-> series count mismatch");
        if( nPointIndex < static_cast<sal_Int32>(m_aPointStyles.size()) )
            m_aPointStyles[nPointIndex]=rStyleName;
    }

    ::std::list< DataRowPointStyle > creatStyleList()
    {
        ::std::list< DataRowPointStyle > aRet;

        DataRowPointStyle aSeriesStyle( DataRowPointStyle::DATA_SERIES
            , m_xSeries, -1, 1, msStyleName, mnAttachedAxis );
        aRet.push_back( aSeriesStyle );

        sal_Int32 nPointIndex=0;
        ::std::vector< ::rtl::OUString >::iterator aPointIt( m_aPointStyles.begin() );
        ::std::vector< ::rtl::OUString >::iterator aPointEnd( m_aPointStyles.end() );
        while( aPointIt != aPointEnd )
        {
            DataRowPointStyle aPointStyle( DataRowPointStyle::DATA_POINT
                , m_xSeries, nPointIndex, 1, *aPointIt, mnAttachedAxis );
            if( nPointIndex < static_cast<sal_Int32>(m_aSeriesStyles.size()) )
            {
                aPointStyle.msSeriesStyleNameForDonuts = m_aSeriesStyles[nPointIndex];
            }
            if( aPointStyle.msSeriesStyleNameForDonuts.getLength()
                || aPointStyle.msStyleName.getLength() )
                aRet.push_back( aPointStyle );
            ++aPointIt;
            ++nPointIndex;
        }

        return aRet;
    }
};

void lcl_swapPointAndSeriesStylesForDonutCharts( ::std::list< DataRowPointStyle >& rStyleList
        , const ::std::map< ::com::sun::star::uno::Reference<
                ::com::sun::star::chart2::XDataSeries> , sal_Int32 >& rSeriesMap )
{
    ::std::list< DataRowPointStyle >::iterator aIt(rStyleList.begin());
    ::std::list< DataRowPointStyle >::iterator aEnd(rStyleList.end());

    //detect old series count
    //and add old series to aSeriesMap
    ::std::map< ::com::sun::star::uno::Reference<
                ::com::sun::star::chart2::XDataSeries >, sal_Int32 > aSeriesMap(rSeriesMap);
    sal_Int32 nOldSeriesCount = 0;
    {
        sal_Int32 nMaxOldSeriesIndex = 0;
        sal_Int32 nOldSeriesIndex = 0;
        for( aIt = rStyleList.begin(); aIt != aEnd; ++aIt )
        {
            DataRowPointStyle aStyle(*aIt);
            if(aStyle.meType == DataRowPointStyle::DATA_SERIES &&
                    aStyle.m_xSeries.is() )
            {
                nMaxOldSeriesIndex = nOldSeriesIndex;

                if( aSeriesMap.end() == aSeriesMap.find(aStyle.m_xSeries) )
                    aSeriesMap[aStyle.m_xSeries] = nOldSeriesIndex;

                nOldSeriesIndex++;
            }
        }
        nOldSeriesCount = nMaxOldSeriesIndex+1;
    }
    /*
    sal_Int32 nOldSeriesCount = 0;
    {
        sal_Int32 nMaxOldSeriesIndex = 0;
        sal_Int32 nOldSeriesIndex = 0;
        for( aIt = rStyleList.begin(); aIt != aEnd; ++aIt )
        {
            DataRowPointStyle aStyle(*aIt);
            if(aStyle.meType == DataRowPointStyle::DATA_SERIES )
            {
                nMaxOldSeriesIndex = nOldSeriesIndex;
                nOldSeriesIndex++;
            }
        }
        nOldSeriesCount = nMaxOldSeriesIndex+1;
    }
    */


    //initialize new series styles
    ::std::map< Reference< chart2::XDataSeries >, sal_Int32 >::const_iterator aSeriesMapIt( aSeriesMap.begin() );
    ::std::map< Reference< chart2::XDataSeries >, sal_Int32 >::const_iterator aSeriesMapEnd( aSeriesMap.end() );

    //sort by index
    ::std::vector< NewDonutSeries > aNewSeriesVector;
    {
        ::std::map< sal_Int32, Reference< chart2::XDataSeries > > aIndexSeriesMap;
        for( ; aSeriesMapIt != aSeriesMapEnd; ++aSeriesMapIt )
            aIndexSeriesMap[aSeriesMapIt->second] = aSeriesMapIt->first;

        ::std::map< sal_Int32, Reference< chart2::XDataSeries > >::const_iterator aIndexIt( aIndexSeriesMap.begin() );
        ::std::map< sal_Int32, Reference< chart2::XDataSeries > >::const_iterator aIndexEnd( aIndexSeriesMap.end() );

        for( ; aIndexIt != aIndexEnd; ++aIndexIt )
            aNewSeriesVector.push_back( NewDonutSeries(aIndexIt->second,nOldSeriesCount) );
    }

    //overwrite attached axis information according to old series styles
    for( aIt = rStyleList.begin(); aIt != aEnd; ++aIt )
    {
        DataRowPointStyle aStyle(*aIt);
        if(aStyle.meType == DataRowPointStyle::DATA_SERIES )
        {
            aSeriesMapIt = aSeriesMap.find( aStyle.m_xSeries );
            if( aSeriesMapIt != aSeriesMapEnd && aSeriesMapIt->second < static_cast<sal_Int32>(aNewSeriesVector.size()) )
                aNewSeriesVector[aSeriesMapIt->second].mnAttachedAxis = aStyle.mnAttachedAxis;
        }
    }

    //overwrite new series style names with old series style name information
    for( aIt = rStyleList.begin(); aIt != aEnd; ++aIt )
    {
        DataRowPointStyle aStyle(*aIt);
        if( aStyle.meType == DataRowPointStyle::DATA_SERIES )
        {
            aSeriesMapIt = aSeriesMap.find(aStyle.m_xSeries);
            if( aSeriesMapEnd != aSeriesMapIt )
            {
                sal_Int32 nNewPointIndex = aSeriesMapIt->second;

                ::std::vector< NewDonutSeries >::iterator aNewSeriesIt( aNewSeriesVector.begin() );
                ::std::vector< NewDonutSeries >::iterator aNewSeriesEnd( aNewSeriesVector.end() );

                for( ;aNewSeriesIt!=aNewSeriesEnd; ++aNewSeriesIt)
                    aNewSeriesIt->setSeriesStyleNameToPoint( aStyle.msStyleName, nNewPointIndex );
            }
        }
    }

    //overwrite new series style names with point style name information
    for( aIt = rStyleList.begin(); aIt != aEnd; ++aIt )
    {
        DataRowPointStyle aStyle(*aIt);
        if( aStyle.meType == DataRowPointStyle::DATA_POINT )
        {
            aSeriesMapIt = aSeriesMap.find(aStyle.m_xSeries);
            if( aSeriesMapEnd != aSeriesMapIt )
            {
                sal_Int32 nNewPointIndex = aSeriesMapIt->second;
                sal_Int32 nNewSeriesIndex = aStyle.m_nPointIndex;
                sal_Int32 nRepeatCount = aStyle.m_nPointRepeat;

                while( nRepeatCount && (nNewSeriesIndex>=0) && (nNewSeriesIndex< static_cast<sal_Int32>(aNewSeriesVector.size()) ) )
                {
                    NewDonutSeries& rNewSeries( aNewSeriesVector[nNewSeriesIndex] );
                    rNewSeries.setPointStyleNameToPoint( aStyle.msStyleName, nNewPointIndex );

                    nRepeatCount--;
                    nNewSeriesIndex++;
                }
            }
        }
    }

    //put information from aNewSeriesVector to output parameter rStyleList
    rStyleList.clear();

    ::std::vector< NewDonutSeries >::iterator aNewSeriesIt( aNewSeriesVector.begin() );
    ::std::vector< NewDonutSeries >::iterator aNewSeriesEnd( aNewSeriesVector.end() );
    for( ;aNewSeriesIt!=aNewSeriesEnd; ++aNewSeriesIt)
    {
        ::std::list< DataRowPointStyle > aList( aNewSeriesIt->creatStyleList() );
        rStyleList.insert(rStyleList.end(),aList.begin(),aList.end());
    }
}

bool lcl_SpecialHandlingForDonutChartNeeded(
    const ::rtl::OUString & rServiceName,
    const SvXMLImport & rImport )
{
    bool bResult = false;
    if( rServiceName.equalsAsciiL(
            RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.DonutChartType" )))
    {
        bResult = SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( rImport.GetModel() );
    }
    return bResult;
}

} // anonymous namespace


void lcl_ApplyDataFromRectangularRangeToDiagram(
        const uno::Reference< chart2::XChartDocument >& xNewDoc
        , const rtl::OUString& rRectangularRange
        , ::com::sun::star::chart::ChartDataRowSource eDataRowSource
        , bool bRowHasLabels, bool bColHasLabels
        , bool bSwitchOnLabelsAndCategoriesForOwnData
        , const rtl::OUString& sColTrans
        , const rtl::OUString& sRowTrans )
{
    if( !xNewDoc.is() )
        return;

    uno::Reference< chart2::XDiagram > xNewDia( xNewDoc->getFirstDiagram());
    uno::Reference< chart2::data::XDataProvider > xDataProvider( xNewDoc->getDataProvider() );
    if( !xNewDia.is() || !xDataProvider.is() )
        return;

    sal_Bool bFirstCellAsLabel =
        (eDataRowSource==chart::ChartDataRowSource_COLUMNS)? bRowHasLabels : bColHasLabels;
    sal_Bool bHasCateories =
        (eDataRowSource==chart::ChartDataRowSource_COLUMNS)? bColHasLabels : bRowHasLabels;

    if( bSwitchOnLabelsAndCategoriesForOwnData )
    {
        bFirstCellAsLabel = true;
        bHasCateories = true;
    }

    uno::Sequence< beans::PropertyValue > aArgs( 3 );
    aArgs[0] = beans::PropertyValue(
        ::rtl::OUString::createFromAscii("CellRangeRepresentation"),
        -1, uno::makeAny( rRectangularRange ),
        beans::PropertyState_DIRECT_VALUE );
    aArgs[1] = beans::PropertyValue(
        ::rtl::OUString::createFromAscii("DataRowSource"),
        -1, uno::makeAny( eDataRowSource ),
        beans::PropertyState_DIRECT_VALUE );
    aArgs[2] = beans::PropertyValue(
        ::rtl::OUString::createFromAscii("FirstCellAsLabel"),
        -1, uno::makeAny( bFirstCellAsLabel ),
        beans::PropertyState_DIRECT_VALUE );

    if( sColTrans.getLength() || sRowTrans.getLength() )
    {
        aArgs.realloc( aArgs.getLength() + 1 );
        aArgs[ aArgs.getLength() - 1 ] = beans::PropertyValue(
            ::rtl::OUString::createFromAscii("SequenceMapping"),
            -1, uno::makeAny( sColTrans.getLength()
                ? lcl_getNumberSequenceFromString( sColTrans, bHasCateories && !xNewDoc->hasInternalDataProvider() )
                : lcl_getNumberSequenceFromString( sRowTrans, bHasCateories && !xNewDoc->hasInternalDataProvider() ) ),
        beans::PropertyState_DIRECT_VALUE );
    }

    //work around wrong writer ranges ( see Issue 58464 )
    {
        rtl::OUString aChartOleObjectName;
        uno::Reference< frame::XModel > xModel(xNewDoc, uno::UNO_QUERY );
        if( xModel.is() )
        {
            comphelper::MediaDescriptor aMediaDescriptor( xModel->getArgs() );

            comphelper::MediaDescriptor::const_iterator aIt(
                aMediaDescriptor.find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HierarchicalDocumentName" ))));
            if( aIt != aMediaDescriptor.end() )
            {
                aChartOleObjectName = (*aIt).second.get< ::rtl::OUString >();
            }
        }
        if( aChartOleObjectName.getLength() )
        {
            aArgs.realloc( aArgs.getLength() + 1 );
            aArgs[ aArgs.getLength() - 1 ] = beans::PropertyValue(
                ::rtl::OUString::createFromAscii("ChartOleObjectName"),
                -1, uno::makeAny( aChartOleObjectName ),
                beans::PropertyState_DIRECT_VALUE );
        }
    }


    uno::Reference< chart2::data::XDataSource > xDataSource(
        xDataProvider->createDataSource( aArgs ));

    aArgs.realloc( aArgs.getLength() + 2 );
    aArgs[ aArgs.getLength() - 2 ] = beans::PropertyValue(
        ::rtl::OUString::createFromAscii("HasCategories"),
        -1, uno::makeAny( bHasCateories ),
        beans::PropertyState_DIRECT_VALUE );
    aArgs[ aArgs.getLength() - 1 ] = beans::PropertyValue(
        ::rtl::OUString::createFromAscii("UseCategoriesAsX"),
        -1, uno::makeAny( sal_False ),//categories in ODF files are not to be used as x values (independent from what is offered in our ui)
        beans::PropertyState_DIRECT_VALUE );

    xNewDia->setDiagramData( xDataSource, aArgs );
}

void SchXMLChartContext::EndElement()
{
	uno::Reference< chart::XChartDocument > xDoc = mrImportHelper.GetChartDocument();
	uno::Reference< beans::XPropertySet > xProp( xDoc, uno::UNO_QUERY );
    uno::Reference< chart2::XChartDocument > xNewDoc( xDoc, uno::UNO_QUERY );

	if( xProp.is())
	{
		if( maMainTitle.getLength())
		{
			uno::Reference< beans::XPropertySet > xTitleProp( xDoc->getTitle(), uno::UNO_QUERY );
			if( xTitleProp.is())
			{
				try
				{
					uno::Any aAny;
					aAny <<= maMainTitle;
					xTitleProp->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "String" )), aAny );
				}
				catch( beans::UnknownPropertyException )
				{
					DBG_ERROR( "Property String for Title not available" );
				}
			}
		}
		if( maSubTitle.getLength())
		{
			uno::Reference< beans::XPropertySet > xTitleProp( xDoc->getSubTitle(), uno::UNO_QUERY );
			if( xTitleProp.is())
			{
				try
				{
					uno::Any aAny;
					aAny <<= maSubTitle;
					xTitleProp->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "String" )), aAny );
				}
				catch( beans::UnknownPropertyException )
				{
					DBG_ERROR( "Property String for Title not available" );
				}
			}
		}
	}

    // cleanup: remove empty chart type groups
    lcl_removeEmptyChartTypeGroups( xNewDoc );

    // set stack mode before a potential chart type detection (in case we have a rectangular range)
    uno::Reference< chart::XDiagram > xDiagram( xDoc->getDiagram() );
    uno::Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY );
    if( xDiaProp.is())
    {
        if( maSeriesDefaultsAndStyles.maStackedDefault.hasValue())
            xDiaProp->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Stacked")),maSeriesDefaultsAndStyles.maStackedDefault);
        if( maSeriesDefaultsAndStyles.maPercentDefault.hasValue())
            xDiaProp->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Percent")),maSeriesDefaultsAndStyles.maPercentDefault);
        if( maSeriesDefaultsAndStyles.maDeepDefault.hasValue())
            xDiaProp->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Deep")),maSeriesDefaultsAndStyles.maDeepDefault);
        if( maSeriesDefaultsAndStyles.maStackedBarsConnectedDefault.hasValue())
            xDiaProp->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StackedBarsConnected")),maSeriesDefaultsAndStyles.maStackedBarsConnectedDefault);
    }

    //the OOo 2.0 implementation and older has a bug with donuts
    bool bSpecialHandlingForDonutChart = lcl_SpecialHandlingForDonutChartNeeded(
        maChartTypeServiceName, GetImport());

    // apply data
    if(!xNewDoc.is())
        return;

    bool bHasOwnData = false;
    if( m_aXLinkHRefAttributeToIndicateDataProvider.equalsAscii( "." ) ) //data comes from the chart itself
        bHasOwnData = true;
    else if( m_aXLinkHRefAttributeToIndicateDataProvider.equalsAscii( ".." ) ) //data comes from the parent application
        bHasOwnData = false;
    else if( m_aXLinkHRefAttributeToIndicateDataProvider.getLength() ) //not supported so far to get the data by sibling objects -> fall back to chart itself if data are available
        bHasOwnData = m_bHasTableElement;
    else
        bHasOwnData = !m_bHasRangeAtPlotArea;

    if( xNewDoc->hasInternalDataProvider())
    {
        if( !m_bHasTableElement && !m_aXLinkHRefAttributeToIndicateDataProvider.equalsAscii( "." ) )
        {
            //#i103147# ODF, workaround broken files with a missing table:cell-range-address at the plot-area
            bool bSwitchSuccessful = SchXMLTools::switchBackToDataProviderFromParent( xNewDoc, maLSequencesPerIndex );
            bHasOwnData = !bSwitchSuccessful;
        }
        else
            bHasOwnData = true;//e.g. in case of copy->paste from calc to impress
    }
    else if( bHasOwnData )
    {
        xNewDoc->createInternalDataProvider( sal_False /* bCloneExistingData */ );
    }
    if( bHasOwnData )
        msChartAddress = ::rtl::OUString::createFromAscii("all");

    bool bSwitchRangesFromOuterToInternalIfNecessary = false;
    if( !bHasOwnData && mbAllRangeAddressesAvailable )
    {
        // special handling for stock chart (merge series together)
        if( mbIsStockChart )
            MergeSeriesForStockChart();
    }
    else if( msChartAddress.getLength() )
    {
        //own data or only rectangular range available

        if( xNewDoc->hasInternalDataProvider() )
            SchXMLTableHelper::applyTableToInternalDataProvider( maTable, xNewDoc );

        bool bOlderThan2_3 = SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( Reference< frame::XModel >( xNewDoc, uno::UNO_QUERY ));
        bool bOldFileWithOwnDataFromRows = (bOlderThan2_3 && bHasOwnData && (meDataRowSource==chart::ChartDataRowSource_ROWS)); // in this case there are range addresses that are simply wrong.

        if( mbAllRangeAddressesAvailable && !bSpecialHandlingForDonutChart && !mbIsStockChart &&
            !bOldFileWithOwnDataFromRows )
        {
            //bHasOwnData is true in this case!
            //e.g. for normal files with own data or also in case of copy paste scenario (e.g. calc to impress)
            bSwitchRangesFromOuterToInternalIfNecessary = true;
        }
        else
        {
            //apply data from rectangular range

            // create datasource from data provider with rectangular range parameters and change the diagram setDiagramData
            try
            {
                if( bOlderThan2_3 && xDiaProp.is() )//for older charts the hidden cells were removed by calc on the fly
                    xDiaProp->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IncludeHiddenCells")),uno::makeAny(false));

                // note: mbRowHasLabels means the first row contains labels, that means we have "column-descriptions",
                // (analogously mbColHasLabels means we have "row-descriptions")
                lcl_ApplyDataFromRectangularRangeToDiagram( xNewDoc, msChartAddress, meDataRowSource, mbRowHasLabels, mbColHasLabels, bHasOwnData, msColTrans, msRowTrans );
            }
            catch( uno::Exception & )
            {
                //try to fallback to internal data
                DBG_ERROR( "Exception during import SchXMLChartContext::lcl_ApplyDataFromRectangularRangeToDiagram try to fallback to internal data" );
                if(!bHasOwnData)
                {
                    bHasOwnData = true;
                    msChartAddress = ::rtl::OUString::createFromAscii("all");
                    if( !xNewDoc->hasInternalDataProvider() )
                    {
                        xNewDoc->createInternalDataProvider( sal_False /* bCloneExistingData */ );
                        SchXMLTableHelper::applyTableToInternalDataProvider( maTable, xNewDoc );
                        try
                        {
                            lcl_ApplyDataFromRectangularRangeToDiagram( xNewDoc, msChartAddress, meDataRowSource, mbRowHasLabels, mbColHasLabels, bHasOwnData, msColTrans, msRowTrans );
                        }
                        catch( uno::Exception & )
                        {
                            DBG_ERROR( "Exception during import SchXMLChartContext::lcl_ApplyDataFromRectangularRangeToDiagram fallback to internal data failed also" );
                        }
                    }
                }
            }
        }
    }
    else
    {
        DBG_ERROR( " Must not get here" );
    }

    // now all series and data point properties are available and can be set
    {
        if( bSpecialHandlingForDonutChart )
        {
            uno::Reference< chart2::XDiagram > xNewDiagram( xNewDoc->getFirstDiagram() );
            lcl_swapPointAndSeriesStylesForDonutCharts( maSeriesDefaultsAndStyles.maSeriesStyleList
                , SchXMLSeriesHelper::getDataSeriesIndexMapFromDiagram(xNewDiagram) );
        }

        SchXMLSeries2Context::initSeriesPropertySets( maSeriesDefaultsAndStyles, uno::Reference< frame::XModel >(xDoc, uno::UNO_QUERY ) );

        //set defaults from diagram to the new series:
        //check whether we need to remove lines from symbol only charts
        bool bSwitchOffLinesForScatter = false;
        {
            bool bLinesOn = true;
            if( (maSeriesDefaultsAndStyles.maLinesOnProperty >>= bLinesOn) && !bLinesOn )
            {
                if( 0 == maChartTypeServiceName.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.ScatterChartType" ) ) )
                {
                    bSwitchOffLinesForScatter = true;
                    SchXMLSeries2Context::switchSeriesLinesOff( maSeriesDefaultsAndStyles.maSeriesStyleList );
                }
            }
        }
        SchXMLSeries2Context::setDefaultsToSeries( maSeriesDefaultsAndStyles );

        // set autostyles for series and data points
        const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
        const SvXMLStyleContext* pStyle = NULL;
	    ::rtl::OUString sCurrStyleName;

        if( pStylesCtxt )
	    {
            //iterate over data-series first
            //don't set series styles for donut charts
            if( !bSpecialHandlingForDonutChart )
            {
                SchXMLSeries2Context::setStylesToSeries( maSeriesDefaultsAndStyles
                                                         , pStylesCtxt, pStyle, sCurrStyleName, mrImportHelper, GetImport(), mbIsStockChart, maLSequencesPerIndex );
                // ... then set attributes for statistics (after their existence was set in the series)
                SchXMLSeries2Context::setStylesToStatisticsObjects( maSeriesDefaultsAndStyles
                            , pStylesCtxt, pStyle, sCurrStyleName );
            }
        }

        //#i98319# call switchRangesFromOuterToInternalIfNecessary before the data point styles are applied, otherwise in copy->paste scenario the data point styles do get lost
        if( bSwitchRangesFromOuterToInternalIfNecessary )
        {
            if( xNewDoc->hasInternalDataProvider() )
                SchXMLTableHelper::switchRangesFromOuterToInternalIfNecessary( maTable, maLSequencesPerIndex, xNewDoc, meDataRowSource );
        }

        if( pStylesCtxt )
        {
            // ... then iterate over data-point attributes, so the latter are not overwritten
            SchXMLSeries2Context::setStylesToDataPoints( maSeriesDefaultsAndStyles
                            , pStylesCtxt, pStyle, sCurrStyleName, mrImportHelper, GetImport(), mbIsStockChart, bSpecialHandlingForDonutChart, bSwitchOffLinesForScatter );
	    }
    }

    if( xProp.is())
	    xProp->setPropertyValue( rtl::OUString::createFromAscii( "RefreshAddInAllowed" ) , uno::makeAny( sal_True) );
}

void SchXMLChartContext::MergeSeriesForStockChart()
{
    OSL_ASSERT( mbIsStockChart );
    try
    {
        uno::Reference< chart::XChartDocument > xOldDoc( mrImportHelper.GetChartDocument());
        uno::Reference< chart2::XChartDocument > xDoc( xOldDoc, uno::UNO_QUERY_THROW );
        uno::Reference< chart2::XDiagram > xDiagram( xDoc->getFirstDiagram());
        if( ! xDiagram.is())
            return;

        bool bHasJapaneseCandlestick = true;
        uno::Reference< chart2::XDataSeriesContainer > xDSContainer;
        uno::Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
        uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
        for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
        {
            uno::Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
            uno::Sequence< uno::Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
            for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
            {
                if( aChartTypes[nCTIdx]->getChartType().equalsAsciiL(
                        RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.CandleStickChartType")))
                {
                    xDSContainer.set( aChartTypes[nCTIdx], uno::UNO_QUERY_THROW );
                    uno::Reference< beans::XPropertySet > xCTProp( aChartTypes[nCTIdx], uno::UNO_QUERY_THROW );
                    xCTProp->getPropertyValue( ::rtl::OUString::createFromAscii("Japanese")) >>= bHasJapaneseCandlestick;
                    break;
                }
            }
        }

        if( xDSContainer.is())
        {
            // with japanese candlesticks: open, low, high, close
            // otherwise: low, high, close
            uno::Sequence< uno::Reference< chart2::XDataSeries > > aSeriesSeq( xDSContainer->getDataSeries());
            const sal_Int32 nSeriesCount( aSeriesSeq.getLength());
            const sal_Int32 nSeriesPerCandleStick = bHasJapaneseCandlestick ? 4: 3;
            sal_Int32 nCandleStickCount = nSeriesCount / nSeriesPerCandleStick;
            OSL_ASSERT( nSeriesPerCandleStick * nCandleStickCount == nSeriesCount );
            uno::Sequence< uno::Reference< chart2::XDataSeries > > aNewSeries( nCandleStickCount );
            for( sal_Int32 i=0; i<nCandleStickCount; ++i )
            {
                sal_Int32 nSeriesIndex = i*nSeriesPerCandleStick;
                if( bHasJapaneseCandlestick )
                {
                    // open values
                    lcl_setRoleAtFirstSequence( aSeriesSeq[ nSeriesIndex ], OUString::createFromAscii("values-first"));
                    aNewSeries[i] = aSeriesSeq[ nSeriesIndex ];
                    // low values
                    lcl_MoveDataToCandleStickSeries(
                        uno::Reference< chart2::data::XDataSource >( aSeriesSeq[ ++nSeriesIndex ], uno::UNO_QUERY_THROW ),
                        aNewSeries[i], OUString::createFromAscii("values-min"));
                }
                else
                {
                    // low values
                    lcl_setRoleAtFirstSequence( aSeriesSeq[ nSeriesIndex ], OUString::createFromAscii("values-min"));
                    aNewSeries[i] = aSeriesSeq[ nSeriesIndex ];
                }
                // high values
                lcl_MoveDataToCandleStickSeries(
                    uno::Reference< chart2::data::XDataSource >( aSeriesSeq[ ++nSeriesIndex ], uno::UNO_QUERY_THROW ),
                    aNewSeries[i], OUString::createFromAscii("values-max"));
                // close values
                lcl_MoveDataToCandleStickSeries(
                    uno::Reference< chart2::data::XDataSource >( aSeriesSeq[ ++nSeriesIndex ], uno::UNO_QUERY_THROW ),
                    aNewSeries[i], OUString::createFromAscii("values-last"));
            }
            xDSContainer->setDataSeries( aNewSeries );
        }
    }
    catch( uno::Exception & )
    {
        DBG_ERROR( "Exception while merging series for stock chart" );
    }
}

SvXMLImportContext* SchXMLChartContext::CreateChildContext(
	sal_uInt16 nPrefix,
	const rtl::OUString& rLocalName,
	const uno::Reference< xml::sax::XAttributeList >& xAttrList )
{
    static const sal_Bool bTrue = sal_True;
    static const uno::Any aTrueBool( &bTrue, ::getBooleanCppuType());

	SvXMLImportContext* pContext = 0;
	const SvXMLTokenMap& rTokenMap = mrImportHelper.GetChartElemTokenMap();
	uno::Reference< chart::XChartDocument > xDoc = mrImportHelper.GetChartDocument();
    uno::Reference< beans::XPropertySet > xProp( xDoc, uno::UNO_QUERY );

	switch( rTokenMap.Get( nPrefix, rLocalName ))
	{
		case XML_TOK_CHART_PLOT_AREA:
			pContext = new SchXMLPlotAreaContext( mrImportHelper, GetImport(), rLocalName,
                                                  m_aXLinkHRefAttributeToIndicateDataProvider,
												  maSeriesAddresses, msCategoriesAddress,
                                                  msChartAddress, m_bHasRangeAtPlotArea, mbAllRangeAddressesAvailable,
                                                  mbColHasLabels, mbRowHasLabels,
                                                  meDataRowSource,
                                                  maSeriesDefaultsAndStyles,
                                                  maChartTypeServiceName,
                                                  maLSequencesPerIndex, maChartSize );
			break;

		case XML_TOK_CHART_TITLE:
			if( xDoc.is())
			{
				if( xProp.is())
				{
					xProp->setPropertyValue( rtl::OUString::createFromAscii( "HasMainTitle" ), aTrueBool );
				}
				uno::Reference< drawing::XShape > xTitleShape( xDoc->getTitle(), uno::UNO_QUERY );
				pContext = new SchXMLTitleContext( mrImportHelper, GetImport(),
												   rLocalName, maMainTitle, xTitleShape );
			}
			break;

		case XML_TOK_CHART_SUBTITLE:
			if( xDoc.is())
			{
				if( xProp.is())
				{
					xProp->setPropertyValue( rtl::OUString::createFromAscii( "HasSubTitle" ), aTrueBool );
				}
				uno::Reference< drawing::XShape > xTitleShape( xDoc->getSubTitle(), uno::UNO_QUERY );
				pContext = new SchXMLTitleContext( mrImportHelper, GetImport(),
												   rLocalName, maSubTitle, xTitleShape );
			}
			break;

		case XML_TOK_CHART_LEGEND:
			pContext = new SchXMLLegendContext( mrImportHelper, GetImport(), rLocalName );
			break;

		case XML_TOK_CHART_TABLE:
            {
                SchXMLTableContext * pTableContext =
                    new SchXMLTableContext( mrImportHelper, GetImport(), rLocalName, maTable );
                m_bHasTableElement = true;
                // #i85913# take into account column- and row- mapping for
                // charts with own data only for those which were not copied
                // from a place where they got data from the container.  Note,
                // that this requires the plot-area been read before the table
                // (which is required in the ODF spec)
                // Note: For stock charts and donut charts with special handling
                // the mapping must not be applied!
                if( !msChartAddress.getLength() && !mbIsStockChart &&
                    !lcl_SpecialHandlingForDonutChartNeeded(
                        maChartTypeServiceName, GetImport()))
                {
                    if( msColTrans.getLength() > 0 )
                    {
                        OSL_ASSERT( msRowTrans.getLength() == 0 );
                        pTableContext->setColumnPermutation( lcl_getNumberSequenceFromString( msColTrans, true ));
                        msColTrans = OUString();
                    }
                    else if( msRowTrans.getLength() > 0 )
                    {
                        pTableContext->setRowPermutation( lcl_getNumberSequenceFromString( msRowTrans, true ));
                        msRowTrans = OUString();
                    }
                }
                pContext = pTableContext;
            }
            break;

        default:
            // try importing as an additional shape
            if( ! mxDrawPage.is())
            {
                uno::Reference< drawing::XDrawPageSupplier  > xSupp( xDoc, uno::UNO_QUERY );
                if( xSupp.is())
                    mxDrawPage = uno::Reference< drawing::XShapes >( xSupp->getDrawPage(), uno::UNO_QUERY );

                DBG_ASSERT( mxDrawPage.is(), "Invalid Chart Page" );
            }
            if( mxDrawPage.is())
                pContext = GetImport().GetShapeImport()->CreateGroupChildContext(
                    GetImport(), nPrefix, rLocalName, xAttrList, mxDrawPage );
            break;
	}

	if( ! pContext )
		pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );

	return pContext;
}


/*
	With a locked controller the following is done here:
		1.	Hide title, subtitle, and legend.
		2.	Set the size of the draw page.
		3.	Set a (logically) empty data set.
		4.	Set the chart type.
*/
void SchXMLChartContext::InitChart(
    const OUString & rChartTypeServiceName, // currently the old service name
    sal_Bool /* bSetSwitchData */ )
{
    uno::Reference< chart::XChartDocument > xDoc = mrImportHelper.GetChartDocument();
	DBG_ASSERT( xDoc.is(), "No valid document!" );
	uno::Reference< frame::XModel > xModel (xDoc, uno::UNO_QUERY );

	// Remove Title and Diagram ("De-InitNew")
	uno::Reference< chart2::XChartDocument > xNewDoc( mrImportHelper.GetChartDocument(), uno::UNO_QUERY );
	if( xNewDoc.is())
	{
        xNewDoc->setFirstDiagram( 0 );
        uno::Reference< chart2::XTitled > xTitled( xNewDoc, uno::UNO_QUERY );
        if( xTitled.is())
            xTitled->setTitleObject( 0 );
    }

	//	Set the chart type via setting the diagram.
	if( rChartTypeServiceName.getLength() &&
		xDoc.is())
	{
		uno::Reference< lang::XMultiServiceFactory > xFact( xDoc, uno::UNO_QUERY );
		if( xFact.is())
		{
			uno::Reference< chart::XDiagram > xDia( xFact->createInstance( rChartTypeServiceName ), uno::UNO_QUERY );
            if( xDia.is())
				xDoc->setDiagram( xDia );
		}
	}
}

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

SchXMLTitleContext::SchXMLTitleContext( SchXMLImportHelper& rImpHelper, SvXMLImport& rImport,
										const rtl::OUString& rLocalName,
										rtl::OUString& rTitle,
										uno::Reference< drawing::XShape >& xTitleShape ) :
		SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ),
		mrImportHelper( rImpHelper ),
		mrTitle( rTitle ),
		mxTitleShape( xTitleShape )
{
}

SchXMLTitleContext::~SchXMLTitleContext()
{}

void SchXMLTitleContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
{
	sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;

    com::sun::star::awt::Point maPosition;
    bool bHasXPosition=false;
    bool bHasYPosition=false;

	for( sal_Int16 i = 0; i < nAttrCount; i++ )
	{
		rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
		rtl::OUString aLocalName;
		rtl::OUString aValue = xAttrList->getValueByIndex( i );
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );

		if( nPrefix == XML_NAMESPACE_SVG )
		{
			if( IsXMLToken( aLocalName, XML_X ) )
            {
				GetImport().GetMM100UnitConverter().convertMeasure( maPosition.X, aValue );
                bHasXPosition = true;
            }
			else if( IsXMLToken( aLocalName, XML_Y ) )
            {
				GetImport().GetMM100UnitConverter().convertMeasure( maPosition.Y, aValue );
                bHasYPosition = true;
            }
		}
		else if( nPrefix == XML_NAMESPACE_CHART )
		{
			if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
				msAutoStyleName = aValue;
		}
	}


	if( mxTitleShape.is())
	{
        if( bHasXPosition && bHasYPosition )
            mxTitleShape->setPosition( maPosition );

		uno::Reference< beans::XPropertySet > xProp( mxTitleShape, uno::UNO_QUERY );
		if( xProp.is())
		{
			const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
			if( pStylesCtxt )
			{
				const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
					mrImportHelper.GetChartFamilyID(), msAutoStyleName );

				if( pStyle && pStyle->ISA( XMLPropStyleContext ))
					(( XMLPropStyleContext* )pStyle )->FillPropertySet( xProp );
			}
		}
	}
}

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

	if( nPrefix == XML_NAMESPACE_TEXT &&
		IsXMLToken( rLocalName, XML_P ) )
	{
		pContext = new SchXMLParagraphContext( GetImport(), rLocalName, mrTitle );
	}
	else
		pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );

	return pContext;
}

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