diff options
author | Katarina Machalkova <kmachalkova@suse.cz> | 2010-10-21 17:53:16 +0200 |
---|---|---|
committer | Katarina Machalkova <kmachalkova@suse.cz> | 2010-10-27 14:04:16 +0200 |
commit | a41687b62b0a6f2b79e44311ddf74c52e844ee36 (patch) | |
tree | 4a7e77a1fcd4d110ce440374a20af75d4d8e1305 /oox | |
parent | 9e02fc64430ccdb311a08dd966cce61884a8b34c (diff) |
New files from xlsx-shared-oox-chart-export-part1.diff
Diffstat (limited to 'oox')
-rw-r--r-- | oox/inc/oox/export/chartexport.hxx | 216 | ||||
-rw-r--r-- | oox/source/export/ColorPropertySet.cxx | 233 | ||||
-rw-r--r-- | oox/source/export/ColorPropertySet.hxx | 129 | ||||
-rw-r--r-- | oox/source/export/SchXMLSeriesHelper.cxx | 301 | ||||
-rw-r--r-- | oox/source/export/SchXMLSeriesHelper.hxx | 83 | ||||
-rw-r--r-- | oox/source/export/chartexport.cxx | 2848 |
6 files changed, 3810 insertions, 0 deletions
diff --git a/oox/inc/oox/export/chartexport.hxx b/oox/inc/oox/export/chartexport.hxx new file mode 100644 index 000000000000..8d15e99b641e --- /dev/null +++ b/oox/inc/oox/export/chartexport.hxx @@ -0,0 +1,216 @@ +/************************************************************************* + * + * 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> +#include <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; + class XChartType; + namespace data + { + class XDataProvider; + class XDataSequence; + } + } + namespace drawing { + class XShape; + class XShapes; + } + namespace task { + class XStatusIndicator; + } + namespace frame { + class XModel; + } +}}} + +namespace oox { namespace drawingml { + +const sal_Int32 AXIS_PRIMARY_X = 1; +const sal_Int32 AXIS_PRIMARY_Y = 2; +const sal_Int32 AXIS_PRIMARY_Z = 3; +const sal_Int32 AXIS_SECONDARY_X = 4; +const sal_Int32 AXIS_SECONDARY_Y = 5; + +struct AxisIdPair{ + sal_Int32 nAxisType; + sal_Int32 nAxisId; + sal_Int32 nCrossAx; + + AxisIdPair( sal_Int32 nType, sal_Int32 nId, sal_Int32 nAx ): nAxisType( nType ),nAxisId( nId ),nCrossAx( nAx ) {} +}; + +class OOX_DLLPUBLIC ChartExport : public DrawingML { + +public: + // first: data sequence for label, second: data sequence for values. + typedef ::std::vector< AxisIdPair > AxisVector; + +private: + sal_Int32 mnXmlNamespace; + Fraction maFraction; + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > mxChartModel; + com::sun::star::uno::Reference< com::sun::star::chart::XDiagram > mxDiagram; + com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > mxNewDiagram; + + 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; + ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence > mxCategoriesValues; + + AxisVector maAxes; + sal_Bool mbHasXAxis; + sal_Bool mbHasYAxis; + sal_Bool mbHasZAxis; + sal_Bool mbHasSecondaryXAxis; + sal_Bool mbHasSecondaryYAxis; + sal_Bool mbIs3DChart; + + +private: + sal_Int32 getChartType( + ); + + rtl::OUString parseFormula( const rtl::OUString& rRange ); + void InitPlotArea(); + + 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 exportLegend( com::sun::star::uno::Reference< + com::sun::star::chart::XChartDocument > rChartDoc ); + void exportTitle( com::sun::star::uno::Reference< + ::com::sun::star::drawing::XShape > xShape ); + void exportPlotArea( ); + + void exportAreaChart( com::sun::star::uno::Reference< com::sun::star::chart2::XChartType > xChartType ); + void exportBarChart( com::sun::star::uno::Reference< com::sun::star::chart2::XChartType > xChartType ); + void exportBubbleChart( com::sun::star::uno::Reference< com::sun::star::chart2::XChartType > xChartType ); + void exportDoughnutChart( com::sun::star::uno::Reference< com::sun::star::chart2::XChartType > xChartType ); + void exportLineChart( com::sun::star::uno::Reference< com::sun::star::chart2::XChartType > xChartType ); + void exportOfPieChart( com::sun::star::uno::Reference< com::sun::star::chart2::XChartType > xChartType ); + void exportPieChart( com::sun::star::uno::Reference< com::sun::star::chart2::XChartType > xChartType ); + void exportRadarChart( com::sun::star::uno::Reference< com::sun::star::chart2::XChartType > xChartType ); + void exportScatterChart( com::sun::star::uno::Reference< com::sun::star::chart2::XChartType > xChartType ); + void exportStockChart( com::sun::star::uno::Reference< com::sun::star::chart2::XChartType > xChartType ); + void exportSuffaceChart( com::sun::star::uno::Reference< com::sun::star::chart2::XChartType > xChartType ); + + void exportSeries( com::sun::star::uno::Reference< com::sun::star::chart2::XChartType > xChartType, sal_Int32& nAttachedAxis ); + void exportCandleStickSeries( + const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< + ::com::sun::star::chart2::XDataSeries > > & aSeriesSeq, + sal_Bool bJapaneseCandleSticks, sal_Int32& nAttachedAxis ); + 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, sal_Int32 nValueType = XML_val ); + void exportShapeProps( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPropSet ); + void exportDataPoints( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xSeriesProperties, + sal_Int32 nSeriesLength ); + void exportGrouping( sal_Bool isBar = sal_False ); + void exportMarker(); + void exportSmooth(); + void exportFirstSliceAng(); + + void exportAxes( ); + void exportXAxis( AxisIdPair aAxisIdPair ); + void exportYAxis( AxisIdPair aAxisIdPair ); + void exportAxis( AxisIdPair aAxisIdPair ); + void _exportAxis( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xAxisProp, + const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xAxisTitle, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xMajorGrid, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xMinorGrid, + sal_Int32 nAxisType, + const char* sAxisPos, + AxisIdPair aAxisIdPair ); + void exportAxesId( sal_Int32 nAttachedAxis ); + void exportView3D(); + sal_Bool isDeep3dChart(); + +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 a/oox/source/export/ColorPropertySet.cxx b/oox/source/export/ColorPropertySet.cxx new file mode 100644 index 000000000000..235e09ccf227 --- /dev/null +++ b/oox/source/export/ColorPropertySet.cxx @@ -0,0 +1,233 @@ +/************************************************************************* + * + * 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: ColorPropertySet.cxx,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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove + +#include "ColorPropertySet.hxx" + +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/drawing/FillStyle.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::beans; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::rtl::OUString; +using ::com::sun::star::uno::RuntimeException; + +// ================================================================================ + +namespace +{ +class lcl_ColorPropertySetInfo : public ::cppu::WeakImplHelper1< + XPropertySetInfo > +{ +public: + lcl_ColorPropertySetInfo( bool bFillColor ); + +protected: + // ____ XPropertySetInfo ____ + virtual Sequence< Property > SAL_CALL getProperties() throw (RuntimeException); + virtual Property SAL_CALL getPropertyByName( const OUString& aName ) throw (UnknownPropertyException, RuntimeException); + virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) throw (RuntimeException); + +private: + bool m_bIsFillColor; + OUString m_aColorPropName; + Property m_aColorProp; +}; + +lcl_ColorPropertySetInfo::lcl_ColorPropertySetInfo( bool bFillColor ) : + m_bIsFillColor( bFillColor ), + // note: length of FillColor and LineColor is 9 + m_aColorPropName( (bFillColor ? "FillColor" : "LineColor"), 9, RTL_TEXTENCODING_ASCII_US ), + m_aColorProp( m_aColorPropName, -1, + ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)), 0) +{} + +Sequence< Property > SAL_CALL lcl_ColorPropertySetInfo::getProperties() + throw (RuntimeException) +{ + + return Sequence< Property >( & m_aColorProp, 1 ); +} + +Property SAL_CALL lcl_ColorPropertySetInfo::getPropertyByName( const OUString& aName ) + throw (UnknownPropertyException, RuntimeException) +{ + if( aName.equals( m_aColorPropName )) + return m_aColorProp; + throw UnknownPropertyException( m_aColorPropName, static_cast< uno::XWeak * >( this )); +} + +sal_Bool SAL_CALL lcl_ColorPropertySetInfo::hasPropertyByName( const OUString& Name ) + throw (RuntimeException) +{ + return Name.equals( m_aColorPropName ); +} + +} // anonymous namespace + +// ================================================================================ + +namespace oox +{ +namespace drawingml +{ + +ColorPropertySet::ColorPropertySet( sal_Int32 nColor, bool bFillColor /* = true */ ) : + // note: length of FillColor and LineColor is 9 + m_aColorPropName( (bFillColor ? "FillColor" : "LineColor"), 9, RTL_TEXTENCODING_ASCII_US ), + m_nColor( nColor ), + m_bIsFillColor( bFillColor ), + m_nDefaultColor( 0x0099ccff ) // blue 8 +{} + +ColorPropertySet::~ColorPropertySet() +{} + +void ColorPropertySet::setColor( sal_Int32 nColor ) +{ + m_nColor = nColor; +} + +sal_Int32 ColorPropertySet::getColor() +{ + return m_nColor; +} + +// ____ XPropertySet ____ + +Reference< XPropertySetInfo > SAL_CALL ColorPropertySet::getPropertySetInfo() + throw (uno::RuntimeException) +{ + if( ! m_xInfo.is()) + m_xInfo.set( new lcl_ColorPropertySetInfo( m_bIsFillColor )); + + return m_xInfo; +} + +void SAL_CALL ColorPropertySet::setPropertyValue( const OUString& /* aPropertyName */, const uno::Any& aValue ) + throw (UnknownPropertyException, + PropertyVetoException, + lang::IllegalArgumentException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + aValue >>= m_nColor; +} + +uno::Any SAL_CALL ColorPropertySet::getPropertyValue( const OUString& aPropertyName ) + throw (UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + if( aPropertyName.equalsAscii("FillStyle") && m_bIsFillColor ) + { + ::com::sun::star::drawing::FillStyle aFillStyle = ::com::sun::star::drawing::FillStyle_SOLID; + return uno::makeAny(aFillStyle); + } + return uno::makeAny( m_nColor ); +} + +void SAL_CALL ColorPropertySet::addPropertyChangeListener( const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* xListener */ ) + throw (UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + OSL_ENSURE( false, "Not Implemented" ); + return; +} + +void SAL_CALL ColorPropertySet::removePropertyChangeListener( const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* aListener */ ) + throw (UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + OSL_ENSURE( false, "Not Implemented" ); + return; +} + +void SAL_CALL ColorPropertySet::addVetoableChangeListener( const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ ) + throw (UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + OSL_ENSURE( false, "Not Implemented" ); + return; +} + +void SAL_CALL ColorPropertySet::removeVetoableChangeListener( const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ ) + throw (UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + OSL_ENSURE( false, "Not Implemented" ); + return; +} + +// ____ XPropertyState ____ + +PropertyState SAL_CALL ColorPropertySet::getPropertyState( const OUString& /* PropertyName */ ) + throw (UnknownPropertyException, + uno::RuntimeException) +{ + return PropertyState_DIRECT_VALUE; +} + +Sequence< PropertyState > SAL_CALL ColorPropertySet::getPropertyStates( const Sequence< OUString >& /* aPropertyName */ ) + throw (UnknownPropertyException, + uno::RuntimeException) +{ + PropertyState aState = PropertyState_DIRECT_VALUE; + return Sequence< PropertyState >( & aState, 1 ); +} + +void SAL_CALL ColorPropertySet::setPropertyToDefault( const OUString& PropertyName ) + throw (UnknownPropertyException, + uno::RuntimeException) +{ + if( PropertyName.equals( m_aColorPropName )) + m_nColor = m_nDefaultColor; +} + +uno::Any SAL_CALL ColorPropertySet::getPropertyDefault( const OUString& aPropertyName ) + throw (UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + if( aPropertyName.equals( m_aColorPropName )) + return uno::makeAny( m_nDefaultColor ); + return uno::Any(); +} + +} // namespace chart +} // namespace xmloff diff --git a/oox/source/export/ColorPropertySet.hxx b/oox/source/export/ColorPropertySet.hxx new file mode 100644 index 000000000000..f62f77a49dee --- /dev/null +++ b/oox/source/export/ColorPropertySet.hxx @@ -0,0 +1,129 @@ +/************************************************************************* + * + * 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: ColorPropertySet.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_COLORPROPERTYSET_HXX +#define XMLOFF_COLORPROPERTYSET_HXX + +#include <cppuhelper/implbase2.hxx> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> + +namespace oox +{ +namespace drawingml +{ + +class ColorPropertySet : public ::cppu::WeakImplHelper2< + ::com::sun::star::beans::XPropertySet, + ::com::sun::star::beans::XPropertyState > +{ +public: + // if bFillColor == false, the color is a LineColor + explicit ColorPropertySet( sal_Int32 nColor, bool bFillColor = true ); + virtual ~ColorPropertySet(); + + void setColor( sal_Int32 nColor ); + sal_Int32 getColor(); + +protected: + // ____ XPropertySet ____ + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyValue( + const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Any& aValue ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::beans::PropertyVetoException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( + const ::rtl::OUString& PropertyName ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( + const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePropertyChangeListener( + const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addVetoableChangeListener( + const ::rtl::OUString& PropertyName, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeVetoableChangeListener( + const ::rtl::OUString& PropertyName, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + // ____ XPropertyState ____ + virtual ::com::sun::star::beans::PropertyState SAL_CALL getPropertyState( + const ::rtl::OUString& PropertyName ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > SAL_CALL getPropertyStates( + const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyName ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyToDefault( + const ::rtl::OUString& PropertyName ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyDefault( + const ::rtl::OUString& aPropertyName ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + +private: + ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySetInfo > m_xInfo; + ::rtl::OUString m_aColorPropName; + sal_Int32 m_nColor; + bool m_bIsFillColor; + sal_Int32 m_nDefaultColor; +}; + +} // namespace chart +} // namespace xmloff + +// XMLOFF_COLORPROPERTYSET_HXX +#endif diff --git a/oox/source/export/SchXMLSeriesHelper.cxx b/oox/source/export/SchXMLSeriesHelper.cxx new file mode 100644 index 000000000000..c755a5338892 --- /dev/null +++ b/oox/source/export/SchXMLSeriesHelper.cxx @@ -0,0 +1,301 @@ +/************************************************************************* + * + * 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 a/oox/source/export/SchXMLSeriesHelper.hxx b/oox/source/export/SchXMLSeriesHelper.hxx new file mode 100644 index 000000000000..7e5851ed2994 --- /dev/null +++ b/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 a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx new file mode 100644 index 000000000000..1d07ebad64ed --- /dev/null +++ b/oox/source/export/chartexport.cxx @@ -0,0 +1,2848 @@ +/************************************************************************* + * + * 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/chart/ChartSymbolType.hpp> +#include <com/sun/star/chart/ChartAxisMarks.hpp> +#include <com/sun/star/chart/ChartAxisLabelPosition.hpp> +#include <com/sun/star/chart/ChartAxisPosition.hpp> +#include <com/sun/star/chart/ChartSolidType.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/DataPointGeometry3D.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 <com/sun/star/drawing/FillStyle.hpp> +#include <com/sun/star/drawing/BitmapMode.hpp> + +#include <com/sun/star/table/CellAddress.hpp> +#include <com/sun/star/sheet/XFormulaParser.hpp> +#include <com/sun/star/sheet/XFormulaTokens.hpp> +#include <com/sun/star/sheet/FormulaToken.hpp> +#include <com/sun/star/sheet/AddressConvention.hpp> + +#include <com/sun/star/text/WritingMode.hpp> +#include <com/sun/star/container/XNamed.hpp> + +#include <comphelper/processfactory.hxx> +#include "SchXMLSeriesHelper.hxx" +#include "ColorPropertySet.hxx" +#include "oox/xls/formulaparser.hxx" +#include "oox/xls/workbookhelper.hxx" +#include "oox/xls/addressconverter.hxx" +#include <set> +#include <time.h> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing; +using namespace ::oox::core; +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::container::XNamed; +using ::com::sun::star::io::XOutputStream; +using ::com::sun::star::table::CellAddress; +using ::com::sun::star::sheet::XFormulaParser; +using ::com::sun::star::sheet::XFormulaTokens; +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 ); + OSL_TRACE("lcl_ConvertRange, the originla formula is %s, the new formula is %s ", OUStringToOString( rRange, RTL_TEXTENCODING_UTF8 ).getStr(), OUStringToOString( aResult, RTL_TEXTENCODING_UTF8 ).getStr()); + 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; +} + + +sal_Int32 lcl_getChartType( const OUString& sChartType ) +{ + chart::TypeId eChartTypeId = chart::TYPEID_UNKNOWN; + if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.BarDiagram" ))) + || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.ColumnChartType") ) ) ) + eChartTypeId = chart::TYPEID_BAR; + else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.AreaDiagram" ))) + || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.AreaChartType") ) ) ) + eChartTypeId = chart::TYPEID_AREA; + else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.LineDiagram" ))) + || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.LineChartType") ) ) ) + eChartTypeId = chart::TYPEID_LINE; + else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.PieDiagram" ))) + || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.PieChartType") ) ) ) + eChartTypeId = chart::TYPEID_PIE; + else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.DonutDiagram" ))) + || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.DonutChartType") ) ) ) + eChartTypeId = chart::TYPEID_DOUGHNUT; + else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.XYDiagram" ))) + || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.ScatterChartType") ) ) ) + eChartTypeId = chart::TYPEID_SCATTER; + else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.NetDiagram" ))) + || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.NetChartType") ) ) ) + eChartTypeId = chart::TYPEID_RADARLINE; + else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.FilledNetDiagram" ))) + || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.FilledNetChartType") ) ) ) + eChartTypeId = chart::TYPEID_RADARAREA; + else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.StockDiagram" ))) + || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.CandleStickChartType") ) ) ) + eChartTypeId = chart::TYPEID_STOCK; + else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.BubbleDiagram" ))) + || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.BubbleChartType") ) ) ) + eChartTypeId = chart::TYPEID_BUBBLE; + + return eChartTypeId; +} + +sal_Int32 lcl_generateRandomValue() +{ + static sal_Int32 MAX_NUMBER = 100000000; + //srand( unsigned( time( NULL ) )); + return sal_Int32( rand() % MAX_NUMBER ); +} + +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 ) + , mbHasXAxis( sal_False ) + , mbHasYAxis( sal_False ) + , mbHasZAxis( sal_False ) + , mbHasSecondaryXAxis( sal_False ) + , mbHasSecondaryYAxis( sal_False ) + , mbIs3DChart( sal_False ) +{ +} + +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( ) +{ + OUString sChartType = mxDiagram->getDiagramType(); + return lcl_getChartType( sChartType ); +} + +OUString ChartExport::parseFormula( const OUString& rRange ) +{ + OUString aResult; + Reference< XFormulaParser > xParser; + uno::Reference< lang::XMultiServiceFactory > xSF( GetFB()->getModelFactory(), uno::UNO_QUERY ); + if( xSF.is() ) + { + try + { + xParser.set( xSF->createInstance( OUString::createFromAscii( "com.sun.star.sheet.FormulaParser" ) ), UNO_QUERY ); + } + catch( Exception& ) + { + } + } + if( xParser.is() ) + { + OSL_TRACE("ChartExport::parseFormula, parser is valid"); + Reference< XPropertySet > xParserProps( xParser, uno::UNO_QUERY ); + if( xParserProps.is() ) + { + xParserProps->setPropertyValue( OUString::createFromAscii("FormulaConvention"), uno::makeAny(::com::sun::star::sheet::AddressConvention::OOO) ); + } + uno::Sequence<sheet::FormulaToken> aTokens = xParser->parseFormula( rRange, CellAddress( 0, 0, 0 ) ); + if( xParserProps.is() ) + { + xParserProps->setPropertyValue( OUString::createFromAscii("FormulaConvention"), uno::makeAny(::com::sun::star::sheet::AddressConvention::XL_OOX) ); + } + aResult = xParser->printFormula( aTokens, CellAddress( 0, 0, 0 ) ); + } + else + { + OSL_TRACE("ChartExport::parseFormula, parser is invalid"); + //FIXME: currently just using simple converter, e.g $Sheet1.$A$1:$C$1 -> Sheet1!$A$1:$C$1 + String aRange( rRange ); + if( aRange.SearchAscii("$") == 0 ) + aRange = aRange.Copy(1); + aRange.SearchAndReplaceAllAscii(".$", String::CreateFromAscii("!$") ); + aResult = aRange; + } + + OSL_TRACE("ChartExport::parseFormula, the originla formula is %s, the new formula is %s ", OUStringToOString( rRange, RTL_TEXTENCODING_UTF8 ).getStr(), OUStringToOString( aResult, RTL_TEXTENCODING_UTF8 ).getStr()); + return aResult; +} + +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"); + Reference< XNamed > xNamed( xShape, UNO_QUERY ); + if (xNamed.is()) + sName = xNamed->getName(); + + sal_Int32 nID = GetChartID(); + + pFS->singleElementNS( mnXmlNamespace, XML_cNvPr, + XML_id, I32S( nID ), + XML_name, USS( sName ), + FSEND ); + + pFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr, + FSEND ); + + if( GetDocumentType() == DOCUMENT_PPTX ) + pFS->singleElementNS( mnXmlNamespace, XML_nvPr, + FSEND ); + pFS->endElementNS( mnXmlNamespace, XML_nvGraphicFramePr ); + + // visual chart properties + WriteShapeTransformation( xShape, mnXmlNamespace ); + + // 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; + const char* sFullPath = NULL; + const char* sRelativePath = NULL; + switch( GetDocumentType() ) + { + case DOCUMENT_DOCX: + { + sFullPath = "word/charts/chart"; + sRelativePath = "charts/chart"; + break; + } + case DOCUMENT_PPTX: + { + sFullPath = "ppt/charts/chart"; + sRelativePath = "../charts/chart"; + break; + } + case DOCUMENT_XLSX: + { + sFullPath = "xl/charts/chart"; + sRelativePath = "../charts/chart"; + break; + } + default: + { + sFullPath = "charts/chart"; + sRelativePath = "charts/chart"; + break; + } + } + OUString sFullStream = OUStringBuffer() + .appendAscii(sFullPath) + .append(nChartCount) + .appendAscii( ".xml" ) + .makeStringAndClear(); + OUString sRelativeStream = OUStringBuffer() + .appendAscii(sRelativePath) + .append(nChartCount) + .appendAscii( ".xml" ) + .makeStringAndClear(); + FSHelperPtr pChart = CreateOutputStream( + sFullStream, + sRelativeStream, + pFS->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 ), USS( sId ), + FSEND ); + + pFS->endElement( FSNS( XML_a, XML_graphicData ) ); + pFS->endElement( FSNS( XML_a, XML_graphic ) ); + pFS->endElementNS( mnXmlNamespace, XML_graphicFrame ); + + SetFS( pChart ); + ExportContent(); + + 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 + Reference< XPropertySet > xPropSet( rChartDoc->getArea(), uno::UNO_QUERY ); + if( xPropSet.is() ) + exportShapeProps( xPropSet ); + 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 ); + mxDiagram.set( rChartDoc->getDiagram() ); + if( xNewDoc.is()) + mxNewDiagram.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 ); + + // title + if( bHasMainTitle ) + { + Reference< drawing::XShape > xShape = rChartDoc->getTitle(); + if( xShape.is() ) + exportTitle( xShape ); + } + InitPlotArea( ); + if( mbIs3DChart ) + { + exportView3D(); + + // sideWall + + // backWall + Reference< beans::XPropertySet > xBackWall( mxNewDiagram->getWall(), uno::UNO_QUERY ); + if( xBackWall.is() ) + { + pFS->startElement( FSNS( XML_c, XML_backWall ), + FSEND ); + exportShapeProps( xBackWall ); + pFS->endElement( FSNS( XML_c, XML_backWall ) ); + } + + // floor + Reference< beans::XPropertySet > xFloor( mxNewDiagram->getFloor(), uno::UNO_QUERY ); + if( xFloor.is() ) + { + pFS->startElement( FSNS( XML_c, XML_floor ), + FSEND ); + exportShapeProps( xFloor ); + pFS->endElement( FSNS( XML_c, XML_floor ) ); + } + + } + // plot area + exportPlotArea( ); + // legend + if( bHasLegend ) + exportLegend( rChartDoc ); + // 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::exportLegend( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc ) +{ + FSHelperPtr pFS = GetFS(); + pFS->startElement( FSNS( XML_c, XML_legend ), + FSEND ); + + Reference< beans::XPropertySet > xProp( rChartDoc->getLegend(), uno::UNO_QUERY ); + if( xProp.is() ) + { + // position + ::com::sun::star::chart::ChartLegendPosition aLegendPos = ::com::sun::star::chart::ChartLegendPosition_NONE; + try + { + Any aAny( xProp->getPropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM( "Alignment" )))); + aAny >>= aLegendPos; + } + catch( beans::UnknownPropertyException & ) + { + DBG_WARNING( "Property Align not found in ChartLegend" ); + } + + const char* strPos = NULL; + switch( aLegendPos ) + { + case ::com::sun::star::chart::ChartLegendPosition_LEFT: + strPos = "l"; + break; + case ::com::sun::star::chart::ChartLegendPosition_RIGHT: + strPos = "r"; + break; + case ::com::sun::star::chart::ChartLegendPosition_TOP: + strPos = "t"; + break; + case ::com::sun::star::chart::ChartLegendPosition_BOTTOM: + strPos = "b"; + break; + case ::com::sun::star::chart::ChartLegendPosition_NONE: + case ::com::sun::star::chart::ChartLegendPosition_MAKE_FIXED_SIZE: + // nothing + break; + } + + if( strPos != NULL ) + { + pFS->singleElement( FSNS( XML_c, XML_legendPos ), + XML_val, strPos, + FSEND ); + } + + // shape properties + exportShapeProps( xProp ); + } + + // manula layout + + // text properties + + // legendEntry + + pFS->endElement( FSNS( XML_c, XML_legend ) ); +} + +void ChartExport::exportTitle( Reference< XShape > xShape ) +{ + OUString sText; + Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY ); + if( xPropSet.is()) + { + xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "String" ))) >>= sText; + } + if( sText.getLength() == 0 ) + return; + + FSHelperPtr pFS = GetFS(); + pFS->startElement( FSNS( XML_c, XML_title ), + FSEND ); + // TODO:customize layout + pFS->singleElement( FSNS( XML_c, XML_layout ), + FSEND ); + + pFS->startElement( FSNS( XML_c, XML_tx ), + FSEND ); + pFS->startElement( FSNS( XML_c, XML_rich ), + FSEND ); + + // TODO: bodyPr + const char* sWritingMode = NULL; + sal_Bool bVertical = sal_False; + xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "StackedText" ))) >>= bVertical; + if( bVertical ) + sWritingMode = "wordArtVert"; + + pFS->singleElement( FSNS( XML_a, XML_bodyPr ), + XML_vert, sWritingMode, + FSEND ); + // TODO: lstStyle + pFS->singleElement( FSNS( XML_a, XML_lstStyle ), + FSEND ); + // FIXME: handle multipul paragraphs to parse aText + pFS->startElement( FSNS( XML_a, XML_p ), + FSEND ); + + pFS->startElement( FSNS( XML_a, XML_pPr ), + FSEND ); + pFS->singleElement( FSNS( XML_a, XML_defRPr ), + FSEND ); + pFS->endElement( FSNS( XML_a, XML_pPr ) ); + + pFS->startElement( FSNS( XML_a, XML_r ), + FSEND ); + WriteRunProperties( xPropSet, sal_False ); + pFS->startElement( FSNS( XML_a, XML_t ), + FSEND ); + pFS->writeEscaped( sText ); + pFS->endElement( FSNS( XML_a, XML_t ) ); + pFS->endElement( FSNS( XML_a, XML_r ) ); + + pFS->endElement( FSNS( XML_a, XML_p ) ); + + pFS->endElement( FSNS( XML_c, XML_rich ) ); + pFS->endElement( FSNS( XML_c, XML_tx ) ); + pFS->endElement( FSNS( XML_c, XML_title ) ); +} + +void ChartExport::exportPlotArea( ) +{ + Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( mxNewDiagram, uno::UNO_QUERY ); + if( ! xBCooSysCnt.is()) + return; + + // 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 + 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()) + return; + Reference< chart2::XChartType > xChartType( aCTSeq[nCTIdx], uno::UNO_QUERY ); + if( ! xChartType.is()) + continue; + // note: if xDSCnt.is() then also aCTSeq[nCTIdx] + OUString aChartType( xChartType->getChartType()); + sal_Int32 eChartType = lcl_getChartType( aChartType ); + switch( eChartType ) + { + case chart::TYPEID_BAR: + { + exportBarChart( xChartType ); + break; + } + case chart::TYPEID_AREA: + { + exportAreaChart( xChartType ); + break; + } + case chart::TYPEID_LINE: + { + exportLineChart( xChartType ); + break; + } + case chart::TYPEID_BUBBLE: + { + exportBubbleChart( xChartType ); + break; + } + case chart::TYPEID_DOUGHNUT: + { + exportDoughnutChart( xChartType ); + break; + } + case chart::TYPEID_OFPIE: + { + exportOfPieChart( xChartType ); + break; + } + case chart::TYPEID_PIE: + { + exportPieChart( xChartType ); + break; + } + case chart::TYPEID_RADARLINE: + case chart::TYPEID_RADARAREA: + { + exportRadarChart( xChartType ); + break; + } + case chart::TYPEID_SCATTER: + { + exportScatterChart( xChartType ); + break; + } + case chart::TYPEID_STOCK: + { + exportStockChart( xChartType ); + break; + } + case chart::TYPEID_SURFACE: + { + exportSuffaceChart( xChartType ); + break; + } + default: + { + OSL_TRACE("ChartExport::exportPlotArea -- not support chart type"); + break; + } + } + + } + } + //Axis Data + exportAxes( ); + + // shape properties + Reference< ::com::sun::star::chart::X3DDisplay > xWallFloorSupplier( mxDiagram, uno::UNO_QUERY ); + if( xWallFloorSupplier.is() ) + { + Reference< beans::XPropertySet > xWallPropSet( xWallFloorSupplier->getWall(), uno::UNO_QUERY ); + if( xWallPropSet.is() ) + { + exportShapeProps( xWallPropSet ); + } + } + + pFS->endElement( FSNS( XML_c, XML_plotArea ) ); + +} + +void ChartExport::exportAreaChart( Reference< chart2::XChartType > xChartType ) +{ + FSHelperPtr pFS = GetFS(); + sal_Int32 nTypeId = XML_areaChart; + if( mbIs3DChart ) + nTypeId = XML_area3DChart; + pFS->startElement( FSNS( XML_c, nTypeId ), + FSEND ); + + exportGrouping( ); + sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; + exportSeries( xChartType, nAttachedAxis ); + exportAxesId( nAttachedAxis ); + + pFS->endElement( FSNS( XML_c, nTypeId ) ); +} + +void ChartExport::exportBarChart( Reference< chart2::XChartType > xChartType ) +{ + sal_Int32 nTypeId = XML_barChart; + if( mbIs3DChart ) + nTypeId = XML_bar3DChart; + FSHelperPtr pFS = GetFS(); + pFS->startElement( FSNS( XML_c, nTypeId ), + FSEND ); + // bar direction + sal_Bool bVertical = sal_False; + Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY); + if( GetProperty( xPropSet, S( "Vertical" ) ) ) + mAny >>= bVertical; + + const char* bardir = bVertical? "bar":"col"; + pFS->singleElement( FSNS( XML_c, XML_barDir ), + XML_val, bardir, + FSEND ); + + exportGrouping( sal_True ); + sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; + exportSeries( xChartType, nAttachedAxis ); + + Reference< XPropertySet > xTypeProp( xChartType, uno::UNO_QUERY ); + if( mbIs3DChart ) + { + // Shape + namespace cssc = ::com::sun::star::chart; + sal_Int32 nGeom3d = cssc::ChartSolidType::RECTANGULAR_SOLID; + if( xPropSet.is() && GetProperty( xPropSet, S("SolidType") ) ) + mAny >>= nGeom3d; + const char* sShapeType = NULL; + switch( nGeom3d ) + { + case cssc::ChartSolidType::RECTANGULAR_SOLID: + sShapeType = "box"; + break; + case cssc::ChartSolidType::CONE: + //case cssc::DataPointGeometry3D::CONE: + sShapeType = "cone"; + break; + case cssc::ChartSolidType::CYLINDER: + //case cssc::DataPointGeometry3D::CYLINDER: + sShapeType = "cylinder"; + break; + case cssc::ChartSolidType::PYRAMID: + //case cssc::DataPointGeometry3D::PYRAMID: + sShapeType = "pyramid"; + break; + } + pFS->singleElement( FSNS( XML_c, XML_shape ), + XML_val, sShapeType, + FSEND ); + } + + //overlap + if( xTypeProp.is() && GetProperty( xTypeProp, S("OverlapSequence") ) ) + { + uno::Sequence< sal_Int32 > aBarPositionSequence; + mAny >>= aBarPositionSequence; + if( aBarPositionSequence.getLength() ) + { + sal_Int32 nOverlap = aBarPositionSequence[0]; + if( nOverlap > 0 ) + pFS->singleElement( FSNS( XML_c, XML_overlap ), + XML_val, I32S( nOverlap ), + FSEND ); + } + } + if( xTypeProp.is() && GetProperty( xTypeProp, S("GapwidthSequence") ) ) + { + uno::Sequence< sal_Int32 > aBarPositionSequence; + mAny >>= aBarPositionSequence; + if( aBarPositionSequence.getLength() ) + { + sal_Int32 nGapWidth = aBarPositionSequence[0]; + pFS->singleElement( FSNS( XML_c, XML_gapWidth ), + XML_val, I32S( nGapWidth ), + FSEND ); + } + } + + exportAxesId( nAttachedAxis ); + + pFS->endElement( FSNS( XML_c, nTypeId ) ); +} + +void ChartExport::exportBubbleChart( Reference< chart2::XChartType > xChartType ) +{ + FSHelperPtr pFS = GetFS(); + pFS->startElement( FSNS( XML_c, XML_bubbleChart ), + FSEND ); + + sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; + exportSeries( xChartType, nAttachedAxis ); + exportAxesId( nAttachedAxis ); + + pFS->endElement( FSNS( XML_c, XML_bubbleChart ) ); +} + +void ChartExport::exportDoughnutChart( Reference< chart2::XChartType > xChartType ) +{ + FSHelperPtr pFS = GetFS(); + pFS->startElement( FSNS( XML_c, XML_doughnutChart ), + FSEND ); + + sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; + exportSeries( xChartType, nAttachedAxis ); + // firstSliceAng + exportFirstSliceAng( ); + //FIXME: holeSize + sal_Int32 nHoleSize = 50; + pFS->singleElement( FSNS( XML_c, XML_holeSize ), + XML_val, I32S( nHoleSize ), + FSEND ); + + exportAxesId( nAttachedAxis ); + + pFS->endElement( FSNS( XML_c, XML_doughnutChart ) ); +} + +void ChartExport::exportLineChart( Reference< chart2::XChartType > xChartType ) +{ + FSHelperPtr pFS = GetFS(); + sal_Int32 nTypeId = XML_lineChart; + if( mbIs3DChart ) + nTypeId = XML_line3DChart; + pFS->startElement( FSNS( XML_c, nTypeId ), + FSEND ); + + exportGrouping( ); + // TODO: show marker symbol in series? + sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; + exportSeries( xChartType, nAttachedAxis ); + + // show marker? + sal_Int32 nSymbolType = ::com::sun::star::chart::ChartSymbolType::NONE; + Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY); + if( GetProperty( xPropSet, S( "SymbolType" ) ) ) + mAny >>= nSymbolType; + + const char* marker = nSymbolType == ::com::sun::star::chart::ChartSymbolType::NONE? "0":"1"; + pFS->singleElement( FSNS( XML_c, XML_marker ), + XML_val, marker, + FSEND ); + + exportAxesId( nAttachedAxis ); + + pFS->endElement( FSNS( XML_c, nTypeId ) ); +} + +void ChartExport::exportOfPieChart( Reference< chart2::XChartType > /*xChartType*/ ) +{ + // TODO: +} + +void ChartExport::exportPieChart( Reference< chart2::XChartType > xChartType ) +{ + FSHelperPtr pFS = GetFS(); + sal_Int32 nTypeId = XML_pieChart; + if( mbIs3DChart ) + nTypeId = XML_pie3DChart; + pFS->startElement( FSNS( XML_c, nTypeId ), + FSEND ); + // TODO: varyColors + const char* varyColors = "1"; + pFS->singleElement( FSNS( XML_c, XML_varyColors ), + XML_val, varyColors, + FSEND ); + + sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; + exportSeries( xChartType, nAttachedAxis ); + + // firstSliceAng + exportFirstSliceAng( ); + + pFS->endElement( FSNS( XML_c, nTypeId ) ); +} + +void ChartExport::exportRadarChart( Reference< chart2::XChartType > xChartType) +{ + FSHelperPtr pFS = GetFS(); + pFS->startElement( FSNS( XML_c, XML_radarChart ), + FSEND ); + + // radarStyle + sal_Int32 eChartType = getChartType( ); + const char* radarStyle = NULL; + if( eChartType == chart::TYPEID_RADARAREA ) + radarStyle = "filled"; + else + radarStyle = "marker"; + pFS->singleElement( FSNS( XML_c, XML_radarStyle ), + XML_val, radarStyle, + FSEND ); + sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; + exportSeries( xChartType, nAttachedAxis ); + exportAxesId( nAttachedAxis ); + + pFS->endElement( FSNS( XML_c, XML_radarChart ) ); +} + +void ChartExport::exportScatterChart( Reference< chart2::XChartType > xChartType ) +{ + FSHelperPtr pFS = GetFS(); + pFS->startElement( FSNS( XML_c, XML_scatterChart ), + FSEND ); + // TODO:scatterStyle + const char* scatterStyle = "lineMarker"; + pFS->singleElement( FSNS( XML_c, XML_scatterStyle ), + XML_val, scatterStyle, + FSEND ); + + // FIXME: should export xVal and yVal + sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; + exportSeries( xChartType, nAttachedAxis ); + exportAxesId( nAttachedAxis ); + + pFS->endElement( FSNS( XML_c, XML_scatterChart ) ); +} + +void ChartExport::exportStockChart( Reference< chart2::XChartType > xChartType ) +{ + FSHelperPtr pFS = GetFS(); + pFS->startElement( FSNS( XML_c, XML_stockChart ), + FSEND ); + + sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; + exportSeries( xChartType, nAttachedAxis ); + // export stock properties + Reference< ::com::sun::star::chart::XStatisticDisplay > xStockPropProvider( mxDiagram, uno::UNO_QUERY ); + if( xStockPropProvider.is()) + { + // stock-range-line + Reference< beans::XPropertySet > xStockPropSet = xStockPropProvider->getMinMaxLine(); + if( xStockPropSet.is() ) + { + pFS->startElement( FSNS( XML_c, XML_hiLowLines ), + FSEND ); + exportShapeProps( xStockPropSet ); + pFS->endElement( FSNS( XML_c, XML_hiLowLines ) ); + } + // stock updownbar + pFS->startElement( FSNS( XML_c, XML_upDownBars ), + FSEND ); + // TODO: gapWidth + sal_Int32 nGapWidth = 150; + pFS->singleElement( FSNS( XML_c, XML_gapWidth ), + XML_val, I32S( nGapWidth ), + FSEND ); + + xStockPropSet = xStockPropProvider->getUpBar(); + if( xStockPropSet.is() ) + { + pFS->startElement( FSNS( XML_c, XML_upBars ), + FSEND ); + exportShapeProps( xStockPropSet ); + pFS->endElement( FSNS( XML_c, XML_upBars ) ); + } + + xStockPropSet = xStockPropProvider->getDownBar(); + if( xStockPropSet.is() ) + { + pFS->startElement( FSNS( XML_c, XML_downBars ), + FSEND ); + exportShapeProps( xStockPropSet ); + pFS->endElement( FSNS( XML_c, XML_downBars ) ); + } + pFS->endElement( FSNS( XML_c, XML_upDownBars ) ); + } + + exportAxesId( nAttachedAxis ); + + pFS->endElement( FSNS( XML_c, XML_stockChart ) ); +} + +void ChartExport::exportSuffaceChart( Reference< chart2::XChartType > xChartType ) +{ + FSHelperPtr pFS = GetFS(); + sal_Int32 nTypeId = XML_surfaceChart; + if( mbIs3DChart ) + nTypeId = XML_surface3DChart; + pFS->startElement( FSNS( XML_c, nTypeId ), + FSEND ); + sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; + exportSeries( xChartType, nAttachedAxis ); + exportAxesId( nAttachedAxis ); + + pFS->endElement( FSNS( XML_c, nTypeId ) ); +} + +void ChartExport::exportSeries( Reference< chart2::XChartType > xChartType, sal_Int32& nAttachedAxis ) +{ + + OUString aLabelRole = xChartType->getRoleOfSequenceForSeriesLabel(); + Reference< chart2::XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY ); + if( ! xDSCnt.is()) + return; + + OUString aChartType( xChartType->getChartType()); + sal_Int32 eChartType = lcl_getChartType( aChartType ); + + // special export for stock charts + if( eChartType == chart::TYPEID_STOCK ) + { + sal_Bool bJapaneseCandleSticks = sal_False; + Reference< beans::XPropertySet > xCTProp( xChartType, uno::UNO_QUERY ); + if( xCTProp.is()) + xCTProp->getPropertyValue( OUString::createFromAscii("Japanese")) >>= bJapaneseCandleSticks; + exportCandleStickSeries( + xDSCnt->getDataSeries(), bJapaneseCandleSticks, nAttachedAxis ); + return; + } + + + // 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 shape properties + Reference< XPropertySet > xPropSet = SchXMLSeriesHelper::createOldAPISeriesPropertySet( + aSeriesSeq[nSeriesIdx], getModel() ); + if( xPropSet.is() ) + { + if( GetProperty( xPropSet, S("Axis") ) ) + { + mAny >>= nAttachedAxis; + if( nAttachedAxis == ::com::sun::star::chart::ChartAxisAssign::SECONDARY_Y ) + nAttachedAxis = AXIS_SECONDARY_Y; + else + nAttachedAxis = AXIS_PRIMARY_Y; + } + exportShapeProps( xPropSet ); + } + + switch( eChartType ) + { + case chart::TYPEID_LINE: + { + exportMarker( ); + break; + } + case chart::TYPEID_PIE: + case chart::TYPEID_DOUGHNUT: + { + if( xPropSet.is() && GetProperty( xPropSet, S("SegmentOffset") ) ) + { + sal_Int32 nOffset = 0; + mAny >>= nOffset; + pFS->singleElement( FSNS( XML_c, XML_explosion ), + XML_val, I32S( nOffset ), + FSEND ); + } + break; + } + case chart::TYPEID_SCATTER: + { + exportMarker( ); + exportSmooth( ); + break; + } + case chart::TYPEID_RADARLINE: + { + exportMarker( ); + break; + } + } + + // TODO: Data Labels: show data lables + + // export data points + exportDataPoints( uno::Reference< beans::XPropertySet >( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY ), nSeriesLength ); + + // export categories + if( mxCategoriesValues.is() ) + exportSeriesCategory( mxCategoriesValues ); + + if( (eChartType == chart::TYPEID_SCATTER) + || (eChartType == chart::TYPEID_BUBBLE) ) + { + // export xVal + Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString::createFromAscii("values-x" ) ) ); + if( xSequence.is() ) + { + Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() ); + if( xValues.is() ) + exportSeriesValues( xValues, XML_xVal ); + } + } + + + if( eChartType == chart::TYPEID_BUBBLE ) + { + // export yVal + Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString::createFromAscii("values-y" ) ) ); + if( xSequence.is() ) + { + Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() ); + if( xValues.is() ) + exportSeriesValues( xValues, XML_yVal ); + } + } + + // export values + if( xValuesSeq.is() ) + { + sal_Int32 nYValueType = XML_val; + if( eChartType == chart::TYPEID_SCATTER ) + nYValueType = XML_yVal; + else if( eChartType == chart::TYPEID_BUBBLE ) + nYValueType = XML_bubbleSize; + exportSeriesValues( xValuesSeq, nYValueType ); + } + + pFS->endElement( FSNS( XML_c, XML_ser ) ); + } + } + } + } +} + +void ChartExport::exportCandleStickSeries( + const Sequence< Reference< chart2::XDataSeries > > & aSeriesSeq, + sal_Bool /*bJapaneseCandleSticks*/, + sal_Int32& nAttachedAxis ) +{ + for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx ) + { + Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nSeriesIdx] ); + nAttachedAxis = lcl_isSeriesAttachedToFirstAxis( xSeries ) ? AXIS_PRIMARY_Y : AXIS_SECONDARY_Y; + + Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY ); + if( xSource.is()) + { + // export series in correct order (as we don't store roles) + // with japanese candlesticks: open, low, high, close + // otherwise: low, high, close + Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt( + xSource->getDataSequences()); + + //sal_Int32 nSeriesLength = + // lcl_getSequenceLengthByRole( aSeqCnt, OUString::createFromAscii("values-last")); + + Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY ); + const char* sSeries[] = {"values-first","values-max","values-min","values-last",0}; + for( sal_Int32 idx = 0; sSeries[idx] != 0 ; idx++ ) + { + Reference< chart2::data::XLabeledDataSequence > xLabeledSeq( lcl_getDataSequenceByRole( aSeqCnt, OUString::createFromAscii(sSeries[idx]) ) ); + if( xLabeledSeq.is()) + { + Reference< chart2::data::XDataSequence > xLabelSeq( xLabeledSeq->getLabel()); + Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues()); + { + 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(idx), + FSEND ); + pFS->singleElement( FSNS( XML_c, XML_order ), + XML_val, I32S(idx), + FSEND ); + + // export label + if( xLabelSeq.is() ) + exportSeriesText( xLabelSeq ); + + // TODO:export shape properties + + // export categories + if( mxCategoriesValues.is() ) + exportSeriesCategory( mxCategoriesValues ); + + // export values + if( xValueSeq.is() ) + exportSeriesValues( xValueSeq ); + + 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 = xValueSeq->getSourceRangeRepresentation(); + aCellRange = parseFormula( 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 ) ); + + 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_idx, "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 = xValueSeq->getSourceRangeRepresentation(); + aCellRange = parseFormula( aCellRange ); + // 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_idx, 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, sal_Int32 nValueType ) +{ + FSHelperPtr pFS = GetFS(); + Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY ); + // sal_Int32 nValueType = XML_val; + pFS->startElement( FSNS( XML_c, nValueType ), + FSEND ); + + OUString aCellRange = xValueSeq->getSourceRangeRepresentation(); + aCellRange = parseFormula( aCellRange ); + // 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_idx, 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, nValueType ) ); +} + +void ChartExport::exportShapeProps( Reference< XPropertySet > xPropSet ) +{ + FSHelperPtr pFS = GetFS(); + pFS->startElement( FSNS( XML_c, XML_spPr ), + FSEND ); + + WriteFill( xPropSet ); + WriteOutline( xPropSet ); + pFS->endElement( FSNS( XML_c, XML_spPr ) ); +} + +void ChartExport::InitPlotArea( ) +{ + Reference< XPropertySet > xDiagramProperties (mxDiagram, uno::UNO_QUERY); + + // Check for supported services and then the properties provided by this service. + Reference<lang::XServiceInfo> xServiceInfo (mxDiagram, uno::UNO_QUERY); + if (xServiceInfo.is()) + { + if (xServiceInfo->supportsService( + OUString::createFromAscii ("com.sun.star.chart.ChartAxisXSupplier"))) + { + xDiagramProperties->getPropertyValue( + OUString(RTL_CONSTASCII_USTRINGPARAM("HasXAxis"))) >>= mbHasXAxis; + } + if (xServiceInfo->supportsService( + OUString::createFromAscii ("com.sun.star.chart.ChartAxisYSupplier"))) + { + xDiagramProperties->getPropertyValue( + OUString(RTL_CONSTASCII_USTRINGPARAM("HasYAxis"))) >>= mbHasYAxis; + } + if (xServiceInfo->supportsService( + OUString::createFromAscii ("com.sun.star.chart.ChartAxisZSupplier"))) + { + xDiagramProperties->getPropertyValue( + OUString(RTL_CONSTASCII_USTRINGPARAM("HasZAxis"))) >>= mbHasZAxis; + } + if (xServiceInfo->supportsService( + OUString::createFromAscii ("com.sun.star.chart.ChartTwoAxisXSupplier"))) + { + xDiagramProperties->getPropertyValue( + OUString(RTL_CONSTASCII_USTRINGPARAM("HasSecondaryXAxis"))) >>= mbHasSecondaryXAxis; + } + if (xServiceInfo->supportsService( + OUString::createFromAscii ("com.sun.star.chart.ChartTwoAxisYSupplier"))) + { + xDiagramProperties->getPropertyValue( + OUString(RTL_CONSTASCII_USTRINGPARAM("HasSecondaryYAxis"))) >>= mbHasSecondaryYAxis; + } + } + + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("Dim3D"))) >>= mbIs3DChart; + + Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY ); + if( mbHasCategoryLabels && mxNewDiagram.is()) + { + Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( mxNewDiagram ) ); + if( xCategories.is() ) + { + mxCategoriesValues.set( xCategories->getValues() ); + } + } +} + +void ChartExport::exportAxes( ) +{ + sal_Int32 nSize = maAxes.size(); + for( sal_Int32 nIdx = 0; nIdx < nSize; nIdx++ ) + { + exportAxis( maAxes[nIdx] ); + /* + sal_Int32 nAxisId = maAxes[nIdx].nAxisId; + switch( nAxisId ) + { + case AXIS_PRIMARY_X: + exportXAxis( maAxes[nIdx] ); + break; + case AXIS_PRIMARY_Y: + exportYAxis( maAxes[nIdx] ); + break; + } + */ + } +} + +void ChartExport::exportAxis( AxisIdPair aAxisIdPair ) +{ + // get some properties from document first + sal_Bool bHasXAxisTitle = sal_False, + bHasYAxisTitle = sal_False, + bHasZAxisTitle = sal_False, + bHasSecondaryXAxisTitle = sal_False, + bHasSecondaryYAxisTitle = sal_False; + sal_Bool bHasXAxisMajorGrid = sal_False, + bHasXAxisMinorGrid = sal_False, + bHasYAxisMajorGrid = sal_False, + bHasYAxisMinorGrid = sal_False, + bHasZAxisMajorGrid = sal_False, + bHasZAxisMinorGrid = sal_False; + + Reference< XPropertySet > xDiagramProperties (mxDiagram, uno::UNO_QUERY); + + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasXAxisTitle"))) >>= bHasXAxisTitle; + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasYAxisTitle"))) >>= bHasYAxisTitle; + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasZAxisTitle"))) >>= bHasZAxisTitle; + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasSecondaryXAxisTitle"))) >>= bHasSecondaryXAxisTitle; + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasSecondaryYAxisTitle"))) >>= bHasSecondaryYAxisTitle; + + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasXAxisGrid"))) >>= bHasXAxisMajorGrid; + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasYAxisGrid"))) >>= bHasYAxisMajorGrid; + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasZAxisGrid"))) >>= bHasZAxisMajorGrid; + + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasXAxisHelpGrid"))) >>= bHasXAxisMinorGrid; + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasYAxisHelpGrid"))) >>= bHasYAxisMinorGrid; + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasZAxisHelpGrid"))) >>= bHasZAxisMinorGrid; + + Reference< XPropertySet > xAxisProp; + Reference< drawing::XShape > xAxisTitle; + Reference< beans::XPropertySet > xMajorGrid; + Reference< beans::XPropertySet > xMinorGrid; + sal_Int32 nAxisType = XML_catAx; + const char* sAxPos = NULL; + + switch( aAxisIdPair.nAxisType ) + { + case AXIS_PRIMARY_X: + { + Reference< ::com::sun::star::chart::XAxisXSupplier > xAxisXSupp( mxDiagram, uno::UNO_QUERY ); + if( xAxisXSupp.is()) + xAxisProp = xAxisXSupp->getXAxis(); + if( bHasXAxisTitle ) + xAxisTitle.set( xAxisXSupp->getXAxisTitle(), uno::UNO_QUERY ); + if( bHasXAxisMajorGrid ) + xMajorGrid.set( xAxisXSupp->getXMainGrid(), uno::UNO_QUERY ); + if( bHasXAxisMinorGrid ) + xMinorGrid.set( xAxisXSupp->getXHelpGrid(), uno::UNO_QUERY ); + + sal_Int32 eChartType = getChartType( ); + if( (eChartType == chart::TYPEID_SCATTER) + || (eChartType == chart::TYPEID_BUBBLE) ) + nAxisType = XML_valAx; + else if( eChartType == chart::TYPEID_STOCK ) + nAxisType = XML_dateAx; + // FIXME: axPos, need to check axis direction + sAxPos = "b"; + break; + } + case AXIS_PRIMARY_Y: + { + Reference< ::com::sun::star::chart::XAxisYSupplier > xAxisYSupp( mxDiagram, uno::UNO_QUERY ); + if( xAxisYSupp.is()) + xAxisProp = xAxisYSupp->getYAxis(); + if( bHasYAxisTitle ) + xAxisTitle.set( xAxisYSupp->getYAxisTitle(), uno::UNO_QUERY ); + if( bHasYAxisMajorGrid ) + xMajorGrid.set( xAxisYSupp->getYMainGrid(), uno::UNO_QUERY ); + if( bHasYAxisMinorGrid ) + xMinorGrid.set( xAxisYSupp->getYHelpGrid(), uno::UNO_QUERY ); + + nAxisType = XML_valAx; + // FIXME: axPos, need to check axis direction + sAxPos = "l"; + break; + } + case AXIS_PRIMARY_Z: + { + Reference< ::com::sun::star::chart::XAxisZSupplier > xAxisZSupp( mxDiagram, uno::UNO_QUERY ); + if( xAxisZSupp.is()) + xAxisProp = xAxisZSupp->getZAxis(); + if( bHasZAxisTitle ) + xAxisTitle.set( xAxisZSupp->getZAxisTitle(), uno::UNO_QUERY ); + if( bHasZAxisMajorGrid ) + xMajorGrid.set( xAxisZSupp->getZMainGrid(), uno::UNO_QUERY ); + if( bHasZAxisMinorGrid ) + xMinorGrid.set( xAxisZSupp->getZHelpGrid(), uno::UNO_QUERY ); + + sal_Int32 eChartType = getChartType( ); + if( (eChartType == chart::TYPEID_SCATTER) + || (eChartType == chart::TYPEID_BUBBLE) ) + nAxisType = XML_valAx; + else if( eChartType == chart::TYPEID_STOCK ) + nAxisType = XML_dateAx; + // FIXME: axPos, need to check axis direction + sAxPos = "b"; + break; + } + case AXIS_SECONDARY_Y: + { + Reference< ::com::sun::star::chart::XTwoAxisYSupplier > xAxisTwoYSupp( mxDiagram, uno::UNO_QUERY ); + if( xAxisTwoYSupp.is()) + xAxisProp = xAxisTwoYSupp->getSecondaryYAxis(); + if( bHasSecondaryYAxisTitle ) + { + Reference< ::com::sun::star::chart::XSecondAxisTitleSupplier > xAxisSupp( mxDiagram, uno::UNO_QUERY ); + xAxisTitle.set( xAxisSupp->getSecondYAxisTitle(), uno::UNO_QUERY ); + } + + nAxisType = XML_valAx; + // FIXME: axPos, need to check axis direction + sAxPos = "l"; + break; + } + } + + + _exportAxis( xAxisProp, xAxisTitle, xMajorGrid, xMinorGrid, nAxisType, sAxPos, aAxisIdPair ); +} + +void ChartExport::exportXAxis( AxisIdPair aAxisIdPair ) +{ + // get some properties from document first + sal_Bool bHasXAxisTitle = sal_False, + bHasSecondaryXAxisTitle = sal_False; + sal_Bool bHasXAxisMajorGrid = sal_False, + bHasXAxisMinorGrid = sal_False; + + Reference< XPropertySet > xDiagramProperties (mxDiagram, uno::UNO_QUERY); + + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasXAxisTitle"))) >>= bHasXAxisTitle; + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasSecondaryXAxisTitle"))) >>= bHasSecondaryXAxisTitle; + + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasXAxisGrid"))) >>= bHasXAxisMajorGrid; + + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasXAxisHelpGrid"))) >>= bHasXAxisMinorGrid; + + // catAx + Reference< ::com::sun::star::chart::XAxisXSupplier > xAxisXSupp( mxDiagram, uno::UNO_QUERY ); + if( !xAxisXSupp.is()) + return; + + Reference< XPropertySet > xAxisProp = xAxisXSupp->getXAxis(); + if( !xAxisProp.is() ) + return; + + sal_Int32 nAxisType = XML_catAx; + sal_Int32 eChartType = getChartType( ); + if( (eChartType == chart::TYPEID_SCATTER) + || (eChartType == chart::TYPEID_BUBBLE) ) + nAxisType = XML_valAx; + else if( eChartType == chart::TYPEID_STOCK ) + nAxisType = XML_dateAx; + + Reference< drawing::XShape > xAxisTitle; + if( bHasXAxisTitle ) + xAxisTitle.set( xAxisXSupp->getXAxisTitle(), uno::UNO_QUERY ); + + // FIXME: axPos, need to check axis direction + const char* sAxPos = "b"; + // major grid line + Reference< beans::XPropertySet > xMajorGrid; + if( bHasXAxisMajorGrid ) + xMajorGrid.set( xAxisXSupp->getXMainGrid(), uno::UNO_QUERY ); + + // minor grid line + Reference< beans::XPropertySet > xMinorGrid; + if( bHasXAxisMinorGrid ) + xMinorGrid.set( xAxisXSupp->getXHelpGrid(), uno::UNO_QUERY ); + + _exportAxis( xAxisProp, xAxisTitle, xMajorGrid, xMinorGrid, nAxisType, sAxPos, aAxisIdPair ); +} + +void ChartExport::exportYAxis( AxisIdPair aAxisIdPair ) +{ + // get some properties from document first + sal_Bool bHasYAxisTitle = sal_False, + bHasSecondaryYAxisTitle = sal_False; + sal_Bool bHasYAxisMajorGrid = sal_False, + bHasYAxisMinorGrid = sal_False; + + Reference< XPropertySet > xDiagramProperties (mxDiagram, uno::UNO_QUERY); + + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasYAxisTitle"))) >>= bHasYAxisTitle; + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasSecondaryYAxisTitle"))) >>= bHasSecondaryYAxisTitle; + + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasYAxisGrid"))) >>= bHasYAxisMajorGrid; + xDiagramProperties->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("HasYAxisHelpGrid"))) >>= bHasYAxisMinorGrid; + + Reference< ::com::sun::star::chart::XAxisYSupplier > xAxisYSupp( mxDiagram, uno::UNO_QUERY ); + if( !xAxisYSupp.is()) + return; + + Reference< XPropertySet > xAxisProp = xAxisYSupp->getYAxis(); + if( !xAxisProp.is() ) + return; + + sal_Int32 nAxisType = XML_valAx; + + Reference< drawing::XShape > xAxisTitle; + if( bHasYAxisTitle ) + xAxisTitle.set( xAxisYSupp->getYAxisTitle(), uno::UNO_QUERY ); + + // FIXME: axPos + const char* sAxPos = "l"; + + // major grid line + Reference< beans::XPropertySet > xMajorGrid; + if( bHasYAxisMajorGrid ) + xMajorGrid.set( xAxisYSupp->getYMainGrid(), uno::UNO_QUERY ); + + // minor grid line + Reference< beans::XPropertySet > xMinorGrid;( xAxisYSupp->getYHelpGrid(), uno::UNO_QUERY ); + if( bHasYAxisMinorGrid ) + xMinorGrid.set( xAxisYSupp->getYHelpGrid(), uno::UNO_QUERY ); + + _exportAxis( xAxisProp, xAxisTitle, xMajorGrid, xMinorGrid, nAxisType, sAxPos, aAxisIdPair ); +} + +void ChartExport::_exportAxis( + const Reference< XPropertySet >& xAxisProp, + const Reference< drawing::XShape >& xAxisTitle, + const Reference< XPropertySet >& xMajorGrid, + const Reference< XPropertySet >& xMinorGrid, + sal_Int32 nAxisType, + const char* sAxisPos, + AxisIdPair aAxisIdPair ) +{ + FSHelperPtr pFS = GetFS(); + pFS->startElement( FSNS( XML_c, nAxisType ), + FSEND ); + pFS->singleElement( FSNS( XML_c, XML_axId ), + XML_val, I32S( aAxisIdPair.nAxisId ), + FSEND ); + + pFS->startElement( FSNS( XML_c, XML_scaling ), + FSEND ); + // orientation: minMax, maxMin + sal_Bool bReverseDirection = sal_False; + if(GetProperty( xAxisProp, S( "ReverseDirection" ) ) ) + mAny >>= bReverseDirection; + + const char* orientation = bReverseDirection ? "maxMin":"minMax"; + pFS->singleElement( FSNS( XML_c, XML_orientation ), + XML_val, orientation, + FSEND ); + // logBase, min, max + if(GetProperty( xAxisProp, S( "Logarithmic" ) ) ) + { + sal_Bool bLogarithmic = sal_False; + mAny >>= bLogarithmic; + if( bLogarithmic ) + { + // default value is 10? + sal_Int32 nLogBase = 10; + pFS->singleElement( FSNS( XML_c, XML_logBase ), + XML_val, I32S( nLogBase ), + FSEND ); + } + } + sal_Bool bAutoMax = sal_False; + if(GetProperty( xAxisProp, S( "AutoMax" ) ) ) + mAny >>= bAutoMax; + + if( !bAutoMax && (GetProperty( xAxisProp, S( "Max" ) ) )) + { + double dMax = 0; + mAny >>= dMax; + pFS->singleElement( FSNS( XML_c, XML_max ), + XML_val, IS( dMax ), + FSEND ); + } + + sal_Bool bAutoMin = sal_False; + if(GetProperty( xAxisProp, S( "AutoMin" ) ) ) + mAny >>= bAutoMin; + + if( !bAutoMin && (GetProperty( xAxisProp, S( "Min" ) ) )) + { + double dMin = 0; + mAny >>= dMin; + pFS->singleElement( FSNS( XML_c, XML_min ), + XML_val, IS( dMin ), + FSEND ); + } + + pFS->endElement( FSNS( XML_c, XML_scaling ) ); + + // title + if( xAxisTitle.is() ) + exportTitle( xAxisTitle ); + + sal_Bool bVisible = sal_True; + if( xAxisProp.is() ) + { + xAxisProp->getPropertyValue( + OUString (RTL_CONSTASCII_USTRINGPARAM ("Visible"))) >>= bVisible; + } + + if( !bVisible ) + { + // other value? + pFS->singleElement( FSNS( XML_c, XML_delete ), + XML_val, "1", + FSEND ); + } + + // FIXME: axPos, need to check the property "ReverseDirection" + pFS->singleElement( FSNS( XML_c, XML_axPos ), + XML_val, sAxisPos, + FSEND ); + // major grid line + if( xMajorGrid.is()) + { + pFS->startElement( FSNS( XML_c, XML_majorGridlines ), + FSEND ); + exportShapeProps( xMajorGrid ); + pFS->endElement( FSNS( XML_c, XML_majorGridlines ) ); + } + + // minor grid line + if( xMinorGrid.is()) + { + pFS->startElement( FSNS( XML_c, XML_minorGridlines ), + FSEND ); + exportShapeProps( xMajorGrid ); + pFS->endElement( FSNS( XML_c, XML_minorGridlines ) ); + } + + // majorTickMark + sal_Int32 nValue = 0; + if(GetProperty( xAxisProp, S( "Marks" ) ) ) + { + mAny >>= nValue; + sal_Bool bInner = nValue & ::com::sun::star::chart::ChartAxisMarks::INNER; + sal_Bool bOuter = nValue & ::com::sun::star::chart::ChartAxisMarks::OUTER; + const char* majorTickMark = NULL; + if( bInner && bOuter ) + majorTickMark = "cross"; + else if( bInner ) + majorTickMark = "in"; + else if( bOuter ) + majorTickMark = "out"; + else + majorTickMark = "none"; + pFS->singleElement( FSNS( XML_c, XML_majorTickMark ), + XML_val, majorTickMark, + FSEND ); + } + // minorTickMark + if(GetProperty( xAxisProp, S( "HelpMarks" ) ) ) + { + mAny >>= nValue; + sal_Bool bInner = nValue & ::com::sun::star::chart::ChartAxisMarks::INNER; + sal_Bool bOuter = nValue & ::com::sun::star::chart::ChartAxisMarks::OUTER; + const char* minorTickMark = NULL; + if( bInner && bOuter ) + minorTickMark = "cross"; + else if( bInner ) + minorTickMark = "in"; + else if( bOuter ) + minorTickMark = "out"; + else + minorTickMark = "none"; + pFS->singleElement( FSNS( XML_c, XML_minorTickMark ), + XML_val, minorTickMark, + FSEND ); + } + // tickLblPos + const char* sTickLblPos = NULL; + sal_Bool bDisplayLabel = sal_True; + if(GetProperty( xAxisProp, S( "DisplayLabels" ) ) ) + mAny >>= bDisplayLabel; + if( bDisplayLabel && (GetProperty( xAxisProp, S( "LabelPosition" ) ) )) + { + ::com::sun::star::chart::ChartAxisLabelPosition eLabelPosition = ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS; + mAny >>= eLabelPosition; + switch( eLabelPosition ) + { + case ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS: + case ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS_OTHER_SIDE: + sTickLblPos = "nextTo"; + break; + case ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START: + sTickLblPos = "low"; + break; + case ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END: + sTickLblPos = "high"; + break; + default: + sTickLblPos = "nextTo"; + break; + } + } + else + { + sTickLblPos = "none"; + } + pFS->singleElement( FSNS( XML_c, XML_tickLblPos ), + XML_val, sTickLblPos, + FSEND ); + + pFS->singleElement( FSNS( XML_c, XML_crossAx ), + XML_val, I32S( aAxisIdPair.nCrossAx ), + FSEND ); + + // crosses & crossesAt + sal_Bool bCrossesValue = sal_False; + const char* sCrosses = NULL; + if(GetProperty( xAxisProp, S( "CrossoverPosition" ) ) ) + { + ::com::sun::star::chart::ChartAxisPosition ePosition( ::com::sun::star::chart::ChartAxisPosition_ZERO ); + mAny >>= ePosition; + switch( ePosition ) + { + case ::com::sun::star::chart::ChartAxisPosition_START: + sCrosses = "min"; + break; + case ::com::sun::star::chart::ChartAxisPosition_END: + sCrosses = "max"; + break; + case ::com::sun::star::chart::ChartAxisPosition_ZERO: + sCrosses = "autoZero"; + break; + default: + bCrossesValue = sal_True; + break; + } + } + + if( bCrossesValue && GetProperty( xAxisProp, S("CrossoverValue" ) ) ) + { + double dValue = 0; + mAny >>= dValue; + pFS->singleElement( FSNS( XML_c, XML_crossesAt ), + XML_val, IS( dValue ), + FSEND ); + } + else + { + pFS->singleElement( FSNS( XML_c, XML_crosses ), + XML_val, sCrosses, + FSEND ); + } + + if( nAxisType == XML_catAx ) + { + // FIXME: seems not support? lblAlgn + const char* sLblAlgn = "ctr"; + pFS->singleElement( FSNS( XML_c, XML_lblAlgn ), + XML_val, sLblAlgn, + FSEND ); + } + if( ( nAxisType == XML_catAx ) + || ( nAxisType == XML_dateAx ) ) + { + // FIXME: seems not support? use default value, + const char* isAuto = "1"; + pFS->singleElement( FSNS( XML_c, XML_auto ), + XML_val, isAuto, + FSEND ); + + // FIXME: seems not support? lblOffset + sal_Int32 nLblOffset = 100; + pFS->singleElement( FSNS( XML_c, XML_lblOffset ), + XML_val, I32S( nLblOffset ), + FSEND ); + } + + // majorUnit + sal_Bool bAutoStepMain = sal_False; + if(GetProperty( xAxisProp, S( "AutoStepMain" ) ) ) + mAny >>= bAutoStepMain; + + if( !bAutoStepMain && (GetProperty( xAxisProp, S( "StepMain" ) ) )) + { + double dMajorUnit = 0; + mAny >>= dMajorUnit; + pFS->singleElement( FSNS( XML_c, XML_majorUnit ), + XML_val, IS( dMajorUnit ), + FSEND ); + } + // minorUnit + sal_Bool bAutoStepHelp = sal_False; + if(GetProperty( xAxisProp, S( "AutoStepHelp" ) ) ) + mAny >>= bAutoStepHelp; + + if( !bAutoStepHelp && (GetProperty( xAxisProp, S( "StepHelp" ) ) )) + { + double dMinorUnit = 0; + mAny >>= dMinorUnit; + pFS->singleElement( FSNS( XML_c, XML_minorUnit ), + XML_val, IS( dMinorUnit ), + FSEND ); + } + + // shape properties + exportShapeProps( xAxisProp ); + // TODO: text properties + + pFS->endElement( FSNS( XML_c, nAxisType ) ); +} + +void ChartExport::exportDataPoints( + const uno::Reference< beans::XPropertySet > & xSeriesProperties, + sal_Int32 nSeriesLength ) +{ + uno::Reference< chart2::XDataSeries > xSeries( xSeriesProperties, uno::UNO_QUERY ); + bool bVaryColorsByPoint = false; + Sequence< sal_Int32 > aDataPointSeq; + if( xSeriesProperties.is()) + { + Any aAny = xSeriesProperties->getPropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM( "AttributedDataPoints" ))); + aAny >>= aDataPointSeq; + xSeriesProperties->getPropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM( "VaryColorsByPoint" ))) >>= bVaryColorsByPoint; + } + + //sal_Int32 nSize = aDataPointSeq.getLength(); + //DBG_ASSERT( nSize <= nSeriesLength, "Too many point attributes" ); + + const sal_Int32 * pPoints = aDataPointSeq.getConstArray(); + sal_Int32 nElement; + //sal_Int32 nRepeat; + Reference< chart2::XColorScheme > xColorScheme; + if( mxNewDiagram.is()) + xColorScheme.set( mxNewDiagram->getDefaultColorScheme()); + + if( bVaryColorsByPoint && xColorScheme.is() ) + { + ::std::set< sal_Int32 > aAttrPointSet; + ::std::copy( pPoints, pPoints + aDataPointSeq.getLength(), + ::std::inserter( aAttrPointSet, aAttrPointSet.begin())); + const ::std::set< sal_Int32 >::const_iterator aEndIt( aAttrPointSet.end()); + for( nElement = 0; nElement < nSeriesLength; ++nElement ) + { + uno::Reference< beans::XPropertySet > xPropSet; + if( aAttrPointSet.find( nElement ) != aEndIt ) + { + try + { + xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet( + xSeries, nElement, getModel() ); + } + catch( uno::Exception & rEx ) + { + (void)rEx; // avoid warning for pro build + DBG_ERROR1( "Exception caught during Export of data point: %s", + OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() ); + } + } + else + { + // property set only containing the color + xPropSet.set( new ColorPropertySet( xColorScheme->getColorByIndex( nElement ))); + } + + if( xPropSet.is() ) + { + OSL_TRACE("ChartExport::exportDataPoints -- writer data points "); + FSHelperPtr pFS = GetFS(); + pFS->startElement( FSNS( XML_c, XML_dPt ), + FSEND ); + pFS->singleElement( FSNS( XML_c, XML_idx ), + XML_val, I32S(nElement), + FSEND ); + exportShapeProps( xPropSet ); + + pFS->endElement( FSNS( XML_c, XML_dPt ) ); + } + } + } +} + +void ChartExport::exportAxesId( sal_Int32 nAttachedAxis ) +{ + sal_Int32 nAxisIdx = lcl_generateRandomValue(); + sal_Int32 nAxisIdy = lcl_generateRandomValue(); + maAxes.push_back( AxisIdPair( AXIS_PRIMARY_X, nAxisIdx, nAxisIdy ) ); + maAxes.push_back( AxisIdPair( nAttachedAxis, nAxisIdy, nAxisIdx ) ); + FSHelperPtr pFS = GetFS(); + pFS->singleElement( FSNS( XML_c, XML_axId ), + XML_val, I32S( nAxisIdx ), + FSEND ); + pFS->singleElement( FSNS( XML_c, XML_axId ), + XML_val, I32S( nAxisIdy ), + FSEND ); + if( mbHasZAxis ) + { + sal_Int32 nAxisIdz = 0; + if( isDeep3dChart() ) + { + nAxisIdz = lcl_generateRandomValue(); + maAxes.push_back( AxisIdPair( AXIS_PRIMARY_Z, nAxisIdz, nAxisIdy ) ); + } + pFS->singleElement( FSNS( XML_c, XML_axId ), + XML_val, I32S( nAxisIdz ), + FSEND ); + } +} + +void ChartExport::exportGrouping( sal_Bool isBar ) +{ + FSHelperPtr pFS = GetFS(); + Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY); + // grouping + sal_Bool bStacked = sal_False; + if( GetProperty( xPropSet, S( "Stacked" ) ) ) + mAny >>= bStacked; + sal_Bool bPercentage = sal_False; + if( GetProperty( xPropSet, S( "Percent" ) ) ) + mAny >>= bPercentage; + + const char* grouping = NULL; + if( bStacked ) + grouping = "stacked"; + else if( bPercentage ) + grouping = "percentStacked"; + else + { + if( isBar && !isDeep3dChart() ) + grouping = "clustered"; + else + grouping = "standard"; + } + pFS->singleElement( FSNS( XML_c, XML_grouping ), + XML_val, grouping, + FSEND ); +} + +void ChartExport::exportMarker() +{ + FSHelperPtr pFS = GetFS(); + pFS->startElement( FSNS( XML_c, XML_marker ), + FSEND ); + Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY ); + sal_Int32 nSymbolType = ::com::sun::star::chart::ChartSymbolType::NONE; + if( GetProperty( xPropSet, S( "SymbolType" ) ) ) + mAny >>= nSymbolType; + // TODO: more properties support for marker + if( nSymbolType == ::com::sun::star::chart::ChartSymbolType::NONE ) + { + pFS->singleElement( FSNS( XML_c, XML_symbol ), + XML_val, "none", + FSEND ); + } + pFS->endElement( FSNS( XML_c, XML_marker ) ); +} + +void ChartExport::exportSmooth() +{ + FSHelperPtr pFS = GetFS(); + Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY ); + sal_Int32 nSplineType = 0; + if( GetProperty( xPropSet, S( "SplineType" ) ) ) + mAny >>= nSplineType; + if( nSplineType != 0 ) + { + pFS->singleElement( FSNS( XML_c, XML_smooth ), + XML_val, "1", + FSEND ); + } +} + +void ChartExport::exportFirstSliceAng( ) +{ + FSHelperPtr pFS = GetFS(); + sal_Int32 nStartingAngle = 0; + Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY); + if( GetProperty( xPropSet, S( "StartingAngle" ) ) ) + mAny >>= nStartingAngle; + + // convert to ooxml angle + nStartingAngle = (450 - nStartingAngle ) % 360; + pFS->singleElement( FSNS( XML_c, XML_firstSliceAng ), + XML_val, I32S( nStartingAngle ), + FSEND ); +} + +void ChartExport::exportView3D() +{ + Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY); + if( !xPropSet.is() ) + return; + FSHelperPtr pFS = GetFS(); + pFS->startElement( FSNS( XML_c, XML_view3D ), + FSEND ); + // rotX + if( GetProperty( xPropSet, S( "RotationHorizontal" ) ) ) + { + sal_Int32 nRotationX = 0; + mAny >>= nRotationX; + // X rotation (map Chart2 [-179,180] to OOXML [0..359]) + if( nRotationX < 0 ) + nRotationX += 360; + pFS->singleElement( FSNS( XML_c, XML_rotX ), + XML_val, I32S( nRotationX ), + FSEND ); + } + // rotY + if( GetProperty( xPropSet, S( "RotationVertical" ) ) ) + { + sal_Int32 nRotationY = 0; + mAny >>= nRotationY; + // Y rotation (map Chart2 [-179,180] to OOXML [0..359]) + if( nRotationY < 0 ) + nRotationY += 360; + pFS->singleElement( FSNS( XML_c, XML_rotY ), + XML_val, I32S( nRotationY ), + FSEND ); + } + // perspective + if( GetProperty( xPropSet, S( "Perspective" ) ) ) + { + sal_Int32 nPerspective = 0; + mAny >>= nPerspective; + // map Chart2 [0,100] to OOXML [0..200] + nPerspective *= 2; + pFS->singleElement( FSNS( XML_c, XML_perspective ), + XML_val, I32S( nPerspective ), + FSEND ); + } + // rAngAx + if( GetProperty( xPropSet, S( "RightAngledAxes" ) ) ) + { + sal_Bool bRightAngled = sal_False; + mAny >>= bRightAngled; + const char* sRightAngled = bRightAngled ? "1":"0"; + pFS->singleElement( FSNS( XML_c, XML_rAngAx ), + XML_val, sRightAngled, + FSEND ); + } + pFS->endElement( FSNS( XML_c, XML_view3D ) ); +} + +sal_Bool ChartExport::isDeep3dChart() +{ + sal_Bool isDeep = sal_False; + if( mbIs3DChart ) + { + Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY); + if( GetProperty( xPropSet, S( "Deep" ) ) ) + mAny >>= isDeep; + } + return isDeep; +} + +}// drawingml +}// oox |