[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