[ooo-build-commit] patches/ooxml

Pei Feng Lin pflin at kemper.freedesktop.org
Mon Jan 4 23:01:28 PST 2010


 patches/ooxml/oox-chart-export-part1.diff | 2069 ++++++++++++++++++++++++++++++
 1 file changed, 2069 insertions(+)

New commits:
commit 77bb4fe806403f99a2e32e99703ec356c53473d0
Author: Fong Lin <pflin at novell.com>
Date:   Tue Jan 5 13:59:46 2010 +0800

    add chart export part1 to ooxml
    
    * patches/ooxml/oox-chart-export-part1.diff:

diff --git a/patches/ooxml/oox-chart-export-part1.diff b/patches/ooxml/oox-chart-export-part1.diff
new file mode 100644
index 0000000..0bcc11c
--- /dev/null
+++ b/patches/ooxml/oox-chart-export-part1.diff
@@ -0,0 +1,2069 @@
+diff --git oox/inc/oox/export/chartexport.hxx oox/inc/oox/export/chartexport.hxx
+new file mode 100644
+index 0000000..5eba2ed
+--- /dev/null
++++ oox/inc/oox/export/chartexport.hxx
+@@ -0,0 +1,151 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile$
++ * $Revision$
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++#ifndef _OOX_EXPORT_CHART_HXX_
++#define _OOX_EXPORT_CHART_HXX_
++
++#include <oox/dllapi.h>
++#include <com/sun/star/uno/XReference.hpp>
++#include <oox/export/drawingml.hxx>
++#include <sax/fshelper.hxx>
++#include <vcl/mapmod.hxx>
++#include <hash_map>
++
++namespace com { namespace sun { namespace star {
++    namespace chart {
++        class XDiagram;
++        class XChartDocument;
++        class XChartDataArray;
++        struct ChartSeriesAddress;
++    }
++    namespace chart2 {
++        class XDiagram;
++        class XChartDocument;
++        class XDataSeries;
++        namespace data
++        {
++            class XDataProvider;
++            class XDataSequence;
++        }
++    }
++    namespace drawing {
++        class XShape;
++        class XShapes;
++    }
++    namespace task {
++        class XStatusIndicator;
++    }
++    namespace frame {
++        class XModel;
++    }
++}}}
++
++namespace oox { namespace drawingml {
++
++class OOX_DLLPUBLIC ChartExport : public DrawingML {
++
++public:
++    // first: data sequence for label, second: data sequence for values.
++    typedef ::std::pair< ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >,
++            ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence > > tLabelValuesDataPair;
++    typedef ::std::vector< tLabelValuesDataPair > tDataSequenceCont;
++
++private:
++    sal_Int32           mnXmlNamespace;
++    Fraction            maFraction;
++    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > mxChartModel;
++
++    rtl::OUString msTableName;
++    rtl::OUStringBuffer msStringBuffer;
++    rtl::OUString msString;
++
++    // members filled by InitRangeSegmentationProperties (retrieved from DataProvider)
++    sal_Bool mbHasSeriesLabels;
++    sal_Bool mbHasCategoryLabels; //if the categories are only automatically generated this will be false
++    sal_Bool mbRowSourceColumns;
++    rtl::OUString msChartAddress;
++    rtl::OUString msTableNumberList;
++    ::com::sun::star::uno::Sequence< sal_Int32 > maSequenceMapping;
++
++    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > mxAdditionalShapes;
++
++    tDataSequenceCont m_aDataSequencesToExport;
++
++private:
++    sal_Int32 getChartType(
++        com::sun::star::uno::Reference< com::sun::star::chart::XDiagram > xDiagram );
++
++    void _ExportContent();
++    void exportChartSpace( com::sun::star::uno::Reference<
++                          com::sun::star::chart::XChartDocument > rChartDoc,
++                      sal_Bool bIncludeTable );
++    void exportChart( com::sun::star::uno::Reference<
++                          com::sun::star::chart::XChartDocument > rChartDoc );
++    void exportPlotArea(
++        com::sun::star::uno::Reference< com::sun::star::chart::XDiagram > xDiagram,
++        com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > xNewDiagram );
++    void exportBarChart(
++        com::sun::star::uno::Reference< com::sun::star::chart::XDiagram > xDiagram,
++        com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > xNewDiagram );
++    void exportSeries(
++        com::sun::star::uno::Reference< com::sun::star::chart::XDiagram > xDiagram,
++        com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > xNewDiagram );
++    void exportDataSeq(
++        const com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >& xValueSeq,
++        sal_Int32 elementTokenId );
++    void exportSeriesText(
++        const com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >& xValueSeq );
++    void exportSeriesCategory(
++        const com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >& xValueSeq );
++    void exportSeriesValues(
++        const com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >& xValueSeq );
++        
++
++public:
++
++    ChartExport( sal_Int32 nXmlNamespace, ::sax_fastparser::FSHelperPtr pFS, ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel, ::oox::core::XmlFilterBase* pFB = NULL, DocumentType eDocumentType = DOCUMENT_PPTX );
++    virtual ~ChartExport() {}
++
++    sal_Int32           GetXmlNamespace() const;
++    ChartExport&        SetXmlNamespace( sal_Int32 nXmlNamespace );
++    sal_Int32           GetChartID( );
++    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > getModel(){ return mxChartModel; }
++
++    virtual ChartExport& WriteChartObj( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape, sal_Int32 nChartCount );
++
++    void ExportContent();
++    void InitRangeSegmentationProperties(
++        const ::com::sun::star::uno::Reference<
++            ::com::sun::star::chart2::XChartDocument > & xChartDoc );
++};
++
++}}
++
++#endif /* ndef _OOX_EXPORT_CHART_HXX_ */
+diff --git oox/inc/oox/export/drawingml.hxx oox/inc/oox/export/drawingml.hxx
+index 211c90e..1b6f3ed 100644
+--- oox/inc/oox/export/drawingml.hxx
++++ oox/inc/oox/export/drawingml.hxx
+@@ -27,6 +27,9 @@ namespace text {
+     class XTextContent;
+     class XTextRange;
+ }
++namespace io {
++    struct XOutputStream;
++}
+ }}}
+ 
+ namespace oox {
+@@ -110,6 +113,15 @@ public:
+     sal_uInt32 ColorWithIntensity( sal_uInt32 nColor, sal_uInt32 nIntensity );
+ 
+     static const char* GetAlignment( sal_Int32 nAlignment );
++
++    sax_fastparser::FSHelperPtr     CreateOutputStream (
++                                        const ::rtl::OUString& sFullStream,
++                                        const ::rtl::OUString& sRelativeStream,
++                                        const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xParentRelation,
++                                        const char* sContentType,
++                                        const char* sRelationshipType,
++                                        ::rtl::OUString* pRelationshipId = NULL );
++
+ };
+ 
+ }
+diff --git oox/source/export/SchXMLSeriesHelper.cxx oox/source/export/SchXMLSeriesHelper.cxx
+new file mode 100644
+index 0000000..ede0a9c
+--- /dev/null
++++ oox/source/export/SchXMLSeriesHelper.cxx
+@@ -0,0 +1,302 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ * 
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: SchXMLSeriesHelper.cxx,v $
++ * $Revision: 1.5 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++// MARKER(update_precomp.py): autogen include statement, do not remove
++#include "SchXMLSeriesHelper.hxx"
++#include <com/sun/star/chart2/XChartDocument.hpp>
++#include <com/sun/star/chart2/XChartTypeContainer.hpp>
++#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
++#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
++#include <com/sun/star/lang/XInitialization.hpp>
++#include <com/sun/star/lang/XMultiServiceFactory.hpp>
++
++// header for define RTL_CONSTASCII_USTRINGPARAM
++#include <rtl/ustring.h>
++// header for define DBG_ERROR1
++#include <tools/debug.hxx>
++
++#include <typeinfo>
++
++using namespace ::com::sun::star;
++using ::rtl::OUString;
++using ::rtl::OUStringToOString;
++
++using ::com::sun::star::uno::Reference;
++using ::com::sun::star::uno::Sequence;
++using ::rtl::OUString;
++
++// ----------------------------------------
++
++::std::vector< Reference< chart2::XDataSeries > >
++    SchXMLSeriesHelper::getDataSeriesFromDiagram(
++        const Reference< chart2::XDiagram > & xDiagram )
++{
++    ::std::vector< Reference< chart2::XDataSeries > > aResult;
++
++    try
++    {
++        Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
++            xDiagram, uno::UNO_QUERY_THROW );
++        Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
++            xCooSysCnt->getCoordinateSystems());
++        for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
++        {
++            Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
++            Sequence< Reference< chart2::XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
++            for( sal_Int32 j=0; j<aChartTypeSeq.getLength(); ++j )
++            {
++                Reference< chart2::XDataSeriesContainer > xDSCnt( aChartTypeSeq[j], uno::UNO_QUERY_THROW );
++                Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries() );
++                ::std::copy( aSeriesSeq.getConstArray(), aSeriesSeq.getConstArray() + aSeriesSeq.getLength(),
++                             ::std::back_inserter( aResult ));
++            }
++        }
++    }
++    catch( uno::Exception & ex )
++    {
++        (void)ex; // avoid warning for pro build
++
++        OSL_ENSURE( false, OUStringToOString( OUString(
++                        OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
++                        OUString::createFromAscii( typeid( ex ).name()) +
++                        OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
++                        ex.Message), RTL_TEXTENCODING_ASCII_US ).getStr());
++
++    }
++
++    return aResult;
++}
++
++::std::map< Reference< chart2::XDataSeries >, sal_Int32 > SchXMLSeriesHelper::getDataSeriesIndexMapFromDiagram(
++        const Reference< chart2::XDiagram > & xDiagram )
++{
++    ::std::map< Reference< chart2::XDataSeries >, sal_Int32 > aRet;
++
++    sal_Int32 nIndex=0;
++
++    ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( SchXMLSeriesHelper::getDataSeriesFromDiagram( xDiagram ));
++    for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aSeriesIt( aSeriesVector.begin() )
++        ; aSeriesIt != aSeriesVector.end()
++        ; aSeriesIt++, nIndex++ )
++    {
++        Reference< chart2::XDataSeries > xSeries( *aSeriesIt );
++        if( xSeries.is() )
++        {
++            if( aRet.end() == aRet.find(xSeries) )
++                aRet[xSeries]=nIndex;
++        }
++    }
++    return aRet;
++}
++
++uno::Reference< chart2::XChartType > lcl_getChartTypeOfSeries(
++                                const uno::Reference< chart2::XDiagram >&   xDiagram
++                              , const Reference< chart2::XDataSeries >& xSeries )
++{
++    if(!xDiagram.is())
++        return 0;
++
++    //iterate through the model to find the given xSeries
++    //the found parent indicates the charttype
++
++    //iterate through all coordinate systems
++    uno::Reference< chart2::XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
++    if( !xCooSysContainer.is())
++        return 0;
++
++    uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
++    for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
++    {
++        uno::Reference< chart2::XCoordinateSystem > xCooSys( aCooSysList[nCS] );
++
++        //iterate through all chart types in the current coordinate system
++        uno::Reference< chart2::XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
++        OSL_ASSERT( xChartTypeContainer.is());
++        if( !xChartTypeContainer.is() )
++            continue;
++        uno::Sequence< uno::Reference< chart2::XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
++        for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
++        {
++            uno::Reference< chart2::XChartType > xChartType( aChartTypeList[nT] );
++
++            //iterate through all series in this chart type
++            uno::Reference< chart2::XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
++            OSL_ASSERT( xDataSeriesContainer.is());
++            if( !xDataSeriesContainer.is() )
++                continue;
++
++            uno::Sequence< uno::Reference< chart2::XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
++            for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
++            {
++                Reference< chart2::XDataSeries > xCurrentSeries( aSeriesList[nS] );
++
++                if( xSeries == xCurrentSeries )
++                    return xChartType;
++            }
++        }
++    }
++    return 0;
++}
++
++bool SchXMLSeriesHelper::isCandleStickSeries(
++                  const Reference< chart2::XDataSeries >& xSeries
++                , const Reference< frame::XModel >& xChartModel )
++{
++    bool bRet = false;
++
++    uno::Reference< chart2::XChartDocument > xNewDoc( xChartModel, uno::UNO_QUERY );
++    if( xNewDoc.is() )
++    {
++        uno::Reference< chart2::XDiagram > xNewDiagram( xNewDoc->getFirstDiagram() );
++        if( xNewDiagram.is() )
++        {
++            uno::Reference< chart2::XChartType > xChartType( lcl_getChartTypeOfSeries(
++                                        xNewDiagram, xSeries ) );
++            if( xChartType.is() )
++            {
++                rtl::OUString aServiceName( xChartType->getChartType() );
++                if( aServiceName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.CandleStickChartType" ) ) ) )
++                    bRet = true;
++            }
++        }
++    }
++    return bRet;
++}
++
++// static
++Reference< chart2::XDataSeries > SchXMLSeriesHelper::getFirstCandleStickSeries(
++    const Reference< chart2::XDiagram > & xDiagram  )
++{
++    Reference< chart2::XDataSeries > xResult;
++
++    try
++    {
++        Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
++        Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
++        for( sal_Int32 nCooSysIdx=0; !xResult.is() && nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
++        {
++            Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
++            Sequence< Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes());
++            for( sal_Int32 nCTIdx=0; !xResult.is() && nCTIdx<aCTSeq.getLength(); ++nCTIdx )
++            {
++                if( aCTSeq[nCTIdx]->getChartType().equals(
++                        ::rtl::OUString::createFromAscii("com.sun.star.chart2.CandleStickChartType")))
++                {
++                    Reference< chart2::XDataSeriesContainer > xSeriesCnt( aCTSeq[nCTIdx], uno::UNO_QUERY_THROW );
++                    Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xSeriesCnt->getDataSeries() );
++                    if( aSeriesSeq.getLength())
++                        xResult.set( aSeriesSeq[0] );
++                    break;
++                }
++            }
++        }
++    }
++    catch( const uno::Exception & )
++    {
++        OSL_ENSURE( false, "Exception caught" );
++    }
++    return xResult;
++}
++
++//static
++uno::Reference< beans::XPropertySet > SchXMLSeriesHelper::createOldAPISeriesPropertySet(
++            const uno::Reference< chart2::XDataSeries >& xSeries
++            , const uno::Reference< frame::XModel >& xChartModel )
++{
++    uno::Reference< beans::XPropertySet > xRet;
++
++    if( xSeries.is() )
++    {
++        try
++        {
++            uno::Reference< lang::XMultiServiceFactory > xFactory( xChartModel, uno::UNO_QUERY );
++            if( xFactory.is() )
++            {
++                xRet = uno::Reference< beans::XPropertySet >( xFactory->createInstance(
++                    OUString::createFromAscii( "com.sun.star.comp.chart2.DataSeriesWrapper" ) ), uno::UNO_QUERY );
++                Reference< lang::XInitialization > xInit( xRet, uno::UNO_QUERY );
++                if(xInit.is())
++                {
++                    Sequence< uno::Any > aArguments(1);
++                    aArguments[0]=uno::makeAny(xSeries);
++                    xInit->initialize(aArguments);
++                }
++            }
++        }
++        catch( uno::Exception & rEx )
++        {
++            (void)rEx; // avoid warning for pro build
++            DBG_ERROR1( "Exception caught SchXMLSeriesHelper::createOldAPISeriesPropertySet: %s",
++                        OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
++        }
++    }
++
++    return xRet;
++}
++
++//static
++uno::Reference< beans::XPropertySet > SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
++            const uno::Reference< chart2::XDataSeries >& xSeries
++            , sal_Int32 nPointIndex
++            , const uno::Reference< frame::XModel >& xChartModel )
++{
++    uno::Reference< beans::XPropertySet > xRet;
++
++    if( xSeries.is() )
++    {
++        try
++        {
++            uno::Reference< lang::XMultiServiceFactory > xFactory( xChartModel, uno::UNO_QUERY );
++            if( xFactory.is() )
++            {
++                xRet = uno::Reference< beans::XPropertySet >( xFactory->createInstance(
++                    OUString::createFromAscii( "com.sun.star.comp.chart2.DataSeriesWrapper" ) ), uno::UNO_QUERY );
++                Reference< lang::XInitialization > xInit( xRet, uno::UNO_QUERY );
++                if(xInit.is())
++                {
++                    Sequence< uno::Any > aArguments(2);
++                    aArguments[0]=uno::makeAny(xSeries);
++                    aArguments[1]=uno::makeAny(nPointIndex);
++                    xInit->initialize(aArguments);
++                }
++            }
++        }
++        catch( uno::Exception & rEx )
++        {
++            (void)rEx; // avoid warning for pro build
++
++            DBG_ERROR1( "Exception caught SchXMLSeriesHelper::createOldAPIDataPointPropertySet: %s",
++                        OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
++        }
++    }
++
++    return xRet;
++}
++
+diff --git oox/source/export/SchXMLSeriesHelper.hxx oox/source/export/SchXMLSeriesHelper.hxx
+new file mode 100644
+index 0000000..6c8a458
+--- /dev/null
++++ oox/source/export/SchXMLSeriesHelper.hxx
+@@ -0,0 +1,83 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ * 
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: SchXMLSeriesHelper.hxx,v $
++ * $Revision: 1.3 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++#ifndef _XMLOFF_SCH_XML_SERIESHELPER_HXX
++#define _XMLOFF_SCH_XML_SERIESHELPER_HXX
++
++#include <com/sun/star/chart2/data/XDataSequence.hpp>
++#include <com/sun/star/chart2/data/XDataSource.hpp>
++#include <com/sun/star/chart2/XDataSeries.hpp>
++#include <com/sun/star/chart2/XDiagram.hpp>
++#include <com/sun/star/frame/XModel.hpp>
++
++#include <vector>
++#include <map>
++
++class SchXMLSeriesHelper
++{
++public:
++    static ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries > >
++            getDataSeriesFromDiagram(
++                const ::com::sun::star::uno::Reference<
++                    ::com::sun::star::chart2::XDiagram > & xDiagram );
++    static ::std::map< ::com::sun::star::uno::Reference<
++                ::com::sun::star::chart2::XDataSeries >, sal_Int32 > 
++            getDataSeriesIndexMapFromDiagram(
++                const ::com::sun::star::uno::Reference<
++                    ::com::sun::star::chart2::XDiagram > & xDiagram );
++
++    static bool isCandleStickSeries(
++                  const ::com::sun::star::uno::Reference<
++                    ::com::sun::star::chart2::XDataSeries >& xSeries
++                , const ::com::sun::star::uno::Reference<
++                    ::com::sun::star::frame::XModel >& xChartModel  );
++
++    static ::com::sun::star::uno::Reference<
++                ::com::sun::star::chart2::XDataSeries > getFirstCandleStickSeries(
++                    const ::com::sun::star::uno::Reference<
++                        ::com::sun::star::chart2::XDiagram > & xDiagram  );
++
++    static ::com::sun::star::uno::Reference<
++                ::com::sun::star::beans::XPropertySet > createOldAPISeriesPropertySet(
++                    const ::com::sun::star::uno::Reference<
++                        ::com::sun::star::chart2::XDataSeries >& xSeries
++                    , const ::com::sun::star::uno::Reference<
++                        ::com::sun::star::frame::XModel >& xChartModel );
++
++    static ::com::sun::star::uno::Reference<
++                ::com::sun::star::beans::XPropertySet > createOldAPIDataPointPropertySet(
++                    const ::com::sun::star::uno::Reference<
++                        ::com::sun::star::chart2::XDataSeries >& xSeries
++                    , sal_Int32 nPointIndex
++                    , const ::com::sun::star::uno::Reference<
++                        ::com::sun::star::frame::XModel >& xChartModel );
++};
++
++// _XMLOFF_SCH_XML_SERIESHELPER_HXX
++#endif
+diff --git oox/source/export/chartexport.cxx oox/source/export/chartexport.cxx
+new file mode 100644
+index 0000000..7abeb14
+--- /dev/null
++++ oox/source/export/chartexport.cxx
+@@ -0,0 +1,1174 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile$
++ * $Revision$
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++#include "tokens.hxx"
++#include "oox/core/xmlfilterbase.hxx"
++#include "oox/export/chartexport.hxx"
++#include "oox/export/utils.hxx"
++#include "oox/drawingml/chart/typegroupconverter.hxx"
++
++#include <cstdio>
++
++#include <com/sun/star/chart/XChartDocument.hpp>
++#include <com/sun/star/chart/ChartLegendPosition.hpp>
++#include <com/sun/star/chart/XTwoAxisXSupplier.hpp>
++#include <com/sun/star/chart/XTwoAxisYSupplier.hpp>
++#include <com/sun/star/chart/XAxisZSupplier.hpp>
++#include <com/sun/star/chart/XChartDataArray.hpp>
++#include <com/sun/star/chart/ChartDataRowSource.hpp>
++#include <com/sun/star/chart/ChartAxisAssign.hpp>
++#include <com/sun/star/chart/ChartSeriesAddress.hpp>
++#include <com/sun/star/chart/X3DDisplay.hpp>
++#include <com/sun/star/chart/XStatisticDisplay.hpp>
++#include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
++
++#include <com/sun/star/chart2/XChartDocument.hpp>
++#include <com/sun/star/chart2/XDiagram.hpp>
++#include <com/sun/star/chart2/RelativePosition.hpp>
++#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
++#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
++#include <com/sun/star/chart2/XChartTypeContainer.hpp>
++#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
++#include <com/sun/star/chart2/data/XDataSource.hpp>
++#include <com/sun/star/chart2/data/XDataSink.hpp>
++#include <com/sun/star/chart2/data/XDataReceiver.hpp>
++#include <com/sun/star/chart2/data/XDataProvider.hpp>
++#include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
++#include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
++#include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
++#include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
++
++#include <com/sun/star/beans/XPropertySet.hpp>
++#include <com/sun/star/beans/XPropertyState.hpp>
++#include <com/sun/star/container/XEnumerationAccess.hpp>
++#include <com/sun/star/drawing/XShape.hpp>
++
++#include <comphelper/processfactory.hxx>
++#include "SchXMLSeriesHelper.hxx"
++
++using namespace ::com::sun::star;
++using namespace ::com::sun::star::uno;
++using namespace ::com::sun::star::drawing;
++using ::com::sun::star::beans::PropertyState;
++using ::com::sun::star::beans::PropertyValue;
++using ::com::sun::star::beans::XPropertySet;
++using ::com::sun::star::beans::XPropertyState;
++using ::com::sun::star::container::XEnumeration;
++using ::com::sun::star::container::XEnumerationAccess;
++using ::com::sun::star::container::XIndexAccess;
++using ::com::sun::star::io::XOutputStream;
++using ::oox::core::XmlFilterBase;
++using ::rtl::OString;
++using ::rtl::OStringBuffer;
++using ::rtl::OUString;
++using ::rtl::OUStringBuffer;
++using ::sax_fastparser::FSHelperPtr;
++
++DBG(extern void dump_pset(Reference< XPropertySet > rXPropSet));
++
++#define IDS(x) (OString(#x " ") + OString::valueOf( mnShapeIdMax++ )).getStr()
++
++namespace oox { namespace drawingml {
++
++#define GETA(propName) \
++    GetProperty( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( #propName ) ) )
++
++#define GETAD(propName) \
++    ( GetPropertyAndState( rXPropSet, rXPropState, String( RTL_CONSTASCII_USTRINGPARAM( #propName ) ), eState ) && eState == beans::PropertyState_DIRECT_VALUE )
++
++#define GET(variable, propName) \
++    if ( GETA(propName) ) \
++        mAny >>= variable;
++
++Reference< uno::XComponentContext > lcl_getComponentContext()
++{
++    Reference< uno::XComponentContext > xContext;
++    try
++    {
++        Reference< beans::XPropertySet > xFactProp( comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
++        if( xFactProp.is())
++            xFactProp->getPropertyValue(OUString::createFromAscii("DefaultContext")) >>= xContext;
++    }
++    catch( uno::Exception& )
++    {}
++
++    return xContext;
++}
++
++class lcl_MatchesRole : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool >
++{
++public:
++    explicit lcl_MatchesRole( const OUString & aRole ) :
++            m_aRole( aRole )
++    {}
++
++    bool operator () ( const Reference< chart2::data::XLabeledDataSequence > & xSeq ) const
++    {
++        if( !xSeq.is() )
++            return  false;
++        Reference< beans::XPropertySet > xProp( xSeq->getValues(), uno::UNO_QUERY );
++        OUString aRole;
++
++        return ( xProp.is() &&
++                 (xProp->getPropertyValue(
++                     OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )) ) >>= aRole ) &&
++                 m_aRole.equals( aRole ));
++    }
++
++private:
++    OUString m_aRole;
++};
++
++template< typename T >
++    void lcl_SequenceToVectorAppend( const Sequence< T > & rSource, ::std::vector< T > & rDestination )
++{
++    rDestination.reserve( rDestination.size() + rSource.getLength());
++    ::std::copy( rSource.getConstArray(), rSource.getConstArray() + rSource.getLength(),
++                 ::std::back_inserter( rDestination ));
++}
++
++Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const Reference< chart2::XDiagram > & xDiagram )
++{
++    Reference< chart2::data::XLabeledDataSequence >  xResult;
++    try
++    {
++        Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
++            xDiagram, uno::UNO_QUERY_THROW );
++        Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
++            xCooSysCnt->getCoordinateSystems());
++        for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
++        {
++            Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[i] );
++            OSL_ASSERT( xCooSys.is());
++            for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
++            {
++                const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
++                for(sal_Int32 nI=0; nI<=nMaxAxisIndex; ++nI)
++                {
++                    Reference< chart2::XAxis > xAxis = xCooSys->getAxisByDimension( nN, nI );
++                    OSL_ASSERT( xAxis.is());
++                    if( xAxis.is())
++                    {
++                        chart2::ScaleData aScaleData = xAxis->getScaleData();
++                        if( aScaleData.Categories.is())
++                        {
++                            xResult.set( aScaleData.Categories );
++                            break;
++                        }
++                    }
++                }
++            }
++        }
++    }
++    catch( uno::Exception & ex )
++    {
++        (void)ex; // avoid warning for pro build
++        OSL_ENSURE( false, OUStringToOString(
++                        OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
++                        OUString::createFromAscii( typeid( ex ).name()) +
++                        OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
++                        ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
++    }
++
++    /*
++    //unused ranges are very problematic as they bear the risk to damage the rectangular structure completly
++    if(!xResult.is())
++    {
++        Sequence< Reference< chart2::data::XLabeledDataSequence > > aUnusedSequences( xDiagram->getUnusedData() );
++
++        lcl_MatchesRole aHasCategories( OUString::createFromAscii("categories" ) );
++        for( sal_Int32 nN=0; nN<aUnusedSequences.getLength(); nN++ )
++        {
++            if( aHasCategories( aUnusedSequences[nN] ) )
++            {
++                xResult.set( aUnusedSequences[nN] );
++                break;
++            }
++        }
++    }
++    */
++
++    return xResult;
++}
++
++Reference< chart2::data::XDataSource > lcl_createDataSource(
++    const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aData )
++{
++    Reference< chart2::data::XDataSink > xSink;
++    Reference< uno::XComponentContext > xContext( lcl_getComponentContext());
++    if( xContext.is() )
++        xSink.set(
++            xContext->getServiceManager()->createInstanceWithContext(
++                OUString::createFromAscii("com.sun.star.chart2.data.DataSource"),
++                xContext ), uno::UNO_QUERY_THROW );
++    if( xSink.is())
++        xSink->setData( aData );
++
++    return Reference< chart2::data::XDataSource >( xSink, uno::UNO_QUERY );
++}
++
++Sequence< Reference< chart2::data::XLabeledDataSequence > > lcl_getAllSeriesSequences( const Reference< chart2::XChartDocument >& xChartDoc )
++{
++    ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aContainer;
++    if( xChartDoc.is() )
++    {
++        Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
++        ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( SchXMLSeriesHelper::getDataSeriesFromDiagram( xDiagram ));
++        for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aSeriesIt( aSeriesVector.begin() )
++            ; aSeriesIt != aSeriesVector.end(); ++aSeriesIt )
++        {
++            Reference< chart2::data::XDataSource > xDataSource( *aSeriesIt, uno::UNO_QUERY );
++            if( !xDataSource.is() )
++                continue;
++            uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > aDataSequences( xDataSource->getDataSequences() );
++            lcl_SequenceToVectorAppend( aDataSequences, aContainer );
++        }
++    }
++
++    Sequence< Reference< chart2::data::XLabeledDataSequence > > aRet( aContainer.size());
++    ::std::copy( aContainer.begin(), aContainer.end(), aRet.getArray());
++
++    return aRet;
++}
++
++Reference< chart2::data::XLabeledDataSequence >
++    lcl_getDataSequenceByRole(
++        const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aLabeledSeq,
++        const OUString & rRole )
++{
++    Reference< chart2::data::XLabeledDataSequence > aNoResult;
++
++    const Reference< chart2::data::XLabeledDataSequence > * pBegin = aLabeledSeq.getConstArray();
++    const Reference< chart2::data::XLabeledDataSequence > * pEnd = pBegin + aLabeledSeq.getLength();
++    const Reference< chart2::data::XLabeledDataSequence > * pMatch =
++        ::std::find_if( pBegin, pEnd, lcl_MatchesRole( rRole ));
++
++    if( pMatch != pEnd )
++        return *pMatch;
++
++    return aNoResult;
++}
++
++Reference< chart2::data::XDataSource > lcl_pressUsedDataIntoRectangularFormat( const Reference< chart2::XChartDocument >& xChartDoc, sal_Bool& rOutSourceHasCategoryLabels )
++{
++    ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aLabeledSeqVector;
++
++    //categories are always the first sequence
++    Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
++    Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xDiagram ) );
++    if( xCategories.is() )
++        aLabeledSeqVector.push_back( xCategories );
++    rOutSourceHasCategoryLabels = sal_Bool(xCategories.is());
++
++    Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeriesSeqVector(
++            lcl_getAllSeriesSequences( xChartDoc ) );
++
++    //the first x-values is always the next sequence //todo ... other x-values get lost for old format
++    Reference< chart2::data::XLabeledDataSequence > xXValues(
++        lcl_getDataSequenceByRole( aSeriesSeqVector, OUString::createFromAscii("values-x" ) ) );
++    if( xXValues.is() )
++        aLabeledSeqVector.push_back( xXValues );
++    
++    //add all other sequences now without x-values
++    lcl_MatchesRole aHasXValues( OUString::createFromAscii("values-x" ) );
++    for( sal_Int32 nN=0; nN<aSeriesSeqVector.getLength(); nN++ )
++    {
++        if( !aHasXValues( aSeriesSeqVector[nN] ) )
++            aLabeledSeqVector.push_back( aSeriesSeqVector[nN] );
++    }
++
++    Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( aLabeledSeqVector.size() );
++    ::std::copy( aLabeledSeqVector.begin(), aLabeledSeqVector.end(), aSeq.getArray() );
++
++    return lcl_createDataSource( aSeq );
++}
++
++bool lcl_isSeriesAttachedToFirstAxis(
++    const Reference< chart2::XDataSeries > & xDataSeries )
++{
++    bool bResult=true;
++
++    try
++    {
++        sal_Int32 nAxisIndex = 0;
++        Reference< beans::XPropertySet > xProp( xDataSeries, uno::UNO_QUERY_THROW );
++        if( xProp.is() )
++            xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("AttachedAxisIndex") ) ) >>= nAxisIndex;
++        bResult = (0==nAxisIndex);
++    }
++    catch( uno::Exception & ex )
++    {
++        (void)ex; // avoid warning for pro build
++        OSL_ENSURE( false, OUStringToOString(
++                        OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
++                        OUString::createFromAscii( typeid( ex ).name()) +
++                        OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
++                        ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
++    }
++
++    return bResult;
++}
++
++OUString lcl_ConvertRange( const ::rtl::OUString & rRange, const Reference< chart2::XChartDocument > & xDoc )
++{
++    OUString aResult = rRange;
++    if( !xDoc.is() )
++        return aResult;
++    Reference< chart2::data::XRangeXMLConversion > xConversion(
++        xDoc->getDataProvider(), uno::UNO_QUERY );
++    if( xConversion.is())
++        aResult = xConversion->convertRangeToXML( rRange );
++    return aResult;
++}
++
++typedef ::std::pair< OUString, OUString > tLabelAndValueRange;
++
++sal_Int32 lcl_getSequenceLengthByRole(
++    const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aSeqCnt,
++    const OUString & rRole )
++{
++    Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
++        lcl_getDataSequenceByRole( aSeqCnt, rRole ));
++    if( xLabeledSeq.is())
++    {
++        Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getValues());
++        return xSeq->getData().getLength();
++    }
++    return 0;
++}
++
++bool lcl_hasChartType( const Reference< chart2::XDiagram > & xDiagram, const OUString & rChartType )
++{
++    try
++    {
++        Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
++        Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
++        for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
++        {
++            Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
++            Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
++            for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
++            {
++                if( aChartTypes[nCTIdx]->getChartType().equals( rChartType ))
++                    return true;
++            }
++        }
++    }
++    catch( uno::Exception & )
++    {
++        DBG_ERROR( "Exception while searching for chart type in diagram" );
++    }
++    return false;
++}
++
++OUString lcl_flattenStringSequence( const Sequence< OUString > & rSequence )
++{
++    OUStringBuffer aResult;
++    bool bPrecedeWithSpace = false;
++    for( sal_Int32 nIndex=0; nIndex<rSequence.getLength(); ++nIndex )
++    {
++        if( rSequence[nIndex].getLength())
++        {
++            if( bPrecedeWithSpace )
++                aResult.append( static_cast< sal_Unicode >( ' ' ));
++            aResult.append( rSequence[nIndex] );
++            bPrecedeWithSpace = true;
++        }
++    }
++    return aResult.makeStringAndClear();
++}
++
++OUString lcl_getLabelString( const Reference< chart2::data::XDataSequence > & xLabelSeq )
++{
++    Sequence< OUString > aLabels;
++
++    uno::Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xLabelSeq, uno::UNO_QUERY );
++    if( xTextualDataSequence.is())
++    {
++        aLabels = xTextualDataSequence->getTextualData();
++    }
++    else if( xLabelSeq.is())
++    {
++        Sequence< uno::Any > aAnies( xLabelSeq->getData());
++        aLabels.realloc( aAnies.getLength());
++        for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
++            aAnies[i] >>= aLabels[i];
++    }
++
++    return lcl_flattenStringSequence( aLabels );
++}
++
++void lcl_fillCategoriesIntoStringVector(
++    const Reference< chart2::data::XDataSequence > & xCategories,
++    ::std::vector< OUString > & rOutCategories )
++{
++    OSL_ASSERT( xCategories.is());
++    if( !xCategories.is())
++        return;
++    Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xCategories, uno::UNO_QUERY );
++    if( xTextualDataSequence.is())
++    {
++        rOutCategories.clear();
++        Sequence< OUString > aTextData( xTextualDataSequence->getTextualData());
++        ::std::copy( aTextData.getConstArray(), aTextData.getConstArray() + aTextData.getLength(),
++                     ::std::back_inserter( rOutCategories ));
++    }
++    else
++    {
++        Sequence< uno::Any > aAnies( xCategories->getData());
++        rOutCategories.resize( aAnies.getLength());
++        for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
++            aAnies[i] >>= rOutCategories[i];
++    }
++}
++
++double lcl_getValueFromSequence( const Reference< chart2::data::XDataSequence > & xSeq, sal_Int32 nIndex )
++{
++    double fResult = 0.0;
++    ::rtl::math::setNan( &fResult );
++    Reference< chart2::data::XNumericalDataSequence > xNumSeq( xSeq, uno::UNO_QUERY );
++    if( xNumSeq.is())
++    {
++        Sequence< double > aValues( xNumSeq->getNumericalData());
++        if( nIndex < aValues.getLength() )
++            fResult = aValues[nIndex];
++    }
++    else
++    {
++        Sequence< uno::Any > aAnies( xSeq->getData());
++        if( nIndex < aAnies.getLength() )
++            aAnies[nIndex] >>= fResult;
++    }
++    return fResult;
++}
++
++::std::vector< double > lcl_getAllValuesFromSequence( const Reference< chart2::data::XDataSequence > & xSeq )
++{
++    double fNan = 0.0;
++    ::rtl::math::setNan( &fNan );
++    ::std::vector< double > aResult;
++
++    Reference< chart2::data::XNumericalDataSequence > xNumSeq( xSeq, uno::UNO_QUERY );
++    if( xNumSeq.is())
++    {
++        Sequence< double > aValues( xNumSeq->getNumericalData());
++        ::std::copy( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(),
++                     ::std::back_inserter( aResult ));
++    }
++    else if( xSeq.is())
++    {
++        Sequence< uno::Any > aAnies( xSeq->getData());
++        aResult.resize( aAnies.getLength(), fNan );
++        for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
++            aAnies[i] >>= aResult[i];
++    }
++    return aResult;
++}
++
++bool lcl_SequenceHasUnhiddenData( const uno::Reference< chart2::data::XDataSequence >& xDataSequence )
++{
++    if( !xDataSequence.is() )
++        return false;
++    uno::Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY );
++    if( xProp.is() )
++    {
++        uno::Sequence< sal_Int32 > aHiddenValues;
++        try
++        {
++            xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "HiddenValues" ) ) ) >>= aHiddenValues;
++            if( !aHiddenValues.getLength() )
++                return true;
++        }
++        catch( uno::Exception& e )
++        {
++            (void)e; // avoid warning
++            return true;
++        }
++    }
++    if( xDataSequence->getData().getLength() )
++        return true;
++    return false;
++}
++
++ChartExport::ChartExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, Reference< frame::XModel >& xModel, XmlFilterBase* pFB, DocumentType eDocumentType )
++    : DrawingML( pFS, pFB, eDocumentType )
++    , mnXmlNamespace( nXmlNamespace )
++    , maFraction( 1, 576 )
++    , mxChartModel( xModel )
++    , mbHasSeriesLabels( sal_False )
++    , mbHasCategoryLabels( sal_False )
++    , mbRowSourceColumns( sal_True )
++{
++}
++
++sal_Int32 ChartExport::GetXmlNamespace() const
++{
++    return mnXmlNamespace;
++}
++
++ChartExport& ChartExport::SetXmlNamespace( sal_Int32 nXmlNamespace )
++{
++    mnXmlNamespace = nXmlNamespace;
++    return *this;
++}
++
++sal_Int32 ChartExport::GetChartID( )
++{
++    sal_Int32 nID = GetFB()->GetUniqueId();
++    return nID;
++}
++
++sal_Int32 ChartExport::getChartType( Reference< ::com::sun::star::chart::XDiagram > xDiagram )
++{
++    OUString sChartType = xDiagram->getDiagramType();
++    chart::TypeId eChartTypeId = chart::TYPEID_UNKNOWN;
++    if( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.BarDiagram" )))
++        eChartTypeId = chart::TYPEID_BAR;
++
++    return eChartTypeId;
++}
++
++ChartExport& ChartExport::WriteChartObj( const Reference< XShape >& xShape, sal_Int32 nChartCount )
++{
++    OSL_TRACE("ChartExport::WriteChartObj -- writer chart object");
++/*
++    FSHelperPtr pFS = GetFS();
++
++    pFS->startElementNS( mnXmlNamespace, XML_graphicFrame, FSEND );
++               
++    pFS->startElementNS( mnXmlNamespace, XML_nvGraphicFramePr, FSEND );
++
++    // TODO: get the correct chart name chart id
++    OUString sName = S("Object 1");
++    sal_Int32 nID = GetChartID();
++
++    pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
++                          XML_id,     I32S( nID ),
++                          XML_name,   USS( sName ),
++                          FSEND );
++
++    pFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr,
++                          FSEND );
++
++    pFS->endElementNS( mnXmlNamespace, XML_nvGraphicFramePr );
++
++    // visual chart properties
++    pFS->startElementNS( mnXmlNamespace, XML_xfrm, FSEND );
++    WriteShapeTransformation( xShape );
++    pFS->endElementNS( mnXmlNamespace, XML_xfrm );
++
++    // writer chart object
++    pFS->startElement( FSNS( XML_a, XML_graphic ), FSEND );
++    pFS->startElement( FSNS( XML_a, XML_graphicData ), 
++                       XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/chart",
++                       FSEND );
++    OUString sId;
++    FSHelperPtr pChart = pFS->CreateOutputStream(
++            XclXmlUtils::GetStreamName( "xl/", "charts/chart", nChartCount ),
++            XclXmlUtils::GetStreamName( "../", "charts/chart", nChartCount ),
++            pFS->GetCurrentStream()->getOutputStream(),
++            "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
++            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
++            &sId );
++            
++    pFS->singleElement(  FSNS( XML_c, XML_chart ),
++            FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
++            FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
++            FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
++            FSEND );
++    
++    pFS->PushStream( pChart );
++    pChart->startElement( FSNS( XML_c, XML_chartSpace ),
++            FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
++            FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
++            FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
++            FSEND );
++    // TODO: export chart body        
++    pChart->endElement( FSNS( XML_c, XML_chartSpace ) );
++
++    pFS->PopStream();
++    
++
++    pFS->endElement( FSNS( XML_a, XML_graphic ) ); 
++    pFS->endElement( FSNS( XML_a, XML_graphicData ) ); 
++    pFS->endElementNS( mnXmlNamespace, XML_graphicFrame );
++    */
++
++    return *this;
++}
++
++void ChartExport::InitRangeSegmentationProperties( const Reference< chart2::XChartDocument > & xChartDoc )
++{
++    if( xChartDoc.is())
++        try
++        {
++            Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
++            OSL_ENSURE( xDataProvider.is(), "No DataProvider" );
++            if( xDataProvider.is())
++            {
++                Reference< chart2::data::XDataSource > xDataSource( lcl_pressUsedDataIntoRectangularFormat( xChartDoc, mbHasCategoryLabels ));
++                Sequence< beans::PropertyValue > aArgs( xDataProvider->detectArguments( xDataSource ));
++                ::rtl::OUString sCellRange, sBrokenRange;
++                bool bBrokenRangeAvailable = false;
++                for( sal_Int32 i=0; i<aArgs.getLength(); ++i )
++                {
++                    if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CellRangeRepresentation")))
++                        aArgs[i].Value >>= sCellRange;
++                    else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("BrokenCellRangeForExport")))
++                    {
++                        if( aArgs[i].Value >>= sBrokenRange )
++                            bBrokenRangeAvailable = true;
++                    }
++                    else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DataRowSource")))
++                    {
++                        ::com::sun::star::chart::ChartDataRowSource eRowSource;
++                        aArgs[i].Value >>= eRowSource;
++                        mbRowSourceColumns = ( eRowSource == ::com::sun::star::chart::ChartDataRowSource_COLUMNS );
++                    }
++                    else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("FirstCellAsLabel")))
++                        aArgs[i].Value >>= mbHasSeriesLabels;
++                    else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("SequenceMapping")))
++                        aArgs[i].Value >>= maSequenceMapping;
++                    else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("TableNumberList")))
++                        aArgs[i].Value >>= msTableNumberList;
++                }
++
++                // #i79009# For Writer we have to export a broken version of the
++                // range, where every row number is noe too large, so that older
++                // version can correctly read those files.
++                msChartAddress = (bBrokenRangeAvailable ? sBrokenRange : sCellRange);
++                if( msChartAddress.getLength() > 0 )
++                {
++                    // convert format to XML-conform one
++                    Reference< chart2::data::XRangeXMLConversion > xConversion( xDataProvider, uno::UNO_QUERY );
++                    if( xConversion.is())
++                        msChartAddress = xConversion->convertRangeToXML( msChartAddress );
++                }
++            }
++        }
++        catch( uno::Exception & ex )
++        {
++            (void)ex; // avoid warning for pro build
++            OSL_ENSURE( false, OUStringToOString(
++                            OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
++                            OUString::createFromAscii( typeid( ex ).name()) +
++                            OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
++                            ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
++        }
++}
++
++void ChartExport::ExportContent()
++{
++    Reference< chart2::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
++    OSL_ASSERT( xChartDoc.is() );
++    if( !xChartDoc.is() )
++        return;
++    InitRangeSegmentationProperties( xChartDoc );
++    // TODO: export chart
++    _ExportContent( );
++}
++
++void ChartExport::_ExportContent()
++{
++    Reference< ::com::sun::star::chart::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
++    if( xChartDoc.is())
++    {
++        // determine if data comes from the outside
++        sal_Bool bIncludeTable = sal_True;
++
++        Reference< chart2::XChartDocument > xNewDoc( xChartDoc, uno::UNO_QUERY );
++        if( xNewDoc.is())
++        {
++            // check if we have own data.  If so we must not export the complete
++            // range string, as this is our only indicator for having own or
++            // external data. @todo: fix this in the file format!
++            Reference< lang::XServiceInfo > xDPServiceInfo( xNewDoc->getDataProvider(), uno::UNO_QUERY );
++            if( ! (xDPServiceInfo.is() &&
++                   xDPServiceInfo->getImplementationName().equalsAsciiL(
++                       RTL_CONSTASCII_STRINGPARAM( "com.sun.star.comp.chart.InternalDataProvider" ))))
++            {
++                bIncludeTable = sal_False;
++            }
++        }
++        else
++        {
++            Reference< lang::XServiceInfo > xServ( xChartDoc, uno::UNO_QUERY );
++            if( xServ.is())
++            {
++                if( xServ->supportsService(
++                        OUString::createFromAscii( "com.sun.star.chart.ChartTableAddressSupplier" )))
++                {
++                    Reference< beans::XPropertySet > xProp( xServ, uno::UNO_QUERY );
++                    if( xProp.is())
++                    {
++                        Any aAny;
++                        try
++                        {
++                            OUString sChartAddress;
++                            aAny = xProp->getPropertyValue(
++                                OUString::createFromAscii( "ChartRangeAddress" ));
++                            aAny >>= msChartAddress;
++                            //maExportHelper.SetChartRangeAddress( sChartAddress );
++
++                            OUString sTableNumberList;
++                            aAny = xProp->getPropertyValue(
++                                OUString::createFromAscii( "TableNumberList" ));
++                            aAny >>= msTableNumberList;
++                            //maExportHelper.SetTableNumberList( sTableNumberList );
++
++                            // do not include own table if there are external addresses
++                            bIncludeTable = (sChartAddress.getLength() == 0);
++                        }
++                        catch( beans::UnknownPropertyException & )
++                        {
++                            DBG_ERROR( "Property ChartRangeAddress not supported by ChartDocument" );
++                        }
++                    }
++                }
++            }
++        }
++        exportChartSpace( xChartDoc, bIncludeTable );
++    }
++    else
++    {
++        DBG_ERROR( "Couldn't export chart due to wrong XModel" );
++    }
++}
++
++void ChartExport::exportChartSpace( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc,
++                                      sal_Bool bIncludeTable )
++{
++    FSHelperPtr pFS = GetFS();
++    pFS->startElement( FSNS( XML_c, XML_chartSpace ),
++            FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
++            FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
++            FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
++            FSEND );
++    // TODO: get the correct editing lanauge
++    pFS->singleElement( FSNS( XML_c, XML_lang ),
++            XML_val, "en-US",
++            FSEND );
++
++    if( !bIncludeTable )
++    {
++        // TODO:external data
++    }
++    //XML_chart
++    exportChart(rChartDoc);
++
++    // TODO: printSettings
++    // TODO: style
++    // TODO: text properties
++    // TODO: shape properties
++    pFS->endElement( FSNS( XML_c, XML_chartSpace ) );
++}
++
++void ChartExport::exportChart( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc )
++{
++    Reference< chart2::XChartDocument > xNewDoc( rChartDoc, uno::UNO_QUERY );
++    Reference< ::com::sun::star::chart::XDiagram > xDiagram = rChartDoc->getDiagram();
++    Reference< chart2::XDiagram > xNewDiagram;
++    if( xNewDoc.is())
++        xNewDiagram.set( xNewDoc->getFirstDiagram());
++
++    // get Properties of ChartDocument
++    sal_Bool bHasMainTitle = sal_False;
++    sal_Bool bHasSubTitle = sal_False;
++    sal_Bool bHasLegend = sal_False;
++    Reference< beans::XPropertySet > xDocPropSet( rChartDoc, uno::UNO_QUERY );
++    if( xDocPropSet.is())
++    {
++        try
++        {
++            Any aAny( xDocPropSet->getPropertyValue(
++                OUString( RTL_CONSTASCII_USTRINGPARAM( "HasMainTitle" ))));
++            aAny >>= bHasMainTitle;
++            aAny = xDocPropSet->getPropertyValue(
++                OUString( RTL_CONSTASCII_USTRINGPARAM( "HasSubTitle" )));
++            aAny >>= bHasSubTitle;
++            aAny = xDocPropSet->getPropertyValue(
++                OUString( RTL_CONSTASCII_USTRINGPARAM( "HasLegend" )));
++            aAny >>= bHasLegend;
++        }    
++        catch( beans::UnknownPropertyException & )
++        {
++            DBG_WARNING( "Required property not found in ChartDocument" );
++        }
++    } // if( xDocPropSet.is())
++
++    // chart element
++    // -------------
++    FSHelperPtr pFS = GetFS();
++    pFS->startElement( FSNS( XML_c, XML_chart ),
++            FSEND );
++    
++    // plot area
++    exportPlotArea( xDiagram, xNewDiagram );
++    // TODO: legend
++    // TODO: title
++    // only visible cells should be plotted on the chart
++    pFS->singleElement( FSNS( XML_c, XML_plotVisOnly ),
++            XML_val, "1",
++            FSEND );
++
++    pFS->endElement( FSNS( XML_c, XML_chart ) );
++}
++
++void ChartExport::exportPlotArea( 
++    Reference< ::com::sun::star::chart::XDiagram > xDiagram,
++    Reference< chart2::XDiagram > xNewDiagram )
++{
++    // plot-area element
++    // -----------------
++    FSHelperPtr pFS = GetFS();
++    pFS->startElement( FSNS( XML_c, XML_plotArea ),
++            FSEND );
++    // layout
++    pFS->singleElement( FSNS( XML_c, XML_layout ),
++            FSEND );
++
++    // chart type
++    switch( getChartType( xDiagram ) )
++    {
++        case chart::TYPEID_BAR:
++        {
++            exportBarChart( xDiagram, xNewDiagram );
++            break;
++        }
++        default:
++        {
++            OSL_TRACE("ChartExport::exportPlotArea -- not support chart type");
++            break;
++        }
++    }
++
++    //Category Axis Data
++    
++    //Value Axis
++
++    pFS->endElement( FSNS( XML_c, XML_plotArea ) );
++
++}
++
++void ChartExport::exportBarChart(
++    Reference< ::com::sun::star::chart::XDiagram > xDiagram,
++    Reference< chart2::XDiagram > xNewDiagram )
++{
++    FSHelperPtr pFS = GetFS();
++    pFS->startElement( FSNS( XML_c, XML_barChart ),
++            FSEND );
++    // TODO:barDir, set default value
++    const char* bardir = "col";
++    pFS->singleElement( FSNS( XML_c, XML_barDir ),
++            XML_val, bardir,
++            FSEND );
++    // TODO: grouping, set default value
++    const char* grouping = "standard";
++    pFS->singleElement( FSNS( XML_c, XML_grouping ),
++            XML_val, grouping,
++            FSEND );
++
++    exportSeries( xDiagram, xNewDiagram );
++
++    pFS->endElement( FSNS( XML_c, XML_barChart ) );
++}
++
++void ChartExport::exportSeries(
++    Reference< ::com::sun::star::chart::XDiagram > xDiagram,
++    Reference< chart2::XDiagram > xNewDiagram )
++{
++    // get categories range
++    OUString aCategoriesRange;
++    Reference< chart2::data::XDataSequence > xCatSeq;
++    Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
++    if( mbHasCategoryLabels && xNewDiagram.is())
++    {
++        Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xNewDiagram ) );
++        if( xCategories.is() )
++        {
++            xCatSeq.set( xCategories->getValues() );
++            if( xCatSeq.is())
++            {
++                aCategoriesRange = lcl_ConvertRange( xCatSeq->getSourceRangeRepresentation(), xNewDoc );
++            }
++        }
++    }
++
++    Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( xNewDiagram, uno::UNO_QUERY );
++    if( ! xBCooSysCnt.is())
++        return;
++
++    Sequence< Reference< chart2::XCoordinateSystem > >
++        aCooSysSeq( xBCooSysCnt->getCoordinateSystems());
++    for( sal_Int32 nCSIdx=0; nCSIdx<aCooSysSeq.getLength(); ++nCSIdx )
++    {
++        Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCSIdx], uno::UNO_QUERY );
++        if( ! xCTCnt.is())
++            continue;
++        Sequence< Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes());
++        for( sal_Int32 nCTIdx=0; nCTIdx<aCTSeq.getLength(); ++nCTIdx )
++        {
++            Reference< chart2::XDataSeriesContainer > xDSCnt( aCTSeq[nCTIdx], uno::UNO_QUERY );
++            if( ! xDSCnt.is())
++                continue;
++            // note: if xDSCnt.is() then also aCTSeq[nCTIdx]
++            OUString aChartType( aCTSeq[nCTIdx]->getChartType());
++            OUString aLabelRole = aCTSeq[nCTIdx]->getRoleOfSequenceForSeriesLabel();
++
++            // export dataseries for current chart-type
++            Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries());
++            for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
++            {
++                // export series
++                Reference< chart2::data::XDataSource > xSource( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY );
++                if( xSource.is())
++                {
++                    Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
++                        xSource->getDataSequences());
++                    sal_Int32 nMainSequenceIndex = -1;
++                    sal_Int32 nSeriesLength = 0;
++                    // search for main sequence and create a series element
++                    {
++                        Reference< chart2::data::XDataSequence > xValuesSeq;
++                        Reference< chart2::data::XDataSequence > xLabelSeq;
++                        sal_Int32 nSeqIdx=0;
++                        for( ; nSeqIdx<aSeqCnt.getLength(); ++nSeqIdx )
++                        {
++                            OUString aRole;
++                            Reference< chart2::data::XDataSequence > xTempValueSeq( aSeqCnt[nSeqIdx]->getValues() );
++                            if( nMainSequenceIndex==-1 )
++                            {
++                                Reference< beans::XPropertySet > xSeqProp( xTempValueSeq, uno::UNO_QUERY );
++                                if( xSeqProp.is())
++                                    xSeqProp->getPropertyValue(OUString::createFromAscii("Role")) >>= aRole;
++                                // "main" sequence
++                                if( aRole.equals( aLabelRole ))
++                                {
++                                    xValuesSeq.set( xTempValueSeq );
++                                    xLabelSeq.set( aSeqCnt[nSeqIdx]->getLabel());
++                                    nMainSequenceIndex = nSeqIdx;
++                                }
++                            }
++                            sal_Int32 nSequenceLength = (xTempValueSeq.is()? xTempValueSeq->getData().getLength() : sal_Int32(0));
++                            if( nSeriesLength < nSequenceLength ) 
++                                nSeriesLength = nSequenceLength;
++                        }
++
++                        // have found the main sequence, then xValuesSeq and
++                        // xLabelSeq contain those.  Otherwise both are empty
++                        {
++                            FSHelperPtr pFS = GetFS();
++                            pFS->startElement( FSNS( XML_c, XML_ser ),
++                                FSEND );
++
++                            // TODO: idx and order
++                            pFS->singleElement( FSNS( XML_c, XML_idx ),
++                                XML_val, I32S(nSeriesIdx),
++                                FSEND );
++                            pFS->singleElement( FSNS( XML_c, XML_order ),
++                                XML_val, I32S(nSeriesIdx),
++                                FSEND );
++                            
++                            // export label
++                            if( xLabelSeq.is() )
++                            {
++                                exportSeriesText( xLabelSeq );
++                            }
++
++                            // export categories
++                            if( xCatSeq.is() )
++                            {
++                                exportSeriesCategory( xCatSeq );
++                            }
++
++                            // export values
++                            if( xValuesSeq.is() )
++                            {
++                                exportSeriesValues( xValuesSeq );
++                            }
++
++                            pFS->endElement( FSNS( XML_c, XML_ser ) );
++                        }
++                    }
++                }
++            }    
++        }
++    }    
++}
++
++void ChartExport::exportDataSeq( const Reference< chart2::data::XDataSequence > & xValueSeq, sal_Int32 elementTokenId )
++{
++    FSHelperPtr pFS = GetFS();
++    Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
++    pFS->startElement( FSNS( XML_c, elementTokenId ),
++            FSEND );
++
++    sal_Int32 eTokenId1 = elementTokenId == XML_val ? XML_numRef:XML_strRef;
++    OUString aCellRange = lcl_ConvertRange( xValueSeq->getSourceRangeRepresentation(), xNewDoc );
++    pFS->startElement( FSNS( XML_c, eTokenId1 ),
++            FSEND );
++    
++    pFS->startElement( FSNS( XML_c, XML_f ),
++            FSEND );
++    pFS->writeEscaped( aCellRange );
++    pFS->endElement( FSNS( XML_c, XML_f ) );
++
++    pFS->endElement( FSNS( XML_c, eTokenId1 ) );
++    pFS->endElement( FSNS( XML_c, elementTokenId ) );
++}
++
++void ChartExport::exportSeriesText( const Reference< chart2::data::XDataSequence > & xValueSeq )
++{
++    FSHelperPtr pFS = GetFS();
++    Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
++    pFS->startElement( FSNS( XML_c, XML_tx ),
++            FSEND );
++
++    OUString aCellRange = lcl_ConvertRange( xValueSeq->getSourceRangeRepresentation(), xNewDoc );
++    pFS->startElement( FSNS( XML_c, XML_strRef ),
++            FSEND );
++    
++    pFS->startElement( FSNS( XML_c, XML_f ),
++            FSEND );
++    pFS->writeEscaped( aCellRange );
++    pFS->endElement( FSNS( XML_c, XML_f ) );
++
++    OUString aLabelString = lcl_getLabelString( xValueSeq );
++    pFS->startElement( FSNS( XML_c, XML_strCache ),
++            FSEND );
++    pFS->singleElement( FSNS( XML_c, XML_ptCount ),
++            XML_val, "1",
++            FSEND );
++    pFS->startElement( FSNS( XML_c, XML_pt ),
++            XML_val, "0",
++            FSEND );
++    pFS->startElement( FSNS( XML_c, XML_v ),
++            FSEND );
++    pFS->writeEscaped( aLabelString );
++    pFS->endElement( FSNS( XML_c, XML_v ) );
++    pFS->endElement( FSNS( XML_c, XML_pt ) );
++    pFS->endElement( FSNS( XML_c, XML_strCache ) );
++    pFS->endElement( FSNS( XML_c, XML_strRef ) );
++    pFS->endElement( FSNS( XML_c, XML_tx ) );
++}
++
++void ChartExport::exportSeriesCategory( const Reference< chart2::data::XDataSequence > & xValueSeq )
++{
++    FSHelperPtr pFS = GetFS();
++    Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
++    pFS->startElement( FSNS( XML_c, XML_cat ),
++            FSEND );
++
++    OUString aCellRange = lcl_ConvertRange( xValueSeq->getSourceRangeRepresentation(), xNewDoc );
++    // TODO: need to handle XML_multiLvlStrRef according to aCellRange
++    pFS->startElement( FSNS( XML_c, XML_strRef ),
++            FSEND );
++    
++    pFS->startElement( FSNS( XML_c, XML_f ),
++            FSEND );
++    pFS->writeEscaped( aCellRange );
++    pFS->endElement( FSNS( XML_c, XML_f ) );
++
++    ::std::vector< OUString > aCategories;
++    lcl_fillCategoriesIntoStringVector( xValueSeq, aCategories );
++    sal_Int32 ptCount = aCategories.size();
++    pFS->startElement( FSNS( XML_c, XML_strCache ),
++            FSEND );
++    pFS->singleElement( FSNS( XML_c, XML_ptCount ),
++            XML_val, I32S( ptCount ),
++            FSEND );
++    for( sal_Int32 i = 0; i < ptCount; i++ )
++    {
++        pFS->startElement( FSNS( XML_c, XML_pt ),
++            XML_val, I32S( i ),
++            FSEND );
++        pFS->startElement( FSNS( XML_c, XML_v ),
++            FSEND );
++        pFS->writeEscaped( aCategories[i] );
++        pFS->endElement( FSNS( XML_c, XML_v ) );
++        pFS->endElement( FSNS( XML_c, XML_pt ) );
++    }
++
++    pFS->endElement( FSNS( XML_c, XML_strCache ) );
++    pFS->endElement( FSNS( XML_c, XML_strRef ) );
++    pFS->endElement( FSNS( XML_c, XML_cat ) );
++}
++
++void ChartExport::exportSeriesValues( const Reference< chart2::data::XDataSequence > & xValueSeq )
++{
++    FSHelperPtr pFS = GetFS();
++    Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
++    pFS->startElement( FSNS( XML_c, XML_val ),
++            FSEND );
++
++    OUString aCellRange = lcl_ConvertRange( xValueSeq->getSourceRangeRepresentation(), xNewDoc );
++    // TODO: need to handle XML_multiLvlStrRef according to aCellRange
++    pFS->startElement( FSNS( XML_c, XML_numRef ),
++            FSEND );
++    
++    pFS->startElement( FSNS( XML_c, XML_f ),
++            FSEND );
++    pFS->writeEscaped( aCellRange );
++    pFS->endElement( FSNS( XML_c, XML_f ) );
++
++    ::std::vector< double > aValues;
++    aValues = lcl_getAllValuesFromSequence( xValueSeq );
++    sal_Int32 ptCount = aValues.size();
++    pFS->startElement( FSNS( XML_c, XML_numCache ),
++            FSEND );
++    pFS->startElement( FSNS( XML_c, XML_formatCode ),
++            FSEND );
++    // TODO: what format code?        
++    pFS->writeEscaped( "General" );
++    pFS->endElement( FSNS( XML_c, XML_formatCode ) );
++    pFS->singleElement( FSNS( XML_c, XML_ptCount ),
++            XML_val, I32S( ptCount ),
++            FSEND );
++    for( sal_Int32 i = 0; i < ptCount; i++ )
++    {
++        pFS->startElement( FSNS( XML_c, XML_pt ),
++            XML_val, I32S( i ),
++            FSEND );
++        pFS->startElement( FSNS( XML_c, XML_v ),
++            FSEND );
++        pFS->write( aValues[i] );
++        pFS->endElement( FSNS( XML_c, XML_v ) );
++        pFS->endElement( FSNS( XML_c, XML_pt ) );
++    }
++
++    pFS->endElement( FSNS( XML_c, XML_numCache ) );
++    pFS->endElement( FSNS( XML_c, XML_numRef ) );
++    pFS->endElement( FSNS( XML_c, XML_val ) );
++}
++
++
++}// drawingml
++}// oox
++
+diff --git oox/source/export/drawingml.cxx oox/source/export/drawingml.cxx
+index 77bcdf4..9d4d5fe 100644
+--- oox/source/export/drawingml.cxx
++++ oox/source/export/drawingml.cxx
+@@ -1535,5 +1535,29 @@ sal_Unicode DrawingML::SubstituteBullet( sal_Unicode cBulletId, ::com::sun::star
+     return sNumStr.GetChar( 0 );
+ }
+ 
++sax_fastparser::FSHelperPtr DrawingML::CreateOutputStream (
++    const OUString& sFullStream,
++    const OUString& sRelativeStream,
++    const Reference< XOutputStream >& xParentRelation,
++    const char* sContentType,
++    const char* sRelationshipType,
++    ::rtl::OUString* pRelationshipId )
++{
++    OUString sRelationshipId;
++    if (xParentRelation.is())
++        sRelationshipId = GetFB()->addRelation( xParentRelation, OUString::createFromAscii( sRelationshipType), sRelativeStream );
++    else
++        sRelationshipId = GetFB()->addRelation( OUString::createFromAscii( sRelationshipType ), sRelativeStream );
++
++    if( pRelationshipId )
++        *pRelationshipId = sRelationshipId;
++
++    sax_fastparser::FSHelperPtr p = GetFB()->openFragmentStreamWithSerializer( sFullStream, OUString::createFromAscii( sContentType ) );
++
++    return p;
++}
++
++
++
+ }
+ }
+diff --git oox/source/export/makefile.mk oox/source/export/makefile.mk
+index 08fa7a0..b88133a 100644
+--- oox/source/export/makefile.mk
++++ oox/source/export/makefile.mk
+@@ -16,6 +16,8 @@ ENABLE_EXCEPTIONS=TRUE
+ SLOFILES =	\
+         $(SLO)$/drawingml.obj \
+         $(SLO)$/shapes.obj \
++        $(SLO)$/chartexport.obj \
++        $(SLO)$/SchXMLSeriesHelper.obj \
+         $(SLO)$/vmlexport.obj \
+         $(SLO)$/vmlexport-shape-types.obj
+ 
+diff --git sc/source/filter/xlsx/xcl97rec.hxx sc/source/filter/xlsx/xcl97rec.hxx
+index 01adc19..0ab5c3c 100644
+--- sc/source/filter/xlsx/xcl97rec.hxx
++++ sc/source/filter/xlsx/xcl97rec.hxx
+@@ -316,6 +316,8 @@ public:
+ 
+     virtual	void				Save( XclExpStream& rStrm );
+ 	virtual	void				SaveXml( XclExpXmlStream& rStrm );
++    static void                 WriteFromTo( XclExpXmlStream& rStrm, const XclObjAny& rObj ); 
++    static void                 WriteFromTo( XclExpXmlStream& rStrm, const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape, SCTAB nTab );        
+ 
+ private:
+     com::sun::star::uno::Reference< com::sun::star::drawing::XShape >
+diff --git sc/source/filter/xlsx/xeescher.hxx sc/source/filter/xlsx/xeescher.hxx
+index 3e5493a..3633d77 100644
+--- sc/source/filter/xlsx/xeescher.hxx
++++ sc/source/filter/xlsx/xeescher.hxx
+@@ -34,6 +34,7 @@
+ #include <vcl/graph.hxx>
+ #include "xcl97rec.hxx"
+ #include "xlescher.hxx"
++#include <com/sun/star/chart/XChartDocument.hpp>
+ 
+ namespace com { namespace sun { namespace star {
+     namespace script { struct ScriptEventDescriptor; }
+@@ -191,6 +192,7 @@ class XclExpChartObj : public XclObj, protected XclExpRoot
+ {
+ public:
+     typedef ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > XShapeRef;
++    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart::XChartDocument > XChartDocRef;
+ 
+ public:
+     explicit            XclExpChartObj( const XclExpRoot& rRoot, XShapeRef xShape );
+@@ -198,10 +200,15 @@ public:
+ 
+     /** Writes the OBJ record and the entire chart substream. */
+     virtual void        Save( XclExpStream& rStrm );
++    virtual void        SaveXml( XclExpXmlStream& rStrm );
++    virtual void        WriteChartObj( sax_fastparser::FSHelperPtr pDrawing, XclExpXmlStream& rStrm );
++    void WriteShapeTransformation( sax_fastparser::FSHelperPtr pFS, const XShapeRef& rXShape, sal_Bool bFlipH = false, sal_Bool bFlipV = false, sal_Int32 nRotation = 0 );
+ 
+ private:
+     typedef ScfRef< XclExpChart > XclExpChartRef;
+     XclExpChartRef      mxChart;        /// The chart itself (BOF/EOF substream data).
++    XShapeRef mxShape;
++    XChartDocRef mxChartDoc;
+ };
+ 
+ // ============================================================================
+diff --git sc/source/filter/xlsx/xlsx-xcl97rec.cxx sc/source/filter/xlsx/xlsx-xcl97rec.cxx
+index 2c73dff..e463be9 100644
+--- sc/source/filter/xlsx/xlsx-xcl97rec.cxx
++++ sc/source/filter/xlsx/xlsx-xcl97rec.cxx
+@@ -1065,19 +1065,17 @@ void XclObjAny::Save( XclExpStream& rStrm )
+     XclObj::Save( rStrm );
+ }
+ 
+-
+-static void
+-WriteFromTo( XclExpXmlStream& rStrm, const XclObjAny& rObj )
++void XclObjAny::WriteFromTo( XclExpXmlStream& rStrm, const Reference< XShape >& rShape, SCTAB nTab )
+ {
+     sax_fastparser::FSHelperPtr pDrawing = rStrm.GetCurrentStream();
+ 
+-    awt::Point  aTopLeft    = rObj.GetShape()->getPosition();
+-    awt::Size   aSize       = rObj.GetShape()->getSize();
++    awt::Point  aTopLeft    = rShape->getPosition();
++    awt::Size   aSize       = rShape->getSize();
+     Rectangle   aLocation( aTopLeft.X, aTopLeft.Y, aTopLeft.X + aSize.Width, aTopLeft.Y + aSize.Height );
+-    ScRange     aRange      = rStrm.GetRoot().GetDoc().GetRange( rObj.GetTab(), aLocation );
++    ScRange     aRange      = rStrm.GetRoot().GetDoc().GetRange( nTab, aLocation );
+     Rectangle   aRangeRect  = rStrm.GetRoot().GetDoc().GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(),
+             aRange.aEnd.Col()-1, aRange.aEnd.Row()-1,
+-            rObj.GetTab() );
++            nTab );
+ 
+ 
+     pDrawing->startElement( FSNS( XML_xdr, XML_from ),
+@@ -1101,6 +1099,11 @@ WriteFromTo( XclExpXmlStream& rStrm, const XclObjAny& rObj )
+     pDrawing->endElement( FSNS( XML_xdr, XML_to ) );
+ }
+ 
++void XclObjAny::WriteFromTo( XclExpXmlStream& rStrm, const XclObjAny& rObj )
++{
++    WriteFromTo( rStrm, rObj.GetShape(), rObj.GetTab() );
++}
++
+ static void
+ WritePicPr( sax_fastparser::FSHelperPtr pDrawing, sal_Int32 nId, Reference< XPropertySet > xPropSet )
+ {
+diff --git sc/source/filter/xlsx/xlsx-xeescher.cxx sc/source/filter/xlsx/xlsx-xeescher.cxx
+index 918e491..f205ec2 100644
+--- sc/source/filter/xlsx/xlsx-xeescher.cxx
++++ sc/source/filter/xlsx/xlsx-xeescher.cxx
+@@ -47,6 +47,9 @@
+ #include <com/sun/star/form/binding/XListEntrySink.hpp>
+ #include <com/sun/star/form/binding/XListEntrySource.hpp>
+ #include <com/sun/star/script/ScriptEventDescriptor.hpp>
++#include <com/sun/star/chart2/XChartDocument.hpp>
++#include <com/sun/star/awt/Point.hpp>
++#include <com/sun/star/awt/Size.hpp>
+ 
+ #include <rtl/ustrbuf.h>
+ #include <vcl/bmpacc.hxx>
+@@ -72,6 +75,8 @@
+ 
+ #include <oox/core/tokens.hxx>
+ #include <oox/export/drawingml.hxx>
++#include <oox/export/chartexport.hxx>
++#include <oox/export/utils.hxx>
+ 
+ using ::rtl::OString;
+ using ::rtl::OUString;
+@@ -92,7 +97,9 @@ using ::com::sun::star::form::binding::XListEntrySource;
+ using ::com::sun::star::script::ScriptEventDescriptor;
+ using ::com::sun::star::table::CellAddress;
+ using ::com::sun::star::table::CellRangeAddress;
++using ::com::sun::star::chart2::XChartDocument;
+ using ::oox::drawingml::DrawingML;
++using ::oox::drawingml::ChartExport;
+ 
+ // ============================================================================
+ 
+@@ -784,7 +791,7 @@ void XclExpTbxControlObj::WriteSbs( XclExpStream& rStrm )
+ 
+ XclExpChartObj::XclExpChartObj( const XclExpRoot& rRoot, Reference< XShape > xShape ) :
+     XclObj( rRoot, EXC_OBJTYPE_CHART ),
+-    XclExpRoot( rRoot )
++    XclExpRoot( rRoot ), mxShape( xShape )
+ {
+     // create the MSODRAWING record contents for the chart object
+     XclEscherEx& rEscherEx = *pMsodrawing->GetEscherEx();
+@@ -820,6 +827,7 @@ XclExpChartObj::XclExpChartObj( const XclExpRoot& rRoot, Reference< XShape > xSh
+     ScfPropertySet aShapeProp( xShape );
+     Reference< XModel > xModel;
+     aShapeProp.GetProperty( xModel, CREATE_OUSTRING( "Model" ) );
++    mxChartDoc.set( xModel,UNO_QUERY );
+     ::com::sun::star::awt::Rectangle aBoundRect;
+     aShapeProp.GetProperty( aBoundRect, CREATE_OUSTRING( "BoundRect" ) );
+     Size aSize( aBoundRect.Width, aBoundRect.Height );
+@@ -838,6 +846,117 @@ void XclExpChartObj::Save( XclExpStream& rStrm )
+     mxChart->Save( rStrm );
+ }
+ 
++void XclExpChartObj::SaveXml( XclExpXmlStream& rStrm )
++{
++    OSL_TRACE("XclExpChartObj::SaveXml -- Entry point to export chart");
++    sax_fastparser::FSHelperPtr pDrawing = rStrm.GetCurrentStream();
++
++    // FIXME: two cell? it seems the two cell anchor is incorrect.
++    pDrawing->startElement( FSNS( XML_xdr, XML_twoCellAnchor ), // OOXTODO: oneCellAnchor, absoluteAnchor
++            XML_editAs, "oneCell",
++            FSEND );
++    Reference< XPropertySet > xPropSet( mxShape, UNO_QUERY );
++    if (xPropSet.is())
++    {
++        XclObjAny::WriteFromTo( rStrm, mxShape, GetTab() );
++        //ChartExport aChartExport( XML_xdr, pDrawing, mxChartDoc, &rStrm, DrawingML::DOCUMENT_XLSX );
++        // TODO: get the correcto chart number
++        WriteChartObj( pDrawing, rStrm );
++    }
++
++    pDrawing->singleElement( FSNS( XML_xdr, XML_clientData),
++            // OOXTODO: XML_fLocksWithSheet
++            // OOXTODO: XML_fPrintsWithSheet
++            FSEND );
++    pDrawing->endElement( FSNS( XML_xdr, XML_twoCellAnchor ) );
++}
++
++void XclExpChartObj::WriteChartObj( sax_fastparser::FSHelperPtr pDrawing, XclExpXmlStream& rStrm )
++{
++    pDrawing->startElement(  FSNS( XML_xdr, XML_graphicFrame ), FSEND );
++               
++    pDrawing->startElement(  FSNS( XML_xdr, XML_nvGraphicFramePr ), FSEND );
++
++    // TODO: get the correct chart name chart id
++    OUString sName = CREATE_OUSTRING("Object 1");
++    sal_Int32 nID = rStrm.GetUniqueId();
++
++    pDrawing->singleElement( FSNS( XML_xdr, XML_cNvPr ),
++                          XML_id,     I32S( nID ),
++                          XML_name,   USS( sName ),
++                          FSEND );
++
++    pDrawing->singleElement( FSNS( XML_xdr, XML_cNvGraphicFramePr ),
++                          FSEND );
++
++    pDrawing->endElement( FSNS( XML_xdr, XML_nvGraphicFramePr ) );
++
++    // visual chart properties
++    //pDrawing->startElement( FSNS( XML_xdr, XML_xfrm ), FSEND );
++    WriteShapeTransformation( pDrawing, mxShape );
++    //pDrawing->endElement( FSNS( XML_xdr, XML_xfrm ) );
++
++    // writer chart object
++    pDrawing->startElement( FSNS( XML_a, XML_graphic ), FSEND );
++    pDrawing->startElement( FSNS( XML_a, XML_graphicData ), 
++                       XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/chart",
++                       FSEND );
++    OUString sId;
++    // TODO: 
++    sal_Int32 nChartCount = 1;
++    sax_fastparser::FSHelperPtr pChart = rStrm.CreateOutputStream(
++            XclXmlUtils::GetStreamName( "xl/", "charts/chart", nChartCount ),
++            XclXmlUtils::GetStreamName( "../", "charts/chart", nChartCount ),
++            rStrm.GetCurrentStream()->getOutputStream(),
++            "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
++            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
++            &sId );
++            
++    pDrawing->singleElement(  FSNS( XML_c, XML_chart ),
++            FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
++            FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
++            FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
++            FSEND );
++    
++    rStrm.PushStream( pChart );
++    Reference< XModel > xModel( mxChartDoc, UNO_QUERY );
++    ChartExport aChartExport( XML_xdr, pChart, xModel, &rStrm, DrawingML::DOCUMENT_XLSX );
++    aChartExport.ExportContent();
++    /*
++    pChart->startElement( FSNS( XML_c, XML_chartSpace ),
++            FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
++            FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
++            FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
++            FSEND );
++    // TODO: export chart body        
++    pChart->endElement( FSNS( XML_c, XML_chartSpace ) );
++    */
++
++    rStrm.PopStream();
++    
++    pDrawing->endElement( FSNS( XML_a, XML_graphicData ) ); 
++    pDrawing->endElement( FSNS( XML_a, XML_graphic ) ); 
++    pDrawing->endElement( FSNS( XML_xdr, XML_graphicFrame ) );
++
++}
++
++void XclExpChartObj::WriteShapeTransformation( sax_fastparser::FSHelperPtr pFS, const XShapeRef& rXShape, sal_Bool bFlipH, sal_Bool bFlipV, sal_Int32 nRotation )
++{
++    ::com::sun::star::awt::Point aPos = rXShape->getPosition();
++    ::com::sun::star::awt::Size aSize = rXShape->getSize();
++
++    pFS->startElementNS( XML_xdr, XML_xfrm,
++                          XML_flipH, bFlipH ? "1" : NULL,
++                          XML_flipV, bFlipV ? "1" : NULL,
++                          XML_rot, nRotation ? I32S( nRotation ) : NULL,
++                          FSEND );
++
++    pFS->singleElementNS( XML_a, XML_off, XML_x, IS( MM100toEMU( aPos.X ) ), XML_y, IS( MM100toEMU( aPos.Y ) ), FSEND );
++    pFS->singleElementNS( XML_a, XML_ext, XML_cx, IS( MM100toEMU( aSize.Width ) ), XML_cy, IS( MM100toEMU( aSize.Height ) ), FSEND );
++
++    pFS->endElementNS( XML_xdr, XML_xfrm );
++}
++
+ // ============================================================================
+ 
+ XclExpNote::XclExpNote( const XclExpRoot& rRoot, const ScAddress& rScPos,


More information about the ooo-build-commit mailing list