LCOV - code coverage report
Current view: top level - oox/source/export - chartexport.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1463 1707 85.7 %
Date: 2014-11-03 Functions: 74 79 93.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <oox/token/tokens.hxx>
      21             : #include "oox/core/xmlfilterbase.hxx"
      22             : #include "oox/export/chartexport.hxx"
      23             : #include "oox/export/utils.hxx"
      24             : #include "drawingml/chart/typegroupconverter.hxx"
      25             : 
      26             : #include <cstdio>
      27             : 
      28             : #include <com/sun/star/awt/Gradient.hpp>
      29             : #include <com/sun/star/chart/XChartDocument.hpp>
      30             : #include <com/sun/star/chart/ChartLegendPosition.hpp>
      31             : #include <com/sun/star/chart/XTwoAxisXSupplier.hpp>
      32             : #include <com/sun/star/chart/XTwoAxisYSupplier.hpp>
      33             : #include <com/sun/star/chart/XAxisZSupplier.hpp>
      34             : #include <com/sun/star/chart/XChartDataArray.hpp>
      35             : #include <com/sun/star/chart/ChartDataRowSource.hpp>
      36             : #include <com/sun/star/chart/ChartAxisAssign.hpp>
      37             : #include <com/sun/star/chart/ChartSeriesAddress.hpp>
      38             : #include <com/sun/star/chart/X3DDisplay.hpp>
      39             : #include <com/sun/star/chart/XStatisticDisplay.hpp>
      40             : #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
      41             : #include <com/sun/star/chart/ChartSymbolType.hpp>
      42             : #include <com/sun/star/chart/ChartAxisMarks.hpp>
      43             : #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
      44             : #include <com/sun/star/chart/ChartAxisPosition.hpp>
      45             : #include <com/sun/star/chart/ChartSolidType.hpp>
      46             : #include <com/sun/star/chart/DataLabelPlacement.hpp>
      47             : #include <com/sun/star/chart/ErrorBarStyle.hpp>
      48             : 
      49             : #include <com/sun/star/chart2/XChartDocument.hpp>
      50             : #include <com/sun/star/chart2/XDiagram.hpp>
      51             : #include <com/sun/star/chart2/RelativePosition.hpp>
      52             : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
      53             : #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
      54             : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
      55             : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
      56             : #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
      57             : #include <com/sun/star/chart2/DataPointLabel.hpp>
      58             : #include <com/sun/star/chart2/Symbol.hpp>
      59             : #include <com/sun/star/chart2/data/XDataSource.hpp>
      60             : #include <com/sun/star/chart2/data/XDataSink.hpp>
      61             : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
      62             : #include <com/sun/star/chart2/data/XDataProvider.hpp>
      63             : #include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
      64             : #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
      65             : #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
      66             : #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
      67             : 
      68             : #include <com/sun/star/beans/XPropertySet.hpp>
      69             : #include <com/sun/star/beans/XPropertyState.hpp>
      70             : #include <com/sun/star/container/XEnumerationAccess.hpp>
      71             : #include <com/sun/star/drawing/XShape.hpp>
      72             : #include <com/sun/star/drawing/FillStyle.hpp>
      73             : #include <com/sun/star/drawing/BitmapMode.hpp>
      74             : #include <com/sun/star/lang/XServiceName.hpp>
      75             : 
      76             : #include <com/sun/star/table/CellAddress.hpp>
      77             : #include <com/sun/star/sheet/XFormulaParser.hpp>
      78             : #include <com/sun/star/sheet/XFormulaTokens.hpp>
      79             : #include <com/sun/star/sheet/FormulaToken.hpp>
      80             : #include <com/sun/star/sheet/AddressConvention.hpp>
      81             : 
      82             : #include <com/sun/star/text/WritingMode.hpp>
      83             : #include <com/sun/star/container/XNamed.hpp>
      84             : 
      85             : #include <comphelper/processfactory.hxx>
      86             : #include <comphelper/random.hxx>
      87             : #include <xmloff/SchXMLSeriesHelper.hxx>
      88             : #include "ColorPropertySet.hxx"
      89             : #include <set>
      90             : #include <boost/unordered_set.hpp>
      91             : 
      92             : #include <rtl/math.hxx>
      93             : 
      94             : using namespace ::com::sun::star;
      95             : using namespace ::com::sun::star::uno;
      96             : using namespace ::com::sun::star::drawing;
      97             : using namespace ::oox::core;
      98             : using ::com::sun::star::beans::PropertyState;
      99             : using ::com::sun::star::beans::PropertyValue;
     100             : using ::com::sun::star::beans::XPropertySet;
     101             : using ::com::sun::star::beans::XPropertyState;
     102             : using ::com::sun::star::container::XEnumeration;
     103             : using ::com::sun::star::container::XEnumerationAccess;
     104             : using ::com::sun::star::container::XIndexAccess;
     105             : using ::com::sun::star::container::XNamed;
     106             : using ::com::sun::star::io::XOutputStream;
     107             : using ::com::sun::star::table::CellAddress;
     108             : using ::com::sun::star::sheet::XFormulaParser;
     109             : using ::com::sun::star::sheet::XFormulaTokens;
     110             : using ::oox::core::XmlFilterBase;
     111             : using ::sax_fastparser::FSHelperPtr;
     112             : 
     113             : namespace cssc = com::sun::star::chart;
     114             : 
     115             : namespace oox { namespace drawingml {
     116             : 
     117        1038 : class lcl_MatchesRole : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool >
     118             : {
     119             : public:
     120         190 :     explicit lcl_MatchesRole( const OUString & aRole ) :
     121         190 :             m_aRole( aRole )
     122         190 :     {}
     123             : 
     124         424 :     bool operator () ( const Reference< chart2::data::XLabeledDataSequence > & xSeq ) const
     125             :     {
     126         424 :         if( !xSeq.is() )
     127           0 :             return  false;
     128         424 :         Reference< beans::XPropertySet > xProp( xSeq->getValues(), uno::UNO_QUERY );
     129         848 :         OUString aRole;
     130             : 
     131        1272 :         return ( xProp.is() &&
     132         424 :                  (xProp->getPropertyValue(
     133        2968 :                      OUString(  "Role" ) ) >>= aRole ) &&
     134        1272 :                  m_aRole.equals( aRole ));
     135             :     }
     136             : 
     137             : private:
     138             :     OUString m_aRole;
     139             : };
     140             : 
     141             : template< typename T >
     142         188 :     void lcl_SequenceToVectorAppend( const Sequence< T > & rSource, ::std::vector< T > & rDestination )
     143             : {
     144         188 :     rDestination.reserve( rDestination.size() + rSource.getLength());
     145         376 :     ::std::copy( rSource.getConstArray(), rSource.getConstArray() + rSource.getLength(),
     146         376 :                  ::std::back_inserter( rDestination ));
     147         188 : }
     148             : 
     149         156 : Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const Reference< chart2::XDiagram > & xDiagram )
     150             : {
     151         156 :     Reference< chart2::data::XLabeledDataSequence >  xResult;
     152             :     try
     153             :     {
     154             :         Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
     155         156 :             xDiagram, uno::UNO_QUERY_THROW );
     156             :         Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
     157         312 :             xCooSysCnt->getCoordinateSystems());
     158         312 :         for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
     159             :         {
     160         156 :             Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[i] );
     161             :             OSL_ASSERT( xCooSys.is());
     162         676 :             for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
     163             :             {
     164         364 :                 const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
     165         596 :                 for(sal_Int32 nI=0; nI<=nMaxAxisIndex; ++nI)
     166             :                 {
     167         376 :                     Reference< chart2::XAxis > xAxis = xCooSys->getAxisByDimension( nN, nI );
     168             :                     OSL_ASSERT( xAxis.is());
     169         376 :                     if( xAxis.is())
     170             :                     {
     171         376 :                         chart2::ScaleData aScaleData = xAxis->getScaleData();
     172         376 :                         if( aScaleData.Categories.is())
     173             :                         {
     174         144 :                             xResult.set( aScaleData.Categories );
     175         144 :                             break;
     176         232 :                         }
     177             :                     }
     178         232 :                 }
     179             :             }
     180         312 :         }
     181             :     }
     182           0 :     catch( const uno::Exception & ex )
     183             :     {
     184             :         (void)ex; // avoid warning for pro build
     185             :         OSL_FAIL( OUStringToOString(
     186             :                         OUString(  "Exception caught. Type: " ) +
     187             :                         OUString::createFromAscii( typeid( ex ).name()) +
     188             :                         OUString(  ", Message: " ) +
     189             :                         ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
     190             :     }
     191             : 
     192         156 :     return xResult;
     193             : }
     194             : 
     195          84 : Reference< chart2::data::XDataSource > lcl_createDataSource(
     196             :     const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aData )
     197             : {
     198             :     Reference< uno::XComponentContext > xContext(
     199          84 :         comphelper::getProcessComponentContext() );
     200             :     Reference< chart2::data::XDataSink > xSink(
     201         168 :         xContext->getServiceManager()->createInstanceWithContext(
     202          84 :             "com.sun.star.chart2.data.DataSource", xContext ),
     203         168 :         uno::UNO_QUERY_THROW );
     204          84 :     if( xSink.is())
     205          84 :         xSink->setData( aData );
     206             : 
     207         168 :     return Reference< chart2::data::XDataSource >( xSink, uno::UNO_QUERY );
     208             : }
     209             : 
     210          84 : Sequence< Reference< chart2::data::XLabeledDataSequence > > lcl_getAllSeriesSequences( const Reference< chart2::XChartDocument >& xChartDoc )
     211             : {
     212          84 :     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aContainer;
     213          84 :     if( xChartDoc.is() )
     214             :     {
     215          84 :         Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
     216         168 :         ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( SchXMLSeriesHelper::getDataSeriesFromDiagram( xDiagram ));
     217         816 :         for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aSeriesIt( aSeriesVector.begin() )
     218         544 :             ; aSeriesIt != aSeriesVector.end(); ++aSeriesIt )
     219             :         {
     220         188 :             Reference< chart2::data::XDataSource > xDataSource( *aSeriesIt, uno::UNO_QUERY );
     221         188 :             if( !xDataSource.is() )
     222           0 :                 continue;
     223         376 :             uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > aDataSequences( xDataSource->getDataSequences() );
     224         188 :             lcl_SequenceToVectorAppend( aDataSequences, aContainer );
     225         272 :         }
     226             :     }
     227             : 
     228          84 :     Sequence< Reference< chart2::data::XLabeledDataSequence > > aRet( aContainer.size());
     229          84 :     ::std::copy( aContainer.begin(), aContainer.end(), aRet.getArray());
     230             : 
     231          84 :     return aRet;
     232             : }
     233             : 
     234             : Reference< chart2::data::XLabeledDataSequence >
     235         106 :     lcl_getDataSequenceByRole(
     236             :         const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aLabeledSeq,
     237             :         const OUString & rRole )
     238             : {
     239         106 :     Reference< chart2::data::XLabeledDataSequence > aNoResult;
     240             : 
     241         106 :     const Reference< chart2::data::XLabeledDataSequence > * pBegin = aLabeledSeq.getConstArray();
     242         106 :     const Reference< chart2::data::XLabeledDataSequence > * pEnd = pBegin + aLabeledSeq.getLength();
     243             :     const Reference< chart2::data::XLabeledDataSequence > * pMatch =
     244         106 :         ::std::find_if( pBegin, pEnd, lcl_MatchesRole( rRole ));
     245             : 
     246         106 :     if( pMatch != pEnd )
     247          32 :         return *pMatch;
     248             : 
     249          74 :     return aNoResult;
     250             : }
     251             : 
     252          84 : Reference< chart2::data::XDataSource > lcl_pressUsedDataIntoRectangularFormat( const Reference< chart2::XChartDocument >& xChartDoc, bool& rOutSourceHasCategoryLabels )
     253             : {
     254          84 :     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aLabeledSeqVector;
     255             : 
     256             :     //categories are always the first sequence
     257         168 :     Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
     258         168 :     Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xDiagram ) );
     259          84 :     if( xCategories.is() )
     260          72 :         aLabeledSeqVector.push_back( xCategories );
     261          84 :     rOutSourceHasCategoryLabels = xCategories.is();
     262             : 
     263             :     Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeriesSeqVector(
     264         168 :             lcl_getAllSeriesSequences( xChartDoc ) );
     265             : 
     266             :     //the first x-values is always the next sequence //todo ... other x-values get lost for old format
     267             :     Reference< chart2::data::XLabeledDataSequence > xXValues(
     268         168 :         lcl_getDataSequenceByRole( aSeriesSeqVector, OUString("values-x") ) );
     269          84 :     if( xXValues.is() )
     270          10 :         aLabeledSeqVector.push_back( xXValues );
     271             : 
     272             :     //add all other sequences now without x-values
     273         168 :     lcl_MatchesRole aHasXValues( OUString("values-x") );
     274         288 :     for( sal_Int32 nN=0; nN<aSeriesSeqVector.getLength(); nN++ )
     275             :     {
     276         204 :         if( !aHasXValues( aSeriesSeqVector[nN] ) )
     277         190 :             aLabeledSeqVector.push_back( aSeriesSeqVector[nN] );
     278             :     }
     279             : 
     280         168 :     Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( aLabeledSeqVector.size() );
     281          84 :     ::std::copy( aLabeledSeqVector.begin(), aLabeledSeqVector.end(), aSeq.getArray() );
     282             : 
     283         168 :     return lcl_createDataSource( aSeq );
     284             : }
     285             : 
     286           2 : bool lcl_isSeriesAttachedToFirstAxis(
     287             :     const Reference< chart2::XDataSeries > & xDataSeries )
     288             : {
     289           2 :     bool bResult=true;
     290             : 
     291             :     try
     292             :     {
     293           2 :         sal_Int32 nAxisIndex = 0;
     294           2 :         Reference< beans::XPropertySet > xProp( xDataSeries, uno::UNO_QUERY_THROW );
     295           2 :         if( xProp.is() )
     296           2 :             xProp->getPropertyValue("AttachedAxisIndex") >>= nAxisIndex;
     297           2 :         bResult = (0==nAxisIndex);
     298             :     }
     299           0 :     catch( const uno::Exception & ex )
     300             :     {
     301             :         (void)ex; // avoid warning for pro build
     302             :         OSL_FAIL( OUStringToOString(
     303             :                         OUString(  "Exception caught. Type: " ) +
     304             :                         OUString::createFromAscii( typeid( ex ).name()) +
     305             :                         OUString(  ", Message: " ) +
     306             :                         ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
     307             :     }
     308             : 
     309           2 :     return bResult;
     310             : }
     311             : 
     312         190 : OUString lcl_flattenStringSequence( const Sequence< OUString > & rSequence )
     313             : {
     314         190 :     OUStringBuffer aResult;
     315         190 :     bool bPrecedeWithSpace = false;
     316         380 :     for( sal_Int32 nIndex=0; nIndex<rSequence.getLength(); ++nIndex )
     317             :     {
     318         190 :         if( !rSequence[nIndex].isEmpty())
     319             :         {
     320         188 :             if( bPrecedeWithSpace )
     321           0 :                 aResult.append( ' ' );
     322         188 :             aResult.append( rSequence[nIndex] );
     323         188 :             bPrecedeWithSpace = true;
     324             :         }
     325             :     }
     326         190 :     return aResult.makeStringAndClear();
     327             : }
     328             : 
     329         190 : OUString lcl_getLabelString( const Reference< chart2::data::XDataSequence > & xLabelSeq )
     330             : {
     331         190 :     Sequence< OUString > aLabels;
     332             : 
     333         380 :     uno::Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xLabelSeq, uno::UNO_QUERY );
     334         190 :     if( xTextualDataSequence.is())
     335             :     {
     336         190 :         aLabels = xTextualDataSequence->getTextualData();
     337             :     }
     338           0 :     else if( xLabelSeq.is())
     339             :     {
     340           0 :         Sequence< uno::Any > aAnies( xLabelSeq->getData());
     341           0 :         aLabels.realloc( aAnies.getLength());
     342           0 :         for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
     343           0 :             aAnies[i] >>= aLabels[i];
     344             :     }
     345             : 
     346         380 :     return lcl_flattenStringSequence( aLabels );
     347             : }
     348             : 
     349         164 : void lcl_fillCategoriesIntoStringVector(
     350             :     const Reference< chart2::data::XDataSequence > & xCategories,
     351             :     ::std::vector< OUString > & rOutCategories )
     352             : {
     353             :     OSL_ASSERT( xCategories.is());
     354         164 :     if( !xCategories.is())
     355         164 :         return;
     356         164 :     Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xCategories, uno::UNO_QUERY );
     357         164 :     if( xTextualDataSequence.is())
     358             :     {
     359         164 :         rOutCategories.clear();
     360         164 :         Sequence< OUString > aTextData( xTextualDataSequence->getTextualData());
     361         164 :         ::std::copy( aTextData.getConstArray(), aTextData.getConstArray() + aTextData.getLength(),
     362         328 :                      ::std::back_inserter( rOutCategories ));
     363             :     }
     364             :     else
     365             :     {
     366           0 :         Sequence< uno::Any > aAnies( xCategories->getData());
     367           0 :         rOutCategories.resize( aAnies.getLength());
     368           0 :         for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
     369           0 :             aAnies[i] >>= rOutCategories[i];
     370         164 :     }
     371             : }
     372             : 
     373         204 : ::std::vector< double > lcl_getAllValuesFromSequence( const Reference< chart2::data::XDataSequence > & xSeq )
     374             : {
     375         204 :     double fNan = 0.0;
     376         204 :     ::rtl::math::setNan( &fNan );
     377         204 :     ::std::vector< double > aResult;
     378             : 
     379         408 :     Reference< chart2::data::XNumericalDataSequence > xNumSeq( xSeq, uno::UNO_QUERY );
     380         204 :     if( xNumSeq.is())
     381             :     {
     382         204 :         Sequence< double > aValues( xNumSeq->getNumericalData());
     383         204 :         ::std::copy( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(),
     384         408 :                      ::std::back_inserter( aResult ));
     385             :     }
     386           0 :     else if( xSeq.is())
     387             :     {
     388           0 :         Sequence< uno::Any > aAnies( xSeq->getData());
     389           0 :         aResult.resize( aAnies.getLength(), fNan );
     390           0 :         for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
     391           0 :             aAnies[i] >>= aResult[i];
     392             :     }
     393         408 :     return aResult;
     394             : }
     395             : 
     396         472 : sal_Int32 lcl_getChartType( const OUString& sChartType )
     397             : {
     398         472 :     chart::TypeId eChartTypeId = chart::TYPEID_UNKNOWN;
     399         944 :     if( sChartType == "com.sun.star.chart.BarDiagram"
     400         472 :         || sChartType == "com.sun.star.chart2.ColumnChartType" )
     401         290 :         eChartTypeId = chart::TYPEID_BAR;
     402         364 :     else if( sChartType == "com.sun.star.chart.AreaDiagram"
     403         182 :              || sChartType == "com.sun.star.chart2.AreaChartType" )
     404          18 :         eChartTypeId = chart::TYPEID_AREA;
     405         328 :     else if( sChartType == "com.sun.star.chart.LineDiagram"
     406         164 :              || sChartType == "com.sun.star.chart2.LineChartType" )
     407          52 :         eChartTypeId = chart::TYPEID_LINE;
     408         224 :     else if( sChartType == "com.sun.star.chart.PieDiagram"
     409         112 :              || sChartType == "com.sun.star.chart2.PieChartType" )
     410          52 :         eChartTypeId = chart::TYPEID_PIE;
     411         120 :     else if( sChartType == "com.sun.star.chart.DonutDiagram"
     412          60 :              || sChartType == "com.sun.star.chart2.DonutChartType" )
     413           8 :         eChartTypeId = chart::TYPEID_DOUGHNUT;
     414         104 :     else if( sChartType == "com.sun.star.chart.XYDiagram"
     415          52 :              || sChartType == "com.sun.star.chart2.ScatterChartType" )
     416          30 :         eChartTypeId = chart::TYPEID_SCATTER;
     417          44 :     else if( sChartType == "com.sun.star.chart.NetDiagram"
     418          22 :              || sChartType == "com.sun.star.chart2.NetChartType" )
     419           0 :         eChartTypeId = chart::TYPEID_RADARLINE;
     420          44 :     else if( sChartType == "com.sun.star.chart.FilledNetDiagram"
     421          22 :              || sChartType == "com.sun.star.chart2.FilledNetChartType" )
     422          12 :         eChartTypeId = chart::TYPEID_RADARAREA;
     423          20 :     else if( sChartType == "com.sun.star.chart.StockDiagram"
     424          10 :              || sChartType == "com.sun.star.chart2.CandleStickChartType" )
     425          10 :         eChartTypeId = chart::TYPEID_STOCK;
     426           0 :     else if( sChartType == "com.sun.star.chart.BubbleDiagram"
     427           0 :              || sChartType == "com.sun.star.chart2.BubbleChartType" )
     428           0 :         eChartTypeId = chart::TYPEID_BUBBLE;
     429             : 
     430         472 :     return eChartTypeId;
     431             : }
     432             : 
     433         156 : sal_Int32 lcl_generateRandomValue()
     434             : {
     435         156 :     return comphelper::rng::uniform_int_distribution(0, 100000000-1);
     436             : }
     437             : 
     438          84 : ChartExport::ChartExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, Reference< frame::XModel >& xModel, XmlFilterBase* pFB, DocumentType eDocumentType )
     439             :     : DrawingML( pFS, pFB, eDocumentType )
     440             :     , mnXmlNamespace( nXmlNamespace )
     441             :     , mnSeriesCount(0)
     442             :     , mxChartModel( xModel )
     443             :     , mbHasCategoryLabels( false )
     444             :     , mbHasZAxis( false )
     445             :     , mbIs3DChart( false )
     446             :     , mbStacked(false)
     447             :     , mbPercent(false)
     448          84 :     , mbClustered(false)
     449             : {
     450          84 : }
     451             : 
     452          12 : sal_Int32 ChartExport::GetChartID( )
     453             : {
     454          12 :     sal_Int32 nID = GetFB()->GetUniqueId();
     455          12 :     return nID;
     456             : }
     457             : 
     458         288 : sal_Int32 ChartExport::getChartType( )
     459             : {
     460         288 :     OUString sChartType = mxDiagram->getDiagramType();
     461         288 :     return lcl_getChartType( sChartType );
     462             : }
     463             : 
     464         558 : OUString ChartExport::parseFormula( const OUString& rRange )
     465             : {
     466         558 :     OUString aResult;
     467        1116 :     Reference< XFormulaParser > xParser;
     468        1116 :     uno::Reference< lang::XMultiServiceFactory > xSF( GetFB()->getModelFactory(), uno::UNO_QUERY );
     469         558 :     if( xSF.is() )
     470             :     {
     471             :         try
     472             :         {
     473         558 :             xParser.set( xSF->createInstance("com.sun.star.sheet.FormulaParser"), UNO_QUERY );
     474             :         }
     475         516 :         catch( Exception& )
     476             :         {
     477             :         }
     478             :     }
     479         558 :     if( xParser.is() )
     480             :     {
     481             :         OSL_TRACE("ChartExport::parseFormula, parser is valid");
     482          42 :         Reference< XPropertySet > xParserProps( xParser, uno::UNO_QUERY );
     483          42 :         if( xParserProps.is() )
     484             :         {
     485          42 :             xParserProps->setPropertyValue("FormulaConvention", uno::makeAny(::com::sun::star::sheet::AddressConvention::OOO) );
     486             :         }
     487          84 :         uno::Sequence<sheet::FormulaToken> aTokens = xParser->parseFormula( rRange, CellAddress( 0, 0, 0 ) );
     488          42 :         if( xParserProps.is() )
     489             :         {
     490          42 :             xParserProps->setPropertyValue("FormulaConvention", uno::makeAny(::com::sun::star::sheet::AddressConvention::XL_OOX) );
     491             :         }
     492          84 :         aResult = xParser->printFormula( aTokens, CellAddress( 0, 0, 0 ) );
     493             :     }
     494             :     else
     495             :     {
     496             :         OSL_TRACE("ChartExport::parseFormula, parser is invalid");
     497             :         //FIXME: currently just using simple converter, e.g $Sheet1.$A$1:$C$1 -> Sheet1!$A$1:$C$1
     498         516 :         OUString aRange( rRange );
     499         516 :         if( aRange.startsWith("$") )
     500           0 :             aRange = aRange.copy(1);
     501         516 :         aRange = aRange.replaceAll(".$", "!$" );
     502         516 :         aResult = aRange;
     503             :     }
     504             : 
     505             :     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());
     506        1116 :     return aResult;
     507             : }
     508             : 
     509          12 : ChartExport& ChartExport::WriteChartObj( const Reference< XShape >& xShape, sal_Int32 nChartCount )
     510             : {
     511             :     OSL_TRACE("ChartExport::WriteChartObj -- writer chart object");
     512          12 :     FSHelperPtr pFS = GetFS();
     513             : 
     514          12 :     pFS->startElementNS( mnXmlNamespace, XML_graphicFrame, FSEND );
     515             : 
     516          12 :     pFS->startElementNS( mnXmlNamespace, XML_nvGraphicFramePr, FSEND );
     517             : 
     518             :     // TODO: get the correct chart name chart id
     519          24 :     OUString sName = "Object 1";
     520          24 :     Reference< XNamed > xNamed( xShape, UNO_QUERY );
     521          12 :     if (xNamed.is())
     522          12 :         sName = xNamed->getName();
     523             : 
     524          12 :     sal_Int32 nID = GetChartID();
     525             : 
     526             :     pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
     527             :                           XML_id,     I32S( nID ),
     528             :                           XML_name,   USS( sName ),
     529          12 :                           FSEND );
     530             : 
     531             :     pFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr,
     532          12 :                           FSEND );
     533             : 
     534          12 :     if( GetDocumentType() == DOCUMENT_PPTX )
     535             :         pFS->singleElementNS( mnXmlNamespace, XML_nvPr,
     536           0 :                           FSEND );
     537          12 :     pFS->endElementNS( mnXmlNamespace, XML_nvGraphicFramePr );
     538             : 
     539             :     // visual chart properties
     540          12 :     WriteShapeTransformation( xShape, mnXmlNamespace );
     541             : 
     542             :     // writer chart object
     543          12 :     pFS->startElement( FSNS( XML_a, XML_graphic ), FSEND );
     544             :     pFS->startElement( FSNS( XML_a, XML_graphicData ),
     545             :                        XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/chart",
     546          12 :                        FSEND );
     547          24 :     OUString sId;
     548          12 :     const char* sFullPath = NULL;
     549          12 :     const char* sRelativePath = NULL;
     550          12 :     switch( GetDocumentType() )
     551             :     {
     552             :         case DOCUMENT_DOCX:
     553             :         {
     554           0 :             sFullPath = "word/charts/chart";
     555           0 :             sRelativePath = "charts/chart";
     556           0 :             break;
     557             :         }
     558             :         case DOCUMENT_PPTX:
     559             :         {
     560           0 :             sFullPath = "ppt/charts/chart";
     561           0 :             sRelativePath = "../charts/chart";
     562           0 :             break;
     563             :         }
     564             :         case DOCUMENT_XLSX:
     565             :         {
     566          12 :             sFullPath = "xl/charts/chart";
     567          12 :             sRelativePath = "../charts/chart";
     568          12 :             break;
     569             :         }
     570             :         default:
     571             :         {
     572           0 :             sFullPath = "charts/chart";
     573           0 :             sRelativePath = "charts/chart";
     574           0 :             break;
     575             :         }
     576             :     }
     577             :     OUString sFullStream = OUStringBuffer()
     578          24 :                             .appendAscii(sFullPath)
     579          12 :                             .append(nChartCount)
     580          12 :                             .appendAscii( ".xml" )
     581          12 :                             .makeStringAndClear();
     582             :     OUString sRelativeStream = OUStringBuffer()
     583          24 :                             .appendAscii(sRelativePath)
     584          12 :                             .append(nChartCount)
     585          12 :                             .appendAscii( ".xml" )
     586          24 :                             .makeStringAndClear();
     587             :     FSHelperPtr pChart = CreateOutputStream(
     588             :             sFullStream,
     589             :             sRelativeStream,
     590             :             pFS->getOutputStream(),
     591             :             "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
     592             :             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
     593          24 :             &sId );
     594             : 
     595             :     pFS->singleElement(  FSNS( XML_c, XML_chart ),
     596             :             FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
     597             :             FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
     598             :             FSNS( XML_r, XML_id ), USS( sId ),
     599          12 :             FSEND );
     600             : 
     601          12 :     pFS->endElement( FSNS( XML_a, XML_graphicData ) );
     602          12 :     pFS->endElement( FSNS( XML_a, XML_graphic ) );
     603          12 :     pFS->endElementNS( mnXmlNamespace, XML_graphicFrame );
     604             : 
     605          12 :     SetFS( pChart );
     606          12 :     ExportContent();
     607             : 
     608          36 :     return *this;
     609             : }
     610             : 
     611          84 : void ChartExport::InitRangeSegmentationProperties( const Reference< chart2::XChartDocument > & xChartDoc )
     612             : {
     613          84 :     if( xChartDoc.is())
     614             :         try
     615             :         {
     616          84 :             Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
     617             :             OSL_ENSURE( xDataProvider.is(), "No DataProvider" );
     618          84 :             if( xDataProvider.is())
     619             :             {
     620          84 :                 Reference< chart2::data::XDataSource > xDataSource( lcl_pressUsedDataIntoRectangularFormat( xChartDoc, mbHasCategoryLabels ));
     621         168 :                 Sequence< beans::PropertyValue > aArgs( xDataProvider->detectArguments( xDataSource ));
     622         168 :                 OUString sCellRange, sBrokenRange;
     623          84 :                 bool bBrokenRangeAvailable = false;
     624         432 :                 for( sal_Int32 i=0; i<aArgs.getLength(); ++i )
     625             :                 {
     626         348 :                     if ( aArgs[i].Name == "CellRangeRepresentation" )
     627          84 :                         aArgs[i].Value >>= sCellRange;
     628         264 :                     else if ( aArgs[i].Name == "BrokenCellRangeForExport" )
     629             :                     {
     630           0 :                         if( aArgs[i].Value >>= sBrokenRange )
     631           0 :                             bBrokenRangeAvailable = true;
     632             :                     }
     633         264 :                     else if ( aArgs[i].Name == "SequenceMapping" )
     634           0 :                         aArgs[i].Value >>= maSequenceMapping;
     635             :                 }
     636             : 
     637             :                 // #i79009# For Writer we have to export a broken version of the
     638             :                 // range, where every row number is noe too large, so that older
     639             :                 // version can correctly read those files.
     640          84 :                 msChartAddress = (bBrokenRangeAvailable ? sBrokenRange : sCellRange);
     641          84 :                 if( !msChartAddress.isEmpty() )
     642             :                 {
     643             :                     // convert format to XML-conform one
     644          84 :                     Reference< chart2::data::XRangeXMLConversion > xConversion( xDataProvider, uno::UNO_QUERY );
     645          84 :                     if( xConversion.is())
     646          84 :                         msChartAddress = xConversion->convertRangeToXML( msChartAddress );
     647          84 :                 }
     648          84 :             }
     649             :         }
     650           0 :         catch( const uno::Exception & ex )
     651             :         {
     652             :             (void)ex; // avoid warning for pro build
     653             :             OSL_FAIL( OUStringToOString(
     654             :                             OUString(  "Exception caught. Type: " ) +
     655             :                             OUString::createFromAscii( typeid( ex ).name()) +
     656             :                             OUString(  ", Message: " ) +
     657             :                             ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
     658             :         }
     659          84 : }
     660             : 
     661          84 : void ChartExport::ExportContent()
     662             : {
     663          84 :     Reference< chart2::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
     664             :     OSL_ASSERT( xChartDoc.is() );
     665          84 :     if( !xChartDoc.is() )
     666          84 :         return;
     667          84 :     InitRangeSegmentationProperties( xChartDoc );
     668             :     // TODO: export chart
     669          84 :     _ExportContent( );
     670             : }
     671             : 
     672          84 : void ChartExport::_ExportContent()
     673             : {
     674          84 :     Reference< ::com::sun::star::chart::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
     675          84 :     if( xChartDoc.is())
     676             :     {
     677             :         // determine if data comes from the outside
     678          84 :         bool bIncludeTable = true;
     679             : 
     680          84 :         Reference< chart2::XChartDocument > xNewDoc( xChartDoc, uno::UNO_QUERY );
     681          84 :         if( xNewDoc.is())
     682             :         {
     683             :             // check if we have own data.  If so we must not export the complete
     684             :             // range string, as this is our only indicator for having own or
     685             :             // external data. @todo: fix this in the file format!
     686          84 :             Reference< lang::XServiceInfo > xDPServiceInfo( xNewDoc->getDataProvider(), uno::UNO_QUERY );
     687          84 :             if( ! (xDPServiceInfo.is() && xDPServiceInfo->getImplementationName() == "com.sun.star.comp.chart.InternalDataProvider" ))
     688             :             {
     689          12 :                 bIncludeTable = false;
     690          84 :             }
     691             :         }
     692             :         else
     693             :         {
     694           0 :             Reference< lang::XServiceInfo > xServ( xChartDoc, uno::UNO_QUERY );
     695           0 :             if( xServ.is())
     696             :             {
     697           0 :                 if( xServ->supportsService(
     698           0 :                         OUString("com.sun.star.chart.ChartTableAddressSupplier")))
     699             :                 {
     700           0 :                     Reference< beans::XPropertySet > xProp( xServ, uno::UNO_QUERY );
     701           0 :                     if( xProp.is())
     702             :                     {
     703           0 :                         Any aAny;
     704             :                         try
     705             :                         {
     706           0 :                             OUString sChartAddress;
     707           0 :                             aAny = xProp->getPropertyValue(
     708           0 :                                 OUString("ChartRangeAddress"));
     709           0 :                             aAny >>= msChartAddress;
     710             :                             //maExportHelper.SetChartRangeAddress( sChartAddress );
     711             : 
     712             :                             //maExportHelper.SetTableNumberList( sTableNumberList );
     713             : 
     714             :                             // do not include own table if there are external addresses
     715           0 :                             bIncludeTable = sChartAddress.isEmpty();
     716             :                         }
     717           0 :                         catch( beans::UnknownPropertyException & )
     718             :                         {
     719             :                             OSL_FAIL( "Property ChartRangeAddress not supported by ChartDocument" );
     720           0 :                         }
     721           0 :                     }
     722             :                 }
     723           0 :             }
     724             :         }
     725          84 :         exportChartSpace( xChartDoc, bIncludeTable );
     726             :     }
     727             :     else
     728             :     {
     729             :         OSL_FAIL( "Couldn't export chart due to wrong XModel" );
     730          84 :     }
     731          84 : }
     732             : 
     733          84 : void ChartExport::exportChartSpace( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc,
     734             :                                       bool bIncludeTable )
     735             : {
     736          84 :     FSHelperPtr pFS = GetFS();
     737             :     pFS->startElement( FSNS( XML_c, XML_chartSpace ),
     738             :             FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
     739             :             FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
     740             :             FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
     741          84 :             FSEND );
     742             :     // TODO: get the correct editing lanauge
     743             :     pFS->singleElement( FSNS( XML_c, XML_lang ),
     744             :             XML_val, "en-US",
     745          84 :             FSEND );
     746             : 
     747          84 :     if( !bIncludeTable )
     748             :     {
     749             :         // TODO:external data
     750             :     }
     751             :     //XML_chart
     752          84 :     exportChart(rChartDoc);
     753             : 
     754             :     // TODO: printSettings
     755             :     // TODO: style
     756             :     // TODO: text properties
     757             :     // TODO: shape properties
     758         168 :     Reference< XPropertySet > xPropSet( rChartDoc->getArea(), uno::UNO_QUERY );
     759          84 :     if( xPropSet.is() )
     760          84 :         exportShapeProps( xPropSet );
     761             : 
     762             :     //XML_externalData
     763          84 :     exportExternalData(rChartDoc);
     764             : 
     765         168 :     pFS->endElement( FSNS( XML_c, XML_chartSpace ) );
     766          84 : }
     767             : 
     768          84 : void ChartExport::exportExternalData( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc )
     769             : {
     770             :     // Embedded external data is grab bagged for docx file hence adding export part of
     771             :     // external data for docx files only.
     772          84 :     if(GetDocumentType() != DOCUMENT_DOCX)
     773          96 :         return;
     774             : 
     775          72 :     OUString externalDataPath;
     776         144 :     Reference< beans::XPropertySet > xDocPropSet( rChartDoc->getDiagram(), uno::UNO_QUERY );
     777          72 :     if( xDocPropSet.is())
     778             :     {
     779             :         try
     780             :         {
     781          72 :             Any aAny( xDocPropSet->getPropertyValue(
     782          72 :                 OUString(  "ExternalData" )));
     783          72 :             aAny >>= externalDataPath;
     784             :         }
     785           0 :         catch( beans::UnknownPropertyException & )
     786             :         {
     787             :             DBG_WARNING( "Required property not found in ChartDocument" );
     788             :         }
     789             :     }
     790          72 :     if(!externalDataPath.isEmpty())
     791             :     {
     792             :         // Here adding external data entry to relationship.
     793          68 :         OUString relationPath = externalDataPath;
     794             :         // Converting absolute path to relative path.
     795          68 :         if( externalDataPath[ 0 ] != '.' && externalDataPath[ 1 ] != '.')
     796             :         {
     797          68 :             sal_Int32 nStartPos = 0;
     798          68 :             sal_Int32 nSepPos = externalDataPath.indexOf( '/', nStartPos );
     799          68 :             if( nSepPos > 0)
     800             :             {
     801          68 :                 relationPath = relationPath.copy( nSepPos,  ::std::max< sal_Int32 >( externalDataPath.getLength(), 0 ) -  nSepPos );
     802          68 :                 relationPath = OUStringBuffer( ".." ).append( relationPath ).makeStringAndClear();
     803             :             }
     804             :         }
     805         136 :         FSHelperPtr pFS = GetFS();
     806         136 :         OUString type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package";
     807          68 :         if (relationPath.endsWith(OUString(".bin")))
     808           0 :             type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject";
     809             : 
     810             :         OUString sRelId = GetFB()->addRelation(pFS->getOutputStream(),
     811             :                         type,
     812         136 :                         relationPath);
     813             :         pFS->singleElementNS( XML_c, XML_externalData,
     814             :                 FSNS(XML_r, XML_id), OUStringToOString(sRelId, RTL_TEXTENCODING_UTF8),
     815         136 :                 FSEND);
     816          72 :     }
     817             : }
     818             : 
     819          84 : void ChartExport::exportChart( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc )
     820             : {
     821          84 :     Reference< chart2::XChartDocument > xNewDoc( rChartDoc, uno::UNO_QUERY );
     822          84 :     mxDiagram.set( rChartDoc->getDiagram() );
     823          84 :     if( xNewDoc.is())
     824          84 :         mxNewDiagram.set( xNewDoc->getFirstDiagram());
     825             : 
     826             :     // get Properties of ChartDocument
     827          84 :     bool bHasMainTitle = false;
     828          84 :     bool bHasSubTitle = false;
     829          84 :     bool bHasLegend = false;
     830         168 :     Reference< beans::XPropertySet > xDocPropSet( rChartDoc, uno::UNO_QUERY );
     831          84 :     if( xDocPropSet.is())
     832             :     {
     833             :         try
     834             :         {
     835          84 :             Any aAny( xDocPropSet->getPropertyValue(
     836          84 :                 OUString(  "HasMainTitle" )));
     837          84 :             aAny >>= bHasMainTitle;
     838         252 :             aAny = xDocPropSet->getPropertyValue(
     839         168 :                 OUString(  "HasSubTitle" ));
     840          84 :             aAny >>= bHasSubTitle;
     841         252 :             aAny = xDocPropSet->getPropertyValue(
     842         168 :                 OUString(  "HasLegend" ));
     843          84 :             aAny >>= bHasLegend;
     844             :         }
     845           0 :         catch( beans::UnknownPropertyException & )
     846             :         {
     847             :             DBG_WARNING( "Required property not found in ChartDocument" );
     848             :         }
     849             :     } // if( xDocPropSet.is())
     850             : 
     851             :     // chart element
     852             : 
     853         168 :     FSHelperPtr pFS = GetFS();
     854             :     pFS->startElement( FSNS( XML_c, XML_chart ),
     855          84 :             FSEND );
     856             : 
     857             :     // title
     858          84 :     if( bHasMainTitle )
     859             :     {
     860          18 :         Reference< drawing::XShape > xShape = rChartDoc->getTitle();
     861          18 :         if( xShape.is() )
     862          18 :             exportTitle( xShape );
     863             :     }
     864          84 :     InitPlotArea( );
     865          84 :     if( mbIs3DChart )
     866             :     {
     867          26 :         exportView3D();
     868             : 
     869             :         // floor
     870          26 :         Reference< beans::XPropertySet > xFloor( mxNewDiagram->getFloor(), uno::UNO_QUERY );
     871          26 :         if( xFloor.is() )
     872             :         {
     873             :             pFS->startElement( FSNS( XML_c, XML_floor ),
     874          26 :                 FSEND );
     875          26 :             exportShapeProps( xFloor );
     876          26 :             pFS->endElement( FSNS( XML_c, XML_floor ) );
     877             :         }
     878             : 
     879             :         // sideWall
     880             : 
     881             :         // backWall
     882          52 :         Reference< beans::XPropertySet > xBackWall( mxNewDiagram->getWall(), uno::UNO_QUERY );
     883          26 :         if( xBackWall.is() )
     884             :         {
     885             :             pFS->startElement( FSNS( XML_c, XML_backWall ),
     886          26 :                 FSEND );
     887          26 :             exportShapeProps( xBackWall );
     888          26 :             pFS->endElement( FSNS( XML_c, XML_backWall ) );
     889          26 :         }
     890             : 
     891             :     }
     892             :     // plot area
     893          84 :     exportPlotArea( );
     894             :     // legend
     895          84 :     if( bHasLegend )
     896          72 :         exportLegend( rChartDoc );
     897             :     // only visible cells should be plotted on the chart
     898             :     pFS->singleElement( FSNS( XML_c, XML_plotVisOnly ),
     899             :             XML_val, "1",
     900          84 :             FSEND );
     901             : 
     902         168 :     pFS->endElement( FSNS( XML_c, XML_chart ) );
     903          84 : }
     904             : 
     905          72 : void ChartExport::exportLegend( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc )
     906             : {
     907          72 :     FSHelperPtr pFS = GetFS();
     908             :     pFS->startElement( FSNS( XML_c, XML_legend ),
     909          72 :             FSEND );
     910             : 
     911         144 :     Reference< beans::XPropertySet > xProp( rChartDoc->getLegend(), uno::UNO_QUERY );
     912          72 :     if( xProp.is() )
     913             :     {
     914             :         // position
     915          72 :         ::com::sun::star::chart::ChartLegendPosition aLegendPos = ::com::sun::star::chart::ChartLegendPosition_NONE;
     916             :         try
     917             :         {
     918          72 :             Any aAny( xProp->getPropertyValue(
     919          72 :                 OUString(  "Alignment" )));
     920          72 :                 aAny >>= aLegendPos;
     921             :         }
     922           0 :         catch( beans::UnknownPropertyException & )
     923             :         {
     924             :             DBG_WARNING( "Property Align not found in ChartLegend" );
     925             :         }
     926             : 
     927          72 :         const char* strPos = NULL;
     928          72 :         switch( aLegendPos )
     929             :         {
     930             :             case ::com::sun::star::chart::ChartLegendPosition_LEFT:
     931           2 :                 strPos = "l";
     932           2 :                 break;
     933             :             case ::com::sun::star::chart::ChartLegendPosition_RIGHT:
     934          60 :                 strPos = "r";
     935          60 :                 break;
     936             :             case ::com::sun::star::chart::ChartLegendPosition_TOP:
     937           2 :                 strPos = "t";
     938           2 :                 break;
     939             :             case ::com::sun::star::chart::ChartLegendPosition_BOTTOM:
     940           6 :                 strPos = "b";
     941           6 :                 break;
     942             :             case ::com::sun::star::chart::ChartLegendPosition_NONE:
     943             :             case ::com::sun::star::chart::ChartLegendPosition_MAKE_FIXED_SIZE:
     944             :                 // nothing
     945           2 :                 break;
     946             :         }
     947             : 
     948          72 :         if( strPos != NULL )
     949             :         {
     950             :             pFS->singleElement( FSNS( XML_c, XML_legendPos ),
     951             :                 XML_val, strPos,
     952          70 :                 FSEND );
     953             :             pFS->singleElement( FSNS( XML_c, XML_overlay ),
     954             :                     XML_val, "0",
     955          70 :                     FSEND );
     956             :         }
     957             : 
     958             :         // shape properties
     959          72 :         exportShapeProps( xProp );
     960             :     }
     961             : 
     962             :     // legendEntry
     963             : 
     964         144 :     pFS->endElement( FSNS( XML_c, XML_legend ) );
     965          72 : }
     966             : 
     967          40 : void ChartExport::exportTitle( Reference< XShape > xShape )
     968             : {
     969          40 :     OUString sText;
     970          80 :     Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
     971          40 :     if( xPropSet.is())
     972             :     {
     973          40 :         xPropSet->getPropertyValue("String") >>= sText;
     974             :     }
     975          40 :     if( sText.isEmpty() )
     976          40 :         return;
     977             : 
     978          80 :     FSHelperPtr pFS = GetFS();
     979             :     pFS->startElement( FSNS( XML_c, XML_title ),
     980          40 :             FSEND );
     981             : 
     982             :     pFS->startElement( FSNS( XML_c, XML_tx ),
     983          40 :             FSEND );
     984             :     pFS->startElement( FSNS( XML_c, XML_rich ),
     985          40 :             FSEND );
     986             : 
     987             :     // TODO: bodyPr
     988          40 :     const char* sWritingMode = NULL;
     989          40 :     bool bVertical = false;
     990          40 :     xPropSet->getPropertyValue("StackedText") >>= bVertical;
     991          40 :     if( bVertical )
     992           0 :         sWritingMode = "wordArtVert";
     993             : 
     994             :     pFS->singleElement( FSNS( XML_a, XML_bodyPr ),
     995             :             XML_vert, sWritingMode,
     996          40 :             FSEND );
     997             :     // TODO: lstStyle
     998             :     pFS->singleElement( FSNS( XML_a, XML_lstStyle ),
     999          40 :             FSEND );
    1000             :     // FIXME: handle multipul paragraphs to parse aText
    1001             :     pFS->startElement( FSNS( XML_a, XML_p ),
    1002          40 :             FSEND );
    1003             : 
    1004             :     pFS->startElement( FSNS( XML_a, XML_pPr ),
    1005          40 :             FSEND );
    1006             :     pFS->singleElement( FSNS( XML_a, XML_defRPr ),
    1007          40 :             FSEND );
    1008          40 :     pFS->endElement( FSNS( XML_a, XML_pPr ) );
    1009             : 
    1010             :     pFS->startElement( FSNS( XML_a, XML_r ),
    1011          40 :             FSEND );
    1012          40 :     WriteRunProperties( xPropSet, false );
    1013             :     pFS->startElement( FSNS( XML_a, XML_t ),
    1014          40 :             FSEND );
    1015          40 :     pFS->writeEscaped( sText );
    1016          40 :     pFS->endElement( FSNS( XML_a, XML_t ) );
    1017          40 :     pFS->endElement( FSNS( XML_a, XML_r ) );
    1018             : 
    1019          40 :     pFS->endElement( FSNS( XML_a, XML_p ) );
    1020             : 
    1021          40 :     pFS->endElement( FSNS( XML_c, XML_rich ) );
    1022          40 :     pFS->endElement( FSNS( XML_c, XML_tx ) );
    1023             : 
    1024             :     // TODO:customize layout
    1025             :     pFS->singleElement( FSNS( XML_c, XML_layout ),
    1026          40 :             FSEND );
    1027             : 
    1028          80 :     pFS->endElement( FSNS( XML_c, XML_title ) );
    1029             : }
    1030             : 
    1031          84 : void ChartExport::exportPlotArea( )
    1032             : {
    1033          84 :     Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( mxNewDiagram, uno::UNO_QUERY );
    1034          84 :     if( ! xBCooSysCnt.is())
    1035           0 :         return;
    1036             : 
    1037             :     // plot-area element
    1038             : 
    1039         168 :     FSHelperPtr pFS = GetFS();
    1040             :     pFS->startElement( FSNS( XML_c, XML_plotArea ),
    1041          84 :             FSEND );
    1042             :     // layout
    1043             :     pFS->singleElement( FSNS( XML_c, XML_layout ),
    1044          84 :             FSEND );
    1045             : 
    1046             :     // chart type
    1047             :     Sequence< Reference< chart2::XCoordinateSystem > >
    1048         168 :         aCooSysSeq( xBCooSysCnt->getCoordinateSystems());
    1049         168 :     for( sal_Int32 nCSIdx=0; nCSIdx<aCooSysSeq.getLength(); ++nCSIdx )
    1050             :     {
    1051             : 
    1052          84 :         Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCSIdx], uno::UNO_QUERY );
    1053          84 :         if( ! xCTCnt.is())
    1054           0 :             continue;
    1055          84 :         mnSeriesCount=0;
    1056         168 :         Sequence< Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes());
    1057         176 :         for( sal_Int32 nCTIdx=0; nCTIdx<aCTSeq.getLength(); ++nCTIdx )
    1058             :         {
    1059          92 :             Reference< chart2::XDataSeriesContainer > xDSCnt( aCTSeq[nCTIdx], uno::UNO_QUERY );
    1060          92 :             if( ! xDSCnt.is())
    1061           0 :                 return;
    1062         184 :             Reference< chart2::XChartType > xChartType( aCTSeq[nCTIdx], uno::UNO_QUERY );
    1063          92 :             if( ! xChartType.is())
    1064           0 :                 continue;
    1065             :             // note: if xDSCnt.is() then also aCTSeq[nCTIdx]
    1066         184 :             OUString aChartType( xChartType->getChartType());
    1067          92 :             sal_Int32 eChartType = lcl_getChartType( aChartType );
    1068          92 :             switch( eChartType )
    1069             :             {
    1070             :                 case chart::TYPEID_BAR:
    1071             :                     {
    1072          46 :                         exportBarChart( xChartType );
    1073          46 :                         break;
    1074             :                     }
    1075             :                 case chart::TYPEID_AREA:
    1076             :                     {
    1077           4 :                         exportAreaChart( xChartType );
    1078           4 :                         break;
    1079             :                     }
    1080             :                 case chart::TYPEID_LINE:
    1081             :                     {
    1082          14 :                         exportLineChart( xChartType );
    1083          14 :                         break;
    1084             :                     }
    1085             :                 case chart::TYPEID_BUBBLE:
    1086             :                     {
    1087           0 :                         exportBubbleChart( xChartType );
    1088           0 :                         break;
    1089             :                     }
    1090             :                 case chart::TYPEID_OFPIE:
    1091             :                     {
    1092           0 :                         exportOfPieChart( xChartType );
    1093           0 :                         break;
    1094             :                     }
    1095             :                 case chart::TYPEID_DOUGHNUT:
    1096             :                 case chart::TYPEID_PIE:
    1097             :                     {
    1098          14 :                         exportPieChart( xChartType );
    1099          14 :                         break;
    1100             :                     }
    1101             :                 case chart::TYPEID_RADARLINE:
    1102             :                 case chart::TYPEID_RADARAREA:
    1103             :                     {
    1104           2 :                         exportRadarChart( xChartType );
    1105           2 :                         break;
    1106             :                     }
    1107             :                 case chart::TYPEID_SCATTER:
    1108             :                     {
    1109          10 :                         exportScatterChart( xChartType );
    1110          10 :                         break;
    1111             :                     }
    1112             :                 case chart::TYPEID_STOCK:
    1113             :                     {
    1114           2 :                         exportStockChart( xChartType );
    1115           2 :                         break;
    1116             :                     }
    1117             :                 case chart::TYPEID_SURFACE:
    1118             :                     {
    1119           0 :                         exportSurfaceChart( xChartType );
    1120           0 :                         break;
    1121             :                     }
    1122             :                 default:
    1123             :                     {
    1124             :                         OSL_TRACE("ChartExport::exportPlotArea -- not support chart type");
    1125           0 :                         break;
    1126             :                     }
    1127             :             }
    1128             : 
    1129          92 :         }
    1130          84 :     }
    1131             :     //Axis Data
    1132          84 :     exportAxes( );
    1133             :     // Data Table
    1134          84 :     exportDataTable();
    1135             : 
    1136             :     // shape properties
    1137             :     /*
    1138             :      * Export the Plot area Shape Properties
    1139             :      * eg: Fill and Outline
    1140             :      */
    1141          84 :     Reference< ::com::sun::star::chart::X3DDisplay > xWallFloorSupplier( mxDiagram, uno::UNO_QUERY );
    1142          84 :     if( xWallFloorSupplier.is() )
    1143             :     {
    1144          84 :         Reference< beans::XPropertySet > xWallPropSet( xWallFloorSupplier->getWall(), uno::UNO_QUERY );
    1145          84 :         if( xWallPropSet.is() )
    1146             :         {
    1147          84 :             exportPlotAreaShapeProps( xWallPropSet );
    1148          84 :         }
    1149             :     }
    1150             : 
    1151         168 :     pFS->endElement( FSNS( XML_c, XML_plotArea ) );
    1152             : 
    1153             : }
    1154             : 
    1155          84 : void ChartExport::exportPlotAreaShapeProps( Reference< XPropertySet > xPropSet )
    1156             : {
    1157          84 :     FSHelperPtr pFS = GetFS();
    1158             :     pFS->startElement( FSNS( XML_c, XML_spPr ),
    1159          84 :             FSEND );
    1160             : 
    1161          84 :     exportFill( xPropSet );
    1162          84 :     WriteOutline( xPropSet );
    1163             : 
    1164          84 :     pFS->endElement( FSNS( XML_c, XML_spPr ) );
    1165          84 : }
    1166             : 
    1167          84 : void ChartExport::exportFill( Reference< XPropertySet > xPropSet )
    1168             : {
    1169          84 :     if ( !GetProperty( xPropSet, "FillStyle" ) )
    1170          84 :         return;
    1171          84 :     FillStyle aFillStyle( FillStyle_NONE );
    1172          84 :     xPropSet->getPropertyValue( "FillStyle" ) >>= aFillStyle;
    1173          84 :     switch( aFillStyle )
    1174             :     {
    1175             :         case FillStyle_GRADIENT :
    1176           0 :             exportGradientFill( xPropSet );
    1177           0 :             break;
    1178             :         case FillStyle_BITMAP :
    1179           2 :             exportBitmapFill( xPropSet );
    1180           2 :             break;
    1181             :         default:
    1182          82 :             WriteFill( xPropSet );
    1183             :     }
    1184             : }
    1185             : 
    1186           2 : void ChartExport::exportBitmapFill( Reference< XPropertySet > xPropSet )
    1187             : {
    1188           2 :     if( xPropSet.is() )
    1189             :      {
    1190           2 :         OUString sFillBitmapName;
    1191           2 :         xPropSet->getPropertyValue("FillBitmapName") >>= sFillBitmapName;
    1192             : 
    1193           4 :         uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY );
    1194             :         try
    1195             :         {
    1196           2 :             uno::Reference< container::XNameAccess > xBitmap( xFact->createInstance("com.sun.star.drawing.BitmapTable"), uno::UNO_QUERY );
    1197           4 :             uno::Any rValue = xBitmap->getByName( sFillBitmapName );
    1198           4 :             OUString sBitmapURL;
    1199           2 :             if( (rValue >>= sBitmapURL) )
    1200             :             {
    1201           2 :                 WriteBlipFill( xPropSet, sBitmapURL, XML_a, true, true );
    1202           2 :             }
    1203             :         }
    1204           0 :         catch (const uno::Exception & rEx)
    1205             :         {
    1206             :             SAL_INFO("oox", "ChartExport::exportBitmapFill " << rEx.Message);
    1207           2 :         }
    1208             : 
    1209             :     }
    1210           2 : }
    1211             : 
    1212           0 : void ChartExport::exportGradientFill( Reference< XPropertySet > xPropSet )
    1213             : {
    1214           0 :     if( xPropSet.is() )
    1215             :      {
    1216           0 :         OUString sFillGradientName;
    1217           0 :         xPropSet->getPropertyValue("FillGradientName") >>= sFillGradientName;
    1218             : 
    1219           0 :         awt::Gradient aGradient;
    1220           0 :         uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY );
    1221             :         try
    1222             :         {
    1223           0 :             uno::Reference< container::XNameAccess > xGradient( xFact->createInstance("com.sun.star.drawing.GradientTable"), uno::UNO_QUERY );
    1224           0 :             uno::Any rValue = xGradient->getByName( sFillGradientName );
    1225           0 :             if( (rValue >>= aGradient) )
    1226             :             {
    1227           0 :                 mpFS->startElementNS( XML_a, XML_gradFill, FSEND );
    1228           0 :                 WriteGradientFill( aGradient );
    1229           0 :                 mpFS->endElementNS( XML_a, XML_gradFill );
    1230           0 :             }
    1231             :         }
    1232           0 :         catch (const uno::Exception & rEx)
    1233             :         {
    1234             :             SAL_INFO("oox",
    1235             :                 "ChartExport::exportGradientFill " << rEx.Message);
    1236           0 :         }
    1237             : 
    1238             :     }
    1239           0 : }
    1240             : 
    1241          84 : void ChartExport::exportDataTable( )
    1242             : {
    1243          84 :     FSHelperPtr pFS = GetFS();
    1244         168 :     Reference< beans::XPropertySet > aPropSet( mxDiagram, uno::UNO_QUERY );
    1245             : 
    1246          84 :     bool bShowVBorder = false;
    1247          84 :     bool bShowHBorder = false;
    1248          84 :     bool bShowOutline = false;
    1249             : 
    1250          84 :     if (GetProperty( aPropSet, "DataTableHBorder"))
    1251          84 :         mAny >>= bShowHBorder;
    1252          84 :     if (GetProperty( aPropSet, "DataTableVBorder"))
    1253          84 :         mAny >>= bShowVBorder;
    1254          84 :     if (GetProperty( aPropSet, "DataTableOutline"))
    1255          84 :         mAny >>= bShowOutline;
    1256             : 
    1257          84 :     if (bShowVBorder || bShowHBorder || bShowOutline)
    1258             :     {
    1259             :         pFS->startElement( FSNS( XML_c, XML_dTable),
    1260          12 :                 FSEND );
    1261          12 :         if (bShowHBorder)
    1262             :             pFS->singleElement( FSNS( XML_c, XML_showHorzBorder ),
    1263             :                             XML_val, "1",
    1264          12 :                             FSEND );
    1265          12 :         if (bShowVBorder)
    1266             :             pFS->singleElement( FSNS( XML_c, XML_showVertBorder ),
    1267             :                             XML_val, "1",
    1268          12 :                             FSEND );
    1269          12 :         if (bShowOutline)
    1270             :             pFS->singleElement( FSNS( XML_c, XML_showOutline ),
    1271             :                             XML_val, "1",
    1272          12 :                             FSEND );
    1273             : 
    1274          12 :         pFS->endElement(  FSNS( XML_c, XML_dTable));
    1275          84 :     }
    1276             : 
    1277          84 : }
    1278           4 : void ChartExport::exportAreaChart( Reference< chart2::XChartType > xChartType )
    1279             : {
    1280           4 :     FSHelperPtr pFS = GetFS();
    1281           4 :     sal_Int32 nTypeId = XML_areaChart;
    1282           4 :     if( mbIs3DChart )
    1283           0 :         nTypeId = XML_area3DChart;
    1284             :     pFS->startElement( FSNS( XML_c, nTypeId ),
    1285           4 :             FSEND );
    1286             : 
    1287           4 :     exportGrouping( );
    1288           4 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1289           4 :     exportSeries( xChartType, nAttachedAxis );
    1290           4 :     exportAxesId( nAttachedAxis );
    1291             : 
    1292           4 :     pFS->endElement( FSNS( XML_c, nTypeId ) );
    1293           4 : }
    1294             : 
    1295          46 : void ChartExport::exportBarChart( Reference< chart2::XChartType > xChartType )
    1296             : {
    1297          46 :     sal_Int32 nTypeId = XML_barChart;
    1298          46 :     if( mbIs3DChart )
    1299          22 :         nTypeId = XML_bar3DChart;
    1300          46 :     FSHelperPtr pFS = GetFS();
    1301             :     pFS->startElement( FSNS( XML_c, nTypeId ),
    1302          46 :             FSEND );
    1303             :     // bar direction
    1304          46 :     bool bVertical = false;
    1305          92 :     Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
    1306          46 :     if( GetProperty( xPropSet, "Vertical" ) )
    1307          46 :         mAny >>= bVertical;
    1308             : 
    1309          46 :     const char* bardir = bVertical? "bar":"col";
    1310             :     pFS->singleElement( FSNS( XML_c, XML_barDir ),
    1311             :             XML_val, bardir,
    1312          46 :             FSEND );
    1313             : 
    1314          46 :     exportGrouping( true );
    1315          46 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1316          46 :     exportSeries( xChartType, nAttachedAxis );
    1317             : 
    1318          92 :     Reference< XPropertySet > xTypeProp( xChartType, uno::UNO_QUERY );
    1319             : 
    1320          46 :     if( xTypeProp.is() && GetProperty( xTypeProp, "GapwidthSequence") )
    1321             :     {
    1322          46 :         uno::Sequence< sal_Int32 > aBarPositionSequence;
    1323          46 :         mAny >>= aBarPositionSequence;
    1324          46 :         if( aBarPositionSequence.getLength() )
    1325             :         {
    1326          46 :             sal_Int32 nGapWidth = aBarPositionSequence[0];
    1327             :             pFS->singleElement( FSNS( XML_c, XML_gapWidth ),
    1328             :                 XML_val, I32S( nGapWidth ),
    1329          46 :                 FSEND );
    1330          46 :         }
    1331             :     }
    1332             : 
    1333          46 :     if( mbIs3DChart )
    1334             :     {
    1335             :         // Shape
    1336             :         namespace cssc = ::com::sun::star::chart;
    1337          22 :         sal_Int32 nGeom3d = cssc::ChartSolidType::RECTANGULAR_SOLID;
    1338          22 :         if( xPropSet.is() && GetProperty( xPropSet, "SolidType") )
    1339          22 :             mAny >>= nGeom3d;
    1340          22 :         const char* sShapeType = NULL;
    1341          22 :         switch( nGeom3d )
    1342             :         {
    1343             :             case cssc::ChartSolidType::RECTANGULAR_SOLID:
    1344          10 :                 sShapeType = "box";
    1345          10 :                 break;
    1346             :             case cssc::ChartSolidType::CONE:
    1347           8 :                 sShapeType = "cone";
    1348           8 :                 break;
    1349             :             case cssc::ChartSolidType::CYLINDER:
    1350           4 :                 sShapeType = "cylinder";
    1351           4 :                 break;
    1352             :             case cssc::ChartSolidType::PYRAMID:
    1353           0 :                 sShapeType = "pyramid";
    1354           0 :                 break;
    1355             :         }
    1356             :         pFS->singleElement( FSNS( XML_c, XML_shape ),
    1357             :             XML_val, sShapeType,
    1358          22 :             FSEND );
    1359             :     }
    1360             : 
    1361             :     //overlap
    1362          46 :     if( !mbIs3DChart && xTypeProp.is() && GetProperty( xTypeProp, "OverlapSequence") )
    1363             :     {
    1364          24 :         uno::Sequence< sal_Int32 > aBarPositionSequence;
    1365          24 :         mAny >>= aBarPositionSequence;
    1366          24 :         if( aBarPositionSequence.getLength() )
    1367             :         {
    1368          24 :             sal_Int32 nOverlap = aBarPositionSequence[0];
    1369             :             pFS->singleElement( FSNS( XML_c, XML_overlap ),
    1370             :                     XML_val, I32S( nOverlap ),
    1371          24 :                     FSEND );
    1372          24 :         }
    1373             :     }
    1374             : 
    1375          46 :     exportAxesId( nAttachedAxis );
    1376             : 
    1377          92 :     pFS->endElement( FSNS( XML_c, nTypeId ) );
    1378          46 : }
    1379             : 
    1380           0 : void ChartExport::exportBubbleChart( Reference< chart2::XChartType > xChartType )
    1381             : {
    1382           0 :     FSHelperPtr pFS = GetFS();
    1383             :     pFS->startElement( FSNS( XML_c, XML_bubbleChart ),
    1384           0 :             FSEND );
    1385             : 
    1386           0 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1387           0 :     exportSeries( xChartType, nAttachedAxis );
    1388           0 :     exportAxesId( nAttachedAxis );
    1389             : 
    1390           0 :     pFS->endElement( FSNS( XML_c, XML_bubbleChart ) );
    1391           0 : }
    1392             : 
    1393           4 : void ChartExport::exportDoughnutChart( Reference< chart2::XChartType > xChartType )
    1394             : {
    1395           4 :     FSHelperPtr pFS = GetFS();
    1396             :     pFS->startElement( FSNS( XML_c, XML_doughnutChart ),
    1397           4 :             FSEND );
    1398             : 
    1399           4 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1400           4 :     exportSeries( xChartType, nAttachedAxis );
    1401             :     // firstSliceAng
    1402           4 :     exportFirstSliceAng( );
    1403             :     //FIXME: holeSize
    1404           4 :     sal_Int32 nHoleSize = 50;
    1405             :     pFS->singleElement( FSNS( XML_c, XML_holeSize ),
    1406             :             XML_val, I32S( nHoleSize ),
    1407           4 :             FSEND );
    1408             : 
    1409           4 :     pFS->endElement( FSNS( XML_c, XML_doughnutChart ) );
    1410           4 : }
    1411             : 
    1412          14 : void ChartExport::exportLineChart( Reference< chart2::XChartType > xChartType )
    1413             : {
    1414          14 :     FSHelperPtr pFS = GetFS();
    1415          14 :     sal_Int32 nTypeId = XML_lineChart;
    1416          14 :     if( mbIs3DChart )
    1417           0 :         nTypeId = XML_line3DChart;
    1418             :     pFS->startElement( FSNS( XML_c, nTypeId ),
    1419          14 :             FSEND );
    1420             : 
    1421          14 :     exportGrouping( );
    1422             :     // TODO: show marker symbol in series?
    1423          14 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1424          14 :     exportSeries( xChartType, nAttachedAxis );
    1425             : 
    1426             :     // show marker?
    1427          14 :     sal_Int32 nSymbolType = ::com::sun::star::chart::ChartSymbolType::NONE;
    1428          28 :     Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
    1429          14 :     if( GetProperty( xPropSet, "SymbolType" ) )
    1430          14 :         mAny >>= nSymbolType;
    1431             : 
    1432          14 :     if( !mbIs3DChart )
    1433             :     {
    1434          14 :         exportHiLowLines();
    1435          14 :         exportUpDownBars(xChartType);
    1436          14 :         const char* marker = nSymbolType == ::com::sun::star::chart::ChartSymbolType::NONE? "0":"1";
    1437             :         pFS->singleElement( FSNS( XML_c, XML_marker ),
    1438             :                 XML_val, marker,
    1439          14 :                 FSEND );
    1440             :     }
    1441             : 
    1442          14 :     exportAxesId( nAttachedAxis );
    1443             : 
    1444          28 :     pFS->endElement( FSNS( XML_c, nTypeId ) );
    1445          14 : }
    1446             : 
    1447           0 : void ChartExport::exportOfPieChart( Reference< chart2::XChartType > /*xChartType*/ )
    1448             : {
    1449             :     // TODO:
    1450           0 : }
    1451             : 
    1452          14 : void ChartExport::exportPieChart( Reference< chart2::XChartType > xChartType )
    1453             : {
    1454          14 :     sal_Int32 eChartType = getChartType( );
    1455          14 :     if(eChartType == chart::TYPEID_DOUGHNUT)
    1456             :     {
    1457           4 :         exportDoughnutChart( xChartType );
    1458          18 :         return;
    1459             :     }
    1460          10 :     FSHelperPtr pFS = GetFS();
    1461          10 :     sal_Int32 nTypeId = XML_pieChart;
    1462          10 :     if( mbIs3DChart )
    1463           4 :         nTypeId = XML_pie3DChart;
    1464             :     pFS->startElement( FSNS( XML_c, nTypeId ),
    1465          10 :             FSEND );
    1466             :     // TODO: varyColors
    1467          10 :     const char* varyColors = "1";
    1468             :     pFS->singleElement( FSNS( XML_c, XML_varyColors ),
    1469             :             XML_val, varyColors,
    1470          10 :             FSEND );
    1471             : 
    1472          10 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1473          10 :     exportSeries( xChartType, nAttachedAxis );
    1474             : 
    1475          10 :     if( !mbIs3DChart )
    1476             :     {
    1477             :         // firstSliceAng
    1478           6 :         exportFirstSliceAng( );
    1479             :     }
    1480             : 
    1481          10 :     pFS->endElement( FSNS( XML_c, nTypeId ) );
    1482             : }
    1483             : 
    1484           2 : void ChartExport::exportRadarChart( Reference< chart2::XChartType > xChartType)
    1485             : {
    1486           2 :     FSHelperPtr pFS = GetFS();
    1487             :     pFS->startElement( FSNS( XML_c, XML_radarChart ),
    1488           2 :             FSEND );
    1489             : 
    1490             :     // radarStyle
    1491           2 :     sal_Int32 eChartType = getChartType( );
    1492           2 :     const char* radarStyle = NULL;
    1493           2 :     if( eChartType == chart::TYPEID_RADARAREA )
    1494           2 :         radarStyle = "filled";
    1495             :     else
    1496           0 :         radarStyle = "marker";
    1497             :     pFS->singleElement( FSNS( XML_c, XML_radarStyle ),
    1498             :             XML_val, radarStyle,
    1499           2 :             FSEND );
    1500           2 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1501           2 :     exportSeries( xChartType, nAttachedAxis );
    1502           2 :     exportAxesId( nAttachedAxis );
    1503             : 
    1504           2 :     pFS->endElement( FSNS( XML_c, XML_radarChart ) );
    1505           2 : }
    1506             : 
    1507          10 : void ChartExport::exportScatterChart( Reference< chart2::XChartType > xChartType )
    1508             : {
    1509          10 :     FSHelperPtr pFS = GetFS();
    1510             :     pFS->startElement( FSNS( XML_c, XML_scatterChart ),
    1511          10 :             FSEND );
    1512             :     // TODO:scatterStyle
    1513          10 :     const char* scatterStyle = "lineMarker";
    1514             :     pFS->singleElement( FSNS( XML_c, XML_scatterStyle ),
    1515             :             XML_val, scatterStyle,
    1516          10 :             FSEND );
    1517             : 
    1518             :     pFS->singleElement( FSNS( XML_c, XML_varyColors ),
    1519             :             XML_val, "0",
    1520          10 :             FSEND );
    1521             : 
    1522             :     // FIXME: should export xVal and yVal
    1523          10 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1524          10 :     exportSeries( xChartType, nAttachedAxis );
    1525          10 :     exportAxesId( nAttachedAxis );
    1526             : 
    1527          10 :     pFS->endElement( FSNS( XML_c, XML_scatterChart ) );
    1528          10 : }
    1529             : 
    1530           2 : void ChartExport::exportStockChart( Reference< chart2::XChartType > xChartType )
    1531             : {
    1532           2 :     FSHelperPtr pFS = GetFS();
    1533             :     pFS->startElement( FSNS( XML_c, XML_stockChart ),
    1534           2 :             FSEND );
    1535             : 
    1536           2 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1537           2 :     exportSeries( xChartType, nAttachedAxis );
    1538             :     // export stock properties
    1539           4 :     Reference< ::com::sun::star::chart::XStatisticDisplay > xStockPropProvider( mxDiagram, uno::UNO_QUERY );
    1540           2 :     if( xStockPropProvider.is())
    1541             :     {
    1542           2 :         exportHiLowLines();
    1543           2 :         exportUpDownBars(xChartType);
    1544             :     }
    1545             : 
    1546           2 :     exportAxesId( nAttachedAxis );
    1547             : 
    1548           4 :     pFS->endElement( FSNS( XML_c, XML_stockChart ) );
    1549           2 : }
    1550             : 
    1551          16 : void ChartExport::exportHiLowLines()
    1552             : {
    1553          16 :     FSHelperPtr pFS = GetFS();
    1554             :     // export the chart property
    1555          32 :     Reference< ::com::sun::star::chart::XStatisticDisplay > xChartPropProvider( mxDiagram, uno::UNO_QUERY );
    1556             : 
    1557          16 :     if (!xChartPropProvider.is())
    1558           0 :         return;
    1559             : 
    1560          32 :     Reference< beans::XPropertySet > xStockPropSet = xChartPropProvider->getMinMaxLine();
    1561          16 :     if( !xStockPropSet.is() )
    1562           0 :         return;
    1563             : 
    1564             :     pFS->startElement( FSNS( XML_c, XML_hiLowLines ),
    1565          16 :             FSEND );
    1566          16 :     exportShapeProps( xStockPropSet );
    1567          32 :     pFS->endElement( FSNS( XML_c, XML_hiLowLines ) );
    1568             : }
    1569             : 
    1570          16 : void ChartExport::exportUpDownBars( Reference< chart2::XChartType > xChartType)
    1571             : {
    1572          16 :     FSHelperPtr pFS = GetFS();
    1573             :     // export the chart property
    1574          32 :     Reference< ::com::sun::star::chart::XStatisticDisplay > xChartPropProvider( mxDiagram, uno::UNO_QUERY );
    1575          16 :     if(xChartPropProvider.is())
    1576             :     {
    1577          16 :         Reference< beans::XPropertySet > xChartPropSet = xChartPropProvider->getMinMaxLine();
    1578             :         //  updownbar
    1579             :         pFS->startElement( FSNS( XML_c, XML_upDownBars ),
    1580          16 :                 FSEND );
    1581             :         // TODO: gapWidth
    1582          16 :         sal_Int32 nGapWidth = 150;
    1583             :         pFS->singleElement( FSNS( XML_c, XML_gapWidth ),
    1584             :                 XML_val, I32S( nGapWidth ),
    1585          16 :                     FSEND );
    1586             : 
    1587          16 :         xChartPropSet = xChartPropProvider->getUpBar();
    1588          16 :         if( xChartPropSet.is() )
    1589             :         {
    1590             :             pFS->startElement( FSNS( XML_c, XML_upBars ),
    1591          16 :                     FSEND );
    1592             :             // For Linechart with UpDownBars, spPr is not getting imported
    1593             :             // so no need to call the exportShapeProps() for LineChart
    1594          16 :             if(xChartType->getChartType().equals("com.sun.star.chart2.CandleStickChartType"))
    1595             :             {
    1596           2 :                 exportShapeProps(xChartPropSet);
    1597             :             }
    1598          16 :             pFS->endElement( FSNS( XML_c, XML_upBars ) );
    1599             :         }
    1600          16 :         xChartPropSet = xChartPropProvider->getDownBar();
    1601          16 :         if( xChartPropSet.is() )
    1602             :         {
    1603             :             pFS->startElement( FSNS( XML_c, XML_downBars ),
    1604          16 :                     FSEND );
    1605          16 :             if(xChartType->getChartType().equals("com.sun.star.chart2.CandleStickChartType"))
    1606             :             {
    1607           2 :                 exportShapeProps(xChartPropSet);
    1608             :             }
    1609          16 :             pFS->endElement( FSNS( XML_c, XML_downBars ) );
    1610             :         }
    1611          16 :         pFS->endElement( FSNS( XML_c, XML_upDownBars ) );
    1612          16 :     }
    1613          16 : }
    1614             : 
    1615           0 : void ChartExport::exportSurfaceChart( Reference< chart2::XChartType > xChartType )
    1616             : {
    1617           0 :     FSHelperPtr pFS = GetFS();
    1618           0 :     sal_Int32 nTypeId = XML_surfaceChart;
    1619           0 :     if( mbIs3DChart )
    1620           0 :         nTypeId = XML_surface3DChart;
    1621             :     pFS->startElement( FSNS( XML_c, nTypeId ),
    1622           0 :             FSEND );
    1623           0 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1624           0 :     exportSeries( xChartType, nAttachedAxis );
    1625           0 :     exportAxesId( nAttachedAxis );
    1626             : 
    1627           0 :     pFS->endElement( FSNS( XML_c, nTypeId ) );
    1628           0 : }
    1629             : 
    1630          92 : void ChartExport::exportSeries( Reference< chart2::XChartType > xChartType, sal_Int32& nAttachedAxis )
    1631             : {
    1632             : 
    1633          92 :     OUString aLabelRole = xChartType->getRoleOfSequenceForSeriesLabel();
    1634         182 :     Reference< chart2::XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY );
    1635          92 :     if( ! xDSCnt.is())
    1636           0 :         return;
    1637             : 
    1638         182 :     OUString aChartType( xChartType->getChartType());
    1639          92 :     sal_Int32 eChartType = lcl_getChartType( aChartType );
    1640             : 
    1641             :     // special export for stock charts
    1642          92 :     if( eChartType == chart::TYPEID_STOCK )
    1643             :     {
    1644           2 :         bool bJapaneseCandleSticks = false;
    1645           2 :         Reference< beans::XPropertySet > xCTProp( xChartType, uno::UNO_QUERY );
    1646           2 :         if( xCTProp.is())
    1647           2 :             xCTProp->getPropertyValue("Japanese") >>= bJapaneseCandleSticks;
    1648             :         exportCandleStickSeries(
    1649           2 :             xDSCnt->getDataSeries(), bJapaneseCandleSticks, nAttachedAxis );
    1650           2 :         return;
    1651             :     }
    1652             : 
    1653             :     // export dataseries for current chart-type
    1654         180 :     Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries());
    1655         276 :     for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
    1656             :     {
    1657             :         // export series
    1658         186 :         Reference< chart2::data::XDataSource > xSource( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY );
    1659         186 :         if( xSource.is())
    1660             :         {
    1661         186 :             Reference< chart2::XDataSeries > xDataSeries( xSource, uno::UNO_QUERY );
    1662             :             Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
    1663         372 :                 xSource->getDataSequences());
    1664             :             // search for main sequence and create a series element
    1665             :             {
    1666         186 :                 sal_Int32 nMainSequenceIndex = -1;
    1667         186 :                 sal_Int32 nSeriesLength = 0;
    1668         186 :                 Reference< chart2::data::XDataSequence > xValuesSeq;
    1669         372 :                 Reference< chart2::data::XDataSequence > xLabelSeq;
    1670         186 :                 sal_Int32 nSeqIdx=0;
    1671         382 :                 for( ; nSeqIdx<aSeqCnt.getLength(); ++nSeqIdx )
    1672             :                 {
    1673         196 :                     OUString aRole;
    1674         392 :                     Reference< chart2::data::XDataSequence > xTempValueSeq( aSeqCnt[nSeqIdx]->getValues() );
    1675         196 :                     if( nMainSequenceIndex==-1 )
    1676             :                     {
    1677         196 :                         Reference< beans::XPropertySet > xSeqProp( xTempValueSeq, uno::UNO_QUERY );
    1678         196 :                         if( xSeqProp.is())
    1679         196 :                             xSeqProp->getPropertyValue("Role") >>= aRole;
    1680             :                         // "main" sequence
    1681         196 :                         if( aRole.equals( aLabelRole ))
    1682             :                         {
    1683         182 :                             xValuesSeq.set( xTempValueSeq );
    1684         182 :                             xLabelSeq.set( aSeqCnt[nSeqIdx]->getLabel());
    1685         182 :                             nMainSequenceIndex = nSeqIdx;
    1686         196 :                         }
    1687             :                     }
    1688         196 :                     sal_Int32 nSequenceLength = (xTempValueSeq.is()? xTempValueSeq->getData().getLength() : sal_Int32(0));
    1689         196 :                     if( nSeriesLength < nSequenceLength )
    1690         182 :                         nSeriesLength = nSequenceLength;
    1691         196 :                 }
    1692             : 
    1693             :                 // have found the main sequence, then xValuesSeq and
    1694             :                 // xLabelSeq contain those.  Otherwise both are empty
    1695             :                 {
    1696         186 :                     FSHelperPtr pFS = GetFS();
    1697             :                     pFS->startElement( FSNS( XML_c, XML_ser ),
    1698         186 :                         FSEND );
    1699             : 
    1700             :                     // TODO: idx and order
    1701             :                     pFS->singleElement( FSNS( XML_c, XML_idx ),
    1702             :                         XML_val, I32S(mnSeriesCount),
    1703         186 :                         FSEND );
    1704             :                     pFS->singleElement( FSNS( XML_c, XML_order ),
    1705             :                         XML_val, I32S(mnSeriesCount++),
    1706         186 :                         FSEND );
    1707             : 
    1708             :                     // export label
    1709         186 :                     if( xLabelSeq.is() )
    1710         182 :                         exportSeriesText( xLabelSeq );
    1711             : 
    1712             :                     // export shape properties
    1713             :                     Reference< XPropertySet > xPropSet = SchXMLSeriesHelper::createOldAPISeriesPropertySet(
    1714         372 :                         aSeriesSeq[nSeriesIdx], getModel() );
    1715         186 :                     if( xPropSet.is() )
    1716             :                     {
    1717         186 :                         if( GetProperty( xPropSet, "Axis") )
    1718             :                         {
    1719         186 :                             mAny >>= nAttachedAxis;
    1720         186 :                             if( nAttachedAxis == ::com::sun::star::chart::ChartAxisAssign::SECONDARY_Y )
    1721           6 :                                 nAttachedAxis = AXIS_SECONDARY_Y;
    1722             :                             else
    1723         180 :                                 nAttachedAxis = AXIS_PRIMARY_Y;
    1724             :                         }
    1725         186 :                         exportShapeProps( xPropSet );
    1726             :                     }
    1727             : 
    1728         186 :                     switch( eChartType )
    1729             :                     {
    1730             :                         case chart::TYPEID_LINE:
    1731             :                         {
    1732          30 :                             exportMarker(xDataSeries);
    1733          30 :                             break;
    1734             :                         }
    1735             :                         case chart::TYPEID_PIE:
    1736             :                         case chart::TYPEID_DOUGHNUT:
    1737             :                         {
    1738          14 :                             if( xPropSet.is() && GetProperty( xPropSet, "SegmentOffset") )
    1739             :                             {
    1740          14 :                                 sal_Int32 nOffset = 0;
    1741          14 :                                 mAny >>= nOffset;
    1742             :                                 pFS->singleElement( FSNS( XML_c, XML_explosion ),
    1743             :                                     XML_val, I32S( nOffset ),
    1744          14 :                                     FSEND );
    1745             :                             }
    1746          14 :                             break;
    1747             :                         }
    1748             :                         case chart::TYPEID_SCATTER:
    1749             :                         {
    1750          14 :                             exportMarker(xDataSeries);
    1751          14 :                             break;
    1752             :                         }
    1753             :                         case chart::TYPEID_RADARLINE:
    1754             :                         {
    1755           0 :                             exportMarker(xDataSeries);
    1756           0 :                             break;
    1757             :                         }
    1758             :                     }
    1759             : 
    1760             :                     // export data points
    1761         186 :                     exportDataPoints( uno::Reference< beans::XPropertySet >( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY ), nSeriesLength );
    1762             : 
    1763             :                     // export data labels
    1764             :                     // Excel does not like our current data label export
    1765             :                     // for scatter charts
    1766         186 :                     if( eChartType != chart::TYPEID_SCATTER )
    1767         172 :                         exportDataLabels(aSeriesSeq[nSeriesIdx], nSeriesLength, eChartType);
    1768             : 
    1769         186 :                     exportTrendlines( aSeriesSeq[nSeriesIdx] );
    1770             : 
    1771         186 :                     if( eChartType != chart::TYPEID_PIE &&
    1772             :                             eChartType != chart::TYPEID_RADARLINE )
    1773             :                     {
    1774             :                         //export error bars here
    1775         172 :                         Reference< XPropertySet > xSeriesPropSet( xSource, uno::UNO_QUERY );
    1776         344 :                         Reference< XPropertySet > xErrorBarYProps;
    1777         172 :                         xSeriesPropSet->getPropertyValue("ErrorBarY") >>= xErrorBarYProps;
    1778         172 :                         if(xErrorBarYProps.is())
    1779           2 :                             exportErrorBar(xErrorBarYProps, true);
    1780         344 :                         Reference< XPropertySet > xErrorBarXProps;
    1781         172 :                         xSeriesPropSet->getPropertyValue("ErrorBarX") >>= xErrorBarXProps;
    1782         172 :                         if(xErrorBarXProps.is())
    1783         172 :                             exportErrorBar(xErrorBarXProps, false);
    1784             :                     }
    1785             : 
    1786             :                     // export categories
    1787         186 :                     if( eChartType != chart::TYPEID_SCATTER && mxCategoriesValues.is() )
    1788         156 :                         exportSeriesCategory( mxCategoriesValues );
    1789             : 
    1790         186 :                     if( (eChartType == chart::TYPEID_SCATTER)
    1791         172 :                         || (eChartType == chart::TYPEID_BUBBLE) )
    1792             :                     {
    1793             :                         // export xVal
    1794          14 :                         Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString("values-x") ) );
    1795          14 :                         if( xSequence.is() )
    1796             :                         {
    1797          14 :                             Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() );
    1798          14 :                             if( xValues.is() )
    1799          14 :                                 exportSeriesValues( xValues, XML_xVal );
    1800          14 :                         }
    1801             :                     }
    1802             : 
    1803         186 :                     if( eChartType == chart::TYPEID_BUBBLE )
    1804             :                     {
    1805             :                         // export yVal
    1806           0 :                         Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString("values-y") ) );
    1807           0 :                         if( xSequence.is() )
    1808             :                         {
    1809           0 :                             Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() );
    1810           0 :                             if( xValues.is() )
    1811           0 :                                 exportSeriesValues( xValues, XML_yVal );
    1812           0 :                         }
    1813             :                     }
    1814             : 
    1815             :                     // export values
    1816         186 :                     if( xValuesSeq.is() )
    1817             :                     {
    1818         182 :                         sal_Int32 nYValueType = XML_val;
    1819         182 :                         if( eChartType == chart::TYPEID_SCATTER )
    1820          14 :                             nYValueType = XML_yVal;
    1821         168 :                         else if( eChartType == chart::TYPEID_BUBBLE )
    1822           0 :                             nYValueType = XML_bubbleSize;
    1823         182 :                         exportSeriesValues( xValuesSeq, nYValueType );
    1824             :                     }
    1825             : 
    1826         186 :                     if( eChartType == chart::TYPEID_SCATTER
    1827         172 :                             || eChartType == chart::TYPEID_LINE )
    1828          44 :                         exportSmooth();
    1829             : 
    1830         372 :                     pFS->endElement( FSNS( XML_c, XML_ser ) );
    1831         186 :                 }
    1832         186 :             }
    1833             :         }
    1834         276 :     }
    1835             : }
    1836             : 
    1837           2 : void ChartExport::exportCandleStickSeries(
    1838             :     const Sequence< Reference< chart2::XDataSeries > > & aSeriesSeq,
    1839             :     bool /*bJapaneseCandleSticks*/,
    1840             :     sal_Int32& nAttachedAxis )
    1841             : {
    1842           4 :     for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
    1843             :     {
    1844           2 :         Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nSeriesIdx] );
    1845           2 :         nAttachedAxis = lcl_isSeriesAttachedToFirstAxis( xSeries ) ? AXIS_PRIMARY_Y : AXIS_SECONDARY_Y;
    1846             : 
    1847           4 :         Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
    1848           2 :         if( xSource.is())
    1849             :         {
    1850             :             // export series in correct order (as we don't store roles)
    1851             :             // with japanese candlesticks: open, low, high, close
    1852             :             // otherwise: low, high, close
    1853             :             Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
    1854           2 :                 xSource->getDataSequences());
    1855             : 
    1856           4 :             Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
    1857           2 :             const char* sSeries[] = {"values-first","values-max","values-min","values-last",0};
    1858             : 
    1859          10 :             for( sal_Int32 idx = 0; sSeries[idx] != 0 ; idx++ )
    1860             :             {
    1861           8 :                 Reference< chart2::data::XLabeledDataSequence > xLabeledSeq( lcl_getDataSequenceByRole( aSeqCnt, OUString::createFromAscii(sSeries[idx]) ) );
    1862           8 :                 if( xLabeledSeq.is())
    1863             :                 {
    1864           8 :                     Reference< chart2::data::XDataSequence > xLabelSeq( xLabeledSeq->getLabel());
    1865          16 :                     Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues());
    1866             :                     {
    1867           8 :                         FSHelperPtr pFS = GetFS();
    1868             :                         pFS->startElement( FSNS( XML_c, XML_ser ),
    1869           8 :                                 FSEND );
    1870             : 
    1871             :                         // TODO: idx and order
    1872             :                         // idx attribute should start from 1 and not from 0.
    1873             :                         pFS->singleElement( FSNS( XML_c, XML_idx ),
    1874             :                                 XML_val, I32S(idx+1),
    1875           8 :                                 FSEND );
    1876             :                         pFS->singleElement( FSNS( XML_c, XML_order ),
    1877             :                                 XML_val, I32S(idx+1),
    1878           8 :                                 FSEND );
    1879             : 
    1880             :                         // export label
    1881           8 :                         if( xLabelSeq.is() )
    1882           8 :                             exportSeriesText( xLabelSeq );
    1883             : 
    1884             :                         // TODO:export shape properties
    1885             : 
    1886             :                         // export categories
    1887           8 :                         if( mxCategoriesValues.is() )
    1888           8 :                             exportSeriesCategory( mxCategoriesValues );
    1889             : 
    1890             :                         // export values
    1891           8 :                         if( xValueSeq.is() )
    1892           8 :                             exportSeriesValues( xValueSeq );
    1893             : 
    1894           8 :                         pFS->endElement( FSNS( XML_c, XML_ser ) );
    1895           8 :                     }
    1896             :                 }
    1897          10 :             }
    1898             :         }
    1899           2 :     }
    1900           2 : }
    1901             : 
    1902         190 : void ChartExport::exportSeriesText( const Reference< chart2::data::XDataSequence > & xValueSeq )
    1903             : {
    1904         190 :     FSHelperPtr pFS = GetFS();
    1905         380 :     Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
    1906             :     pFS->startElement( FSNS( XML_c, XML_tx ),
    1907         190 :             FSEND );
    1908             : 
    1909         380 :     OUString aCellRange =  xValueSeq->getSourceRangeRepresentation();
    1910         190 :     aCellRange = parseFormula( aCellRange );
    1911             :     pFS->startElement( FSNS( XML_c, XML_strRef ),
    1912         190 :             FSEND );
    1913             : 
    1914             :     pFS->startElement( FSNS( XML_c, XML_f ),
    1915         190 :             FSEND );
    1916         190 :     pFS->writeEscaped( aCellRange );
    1917         190 :     pFS->endElement( FSNS( XML_c, XML_f ) );
    1918             : 
    1919         380 :     OUString aLabelString = lcl_getLabelString( xValueSeq );
    1920             :     pFS->startElement( FSNS( XML_c, XML_strCache ),
    1921         190 :             FSEND );
    1922             :     pFS->singleElement( FSNS( XML_c, XML_ptCount ),
    1923             :             XML_val, "1",
    1924         190 :             FSEND );
    1925             :     pFS->startElement( FSNS( XML_c, XML_pt ),
    1926             :             XML_idx, "0",
    1927         190 :             FSEND );
    1928             :     pFS->startElement( FSNS( XML_c, XML_v ),
    1929         190 :             FSEND );
    1930         190 :     pFS->writeEscaped( aLabelString );
    1931         190 :     pFS->endElement( FSNS( XML_c, XML_v ) );
    1932         190 :     pFS->endElement( FSNS( XML_c, XML_pt ) );
    1933         190 :     pFS->endElement( FSNS( XML_c, XML_strCache ) );
    1934         190 :     pFS->endElement( FSNS( XML_c, XML_strRef ) );
    1935         380 :     pFS->endElement( FSNS( XML_c, XML_tx ) );
    1936         190 : }
    1937             : 
    1938         164 : void ChartExport::exportSeriesCategory( const Reference< chart2::data::XDataSequence > & xValueSeq )
    1939             : {
    1940         164 :     FSHelperPtr pFS = GetFS();
    1941         328 :     Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
    1942             :     pFS->startElement( FSNS( XML_c, XML_cat ),
    1943         164 :             FSEND );
    1944             : 
    1945         328 :     OUString aCellRange =  xValueSeq->getSourceRangeRepresentation();
    1946         164 :     aCellRange = parseFormula( aCellRange );
    1947             :     // TODO: need to handle XML_multiLvlStrRef according to aCellRange
    1948             :     pFS->startElement( FSNS( XML_c, XML_strRef ),
    1949         164 :             FSEND );
    1950             : 
    1951             :     pFS->startElement( FSNS( XML_c, XML_f ),
    1952         164 :             FSEND );
    1953         164 :     pFS->writeEscaped( aCellRange );
    1954         164 :     pFS->endElement( FSNS( XML_c, XML_f ) );
    1955             : 
    1956         328 :     ::std::vector< OUString > aCategories;
    1957         164 :     lcl_fillCategoriesIntoStringVector( xValueSeq, aCategories );
    1958         164 :     sal_Int32 ptCount = aCategories.size();
    1959             :     pFS->startElement( FSNS( XML_c, XML_strCache ),
    1960         164 :             FSEND );
    1961             :     pFS->singleElement( FSNS( XML_c, XML_ptCount ),
    1962             :             XML_val, I32S( ptCount ),
    1963         164 :             FSEND );
    1964         964 :     for( sal_Int32 i = 0; i < ptCount; i++ )
    1965             :     {
    1966             :         pFS->startElement( FSNS( XML_c, XML_pt ),
    1967             :             XML_idx, I32S( i ),
    1968         800 :             FSEND );
    1969             :         pFS->startElement( FSNS( XML_c, XML_v ),
    1970         800 :             FSEND );
    1971         800 :         pFS->writeEscaped( aCategories[i] );
    1972         800 :         pFS->endElement( FSNS( XML_c, XML_v ) );
    1973         800 :         pFS->endElement( FSNS( XML_c, XML_pt ) );
    1974             :     }
    1975             : 
    1976         164 :     pFS->endElement( FSNS( XML_c, XML_strCache ) );
    1977         164 :     pFS->endElement( FSNS( XML_c, XML_strRef ) );
    1978         328 :     pFS->endElement( FSNS( XML_c, XML_cat ) );
    1979         164 : }
    1980             : 
    1981         204 : void ChartExport::exportSeriesValues( const Reference< chart2::data::XDataSequence > & xValueSeq, sal_Int32 nValueType )
    1982             : {
    1983         204 :     FSHelperPtr pFS = GetFS();
    1984         408 :     Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
    1985             :     pFS->startElement( FSNS( XML_c, nValueType ),
    1986         204 :             FSEND );
    1987             : 
    1988         408 :     OUString aCellRange =  xValueSeq->getSourceRangeRepresentation();
    1989         204 :     aCellRange = parseFormula( aCellRange );
    1990             :     // TODO: need to handle XML_multiLvlStrRef according to aCellRange
    1991             :     pFS->startElement( FSNS( XML_c, XML_numRef ),
    1992         204 :             FSEND );
    1993             : 
    1994             :     pFS->startElement( FSNS( XML_c, XML_f ),
    1995         204 :             FSEND );
    1996         204 :     pFS->writeEscaped( aCellRange );
    1997         204 :     pFS->endElement( FSNS( XML_c, XML_f ) );
    1998             : 
    1999         408 :     ::std::vector< double > aValues;
    2000         204 :     aValues = lcl_getAllValuesFromSequence( xValueSeq );
    2001         204 :     sal_Int32 ptCount = aValues.size();
    2002             :     pFS->startElement( FSNS( XML_c, XML_numCache ),
    2003         204 :             FSEND );
    2004             :     pFS->startElement( FSNS( XML_c, XML_formatCode ),
    2005         204 :             FSEND );
    2006             :     // TODO: what format code?
    2007         204 :     pFS->writeEscaped( "General" );
    2008         204 :     pFS->endElement( FSNS( XML_c, XML_formatCode ) );
    2009             :     pFS->singleElement( FSNS( XML_c, XML_ptCount ),
    2010             :             XML_val, I32S( ptCount ),
    2011         204 :             FSEND );
    2012             : 
    2013         204 :     bool bIsNumberValue = true;
    2014         204 :     bool bXSeriesValue = false;
    2015         204 :     double Value = 1.0;
    2016             : 
    2017         204 :     if(nValueType == XML_xVal)
    2018          14 :         bXSeriesValue = true;
    2019             : 
    2020        1172 :     for( sal_Int32 i = 0; i < ptCount; i++ )
    2021             :     {
    2022             :         pFS->startElement( FSNS( XML_c, XML_pt ),
    2023             :             XML_idx, I32S( i ),
    2024         968 :             FSEND );
    2025             :         pFS->startElement( FSNS( XML_c, XML_v ),
    2026         968 :             FSEND );
    2027         968 :         if (bIsNumberValue && !rtl::math::isNan(aValues[i]))
    2028         958 :             pFS->write( aValues[i] );
    2029          10 :         else if(bXSeriesValue)
    2030             :         {
    2031             :             //In Case aValues is not a number for X Values...We write X values as 1,2,3....MS Word does the same thing.
    2032           0 :             pFS->write( Value );
    2033           0 :             Value = Value + 1;
    2034           0 :             bIsNumberValue = false;
    2035             :         }
    2036         968 :         pFS->endElement( FSNS( XML_c, XML_v ) );
    2037         968 :         pFS->endElement( FSNS( XML_c, XML_pt ) );
    2038             :     }
    2039             : 
    2040         204 :     pFS->endElement( FSNS( XML_c, XML_numCache ) );
    2041         204 :     pFS->endElement( FSNS( XML_c, XML_numRef ) );
    2042         408 :     pFS->endElement( FSNS( XML_c, nValueType ) );
    2043         204 : }
    2044             : 
    2045         734 : void ChartExport::exportShapeProps( Reference< XPropertySet > xPropSet )
    2046             : {
    2047         734 :     FSHelperPtr pFS = GetFS();
    2048             :     pFS->startElement( FSNS( XML_c, XML_spPr ),
    2049         734 :             FSEND );
    2050             : 
    2051         734 :     WriteFill( xPropSet );
    2052         734 :     WriteOutline( xPropSet );
    2053             : 
    2054         734 :     pFS->endElement( FSNS( XML_c, XML_spPr ) );
    2055         734 : }
    2056             : 
    2057          84 : void ChartExport::InitPlotArea( )
    2058             : {
    2059          84 :     Reference< XPropertySet > xDiagramProperties (mxDiagram, uno::UNO_QUERY);
    2060             : 
    2061             :     //    Check for supported services and then the properties provided by this service.
    2062         168 :     Reference<lang::XServiceInfo> xServiceInfo (mxDiagram, uno::UNO_QUERY);
    2063          84 :     if (xServiceInfo.is())
    2064             :     {
    2065         252 :         if (xServiceInfo->supportsService(
    2066         168 :             OUString("com.sun.star.chart.ChartAxisZSupplier")))
    2067             :         {
    2068          84 :             xDiagramProperties->getPropertyValue(
    2069         168 :                 OUString("HasZAxis")) >>= mbHasZAxis;
    2070             :         }
    2071             :     }
    2072             : 
    2073          84 :     xDiagramProperties->getPropertyValue(
    2074         168 :         OUString ("Dim3D")) >>=  mbIs3DChart;
    2075             : 
    2076         168 :     Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
    2077          84 :     if( mbHasCategoryLabels && mxNewDiagram.is())
    2078             :     {
    2079          72 :         Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( mxNewDiagram ) );
    2080          72 :         if( xCategories.is() )
    2081             :         {
    2082          72 :             mxCategoriesValues.set( xCategories->getValues() );
    2083          72 :         }
    2084          84 :     }
    2085          84 : }
    2086             : 
    2087          84 : void ChartExport::exportAxes( )
    2088             : {
    2089          84 :     sal_Int32 nSize = maAxes.size();
    2090         240 :     for( sal_Int32 nIdx = 0; nIdx < nSize; nIdx++ )
    2091             :     {
    2092         156 :         exportAxis( maAxes[nIdx] );
    2093             :     }
    2094          84 : }
    2095             : 
    2096         156 : void ChartExport::exportAxis( AxisIdPair aAxisIdPair )
    2097             : {
    2098             :     // get some properties from document first
    2099         156 :     bool bHasXAxisTitle = false,
    2100         156 :         bHasYAxisTitle = false,
    2101         156 :         bHasZAxisTitle = false,
    2102         156 :         bHasSecondaryXAxisTitle = false,
    2103         156 :         bHasSecondaryYAxisTitle = false;
    2104         156 :     bool bHasXAxisMajorGrid = false,
    2105         156 :         bHasXAxisMinorGrid = false,
    2106         156 :         bHasYAxisMajorGrid = false,
    2107         156 :         bHasYAxisMinorGrid = false,
    2108         156 :         bHasZAxisMajorGrid = false,
    2109         156 :         bHasZAxisMinorGrid = false;
    2110             : 
    2111         156 :        Reference< XPropertySet > xDiagramProperties (mxDiagram, uno::UNO_QUERY);
    2112             : 
    2113         156 :     xDiagramProperties->getPropertyValue(
    2114         156 :         OUString ("HasXAxisTitle")) >>= bHasXAxisTitle;
    2115         156 :     xDiagramProperties->getPropertyValue(
    2116         156 :         OUString ("HasYAxisTitle")) >>= bHasYAxisTitle;
    2117         156 :     xDiagramProperties->getPropertyValue(
    2118         156 :         OUString ("HasZAxisTitle")) >>= bHasZAxisTitle;
    2119         156 :     xDiagramProperties->getPropertyValue(
    2120         156 :         OUString ("HasSecondaryXAxisTitle")) >>=  bHasSecondaryXAxisTitle;
    2121         156 :     xDiagramProperties->getPropertyValue(
    2122         156 :         OUString ("HasSecondaryYAxisTitle")) >>=  bHasSecondaryYAxisTitle;
    2123             : 
    2124         156 :     xDiagramProperties->getPropertyValue(
    2125         156 :         OUString ("HasXAxisGrid")) >>=  bHasXAxisMajorGrid;
    2126         156 :     xDiagramProperties->getPropertyValue(
    2127         156 :         OUString ("HasYAxisGrid")) >>=  bHasYAxisMajorGrid;
    2128         156 :     xDiagramProperties->getPropertyValue(
    2129         156 :         OUString ("HasZAxisGrid")) >>=  bHasZAxisMajorGrid;
    2130             : 
    2131         156 :     xDiagramProperties->getPropertyValue(
    2132         156 :         OUString ("HasXAxisHelpGrid")) >>=  bHasXAxisMinorGrid;
    2133         156 :     xDiagramProperties->getPropertyValue(
    2134         156 :         OUString ("HasYAxisHelpGrid")) >>=  bHasYAxisMinorGrid;
    2135         156 :     xDiagramProperties->getPropertyValue(
    2136         156 :         OUString ("HasZAxisHelpGrid")) >>=  bHasZAxisMinorGrid;
    2137             : 
    2138         312 :     Reference< XPropertySet > xAxisProp;
    2139         312 :     Reference< drawing::XShape > xAxisTitle;
    2140         312 :     Reference< beans::XPropertySet > xMajorGrid;
    2141         312 :     Reference< beans::XPropertySet > xMinorGrid;
    2142         156 :     sal_Int32 nAxisType = XML_catAx;
    2143         156 :     const char* sAxPos = NULL;
    2144             : 
    2145         156 :     switch( aAxisIdPair.nAxisType )
    2146             :     {
    2147             :         case AXIS_PRIMARY_X:
    2148             :         {
    2149          78 :             Reference< ::com::sun::star::chart::XAxisXSupplier > xAxisXSupp( mxDiagram, uno::UNO_QUERY );
    2150          78 :             if( xAxisXSupp.is())
    2151          78 :                 xAxisProp = xAxisXSupp->getXAxis();
    2152          78 :             if( bHasXAxisTitle )
    2153          10 :                 xAxisTitle.set( xAxisXSupp->getXAxisTitle(), uno::UNO_QUERY );
    2154          78 :             if( bHasXAxisMajorGrid )
    2155           8 :                 xMajorGrid.set( xAxisXSupp->getXMainGrid(), uno::UNO_QUERY );
    2156          78 :             if( bHasXAxisMinorGrid )
    2157           0 :                 xMinorGrid.set( xAxisXSupp->getXHelpGrid(), uno::UNO_QUERY );
    2158             : 
    2159          78 :             sal_Int32 eChartType = getChartType( );
    2160          78 :             if( (eChartType == chart::TYPEID_SCATTER)
    2161          68 :                 || (eChartType == chart::TYPEID_BUBBLE) )
    2162          10 :                 nAxisType = XML_valAx;
    2163          68 :             else if( eChartType == chart::TYPEID_STOCK )
    2164           4 :                 nAxisType = XML_dateAx;
    2165             :             // FIXME: axPos, need to check axis direction
    2166          78 :             sAxPos = "b";
    2167          78 :             break;
    2168             :         }
    2169             :         case AXIS_PRIMARY_Y:
    2170             :         {
    2171          72 :             Reference< ::com::sun::star::chart::XAxisYSupplier > xAxisYSupp( mxDiagram, uno::UNO_QUERY );
    2172          72 :             if( xAxisYSupp.is())
    2173          72 :                 xAxisProp = xAxisYSupp->getYAxis();
    2174          72 :             if( bHasYAxisTitle )
    2175          12 :                 xAxisTitle.set( xAxisYSupp->getYAxisTitle(), uno::UNO_QUERY );
    2176          72 :             if( bHasYAxisMajorGrid )
    2177          68 :                 xMajorGrid.set( xAxisYSupp->getYMainGrid(), uno::UNO_QUERY );
    2178          72 :             if( bHasYAxisMinorGrid )
    2179          10 :                 xMinorGrid.set( xAxisYSupp->getYHelpGrid(), uno::UNO_QUERY );
    2180             : 
    2181          72 :             nAxisType = XML_valAx;
    2182             :             // FIXME: axPos, need to check axis direction
    2183          72 :             sAxPos = "l";
    2184          72 :             break;
    2185             :         }
    2186             :         case AXIS_PRIMARY_Z:
    2187             :         {
    2188           0 :             Reference< ::com::sun::star::chart::XAxisZSupplier > xAxisZSupp( mxDiagram, uno::UNO_QUERY );
    2189           0 :             if( xAxisZSupp.is())
    2190           0 :                 xAxisProp = xAxisZSupp->getZAxis();
    2191           0 :             if( bHasZAxisTitle )
    2192           0 :                 xAxisTitle.set( xAxisZSupp->getZAxisTitle(), uno::UNO_QUERY );
    2193           0 :             if( bHasZAxisMajorGrid )
    2194           0 :                 xMajorGrid.set( xAxisZSupp->getZMainGrid(), uno::UNO_QUERY );
    2195           0 :             if( bHasZAxisMinorGrid )
    2196           0 :                 xMinorGrid.set( xAxisZSupp->getZHelpGrid(), uno::UNO_QUERY );
    2197             : 
    2198           0 :             sal_Int32 eChartType = getChartType( );
    2199           0 :             if( (eChartType == chart::TYPEID_SCATTER)
    2200           0 :                 || (eChartType == chart::TYPEID_BUBBLE) )
    2201           0 :                 nAxisType = XML_valAx;
    2202           0 :             else if( eChartType == chart::TYPEID_STOCK )
    2203           0 :                 nAxisType = XML_dateAx;
    2204             :             // FIXME: axPos, need to check axis direction
    2205           0 :             sAxPos = "b";
    2206           0 :             break;
    2207             :         }
    2208             :         case AXIS_SECONDARY_Y:
    2209             :         {
    2210           6 :             Reference< ::com::sun::star::chart::XTwoAxisYSupplier > xAxisTwoYSupp( mxDiagram, uno::UNO_QUERY );
    2211           6 :             if( xAxisTwoYSupp.is())
    2212           6 :                 xAxisProp = xAxisTwoYSupp->getSecondaryYAxis();
    2213           6 :             if( bHasSecondaryYAxisTitle )
    2214             :             {
    2215           0 :                 Reference< ::com::sun::star::chart::XSecondAxisTitleSupplier > xAxisSupp( mxDiagram, uno::UNO_QUERY );
    2216           0 :                 xAxisTitle.set( xAxisSupp->getSecondYAxisTitle(), uno::UNO_QUERY );
    2217             :             }
    2218             : 
    2219           6 :             nAxisType = XML_valAx;
    2220             :             // FIXME: axPos, need to check axis direction
    2221           6 :             sAxPos = "l";
    2222           6 :             break;
    2223             :         }
    2224             :     }
    2225             : 
    2226         312 :     _exportAxis( xAxisProp, xAxisTitle, xMajorGrid, xMinorGrid, nAxisType, sAxPos, aAxisIdPair );
    2227         156 : }
    2228             : 
    2229         156 : void ChartExport::_exportAxis(
    2230             :     const Reference< XPropertySet >& xAxisProp,
    2231             :     const Reference< drawing::XShape >& xAxisTitle,
    2232             :     const Reference< XPropertySet >& xMajorGrid,
    2233             :     const Reference< XPropertySet >& xMinorGrid,
    2234             :     sal_Int32 nAxisType,
    2235             :     const char* sAxisPos,
    2236             :     AxisIdPair aAxisIdPair )
    2237             : {
    2238         156 :     FSHelperPtr pFS = GetFS();
    2239             :     pFS->startElement( FSNS( XML_c, nAxisType ),
    2240         156 :             FSEND );
    2241             :     pFS->singleElement( FSNS( XML_c, XML_axId ),
    2242             :             XML_val, I32S( aAxisIdPair.nAxisId ),
    2243         156 :             FSEND );
    2244             : 
    2245             :     pFS->startElement( FSNS( XML_c, XML_scaling ),
    2246         156 :             FSEND );
    2247             :     // logBase, min, max
    2248         156 :     if(GetProperty( xAxisProp, "Logarithmic" ) )
    2249             :     {
    2250         156 :         bool bLogarithmic = false;
    2251         156 :         mAny >>= bLogarithmic;
    2252         156 :         if( bLogarithmic )
    2253             :         {
    2254             :             // default value is 10?
    2255           2 :             sal_Int32 nLogBase = 10;
    2256             :             pFS->singleElement( FSNS( XML_c, XML_logBase ),
    2257             :                 XML_val, I32S( nLogBase ),
    2258           2 :                 FSEND );
    2259             :         }
    2260             :     }
    2261             : 
    2262             :     // orientation: minMax, maxMin
    2263         156 :     bool bReverseDirection = false;
    2264         156 :     if(GetProperty( xAxisProp, "ReverseDirection" ) )
    2265         156 :         mAny >>= bReverseDirection;
    2266             : 
    2267         156 :     const char* orientation = bReverseDirection ? "maxMin":"minMax";
    2268             :     pFS->singleElement( FSNS( XML_c, XML_orientation ),
    2269             :             XML_val, orientation,
    2270         156 :             FSEND );
    2271             : 
    2272         156 :     bool bAutoMax = false;
    2273         156 :     if(GetProperty( xAxisProp, "AutoMax" ) )
    2274         156 :         mAny >>= bAutoMax;
    2275             : 
    2276         156 :     if( !bAutoMax && (GetProperty( xAxisProp, "Max" ) ) )
    2277             :     {
    2278           0 :         double dMax = 0;
    2279           0 :         mAny >>= dMax;
    2280             :         pFS->singleElement( FSNS( XML_c, XML_max ),
    2281             :             XML_val, IS( dMax ),
    2282           0 :             FSEND );
    2283             :     }
    2284             : 
    2285         156 :     bool bAutoMin = false;
    2286         156 :     if(GetProperty( xAxisProp, "AutoMin" ) )
    2287         156 :         mAny >>= bAutoMin;
    2288             : 
    2289         156 :     if( !bAutoMin && (GetProperty( xAxisProp, "Min" ) ) )
    2290             :     {
    2291           4 :         double dMin = 0;
    2292           4 :         mAny >>= dMin;
    2293             :         pFS->singleElement( FSNS( XML_c, XML_min ),
    2294             :             XML_val, IS( dMin ),
    2295           4 :             FSEND );
    2296             :     }
    2297             : 
    2298         156 :     pFS->endElement( FSNS( XML_c, XML_scaling ) );
    2299             : 
    2300         156 :     bool bVisible = true;
    2301         156 :     if( xAxisProp.is() )
    2302             :     {
    2303         156 :         xAxisProp->getPropertyValue(
    2304         156 :             OUString ("Visible")) >>=  bVisible;
    2305             :     }
    2306             : 
    2307             :     pFS->singleElement( FSNS( XML_c, XML_delete ),
    2308             :             XML_val, bVisible ? "0" : "1",
    2309         156 :             FSEND );
    2310             : 
    2311             :     // FIXME: axPos, need to check the property "ReverseDirection"
    2312             :     pFS->singleElement( FSNS( XML_c, XML_axPos ),
    2313             :             XML_val, sAxisPos,
    2314         156 :             FSEND );
    2315             :     // major grid line
    2316         156 :     if( xMajorGrid.is())
    2317             :     {
    2318             :         pFS->startElement( FSNS( XML_c, XML_majorGridlines ),
    2319          76 :             FSEND );
    2320          76 :         exportShapeProps( xMajorGrid );
    2321          76 :         pFS->endElement( FSNS( XML_c, XML_majorGridlines ) );
    2322             :     }
    2323             : 
    2324             :     // minor grid line
    2325         156 :     if( xMinorGrid.is())
    2326             :     {
    2327             :         pFS->startElement( FSNS( XML_c, XML_minorGridlines ),
    2328          10 :             FSEND );
    2329          10 :         exportShapeProps( xMinorGrid );
    2330          10 :         pFS->endElement( FSNS( XML_c, XML_minorGridlines ) );
    2331             :     }
    2332             : 
    2333             :     // title
    2334         156 :     if( xAxisTitle.is() )
    2335          22 :         exportTitle( xAxisTitle );
    2336             : 
    2337             :     // majorTickMark
    2338         156 :     sal_Int32 nValue = 0;
    2339         156 :     if(GetProperty( xAxisProp, "Marks" ) )
    2340             :     {
    2341         156 :         mAny >>= nValue;
    2342         156 :         bool bInner = nValue & ::com::sun::star::chart::ChartAxisMarks::INNER;
    2343         156 :         bool bOuter = nValue & ::com::sun::star::chart::ChartAxisMarks::OUTER;
    2344         156 :         const char* majorTickMark = NULL;
    2345         156 :         if( bInner && bOuter )
    2346           2 :             majorTickMark = "cross";
    2347         154 :         else if( bInner )
    2348           0 :             majorTickMark = "in";
    2349         154 :         else if( bOuter )
    2350         118 :             majorTickMark = "out";
    2351             :         else
    2352          36 :             majorTickMark = "none";
    2353             :         pFS->singleElement( FSNS( XML_c, XML_majorTickMark ),
    2354             :             XML_val, majorTickMark,
    2355         156 :             FSEND );
    2356             :     }
    2357             :     // minorTickMark
    2358         156 :     if(GetProperty( xAxisProp, "HelpMarks" ) )
    2359             :     {
    2360         156 :         mAny >>= nValue;
    2361         156 :         bool bInner = nValue & ::com::sun::star::chart::ChartAxisMarks::INNER;
    2362         156 :         bool bOuter = nValue & ::com::sun::star::chart::ChartAxisMarks::OUTER;
    2363         156 :         const char* minorTickMark = NULL;
    2364         156 :         if( bInner && bOuter )
    2365           0 :             minorTickMark = "cross";
    2366         156 :         else if( bInner )
    2367           0 :             minorTickMark = "in";
    2368         156 :         else if( bOuter )
    2369           0 :             minorTickMark = "out";
    2370             :         else
    2371         156 :             minorTickMark = "none";
    2372             :         pFS->singleElement( FSNS( XML_c, XML_minorTickMark ),
    2373             :             XML_val, minorTickMark,
    2374         156 :             FSEND );
    2375             :     }
    2376             :     // tickLblPos
    2377         156 :     const char* sTickLblPos = NULL;
    2378         156 :     bool bDisplayLabel = true;
    2379         156 :     if(GetProperty( xAxisProp, "DisplayLabels" ) )
    2380         156 :         mAny >>= bDisplayLabel;
    2381         156 :     if( bDisplayLabel && (GetProperty( xAxisProp, "LabelPosition" ) ) )
    2382             :     {
    2383         154 :         ::com::sun::star::chart::ChartAxisLabelPosition eLabelPosition = ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS;
    2384         154 :         mAny >>= eLabelPosition;
    2385         154 :         switch( eLabelPosition )
    2386             :         {
    2387             :             case ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS:
    2388             :             case ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS_OTHER_SIDE:
    2389         154 :                 sTickLblPos = "nextTo";
    2390         154 :                 break;
    2391             :             case ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START:
    2392           0 :                 sTickLblPos = "low";
    2393           0 :                 break;
    2394             :             case ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END:
    2395           0 :                 sTickLblPos = "high";
    2396           0 :                 break;
    2397             :             default:
    2398           0 :                 sTickLblPos = "nextTo";
    2399           0 :                 break;
    2400             :         }
    2401             :     }
    2402             :     else
    2403             :     {
    2404           2 :         sTickLblPos = "none";
    2405             :     }
    2406             :     pFS->singleElement( FSNS( XML_c, XML_tickLblPos ),
    2407             :             XML_val, sTickLblPos,
    2408         156 :             FSEND );
    2409             : 
    2410             :     // shape properties
    2411         156 :     exportShapeProps( xAxisProp );
    2412             : 
    2413             :     pFS->singleElement( FSNS( XML_c, XML_crossAx ),
    2414             :             XML_val, I32S( aAxisIdPair.nCrossAx ),
    2415         156 :             FSEND );
    2416             : 
    2417             :     // crosses & crossesAt
    2418         156 :     bool bCrossesValue = false;
    2419         156 :     const char* sCrosses = NULL;
    2420         156 :     if(GetProperty( xAxisProp, "CrossoverPosition" ) )
    2421             :     {
    2422         156 :         ::com::sun::star::chart::ChartAxisPosition ePosition( ::com::sun::star::chart::ChartAxisPosition_ZERO );
    2423         156 :         mAny >>= ePosition;
    2424         156 :         switch( ePosition )
    2425             :         {
    2426             :             case ::com::sun::star::chart::ChartAxisPosition_START:
    2427           0 :                 sCrosses = "min";
    2428           0 :                 break;
    2429             :             case ::com::sun::star::chart::ChartAxisPosition_END:
    2430           6 :                 sCrosses = "max";
    2431           6 :                 break;
    2432             :             case ::com::sun::star::chart::ChartAxisPosition_ZERO:
    2433         150 :                 sCrosses = "autoZero";
    2434         150 :                 break;
    2435             :             default:
    2436           0 :                 bCrossesValue = true;
    2437           0 :                 break;
    2438             :         }
    2439             :     }
    2440             : 
    2441         156 :     if( bCrossesValue && GetProperty( xAxisProp, "CrossoverValue" ) )
    2442             :     {
    2443           0 :         double dValue = 0;
    2444           0 :         mAny >>= dValue;
    2445             :         pFS->singleElement( FSNS( XML_c, XML_crossesAt ),
    2446             :             XML_val, IS( dValue ),
    2447           0 :             FSEND );
    2448             :     }
    2449             :     else
    2450             :     {
    2451             :         pFS->singleElement( FSNS( XML_c, XML_crosses ),
    2452             :             XML_val, sCrosses,
    2453         156 :             FSEND );
    2454             :     }
    2455             : 
    2456         156 :     if( ( nAxisType == XML_catAx )
    2457          92 :         || ( nAxisType == XML_dateAx ) )
    2458             :     {
    2459             :         // FIXME: seems not support? use default value,
    2460          68 :         const char* isAuto = "1";
    2461             :         pFS->singleElement( FSNS( XML_c, XML_auto ),
    2462             :             XML_val, isAuto,
    2463          68 :             FSEND );
    2464             : 
    2465          68 :         if( nAxisType == XML_catAx )
    2466             :         {
    2467             :             // FIXME: seems not support? lblAlgn
    2468          64 :             const char* sLblAlgn = "ctr";
    2469             :             pFS->singleElement( FSNS( XML_c, XML_lblAlgn ),
    2470             :                     XML_val, sLblAlgn,
    2471          64 :                     FSEND );
    2472             :         }
    2473             : 
    2474             :         // FIXME: seems not support? lblOffset
    2475          68 :         sal_Int32 nLblOffset = 100;
    2476             :         pFS->singleElement( FSNS( XML_c, XML_lblOffset ),
    2477             :             XML_val, I32S( nLblOffset ),
    2478          68 :             FSEND );
    2479             :     }
    2480             : 
    2481             :     // majorUnit
    2482         156 :     bool bAutoStepMain = false;
    2483         156 :     if(GetProperty( xAxisProp, "AutoStepMain" ) )
    2484         156 :         mAny >>= bAutoStepMain;
    2485             : 
    2486         156 :     if( !bAutoStepMain && (GetProperty( xAxisProp, "StepMain" ) ) )
    2487             :     {
    2488           0 :         double dMajorUnit = 0;
    2489           0 :         mAny >>= dMajorUnit;
    2490             :         pFS->singleElement( FSNS( XML_c, XML_majorUnit ),
    2491             :             XML_val, IS( dMajorUnit ),
    2492           0 :             FSEND );
    2493             :     }
    2494             :     // minorUnit
    2495         156 :     bool bAutoStepHelp = false;
    2496         156 :     if(GetProperty( xAxisProp, "AutoStepHelp" ) )
    2497         156 :         mAny >>= bAutoStepHelp;
    2498             : 
    2499         156 :     if( !bAutoStepHelp && (GetProperty( xAxisProp, "StepHelp" ) ) )
    2500             :     {
    2501           0 :         double dMinorUnit = 0;
    2502           0 :         mAny >>= dMinorUnit;
    2503             :         pFS->singleElement( FSNS( XML_c, XML_minorUnit ),
    2504             :             XML_val, IS( dMinorUnit ),
    2505           0 :             FSEND );
    2506             :     }
    2507             : 
    2508         156 :     bool bDisplayUnits = false;
    2509         156 :     if( nAxisType == XML_valAx && GetProperty( xAxisProp, "DisplayUnits" ) )
    2510             :     {
    2511          88 :         mAny >>= bDisplayUnits;
    2512          88 :         if(bDisplayUnits)
    2513             :         {
    2514           2 :             OUString aVal;
    2515           2 :             if(GetProperty( xAxisProp, "BuiltInUnit" ))
    2516             :             {
    2517           2 :                 mAny >>= aVal;
    2518           2 :                 if(!aVal.isEmpty())
    2519             :                 {
    2520             :                     pFS->startElement( FSNS( XML_c, XML_dispUnits ),
    2521           2 :                             FSEND );
    2522             : 
    2523           2 :                     OString aBuiltInUnit = OUStringToOString(aVal, RTL_TEXTENCODING_UTF8);
    2524             :                     pFS->singleElement( FSNS( XML_c, XML_builtInUnit ),
    2525             :                             XML_val, aBuiltInUnit.getStr(),
    2526           2 :                             FSEND );
    2527             : 
    2528           2 :                     pFS->singleElement(FSNS( XML_c, XML_dispUnitsLbl ),FSEND);
    2529           2 :                     pFS->endElement( FSNS( XML_c, XML_dispUnits ) );
    2530             :                 }
    2531           2 :              }
    2532             :         }
    2533             :     }
    2534             :     // TODO: text properties
    2535             : 
    2536         156 :     pFS->endElement( FSNS( XML_c, nAxisType ) );
    2537         156 : }
    2538             : 
    2539             : namespace {
    2540             : 
    2541         168 : struct LabelPlacementParam
    2542             : {
    2543             :     bool mbExport;
    2544             :     sal_Int32 meDefault;
    2545             : 
    2546             :     boost::unordered_set<sal_Int32> maAllowedValues;
    2547             : 
    2548         168 :     LabelPlacementParam() :
    2549             :         mbExport(true),
    2550         168 :         meDefault(css::chart::DataLabelPlacement::OUTSIDE) {}
    2551             : 
    2552         168 :     void allowAll()
    2553             :     {
    2554         168 :         maAllowedValues.insert(css::chart::DataLabelPlacement::OUTSIDE);
    2555         168 :         maAllowedValues.insert(css::chart::DataLabelPlacement::INSIDE);
    2556         168 :         maAllowedValues.insert(css::chart::DataLabelPlacement::CENTER);
    2557         168 :         maAllowedValues.insert(css::chart::DataLabelPlacement::NEAR_ORIGIN);
    2558         168 :         maAllowedValues.insert(css::chart::DataLabelPlacement::TOP);
    2559         168 :         maAllowedValues.insert(css::chart::DataLabelPlacement::BOTTOM);
    2560         168 :         maAllowedValues.insert(css::chart::DataLabelPlacement::LEFT);
    2561         168 :         maAllowedValues.insert(css::chart::DataLabelPlacement::RIGHT);
    2562         168 :         maAllowedValues.insert(css::chart::DataLabelPlacement::AVOID_OVERLAP);
    2563         168 :     }
    2564             : };
    2565             : 
    2566         152 : const char* toOOXMLPlacement( sal_Int32 nPlacement )
    2567             : {
    2568         152 :     switch (nPlacement)
    2569             :     {
    2570           0 :         case css::chart::DataLabelPlacement::OUTSIDE:       return "outEnd";
    2571           2 :         case css::chart::DataLabelPlacement::INSIDE:        return "inEnd";
    2572          70 :         case css::chart::DataLabelPlacement::CENTER:        return "ctr";
    2573           4 :         case css::chart::DataLabelPlacement::NEAR_ORIGIN:   return "inBase";
    2574           0 :         case css::chart::DataLabelPlacement::TOP:           return "t";
    2575           0 :         case css::chart::DataLabelPlacement::BOTTOM:        return "b";
    2576           0 :         case css::chart::DataLabelPlacement::LEFT:          return "l";
    2577          10 :         case css::chart::DataLabelPlacement::RIGHT:         return "r";
    2578          66 :         case css::chart::DataLabelPlacement::AVOID_OVERLAP: return "bestFit";
    2579             :         default:
    2580             :             ;
    2581             :     }
    2582             : 
    2583           0 :     return "outEnd";
    2584             : }
    2585             : 
    2586         264 : void writeLabelProperties(
    2587             :     FSHelperPtr pFS, const uno::Reference<beans::XPropertySet>& xPropSet, const LabelPlacementParam& rLabelParam )
    2588             : {
    2589         264 :     if (!xPropSet.is())
    2590         264 :         return;
    2591             : 
    2592         264 :     chart2::DataPointLabel aLabel;
    2593         264 :     sal_Int32 nLabelBorderWidth = 0;
    2594         264 :     sal_Int32 nLabelBorderColor = 0x00FFFFFF;
    2595             : 
    2596         264 :     xPropSet->getPropertyValue("Label") >>= aLabel;
    2597         264 :     xPropSet->getPropertyValue("LabelBorderWidth") >>= nLabelBorderWidth;
    2598         264 :     xPropSet->getPropertyValue("LabelBorderColor") >>= nLabelBorderColor;
    2599             : 
    2600         264 :     if (nLabelBorderWidth > 0)
    2601             :     {
    2602          34 :         pFS->startElement(FSNS(XML_c, XML_spPr), FSEND);
    2603          34 :         pFS->startElement(FSNS(XML_a, XML_ln), XML_w, IS(convertHmmToEmu(nLabelBorderWidth)), FSEND);
    2604          34 :         pFS->startElement(FSNS(XML_a, XML_solidFill), FSEND);
    2605             : 
    2606          34 :         OString aStr = OString::number(nLabelBorderColor, 16).toAsciiUpperCase();
    2607          34 :         pFS->singleElement(FSNS(XML_a, XML_srgbClr), XML_val, aStr.getStr(), FSEND);
    2608             : 
    2609          34 :         pFS->endElement(FSNS(XML_a, XML_solidFill));
    2610          34 :         pFS->endElement(FSNS(XML_a, XML_ln));
    2611          34 :         pFS->endElement(FSNS(XML_c, XML_spPr));
    2612             :     }
    2613             : 
    2614         264 :     if (rLabelParam.mbExport)
    2615             :     {
    2616         160 :         sal_Int32 nLabelPlacement = rLabelParam.meDefault;
    2617         160 :         if (xPropSet->getPropertyValue("LabelPlacement") >>= nLabelPlacement)
    2618             :         {
    2619         152 :             if (!rLabelParam.maAllowedValues.count(nLabelPlacement))
    2620          62 :                 nLabelPlacement = rLabelParam.meDefault;
    2621         152 :             pFS->singleElement(FSNS(XML_c, XML_dLblPos), XML_val, toOOXMLPlacement(nLabelPlacement), FSEND);
    2622             :         }
    2623             :     }
    2624             : 
    2625         264 :     pFS->singleElement(FSNS(XML_c, XML_showLegendKey), XML_val, BS(aLabel.ShowLegendSymbol), FSEND);
    2626         264 :     pFS->singleElement(FSNS(XML_c, XML_showVal), XML_val, BS(aLabel.ShowNumber), FSEND);
    2627         264 :     pFS->singleElement(FSNS(XML_c, XML_showCatName), XML_val, BS(aLabel.ShowCategoryName), FSEND);
    2628         264 :     pFS->singleElement(FSNS(XML_c, XML_showSerName), XML_val, BS(false), FSEND);
    2629         264 :     pFS->singleElement(FSNS(XML_c, XML_showPercent), XML_val, BS(aLabel.ShowNumberInPercent), FSEND);
    2630             : }
    2631             : 
    2632             : }
    2633             : 
    2634         172 : void ChartExport::exportDataLabels(
    2635             :     const uno::Reference<chart2::XDataSeries> & xSeries, sal_Int32 nSeriesLength, sal_Int32 eChartType )
    2636             : {
    2637         172 :     if (!xSeries.is() || nSeriesLength <= 0)
    2638           8 :         return;
    2639             : 
    2640         168 :     uno::Reference<beans::XPropertySet> xPropSet(xSeries, uno::UNO_QUERY);
    2641         168 :     if (!xPropSet.is())
    2642           0 :         return;
    2643             : 
    2644         336 :     FSHelperPtr pFS = GetFS();
    2645         168 :     pFS->startElement(FSNS(XML_c, XML_dLbls), FSEND);
    2646             : 
    2647         336 :     uno::Sequence<sal_Int32> aAttrLabelIndices;
    2648         168 :     xPropSet->getPropertyValue("AttributedDataPoints") >>= aAttrLabelIndices;
    2649             : 
    2650             :     // We must not export label placement property when the chart type doesn't
    2651             :     // support this option in MS Office, else MS Office would think the file
    2652             :     // is corrupt & refuse to open it.
    2653             : 
    2654         168 :     const chart::TypeGroupInfo& rInfo = chart::GetTypeGroupInfo(static_cast<chart::TypeId>(eChartType));
    2655         336 :     LabelPlacementParam aParam;
    2656         168 :     aParam.mbExport = !mbIs3DChart;
    2657         168 :     aParam.meDefault = rInfo.mnDefLabelPos;
    2658         168 :     aParam.allowAll();
    2659         168 :     switch (getChartType()) // diagram chart type
    2660             :     {
    2661             :         case chart::TYPEID_PIE:
    2662             :             // All pie charts support label placement.
    2663          10 :             aParam.mbExport = true;
    2664          10 :         break;
    2665             :         case chart::TYPEID_DOUGHNUT:
    2666             :         case chart::TYPEID_AREA:
    2667             :         case chart::TYPEID_RADARLINE:
    2668             :         case chart::TYPEID_RADARAREA:
    2669             :             // These chart types don't support label placement.
    2670          14 :             aParam.mbExport = false;
    2671          14 :         break;
    2672             :         case chart::TYPEID_BAR:
    2673         126 :             if (mbStacked || mbPercent || mbClustered)
    2674             :             {
    2675         126 :                 aParam.maAllowedValues.clear();
    2676         126 :                 aParam.maAllowedValues.insert(css::chart::DataLabelPlacement::CENTER);
    2677         126 :                 aParam.maAllowedValues.insert(css::chart::DataLabelPlacement::INSIDE);
    2678         126 :                 aParam.maAllowedValues.insert(css::chart::DataLabelPlacement::NEAR_ORIGIN);
    2679         126 :                 aParam.meDefault = css::chart::DataLabelPlacement::CENTER;
    2680             :             }
    2681         126 :         break;
    2682             :         default:
    2683             :             ;
    2684             :     }
    2685             : 
    2686         168 :     const sal_Int32* p = aAttrLabelIndices.getConstArray();
    2687         168 :     const sal_Int32* pEnd = p + aAttrLabelIndices.getLength();
    2688         264 :     for (; p != pEnd; ++p)
    2689             :     {
    2690          96 :         sal_Int32 nIdx = *p;
    2691          96 :         uno::Reference<beans::XPropertySet> xLabelPropSet = xSeries->getDataPointByIndex(nIdx);
    2692          96 :         if (!xLabelPropSet.is())
    2693           0 :             continue;
    2694             : 
    2695             :         // Individual label property that overwrites the baseline.
    2696          96 :         pFS->startElement(FSNS(XML_c, XML_dLbl), FSEND);
    2697          96 :         pFS->singleElement(FSNS(XML_c, XML_idx), XML_val, I32S(nIdx), FSEND);
    2698          96 :         writeLabelProperties(pFS, xLabelPropSet, aParam);
    2699          96 :         pFS->endElement(FSNS(XML_c, XML_dLbl));
    2700          96 :     }
    2701             : 
    2702             :     // Baseline label properties for all labels.
    2703         168 :     writeLabelProperties(pFS, xPropSet, aParam);
    2704             : 
    2705         336 :     pFS->endElement(FSNS(XML_c, XML_dLbls));
    2706             : }
    2707             : 
    2708         186 : void ChartExport::exportDataPoints(
    2709             :     const uno::Reference< beans::XPropertySet > & xSeriesProperties,
    2710             :     sal_Int32 nSeriesLength )
    2711             : {
    2712         186 :     uno::Reference< chart2::XDataSeries > xSeries( xSeriesProperties, uno::UNO_QUERY );
    2713         186 :     bool bVaryColorsByPoint = false;
    2714         372 :     Sequence< sal_Int32 > aDataPointSeq;
    2715         186 :     if( xSeriesProperties.is())
    2716             :     {
    2717         186 :         Any aAny = xSeriesProperties->getPropertyValue(
    2718         186 :             OUString(  "AttributedDataPoints" ));
    2719         186 :         aAny >>= aDataPointSeq;
    2720         186 :         xSeriesProperties->getPropertyValue(
    2721         186 :             OUString(  "VaryColorsByPoint" )) >>= bVaryColorsByPoint;
    2722             :     }
    2723             : 
    2724         186 :     const sal_Int32 * pPoints = aDataPointSeq.getConstArray();
    2725             :     sal_Int32 nElement;
    2726         372 :     Reference< chart2::XColorScheme > xColorScheme;
    2727         186 :     if( mxNewDiagram.is())
    2728         186 :         xColorScheme.set( mxNewDiagram->getDefaultColorScheme());
    2729             : 
    2730         186 :     if( bVaryColorsByPoint && xColorScheme.is() )
    2731             :     {
    2732          14 :         ::std::set< sal_Int32 > aAttrPointSet;
    2733          14 :         ::std::copy( pPoints, pPoints + aDataPointSeq.getLength(),
    2734          28 :                     ::std::inserter( aAttrPointSet, aAttrPointSet.begin()));
    2735          14 :         const ::std::set< sal_Int32 >::const_iterator aEndIt( aAttrPointSet.end());
    2736          86 :         for( nElement = 0; nElement < nSeriesLength; ++nElement )
    2737             :         {
    2738          72 :             uno::Reference< beans::XPropertySet > xPropSet;
    2739          72 :             if( aAttrPointSet.find( nElement ) != aEndIt )
    2740             :             {
    2741             :                 try
    2742             :                 {
    2743         144 :                     xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
    2744          72 :                             xSeries, nElement, getModel() );
    2745             :                 }
    2746           0 :                 catch( const uno::Exception & rEx )
    2747             :                 {
    2748             :                     SAL_WARN( "oox", "Exception caught during Export of data point: " << rEx.Message );
    2749             :                 }
    2750             :             }
    2751             :             else
    2752             :             {
    2753             :                 // property set only containing the color
    2754           0 :                 xPropSet.set( new ColorPropertySet( xColorScheme->getColorByIndex( nElement )));
    2755             :             }
    2756             : 
    2757          72 :             if( xPropSet.is() )
    2758             :             {
    2759             :                 OSL_TRACE("ChartExport::exportDataPoints -- writer data points ");
    2760          72 :                 FSHelperPtr pFS = GetFS();
    2761             :                 pFS->startElement( FSNS( XML_c, XML_dPt ),
    2762          72 :                     FSEND );
    2763             :                 pFS->singleElement( FSNS( XML_c, XML_idx ),
    2764             :                     XML_val, I32S(nElement),
    2765          72 :                     FSEND );
    2766          72 :                 exportShapeProps( xPropSet );
    2767             : 
    2768          72 :                 pFS->endElement( FSNS( XML_c, XML_dPt ) );
    2769             :             }
    2770          86 :         }
    2771         186 :     }
    2772         186 : }
    2773             : 
    2774          78 : void ChartExport::exportAxesId( sal_Int32 nAttachedAxis )
    2775             : {
    2776          78 :     sal_Int32 nAxisIdx = lcl_generateRandomValue();
    2777          78 :     sal_Int32 nAxisIdy = lcl_generateRandomValue();
    2778          78 :     maAxes.push_back( AxisIdPair( AXIS_PRIMARY_X, nAxisIdx, nAxisIdy ) );
    2779          78 :     maAxes.push_back( AxisIdPair( nAttachedAxis, nAxisIdy, nAxisIdx ) );
    2780          78 :     FSHelperPtr pFS = GetFS();
    2781             :     pFS->singleElement( FSNS( XML_c, XML_axId ),
    2782             :             XML_val, I32S( nAxisIdx ),
    2783          78 :             FSEND );
    2784             :     pFS->singleElement( FSNS( XML_c, XML_axId ),
    2785             :             XML_val, I32S( nAxisIdy ),
    2786          78 :             FSEND );
    2787          78 :     if( mbHasZAxis )
    2788             :     {
    2789          22 :         sal_Int32 nAxisIdz = 0;
    2790          22 :         if( isDeep3dChart() )
    2791             :         {
    2792           0 :             nAxisIdz = lcl_generateRandomValue();
    2793           0 :             maAxes.push_back( AxisIdPair( AXIS_PRIMARY_Z, nAxisIdz, nAxisIdy ) );
    2794             :         }
    2795             :         pFS->singleElement( FSNS( XML_c, XML_axId ),
    2796             :             XML_val, I32S( nAxisIdz ),
    2797          22 :             FSEND );
    2798          78 :     }
    2799          78 : }
    2800             : 
    2801          64 : void ChartExport::exportGrouping( bool isBar )
    2802             : {
    2803          64 :     FSHelperPtr pFS = GetFS();
    2804         128 :     Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
    2805             :     // grouping
    2806          64 :     if( GetProperty( xPropSet, "Stacked" ) )
    2807          64 :         mAny >>= mbStacked;
    2808          64 :     if( GetProperty( xPropSet, "Percent" ) )
    2809          64 :         mAny >>= mbPercent;
    2810             : 
    2811          64 :     const char* grouping = NULL;
    2812          64 :     if (mbStacked)
    2813           8 :         grouping = "stacked";
    2814          56 :     else if (mbPercent)
    2815          10 :         grouping = "percentStacked";
    2816             :     else
    2817             :     {
    2818          46 :         if( isBar && !isDeep3dChart() )
    2819             :         {
    2820          34 :             grouping = "clustered";
    2821          34 :             mbClustered = true;
    2822             :         }
    2823             :         else
    2824          12 :             grouping = "standard";
    2825             :     }
    2826             :     pFS->singleElement( FSNS( XML_c, XML_grouping ),
    2827             :             XML_val, grouping,
    2828         128 :             FSEND );
    2829          64 : }
    2830             : 
    2831         186 : void ChartExport::exportTrendlines( Reference< chart2::XDataSeries > xSeries )
    2832             : {
    2833         186 :     FSHelperPtr pFS = GetFS();
    2834         372 :     Reference< chart2::XRegressionCurveContainer > xRegressionCurveContainer( xSeries, UNO_QUERY );
    2835         186 :     if( xRegressionCurveContainer.is() )
    2836             :     {
    2837         186 :         Sequence< Reference< chart2::XRegressionCurve > > aRegCurveSeq = xRegressionCurveContainer->getRegressionCurves();
    2838         186 :         const Reference< chart2::XRegressionCurve >* pBeg = aRegCurveSeq.getConstArray();
    2839         186 :         const Reference< chart2::XRegressionCurve >* pEnd = pBeg + aRegCurveSeq.getLength();
    2840         192 :         for( const Reference< chart2::XRegressionCurve >* pIt = pBeg; pIt != pEnd; ++pIt )
    2841             :         {
    2842           6 :             Reference< chart2::XRegressionCurve > xRegCurve = *pIt;
    2843           6 :             if (!xRegCurve.is())
    2844           0 :                 continue;
    2845             : 
    2846          12 :             Reference< XPropertySet > xProperties( xRegCurve , uno::UNO_QUERY );
    2847             : 
    2848          12 :             OUString aService;
    2849          12 :             Reference< lang::XServiceName > xServiceName( xProperties, UNO_QUERY );
    2850           6 :             if( !xServiceName.is() )
    2851           0 :                 continue;
    2852             : 
    2853           6 :             aService = xServiceName->getServiceName();
    2854             : 
    2855          16 :             if(aService != "com.sun.star.chart2.LinearRegressionCurve" &&
    2856           8 :                     aService != "com.sun.star.chart2.ExponentialRegressionCurve" &&
    2857           8 :                     aService != "com.sun.star.chart2.LogarithmicRegressionCurve" &&
    2858           8 :                     aService != "com.sun.star.chart2.PotentialRegressionCurve" &&
    2859          12 :                     aService != "com.sun.star.chart2.PolynomialRegressionCurve" &&
    2860           2 :                     aService != "com.sun.star.chart2.MovingAverageRegressionCurve")
    2861           0 :                 continue;
    2862             : 
    2863           6 :             pFS->startElement( FSNS( XML_c, XML_trendline ), FSEND );
    2864             : 
    2865          12 :             OUString aName;
    2866           6 :             xProperties->getPropertyValue("CurveName") >>= aName;
    2867           6 :             if(!aName.isEmpty())
    2868             :             {
    2869           6 :                 pFS->startElement( FSNS( XML_c, XML_name), FSEND);
    2870           6 :                 pFS->writeEscaped(aName);
    2871           6 :                 pFS->endElement( FSNS( XML_c, XML_name) );
    2872             :             }
    2873             : 
    2874           6 :             exportShapeProps( xProperties );
    2875             : 
    2876           6 :             if( aService == "com.sun.star.chart2.LinearRegressionCurve" )
    2877             :             {
    2878             :                 pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
    2879             :                     XML_val, "linear",
    2880           2 :                     FSEND );
    2881             :             }
    2882           4 :             else if( aService == "com.sun.star.chart2.ExponentialRegressionCurve" )
    2883             :             {
    2884             :                 pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
    2885             :                     XML_val, "exp",
    2886           0 :                     FSEND );
    2887             :             }
    2888           4 :             else if( aService == "com.sun.star.chart2.LogarithmicRegressionCurve" )
    2889             :             {
    2890             :                 pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
    2891             :                     XML_val, "log",
    2892           0 :                     FSEND );
    2893             :             }
    2894           4 :             else if( aService == "com.sun.star.chart2.PotentialRegressionCurve" )
    2895             :             {
    2896             :                 pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
    2897             :                     XML_val, "power",
    2898           0 :                     FSEND );
    2899             :             }
    2900           4 :             else if( aService == "com.sun.star.chart2.PolynomialRegressionCurve" )
    2901             :             {
    2902             :                 pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
    2903             :                     XML_val, "poly",
    2904           2 :                     FSEND );
    2905             : 
    2906           2 :                 sal_Int32 aDegree = 2;
    2907           2 :                 xProperties->getPropertyValue( "PolynomialDegree") >>= aDegree;
    2908             :                 pFS->singleElement( FSNS( XML_c, XML_order ),
    2909             :                     XML_val, I32S(aDegree),
    2910           2 :                     FSEND );
    2911             :             }
    2912           2 :             else if( aService == "com.sun.star.chart2.MovingAverageRegressionCurve" )
    2913             :             {
    2914             :                 pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
    2915             :                     XML_val, "movingAvg",
    2916           2 :                     FSEND );
    2917             : 
    2918           2 :                 sal_Int32 aPeriod = 2;
    2919           2 :                 xProperties->getPropertyValue( "MovingAveragePeriod") >>= aPeriod;
    2920             : 
    2921             :                 pFS->singleElement( FSNS( XML_c, XML_period ),
    2922             :                     XML_val, I32S(aPeriod),
    2923           2 :                     FSEND );
    2924             :             }
    2925             :             else
    2926             :             {
    2927             :                 // should never happen
    2928             :                 // This would produce invalid OOXML files so we check earlier for the type
    2929             :                 assert(false);
    2930             :             }
    2931             : 
    2932           6 :             double aExtrapolateForward = 0.0;
    2933           6 :             double aExtrapolateBackward = 0.0;
    2934             : 
    2935           6 :             xProperties->getPropertyValue("ExtrapolateForward") >>= aExtrapolateForward;
    2936           6 :             xProperties->getPropertyValue("ExtrapolateBackward") >>= aExtrapolateBackward;
    2937             : 
    2938             :             pFS->singleElement( FSNS( XML_c, XML_forward ),
    2939             :                     XML_val, OString::number(aExtrapolateForward).getStr(),
    2940           6 :                     FSEND );
    2941             : 
    2942             :             pFS->singleElement( FSNS( XML_c, XML_backward ),
    2943             :                     XML_val, OString::number(aExtrapolateBackward).getStr(),
    2944           6 :                     FSEND );
    2945             : 
    2946           6 :             bool aForceIntercept = false;
    2947           6 :             xProperties->getPropertyValue("ForceIntercept") >>= aForceIntercept;
    2948             : 
    2949           6 :             if (aForceIntercept)
    2950             :             {
    2951           2 :                 double aInterceptValue = 0.0;
    2952           2 :                 xProperties->getPropertyValue("InterceptValue") >>= aInterceptValue;
    2953             : 
    2954             :                 pFS->singleElement( FSNS( XML_c, XML_intercept ),
    2955             :                     XML_val, OString::number(aInterceptValue).getStr(),
    2956           2 :                     FSEND );
    2957             :             }
    2958             : 
    2959             :             // Equation properties
    2960          12 :             Reference< XPropertySet > xEquationProperties( xRegCurve->getEquationProperties() );
    2961             : 
    2962             :             // Show Equation
    2963           6 :             bool aShowEquation = false;
    2964           6 :             xEquationProperties->getPropertyValue("ShowEquation") >>= aShowEquation;
    2965             : 
    2966             :             // Show R^2
    2967           6 :             bool aShowCorrelationCoefficient = false;
    2968           6 :             xEquationProperties->getPropertyValue("ShowCorrelationCoefficient") >>= aShowCorrelationCoefficient;
    2969             : 
    2970             :             pFS->singleElement( FSNS( XML_c, XML_dispRSqr ),
    2971             :                     XML_val, aShowCorrelationCoefficient ? "1" : "0",
    2972           6 :                     FSEND );
    2973             : 
    2974             :             pFS->singleElement( FSNS( XML_c, XML_dispEq ),
    2975             :                     XML_val, aShowEquation ? "1" : "0",
    2976           6 :                     FSEND );
    2977             : 
    2978           6 :             pFS->endElement( FSNS( XML_c, XML_trendline ) );
    2979         192 :         }
    2980         186 :     }
    2981         186 : }
    2982             : 
    2983          44 : void ChartExport::exportMarker(Reference< chart2::XDataSeries > xSeries)
    2984             : {
    2985          44 :     Reference< XPropertySet > xPropSet( xSeries, uno::UNO_QUERY );
    2986          68 :     chart2::Symbol aSymbol;
    2987          44 :     if( GetProperty( xPropSet, "Symbol" ) )
    2988          44 :         mAny >>= aSymbol;
    2989             : 
    2990          44 :     if(aSymbol.Style != chart2::SymbolStyle_STANDARD && aSymbol.Style != chart2::SymbolStyle_AUTO)
    2991          64 :         return;
    2992             : 
    2993          48 :     FSHelperPtr pFS = GetFS();
    2994             :     pFS->startElement( FSNS( XML_c, XML_marker ),
    2995          24 :             FSEND );
    2996             : 
    2997          24 :     sal_Int32 nSymbol = aSymbol.StandardSymbol;
    2998             :     // TODO: more properties support for marker
    2999          24 :     const char* pSymbolType = NULL;
    3000          24 :     switch( nSymbol )
    3001             :     {
    3002             :         case 0:
    3003          14 :             pSymbolType = "square";
    3004          14 :             break;
    3005             :         case 1:
    3006           2 :             pSymbolType = "diamond";
    3007           2 :             break;
    3008             :         case 2:
    3009             :         case 3:
    3010             :         case 4:
    3011             :         case 5:
    3012           0 :             pSymbolType = "triangle";
    3013           0 :             break;
    3014             :         case 8:
    3015           0 :             pSymbolType = "circle";
    3016           0 :             break;
    3017             :         case 9:
    3018           0 :             pSymbolType = "star";
    3019           0 :             break;
    3020             :         case 10:
    3021           6 :             pSymbolType = "x"; // in MS office 2010 built in symbol marker 'X' is represented as 'x'
    3022           6 :             break;
    3023             :         case 11:
    3024           0 :             pSymbolType = "plus";
    3025           0 :             break;
    3026             :         case 13:
    3027           0 :             pSymbolType = "dash";
    3028           0 :             break;
    3029             :         default:
    3030           2 :             pSymbolType = "square";
    3031           2 :             break;
    3032             :     }
    3033             : 
    3034          24 :     if( pSymbolType )
    3035             :     {
    3036             :         pFS->singleElement( FSNS( XML_c, XML_symbol ),
    3037             :             XML_val, pSymbolType,
    3038          24 :             FSEND );
    3039             :     }
    3040             : 
    3041          24 :     awt::Size aSymbolSize = aSymbol.Size;
    3042          24 :     sal_Int32 nSize = std::max( aSymbolSize.Width, aSymbolSize.Height );
    3043             : 
    3044          24 :     nSize = nSize/250.0*7.0 + 1; // just guessed based on some test cases,
    3045             :                                 //the value is always 1 less than the actual value.
    3046          24 :     nSize = std::min<sal_Int32>( 72, std::max<sal_Int32>( 2, nSize ) );
    3047             :     pFS->singleElement( FSNS( XML_c, XML_size),
    3048             :             XML_val, I32S(nSize),
    3049          24 :             FSEND );
    3050             : 
    3051             :     pFS->startElement( FSNS( XML_c, XML_spPr ),
    3052          24 :             FSEND );
    3053          24 :     WriteSolidFill(aSymbol.FillColor);
    3054          24 :     pFS->endElement( FSNS( XML_c, XML_spPr ) );
    3055             : 
    3056          48 :     pFS->endElement( FSNS( XML_c, XML_marker ) );
    3057             : }
    3058             : 
    3059          44 : void ChartExport::exportSmooth()
    3060             : {
    3061          44 :     FSHelperPtr pFS = GetFS();
    3062          88 :     Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY );
    3063          44 :     sal_Int32 nSplineType = 0;
    3064          44 :     if( GetProperty( xPropSet, "SplineType" ) )
    3065          44 :         mAny >>= nSplineType;
    3066          44 :     const char* pVal = nSplineType != 0 ? "1" : "0";
    3067             :     pFS->singleElement( FSNS( XML_c, XML_smooth ),
    3068             :             XML_val, pVal,
    3069          88 :             FSEND );
    3070          44 : }
    3071             : 
    3072          10 : void ChartExport::exportFirstSliceAng( )
    3073             : {
    3074          10 :     FSHelperPtr pFS = GetFS();
    3075          10 :     sal_Int32 nStartingAngle = 0;
    3076          20 :     Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
    3077          10 :     if( GetProperty( xPropSet, "StartingAngle" ) )
    3078          10 :         mAny >>= nStartingAngle;
    3079             : 
    3080             :     // convert to ooxml angle
    3081          10 :     nStartingAngle = (450 - nStartingAngle ) % 360;
    3082             :     pFS->singleElement( FSNS( XML_c, XML_firstSliceAng ),
    3083             :             XML_val, I32S( nStartingAngle ),
    3084          20 :             FSEND );
    3085          10 : }
    3086             : 
    3087             : namespace {
    3088             : 
    3089           2 : const char* getErrorBarStyle(sal_Int32 nErrorBarStyle)
    3090             : {
    3091           2 :     switch(nErrorBarStyle)
    3092             :     {
    3093             :         case cssc::ErrorBarStyle::NONE:
    3094             :             // I have no idea how to map it to OOXML
    3095             :             // this approach is as good as any else
    3096           0 :             return "fixedVal";
    3097             :         case cssc::ErrorBarStyle::VARIANCE:
    3098           0 :             break;
    3099             :         case cssc::ErrorBarStyle::STANDARD_DEVIATION:
    3100           0 :             return "stdDev";
    3101             :         case cssc::ErrorBarStyle::ABSOLUTE:
    3102           0 :             return "fixedVal";
    3103             :         case cssc::ErrorBarStyle::RELATIVE:
    3104           2 :             return "percentage";
    3105             :         case cssc::ErrorBarStyle::ERROR_MARGIN:
    3106           0 :             break;
    3107             :         case cssc::ErrorBarStyle::STANDARD_ERROR:
    3108           0 :             return "stdErr";
    3109             :         case cssc::ErrorBarStyle::FROM_DATA:
    3110           0 :             return "cust";
    3111             :         default:
    3112             :             assert(false && "can't happen");
    3113             :     }
    3114           0 :     return NULL;
    3115             : }
    3116             : 
    3117           0 : Reference< chart2::data::XDataSequence>  getLabeledSequence(
    3118             :         const uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > >& aSequences,
    3119             :         bool bPositive )
    3120             : {
    3121           0 :     const OUString aRolePrefix( "error-bars" );
    3122           0 :     OUString aDirection;
    3123           0 :     if(bPositive)
    3124           0 :         aDirection = "positive";
    3125             :     else
    3126           0 :         aDirection = "negative";
    3127             : 
    3128           0 :     for( sal_Int32 nI=0; nI< aSequences.getLength(); ++nI )
    3129             :     {
    3130           0 :         if( aSequences[nI].is())
    3131             :         {
    3132           0 :             uno::Reference< chart2::data::XDataSequence > xSequence( aSequences[nI]->getValues());
    3133           0 :             uno::Reference< beans::XPropertySet > xSeqProp( xSequence, uno::UNO_QUERY_THROW );
    3134           0 :             OUString aRole;
    3135           0 :             if( ( xSeqProp->getPropertyValue(
    3136           0 :                             OUString( "Role" )) >>= aRole ) &&
    3137           0 :                     aRole.match( aRolePrefix ) && aRole.indexOf(aDirection) >= 0 )
    3138             :             {
    3139           0 :                 return xSequence;
    3140           0 :             }
    3141             :         }
    3142             :     }
    3143             : 
    3144           0 :     return Reference< chart2::data::XDataSequence > ();
    3145             : }
    3146             : 
    3147             : }
    3148             : 
    3149           2 : void ChartExport::exportErrorBar(Reference< XPropertySet> xErrorBarProps, bool bYError)
    3150             : {
    3151           2 :     sal_Int32 nErrorBarStyle = cssc::ErrorBarStyle::NONE;
    3152           2 :     xErrorBarProps->getPropertyValue("ErrorBarStyle") >>= nErrorBarStyle;
    3153           2 :     const char* pErrorBarStyle = getErrorBarStyle(nErrorBarStyle);
    3154           2 :     if(!pErrorBarStyle)
    3155           2 :         return;
    3156             : 
    3157           2 :     FSHelperPtr pFS = GetFS();
    3158             :     pFS->startElement( FSNS( XML_c, XML_errBars ),
    3159           2 :             FSEND );
    3160             :     pFS->singleElement( FSNS( XML_c, XML_errDir ),
    3161             :             XML_val, bYError ? "y" : "x",
    3162           2 :             FSEND );
    3163           2 :     bool bPositive = false, bNegative = false;
    3164           2 :     xErrorBarProps->getPropertyValue("ShowPositiveError") >>= bPositive;
    3165           2 :     xErrorBarProps->getPropertyValue("ShowNegativeError") >>= bNegative;
    3166             :     const char* pErrBarType;
    3167           2 :     if(bPositive && bNegative)
    3168           2 :         pErrBarType = "both";
    3169           0 :     else if(bPositive)
    3170           0 :         pErrBarType = "plus";
    3171           0 :     else if(bNegative)
    3172           0 :         pErrBarType = "minus";
    3173             :     else
    3174             :     {
    3175             :         // what the hell should we do now?
    3176             :         // at least this makes the file valid
    3177           0 :         pErrBarType = "both";
    3178             :     }
    3179             :     pFS->singleElement( FSNS( XML_c, XML_errBarType ),
    3180             :             XML_val, pErrBarType,
    3181           2 :             FSEND );
    3182             :     pFS->singleElement( FSNS( XML_c, XML_errValType ),
    3183             :             XML_val, pErrorBarStyle,
    3184           2 :             FSEND );
    3185             :     pFS->singleElement( FSNS( XML_c, XML_noEndCap ),
    3186             :             XML_val, "0",
    3187           2 :             FSEND );
    3188           2 :     if(nErrorBarStyle == cssc::ErrorBarStyle::FROM_DATA)
    3189             :     {
    3190           0 :         uno::Reference< chart2::data::XDataSource > xDataSource(xErrorBarProps, uno::UNO_QUERY);
    3191             :         Sequence< Reference < chart2::data::XLabeledDataSequence > > aSequences =
    3192           0 :             xDataSource->getDataSequences();
    3193             : 
    3194           0 :         if(bPositive)
    3195             :         {
    3196           0 :             exportSeriesValues(getLabeledSequence(aSequences, true), XML_plus);
    3197             :         }
    3198             : 
    3199           0 :         if(bNegative)
    3200             :         {
    3201           0 :             exportSeriesValues(getLabeledSequence(aSequences, false), XML_minus);
    3202           0 :         }
    3203             :     }
    3204             :     else
    3205             :     {
    3206           2 :         double nVal = 0.0;
    3207           2 :         if(nErrorBarStyle == cssc::ErrorBarStyle::STANDARD_DEVIATION)
    3208             :         {
    3209           0 :             xErrorBarProps->getPropertyValue("Weight") >>= nVal;
    3210             :         }
    3211             :         else
    3212             :         {
    3213           2 :             if(bPositive)
    3214           2 :                 xErrorBarProps->getPropertyValue("PositiveError") >>= nVal;
    3215             :             else
    3216           0 :                 xErrorBarProps->getPropertyValue("NegativeError") >>= nVal;
    3217             :         }
    3218             : 
    3219           2 :         OString aVal = OString::number(nVal);
    3220             : 
    3221             :         pFS->singleElement( FSNS( XML_c, XML_val ),
    3222             :                 XML_val, aVal.getStr(),
    3223           2 :                 FSEND );
    3224             :     }
    3225             : 
    3226           2 :     pFS->endElement( FSNS( XML_c, XML_errBars) );
    3227             : }
    3228             : 
    3229          26 : void ChartExport::exportView3D()
    3230             : {
    3231          26 :     Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
    3232          26 :     if( !xPropSet.is() )
    3233          26 :         return;
    3234          52 :     FSHelperPtr pFS = GetFS();
    3235             :     pFS->startElement( FSNS( XML_c, XML_view3D ),
    3236          26 :             FSEND );
    3237          26 :     sal_Int32 eChartType = getChartType( );
    3238             :     // rotX
    3239          26 :     if( GetProperty( xPropSet, "RotationHorizontal" ) )
    3240             :     {
    3241          26 :         sal_Int32 nRotationX = 0;
    3242          26 :         mAny >>= nRotationX;
    3243          26 :         if( nRotationX < 0 )
    3244             :         {
    3245           4 :             if(eChartType == chart::TYPEID_PIE)
    3246             :             {
    3247             :             /* In OOXML we get value in 0..90 range for pie chart X rotation , whereas we expect it to be in -90..90 range,
    3248             :                so we conver that during import. It  is modified in View3DConverter::convertFromModel()
    3249             :                here we convert it back to 0..90 as we received in import */
    3250           4 :                nRotationX += 90;  // X rotation (map Chart2 [-179,180] to OOXML [0..90])
    3251             :             }
    3252             :             else
    3253           0 :                 nRotationX += 360; // X rotation (map Chart2 [-179,180] to OOXML [-90..90])
    3254             :         }
    3255             :         pFS->singleElement( FSNS( XML_c, XML_rotX ),
    3256             :             XML_val, I32S( nRotationX ),
    3257          26 :             FSEND );
    3258             :     }
    3259             :     // rotY
    3260          26 :     if( GetProperty( xPropSet, "RotationVertical" ) )
    3261             :     {
    3262             :         // Y rotation (map Chart2 [-179,180] to OOXML [0..359])
    3263          26 :         if( eChartType == chart::TYPEID_PIE && GetProperty( xPropSet, "StartingAngle" ) )
    3264             :         {
    3265             :          // Y rotation used as 'first pie slice angle' in 3D pie charts
    3266           4 :             sal_Int32 nStartingAngle=0;
    3267           4 :             mAny >>= nStartingAngle;
    3268             :             // convert to ooxml angle
    3269           4 :             nStartingAngle = (450 - nStartingAngle ) % 360;
    3270             :             pFS->singleElement( FSNS( XML_c, XML_rotY ),
    3271             :                            XML_val, I32S( nStartingAngle ),
    3272           4 :                            FSEND );
    3273             :         }
    3274             :         else
    3275             :         {
    3276          22 :             sal_Int32 nRotationY = 0;
    3277          22 :             mAny >>= nRotationY;
    3278             :             // Y rotation (map Chart2 [-179,180] to OOXML [0..359])
    3279          22 :             if( nRotationY < 0 )
    3280           0 :                 nRotationY += 360;
    3281             :             pFS->singleElement( FSNS( XML_c, XML_rotY ),
    3282             :                             XML_val, I32S( nRotationY ),
    3283          22 :                             FSEND );
    3284             :         }
    3285             :     }
    3286             :     // rAngAx
    3287          26 :     if( GetProperty( xPropSet, "RightAngledAxes" ) )
    3288             :     {
    3289          26 :         bool bRightAngled = false;
    3290          26 :         mAny >>= bRightAngled;
    3291          26 :         const char* sRightAngled = bRightAngled ? "1":"0";
    3292             :         pFS->singleElement( FSNS( XML_c, XML_rAngAx ),
    3293             :             XML_val, sRightAngled,
    3294          26 :             FSEND );
    3295             :     }
    3296             :     // perspective
    3297          26 :     if( GetProperty( xPropSet, "Perspective" ) )
    3298             :     {
    3299          26 :         sal_Int32 nPerspective = 0;
    3300          26 :         mAny >>= nPerspective;
    3301             :         // map Chart2 [0,100] to OOXML [0..200]
    3302          26 :         nPerspective *= 2;
    3303             :         pFS->singleElement( FSNS( XML_c, XML_perspective ),
    3304             :             XML_val, I32S( nPerspective ),
    3305          26 :             FSEND );
    3306             :     }
    3307          52 :     pFS->endElement( FSNS( XML_c, XML_view3D ) );
    3308             : }
    3309             : 
    3310          56 : bool ChartExport::isDeep3dChart()
    3311             : {
    3312          56 :     bool isDeep = false;
    3313          56 :     if( mbIs3DChart )
    3314             :     {
    3315          34 :         Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
    3316          34 :         if( GetProperty( xPropSet, "Deep" ) )
    3317          34 :             mAny >>= isDeep;
    3318             :     }
    3319          56 :     return isDeep;
    3320             : }
    3321             : 
    3322             : }// drawingml
    3323         408 : }// oox
    3324             : 
    3325             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10