LCOV - code coverage report
Current view: top level - libreoffice/oox/source/export - chartexport.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1 1291 0.1 %
Date: 2012-12-17 Functions: 2 61 3.3 %
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 "oox/drawingml/chart/typegroupconverter.hxx"
      25             : 
      26             : #include <cstdio>
      27             : 
      28             : #include <com/sun/star/chart/XChartDocument.hpp>
      29             : #include <com/sun/star/chart/ChartLegendPosition.hpp>
      30             : #include <com/sun/star/chart/XTwoAxisXSupplier.hpp>
      31             : #include <com/sun/star/chart/XTwoAxisYSupplier.hpp>
      32             : #include <com/sun/star/chart/XAxisZSupplier.hpp>
      33             : #include <com/sun/star/chart/XChartDataArray.hpp>
      34             : #include <com/sun/star/chart/ChartDataRowSource.hpp>
      35             : #include <com/sun/star/chart/ChartAxisAssign.hpp>
      36             : #include <com/sun/star/chart/ChartSeriesAddress.hpp>
      37             : #include <com/sun/star/chart/X3DDisplay.hpp>
      38             : #include <com/sun/star/chart/XStatisticDisplay.hpp>
      39             : #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
      40             : #include <com/sun/star/chart/ChartSymbolType.hpp>
      41             : #include <com/sun/star/chart/ChartAxisMarks.hpp>
      42             : #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
      43             : #include <com/sun/star/chart/ChartAxisPosition.hpp>
      44             : #include <com/sun/star/chart/ChartSolidType.hpp>
      45             : 
      46             : #include <com/sun/star/chart2/XChartDocument.hpp>
      47             : #include <com/sun/star/chart2/XDiagram.hpp>
      48             : #include <com/sun/star/chart2/RelativePosition.hpp>
      49             : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
      50             : #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
      51             : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
      52             : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
      53             : #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
      54             : #include <com/sun/star/chart2/data/XDataSource.hpp>
      55             : #include <com/sun/star/chart2/data/XDataSink.hpp>
      56             : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
      57             : #include <com/sun/star/chart2/data/XDataProvider.hpp>
      58             : #include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
      59             : #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
      60             : #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
      61             : #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
      62             : 
      63             : #include <com/sun/star/beans/XPropertySet.hpp>
      64             : #include <com/sun/star/beans/XPropertyState.hpp>
      65             : #include <com/sun/star/container/XEnumerationAccess.hpp>
      66             : #include <com/sun/star/drawing/XShape.hpp>
      67             : #include <com/sun/star/drawing/FillStyle.hpp>
      68             : #include <com/sun/star/drawing/BitmapMode.hpp>
      69             : 
      70             : #include <com/sun/star/table/CellAddress.hpp>
      71             : #include <com/sun/star/sheet/XFormulaParser.hpp>
      72             : #include <com/sun/star/sheet/XFormulaTokens.hpp>
      73             : #include <com/sun/star/sheet/FormulaToken.hpp>
      74             : #include <com/sun/star/sheet/AddressConvention.hpp>
      75             : 
      76             : #include <com/sun/star/text/WritingMode.hpp>
      77             : #include <com/sun/star/container/XNamed.hpp>
      78             : 
      79             : #include <comphelper/processfactory.hxx>
      80             : #include "SchXMLSeriesHelper.hxx"
      81             : #include "ColorPropertySet.hxx"
      82             : #include <set>
      83             : #include <time.h>
      84             : 
      85             : using namespace ::com::sun::star;
      86             : using namespace ::com::sun::star::uno;
      87             : using namespace ::com::sun::star::drawing;
      88             : using namespace ::oox::core;
      89             : using ::com::sun::star::beans::PropertyState;
      90             : using ::com::sun::star::beans::PropertyValue;
      91             : using ::com::sun::star::beans::XPropertySet;
      92             : using ::com::sun::star::beans::XPropertyState;
      93             : using ::com::sun::star::container::XEnumeration;
      94             : using ::com::sun::star::container::XEnumerationAccess;
      95             : using ::com::sun::star::container::XIndexAccess;
      96             : using ::com::sun::star::container::XNamed;
      97             : using ::com::sun::star::io::XOutputStream;
      98             : using ::com::sun::star::table::CellAddress;
      99             : using ::com::sun::star::sheet::XFormulaParser;
     100             : using ::com::sun::star::sheet::XFormulaTokens;
     101             : using ::oox::core::XmlFilterBase;
     102             : using ::rtl::OString;
     103             : using ::rtl::OStringBuffer;
     104             : using ::rtl::OUString;
     105             : using ::rtl::OUStringBuffer;
     106             : using ::sax_fastparser::FSHelperPtr;
     107             : 
     108             : DBG(extern void dump_pset(Reference< XPropertySet > rXPropSet));
     109             : 
     110             : #define IDS(x) (OString(#x " ") + OString::valueOf( mnShapeIdMax++ )).getStr()
     111             : 
     112             : namespace oox { namespace drawingml {
     113             : 
     114             : #define GETA(propName) \
     115             :     GetProperty( rXPropSet, String(  #propName  ) )
     116             : 
     117             : #define GETAD(propName) \
     118             :     ( GetPropertyAndState( rXPropSet, rXPropState, String(  #propName  ), eState ) && eState == beans::PropertyState_DIRECT_VALUE )
     119             : 
     120             : #define GET(variable, propName) \
     121             :     if ( GETA(propName) ) \
     122             :         mAny >>= variable;
     123             : 
     124           0 : class lcl_MatchesRole : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool >
     125             : {
     126             : public:
     127           0 :     explicit lcl_MatchesRole( const OUString & aRole ) :
     128           0 :             m_aRole( aRole )
     129           0 :     {}
     130             : 
     131           0 :     bool operator () ( const Reference< chart2::data::XLabeledDataSequence > & xSeq ) const
     132             :     {
     133           0 :         if( !xSeq.is() )
     134           0 :             return  false;
     135           0 :         Reference< beans::XPropertySet > xProp( xSeq->getValues(), uno::UNO_QUERY );
     136           0 :         OUString aRole;
     137             : 
     138           0 :         return ( xProp.is() &&
     139           0 :                  (xProp->getPropertyValue(
     140           0 :                      OUString(  "Role" ) ) >>= aRole ) &&
     141           0 :                  m_aRole.equals( aRole ));
     142             :     }
     143             : 
     144             : private:
     145             :     OUString m_aRole;
     146             : };
     147             : 
     148             : template< typename T >
     149           0 :     void lcl_SequenceToVectorAppend( const Sequence< T > & rSource, ::std::vector< T > & rDestination )
     150             : {
     151           0 :     rDestination.reserve( rDestination.size() + rSource.getLength());
     152           0 :     ::std::copy( rSource.getConstArray(), rSource.getConstArray() + rSource.getLength(),
     153             :                  ::std::back_inserter( rDestination ));
     154           0 : }
     155             : 
     156           0 : Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const Reference< chart2::XDiagram > & xDiagram )
     157             : {
     158           0 :     Reference< chart2::data::XLabeledDataSequence >  xResult;
     159             :     try
     160             :     {
     161             :         Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
     162           0 :             xDiagram, uno::UNO_QUERY_THROW );
     163             :         Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
     164           0 :             xCooSysCnt->getCoordinateSystems());
     165           0 :         for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
     166             :         {
     167           0 :             Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[i] );
     168             :             OSL_ASSERT( xCooSys.is());
     169           0 :             for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
     170             :             {
     171           0 :                 const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
     172           0 :                 for(sal_Int32 nI=0; nI<=nMaxAxisIndex; ++nI)
     173             :                 {
     174           0 :                     Reference< chart2::XAxis > xAxis = xCooSys->getAxisByDimension( nN, nI );
     175             :                     OSL_ASSERT( xAxis.is());
     176           0 :                     if( xAxis.is())
     177             :                     {
     178           0 :                         chart2::ScaleData aScaleData = xAxis->getScaleData();
     179           0 :                         if( aScaleData.Categories.is())
     180             :                         {
     181           0 :                             xResult.set( aScaleData.Categories );
     182             :                             break;
     183           0 :                         }
     184             :                     }
     185           0 :                 }
     186             :             }
     187           0 :         }
     188             :     }
     189           0 :     catch( const uno::Exception & ex )
     190             :     {
     191             :         (void)ex; // avoid warning for pro build
     192             :         OSL_FAIL( rtl::OUStringToOString(
     193             :                         OUString(  "Exception caught. Type: " ) +
     194             :                         OUString::createFromAscii( typeid( ex ).name()) +
     195             :                         OUString(  ", Message: " ) +
     196             :                         ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
     197             :     }
     198             : 
     199           0 :     return xResult;
     200             : }
     201             : 
     202           0 : Reference< chart2::data::XDataSource > lcl_createDataSource(
     203             :     const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aData )
     204             : {
     205             :     Reference< uno::XComponentContext > xContext(
     206           0 :         comphelper::getProcessComponentContext() );
     207             :     Reference< chart2::data::XDataSink > xSink(
     208           0 :         xContext->getServiceManager()->createInstanceWithContext(
     209           0 :             "com.sun.star.chart2.data.DataSource", xContext ),
     210           0 :         uno::UNO_QUERY_THROW );
     211           0 :     if( xSink.is())
     212           0 :         xSink->setData( aData );
     213             : 
     214           0 :     return Reference< chart2::data::XDataSource >( xSink, uno::UNO_QUERY );
     215             : }
     216             : 
     217           0 : Sequence< Reference< chart2::data::XLabeledDataSequence > > lcl_getAllSeriesSequences( const Reference< chart2::XChartDocument >& xChartDoc )
     218             : {
     219           0 :     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aContainer;
     220           0 :     if( xChartDoc.is() )
     221             :     {
     222           0 :         Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
     223           0 :         ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( SchXMLSeriesHelper::getDataSeriesFromDiagram( xDiagram ));
     224           0 :         for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aSeriesIt( aSeriesVector.begin() )
     225           0 :             ; aSeriesIt != aSeriesVector.end(); ++aSeriesIt )
     226             :         {
     227           0 :             Reference< chart2::data::XDataSource > xDataSource( *aSeriesIt, uno::UNO_QUERY );
     228           0 :             if( !xDataSource.is() )
     229           0 :                 continue;
     230           0 :             uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > aDataSequences( xDataSource->getDataSequences() );
     231           0 :             lcl_SequenceToVectorAppend( aDataSequences, aContainer );
     232           0 :         }
     233             :     }
     234             : 
     235           0 :     Sequence< Reference< chart2::data::XLabeledDataSequence > > aRet( aContainer.size());
     236           0 :     ::std::copy( aContainer.begin(), aContainer.end(), aRet.getArray());
     237             : 
     238           0 :     return aRet;
     239             : }
     240             : 
     241             : Reference< chart2::data::XLabeledDataSequence >
     242           0 :     lcl_getDataSequenceByRole(
     243             :         const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aLabeledSeq,
     244             :         const OUString & rRole )
     245             : {
     246           0 :     Reference< chart2::data::XLabeledDataSequence > aNoResult;
     247             : 
     248           0 :     const Reference< chart2::data::XLabeledDataSequence > * pBegin = aLabeledSeq.getConstArray();
     249           0 :     const Reference< chart2::data::XLabeledDataSequence > * pEnd = pBegin + aLabeledSeq.getLength();
     250             :     const Reference< chart2::data::XLabeledDataSequence > * pMatch =
     251           0 :         ::std::find_if( pBegin, pEnd, lcl_MatchesRole( rRole ));
     252             : 
     253           0 :     if( pMatch != pEnd )
     254           0 :         return *pMatch;
     255             : 
     256           0 :     return aNoResult;
     257             : }
     258             : 
     259           0 : Reference< chart2::data::XDataSource > lcl_pressUsedDataIntoRectangularFormat( const Reference< chart2::XChartDocument >& xChartDoc, sal_Bool& rOutSourceHasCategoryLabels )
     260             : {
     261           0 :     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aLabeledSeqVector;
     262             : 
     263             :     //categories are always the first sequence
     264           0 :     Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
     265           0 :     Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xDiagram ) );
     266           0 :     if( xCategories.is() )
     267           0 :         aLabeledSeqVector.push_back( xCategories );
     268           0 :     rOutSourceHasCategoryLabels = sal_Bool(xCategories.is());
     269             : 
     270             :     Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeriesSeqVector(
     271           0 :             lcl_getAllSeriesSequences( xChartDoc ) );
     272             : 
     273             :     //the first x-values is always the next sequence //todo ... other x-values get lost for old format
     274             :     Reference< chart2::data::XLabeledDataSequence > xXValues(
     275           0 :         lcl_getDataSequenceByRole( aSeriesSeqVector, OUString("values-x") ) );
     276           0 :     if( xXValues.is() )
     277           0 :         aLabeledSeqVector.push_back( xXValues );
     278             : 
     279             :     //add all other sequences now without x-values
     280           0 :     lcl_MatchesRole aHasXValues( OUString("values-x") );
     281           0 :     for( sal_Int32 nN=0; nN<aSeriesSeqVector.getLength(); nN++ )
     282             :     {
     283           0 :         if( !aHasXValues( aSeriesSeqVector[nN] ) )
     284           0 :             aLabeledSeqVector.push_back( aSeriesSeqVector[nN] );
     285             :     }
     286             : 
     287           0 :     Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( aLabeledSeqVector.size() );
     288           0 :     ::std::copy( aLabeledSeqVector.begin(), aLabeledSeqVector.end(), aSeq.getArray() );
     289             : 
     290           0 :     return lcl_createDataSource( aSeq );
     291             : }
     292             : 
     293           0 : bool lcl_isSeriesAttachedToFirstAxis(
     294             :     const Reference< chart2::XDataSeries > & xDataSeries )
     295             : {
     296           0 :     bool bResult=true;
     297             : 
     298             :     try
     299             :     {
     300           0 :         sal_Int32 nAxisIndex = 0;
     301           0 :         Reference< beans::XPropertySet > xProp( xDataSeries, uno::UNO_QUERY_THROW );
     302           0 :         if( xProp.is() )
     303           0 :             xProp->getPropertyValue( OUString( "AttachedAxisIndex" ) ) >>= nAxisIndex;
     304           0 :         bResult = (0==nAxisIndex);
     305             :     }
     306           0 :     catch( const uno::Exception & ex )
     307             :     {
     308             :         (void)ex; // avoid warning for pro build
     309             :         OSL_FAIL( rtl::OUStringToOString(
     310             :                         OUString(  "Exception caught. Type: " ) +
     311             :                         OUString::createFromAscii( typeid( ex ).name()) +
     312             :                         OUString(  ", Message: " ) +
     313             :                         ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
     314             :     }
     315             : 
     316           0 :     return bResult;
     317             : }
     318             : 
     319           0 : OUString lcl_flattenStringSequence( const Sequence< OUString > & rSequence )
     320             : {
     321           0 :     OUStringBuffer aResult;
     322           0 :     bool bPrecedeWithSpace = false;
     323           0 :     for( sal_Int32 nIndex=0; nIndex<rSequence.getLength(); ++nIndex )
     324             :     {
     325           0 :         if( !rSequence[nIndex].isEmpty())
     326             :         {
     327           0 :             if( bPrecedeWithSpace )
     328           0 :                 aResult.append( static_cast< sal_Unicode >( ' ' ));
     329           0 :             aResult.append( rSequence[nIndex] );
     330           0 :             bPrecedeWithSpace = true;
     331             :         }
     332             :     }
     333           0 :     return aResult.makeStringAndClear();
     334             : }
     335             : 
     336           0 : OUString lcl_getLabelString( const Reference< chart2::data::XDataSequence > & xLabelSeq )
     337             : {
     338           0 :     Sequence< OUString > aLabels;
     339             : 
     340           0 :     uno::Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xLabelSeq, uno::UNO_QUERY );
     341           0 :     if( xTextualDataSequence.is())
     342             :     {
     343           0 :         aLabels = xTextualDataSequence->getTextualData();
     344             :     }
     345           0 :     else if( xLabelSeq.is())
     346             :     {
     347           0 :         Sequence< uno::Any > aAnies( xLabelSeq->getData());
     348           0 :         aLabels.realloc( aAnies.getLength());
     349           0 :         for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
     350           0 :             aAnies[i] >>= aLabels[i];
     351             :     }
     352             : 
     353           0 :     return lcl_flattenStringSequence( aLabels );
     354             : }
     355             : 
     356           0 : void lcl_fillCategoriesIntoStringVector(
     357             :     const Reference< chart2::data::XDataSequence > & xCategories,
     358             :     ::std::vector< OUString > & rOutCategories )
     359             : {
     360             :     OSL_ASSERT( xCategories.is());
     361           0 :     if( !xCategories.is())
     362           0 :         return;
     363           0 :     Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xCategories, uno::UNO_QUERY );
     364           0 :     if( xTextualDataSequence.is())
     365             :     {
     366           0 :         rOutCategories.clear();
     367           0 :         Sequence< OUString > aTextData( xTextualDataSequence->getTextualData());
     368           0 :         ::std::copy( aTextData.getConstArray(), aTextData.getConstArray() + aTextData.getLength(),
     369           0 :                      ::std::back_inserter( rOutCategories ));
     370             :     }
     371             :     else
     372             :     {
     373           0 :         Sequence< uno::Any > aAnies( xCategories->getData());
     374           0 :         rOutCategories.resize( aAnies.getLength());
     375           0 :         for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
     376           0 :             aAnies[i] >>= rOutCategories[i];
     377           0 :     }
     378             : }
     379             : 
     380           0 : ::std::vector< double > lcl_getAllValuesFromSequence( const Reference< chart2::data::XDataSequence > & xSeq )
     381             : {
     382           0 :     double fNan = 0.0;
     383           0 :     ::rtl::math::setNan( &fNan );
     384           0 :     ::std::vector< double > aResult;
     385             : 
     386           0 :     Reference< chart2::data::XNumericalDataSequence > xNumSeq( xSeq, uno::UNO_QUERY );
     387           0 :     if( xNumSeq.is())
     388             :     {
     389           0 :         Sequence< double > aValues( xNumSeq->getNumericalData());
     390           0 :         ::std::copy( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(),
     391           0 :                      ::std::back_inserter( aResult ));
     392             :     }
     393           0 :     else if( xSeq.is())
     394             :     {
     395           0 :         Sequence< uno::Any > aAnies( xSeq->getData());
     396           0 :         aResult.resize( aAnies.getLength(), fNan );
     397           0 :         for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
     398           0 :             aAnies[i] >>= aResult[i];
     399             :     }
     400           0 :     return aResult;
     401             : }
     402             : 
     403           0 : sal_Int32 lcl_getChartType( const OUString& sChartType )
     404             : {
     405           0 :     chart::TypeId eChartTypeId = chart::TYPEID_UNKNOWN;
     406           0 :     if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.BarDiagram" )))
     407           0 :         || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.ColumnChartType") ) ) )
     408           0 :         eChartTypeId = chart::TYPEID_BAR;
     409           0 :     else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.AreaDiagram" )))
     410           0 :         || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.AreaChartType") ) ) )
     411           0 :         eChartTypeId = chart::TYPEID_AREA;
     412           0 :     else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.LineDiagram" )))
     413           0 :         || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.LineChartType") ) ) )
     414           0 :         eChartTypeId = chart::TYPEID_LINE;
     415           0 :     else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.PieDiagram" )))
     416           0 :         || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.PieChartType") ) ) )
     417           0 :         eChartTypeId = chart::TYPEID_PIE;
     418           0 :     else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.DonutDiagram" )))
     419           0 :         || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.DonutChartType") ) ) )
     420           0 :         eChartTypeId = chart::TYPEID_DOUGHNUT;
     421           0 :     else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.XYDiagram" )))
     422           0 :         || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.ScatterChartType") ) ) )
     423           0 :         eChartTypeId = chart::TYPEID_SCATTER;
     424           0 :     else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.NetDiagram" )))
     425           0 :         || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.NetChartType") ) ) )
     426           0 :         eChartTypeId = chart::TYPEID_RADARLINE;
     427           0 :     else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.FilledNetDiagram" )))
     428           0 :         || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.FilledNetChartType") ) ) )
     429           0 :         eChartTypeId = chart::TYPEID_RADARAREA;
     430           0 :     else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.StockDiagram" )))
     431           0 :         || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.CandleStickChartType") ) ) )
     432           0 :         eChartTypeId = chart::TYPEID_STOCK;
     433           0 :     else if(( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.BubbleDiagram" )))
     434           0 :         || ( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.BubbleChartType") ) ) )
     435           0 :         eChartTypeId = chart::TYPEID_BUBBLE;
     436             : 
     437           0 :     return eChartTypeId;
     438             : }
     439             : 
     440           0 : sal_Int32 lcl_generateRandomValue()
     441             : {
     442             :     static sal_Int32 MAX_NUMBER = 100000000;
     443             :     //srand( unsigned( time( NULL ) ));
     444           0 :     return sal_Int32( rand() % MAX_NUMBER );
     445             : }
     446             : 
     447           0 : ChartExport::ChartExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, Reference< frame::XModel >& xModel, XmlFilterBase* pFB, DocumentType eDocumentType )
     448             :     : DrawingML( pFS, pFB, eDocumentType )
     449             :     , mnXmlNamespace( nXmlNamespace )
     450             :     , maFraction( 1, 576 )
     451             :     , mxChartModel( xModel )
     452             :     , mbHasSeriesLabels( sal_False )
     453             :     , mbHasCategoryLabels( sal_False )
     454             :     , mbRowSourceColumns( sal_True )
     455             :     , mbHasXAxis( sal_False )
     456             :     , mbHasYAxis( sal_False )
     457             :     , mbHasZAxis( sal_False )
     458             :     , mbHasSecondaryXAxis( sal_False )
     459             :     , mbHasSecondaryYAxis( sal_False )
     460           0 :     , mbIs3DChart( sal_False )
     461             : {
     462           0 : }
     463             : 
     464           0 : sal_Int32 ChartExport::GetChartID( )
     465             : {
     466           0 :     sal_Int32 nID = GetFB()->GetUniqueId();
     467           0 :     return nID;
     468             : }
     469             : 
     470           0 : sal_Int32 ChartExport::getChartType( )
     471             : {
     472           0 :     OUString sChartType = mxDiagram->getDiagramType();
     473           0 :     return lcl_getChartType( sChartType );
     474             : }
     475             : 
     476           0 : OUString ChartExport::parseFormula( const OUString& rRange )
     477             : {
     478           0 :     OUString aResult;
     479           0 :     Reference< XFormulaParser > xParser;
     480           0 :     uno::Reference< lang::XMultiServiceFactory > xSF( GetFB()->getModelFactory(), uno::UNO_QUERY );
     481           0 :     if( xSF.is() )
     482             :     {
     483             :         try
     484             :         {
     485           0 :             xParser.set( xSF->createInstance( OUString("com.sun.star.sheet.FormulaParser") ), UNO_QUERY );
     486             :         }
     487           0 :         catch( Exception& )
     488             :         {
     489             :         }
     490             :     }
     491           0 :     if( xParser.is() )
     492             :     {
     493             :         OSL_TRACE("ChartExport::parseFormula, parser is valid");
     494           0 :         Reference< XPropertySet > xParserProps( xParser, uno::UNO_QUERY );
     495           0 :         if( xParserProps.is() )
     496             :         {
     497           0 :             xParserProps->setPropertyValue( OUString("FormulaConvention"), uno::makeAny(::com::sun::star::sheet::AddressConvention::OOO) );
     498             :         }
     499           0 :         uno::Sequence<sheet::FormulaToken> aTokens = xParser->parseFormula( rRange, CellAddress( 0, 0, 0 ) );
     500           0 :         if( xParserProps.is() )
     501             :         {
     502           0 :             xParserProps->setPropertyValue( OUString("FormulaConvention"), uno::makeAny(::com::sun::star::sheet::AddressConvention::XL_OOX) );
     503             :         }
     504           0 :         aResult = xParser->printFormula( aTokens, CellAddress( 0, 0, 0 ) );
     505             :     }
     506             :     else
     507             :     {
     508             :         OSL_TRACE("ChartExport::parseFormula, parser is invalid");
     509             :         //FIXME: currently just using simple converter, e.g $Sheet1.$A$1:$C$1 -> Sheet1!$A$1:$C$1
     510           0 :         String aRange( rRange );
     511           0 :         if( aRange.SearchAscii("$") == 0 )
     512           0 :             aRange = aRange.Copy(1);
     513           0 :         aRange.SearchAndReplaceAllAscii(".$", rtl::OUString("!$") );
     514           0 :         aResult = aRange;
     515             :     }
     516             : 
     517             :     OSL_TRACE("ChartExport::parseFormula, the originla formula is %s, the new formula is %s ", rtl::OUStringToOString( rRange, RTL_TEXTENCODING_UTF8 ).getStr(), rtl::OUStringToOString( aResult, RTL_TEXTENCODING_UTF8 ).getStr());
     518           0 :     return aResult;
     519             : }
     520             : 
     521           0 : ChartExport& ChartExport::WriteChartObj( const Reference< XShape >& xShape, sal_Int32 nChartCount )
     522             : {
     523             :     OSL_TRACE("ChartExport::WriteChartObj -- writer chart object");
     524           0 :     FSHelperPtr pFS = GetFS();
     525             : 
     526           0 :     pFS->startElementNS( mnXmlNamespace, XML_graphicFrame, FSEND );
     527             : 
     528           0 :     pFS->startElementNS( mnXmlNamespace, XML_nvGraphicFramePr, FSEND );
     529             : 
     530             :     // TODO: get the correct chart name chart id
     531           0 :     OUString sName = S("Object 1");
     532           0 :     Reference< XNamed > xNamed( xShape, UNO_QUERY );
     533           0 :     if (xNamed.is())
     534           0 :         sName = xNamed->getName();
     535             : 
     536           0 :     sal_Int32 nID = GetChartID();
     537             : 
     538             :     pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
     539             :                           XML_id,     I32S( nID ),
     540             :                           XML_name,   USS( sName ),
     541           0 :                           FSEND );
     542             : 
     543             :     pFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr,
     544           0 :                           FSEND );
     545             : 
     546           0 :     if( GetDocumentType() == DOCUMENT_PPTX )
     547             :         pFS->singleElementNS( mnXmlNamespace, XML_nvPr,
     548           0 :                           FSEND );
     549           0 :     pFS->endElementNS( mnXmlNamespace, XML_nvGraphicFramePr );
     550             : 
     551             :     // visual chart properties
     552           0 :     WriteShapeTransformation( xShape, mnXmlNamespace );
     553             : 
     554             :     // writer chart object
     555           0 :     pFS->startElement( FSNS( XML_a, XML_graphic ), FSEND );
     556             :     pFS->startElement( FSNS( XML_a, XML_graphicData ),
     557             :                        XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/chart",
     558           0 :                        FSEND );
     559           0 :     OUString sId;
     560           0 :     const char* sFullPath = NULL;
     561           0 :     const char* sRelativePath = NULL;
     562           0 :     switch( GetDocumentType() )
     563             :     {
     564             :         case DOCUMENT_DOCX:
     565             :         {
     566           0 :             sFullPath = "word/charts/chart";
     567           0 :             sRelativePath = "charts/chart";
     568           0 :             break;
     569             :         }
     570             :         case DOCUMENT_PPTX:
     571             :         {
     572           0 :             sFullPath = "ppt/charts/chart";
     573           0 :             sRelativePath = "../charts/chart";
     574           0 :             break;
     575             :         }
     576             :         case DOCUMENT_XLSX:
     577             :         {
     578           0 :             sFullPath = "xl/charts/chart";
     579           0 :             sRelativePath = "../charts/chart";
     580           0 :             break;
     581             :         }
     582             :         default:
     583             :         {
     584           0 :             sFullPath = "charts/chart";
     585           0 :             sRelativePath = "charts/chart";
     586           0 :             break;
     587             :         }
     588             :     }
     589             :     OUString sFullStream = OUStringBuffer()
     590           0 :                             .appendAscii(sFullPath)
     591           0 :                             .append(nChartCount)
     592           0 :                             .appendAscii( ".xml" )
     593           0 :                             .makeStringAndClear();
     594             :     OUString sRelativeStream = OUStringBuffer()
     595           0 :                             .appendAscii(sRelativePath)
     596           0 :                             .append(nChartCount)
     597           0 :                             .appendAscii( ".xml" )
     598           0 :                             .makeStringAndClear();
     599             :     FSHelperPtr pChart = CreateOutputStream(
     600             :             sFullStream,
     601             :             sRelativeStream,
     602             :             pFS->getOutputStream(),
     603             :             "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
     604             :             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
     605           0 :             &sId );
     606             : 
     607             :     pFS->singleElement(  FSNS( XML_c, XML_chart ),
     608             :             FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
     609             :             FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
     610             :             FSNS( XML_r, XML_id ), USS( sId ),
     611           0 :             FSEND );
     612             : 
     613           0 :     pFS->endElement( FSNS( XML_a, XML_graphicData ) );
     614           0 :     pFS->endElement( FSNS( XML_a, XML_graphic ) );
     615           0 :     pFS->endElementNS( mnXmlNamespace, XML_graphicFrame );
     616             : 
     617           0 :     SetFS( pChart );
     618           0 :     ExportContent();
     619             : 
     620           0 :     return *this;
     621             : }
     622             : 
     623           0 : void ChartExport::InitRangeSegmentationProperties( const Reference< chart2::XChartDocument > & xChartDoc )
     624             : {
     625           0 :     if( xChartDoc.is())
     626             :         try
     627             :         {
     628           0 :             Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
     629             :             OSL_ENSURE( xDataProvider.is(), "No DataProvider" );
     630           0 :             if( xDataProvider.is())
     631             :             {
     632           0 :                 Reference< chart2::data::XDataSource > xDataSource( lcl_pressUsedDataIntoRectangularFormat( xChartDoc, mbHasCategoryLabels ));
     633           0 :                 Sequence< beans::PropertyValue > aArgs( xDataProvider->detectArguments( xDataSource ));
     634           0 :                 ::rtl::OUString sCellRange, sBrokenRange;
     635           0 :                 bool bBrokenRangeAvailable = false;
     636           0 :                 for( sal_Int32 i=0; i<aArgs.getLength(); ++i )
     637             :                 {
     638           0 :                     if ( aArgs[i].Name == "CellRangeRepresentation" )
     639           0 :                         aArgs[i].Value >>= sCellRange;
     640           0 :                     else if ( aArgs[i].Name == "BrokenCellRangeForExport" )
     641             :                     {
     642           0 :                         if( aArgs[i].Value >>= sBrokenRange )
     643           0 :                             bBrokenRangeAvailable = true;
     644             :                     }
     645           0 :                     else if ( aArgs[i].Name == "DataRowSource" )
     646             :                     {
     647             :                         ::com::sun::star::chart::ChartDataRowSource eRowSource;
     648           0 :                         aArgs[i].Value >>= eRowSource;
     649           0 :                         mbRowSourceColumns = ( eRowSource == ::com::sun::star::chart::ChartDataRowSource_COLUMNS );
     650             :                     }
     651           0 :                     else if ( aArgs[i].Name == "FirstCellAsLabel" )
     652           0 :                         aArgs[i].Value >>= mbHasSeriesLabels;
     653           0 :                     else if ( aArgs[i].Name == "SequenceMapping" )
     654           0 :                         aArgs[i].Value >>= maSequenceMapping;
     655           0 :                     else if ( aArgs[i].Name == "TableNumberList" )
     656           0 :                         aArgs[i].Value >>= msTableNumberList;
     657             :                 }
     658             : 
     659             :                 // #i79009# For Writer we have to export a broken version of the
     660             :                 // range, where every row number is noe too large, so that older
     661             :                 // version can correctly read those files.
     662           0 :                 msChartAddress = (bBrokenRangeAvailable ? sBrokenRange : sCellRange);
     663           0 :                 if( !msChartAddress.isEmpty() )
     664             :                 {
     665             :                     // convert format to XML-conform one
     666           0 :                     Reference< chart2::data::XRangeXMLConversion > xConversion( xDataProvider, uno::UNO_QUERY );
     667           0 :                     if( xConversion.is())
     668           0 :                         msChartAddress = xConversion->convertRangeToXML( msChartAddress );
     669           0 :                 }
     670           0 :             }
     671             :         }
     672           0 :         catch( const uno::Exception & ex )
     673             :         {
     674             :             (void)ex; // avoid warning for pro build
     675             :             OSL_FAIL( rtl::OUStringToOString(
     676             :                             OUString(  "Exception caught. Type: " ) +
     677             :                             OUString::createFromAscii( typeid( ex ).name()) +
     678             :                             OUString(  ", Message: " ) +
     679             :                             ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
     680             :         }
     681           0 : }
     682             : 
     683           0 : void ChartExport::ExportContent()
     684             : {
     685           0 :     Reference< chart2::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
     686             :     OSL_ASSERT( xChartDoc.is() );
     687           0 :     if( !xChartDoc.is() )
     688           0 :         return;
     689           0 :     InitRangeSegmentationProperties( xChartDoc );
     690             :     // TODO: export chart
     691           0 :     _ExportContent( );
     692             : }
     693             : 
     694           0 : void ChartExport::_ExportContent()
     695             : {
     696           0 :     Reference< ::com::sun::star::chart::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
     697           0 :     if( xChartDoc.is())
     698             :     {
     699             :         // determine if data comes from the outside
     700           0 :         sal_Bool bIncludeTable = sal_True;
     701             : 
     702           0 :         Reference< chart2::XChartDocument > xNewDoc( xChartDoc, uno::UNO_QUERY );
     703           0 :         if( xNewDoc.is())
     704             :         {
     705             :             // check if we have own data.  If so we must not export the complete
     706             :             // range string, as this is our only indicator for having own or
     707             :             // external data. @todo: fix this in the file format!
     708           0 :             Reference< lang::XServiceInfo > xDPServiceInfo( xNewDoc->getDataProvider(), uno::UNO_QUERY );
     709           0 :             if( ! (xDPServiceInfo.is() && xDPServiceInfo->getImplementationName() == "com.sun.star.comp.chart.InternalDataProvider" ))
     710             :             {
     711           0 :                 bIncludeTable = sal_False;
     712           0 :             }
     713             :         }
     714             :         else
     715             :         {
     716           0 :             Reference< lang::XServiceInfo > xServ( xChartDoc, uno::UNO_QUERY );
     717           0 :             if( xServ.is())
     718             :             {
     719           0 :                 if( xServ->supportsService(
     720           0 :                         OUString("com.sun.star.chart.ChartTableAddressSupplier")))
     721             :                 {
     722           0 :                     Reference< beans::XPropertySet > xProp( xServ, uno::UNO_QUERY );
     723           0 :                     if( xProp.is())
     724             :                     {
     725           0 :                         Any aAny;
     726             :                         try
     727             :                         {
     728           0 :                             OUString sChartAddress;
     729           0 :                             aAny = xProp->getPropertyValue(
     730           0 :                                 OUString("ChartRangeAddress"));
     731           0 :                             aAny >>= msChartAddress;
     732             :                             //maExportHelper.SetChartRangeAddress( sChartAddress );
     733             : 
     734             :                             // OUString sTableNumberList;
     735           0 :                             aAny = xProp->getPropertyValue(
     736           0 :                                 OUString("TableNumberList"));
     737           0 :                             aAny >>= msTableNumberList;
     738             :                             //maExportHelper.SetTableNumberList( sTableNumberList );
     739             : 
     740             :                             // do not include own table if there are external addresses
     741           0 :                             bIncludeTable = sChartAddress.isEmpty();
     742             :                         }
     743           0 :                         catch( beans::UnknownPropertyException & )
     744             :                         {
     745             :                             OSL_FAIL( "Property ChartRangeAddress not supported by ChartDocument" );
     746           0 :                         }
     747           0 :                     }
     748             :                 }
     749           0 :             }
     750             :         }
     751           0 :         exportChartSpace( xChartDoc, bIncludeTable );
     752             :     }
     753             :     else
     754             :     {
     755             :         OSL_FAIL( "Couldn't export chart due to wrong XModel" );
     756           0 :     }
     757           0 : }
     758             : 
     759           0 : void ChartExport::exportChartSpace( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc,
     760             :                                       sal_Bool bIncludeTable )
     761             : {
     762           0 :     FSHelperPtr pFS = GetFS();
     763             :     pFS->startElement( FSNS( XML_c, XML_chartSpace ),
     764             :             FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
     765             :             FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
     766             :             FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
     767           0 :             FSEND );
     768             :     // TODO: get the correct editing lanauge
     769             :     pFS->singleElement( FSNS( XML_c, XML_lang ),
     770             :             XML_val, "en-US",
     771           0 :             FSEND );
     772             : 
     773             :     if( !bIncludeTable )
     774             :     {
     775             :         // TODO:external data
     776             :     }
     777             :     //XML_chart
     778           0 :     exportChart(rChartDoc);
     779             : 
     780             :     // TODO: printSettings
     781             :     // TODO: style
     782             :     // TODO: text properties
     783             :     // TODO: shape properties
     784           0 :     Reference< XPropertySet > xPropSet( rChartDoc->getArea(), uno::UNO_QUERY );
     785           0 :     if( xPropSet.is() )
     786           0 :         exportShapeProps( xPropSet );
     787           0 :     pFS->endElement( FSNS( XML_c, XML_chartSpace ) );
     788           0 : }
     789             : 
     790           0 : void ChartExport::exportChart( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc )
     791             : {
     792           0 :     Reference< chart2::XChartDocument > xNewDoc( rChartDoc, uno::UNO_QUERY );
     793           0 :     mxDiagram.set( rChartDoc->getDiagram() );
     794           0 :     if( xNewDoc.is())
     795           0 :         mxNewDiagram.set( xNewDoc->getFirstDiagram());
     796             : 
     797             :     // get Properties of ChartDocument
     798           0 :     sal_Bool bHasMainTitle = sal_False;
     799           0 :     sal_Bool bHasSubTitle = sal_False;
     800           0 :     sal_Bool bHasLegend = sal_False;
     801           0 :     Reference< beans::XPropertySet > xDocPropSet( rChartDoc, uno::UNO_QUERY );
     802           0 :     if( xDocPropSet.is())
     803             :     {
     804             :         try
     805             :         {
     806           0 :             Any aAny( xDocPropSet->getPropertyValue(
     807           0 :                 OUString(  "HasMainTitle" )));
     808           0 :             aAny >>= bHasMainTitle;
     809           0 :             aAny = xDocPropSet->getPropertyValue(
     810           0 :                 OUString(  "HasSubTitle" ));
     811           0 :             aAny >>= bHasSubTitle;
     812           0 :             aAny = xDocPropSet->getPropertyValue(
     813           0 :                 OUString(  "HasLegend" ));
     814           0 :             aAny >>= bHasLegend;
     815             :         }
     816           0 :         catch( beans::UnknownPropertyException & )
     817             :         {
     818             :             DBG_WARNING( "Required property not found in ChartDocument" );
     819             :         }
     820             :     } // if( xDocPropSet.is())
     821             : 
     822             :     // chart element
     823             :     // -------------
     824           0 :     FSHelperPtr pFS = GetFS();
     825             :     pFS->startElement( FSNS( XML_c, XML_chart ),
     826           0 :             FSEND );
     827             : 
     828             :     // title
     829           0 :     if( bHasMainTitle )
     830             :     {
     831           0 :         Reference< drawing::XShape > xShape = rChartDoc->getTitle();
     832           0 :         if( xShape.is() )
     833           0 :             exportTitle( xShape );
     834             :     }
     835           0 :     InitPlotArea( );
     836           0 :     if( mbIs3DChart )
     837             :     {
     838           0 :         exportView3D();
     839             : 
     840             :         // sideWall
     841             : 
     842             :         // backWall
     843           0 :         Reference< beans::XPropertySet > xBackWall( mxNewDiagram->getWall(), uno::UNO_QUERY );
     844           0 :         if( xBackWall.is() )
     845             :         {
     846             :             pFS->startElement( FSNS( XML_c, XML_backWall ),
     847           0 :                 FSEND );
     848           0 :             exportShapeProps( xBackWall );
     849           0 :             pFS->endElement( FSNS( XML_c, XML_backWall ) );
     850             :         }
     851             : 
     852             :         // floor
     853           0 :         Reference< beans::XPropertySet > xFloor( mxNewDiagram->getFloor(), uno::UNO_QUERY );
     854           0 :         if( xFloor.is() )
     855             :         {
     856             :             pFS->startElement( FSNS( XML_c, XML_floor ),
     857           0 :                 FSEND );
     858           0 :             exportShapeProps( xFloor );
     859           0 :             pFS->endElement( FSNS( XML_c, XML_floor ) );
     860           0 :         }
     861             : 
     862             :     }
     863             :     // plot area
     864           0 :     exportPlotArea( );
     865             :     // legend
     866           0 :     if( bHasLegend )
     867           0 :         exportLegend( rChartDoc );
     868             :     // only visible cells should be plotted on the chart
     869             :     pFS->singleElement( FSNS( XML_c, XML_plotVisOnly ),
     870             :             XML_val, "1",
     871           0 :             FSEND );
     872             : 
     873           0 :     pFS->endElement( FSNS( XML_c, XML_chart ) );
     874           0 : }
     875             : 
     876           0 : void ChartExport::exportLegend( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc )
     877             : {
     878           0 :     FSHelperPtr pFS = GetFS();
     879             :     pFS->startElement( FSNS( XML_c, XML_legend ),
     880           0 :             FSEND );
     881             : 
     882           0 :     Reference< beans::XPropertySet > xProp( rChartDoc->getLegend(), uno::UNO_QUERY );
     883           0 :     if( xProp.is() )
     884             :     {
     885             :         // position
     886           0 :         ::com::sun::star::chart::ChartLegendPosition aLegendPos = ::com::sun::star::chart::ChartLegendPosition_NONE;
     887             :         try
     888             :         {
     889           0 :             Any aAny( xProp->getPropertyValue(
     890           0 :                 OUString(  "Alignment" )));
     891           0 :                 aAny >>= aLegendPos;
     892             :         }
     893           0 :         catch( beans::UnknownPropertyException & )
     894             :         {
     895             :             DBG_WARNING( "Property Align not found in ChartLegend" );
     896             :         }
     897             : 
     898           0 :         const char* strPos = NULL;
     899           0 :         switch( aLegendPos )
     900             :         {
     901             :             case ::com::sun::star::chart::ChartLegendPosition_LEFT:
     902           0 :                 strPos = "l";
     903           0 :                 break;
     904             :             case ::com::sun::star::chart::ChartLegendPosition_RIGHT:
     905           0 :                 strPos = "r";
     906           0 :                 break;
     907             :             case ::com::sun::star::chart::ChartLegendPosition_TOP:
     908           0 :                 strPos = "t";
     909           0 :                 break;
     910             :             case ::com::sun::star::chart::ChartLegendPosition_BOTTOM:
     911           0 :                 strPos = "b";
     912           0 :                 break;
     913             :             case ::com::sun::star::chart::ChartLegendPosition_NONE:
     914             :             case ::com::sun::star::chart::ChartLegendPosition_MAKE_FIXED_SIZE:
     915             :                 // nothing
     916           0 :                 break;
     917             :         }
     918             : 
     919           0 :         if( strPos != NULL )
     920             :         {
     921             :             pFS->singleElement( FSNS( XML_c, XML_legendPos ),
     922             :                 XML_val, strPos,
     923           0 :                 FSEND );
     924             :         }
     925             : 
     926             :         // shape properties
     927           0 :         exportShapeProps( xProp );
     928             :     }
     929             : 
     930             :     // legendEntry
     931             : 
     932           0 :     pFS->endElement( FSNS( XML_c, XML_legend ) );
     933           0 : }
     934             : 
     935           0 : void ChartExport::exportTitle( Reference< XShape > xShape )
     936             : {
     937           0 :     OUString sText;
     938           0 :     Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
     939           0 :     if( xPropSet.is())
     940             :     {
     941           0 :         xPropSet->getPropertyValue( OUString(  "String" )) >>= sText;
     942             :     }
     943           0 :     if( sText.isEmpty() )
     944           0 :         return;
     945             : 
     946           0 :     FSHelperPtr pFS = GetFS();
     947             :     pFS->startElement( FSNS( XML_c, XML_title ),
     948           0 :             FSEND );
     949             :     // TODO:customize layout
     950             :     pFS->singleElement( FSNS( XML_c, XML_layout ),
     951           0 :             FSEND );
     952             : 
     953             :     pFS->startElement( FSNS( XML_c, XML_tx ),
     954           0 :             FSEND );
     955             :     pFS->startElement( FSNS( XML_c, XML_rich ),
     956           0 :             FSEND );
     957             : 
     958             :     // TODO: bodyPr
     959           0 :     const char* sWritingMode = NULL;
     960           0 :     sal_Bool bVertical = sal_False;
     961           0 :     xPropSet->getPropertyValue( OUString(  "StackedText" )) >>= bVertical;
     962           0 :     if( bVertical )
     963           0 :         sWritingMode = "wordArtVert";
     964             : 
     965             :     pFS->singleElement( FSNS( XML_a, XML_bodyPr ),
     966             :             XML_vert, sWritingMode,
     967           0 :             FSEND );
     968             :     // TODO: lstStyle
     969             :     pFS->singleElement( FSNS( XML_a, XML_lstStyle ),
     970           0 :             FSEND );
     971             :     // FIXME: handle multipul paragraphs to parse aText
     972             :     pFS->startElement( FSNS( XML_a, XML_p ),
     973           0 :             FSEND );
     974             : 
     975             :     pFS->startElement( FSNS( XML_a, XML_pPr ),
     976           0 :             FSEND );
     977             :     pFS->singleElement( FSNS( XML_a, XML_defRPr ),
     978           0 :             FSEND );
     979           0 :     pFS->endElement( FSNS( XML_a, XML_pPr ) );
     980             : 
     981             :     pFS->startElement( FSNS( XML_a, XML_r ),
     982           0 :             FSEND );
     983           0 :     WriteRunProperties( xPropSet, sal_False );
     984             :     pFS->startElement( FSNS( XML_a, XML_t ),
     985           0 :             FSEND );
     986           0 :     pFS->writeEscaped( sText );
     987           0 :     pFS->endElement( FSNS( XML_a, XML_t ) );
     988           0 :     pFS->endElement( FSNS( XML_a, XML_r ) );
     989             : 
     990           0 :     pFS->endElement( FSNS( XML_a, XML_p ) );
     991             : 
     992           0 :     pFS->endElement( FSNS( XML_c, XML_rich ) );
     993           0 :     pFS->endElement( FSNS( XML_c, XML_tx ) );
     994           0 :     pFS->endElement( FSNS( XML_c, XML_title ) );
     995             : }
     996             : 
     997           0 : void ChartExport::exportPlotArea( )
     998             : {
     999           0 :     Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( mxNewDiagram, uno::UNO_QUERY );
    1000           0 :     if( ! xBCooSysCnt.is())
    1001             :         return;
    1002             : 
    1003             :     // plot-area element
    1004             :     // -----------------
    1005           0 :     FSHelperPtr pFS = GetFS();
    1006             :     pFS->startElement( FSNS( XML_c, XML_plotArea ),
    1007           0 :             FSEND );
    1008             :     // layout
    1009             :     pFS->singleElement( FSNS( XML_c, XML_layout ),
    1010           0 :             FSEND );
    1011             : 
    1012             :     // chart type
    1013             :     Sequence< Reference< chart2::XCoordinateSystem > >
    1014           0 :         aCooSysSeq( xBCooSysCnt->getCoordinateSystems());
    1015           0 :     for( sal_Int32 nCSIdx=0; nCSIdx<aCooSysSeq.getLength(); ++nCSIdx )
    1016             :     {
    1017           0 :         Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCSIdx], uno::UNO_QUERY );
    1018           0 :         if( ! xCTCnt.is())
    1019           0 :             continue;
    1020           0 :         Sequence< Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes());
    1021           0 :         for( sal_Int32 nCTIdx=0; nCTIdx<aCTSeq.getLength(); ++nCTIdx )
    1022             :         {
    1023           0 :             Reference< chart2::XDataSeriesContainer > xDSCnt( aCTSeq[nCTIdx], uno::UNO_QUERY );
    1024           0 :             if( ! xDSCnt.is())
    1025             :                 return;
    1026           0 :             Reference< chart2::XChartType > xChartType( aCTSeq[nCTIdx], uno::UNO_QUERY );
    1027           0 :             if( ! xChartType.is())
    1028           0 :                 continue;
    1029             :             // note: if xDSCnt.is() then also aCTSeq[nCTIdx]
    1030           0 :             OUString aChartType( xChartType->getChartType());
    1031           0 :             sal_Int32 eChartType = lcl_getChartType( aChartType );
    1032           0 :     switch( eChartType )
    1033             :     {
    1034             :         case chart::TYPEID_BAR:
    1035             :         {
    1036           0 :             exportBarChart( xChartType );
    1037           0 :             break;
    1038             :         }
    1039             :         case chart::TYPEID_AREA:
    1040             :         {
    1041           0 :             exportAreaChart( xChartType );
    1042           0 :             break;
    1043             :         }
    1044             :         case chart::TYPEID_LINE:
    1045             :         {
    1046           0 :             exportLineChart( xChartType );
    1047           0 :             break;
    1048             :         }
    1049             :         case chart::TYPEID_BUBBLE:
    1050             :         {
    1051           0 :             exportBubbleChart( xChartType );
    1052           0 :             break;
    1053             :         }
    1054             :         case chart::TYPEID_DOUGHNUT:
    1055             :         {
    1056           0 :             exportDoughnutChart( xChartType );
    1057           0 :             break;
    1058             :         }
    1059             :         case chart::TYPEID_OFPIE:
    1060             :         {
    1061           0 :             exportOfPieChart( xChartType );
    1062           0 :             break;
    1063             :         }
    1064             :         case chart::TYPEID_PIE:
    1065             :         {
    1066           0 :             exportPieChart( xChartType );
    1067           0 :             break;
    1068             :         }
    1069             :         case chart::TYPEID_RADARLINE:
    1070             :         case chart::TYPEID_RADARAREA:
    1071             :         {
    1072           0 :             exportRadarChart( xChartType );
    1073           0 :             break;
    1074             :         }
    1075             :         case chart::TYPEID_SCATTER:
    1076             :         {
    1077           0 :             exportScatterChart( xChartType );
    1078           0 :             break;
    1079             :         }
    1080             :         case chart::TYPEID_STOCK:
    1081             :         {
    1082           0 :             exportStockChart( xChartType );
    1083           0 :             break;
    1084             :         }
    1085             :         case chart::TYPEID_SURFACE:
    1086             :         {
    1087           0 :             exportSuffaceChart( xChartType );
    1088           0 :             break;
    1089             :         }
    1090             :         default:
    1091             :         {
    1092             :             OSL_TRACE("ChartExport::exportPlotArea -- not support chart type");
    1093           0 :             break;
    1094             :         }
    1095             :     }
    1096             : 
    1097           0 :         }
    1098           0 :     }
    1099             :     //Axis Data
    1100           0 :     exportAxes( );
    1101             : 
    1102             :     // shape properties
    1103           0 :     Reference< ::com::sun::star::chart::X3DDisplay > xWallFloorSupplier( mxDiagram, uno::UNO_QUERY );
    1104           0 :     if( xWallFloorSupplier.is() )
    1105             :     {
    1106           0 :         Reference< beans::XPropertySet > xWallPropSet( xWallFloorSupplier->getWall(), uno::UNO_QUERY );
    1107           0 :         if( xWallPropSet.is() )
    1108             :         {
    1109           0 :             exportShapeProps( xWallPropSet );
    1110           0 :         }
    1111             :     }
    1112             : 
    1113           0 :     pFS->endElement( FSNS( XML_c, XML_plotArea ) );
    1114             : 
    1115             : }
    1116             : 
    1117           0 : void ChartExport::exportAreaChart( Reference< chart2::XChartType > xChartType )
    1118             : {
    1119           0 :     FSHelperPtr pFS = GetFS();
    1120           0 :     sal_Int32 nTypeId = XML_areaChart;
    1121           0 :     if( mbIs3DChart )
    1122           0 :         nTypeId = XML_area3DChart;
    1123             :     pFS->startElement( FSNS( XML_c, nTypeId ),
    1124           0 :             FSEND );
    1125             : 
    1126           0 :     exportGrouping( );
    1127           0 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1128           0 :     exportSeries( xChartType, nAttachedAxis );
    1129           0 :     exportAxesId( nAttachedAxis );
    1130             : 
    1131           0 :     pFS->endElement( FSNS( XML_c, nTypeId ) );
    1132           0 : }
    1133             : 
    1134           0 : void ChartExport::exportBarChart( Reference< chart2::XChartType > xChartType )
    1135             : {
    1136           0 :     sal_Int32 nTypeId = XML_barChart;
    1137           0 :     if( mbIs3DChart )
    1138           0 :         nTypeId = XML_bar3DChart;
    1139           0 :     FSHelperPtr pFS = GetFS();
    1140             :     pFS->startElement( FSNS( XML_c, nTypeId ),
    1141           0 :             FSEND );
    1142             :     // bar direction
    1143           0 :     sal_Bool bVertical = sal_False;
    1144           0 :     Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
    1145           0 :     if( GetProperty( xPropSet, S( "Vertical" ) ) )
    1146           0 :         mAny >>= bVertical;
    1147             : 
    1148           0 :     const char* bardir = bVertical? "bar":"col";
    1149             :     pFS->singleElement( FSNS( XML_c, XML_barDir ),
    1150             :             XML_val, bardir,
    1151           0 :             FSEND );
    1152             : 
    1153           0 :     exportGrouping( sal_True );
    1154           0 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1155           0 :     exportSeries( xChartType, nAttachedAxis );
    1156             : 
    1157           0 :     Reference< XPropertySet > xTypeProp( xChartType, uno::UNO_QUERY );
    1158           0 :     if( mbIs3DChart )
    1159             :     {
    1160             :         // Shape
    1161             :         namespace cssc = ::com::sun::star::chart;
    1162           0 :         sal_Int32 nGeom3d = cssc::ChartSolidType::RECTANGULAR_SOLID;
    1163           0 :         if( xPropSet.is() && GetProperty( xPropSet, S("SolidType") ) )
    1164           0 :             mAny >>= nGeom3d;
    1165           0 :         const char* sShapeType = NULL;
    1166           0 :         switch( nGeom3d )
    1167             :         {
    1168             :             case cssc::ChartSolidType::RECTANGULAR_SOLID:
    1169           0 :                 sShapeType = "box";
    1170           0 :                 break;
    1171             :             case cssc::ChartSolidType::CONE:
    1172           0 :                 sShapeType = "cone";
    1173           0 :                 break;
    1174             :             case cssc::ChartSolidType::CYLINDER:
    1175           0 :                 sShapeType = "cylinder";
    1176           0 :                 break;
    1177             :             case cssc::ChartSolidType::PYRAMID:
    1178           0 :                 sShapeType = "pyramid";
    1179           0 :                 break;
    1180             :         }
    1181             :         pFS->singleElement( FSNS( XML_c, XML_shape ),
    1182             :             XML_val, sShapeType,
    1183           0 :             FSEND );
    1184             :     }
    1185             : 
    1186             :     //overlap
    1187           0 :     if( xTypeProp.is() && GetProperty( xTypeProp, S("OverlapSequence") ) )
    1188             :     {
    1189           0 :         uno::Sequence< sal_Int32 > aBarPositionSequence;
    1190           0 :         mAny >>= aBarPositionSequence;
    1191           0 :         if( aBarPositionSequence.getLength() )
    1192             :         {
    1193           0 :             sal_Int32 nOverlap = aBarPositionSequence[0];
    1194           0 :             if( nOverlap > 0 )
    1195             :                 pFS->singleElement( FSNS( XML_c, XML_overlap ),
    1196             :                     XML_val, I32S( nOverlap ),
    1197           0 :                     FSEND );
    1198           0 :         }
    1199             :     }
    1200           0 :     if( xTypeProp.is() && GetProperty( xTypeProp, S("GapwidthSequence") ) )
    1201             :     {
    1202           0 :         uno::Sequence< sal_Int32 > aBarPositionSequence;
    1203           0 :         mAny >>= aBarPositionSequence;
    1204           0 :         if( aBarPositionSequence.getLength() )
    1205             :         {
    1206           0 :             sal_Int32 nGapWidth = aBarPositionSequence[0];
    1207             :             pFS->singleElement( FSNS( XML_c, XML_gapWidth ),
    1208             :                 XML_val, I32S( nGapWidth ),
    1209           0 :                 FSEND );
    1210           0 :         }
    1211             :     }
    1212             : 
    1213           0 :     exportAxesId( nAttachedAxis );
    1214             : 
    1215           0 :     pFS->endElement( FSNS( XML_c, nTypeId ) );
    1216           0 : }
    1217             : 
    1218           0 : void ChartExport::exportBubbleChart( Reference< chart2::XChartType > xChartType )
    1219             : {
    1220           0 :     FSHelperPtr pFS = GetFS();
    1221             :     pFS->startElement( FSNS( XML_c, XML_bubbleChart ),
    1222           0 :             FSEND );
    1223             : 
    1224           0 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1225           0 :     exportSeries( xChartType, nAttachedAxis );
    1226           0 :     exportAxesId( nAttachedAxis );
    1227             : 
    1228           0 :     pFS->endElement( FSNS( XML_c, XML_bubbleChart ) );
    1229           0 : }
    1230             : 
    1231           0 : void ChartExport::exportDoughnutChart( Reference< chart2::XChartType > xChartType )
    1232             : {
    1233           0 :     FSHelperPtr pFS = GetFS();
    1234             :     pFS->startElement( FSNS( XML_c, XML_doughnutChart ),
    1235           0 :             FSEND );
    1236             : 
    1237           0 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1238           0 :     exportSeries( xChartType, nAttachedAxis );
    1239             :     // firstSliceAng
    1240           0 :     exportFirstSliceAng( );
    1241             :     //FIXME: holeSize
    1242           0 :     sal_Int32 nHoleSize = 50;
    1243             :     pFS->singleElement( FSNS( XML_c, XML_holeSize ),
    1244             :             XML_val, I32S( nHoleSize ),
    1245           0 :             FSEND );
    1246             : 
    1247           0 :     exportAxesId( nAttachedAxis );
    1248             : 
    1249           0 :     pFS->endElement( FSNS( XML_c, XML_doughnutChart ) );
    1250           0 : }
    1251             : 
    1252           0 : void ChartExport::exportLineChart( Reference< chart2::XChartType > xChartType )
    1253             : {
    1254           0 :     FSHelperPtr pFS = GetFS();
    1255           0 :     sal_Int32 nTypeId = XML_lineChart;
    1256           0 :     if( mbIs3DChart )
    1257           0 :         nTypeId = XML_line3DChart;
    1258             :     pFS->startElement( FSNS( XML_c, nTypeId ),
    1259           0 :             FSEND );
    1260             : 
    1261           0 :     exportGrouping( );
    1262             :     // TODO: show marker symbol in series?
    1263           0 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1264           0 :     exportSeries( xChartType, nAttachedAxis );
    1265             : 
    1266             :     // show marker?
    1267           0 :     sal_Int32 nSymbolType = ::com::sun::star::chart::ChartSymbolType::NONE;
    1268           0 :     Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
    1269           0 :     if( GetProperty( xPropSet, S( "SymbolType" ) ) )
    1270           0 :         mAny >>= nSymbolType;
    1271             : 
    1272           0 :     const char* marker = nSymbolType == ::com::sun::star::chart::ChartSymbolType::NONE? "0":"1";
    1273             :     pFS->singleElement( FSNS( XML_c, XML_marker ),
    1274             :             XML_val, marker,
    1275           0 :             FSEND );
    1276             : 
    1277           0 :     exportAxesId( nAttachedAxis );
    1278             : 
    1279           0 :     pFS->endElement( FSNS( XML_c, nTypeId ) );
    1280           0 : }
    1281             : 
    1282           0 : void ChartExport::exportOfPieChart( Reference< chart2::XChartType > /*xChartType*/ )
    1283             : {
    1284             :     // TODO:
    1285           0 : }
    1286             : 
    1287           0 : void ChartExport::exportPieChart( Reference< chart2::XChartType > xChartType )
    1288             : {
    1289           0 :     FSHelperPtr pFS = GetFS();
    1290           0 :     sal_Int32 nTypeId = XML_pieChart;
    1291           0 :     if( mbIs3DChart )
    1292           0 :         nTypeId = XML_pie3DChart;
    1293             :     pFS->startElement( FSNS( XML_c, nTypeId ),
    1294           0 :             FSEND );
    1295             :     // TODO: varyColors
    1296           0 :     const char* varyColors = "1";
    1297             :     pFS->singleElement( FSNS( XML_c, XML_varyColors ),
    1298             :             XML_val, varyColors,
    1299           0 :             FSEND );
    1300             : 
    1301           0 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1302           0 :     exportSeries( xChartType, nAttachedAxis );
    1303             : 
    1304             :     // firstSliceAng
    1305           0 :     exportFirstSliceAng( );
    1306             : 
    1307           0 :     pFS->endElement( FSNS( XML_c, nTypeId ) );
    1308           0 : }
    1309             : 
    1310           0 : void ChartExport::exportRadarChart( Reference< chart2::XChartType > xChartType)
    1311             : {
    1312           0 :     FSHelperPtr pFS = GetFS();
    1313             :     pFS->startElement( FSNS( XML_c, XML_radarChart ),
    1314           0 :             FSEND );
    1315             : 
    1316             :     // radarStyle
    1317           0 :     sal_Int32 eChartType = getChartType( );
    1318           0 :     const char* radarStyle = NULL;
    1319           0 :     if( eChartType == chart::TYPEID_RADARAREA )
    1320           0 :         radarStyle = "filled";
    1321             :     else
    1322           0 :         radarStyle = "marker";
    1323             :     pFS->singleElement( FSNS( XML_c, XML_radarStyle ),
    1324             :             XML_val, radarStyle,
    1325           0 :             FSEND );
    1326           0 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1327           0 :     exportSeries( xChartType, nAttachedAxis );
    1328           0 :     exportAxesId( nAttachedAxis );
    1329             : 
    1330           0 :     pFS->endElement( FSNS( XML_c, XML_radarChart ) );
    1331           0 : }
    1332             : 
    1333           0 : void ChartExport::exportScatterChart( Reference< chart2::XChartType > xChartType )
    1334             : {
    1335           0 :     FSHelperPtr pFS = GetFS();
    1336             :     pFS->startElement( FSNS( XML_c, XML_scatterChart ),
    1337           0 :             FSEND );
    1338             :     // TODO:scatterStyle
    1339           0 :     const char* scatterStyle = "lineMarker";
    1340             :     pFS->singleElement( FSNS( XML_c, XML_scatterStyle ),
    1341             :             XML_val, scatterStyle,
    1342           0 :             FSEND );
    1343             : 
    1344             :     // FIXME: should export xVal and yVal
    1345           0 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1346           0 :     exportSeries( xChartType, nAttachedAxis );
    1347           0 :     exportAxesId( nAttachedAxis );
    1348             : 
    1349           0 :     pFS->endElement( FSNS( XML_c, XML_scatterChart ) );
    1350           0 : }
    1351             : 
    1352           0 : void ChartExport::exportStockChart( Reference< chart2::XChartType > xChartType )
    1353             : {
    1354           0 :     FSHelperPtr pFS = GetFS();
    1355             :     pFS->startElement( FSNS( XML_c, XML_stockChart ),
    1356           0 :             FSEND );
    1357             : 
    1358           0 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1359           0 :     exportSeries( xChartType, nAttachedAxis );
    1360             :     // export stock properties
    1361           0 :     Reference< ::com::sun::star::chart::XStatisticDisplay > xStockPropProvider( mxDiagram, uno::UNO_QUERY );
    1362           0 :     if( xStockPropProvider.is())
    1363             :     {
    1364             :         // stock-range-line
    1365           0 :         Reference< beans::XPropertySet > xStockPropSet = xStockPropProvider->getMinMaxLine();
    1366           0 :         if( xStockPropSet.is() )
    1367             :         {
    1368             :             pFS->startElement( FSNS( XML_c, XML_hiLowLines ),
    1369           0 :                 FSEND );
    1370           0 :             exportShapeProps( xStockPropSet );
    1371           0 :             pFS->endElement( FSNS( XML_c, XML_hiLowLines ) );
    1372             :         }
    1373             :         // stock updownbar
    1374             :         pFS->startElement( FSNS( XML_c, XML_upDownBars ),
    1375           0 :                 FSEND );
    1376             :         // TODO: gapWidth
    1377           0 :         sal_Int32 nGapWidth = 150;
    1378             :         pFS->singleElement( FSNS( XML_c, XML_gapWidth ),
    1379             :             XML_val, I32S( nGapWidth ),
    1380           0 :             FSEND );
    1381             : 
    1382           0 :         xStockPropSet = xStockPropProvider->getUpBar();
    1383           0 :         if( xStockPropSet.is() )
    1384             :         {
    1385             :             pFS->startElement( FSNS( XML_c, XML_upBars ),
    1386           0 :                 FSEND );
    1387           0 :             exportShapeProps( xStockPropSet );
    1388           0 :             pFS->endElement( FSNS( XML_c, XML_upBars ) );
    1389             :         }
    1390             : 
    1391           0 :         xStockPropSet = xStockPropProvider->getDownBar();
    1392           0 :         if( xStockPropSet.is() )
    1393             :         {
    1394             :             pFS->startElement( FSNS( XML_c, XML_downBars ),
    1395           0 :                 FSEND );
    1396           0 :             exportShapeProps( xStockPropSet );
    1397           0 :             pFS->endElement( FSNS( XML_c, XML_downBars ) );
    1398             :         }
    1399           0 :         pFS->endElement( FSNS( XML_c, XML_upDownBars ) );
    1400             :     }
    1401             : 
    1402           0 :     exportAxesId( nAttachedAxis );
    1403             : 
    1404           0 :     pFS->endElement( FSNS( XML_c, XML_stockChart ) );
    1405           0 : }
    1406             : 
    1407           0 : void ChartExport::exportSuffaceChart( Reference< chart2::XChartType > xChartType )
    1408             : {
    1409           0 :     FSHelperPtr pFS = GetFS();
    1410           0 :     sal_Int32 nTypeId = XML_surfaceChart;
    1411           0 :     if( mbIs3DChart )
    1412           0 :         nTypeId = XML_surface3DChart;
    1413             :     pFS->startElement( FSNS( XML_c, nTypeId ),
    1414           0 :             FSEND );
    1415           0 :     sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
    1416           0 :     exportSeries( xChartType, nAttachedAxis );
    1417           0 :     exportAxesId( nAttachedAxis );
    1418             : 
    1419           0 :     pFS->endElement( FSNS( XML_c, nTypeId ) );
    1420           0 : }
    1421             : 
    1422           0 : void ChartExport::exportSeries( Reference< chart2::XChartType > xChartType, sal_Int32& nAttachedAxis )
    1423             : {
    1424             : 
    1425           0 :     OUString aLabelRole = xChartType->getRoleOfSequenceForSeriesLabel();
    1426           0 :     Reference< chart2::XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY );
    1427           0 :     if( ! xDSCnt.is())
    1428             :         return;
    1429             : 
    1430           0 :     OUString aChartType( xChartType->getChartType());
    1431           0 :     sal_Int32 eChartType = lcl_getChartType( aChartType );
    1432             : 
    1433             :     // special export for stock charts
    1434           0 :     if( eChartType == chart::TYPEID_STOCK )
    1435             :     {
    1436           0 :         sal_Bool bJapaneseCandleSticks = sal_False;
    1437           0 :         Reference< beans::XPropertySet > xCTProp( xChartType, uno::UNO_QUERY );
    1438           0 :         if( xCTProp.is())
    1439           0 :             xCTProp->getPropertyValue( OUString("Japanese")) >>= bJapaneseCandleSticks;
    1440             :         exportCandleStickSeries(
    1441           0 :             xDSCnt->getDataSeries(), bJapaneseCandleSticks, nAttachedAxis );
    1442           0 :         return;
    1443             :     }
    1444             : 
    1445             : 
    1446             :     // export dataseries for current chart-type
    1447           0 :     Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries());
    1448           0 :     for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
    1449             :     {
    1450             :         // export series
    1451           0 :         Reference< chart2::data::XDataSource > xSource( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY );
    1452           0 :         if( xSource.is())
    1453             :         {
    1454             :             Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
    1455           0 :                 xSource->getDataSequences());
    1456             :             // search for main sequence and create a series element
    1457             :             {
    1458           0 :                 sal_Int32 nMainSequenceIndex = -1;
    1459           0 :                 sal_Int32 nSeriesLength = 0;
    1460           0 :                 Reference< chart2::data::XDataSequence > xValuesSeq;
    1461           0 :                 Reference< chart2::data::XDataSequence > xLabelSeq;
    1462           0 :                 sal_Int32 nSeqIdx=0;
    1463           0 :                 for( ; nSeqIdx<aSeqCnt.getLength(); ++nSeqIdx )
    1464             :                 {
    1465           0 :                     OUString aRole;
    1466           0 :                     Reference< chart2::data::XDataSequence > xTempValueSeq( aSeqCnt[nSeqIdx]->getValues() );
    1467           0 :                     if( nMainSequenceIndex==-1 )
    1468             :                     {
    1469           0 :                         Reference< beans::XPropertySet > xSeqProp( xTempValueSeq, uno::UNO_QUERY );
    1470           0 :                         if( xSeqProp.is())
    1471           0 :                             xSeqProp->getPropertyValue(OUString("Role")) >>= aRole;
    1472             :                         // "main" sequence
    1473           0 :                         if( aRole.equals( aLabelRole ))
    1474             :                         {
    1475           0 :                             xValuesSeq.set( xTempValueSeq );
    1476           0 :                             xLabelSeq.set( aSeqCnt[nSeqIdx]->getLabel());
    1477           0 :                             nMainSequenceIndex = nSeqIdx;
    1478           0 :                         }
    1479             :                     }
    1480           0 :                     sal_Int32 nSequenceLength = (xTempValueSeq.is()? xTempValueSeq->getData().getLength() : sal_Int32(0));
    1481           0 :                     if( nSeriesLength < nSequenceLength )
    1482           0 :                         nSeriesLength = nSequenceLength;
    1483           0 :                 }
    1484             : 
    1485             :                 // have found the main sequence, then xValuesSeq and
    1486             :                 // xLabelSeq contain those.  Otherwise both are empty
    1487             :                 {
    1488           0 :                     FSHelperPtr pFS = GetFS();
    1489             :                     pFS->startElement( FSNS( XML_c, XML_ser ),
    1490           0 :                         FSEND );
    1491             : 
    1492             :                     // TODO: idx and order
    1493             :                     pFS->singleElement( FSNS( XML_c, XML_idx ),
    1494             :                         XML_val, I32S(nSeriesIdx),
    1495           0 :                         FSEND );
    1496             :                     pFS->singleElement( FSNS( XML_c, XML_order ),
    1497             :                         XML_val, I32S(nSeriesIdx),
    1498           0 :                         FSEND );
    1499             : 
    1500             :                     // export label
    1501           0 :                     if( xLabelSeq.is() )
    1502           0 :                         exportSeriesText( xLabelSeq );
    1503             : 
    1504             :                     // export shape properties
    1505             :                     Reference< XPropertySet > xPropSet = SchXMLSeriesHelper::createOldAPISeriesPropertySet(
    1506           0 :                         aSeriesSeq[nSeriesIdx], getModel() );
    1507           0 :                     if( xPropSet.is() )
    1508             :                     {
    1509           0 :                         if( GetProperty( xPropSet, S("Axis") ) )
    1510             :                         {
    1511           0 :                             mAny >>= nAttachedAxis;
    1512           0 :                             if( nAttachedAxis == ::com::sun::star::chart::ChartAxisAssign::SECONDARY_Y )
    1513           0 :                                 nAttachedAxis = AXIS_SECONDARY_Y;
    1514             :                             else
    1515           0 :                                 nAttachedAxis = AXIS_PRIMARY_Y;
    1516             :                         }
    1517           0 :                         exportShapeProps( xPropSet );
    1518             :                     }
    1519             : 
    1520           0 :                     switch( eChartType )
    1521             :                     {
    1522             :                         case chart::TYPEID_LINE:
    1523             :                         {
    1524           0 :                             exportMarker( );
    1525           0 :                             break;
    1526             :                         }
    1527             :                         case chart::TYPEID_PIE:
    1528             :                         case chart::TYPEID_DOUGHNUT:
    1529             :                         {
    1530           0 :                             if( xPropSet.is() && GetProperty( xPropSet, S("SegmentOffset") ) )
    1531             :                             {
    1532           0 :                                 sal_Int32 nOffset = 0;
    1533           0 :                                 mAny >>= nOffset;
    1534             :                                 pFS->singleElement( FSNS( XML_c, XML_explosion ),
    1535             :                                     XML_val, I32S( nOffset ),
    1536           0 :                                     FSEND );
    1537             :                             }
    1538           0 :                             break;
    1539             :                         }
    1540             :                         case chart::TYPEID_SCATTER:
    1541             :                         {
    1542           0 :                             exportMarker( );
    1543           0 :                             exportSmooth( );
    1544           0 :                             break;
    1545             :                         }
    1546             :                         case chart::TYPEID_RADARLINE:
    1547             :                         {
    1548           0 :                             exportMarker( );
    1549           0 :                             break;
    1550             :                         }
    1551             :                     }
    1552             : 
    1553             :                     // TODO: Data Labels: show data lables
    1554             : 
    1555             :                     // export data points
    1556           0 :                     exportDataPoints( uno::Reference< beans::XPropertySet >( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY ), nSeriesLength );
    1557             : 
    1558             :                     // export categories
    1559           0 :                     if( mxCategoriesValues.is() )
    1560           0 :                         exportSeriesCategory( mxCategoriesValues );
    1561             : 
    1562           0 :                     if( (eChartType == chart::TYPEID_SCATTER)
    1563             :                         || (eChartType == chart::TYPEID_BUBBLE) )
    1564             :                     {
    1565             :                         // export xVal
    1566           0 :                         Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString("values-x") ) );
    1567           0 :                         if( xSequence.is() )
    1568             :                         {
    1569           0 :                             Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() );
    1570           0 :                             if( xValues.is() )
    1571           0 :                                 exportSeriesValues( xValues, XML_xVal );
    1572           0 :                         }
    1573             :                     }
    1574             : 
    1575             : 
    1576           0 :                     if( eChartType == chart::TYPEID_BUBBLE )
    1577             :                     {
    1578             :                         // export yVal
    1579           0 :                         Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString("values-y") ) );
    1580           0 :                         if( xSequence.is() )
    1581             :                         {
    1582           0 :                             Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() );
    1583           0 :                             if( xValues.is() )
    1584           0 :                                 exportSeriesValues( xValues, XML_yVal );
    1585           0 :                         }
    1586             :                     }
    1587             : 
    1588             :                     // export values
    1589           0 :                     if( xValuesSeq.is() )
    1590             :                     {
    1591           0 :                         sal_Int32 nYValueType = XML_val;
    1592           0 :                         if( eChartType == chart::TYPEID_SCATTER )
    1593           0 :                             nYValueType = XML_yVal;
    1594           0 :                         else if( eChartType == chart::TYPEID_BUBBLE )
    1595           0 :                             nYValueType = XML_bubbleSize;
    1596           0 :                         exportSeriesValues( xValuesSeq, nYValueType );
    1597             :                     }
    1598             : 
    1599           0 :                     pFS->endElement( FSNS( XML_c, XML_ser ) );
    1600           0 :                 }
    1601           0 :             }
    1602             :         }
    1603           0 :     }
    1604             : }
    1605             : 
    1606           0 : void ChartExport::exportCandleStickSeries(
    1607             :     const Sequence< Reference< chart2::XDataSeries > > & aSeriesSeq,
    1608             :     sal_Bool /*bJapaneseCandleSticks*/,
    1609             :     sal_Int32& nAttachedAxis )
    1610             : {
    1611           0 :     for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
    1612             :     {
    1613           0 :         Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nSeriesIdx] );
    1614           0 :         nAttachedAxis = lcl_isSeriesAttachedToFirstAxis( xSeries ) ? AXIS_PRIMARY_Y : AXIS_SECONDARY_Y;
    1615             : 
    1616           0 :         Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
    1617           0 :         if( xSource.is())
    1618             :         {
    1619             :             // export series in correct order (as we don't store roles)
    1620             :             // with japanese candlesticks: open, low, high, close
    1621             :             // otherwise: low, high, close
    1622             :             Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
    1623           0 :                 xSource->getDataSequences());
    1624             : 
    1625           0 :             Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
    1626           0 :             const char* sSeries[] = {"values-first","values-max","values-min","values-last",0};
    1627           0 :             for( sal_Int32 idx = 0; sSeries[idx] != 0 ; idx++ )
    1628             :             {
    1629           0 :                 Reference< chart2::data::XLabeledDataSequence > xLabeledSeq( lcl_getDataSequenceByRole( aSeqCnt, OUString::createFromAscii(sSeries[idx]) ) );
    1630           0 :                 if( xLabeledSeq.is())
    1631             :                 {
    1632           0 :                     Reference< chart2::data::XDataSequence > xLabelSeq( xLabeledSeq->getLabel());
    1633           0 :                     Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues());
    1634             :                         {
    1635           0 :                             FSHelperPtr pFS = GetFS();
    1636             :                             pFS->startElement( FSNS( XML_c, XML_ser ),
    1637           0 :                                 FSEND );
    1638             : 
    1639             :                             // TODO: idx and order
    1640             :                             pFS->singleElement( FSNS( XML_c, XML_idx ),
    1641             :                                 XML_val, I32S(idx),
    1642           0 :                                 FSEND );
    1643             :                             pFS->singleElement( FSNS( XML_c, XML_order ),
    1644             :                                 XML_val, I32S(idx),
    1645           0 :                                 FSEND );
    1646             : 
    1647             :                             // export label
    1648           0 :                             if( xLabelSeq.is() )
    1649           0 :                                 exportSeriesText( xLabelSeq );
    1650             : 
    1651             :                             // TODO:export shape properties
    1652             : 
    1653             :                             // export categories
    1654           0 :                             if( mxCategoriesValues.is() )
    1655           0 :                                 exportSeriesCategory( mxCategoriesValues );
    1656             : 
    1657             :                             // export values
    1658           0 :                             if( xValueSeq.is() )
    1659           0 :                                 exportSeriesValues( xValueSeq );
    1660             : 
    1661           0 :                             pFS->endElement( FSNS( XML_c, XML_ser ) );
    1662           0 :                         }
    1663             :                 }
    1664           0 :             }
    1665             :         }
    1666           0 :     }
    1667           0 : }
    1668             : 
    1669             : 
    1670             : 
    1671           0 : void ChartExport::exportSeriesText( const Reference< chart2::data::XDataSequence > & xValueSeq )
    1672             : {
    1673           0 :     FSHelperPtr pFS = GetFS();
    1674           0 :     Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
    1675             :     pFS->startElement( FSNS( XML_c, XML_tx ),
    1676           0 :             FSEND );
    1677             : 
    1678           0 :     OUString aCellRange =  xValueSeq->getSourceRangeRepresentation();
    1679           0 :     aCellRange = parseFormula( aCellRange );
    1680             :     pFS->startElement( FSNS( XML_c, XML_strRef ),
    1681           0 :             FSEND );
    1682             : 
    1683             :     pFS->startElement( FSNS( XML_c, XML_f ),
    1684           0 :             FSEND );
    1685           0 :     pFS->writeEscaped( aCellRange );
    1686           0 :     pFS->endElement( FSNS( XML_c, XML_f ) );
    1687             : 
    1688           0 :     OUString aLabelString = lcl_getLabelString( xValueSeq );
    1689             :     pFS->startElement( FSNS( XML_c, XML_strCache ),
    1690           0 :             FSEND );
    1691             :     pFS->singleElement( FSNS( XML_c, XML_ptCount ),
    1692             :             XML_val, "1",
    1693           0 :             FSEND );
    1694             :     pFS->startElement( FSNS( XML_c, XML_pt ),
    1695             :             XML_idx, "0",
    1696           0 :             FSEND );
    1697             :     pFS->startElement( FSNS( XML_c, XML_v ),
    1698           0 :             FSEND );
    1699           0 :     pFS->writeEscaped( aLabelString );
    1700           0 :     pFS->endElement( FSNS( XML_c, XML_v ) );
    1701           0 :     pFS->endElement( FSNS( XML_c, XML_pt ) );
    1702           0 :     pFS->endElement( FSNS( XML_c, XML_strCache ) );
    1703           0 :     pFS->endElement( FSNS( XML_c, XML_strRef ) );
    1704           0 :     pFS->endElement( FSNS( XML_c, XML_tx ) );
    1705           0 : }
    1706             : 
    1707           0 : void ChartExport::exportSeriesCategory( const Reference< chart2::data::XDataSequence > & xValueSeq )
    1708             : {
    1709           0 :     FSHelperPtr pFS = GetFS();
    1710           0 :     Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
    1711             :     pFS->startElement( FSNS( XML_c, XML_cat ),
    1712           0 :             FSEND );
    1713             : 
    1714           0 :     OUString aCellRange =  xValueSeq->getSourceRangeRepresentation();
    1715           0 :     aCellRange = parseFormula( aCellRange );
    1716             :     // TODO: need to handle XML_multiLvlStrRef according to aCellRange
    1717             :     pFS->startElement( FSNS( XML_c, XML_strRef ),
    1718           0 :             FSEND );
    1719             : 
    1720             :     pFS->startElement( FSNS( XML_c, XML_f ),
    1721           0 :             FSEND );
    1722           0 :     pFS->writeEscaped( aCellRange );
    1723           0 :     pFS->endElement( FSNS( XML_c, XML_f ) );
    1724             : 
    1725           0 :     ::std::vector< OUString > aCategories;
    1726           0 :     lcl_fillCategoriesIntoStringVector( xValueSeq, aCategories );
    1727           0 :     sal_Int32 ptCount = aCategories.size();
    1728             :     pFS->startElement( FSNS( XML_c, XML_strCache ),
    1729           0 :             FSEND );
    1730             :     pFS->singleElement( FSNS( XML_c, XML_ptCount ),
    1731             :             XML_val, I32S( ptCount ),
    1732           0 :             FSEND );
    1733           0 :     for( sal_Int32 i = 0; i < ptCount; i++ )
    1734             :     {
    1735             :         pFS->startElement( FSNS( XML_c, XML_pt ),
    1736             :             XML_idx, I32S( i ),
    1737           0 :             FSEND );
    1738             :         pFS->startElement( FSNS( XML_c, XML_v ),
    1739           0 :             FSEND );
    1740           0 :         pFS->writeEscaped( aCategories[i] );
    1741           0 :         pFS->endElement( FSNS( XML_c, XML_v ) );
    1742           0 :         pFS->endElement( FSNS( XML_c, XML_pt ) );
    1743             :     }
    1744             : 
    1745           0 :     pFS->endElement( FSNS( XML_c, XML_strCache ) );
    1746           0 :     pFS->endElement( FSNS( XML_c, XML_strRef ) );
    1747           0 :     pFS->endElement( FSNS( XML_c, XML_cat ) );
    1748           0 : }
    1749             : 
    1750           0 : void ChartExport::exportSeriesValues( const Reference< chart2::data::XDataSequence > & xValueSeq, sal_Int32 nValueType )
    1751             : {
    1752           0 :     FSHelperPtr pFS = GetFS();
    1753           0 :     Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
    1754             :     pFS->startElement( FSNS( XML_c, nValueType ),
    1755           0 :             FSEND );
    1756             : 
    1757           0 :     OUString aCellRange =  xValueSeq->getSourceRangeRepresentation();
    1758           0 :     aCellRange = parseFormula( aCellRange );
    1759             :     // TODO: need to handle XML_multiLvlStrRef according to aCellRange
    1760             :     pFS->startElement( FSNS( XML_c, XML_numRef ),
    1761           0 :             FSEND );
    1762             : 
    1763             :     pFS->startElement( FSNS( XML_c, XML_f ),
    1764           0 :             FSEND );
    1765           0 :     pFS->writeEscaped( aCellRange );
    1766           0 :     pFS->endElement( FSNS( XML_c, XML_f ) );
    1767             : 
    1768           0 :     ::std::vector< double > aValues;
    1769           0 :     aValues = lcl_getAllValuesFromSequence( xValueSeq );
    1770           0 :     sal_Int32 ptCount = aValues.size();
    1771             :     pFS->startElement( FSNS( XML_c, XML_numCache ),
    1772           0 :             FSEND );
    1773             :     pFS->startElement( FSNS( XML_c, XML_formatCode ),
    1774           0 :             FSEND );
    1775             :     // TODO: what format code?
    1776           0 :     pFS->writeEscaped( "General" );
    1777           0 :     pFS->endElement( FSNS( XML_c, XML_formatCode ) );
    1778             :     pFS->singleElement( FSNS( XML_c, XML_ptCount ),
    1779             :             XML_val, I32S( ptCount ),
    1780           0 :             FSEND );
    1781           0 :     for( sal_Int32 i = 0; i < ptCount; i++ )
    1782             :     {
    1783             :         pFS->startElement( FSNS( XML_c, XML_pt ),
    1784             :             XML_idx, I32S( i ),
    1785           0 :             FSEND );
    1786             :         pFS->startElement( FSNS( XML_c, XML_v ),
    1787           0 :             FSEND );
    1788           0 :         if (aValues[i] == aValues[i])
    1789           0 :             pFS->write( aValues[i] );
    1790           0 :         pFS->endElement( FSNS( XML_c, XML_v ) );
    1791           0 :         pFS->endElement( FSNS( XML_c, XML_pt ) );
    1792             :     }
    1793             : 
    1794           0 :     pFS->endElement( FSNS( XML_c, XML_numCache ) );
    1795           0 :     pFS->endElement( FSNS( XML_c, XML_numRef ) );
    1796           0 :     pFS->endElement( FSNS( XML_c, nValueType ) );
    1797           0 : }
    1798             : 
    1799           0 : void ChartExport::exportShapeProps( Reference< XPropertySet > xPropSet )
    1800             : {
    1801           0 :     FSHelperPtr pFS = GetFS();
    1802             :     pFS->startElement( FSNS( XML_c, XML_spPr ),
    1803           0 :             FSEND );
    1804             : 
    1805           0 :     WriteFill( xPropSet );
    1806           0 :     WriteOutline( xPropSet );
    1807           0 :     pFS->endElement( FSNS( XML_c, XML_spPr ) );
    1808           0 : }
    1809             : 
    1810           0 : void ChartExport::InitPlotArea( )
    1811             : {
    1812           0 :        Reference< XPropertySet > xDiagramProperties (mxDiagram, uno::UNO_QUERY);
    1813             : 
    1814             :     //    Check for supported services and then the properties provided by this service.
    1815           0 :     Reference<lang::XServiceInfo> xServiceInfo (mxDiagram, uno::UNO_QUERY);
    1816           0 :     if (xServiceInfo.is())
    1817             :     {
    1818           0 :         if (xServiceInfo->supportsService(
    1819           0 :             OUString("com.sun.star.chart.ChartAxisXSupplier")))
    1820             :         {
    1821           0 :             xDiagramProperties->getPropertyValue(
    1822           0 :                 OUString("HasXAxis")) >>= mbHasXAxis;
    1823             :         }
    1824           0 :         if (xServiceInfo->supportsService(
    1825           0 :             OUString("com.sun.star.chart.ChartAxisYSupplier")))
    1826             :         {
    1827           0 :             xDiagramProperties->getPropertyValue(
    1828           0 :                 OUString("HasYAxis")) >>= mbHasYAxis;
    1829             :         }
    1830           0 :         if (xServiceInfo->supportsService(
    1831           0 :             OUString("com.sun.star.chart.ChartAxisZSupplier")))
    1832             :         {
    1833           0 :             xDiagramProperties->getPropertyValue(
    1834           0 :                 OUString("HasZAxis")) >>= mbHasZAxis;
    1835             :         }
    1836           0 :         if (xServiceInfo->supportsService(
    1837           0 :             OUString("com.sun.star.chart.ChartTwoAxisXSupplier")))
    1838             :         {
    1839           0 :             xDiagramProperties->getPropertyValue(
    1840           0 :                 OUString("HasSecondaryXAxis")) >>= mbHasSecondaryXAxis;
    1841             :         }
    1842           0 :         if (xServiceInfo->supportsService(
    1843           0 :             OUString("com.sun.star.chart.ChartTwoAxisYSupplier")))
    1844             :         {
    1845           0 :             xDiagramProperties->getPropertyValue(
    1846           0 :                 OUString("HasSecondaryYAxis")) >>= mbHasSecondaryYAxis;
    1847             :         }
    1848             :     }
    1849             : 
    1850           0 :     xDiagramProperties->getPropertyValue(
    1851           0 :         OUString ("Dim3D")) >>=  mbIs3DChart;
    1852             : 
    1853           0 :     Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
    1854           0 :     if( mbHasCategoryLabels && mxNewDiagram.is())
    1855             :     {
    1856           0 :         Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( mxNewDiagram ) );
    1857           0 :         if( xCategories.is() )
    1858             :         {
    1859           0 :             mxCategoriesValues.set( xCategories->getValues() );
    1860           0 :         }
    1861           0 :     }
    1862           0 : }
    1863             : 
    1864           0 : void ChartExport::exportAxes( )
    1865             : {
    1866           0 :     sal_Int32 nSize = maAxes.size();
    1867           0 :     for( sal_Int32 nIdx = 0; nIdx < nSize; nIdx++ )
    1868             :     {
    1869           0 :         exportAxis( maAxes[nIdx] );
    1870             :     }
    1871           0 : }
    1872             : 
    1873           0 : void ChartExport::exportAxis( AxisIdPair aAxisIdPair )
    1874             : {
    1875             :     // get some properties from document first
    1876           0 :     sal_Bool bHasXAxisTitle = sal_False,
    1877           0 :         bHasYAxisTitle = sal_False,
    1878           0 :         bHasZAxisTitle = sal_False,
    1879           0 :         bHasSecondaryXAxisTitle = sal_False,
    1880           0 :         bHasSecondaryYAxisTitle = sal_False;
    1881           0 :     sal_Bool bHasXAxisMajorGrid = sal_False,
    1882           0 :         bHasXAxisMinorGrid = sal_False,
    1883           0 :         bHasYAxisMajorGrid = sal_False,
    1884           0 :         bHasYAxisMinorGrid = sal_False,
    1885           0 :         bHasZAxisMajorGrid = sal_False,
    1886           0 :         bHasZAxisMinorGrid = sal_False;
    1887             : 
    1888           0 :        Reference< XPropertySet > xDiagramProperties (mxDiagram, uno::UNO_QUERY);
    1889             : 
    1890           0 :     xDiagramProperties->getPropertyValue(
    1891           0 :         OUString ("HasXAxisTitle")) >>= bHasXAxisTitle;
    1892           0 :     xDiagramProperties->getPropertyValue(
    1893           0 :         OUString ("HasYAxisTitle")) >>= bHasYAxisTitle;
    1894           0 :     xDiagramProperties->getPropertyValue(
    1895           0 :         OUString ("HasZAxisTitle")) >>= bHasZAxisTitle;
    1896           0 :     xDiagramProperties->getPropertyValue(
    1897           0 :         OUString ("HasSecondaryXAxisTitle")) >>=  bHasSecondaryXAxisTitle;
    1898           0 :     xDiagramProperties->getPropertyValue(
    1899           0 :         OUString ("HasSecondaryYAxisTitle")) >>=  bHasSecondaryYAxisTitle;
    1900             : 
    1901           0 :     xDiagramProperties->getPropertyValue(
    1902           0 :         OUString ("HasXAxisGrid")) >>=  bHasXAxisMajorGrid;
    1903           0 :     xDiagramProperties->getPropertyValue(
    1904           0 :         OUString ("HasYAxisGrid")) >>=  bHasYAxisMajorGrid;
    1905           0 :     xDiagramProperties->getPropertyValue(
    1906           0 :         OUString ("HasZAxisGrid")) >>=  bHasZAxisMajorGrid;
    1907             : 
    1908           0 :     xDiagramProperties->getPropertyValue(
    1909           0 :         OUString ("HasXAxisHelpGrid")) >>=  bHasXAxisMinorGrid;
    1910           0 :     xDiagramProperties->getPropertyValue(
    1911           0 :         OUString ("HasYAxisHelpGrid")) >>=  bHasYAxisMinorGrid;
    1912           0 :     xDiagramProperties->getPropertyValue(
    1913           0 :         OUString ("HasZAxisHelpGrid")) >>=  bHasZAxisMinorGrid;
    1914             : 
    1915           0 :     Reference< XPropertySet > xAxisProp;
    1916           0 :     Reference< drawing::XShape > xAxisTitle;
    1917           0 :     Reference< beans::XPropertySet > xMajorGrid;
    1918           0 :     Reference< beans::XPropertySet > xMinorGrid;
    1919           0 :     sal_Int32 nAxisType = XML_catAx;
    1920           0 :     const char* sAxPos = NULL;
    1921             : 
    1922           0 :     switch( aAxisIdPair.nAxisType )
    1923             :     {
    1924             :         case AXIS_PRIMARY_X:
    1925             :         {
    1926           0 :             Reference< ::com::sun::star::chart::XAxisXSupplier > xAxisXSupp( mxDiagram, uno::UNO_QUERY );
    1927           0 :             if( xAxisXSupp.is())
    1928           0 :                 xAxisProp = xAxisXSupp->getXAxis();
    1929           0 :             if( bHasXAxisTitle )
    1930           0 :                 xAxisTitle.set( xAxisXSupp->getXAxisTitle(), uno::UNO_QUERY );
    1931           0 :             if( bHasXAxisMajorGrid )
    1932           0 :                 xMajorGrid.set( xAxisXSupp->getXMainGrid(), uno::UNO_QUERY );
    1933           0 :             if( bHasXAxisMinorGrid )
    1934           0 :                 xMinorGrid.set( xAxisXSupp->getXHelpGrid(), uno::UNO_QUERY );
    1935             : 
    1936           0 :             sal_Int32 eChartType = getChartType( );
    1937           0 :             if( (eChartType == chart::TYPEID_SCATTER)
    1938             :                 || (eChartType == chart::TYPEID_BUBBLE) )
    1939           0 :                 nAxisType = XML_valAx;
    1940           0 :             else if( eChartType == chart::TYPEID_STOCK )
    1941           0 :                 nAxisType = XML_dateAx;
    1942             :             // FIXME: axPos, need to check axis direction
    1943           0 :             sAxPos = "b";
    1944           0 :             break;
    1945             :         }
    1946             :         case AXIS_PRIMARY_Y:
    1947             :         {
    1948           0 :             Reference< ::com::sun::star::chart::XAxisYSupplier > xAxisYSupp( mxDiagram, uno::UNO_QUERY );
    1949           0 :             if( xAxisYSupp.is())
    1950           0 :                 xAxisProp = xAxisYSupp->getYAxis();
    1951           0 :             if( bHasYAxisTitle )
    1952           0 :                 xAxisTitle.set( xAxisYSupp->getYAxisTitle(), uno::UNO_QUERY );
    1953           0 :             if( bHasYAxisMajorGrid )
    1954           0 :                 xMajorGrid.set( xAxisYSupp->getYMainGrid(), uno::UNO_QUERY );
    1955           0 :             if( bHasYAxisMinorGrid )
    1956           0 :                 xMinorGrid.set( xAxisYSupp->getYHelpGrid(), uno::UNO_QUERY );
    1957             : 
    1958           0 :             nAxisType = XML_valAx;
    1959             :             // FIXME: axPos, need to check axis direction
    1960           0 :             sAxPos = "l";
    1961           0 :             break;
    1962             :         }
    1963             :         case AXIS_PRIMARY_Z:
    1964             :         {
    1965           0 :             Reference< ::com::sun::star::chart::XAxisZSupplier > xAxisZSupp( mxDiagram, uno::UNO_QUERY );
    1966           0 :             if( xAxisZSupp.is())
    1967           0 :                 xAxisProp = xAxisZSupp->getZAxis();
    1968           0 :             if( bHasZAxisTitle )
    1969           0 :                 xAxisTitle.set( xAxisZSupp->getZAxisTitle(), uno::UNO_QUERY );
    1970           0 :             if( bHasZAxisMajorGrid )
    1971           0 :                 xMajorGrid.set( xAxisZSupp->getZMainGrid(), uno::UNO_QUERY );
    1972           0 :             if( bHasZAxisMinorGrid )
    1973           0 :                 xMinorGrid.set( xAxisZSupp->getZHelpGrid(), uno::UNO_QUERY );
    1974             : 
    1975           0 :             sal_Int32 eChartType = getChartType( );
    1976           0 :             if( (eChartType == chart::TYPEID_SCATTER)
    1977             :                 || (eChartType == chart::TYPEID_BUBBLE) )
    1978           0 :                 nAxisType = XML_valAx;
    1979           0 :             else if( eChartType == chart::TYPEID_STOCK )
    1980           0 :                 nAxisType = XML_dateAx;
    1981             :             // FIXME: axPos, need to check axis direction
    1982           0 :             sAxPos = "b";
    1983           0 :             break;
    1984             :         }
    1985             :         case AXIS_SECONDARY_Y:
    1986             :         {
    1987           0 :             Reference< ::com::sun::star::chart::XTwoAxisYSupplier > xAxisTwoYSupp( mxDiagram, uno::UNO_QUERY );
    1988           0 :             if( xAxisTwoYSupp.is())
    1989           0 :                 xAxisProp = xAxisTwoYSupp->getSecondaryYAxis();
    1990           0 :             if( bHasSecondaryYAxisTitle )
    1991             :             {
    1992           0 :                 Reference< ::com::sun::star::chart::XSecondAxisTitleSupplier > xAxisSupp( mxDiagram, uno::UNO_QUERY );
    1993           0 :                 xAxisTitle.set( xAxisSupp->getSecondYAxisTitle(), uno::UNO_QUERY );
    1994             :             }
    1995             : 
    1996           0 :             nAxisType = XML_valAx;
    1997             :             // FIXME: axPos, need to check axis direction
    1998           0 :             sAxPos = "l";
    1999           0 :             break;
    2000             :         }
    2001             :     }
    2002             : 
    2003             : 
    2004           0 :     _exportAxis( xAxisProp, xAxisTitle, xMajorGrid, xMinorGrid, nAxisType, sAxPos, aAxisIdPair );
    2005           0 : }
    2006             : 
    2007           0 : void ChartExport::_exportAxis(
    2008             :     const Reference< XPropertySet >& xAxisProp,
    2009             :     const Reference< drawing::XShape >& xAxisTitle,
    2010             :     const Reference< XPropertySet >& xMajorGrid,
    2011             :     const Reference< XPropertySet >& xMinorGrid,
    2012             :     sal_Int32 nAxisType,
    2013             :     const char* sAxisPos,
    2014             :     AxisIdPair aAxisIdPair )
    2015             : {
    2016           0 :     FSHelperPtr pFS = GetFS();
    2017             :     pFS->startElement( FSNS( XML_c, nAxisType ),
    2018           0 :             FSEND );
    2019             :     pFS->singleElement( FSNS( XML_c, XML_axId ),
    2020             :             XML_val, I32S( aAxisIdPair.nAxisId ),
    2021           0 :             FSEND );
    2022             : 
    2023             :     pFS->startElement( FSNS( XML_c, XML_scaling ),
    2024           0 :             FSEND );
    2025             :     // orientation: minMax, maxMin
    2026           0 :     sal_Bool bReverseDirection = sal_False;
    2027           0 :     if(GetProperty( xAxisProp, S( "ReverseDirection" ) ) )
    2028           0 :         mAny >>= bReverseDirection;
    2029             : 
    2030           0 :     const char* orientation = bReverseDirection ? "maxMin":"minMax";
    2031             :     pFS->singleElement( FSNS( XML_c, XML_orientation ),
    2032             :             XML_val, orientation,
    2033           0 :             FSEND );
    2034             :     // logBase, min, max
    2035           0 :     if(GetProperty( xAxisProp, S( "Logarithmic" ) ) )
    2036             :     {
    2037           0 :         sal_Bool bLogarithmic = sal_False;
    2038           0 :         mAny >>= bLogarithmic;
    2039           0 :         if( bLogarithmic )
    2040             :         {
    2041             :             // default value is 10?
    2042           0 :             sal_Int32 nLogBase = 10;
    2043             :             pFS->singleElement( FSNS( XML_c, XML_logBase ),
    2044             :                 XML_val, I32S( nLogBase ),
    2045           0 :                 FSEND );
    2046             :         }
    2047             :     }
    2048           0 :     sal_Bool bAutoMax = sal_False;
    2049           0 :     if(GetProperty( xAxisProp, S( "AutoMax" ) ) )
    2050           0 :         mAny >>= bAutoMax;
    2051             : 
    2052           0 :     if( !bAutoMax && (GetProperty( xAxisProp, S( "Max" ) ) ))
    2053             :     {
    2054           0 :         double dMax = 0;
    2055           0 :         mAny >>= dMax;
    2056             :         pFS->singleElement( FSNS( XML_c, XML_max ),
    2057             :             XML_val, IS( dMax ),
    2058           0 :             FSEND );
    2059             :     }
    2060             : 
    2061           0 :     sal_Bool bAutoMin = sal_False;
    2062           0 :     if(GetProperty( xAxisProp, S( "AutoMin" ) ) )
    2063           0 :         mAny >>= bAutoMin;
    2064             : 
    2065           0 :     if( !bAutoMin && (GetProperty( xAxisProp, S( "Min" ) ) ))
    2066             :     {
    2067           0 :         double dMin = 0;
    2068           0 :         mAny >>= dMin;
    2069             :         pFS->singleElement( FSNS( XML_c, XML_min ),
    2070             :             XML_val, IS( dMin ),
    2071           0 :             FSEND );
    2072             :     }
    2073             : 
    2074           0 :     pFS->endElement( FSNS( XML_c, XML_scaling ) );
    2075             : 
    2076             :     // title
    2077           0 :     if( xAxisTitle.is() )
    2078           0 :         exportTitle( xAxisTitle );
    2079             : 
    2080           0 :     sal_Bool bVisible = sal_True;
    2081           0 :     if( xAxisProp.is() )
    2082             :     {
    2083           0 :         xAxisProp->getPropertyValue(
    2084           0 :             OUString ("Visible")) >>=  bVisible;
    2085             :     }
    2086             : 
    2087           0 :     if( !bVisible )
    2088             :     {
    2089             :         // other value?
    2090             :         pFS->singleElement( FSNS( XML_c, XML_delete ),
    2091             :             XML_val, "1",
    2092           0 :             FSEND );
    2093             :     }
    2094             : 
    2095             :     // FIXME: axPos, need to check the property "ReverseDirection"
    2096             :     pFS->singleElement( FSNS( XML_c, XML_axPos ),
    2097             :             XML_val, sAxisPos,
    2098           0 :             FSEND );
    2099             :     // major grid line
    2100           0 :     if( xMajorGrid.is())
    2101             :     {
    2102             :         pFS->startElement( FSNS( XML_c, XML_majorGridlines ),
    2103           0 :             FSEND );
    2104           0 :         exportShapeProps( xMajorGrid );
    2105           0 :         pFS->endElement( FSNS( XML_c, XML_majorGridlines ) );
    2106             :     }
    2107             : 
    2108             :     // minor grid line
    2109           0 :     if( xMinorGrid.is())
    2110             :     {
    2111             :         pFS->startElement( FSNS( XML_c, XML_minorGridlines ),
    2112           0 :             FSEND );
    2113           0 :         exportShapeProps( xMajorGrid );
    2114           0 :         pFS->endElement( FSNS( XML_c, XML_minorGridlines ) );
    2115             :     }
    2116             : 
    2117             :     // majorTickMark
    2118           0 :     sal_Int32 nValue = 0;
    2119           0 :     if(GetProperty( xAxisProp, S( "Marks" ) ) )
    2120             :     {
    2121           0 :         mAny >>= nValue;
    2122           0 :         sal_Bool bInner = nValue & ::com::sun::star::chart::ChartAxisMarks::INNER;
    2123           0 :         sal_Bool bOuter = nValue & ::com::sun::star::chart::ChartAxisMarks::OUTER;
    2124           0 :         const char* majorTickMark = NULL;
    2125           0 :         if( bInner && bOuter )
    2126           0 :             majorTickMark = "cross";
    2127           0 :         else if( bInner )
    2128           0 :             majorTickMark = "in";
    2129           0 :         else if( bOuter )
    2130           0 :             majorTickMark = "out";
    2131             :         else
    2132           0 :             majorTickMark = "none";
    2133             :         pFS->singleElement( FSNS( XML_c, XML_majorTickMark ),
    2134             :             XML_val, majorTickMark,
    2135           0 :             FSEND );
    2136             :     }
    2137             :     // minorTickMark
    2138           0 :     if(GetProperty( xAxisProp, S( "HelpMarks" ) ) )
    2139             :     {
    2140           0 :         mAny >>= nValue;
    2141           0 :         sal_Bool bInner = nValue & ::com::sun::star::chart::ChartAxisMarks::INNER;
    2142           0 :         sal_Bool bOuter = nValue & ::com::sun::star::chart::ChartAxisMarks::OUTER;
    2143           0 :         const char* minorTickMark = NULL;
    2144           0 :         if( bInner && bOuter )
    2145           0 :             minorTickMark = "cross";
    2146           0 :         else if( bInner )
    2147           0 :             minorTickMark = "in";
    2148           0 :         else if( bOuter )
    2149           0 :             minorTickMark = "out";
    2150             :         else
    2151           0 :             minorTickMark = "none";
    2152             :         pFS->singleElement( FSNS( XML_c, XML_minorTickMark ),
    2153             :             XML_val, minorTickMark,
    2154           0 :             FSEND );
    2155             :     }
    2156             :     // tickLblPos
    2157           0 :     const char* sTickLblPos = NULL;
    2158           0 :     sal_Bool bDisplayLabel = sal_True;
    2159           0 :     if(GetProperty( xAxisProp, S( "DisplayLabels" ) ) )
    2160           0 :         mAny >>= bDisplayLabel;
    2161           0 :     if( bDisplayLabel && (GetProperty( xAxisProp, S( "LabelPosition" ) ) ))
    2162             :     {
    2163           0 :         ::com::sun::star::chart::ChartAxisLabelPosition eLabelPosition = ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS;
    2164           0 :         mAny >>= eLabelPosition;
    2165           0 :         switch( eLabelPosition )
    2166             :         {
    2167             :             case ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS:
    2168             :             case ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS_OTHER_SIDE:
    2169           0 :                 sTickLblPos = "nextTo";
    2170           0 :                 break;
    2171             :             case ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START:
    2172           0 :                 sTickLblPos = "low";
    2173           0 :                 break;
    2174             :             case ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END:
    2175           0 :                 sTickLblPos = "high";
    2176           0 :                 break;
    2177             :             default:
    2178           0 :                 sTickLblPos = "nextTo";
    2179           0 :                 break;
    2180             :         }
    2181             :     }
    2182             :     else
    2183             :     {
    2184           0 :         sTickLblPos = "none";
    2185             :     }
    2186             :     pFS->singleElement( FSNS( XML_c, XML_tickLblPos ),
    2187             :             XML_val, sTickLblPos,
    2188           0 :             FSEND );
    2189             : 
    2190             :     pFS->singleElement( FSNS( XML_c, XML_crossAx ),
    2191             :             XML_val, I32S( aAxisIdPair.nCrossAx ),
    2192           0 :             FSEND );
    2193             : 
    2194             :     // crosses & crossesAt
    2195           0 :     sal_Bool bCrossesValue = sal_False;
    2196           0 :     const char* sCrosses = NULL;
    2197           0 :     if(GetProperty( xAxisProp, S( "CrossoverPosition" ) ) )
    2198             :     {
    2199           0 :         ::com::sun::star::chart::ChartAxisPosition ePosition( ::com::sun::star::chart::ChartAxisPosition_ZERO );
    2200           0 :         mAny >>= ePosition;
    2201           0 :         switch( ePosition )
    2202             :         {
    2203             :             case ::com::sun::star::chart::ChartAxisPosition_START:
    2204           0 :                 sCrosses = "min";
    2205           0 :                 break;
    2206             :             case ::com::sun::star::chart::ChartAxisPosition_END:
    2207           0 :                 sCrosses = "max";
    2208           0 :                 break;
    2209             :             case ::com::sun::star::chart::ChartAxisPosition_ZERO:
    2210           0 :                 sCrosses = "autoZero";
    2211           0 :                 break;
    2212             :             default:
    2213           0 :                 bCrossesValue = sal_True;
    2214           0 :                 break;
    2215             :         }
    2216             :     }
    2217             : 
    2218           0 :     if( bCrossesValue && GetProperty( xAxisProp, S("CrossoverValue" ) ) )
    2219             :     {
    2220           0 :         double dValue = 0;
    2221           0 :         mAny >>= dValue;
    2222             :         pFS->singleElement( FSNS( XML_c, XML_crossesAt ),
    2223             :             XML_val, IS( dValue ),
    2224           0 :             FSEND );
    2225             :     }
    2226             :     else
    2227             :     {
    2228             :         pFS->singleElement( FSNS( XML_c, XML_crosses ),
    2229             :             XML_val, sCrosses,
    2230           0 :             FSEND );
    2231             :     }
    2232             : 
    2233           0 :     if( nAxisType == XML_catAx )
    2234             :     {
    2235             :         // FIXME: seems not support? lblAlgn
    2236           0 :         const char* sLblAlgn = "ctr";
    2237             :         pFS->singleElement( FSNS( XML_c, XML_lblAlgn ),
    2238             :             XML_val, sLblAlgn,
    2239           0 :             FSEND );
    2240             :     }
    2241           0 :     if( ( nAxisType == XML_catAx )
    2242             :         || ( nAxisType == XML_dateAx ) )
    2243             :     {
    2244             :         // FIXME: seems not support? use default value,
    2245           0 :         const char* isAuto = "1";
    2246             :         pFS->singleElement( FSNS( XML_c, XML_auto ),
    2247             :             XML_val, isAuto,
    2248           0 :             FSEND );
    2249             : 
    2250             :         // FIXME: seems not support? lblOffset
    2251           0 :         sal_Int32 nLblOffset = 100;
    2252             :         pFS->singleElement( FSNS( XML_c, XML_lblOffset ),
    2253             :             XML_val, I32S( nLblOffset ),
    2254           0 :             FSEND );
    2255             :     }
    2256             : 
    2257             :     // majorUnit
    2258           0 :     sal_Bool bAutoStepMain = sal_False;
    2259           0 :     if(GetProperty( xAxisProp, S( "AutoStepMain" ) ) )
    2260           0 :         mAny >>= bAutoStepMain;
    2261             : 
    2262           0 :     if( !bAutoStepMain && (GetProperty( xAxisProp, S( "StepMain" ) ) ))
    2263             :     {
    2264           0 :         double dMajorUnit = 0;
    2265           0 :         mAny >>= dMajorUnit;
    2266             :         pFS->singleElement( FSNS( XML_c, XML_majorUnit ),
    2267             :             XML_val, IS( dMajorUnit ),
    2268           0 :             FSEND );
    2269             :     }
    2270             :     // minorUnit
    2271           0 :     sal_Bool bAutoStepHelp = sal_False;
    2272           0 :     if(GetProperty( xAxisProp, S( "AutoStepHelp" ) ) )
    2273           0 :         mAny >>= bAutoStepHelp;
    2274             : 
    2275           0 :     if( !bAutoStepHelp && (GetProperty( xAxisProp, S( "StepHelp" ) ) ))
    2276             :     {
    2277           0 :         double dMinorUnit = 0;
    2278           0 :         mAny >>= dMinorUnit;
    2279             :         pFS->singleElement( FSNS( XML_c, XML_minorUnit ),
    2280             :             XML_val, IS( dMinorUnit ),
    2281           0 :             FSEND );
    2282             :     }
    2283             : 
    2284             :     // shape properties
    2285           0 :     exportShapeProps( xAxisProp );
    2286             :     // TODO: text properties
    2287             : 
    2288           0 :     pFS->endElement( FSNS( XML_c, nAxisType ) );
    2289           0 : }
    2290             : 
    2291           0 : void ChartExport::exportDataPoints(
    2292             :     const uno::Reference< beans::XPropertySet > & xSeriesProperties,
    2293             :     sal_Int32 nSeriesLength )
    2294             : {
    2295           0 :     uno::Reference< chart2::XDataSeries > xSeries( xSeriesProperties, uno::UNO_QUERY );
    2296           0 :     bool bVaryColorsByPoint = false;
    2297           0 :     Sequence< sal_Int32 > aDataPointSeq;
    2298           0 :     if( xSeriesProperties.is())
    2299             :     {
    2300           0 :         Any aAny = xSeriesProperties->getPropertyValue(
    2301           0 :             OUString(  "AttributedDataPoints" ));
    2302           0 :         aAny >>= aDataPointSeq;
    2303           0 :         xSeriesProperties->getPropertyValue(
    2304           0 :             OUString(  "VaryColorsByPoint" )) >>= bVaryColorsByPoint;
    2305             :     }
    2306             : 
    2307           0 :     const sal_Int32 * pPoints = aDataPointSeq.getConstArray();
    2308             :     sal_Int32 nElement;
    2309           0 :     Reference< chart2::XColorScheme > xColorScheme;
    2310           0 :     if( mxNewDiagram.is())
    2311           0 :         xColorScheme.set( mxNewDiagram->getDefaultColorScheme());
    2312             : 
    2313           0 :     if( bVaryColorsByPoint && xColorScheme.is() )
    2314             :     {
    2315           0 :         ::std::set< sal_Int32 > aAttrPointSet;
    2316           0 :         ::std::copy( pPoints, pPoints + aDataPointSeq.getLength(),
    2317           0 :                     ::std::inserter( aAttrPointSet, aAttrPointSet.begin()));
    2318           0 :         const ::std::set< sal_Int32 >::const_iterator aEndIt( aAttrPointSet.end());
    2319           0 :         for( nElement = 0; nElement < nSeriesLength; ++nElement )
    2320             :         {
    2321           0 :             uno::Reference< beans::XPropertySet > xPropSet;
    2322           0 :             if( aAttrPointSet.find( nElement ) != aEndIt )
    2323             :             {
    2324             :                 try
    2325             :                 {
    2326             :                     xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
    2327           0 :                             xSeries, nElement, getModel() );
    2328             :                 }
    2329           0 :                 catch( const uno::Exception & rEx )
    2330             :                 {
    2331             :                     (void)rEx; // avoid warning for pro build
    2332             :                     OSL_TRACE( "Exception caught during Export of data point: %s",
    2333             :                                     rtl::OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
    2334             :                 }
    2335             :             }
    2336             :             else
    2337             :             {
    2338             :                 // property set only containing the color
    2339           0 :                 xPropSet.set( new ColorPropertySet( xColorScheme->getColorByIndex( nElement )));
    2340             :             }
    2341             : 
    2342           0 :             if( xPropSet.is() )
    2343             :             {
    2344             :                 OSL_TRACE("ChartExport::exportDataPoints -- writer data points ");
    2345           0 :                 FSHelperPtr pFS = GetFS();
    2346             :                 pFS->startElement( FSNS( XML_c, XML_dPt ),
    2347           0 :                     FSEND );
    2348             :                 pFS->singleElement( FSNS( XML_c, XML_idx ),
    2349             :                     XML_val, I32S(nElement),
    2350           0 :                     FSEND );
    2351           0 :                 exportShapeProps( xPropSet );
    2352             : 
    2353           0 :                 pFS->endElement( FSNS( XML_c, XML_dPt ) );
    2354             :             }
    2355           0 :         }
    2356           0 :     }
    2357           0 : }
    2358             : 
    2359           0 : void ChartExport::exportAxesId( sal_Int32 nAttachedAxis )
    2360             : {
    2361           0 :     sal_Int32 nAxisIdx = lcl_generateRandomValue();
    2362           0 :     sal_Int32 nAxisIdy = lcl_generateRandomValue();
    2363           0 :     maAxes.push_back( AxisIdPair( AXIS_PRIMARY_X, nAxisIdx, nAxisIdy ) );
    2364           0 :     maAxes.push_back( AxisIdPair( nAttachedAxis, nAxisIdy, nAxisIdx ) );
    2365           0 :     FSHelperPtr pFS = GetFS();
    2366             :     pFS->singleElement( FSNS( XML_c, XML_axId ),
    2367             :             XML_val, I32S( nAxisIdx ),
    2368           0 :             FSEND );
    2369             :     pFS->singleElement( FSNS( XML_c, XML_axId ),
    2370             :             XML_val, I32S( nAxisIdy ),
    2371           0 :             FSEND );
    2372           0 :     if( mbHasZAxis )
    2373             :     {
    2374           0 :         sal_Int32 nAxisIdz = 0;
    2375           0 :         if( isDeep3dChart() )
    2376             :         {
    2377           0 :             nAxisIdz = lcl_generateRandomValue();
    2378           0 :             maAxes.push_back( AxisIdPair( AXIS_PRIMARY_Z, nAxisIdz, nAxisIdy ) );
    2379             :         }
    2380             :         pFS->singleElement( FSNS( XML_c, XML_axId ),
    2381             :             XML_val, I32S( nAxisIdz ),
    2382           0 :             FSEND );
    2383           0 :     }
    2384           0 : }
    2385             : 
    2386           0 : void ChartExport::exportGrouping( sal_Bool isBar )
    2387             : {
    2388           0 :     FSHelperPtr pFS = GetFS();
    2389           0 :     Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
    2390             :     // grouping
    2391           0 :     sal_Bool bStacked = sal_False;
    2392           0 :     if( GetProperty( xPropSet, S( "Stacked" ) ) )
    2393           0 :         mAny >>= bStacked;
    2394           0 :     sal_Bool bPercentage = sal_False;
    2395           0 :     if( GetProperty( xPropSet, S( "Percent" ) ) )
    2396           0 :         mAny >>= bPercentage;
    2397             : 
    2398           0 :     const char* grouping = NULL;
    2399           0 :     if( bStacked )
    2400           0 :         grouping = "stacked";
    2401           0 :     else if( bPercentage )
    2402           0 :         grouping = "percentStacked";
    2403             :     else
    2404             :     {
    2405           0 :         if( isBar && !isDeep3dChart() )
    2406           0 :             grouping = "clustered";
    2407             :         else
    2408           0 :             grouping = "standard";
    2409             :     }
    2410             :     pFS->singleElement( FSNS( XML_c, XML_grouping ),
    2411             :             XML_val, grouping,
    2412           0 :             FSEND );
    2413           0 : }
    2414             : 
    2415           0 : void ChartExport::exportMarker()
    2416             : {
    2417           0 :     FSHelperPtr pFS = GetFS();
    2418             :     pFS->startElement( FSNS( XML_c, XML_marker ),
    2419           0 :             FSEND );
    2420           0 :     Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY );
    2421           0 :     sal_Int32 nSymbolType = ::com::sun::star::chart::ChartSymbolType::NONE;
    2422           0 :     if( GetProperty( xPropSet, S( "SymbolType" ) ) )
    2423           0 :         mAny >>= nSymbolType;
    2424             :     // TODO: more properties support for marker
    2425           0 :     if( nSymbolType == ::com::sun::star::chart::ChartSymbolType::NONE )
    2426             :     {
    2427             :         pFS->singleElement( FSNS( XML_c, XML_symbol ),
    2428             :             XML_val, "none",
    2429           0 :             FSEND );
    2430             :     }
    2431           0 :     pFS->endElement( FSNS( XML_c, XML_marker ) );
    2432           0 : }
    2433             : 
    2434           0 : void ChartExport::exportSmooth()
    2435             : {
    2436           0 :     FSHelperPtr pFS = GetFS();
    2437           0 :     Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY );
    2438           0 :     sal_Int32 nSplineType = 0;
    2439           0 :     if( GetProperty( xPropSet, S( "SplineType" ) ) )
    2440           0 :         mAny >>= nSplineType;
    2441           0 :     if( nSplineType != 0 )
    2442             :     {
    2443             :         pFS->singleElement( FSNS( XML_c, XML_smooth ),
    2444             :             XML_val, "1",
    2445           0 :             FSEND );
    2446           0 :     }
    2447           0 : }
    2448             : 
    2449           0 : void ChartExport::exportFirstSliceAng( )
    2450             : {
    2451           0 :     FSHelperPtr pFS = GetFS();
    2452           0 :     sal_Int32 nStartingAngle = 0;
    2453           0 :     Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
    2454           0 :     if( GetProperty( xPropSet, S( "StartingAngle" ) ) )
    2455           0 :         mAny >>= nStartingAngle;
    2456             : 
    2457             :     // convert to ooxml angle
    2458           0 :     nStartingAngle = (450 - nStartingAngle ) % 360;
    2459             :     pFS->singleElement( FSNS( XML_c, XML_firstSliceAng ),
    2460             :             XML_val, I32S( nStartingAngle ),
    2461           0 :             FSEND );
    2462           0 : }
    2463             : 
    2464           0 : void ChartExport::exportView3D()
    2465             : {
    2466           0 :     Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
    2467           0 :     if( !xPropSet.is() )
    2468           0 :         return;
    2469           0 :     FSHelperPtr pFS = GetFS();
    2470             :     pFS->startElement( FSNS( XML_c, XML_view3D ),
    2471           0 :             FSEND );
    2472             :     // rotX
    2473           0 :     if( GetProperty( xPropSet, S( "RotationHorizontal" ) ) )
    2474             :     {
    2475           0 :         sal_Int32 nRotationX = 0;
    2476           0 :         mAny >>= nRotationX;
    2477             :         // X rotation (map Chart2 [-179,180] to OOXML [0..359])
    2478           0 :         if( nRotationX < 0 )
    2479           0 :             nRotationX += 360;
    2480             :         pFS->singleElement( FSNS( XML_c, XML_rotX ),
    2481             :             XML_val, I32S( nRotationX ),
    2482           0 :             FSEND );
    2483             :     }
    2484             :     // rotY
    2485           0 :     if( GetProperty( xPropSet, S( "RotationVertical" ) ) )
    2486             :     {
    2487           0 :         sal_Int32 nRotationY = 0;
    2488           0 :         mAny >>= nRotationY;
    2489             :         // Y rotation (map Chart2 [-179,180] to OOXML [0..359])
    2490           0 :         if( nRotationY < 0 )
    2491           0 :             nRotationY += 360;
    2492             :         pFS->singleElement( FSNS( XML_c, XML_rotY ),
    2493             :             XML_val, I32S( nRotationY ),
    2494           0 :             FSEND );
    2495             :     }
    2496             :     // perspective
    2497           0 :     if( GetProperty( xPropSet, S( "Perspective" ) ) )
    2498             :     {
    2499           0 :         sal_Int32 nPerspective = 0;
    2500           0 :         mAny >>= nPerspective;
    2501             :         // map Chart2 [0,100] to OOXML [0..200]
    2502           0 :         nPerspective *= 2;
    2503             :         pFS->singleElement( FSNS( XML_c, XML_perspective ),
    2504             :             XML_val, I32S( nPerspective ),
    2505           0 :             FSEND );
    2506             :     }
    2507             :     // rAngAx
    2508           0 :     if( GetProperty( xPropSet, S( "RightAngledAxes" ) ) )
    2509             :     {
    2510           0 :         sal_Bool bRightAngled = sal_False;
    2511           0 :         mAny >>= bRightAngled;
    2512           0 :         const char* sRightAngled = bRightAngled ? "1":"0";
    2513             :         pFS->singleElement( FSNS( XML_c, XML_rAngAx ),
    2514             :             XML_val, sRightAngled,
    2515           0 :             FSEND );
    2516             :     }
    2517           0 :     pFS->endElement( FSNS( XML_c, XML_view3D ) );
    2518             : }
    2519             : 
    2520           0 : sal_Bool ChartExport::isDeep3dChart()
    2521             : {
    2522           0 :     sal_Bool isDeep = sal_False;
    2523           0 :     if( mbIs3DChart )
    2524             :     {
    2525           0 :         Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
    2526           0 :         if( GetProperty( xPropSet, S( "Deep" ) ) )
    2527           0 :             mAny >>= isDeep;
    2528             :     }
    2529           0 :     return isDeep;
    2530             : }
    2531             : 
    2532             : }// drawingml
    2533         174 : }// oox
    2534             : 
    2535             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10