1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 
31 #include <xmloff/xmlprmap.hxx>
32 
33 #include "SchXMLExport.hxx"
34 #include "XMLChartPropertySetMapper.hxx"
35 #include "SchXMLSeriesHelper.hxx"
36 #include "ColorPropertySet.hxx"
37 #include "SchXMLTools.hxx"
38 #include "SchXMLEnumConverter.hxx"
39 
40 #include <tools/debug.hxx>
41 #include <rtl/logfile.hxx>
42 #include <comphelper/processfactory.hxx>
43 #include <tools/globname.hxx>
44 #include <sot/clsids.hxx>
45 
46 #include <xmloff/nmspmap.hxx>
47 #include "xmloff/xmlnmspe.hxx"
48 #include <xmloff/xmltoken.hxx>
49 #include <xmloff/families.hxx>
50 #include <xmloff/xmlaustp.hxx>
51 #include <xmloff/xmluconv.hxx>
52 #include <xmloff/xmlmetae.hxx>
53 #include "xexptran.hxx"
54 #include <rtl/math.hxx>
55 // header for any2enum
56 #include <comphelper/extract.hxx>
57 
58 #include <list>
59 #include <typeinfo>
60 #include <algorithm>
61 
62 #include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
63 #include <com/sun/star/lang/XServiceInfo.hpp>
64 #include <com/sun/star/lang/XServiceName.hpp>
65 #include <com/sun/star/beans/XPropertySet.hpp>
66 #include <com/sun/star/uno/XComponentContext.hpp>
67 #include <com/sun/star/util/XRefreshable.hpp>
68 
69 #include <com/sun/star/chart/XAxis.hpp>
70 #include <com/sun/star/chart/XAxisSupplier.hpp>
71 #include <com/sun/star/chart/XChartDocument.hpp>
72 #include <com/sun/star/chart/ChartLegendPosition.hpp>
73 #include <com/sun/star/chart/ChartLegendExpansion.hpp>
74 #include <com/sun/star/chart/ChartDataRowSource.hpp>
75 #include <com/sun/star/chart/ChartAxisAssign.hpp>
76 #include <com/sun/star/chart/ChartAxisType.hpp>
77 #include <com/sun/star/chart/TimeIncrement.hpp>
78 #include <com/sun/star/chart/TimeInterval.hpp>
79 #include <com/sun/star/chart/TimeUnit.hpp>
80 #include <com/sun/star/chart/ChartSeriesAddress.hpp>
81 #include <com/sun/star/chart/X3DDisplay.hpp>
82 #include <com/sun/star/chart/XStatisticDisplay.hpp>
83 #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
84 #include <com/sun/star/chart/XDiagramPositioning.hpp>
85 
86 #include <com/sun/star/chart2/XAnyDescriptionAccess.hpp>
87 #include <com/sun/star/chart2/AxisType.hpp>
88 #include <com/sun/star/chart2/XChartDocument.hpp>
89 #include <com/sun/star/chart2/XDiagram.hpp>
90 #include <com/sun/star/chart2/RelativePosition.hpp>
91 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
92 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
93 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
94 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
95 #include <com/sun/star/chart2/data/XDataSource.hpp>
96 #include <com/sun/star/chart2/data/XDataSink.hpp>
97 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
98 #include <com/sun/star/chart2/data/XDataProvider.hpp>
99 #include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
100 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
101 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
102 #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
103 
104 #include <com/sun/star/util/XStringMapping.hpp>
105 #include <com/sun/star/drawing/HomogenMatrix.hpp>
106 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
107 #include <com/sun/star/drawing/XShapes.hpp>
108 #include <com/sun/star/embed/Aspects.hpp>
109 #include <com/sun/star/embed/XVisualObject.hpp>
110 #include <com/sun/star/container/XChild.hpp>
111 
112 
113 #include "MultiPropertySetHandler.hxx"
114 #include "PropertyMap.hxx"
115 
116 using namespace com::sun::star;
117 using namespace ::xmloff::token;
118 
119 using ::rtl::OUString;
120 using ::rtl::OUStringBuffer;
121 using ::rtl::OUStringToOString;
122 using ::com::sun::star::uno::Sequence;
123 using ::com::sun::star::uno::Reference;
124 using ::com::sun::star::uno::Any;
125 using ::std::vector;
126 
127 // ========================================
128 // class SchXMLExportHelper_Impl
129 // ========================================
130 
131 class SchXMLExportHelper_Impl
132 {
133 public:
134     // first: data sequence for label, second: data sequence for values.
135     typedef ::std::pair< ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >,
136             ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence > > tLabelValuesDataPair;
137     typedef ::std::vector< tLabelValuesDataPair > tDataSequenceCont;
138 
139 public:
140 	SchXMLExportHelper_Impl( SvXMLExport& rExport,
141 						SvXMLAutoStylePoolP& rASPool );
142 
143     virtual ~SchXMLExportHelper_Impl();
144 
145     // auto-styles
146 	/// parse chart and collect all auto-styles used in current pool
147 	void collectAutoStyles( com::sun::star::uno::Reference<
148 							com::sun::star::chart::XChartDocument > rChartDoc );
149 
150     /// write the styles collected into the current pool as <style:style> elements
151 	void exportAutoStyles();
152 
153     /** export the <chart:chart> element corresponding to rChartDoc
154 		if bIncludeTable is true, the chart data is exported as <table:table>
155 		element (inside the chart element).
156 
157 		Otherwise the external references stored in the chart document are used
158 		for writing the corresponding attributes at series
159 
160 		All attributes contained in xAttrList are written at the chart element,
161 		which ist the outer element of a chart. So these attributes can easily
162 		be parsed again by the container
163 	 */
164 	void exportChart( com::sun::star::uno::Reference<
165 					  	com::sun::star::chart::XChartDocument > rChartDoc,
166 					  sal_Bool bIncludeTable );
167 
168     UniReference< XMLPropertySetMapper > GetPropertySetMapper() const;
169 
170     void SetChartRangeAddress( const ::rtl::OUString& rAddress )
171         { msChartAddress = rAddress; }
172     void SetTableNumberList( const ::rtl::OUString& rList )
173         { msTableNumberList = rList; }
174 
175     void InitRangeSegmentationProperties(
176         const ::com::sun::star::uno::Reference<
177             ::com::sun::star::chart2::XChartDocument > & xChartDoc );
178 
179     ::com::sun::star::awt::Size getPageSize(
180         const ::com::sun::star::uno::Reference<
181             ::com::sun::star::chart2::XChartDocument > & xChartDoc ) const;
182 
183     /** first parseDocument: collect autostyles and store names in this queue
184         second parseDocument: export content and use names from this queue
185      */
186     ::std::queue< ::rtl::OUString > maAutoStyleNameQueue;
187     void CollectAutoStyle(
188         const std::vector< XMLPropertyState >& aStates );
189     void AddAutoStyleAttribute(
190         const std::vector< XMLPropertyState >& aStates );
191 
192     SvXMLAutoStylePoolP& GetAutoStylePoolP()
193     { return mrAutoStylePool; }
194 
195 	/// if bExportContent is false the auto-styles are collected
196 	void parseDocument( com::sun::star::uno::Reference<
197 							com::sun::star::chart::XChartDocument >& rChartDoc,
198 						sal_Bool bExportContent,
199 						sal_Bool bIncludeTable = sal_False );
200 	void exportTable();
201 	void exportPlotArea(
202         com::sun::star::uno::Reference< com::sun::star::chart::XDiagram > xDiagram,
203         com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > xNewDiagram,
204         const ::com::sun::star::awt::Size & rPageSize,
205         sal_Bool bExportContent,
206         sal_Bool bIncludeTable );
207     void exportCoordinateRegion( const com::sun::star::uno::Reference< com::sun::star::chart::XDiagram >& xDiagram );
208 	void exportAxes( const com::sun::star::uno::Reference< com::sun::star::chart::XDiagram > & xDiagram,
209                                     const com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > & xNewDiagram,
210                                     sal_Bool bExportContent );
211     void exportAxis( enum XMLTokenEnum eDimension, enum XMLTokenEnum eAxisName,
212                     const Reference< beans::XPropertySet > xAxisProps, const Reference< chart2::XAxis >& xChart2Axis,
213                     const OUString& rCategoriesRanges,
214                     bool bHasTitle, bool bHasMajorGrid, bool bHasMinorGrid, bool bExportContent );
215     void exportGrid( const Reference< beans::XPropertySet > xGridProperties, bool bMajor, bool bExportContent );
216     void exportDateScale( const Reference< beans::XPropertySet > xAxisProps );
217     void exportAxisTitle( const Reference< beans::XPropertySet > xTitleProps, bool bExportContent );
218 
219 	void exportSeries(
220         const com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > & xNewDiagram,
221         const ::com::sun::star::awt::Size & rPageSize,
222         sal_Bool bExportContent,
223         sal_Bool bHasTwoYAxes );
224     void exportCandleStickSeries(
225         const ::com::sun::star::uno::Sequence<
226             ::com::sun::star::uno::Reference<
227                 ::com::sun::star::chart2::XDataSeries > > & aSeriesSeq,
228         const ::com::sun::star::uno::Reference<
229             ::com::sun::star::chart2::XDiagram > & xDiagram,
230         sal_Bool bJapaneseCandleSticks,
231         sal_Bool bExportContent );
232     void exportDataPoints(
233         const ::com::sun::star::uno::Reference<
234             ::com::sun::star::beans::XPropertySet > & xSeriesProperties,
235         sal_Int32 nSeriesLength,
236         const ::com::sun::star::uno::Reference<
237             ::com::sun::star::chart2::XDiagram > & xDiagram,
238         sal_Bool bExportContent );
239     void exportRegressionCurve(
240         const ::com::sun::star::uno::Reference<
241             ::com::sun::star::chart2::XDataSeries > & xSeries,
242         const ::com::sun::star::uno::Reference<
243             ::com::sun::star::beans::XPropertySet > & xSeriesProp,
244         const ::com::sun::star::awt::Size & rPageSize,
245         sal_Bool bExportContent );
246 
247 	/// add svg position as attribute for current element
248     void addPosition( const ::com::sun::star::awt::Point & rPosition );
249 	void addPosition( com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape );
250 	/// add svg size as attribute for current element
251     void addSize( const ::com::sun::star::awt::Size & rSize, bool bIsOOoNamespace = false );
252     void addSize( com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape, bool bIsOOoNamespace = false  );
253 	/// fills the member msString with the appropriate String (i.e. "A3")
254 	void getCellAddress( sal_Int32 nCol, sal_Int32 nRow );
255     /// exports a string as a paragraph element
256     void exportText( const ::rtl::OUString& rText, bool bConvertTabsLFs = false );
257     void exportErrorBarRanges();
258 
259     SchXMLExportHelper_Impl(SchXMLExportHelper_Impl &); // not defined
260     void operator =(SchXMLExportHelper_Impl &); // not defined
261 
262 public:
263 	SvXMLExport& mrExport;
264 	SvXMLAutoStylePoolP& mrAutoStylePool;
265 	UniReference< XMLPropertyHandlerFactory > mxPropertyHandlerFactory;
266 	UniReference< XMLPropertySetMapper > mxPropertySetMapper;
267 	UniReference< XMLChartExportPropertyMapper > mxExpPropMapper;
268 
269 	rtl::OUString msTableName;
270 	rtl::OUStringBuffer msStringBuffer;
271 	rtl::OUString msString;
272 
273     // members filled by InitRangeSegmentationProperties (retrieved from DataProvider)
274 	sal_Bool mbHasSeriesLabels;
275 	sal_Bool mbHasCategoryLabels; //if the categories are only automatically generated this will be false
276 	sal_Bool mbRowSourceColumns;
277 	rtl::OUString msChartAddress;
278 	rtl::OUString msTableNumberList;
279     ::com::sun::star::uno::Sequence< sal_Int32 > maSequenceMapping;
280 
281 	rtl::OUString msCLSID;
282 
283     ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > mxAdditionalShapes;
284 
285     tDataSequenceCont m_aDataSequencesToExport;
286     rtl::OUString maCategoriesRange;
287 };
288 
289 namespace
290 {
291 Reference< uno::XComponentContext > lcl_getComponentContext()
292 {
293     Reference< uno::XComponentContext > xContext;
294     try
295     {
296         Reference< beans::XPropertySet > xFactProp( comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
297         if( xFactProp.is())
298             xFactProp->getPropertyValue(OUString::createFromAscii("DefaultContext")) >>= xContext;
299     }
300     catch( uno::Exception& )
301     {}
302 
303     return xContext;
304 }
305 
306 class lcl_MatchesRole : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool >
307 {
308 public:
309     explicit lcl_MatchesRole( const OUString & aRole ) :
310             m_aRole( aRole )
311     {}
312 
313     bool operator () ( const Reference< chart2::data::XLabeledDataSequence > & xSeq ) const
314     {
315         if( !xSeq.is() )
316             return  false;
317         Reference< beans::XPropertySet > xProp( xSeq->getValues(), uno::UNO_QUERY );
318         OUString aRole;
319 
320         return ( xProp.is() &&
321                  (xProp->getPropertyValue(
322                      OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )) ) >>= aRole ) &&
323                  m_aRole.equals( aRole ));
324     }
325 
326 private:
327     OUString m_aRole;
328 };
329 
330 template< typename T >
331     void lcl_SequenceToVectorAppend( const Sequence< T > & rSource, ::std::vector< T > & rDestination )
332 {
333     rDestination.reserve( rDestination.size() + rSource.getLength());
334     ::std::copy( rSource.getConstArray(), rSource.getConstArray() + rSource.getLength(),
335                  ::std::back_inserter( rDestination ));
336 }
337 
338 template< typename T >
339     void lcl_SequenceToVector( const Sequence< T > & rSource, ::std::vector< T > & rDestination )
340 {
341     rDestination.clear();
342     lcl_SequenceToVectorAppend( rSource, rDestination );
343 }
344 
345 Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const Reference< chart2::XDiagram > & xDiagram )
346 {
347     Reference< chart2::data::XLabeledDataSequence >  xResult;
348     try
349     {
350         Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
351             xDiagram, uno::UNO_QUERY_THROW );
352         Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
353             xCooSysCnt->getCoordinateSystems());
354         for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
355         {
356             Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[i] );
357             OSL_ASSERT( xCooSys.is());
358             for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
359             {
360                 const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
361                 for(sal_Int32 nI=0; nI<=nMaxAxisIndex; ++nI)
362                 {
363                     Reference< chart2::XAxis > xAxis = xCooSys->getAxisByDimension( nN, nI );
364                     OSL_ASSERT( xAxis.is());
365                     if( xAxis.is())
366                     {
367                         chart2::ScaleData aScaleData = xAxis->getScaleData();
368                         if( aScaleData.Categories.is())
369                         {
370                             xResult.set( aScaleData.Categories );
371                             break;
372                         }
373                     }
374                 }
375             }
376         }
377     }
378     catch( uno::Exception & ex )
379     {
380         (void)ex; // avoid warning for pro build
381         OSL_ENSURE( false, OUStringToOString(
382                         OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
383                         OUString::createFromAscii( typeid( ex ).name()) +
384                         OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
385                         ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
386     }
387 
388     return xResult;
389 }
390 
391 Reference< chart2::data::XDataSource > lcl_createDataSource(
392     const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aData )
393 {
394     Reference< chart2::data::XDataSink > xSink;
395     Reference< uno::XComponentContext > xContext( lcl_getComponentContext());
396     if( xContext.is() )
397         xSink.set(
398             xContext->getServiceManager()->createInstanceWithContext(
399                 OUString::createFromAscii("com.sun.star.chart2.data.DataSource"),
400                 xContext ), uno::UNO_QUERY_THROW );
401     if( xSink.is())
402         xSink->setData( aData );
403 
404     return Reference< chart2::data::XDataSource >( xSink, uno::UNO_QUERY );
405 }
406 
407 Sequence< Reference< chart2::data::XLabeledDataSequence > > lcl_getAllSeriesSequences( const Reference< chart2::XChartDocument >& xChartDoc )
408 {
409     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aContainer;
410     if( xChartDoc.is() )
411     {
412         Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
413         ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( SchXMLSeriesHelper::getDataSeriesFromDiagram( xDiagram ));
414         for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aSeriesIt( aSeriesVector.begin() )
415             ; aSeriesIt != aSeriesVector.end(); ++aSeriesIt )
416         {
417             Reference< chart2::data::XDataSource > xDataSource( *aSeriesIt, uno::UNO_QUERY );
418             if( !xDataSource.is() )
419                 continue;
420             uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > aDataSequences( xDataSource->getDataSequences() );
421             lcl_SequenceToVectorAppend( aDataSequences, aContainer );
422         }
423     }
424 
425     Sequence< Reference< chart2::data::XLabeledDataSequence > > aRet( aContainer.size());
426     ::std::copy( aContainer.begin(), aContainer.end(), aRet.getArray());
427 
428     return aRet;
429 }
430 
431 Reference< chart2::data::XLabeledDataSequence >
432     lcl_getDataSequenceByRole(
433         const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aLabeledSeq,
434         const OUString & rRole )
435 {
436     Reference< chart2::data::XLabeledDataSequence > aNoResult;
437 
438     const Reference< chart2::data::XLabeledDataSequence > * pBegin = aLabeledSeq.getConstArray();
439     const Reference< chart2::data::XLabeledDataSequence > * pEnd = pBegin + aLabeledSeq.getLength();
440     const Reference< chart2::data::XLabeledDataSequence > * pMatch =
441         ::std::find_if( pBegin, pEnd, lcl_MatchesRole( rRole ));
442 
443     if( pMatch != pEnd )
444         return *pMatch;
445 
446     return aNoResult;
447 }
448 
449 Reference< chart2::data::XDataSource > lcl_pressUsedDataIntoRectangularFormat( const Reference< chart2::XChartDocument >& xChartDoc, sal_Bool& rOutSourceHasCategoryLabels )
450 {
451     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aLabeledSeqVector;
452 
453     //categories are always the first sequence
454     Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
455     Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xDiagram ) );
456     if( xCategories.is() )
457         aLabeledSeqVector.push_back( xCategories );
458     rOutSourceHasCategoryLabels = sal_Bool(xCategories.is());
459 
460     Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeriesSeqVector(
461             lcl_getAllSeriesSequences( xChartDoc ) );
462 
463     //the first x-values is always the next sequence //todo ... other x-values get lost for old format
464     Reference< chart2::data::XLabeledDataSequence > xXValues(
465         lcl_getDataSequenceByRole( aSeriesSeqVector, OUString::createFromAscii("values-x" ) ) );
466     if( xXValues.is() )
467         aLabeledSeqVector.push_back( xXValues );
468 
469     //add all other sequences now without x-values
470     lcl_MatchesRole aHasXValues( OUString::createFromAscii("values-x" ) );
471     for( sal_Int32 nN=0; nN<aSeriesSeqVector.getLength(); nN++ )
472     {
473         if( !aHasXValues( aSeriesSeqVector[nN] ) )
474             aLabeledSeqVector.push_back( aSeriesSeqVector[nN] );
475     }
476 
477     Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( aLabeledSeqVector.size() );
478     ::std::copy( aLabeledSeqVector.begin(), aLabeledSeqVector.end(), aSeq.getArray() );
479 
480     return lcl_createDataSource( aSeq );
481 }
482 
483 bool lcl_isSeriesAttachedToFirstAxis(
484     const Reference< chart2::XDataSeries > & xDataSeries )
485 {
486     bool bResult=true;
487 
488     try
489     {
490         sal_Int32 nAxisIndex = 0;
491         Reference< beans::XPropertySet > xProp( xDataSeries, uno::UNO_QUERY_THROW );
492         if( xProp.is() )
493             xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("AttachedAxisIndex") ) ) >>= nAxisIndex;
494         bResult = (0==nAxisIndex);
495     }
496     catch( uno::Exception & ex )
497     {
498         (void)ex; // avoid warning for pro build
499         OSL_ENSURE( false, OUStringToOString(
500                         OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
501                         OUString::createFromAscii( typeid( ex ).name()) +
502                         OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
503                         ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
504     }
505 
506     return bResult;
507 }
508 
509 OUString lcl_ConvertRange( const ::rtl::OUString & rRange, const Reference< chart2::XChartDocument > & xDoc )
510 {
511     OUString aResult = rRange;
512     if( !xDoc.is() )
513         return aResult;
514     Reference< chart2::data::XRangeXMLConversion > xConversion(
515         xDoc->getDataProvider(), uno::UNO_QUERY );
516     if( xConversion.is())
517         aResult = xConversion->convertRangeToXML( rRange );
518     return aResult;
519 }
520 
521 typedef ::std::pair< OUString, OUString > tLabelAndValueRange;
522 
523 tLabelAndValueRange lcl_getLabelAndValueRangeByRole(
524     const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aSeqCnt,
525     const OUString & rRole,
526     const Reference< chart2::XChartDocument > & xDoc,
527     SchXMLExportHelper_Impl::tDataSequenceCont & rOutSequencesToExport )
528 {
529     tLabelAndValueRange aResult;
530 
531     Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
532         lcl_getDataSequenceByRole( aSeqCnt, rRole ));
533     if( xLabeledSeq.is())
534     {
535         Reference< chart2::data::XDataSequence > xLabelSeq( xLabeledSeq->getLabel());
536         if( xLabelSeq.is())
537             aResult.first = lcl_ConvertRange( xLabelSeq->getSourceRangeRepresentation(), xDoc );
538 
539         Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues());
540         if( xValueSeq.is())
541             aResult.second = lcl_ConvertRange( xValueSeq->getSourceRangeRepresentation(), xDoc );
542 
543         if( xLabelSeq.is() || xValueSeq.is())
544             rOutSequencesToExport.push_back( SchXMLExportHelper_Impl::tLabelValuesDataPair( xLabelSeq, xValueSeq ));
545     }
546 
547     return aResult;
548 }
549 
550 sal_Int32 lcl_getSequenceLengthByRole(
551     const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aSeqCnt,
552     const OUString & rRole )
553 {
554     Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
555         lcl_getDataSequenceByRole( aSeqCnt, rRole ));
556     if( xLabeledSeq.is())
557     {
558         Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getValues());
559         return xSeq->getData().getLength();
560     }
561     return 0;
562 }
563 
564 bool lcl_hasChartType( const Reference< chart2::XDiagram > & xDiagram, const OUString & rChartType )
565 {
566     try
567     {
568         Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
569         Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
570         for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
571         {
572             Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
573             Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
574             for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
575             {
576                 if( aChartTypes[nCTIdx]->getChartType().equals( rChartType ))
577                     return true;
578             }
579         }
580     }
581     catch( uno::Exception & )
582     {
583         DBG_ERROR( "Exception while searching for chart type in diagram" );
584     }
585     return false;
586 }
587 
588 OUString lcl_flattenStringSequence( const Sequence< OUString > & rSequence )
589 {
590     OUStringBuffer aResult;
591     bool bPrecedeWithSpace = false;
592     for( sal_Int32 nIndex=0; nIndex<rSequence.getLength(); ++nIndex )
593     {
594         if( rSequence[nIndex].getLength())
595         {
596             if( bPrecedeWithSpace )
597                 aResult.append( static_cast< sal_Unicode >( ' ' ));
598             aResult.append( rSequence[nIndex] );
599             bPrecedeWithSpace = true;
600         }
601     }
602     return aResult.makeStringAndClear();
603 }
604 
605 void lcl_getLabelStringSequence( Sequence< OUString >& rOutLabels, const Reference< chart2::data::XDataSequence > & xLabelSeq )
606 {
607     uno::Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xLabelSeq, uno::UNO_QUERY );
608     if( xTextualDataSequence.is())
609     {
610         rOutLabels = xTextualDataSequence->getTextualData();
611     }
612     else if( xLabelSeq.is())
613     {
614         Sequence< uno::Any > aAnies( xLabelSeq->getData());
615         rOutLabels.realloc( aAnies.getLength());
616         for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
617             aAnies[i] >>= rOutLabels[i];
618     }
619 }
620 
621 sal_Int32 lcl_getMaxSequenceLength(
622     const SchXMLExportHelper_Impl::tDataSequenceCont & rContainer )
623 {
624     sal_Int32 nResult = 0;
625     for( SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator aIt( rContainer.begin());
626          aIt != rContainer.end(); ++aIt )
627     {
628         if( aIt->second.is())
629         {
630             sal_Int32 nSeqLength = aIt->second->getData().getLength();
631             if( nSeqLength > nResult )
632                 nResult = nSeqLength;
633         }
634     }
635     return nResult;
636 }
637 
638 uno::Sequence< rtl::OUString > lcl_DataSequenceToStringSequence(
639     const uno::Reference< chart2::data::XDataSequence >& xDataSequence )
640 {
641     uno::Sequence< rtl::OUString > aResult;
642     if(!xDataSequence.is())
643         return aResult;
644 
645     uno::Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xDataSequence, uno::UNO_QUERY );
646     if( xTextualDataSequence.is() )
647     {
648         aResult = xTextualDataSequence->getTextualData();
649     }
650     else
651     {
652         uno::Sequence< uno::Any > aValues = xDataSequence->getData();
653         aResult.realloc(aValues.getLength());
654 
655         for(sal_Int32 nN=aValues.getLength();nN--;)
656             aValues[nN] >>= aResult[nN];
657     }
658 
659     return aResult;
660 }
661 ::std::vector< double > lcl_getAllValuesFromSequence( const Reference< chart2::data::XDataSequence > & xSeq )
662 {
663     double fNan = 0.0;
664     ::rtl::math::setNan( &fNan );
665     ::std::vector< double > aResult;
666     if(!xSeq.is())
667         return aResult;
668 
669     uno::Sequence< double > aValuesSequence;
670     Reference< chart2::data::XNumericalDataSequence > xNumSeq( xSeq, uno::UNO_QUERY );
671     if( xNumSeq.is() )
672     {
673         aValuesSequence = xNumSeq->getNumericalData();
674     }
675     else
676     {
677         Sequence< uno::Any > aAnies( xSeq->getData() );
678         aValuesSequence.realloc( aAnies.getLength() );
679         for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
680             aAnies[i] >>= aValuesSequence[i];
681     }
682 
683     //special handling for x-values (if x-values do point to categories, indices are used instead )
684     Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY );
685     if( xProp.is() )
686     {
687         OUString aRole;
688         xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Role") ) ) >>= aRole;
689         if( aRole.match( OUString( RTL_CONSTASCII_USTRINGPARAM( "values-x") ) ) )
690         {
691             //lcl_clearIfNoValuesButTextIsContained - replace by indices if the values are not appropriate
692             bool bHasValue=false;
693             bool bHasText=false;
694             sal_Int32 nCount = aValuesSequence.getLength();
695             for( sal_Int32 j = 0; j < nCount; ++j )
696             {
697                 if( !::rtl::math::isNan( aValuesSequence[j] ) )
698                 {
699                     bHasValue=true;
700                     break;
701                 }
702             }
703             if(!bHasValue)
704             {
705                 //no double value is countained
706                 //is there any text?
707                 uno::Sequence< rtl::OUString > aStrings( lcl_DataSequenceToStringSequence( xSeq ) );
708                 sal_Int32 nTextCount = aStrings.getLength();
709                 for( sal_Int32 j = 0; j < nTextCount; ++j )
710                 {
711                     if( aStrings[j].getLength() )
712                     {
713                         bHasText=true;
714                         break;
715                     }
716                 }
717             }
718             if( !bHasValue && bHasText )
719             {
720                 for( sal_Int32 j = 0; j < nCount; ++j )
721                     aValuesSequence[j] = j+1;
722             }
723         }
724     }
725 
726     ::std::copy( aValuesSequence.getConstArray(), aValuesSequence.getConstArray() + aValuesSequence.getLength(),
727                      ::std::back_inserter( aResult ));
728     return aResult;
729 }
730 
731 bool lcl_SequenceHasUnhiddenData( const uno::Reference< chart2::data::XDataSequence >& xDataSequence )
732 {
733     if( !xDataSequence.is() )
734         return false;
735     uno::Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY );
736     if( xProp.is() )
737     {
738         uno::Sequence< sal_Int32 > aHiddenValues;
739         try
740         {
741             xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "HiddenValues" ) ) ) >>= aHiddenValues;
742             if( !aHiddenValues.getLength() )
743                 return true;
744         }
745         catch( uno::Exception& e )
746         {
747             (void)e; // avoid warning
748             return true;
749         }
750     }
751     if( xDataSequence->getData().getLength() )
752         return true;
753     return false;
754 }
755 
756 typedef vector< OUString > tStringVector;
757 typedef vector< double > tDoubleVector;
758 typedef vector< vector< OUString > > t2DStringVector;
759 typedef vector< vector< double > > t2DNumberContainer;
760 
761 struct lcl_TableData
762 {
763     t2DNumberContainer  aDataInRows;
764     tStringVector       aDataRangeRepresentations;
765 
766     tStringVector       aColumnDescriptions;
767     tStringVector       aColumnDescriptions_Ranges;
768 
769     tStringVector       aRowDescriptions;
770     tStringVector       aRowDescriptions_Ranges;
771 
772     Sequence< Sequence< uno::Any > >    aComplexColumnDescriptions;//outer index is columns - inner index is level
773     Sequence< Sequence< uno::Any > >    aComplexRowDescriptions;//outer index is rows - inner index is level
774 
775     ::std::vector< sal_Int32 > aHiddenColumns;
776 };
777 
778 // ::std::bind2nd( ::std::mem_fun_ref( &T::resize ), nSize ) does not work
779 template< class T >
780     struct lcl_resize
781     {
782         lcl_resize( typename T::size_type nSize, typename T::value_type fDefaultValue ) : m_nSize( nSize ), m_fDefaultValue( fDefaultValue ) {}
783         void operator()( T & t )
784         { t.resize( m_nSize, m_fDefaultValue ); }
785     private:
786         typename T::size_type m_nSize;
787         typename T::value_type m_fDefaultValue;
788     };
789 
790 
791 typedef ::std::map< sal_Int32, SchXMLExportHelper_Impl::tLabelValuesDataPair >
792     lcl_DataSequenceMap;
793 
794 struct lcl_SequenceToMapElement :
795     public ::std::unary_function< lcl_DataSequenceMap::mapped_type, lcl_DataSequenceMap::value_type >
796 {
797     lcl_SequenceToMapElement()
798     {}
799     result_type operator() ( const argument_type & rContent )
800     {
801         sal_Int32 nIndex = -1;
802         if( rContent.second.is()) //has values
803         {
804             OUString aRangeRep( rContent.second->getSourceRangeRepresentation());
805             nIndex = aRangeRep.toInt32();
806         }
807         else if( rContent.first.is()) //has labels
808             nIndex = rContent.first->getSourceRangeRepresentation().copy( sizeof("label ")).toInt32();
809         return result_type( nIndex, rContent );
810     }
811 };
812 
813 void lcl_ReorderInternalSequencesAccordingToTheirRangeName(
814     SchXMLExportHelper_Impl::tDataSequenceCont & rInOutSequences )
815 {
816     lcl_DataSequenceMap aIndexSequenceMap;
817     ::std::transform( rInOutSequences.begin(), rInOutSequences.end(),
818                       ::std::inserter( aIndexSequenceMap, aIndexSequenceMap.begin()),
819                       lcl_SequenceToMapElement());
820 
821     rInOutSequences.clear();
822     sal_Int32 nIndex = 0;
823     for( lcl_DataSequenceMap::const_iterator aIt = aIndexSequenceMap.begin();
824          aIt != aIndexSequenceMap.end(); ++aIt, ++nIndex )
825     {
826         if( aIt->first < 0 )
827             continue;
828         // fill empty columns
829         for( ; nIndex < aIt->first; ++nIndex )
830             rInOutSequences.push_back(
831                 SchXMLExportHelper_Impl::tDataSequenceCont::value_type( 0, 0 ));
832         OSL_ASSERT( nIndex == aIt->first );
833         rInOutSequences.push_back( aIt->second );
834     }
835 }
836 
837 
838 lcl_TableData lcl_getDataForLocalTable(
839     const SchXMLExportHelper_Impl::tDataSequenceCont & aSequencesToExport,
840     const Reference< chart2::XAnyDescriptionAccess >& xAnyDescriptionAccess,
841     const OUString& rCategoriesRange,
842     bool bSeriesFromColumns,
843     const Reference< chart2::data::XRangeXMLConversion > & xRangeConversion )
844 {
845     lcl_TableData aResult;
846 
847     try
848     {
849         Sequence< OUString > aSimpleCategories;
850         if( xAnyDescriptionAccess.is() )
851         {
852             //categories
853             if( bSeriesFromColumns )
854             {
855                 aSimpleCategories = xAnyDescriptionAccess->getRowDescriptions();
856                 aResult.aComplexRowDescriptions = xAnyDescriptionAccess->getAnyRowDescriptions();
857             }
858             else
859             {
860                 aSimpleCategories = xAnyDescriptionAccess->getColumnDescriptions();
861                 aResult.aComplexColumnDescriptions = xAnyDescriptionAccess->getAnyColumnDescriptions();
862             }
863         }
864 
865         //series values and series labels
866         SchXMLExportHelper_Impl::tDataSequenceCont::size_type nNumSequences = aSequencesToExport.size();
867         SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator aBegin( aSequencesToExport.begin());
868         SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator aEnd( aSequencesToExport.end());
869         SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator aIt( aBegin );
870 
871         size_t nMaxSequenceLength( lcl_getMaxSequenceLength( aSequencesToExport ));
872         size_t nCategoriesLength( aSimpleCategories.getLength() );
873         if( nCategoriesLength > nMaxSequenceLength )
874         {
875             aSimpleCategories.realloc(nMaxSequenceLength);//#i110617#
876             nCategoriesLength = nMaxSequenceLength;
877         }
878         size_t nNumColumns( bSeriesFromColumns ? nNumSequences : nMaxSequenceLength );
879         size_t nNumRows( bSeriesFromColumns ? nMaxSequenceLength : nNumSequences );
880 
881         // resize data
882         aResult.aDataInRows.resize( nNumRows );
883         double fNan = 0.0;
884         ::rtl::math::setNan( &fNan );
885         ::std::for_each( aResult.aDataInRows.begin(), aResult.aDataInRows.end(),
886                          lcl_resize< t2DNumberContainer::value_type >( nNumColumns, fNan ));
887         aResult.aColumnDescriptions.resize( nNumColumns );
888         aResult.aComplexColumnDescriptions.realloc( nNumColumns );
889         aResult.aRowDescriptions.resize( nNumRows );
890         aResult.aComplexRowDescriptions.realloc( nNumRows );
891 
892         tStringVector& rCategories = bSeriesFromColumns ? aResult.aRowDescriptions    : aResult.aColumnDescriptions;
893         tStringVector& rLabels     = bSeriesFromColumns ? aResult.aColumnDescriptions : aResult.aRowDescriptions;
894 
895         //categories
896         lcl_SequenceToVector( aSimpleCategories, rCategories );
897         if( rCategoriesRange.getLength() )
898         {
899             OUString aRange(rCategoriesRange);
900             if( xRangeConversion.is())
901                 aRange = xRangeConversion->convertRangeToXML( aRange );
902             if( bSeriesFromColumns )
903                 aResult.aRowDescriptions_Ranges.push_back( aRange );
904             else
905                 aResult.aColumnDescriptions_Ranges.push_back( aRange );
906         }
907 
908         // iterate over all sequences
909         size_t nSeqIdx = 0;
910         Sequence< Sequence< OUString > > aComplexLabels(nNumSequences);
911         for( ; aIt != aEnd; ++aIt, ++nSeqIdx )
912         {
913             OUString aRange;
914             Sequence< OUString >& rCurrentComplexLabel = aComplexLabels[nSeqIdx];
915             if( aIt->first.is())
916             {
917                 lcl_getLabelStringSequence( rCurrentComplexLabel, aIt->first );
918                 rLabels[nSeqIdx] = lcl_flattenStringSequence( rCurrentComplexLabel );
919                 aRange = aIt->first->getSourceRangeRepresentation();
920                 if( xRangeConversion.is())
921                     aRange = xRangeConversion->convertRangeToXML( aRange );
922             }
923             else if( aIt->second.is())
924             {
925                 rCurrentComplexLabel.realloc(1);
926                 rLabels[nSeqIdx] = rCurrentComplexLabel[0] = lcl_flattenStringSequence(
927                     aIt->second->generateLabel( chart2::data::LabelOrigin_SHORT_SIDE ));
928             }
929             if( bSeriesFromColumns )
930                 aResult.aColumnDescriptions_Ranges.push_back( aRange );
931             else
932                 aResult.aRowDescriptions_Ranges.push_back( aRange );
933 
934             ::std::vector< double > aNumbers( lcl_getAllValuesFromSequence( aIt->second ));
935             if( bSeriesFromColumns )
936             {
937                 const sal_Int32 nSize( static_cast< sal_Int32 >( aNumbers.size()));
938                 for( sal_Int32 nIdx=0; nIdx<nSize; ++nIdx )
939                     aResult.aDataInRows[nIdx][nSeqIdx] = aNumbers[nIdx];
940             }
941             else
942                 aResult.aDataInRows[nSeqIdx] = aNumbers;
943 
944             if( aIt->second.is())
945             {
946                 aRange =  aIt->second->getSourceRangeRepresentation();
947                 if( xRangeConversion.is())
948                     aRange = xRangeConversion->convertRangeToXML( aRange );
949             }
950             aResult.aDataRangeRepresentations.push_back( aRange );
951 
952             //is column hidden?
953             if( !lcl_SequenceHasUnhiddenData(aIt->first) && !lcl_SequenceHasUnhiddenData(aIt->second) )
954                 aResult.aHiddenColumns.push_back(nSeqIdx);
955         }
956         Sequence< Sequence< Any > >& rComplexAnyLabels = bSeriesFromColumns ? aResult.aComplexColumnDescriptions : aResult.aComplexRowDescriptions;//#i116544#
957         rComplexAnyLabels.realloc(aComplexLabels.getLength());
958         for( sal_Int32 nN=0; nN<aComplexLabels.getLength();nN++ )
959         {
960             Sequence< OUString >& rSource = aComplexLabels[nN];
961             Sequence< Any >& rTarget = rComplexAnyLabels[nN];
962             rTarget.realloc( rSource.getLength() );
963             for( sal_Int32 i=0; i<rSource.getLength(); i++ )
964                 rTarget[i] = uno::makeAny( rSource[i] );
965         }
966     }
967     catch( uno::Exception & rEx )
968     {
969         (void)rEx; // avoid warning for pro build
970         OSL_TRACE( OUStringToOString( OUString( RTL_CONSTASCII_USTRINGPARAM(
971                     "something went wrong during table data collection: " )) + rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
972     }
973 
974     return aResult;
975 }
976 
977 void lcl_exportNumberFormat( const OUString& rPropertyName, const Reference< beans::XPropertySet >& xPropSet,
978                                         SvXMLExport& rExport )
979 {
980     if( xPropSet.is())
981     {
982         sal_Int32 nNumberFormat = 0;
983         Any aNumAny = xPropSet->getPropertyValue( rPropertyName );
984         if( (aNumAny >>= nNumberFormat) && (nNumberFormat != -1) )
985             rExport.addDataStyle( nNumberFormat );
986     }
987 }
988 
989 ::std::vector< Reference< chart2::data::XDataSequence > >
990     lcl_getErrorBarSequences( const Reference< beans::XPropertySet > & xErrorBarProp )
991 {
992     ::std::vector< Reference< chart2::data::XDataSequence > > aResult;
993     Reference< chart2::data::XDataSource > xErrorBarDataSource( xErrorBarProp, uno::UNO_QUERY );
994     if( !xErrorBarDataSource.is())
995         return aResult;
996 
997     const OUString aRolePrefix( RTL_CONSTASCII_USTRINGPARAM( "error-bars-" ));
998 //     const OUString aXRolePrefix( aRolePrefix + OUString( RTL_CONSTASCII_USTRINGPARAM( "x-" )));
999 //     const OUString aYRolePrefix( aRolePrefix + OUString( RTL_CONSTASCII_USTRINGPARAM( "y-" )));
1000 //     const OUString aPositivePostfix( RTL_CONSTASCII_USTRINGPARAM( "positive" ));
1001 //     const OUString aNegativePostfix( RTL_CONSTASCII_USTRINGPARAM( "negative" ));
1002 
1003     Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences(
1004         xErrorBarDataSource->getDataSequences());
1005     for( sal_Int32 nI=0; nI< aSequences.getLength(); ++nI )
1006     {
1007         try
1008         {
1009             if( aSequences[nI].is())
1010             {
1011                 Reference< chart2::data::XDataSequence > xSequence( aSequences[nI]->getValues());
1012                 Reference< beans::XPropertySet > xSeqProp( xSequence, uno::UNO_QUERY_THROW );
1013                 OUString aRole;
1014                 if( ( xSeqProp->getPropertyValue(
1015                           OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" ))) >>= aRole ) &&
1016                     aRole.match( aRolePrefix ))
1017                 {
1018                     aResult.push_back( xSequence );
1019                 }
1020             }
1021         }
1022         catch( uno::Exception & rEx )
1023         {
1024 #ifdef DBG_UTIL
1025             String aStr( rEx.Message );
1026             ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US );
1027             DBG_ERROR1( "chart:exporting error bar ranges: %s", aBStr.GetBuffer());
1028 #else
1029             (void)rEx; // avoid warning
1030 #endif
1031         }
1032     }
1033 
1034     return aResult;
1035 }
1036 
1037 bool lcl_exportDomainForThisSequence( const Reference< chart2::data::XDataSequence > xValues, rtl::OUString& rFirstRangeForThisDomainIndex, SvXMLExport& rExport )
1038 {
1039     bool bDomainExported = false;
1040     if( xValues.is())
1041     {
1042         Reference< chart2::XChartDocument > xNewDoc( rExport.GetModel(), uno::UNO_QUERY );
1043         OUString aRange( lcl_ConvertRange( xValues->getSourceRangeRepresentation(), xNewDoc ) );
1044 
1045         //work around error in OOo 2.0 (problems with multiple series having a domain element)
1046         if( !rFirstRangeForThisDomainIndex.getLength() || !aRange.equals(rFirstRangeForThisDomainIndex) )
1047         {
1048             rExport.AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, aRange);
1049             SvXMLElementExport aDomain( rExport, XML_NAMESPACE_CHART, XML_DOMAIN, sal_True, sal_True );
1050             bDomainExported = true;
1051         }
1052 
1053         if( !rFirstRangeForThisDomainIndex.getLength() )
1054             rFirstRangeForThisDomainIndex = aRange;
1055     }
1056     return bDomainExported;
1057 }
1058 
1059 } // anonymous namespace
1060 
1061 struct SchXMLDataPointStruct
1062 {
1063     OUString   maStyleName;
1064     sal_Int32  mnRepeat;
1065 
1066     SchXMLDataPointStruct() : mnRepeat( 1 ) {}
1067 };
1068 
1069 // ========================================
1070 // class SchXMLExportHelper
1071 // ========================================
1072 
1073 SchXMLExportHelper::SchXMLExportHelper(	SvXMLExport& rExport, SvXMLAutoStylePoolP& rASPool )
1074     : m_pImpl( new SchXMLExportHelper_Impl( rExport, rASPool ) )
1075 {
1076 }
1077 
1078 SchXMLExportHelper::~SchXMLExportHelper()
1079 {
1080     delete m_pImpl;
1081 }
1082 
1083 const OUString& SchXMLExportHelper::getChartCLSID()
1084 {
1085 	return m_pImpl->msCLSID;
1086 }
1087 
1088 UniReference< XMLPropertySetMapper > SchXMLExportHelper_Impl::GetPropertySetMapper() const
1089 {
1090     return mxPropertySetMapper;
1091 }
1092 
1093 void SchXMLExportHelper_Impl::exportAutoStyles()
1094 {
1095 	if( mxExpPropMapper.is())
1096 	{
1097 		//ToDo: when embedded in calc/writer this is not necessary because the
1098 		// numberformatter is shared between both documents
1099 		mrExport.exportAutoDataStyles();
1100 
1101 		// export chart auto styles
1102 		mrAutoStylePool.exportXML(
1103 			XML_STYLE_FAMILY_SCH_CHART_ID
1104 			, mrExport.GetDocHandler(),
1105 			mrExport.GetMM100UnitConverter(),
1106 			mrExport.GetNamespaceMap()
1107             );
1108 
1109         // export auto styles for additional shapes
1110         mrExport.GetShapeExport()->exportAutoStyles();
1111         // and for text in additional shapes
1112         mrExport.GetTextParagraphExport()->exportTextAutoStyles();
1113 	}
1114 }
1115 
1116 // private methods
1117 // ---------------
1118 
1119 SchXMLExportHelper_Impl::SchXMLExportHelper_Impl(
1120 	SvXMLExport& rExport,
1121 	SvXMLAutoStylePoolP& rASPool ) :
1122 		mrExport( rExport ),
1123 		mrAutoStylePool( rASPool ),
1124 		mbHasSeriesLabels( sal_False ),
1125 		mbHasCategoryLabels( sal_False ),
1126 		mbRowSourceColumns( sal_True )
1127 		// #110680#
1128 		// this id depends on the ServiceManager used due to the binary filter stripping.
1129 		// ,msCLSID( rtl::OUString( SvGlobalName( SO3_SCH_CLASSID ).GetHexName()))
1130 {
1131 	// #110680#
1132 	// changed initialisation for msCLSID. Compare the ServiceInfo name with
1133 	// the known name of the LegacyServiceManager.
1134 	Reference<lang::XServiceInfo> xServiceInfo( mrExport.getServiceFactory(), uno::UNO_QUERY );
1135 	DBG_ASSERT( xServiceInfo.is(), "XMultiServiceFactory without xServiceInfo (!)" );
1136 	OUString rdbURL = xServiceInfo->getImplementationName();
1137 	OUString implLegacyServiceManagerName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.office.LegacyServiceManager" ) );
1138 
1139 	if( rdbURL.equals( implLegacyServiceManagerName ))
1140 	{
1141 		msCLSID = OUString( SvGlobalName( BF_SO3_SCH_CLASSID ).GetHexName());
1142 	}
1143 	else
1144 	{
1145 		msCLSID = OUString( SvGlobalName( SO3_SCH_CLASSID ).GetHexName());
1146 	}
1147 
1148 	msTableName = OUString::createFromAscii( "local-table" );
1149 
1150 	// create factory
1151 	mxPropertyHandlerFactory = new XMLChartPropHdlFactory;
1152 
1153 	if( mxPropertyHandlerFactory.is() )
1154 	{
1155 		// create property set mapper
1156 		mxPropertySetMapper = new XMLChartPropertySetMapper;
1157 	}
1158 
1159 	mxExpPropMapper = new XMLChartExportPropertyMapper( mxPropertySetMapper, rExport );
1160 
1161 	// register chart auto-style family
1162 	mrAutoStylePool.AddFamily(
1163 		XML_STYLE_FAMILY_SCH_CHART_ID,
1164 		OUString::createFromAscii( XML_STYLE_FAMILY_SCH_CHART_NAME ),
1165 		mxExpPropMapper.get(),
1166 		OUString::createFromAscii( XML_STYLE_FAMILY_SCH_CHART_PREFIX ));
1167 
1168     // register shape family
1169 	mrAutoStylePool.AddFamily(
1170 		XML_STYLE_FAMILY_SD_GRAPHICS_ID,
1171 		OUString::createFromAscii( XML_STYLE_FAMILY_SD_GRAPHICS_NAME ),
1172 		mxExpPropMapper.get(),
1173 		OUString::createFromAscii( XML_STYLE_FAMILY_SD_GRAPHICS_PREFIX ));
1174     // register paragraph family also for shapes
1175 	mrAutoStylePool.AddFamily(
1176 		XML_STYLE_FAMILY_TEXT_PARAGRAPH,
1177         GetXMLToken( XML_PARAGRAPH ),
1178 		mxExpPropMapper.get(),
1179         String( 'P' ));
1180     // register text family also for shapes
1181 	mrAutoStylePool.AddFamily(
1182         XML_STYLE_FAMILY_TEXT_TEXT,
1183         GetXMLToken( XML_TEXT ),
1184 		mxExpPropMapper.get(),
1185         String( 'T' ));
1186 }
1187 
1188 SchXMLExportHelper_Impl::~SchXMLExportHelper_Impl()
1189 {
1190 }
1191 
1192 void SchXMLExportHelper_Impl::collectAutoStyles( Reference< chart::XChartDocument > rChartDoc )
1193 {
1194     parseDocument( rChartDoc, sal_False );
1195 }
1196 
1197 void SchXMLExportHelper_Impl::exportChart( Reference< chart::XChartDocument > rChartDoc,
1198 									  sal_Bool bIncludeTable )
1199 {
1200     parseDocument( rChartDoc, sal_True, bIncludeTable );
1201     DBG_ASSERT( maAutoStyleNameQueue.empty(), "There are still remaining autostyle names in the queue" );
1202 }
1203 
1204 ::rtl::OUString lcl_GetStringFromNumberSequence( const ::com::sun::star::uno::Sequence< sal_Int32 >& rSequenceMapping, bool bRemoveOneFromEachIndex /*should be true if having categories*/ )
1205 {
1206     const sal_Int32* pArray = rSequenceMapping.getConstArray();
1207     const sal_Int32 nSize = rSequenceMapping.getLength();
1208     sal_Int32 i = 0;
1209     OUStringBuffer aBuf;
1210     bool bHasPredecessor = false;
1211     for( i = 0; i < nSize; ++i )
1212     {
1213         sal_Int32 nIndex = pArray[ i ];
1214         if( bRemoveOneFromEachIndex )
1215             --nIndex;
1216         if(nIndex>=0)
1217         {
1218             if(bHasPredecessor)
1219                 aBuf.append( static_cast< sal_Unicode >( ' ' ));
1220             aBuf.append( nIndex, 10 );
1221             bHasPredecessor = true;
1222         }
1223     }
1224     return aBuf.makeStringAndClear();
1225 }
1226 
1227 /// if bExportContent is false the auto-styles are collected
1228 void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument >& rChartDoc,
1229 										sal_Bool bExportContent,
1230 										sal_Bool bIncludeTable )
1231 {
1232     Reference< chart2::XChartDocument > xNewDoc( rChartDoc, uno::UNO_QUERY );
1233     if( !rChartDoc.is() || !xNewDoc.is() )
1234 	{
1235 		DBG_ERROR( "No XChartDocument was given for export." );
1236 		return;
1237 	}
1238 
1239     awt::Size aPageSize( getPageSize( xNewDoc ));
1240     if( bExportContent )
1241         addSize( aPageSize );
1242     Reference< chart::XDiagram > xDiagram = rChartDoc->getDiagram();
1243     Reference< chart2::XDiagram > xNewDiagram;
1244     if( xNewDoc.is())
1245         xNewDiagram.set( xNewDoc->getFirstDiagram());
1246 
1247     //todo remove if model changes are notified and view is updated automatically
1248     if( bExportContent )
1249     {
1250         Reference< util::XRefreshable > xRefreshable( xNewDoc, uno::UNO_QUERY );
1251         if( xRefreshable.is() )
1252             xRefreshable->refresh();
1253     }
1254 
1255 	// get Properties of ChartDocument
1256 	sal_Bool bHasMainTitle = sal_False;
1257 	sal_Bool bHasSubTitle = sal_False;
1258 	sal_Bool bHasLegend = sal_False;
1259     util::DateTime aNullDate(0,0,0,0,30,12,1899);
1260 
1261     std::vector< XMLPropertyState > aPropertyStates;
1262 
1263 	Reference< beans::XPropertySet > xDocPropSet( rChartDoc, uno::UNO_QUERY );
1264 	if( xDocPropSet.is())
1265 	{
1266 		try
1267 		{
1268 			Any aAny( xDocPropSet->getPropertyValue(
1269 				OUString( RTL_CONSTASCII_USTRINGPARAM( "HasMainTitle" ))));
1270 			aAny >>= bHasMainTitle;
1271 			aAny = xDocPropSet->getPropertyValue(
1272 				OUString( RTL_CONSTASCII_USTRINGPARAM( "HasSubTitle" )));
1273 			aAny >>= bHasSubTitle;
1274 			aAny = xDocPropSet->getPropertyValue(
1275 				OUString( RTL_CONSTASCII_USTRINGPARAM( "HasLegend" )));
1276 			aAny >>= bHasLegend;
1277             if ( bIncludeTable )
1278             {
1279                 OUString sNullDate( RTL_CONSTASCII_USTRINGPARAM( "NullDate" ));
1280                 aAny = xDocPropSet->getPropertyValue(sNullDate);
1281                 if ( !aAny.hasValue() )
1282                 {
1283                     Reference<container::XChild> xChild(rChartDoc, uno::UNO_QUERY );
1284                     if ( xChild.is() )
1285                     {
1286                         Reference< beans::XPropertySet > xParentDoc( xChild->getParent(),uno::UNO_QUERY);
1287                         if ( xParentDoc.is() && xParentDoc->getPropertySetInfo()->hasPropertyByName(sNullDate) )
1288                             aAny = xParentDoc->getPropertyValue(sNullDate);
1289                     }
1290                 }
1291 
1292                 aAny >>= aNullDate;
1293             }
1294 		}
1295 		catch( beans::UnknownPropertyException & )
1296 		{
1297 			DBG_WARNING( "Required property not found in ChartDocument" );
1298 		}
1299 	} // if( xDocPropSet.is())
1300 
1301     if ( bIncludeTable && (aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899 ) )
1302     {
1303         SvXMLElementExport aSet( mrExport, XML_NAMESPACE_TABLE, XML_CALCULATION_SETTINGS, sal_True, sal_True );
1304         {
1305             ::rtl::OUStringBuffer sBuffer;
1306             SvXMLUnitConverter::convertDateTime(sBuffer,aNullDate);
1307             mrExport.AddAttribute( XML_NAMESPACE_TABLE,XML_DATE_VALUE,sBuffer.makeStringAndClear());
1308             SvXMLElementExport aNull( mrExport, XML_NAMESPACE_TABLE, XML_NULL_DATE, sal_True, sal_True );
1309         }
1310     }
1311 
1312 	// chart element
1313 	// -------------
1314 
1315 	SvXMLElementExport* pElChart = 0;
1316 	// get property states for autostyles
1317 	if( mxExpPropMapper.is())
1318 	{
1319 		Reference< beans::XPropertySet > xPropSet( rChartDoc->getArea(), uno::UNO_QUERY );
1320 		if( xPropSet.is())
1321 			aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1322 	}
1323 
1324 	if( bExportContent )
1325 	{
1326         //export data provider in xlink:href attribute
1327         const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
1328         if( nCurrentODFVersion >= SvtSaveOptions::ODFVER_012 )
1329         {
1330             OUString aDataProviderURL( RTL_CONSTASCII_USTRINGPARAM( ".." ) );
1331             if( xNewDoc->hasInternalDataProvider() )
1332                 aDataProviderURL = OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) );
1333             else //special handling for data base data provider necessary
1334             {
1335                 Reference< chart2::data::XDatabaseDataProvider > xDBDataProvider( xNewDoc->getDataProvider(), uno::UNO_QUERY );
1336                 if( xDBDataProvider.is() )
1337                     aDataProviderURL = OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) );
1338             }
1339             mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, aDataProviderURL );
1340             mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
1341         }
1342 
1343         OUString sChartType( xDiagram->getDiagramType() );
1344 
1345 		// attributes
1346 		// determine class
1347 		if( sChartType.getLength())
1348 		{
1349 			enum XMLTokenEnum eXMLChartType = SchXMLTools::getTokenByChartType( sChartType, true /* bUseOldNames */ );
1350 
1351             DBG_ASSERT( eXMLChartType != XML_TOKEN_INVALID, "invalid chart class" );
1352             if( eXMLChartType == XML_TOKEN_INVALID )
1353                 eXMLChartType = XML_BAR;
1354 
1355             if( eXMLChartType == XML_ADD_IN )
1356             {
1357                 // sChartType is the servie-name of the add-in
1358 				mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS,
1359                                        mrExport.GetNamespaceMap().GetQNameByKey(
1360                                            XML_NAMESPACE_OOO, sChartType) );
1361 			}
1362             else if( eXMLChartType != XML_TOKEN_INVALID )
1363 			{
1364 				mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS,
1365 						mrExport.GetNamespaceMap().GetQNameByKey(
1366 							XML_NAMESPACE_CHART, GetXMLToken(eXMLChartType )) );
1367 			}
1368 
1369             //column-mapping or row-mapping
1370             if( maSequenceMapping.getLength() )
1371             {
1372                 enum XMLTokenEnum eTransToken = ::xmloff::token::XML_ROW_MAPPING;
1373                 if( mbRowSourceColumns )
1374                     eTransToken = ::xmloff::token::XML_COLUMN_MAPPING;
1375                 ::rtl::OUString aSequenceMappingStr( lcl_GetStringFromNumberSequence(
1376                     maSequenceMapping, mbHasCategoryLabels && !xNewDoc->hasInternalDataProvider() ) );
1377 
1378                 mrExport.AddAttribute( XML_NAMESPACE_CHART,
1379                                         ::xmloff::token::GetXMLToken( eTransToken ),
1380                                         aSequenceMappingStr );
1381             }
1382         }
1383 		// write style name
1384         AddAutoStyleAttribute( aPropertyStates );
1385 
1386 		//element
1387 		pElChart = new SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_CHART, sal_True, sal_True );
1388 	}
1389 	else	// autostyles
1390 	{
1391         CollectAutoStyle( aPropertyStates );
1392 	}
1393 	// remove property states for autostyles
1394 	aPropertyStates.clear();
1395 
1396 	// title element
1397 	// -------------
1398 
1399 	if( bHasMainTitle )
1400 	{
1401 		// get property states for autostyles
1402 		if( mxExpPropMapper.is())
1403 		{
1404 			Reference< beans::XPropertySet > xPropSet( rChartDoc->getTitle(), uno::UNO_QUERY );
1405 			if( xPropSet.is())
1406 				aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1407 		}
1408 		if( bExportContent )
1409 		{
1410 			Reference< drawing::XShape > xShape = rChartDoc->getTitle();
1411 			if( xShape.is())	// && "hasTitleBeenMoved"
1412 				addPosition( xShape );
1413 
1414 			// write style name
1415             AddAutoStyleAttribute( aPropertyStates );
1416 
1417 			// element
1418 			SvXMLElementExport aElTitle( mrExport, XML_NAMESPACE_CHART, XML_TITLE, sal_True, sal_True );
1419 
1420 			// content (text:p)
1421 			Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
1422 			if( xPropSet.is())
1423 			{
1424 				Any aAny( xPropSet->getPropertyValue(
1425 					OUString( RTL_CONSTASCII_USTRINGPARAM( "String" ))));
1426 				OUString aText;
1427 				aAny >>= aText;
1428                 exportText( aText );
1429 			}
1430 		}
1431 		else	// autostyles
1432 		{
1433             CollectAutoStyle( aPropertyStates );
1434 		}
1435 		// remove property states for autostyles
1436 		aPropertyStates.clear();
1437 	}
1438 
1439 	// subtitle element
1440 	// ----------------
1441 
1442 	if( bHasSubTitle )
1443 	{
1444 		// get property states for autostyles
1445 		if( mxExpPropMapper.is())
1446 		{
1447 			Reference< beans::XPropertySet > xPropSet( rChartDoc->getSubTitle(), uno::UNO_QUERY );
1448 			if( xPropSet.is())
1449 				aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1450 		}
1451 
1452 		if( bExportContent )
1453 		{
1454 			Reference< drawing::XShape > xShape = rChartDoc->getSubTitle();
1455 			if( xShape.is())
1456 				addPosition( xShape );
1457 
1458 			// write style name
1459             AddAutoStyleAttribute( aPropertyStates );
1460 
1461 			// element (has no subelements)
1462 			SvXMLElementExport aElSubTitle( mrExport, XML_NAMESPACE_CHART, XML_SUBTITLE, sal_True, sal_True );
1463 
1464 			// content (text:p)
1465 			Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
1466 			if( xPropSet.is())
1467 			{
1468 				Any aAny( xPropSet->getPropertyValue(
1469 					OUString( RTL_CONSTASCII_USTRINGPARAM( "String" ))));
1470 				OUString aText;
1471 				aAny >>= aText;
1472                 exportText( aText );
1473 			}
1474 		}
1475 		else	// autostyles
1476 		{
1477             CollectAutoStyle( aPropertyStates );
1478 		}
1479 		// remove property states for autostyles
1480 		aPropertyStates.clear();
1481 	}
1482 
1483 	// legend element
1484 	// --------------
1485 	if( bHasLegend )
1486 	{
1487 		// get property states for autostyles
1488 		if( mxExpPropMapper.is())
1489 		{
1490 			Reference< beans::XPropertySet > xPropSet( rChartDoc->getLegend(), uno::UNO_QUERY );
1491 			if( xPropSet.is())
1492 				aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1493 		}
1494 
1495 		if( bExportContent )
1496 		{
1497 			Reference< beans::XPropertySet > xProp( rChartDoc->getLegend(), uno::UNO_QUERY );
1498 			if( xProp.is())
1499 			{
1500                 // export legend anchor position
1501                 try
1502 				{
1503 					Any aAny( xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Alignment" ))));
1504                     if( SchXMLEnumConverter::getLegendPositionConverter().exportXML( msString, aAny, mrExport.GetMM100UnitConverter() ) )
1505                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_LEGEND_POSITION, msString );
1506 				}
1507 				catch( beans::UnknownPropertyException & )
1508 				{
1509 					DBG_WARNING( "Property Align not found in ChartLegend" );
1510 				}
1511 
1512 				// export absolute legend position
1513 				Reference< drawing::XShape > xLegendShape( xProp, uno::UNO_QUERY );
1514 				addPosition( xLegendShape );
1515 
1516 				// export legend size
1517                 const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
1518                 if( xLegendShape.is() && nCurrentODFVersion >= SvtSaveOptions::ODFVER_012 && nCurrentODFVersion == SvtSaveOptions::ODFVER_LATEST )//do not export legend-expansion to ODF 1.0 and export size only if extensions are enabled //#i28670# todo: change this dependent on fileformat evolution
1519                 {
1520                     try
1521 				    {
1522                         chart::ChartLegendExpansion nLegendExpansion = chart::ChartLegendExpansion_HIGH;
1523                         OUString aExpansionString;
1524 					    Any aAny( xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Expansion" ))));
1525 					    bool bHasExpansion = (aAny >>= nLegendExpansion);
1526                         if( bHasExpansion && SchXMLEnumConverter::getLegendExpansionConverter().exportXML( aExpansionString, aAny, mrExport.GetMM100UnitConverter() ) )
1527                         {
1528                             mrExport.AddAttribute( XML_NAMESPACE_STYLE, XML_LEGEND_EXPANSION, aExpansionString );
1529                             if( nLegendExpansion == chart::ChartLegendExpansion_CUSTOM)
1530                             {
1531                                 awt::Size aSize( xLegendShape->getSize() );
1532                                 addSize( aSize, true );
1533                                 rtl::OUStringBuffer aAspectRatioString;
1534                                 SvXMLUnitConverter::convertDouble(aAspectRatioString, double(aSize.Width)/double(aSize.Height));
1535                                 mrExport.AddAttribute( XML_NAMESPACE_STYLE, XML_LEGEND_EXPANSION_ASPECT_RATIO, aAspectRatioString.makeStringAndClear() );
1536                             }
1537                         }
1538 				    }
1539 				    catch( beans::UnknownPropertyException & )
1540 				    {
1541 					    DBG_WARNING( "Property Expansion not found in ChartLegend" );
1542 				    }
1543                 }
1544 			}
1545 
1546 			// write style name
1547             AddAutoStyleAttribute( aPropertyStates );
1548 
1549 			// element
1550 			SvXMLElementExport aLegend( mrExport, XML_NAMESPACE_CHART, XML_LEGEND, sal_True, sal_True );
1551 		}
1552 		else	// autostyles
1553 		{
1554             CollectAutoStyle( aPropertyStates );
1555 		}
1556 		// remove property states for autostyles
1557 		aPropertyStates.clear();
1558 	}
1559 
1560 	// plot-area element
1561 	// -----------------
1562 	if( xDiagram.is())
1563 		exportPlotArea( xDiagram, xNewDiagram, aPageSize, bExportContent, bIncludeTable );
1564 
1565     // export additional shapes
1566     // ------------------------
1567     if( xDocPropSet.is() )
1568     {
1569         if( bExportContent )
1570         {
1571             if( mxAdditionalShapes.is())
1572             {
1573                 // can't call exportShapes with all shapes because the
1574                 // initialisation happend with the complete draw page and not
1575                 // the XShapes object used here. Thus the shapes have to be
1576                 // exported one by one
1577                 UniReference< XMLShapeExport > rShapeExport = mrExport.GetShapeExport();
1578                 Reference< drawing::XShape > xShape;
1579                 const sal_Int32 nShapeCount( mxAdditionalShapes->getCount());
1580                 for( sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++ )
1581                 {
1582                     mxAdditionalShapes->getByIndex( nShapeId ) >>= xShape;
1583                     DBG_ASSERT( xShape.is(), "Shape without an XShape?" );
1584                     if( ! xShape.is())
1585                         continue;
1586 
1587                     rShapeExport->exportShape( xShape );
1588                 }
1589                 // this would be the easier way if it worked:
1590                 //mrExport.GetShapeExport()->exportShapes( mxAdditionalShapes );
1591             }
1592         }
1593         else
1594         {
1595             // get a sequence of non-chart shapes (inserted via clipboard)
1596             try
1597             {
1598                 Any aShapesAny = xDocPropSet->getPropertyValue( OUString::createFromAscii( "AdditionalShapes" ));
1599                 aShapesAny >>= mxAdditionalShapes;
1600             }
1601             catch( uno::Exception & rEx )
1602 		    {
1603                 (void)rEx; // avoid warning for pro build
1604                 OSL_TRACE(
1605                     OUStringToOString(
1606                         OUString( RTL_CONSTASCII_USTRINGPARAM(
1607                             "AdditionalShapes not found: " )) +
1608                         rEx.Message,
1609                         RTL_TEXTENCODING_ASCII_US ).getStr());
1610 		    }
1611 
1612             if( mxAdditionalShapes.is())
1613             {
1614                 // seek shapes has to be called for the whole page because in
1615                 // the shape export the vector of shapes is accessed via the
1616                 // ZOrder which might be (actually is) larger than the number of
1617                 // shapes in mxAdditionalShapes
1618                 Reference< drawing::XDrawPageSupplier > xSupplier( rChartDoc, uno::UNO_QUERY );
1619                 DBG_ASSERT( xSupplier.is(), "Cannot retrieve draw page to initialize shape export" );
1620                 if( xSupplier.is() )
1621                 {
1622                     Reference< drawing::XShapes > xDrawPage( xSupplier->getDrawPage(), uno::UNO_QUERY );
1623                     DBG_ASSERT( xDrawPage.is(), "Invalid draw page for initializing shape export" );
1624                     if( xDrawPage.is())
1625                         mrExport.GetShapeExport()->seekShapes( xDrawPage );
1626                 }
1627 
1628                 // can't call collectShapesAutoStyles with all shapes because
1629                 // the initialisation happend with the complete draw page and
1630                 // not the XShapes object used here. Thus the shapes have to be
1631                 // exported one by one
1632                 UniReference< XMLShapeExport > rShapeExport = mrExport.GetShapeExport();
1633                 Reference< drawing::XShape > xShape;
1634                 const sal_Int32 nShapeCount( mxAdditionalShapes->getCount());
1635                 for( sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++ )
1636                 {
1637                     mxAdditionalShapes->getByIndex( nShapeId ) >>= xShape;
1638                     DBG_ASSERT( xShape.is(), "Shape without an XShape?" );
1639                     if( ! xShape.is())
1640                         continue;
1641 
1642                     rShapeExport->collectShapeAutoStyles( xShape );
1643                 }
1644                 // this would be the easier way if it worked:
1645                 // mrExport.GetShapeExport()->collectShapesAutoStyles( mxAdditionalShapes );
1646             }
1647         }
1648     }
1649 
1650 	// table element
1651 	// (is included as subelement of chart)
1652 	// ------------------------------------
1653 	if( bExportContent )
1654 	{
1655         // #85929# always export table, otherwise clipboard may loose data
1656         exportTable();
1657 	}
1658 
1659 	// close <chart:chart> element
1660 	if( pElChart )
1661 		delete pElChart;
1662 }
1663 
1664 void lcl_exportComplexLabel( const Sequence< uno::Any >& rComplexLabel, SvXMLExport& rExport )
1665 {
1666     sal_Int32 nLength = rComplexLabel.getLength();
1667     if( nLength<=1 )
1668         return;
1669     SvXMLElementExport aTextList( rExport, XML_NAMESPACE_TEXT, XML_LIST, sal_True, sal_True );
1670     for(sal_Int32 nN=0; nN<nLength; nN++)
1671     {
1672         SvXMLElementExport aListItem( rExport, XML_NAMESPACE_TEXT, XML_LIST_ITEM, sal_True, sal_True );
1673         OUString aString;
1674         if( !(rComplexLabel[nN]>>=aString) )
1675         {
1676             //todo?
1677         }
1678         SchXMLTools::exportText( rExport, aString, false /*bConvertTabsLFs*/ );
1679     }
1680 }
1681 
1682 void SchXMLExportHelper_Impl::exportTable()
1683 {
1684     // table element
1685 	// -------------
1686 	mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, msTableName );
1687 
1688     try
1689     {
1690         bool bProtected = false;
1691         Reference< beans::XPropertySet > xProps( mrExport.GetModel(), uno::UNO_QUERY_THROW );
1692         if ( ( xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DisableDataTableDialog" ) ) ) >>= bProtected ) &&
1693              bProtected )
1694         {
1695             mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE );
1696         }
1697     }
1698     catch ( uno::Exception& )
1699     {
1700     }
1701 
1702     SvXMLElementExport aTable( mrExport, XML_NAMESPACE_TABLE, XML_TABLE, sal_True, sal_True );
1703 
1704     bool bHasOwnData = false;
1705     Reference< chart2::XChartDocument > xNewDoc( mrExport.GetModel(), uno::UNO_QUERY );
1706     Reference< chart2::data::XRangeXMLConversion > xRangeConversion;
1707     if( xNewDoc.is())
1708     {
1709         bHasOwnData = xNewDoc->hasInternalDataProvider();
1710         xRangeConversion.set( xNewDoc->getDataProvider(), uno::UNO_QUERY );
1711     }
1712 
1713     Reference< chart2::XAnyDescriptionAccess > xAnyDescriptionAccess;
1714     {
1715         Reference< chart::XChartDocument > xChartDoc( mrExport.GetModel(), uno::UNO_QUERY );
1716         if( xChartDoc.is() )
1717             xAnyDescriptionAccess = Reference< chart2::XAnyDescriptionAccess >( xChartDoc->getData(), uno::UNO_QUERY );
1718     }
1719 
1720     if( bHasOwnData )
1721         lcl_ReorderInternalSequencesAccordingToTheirRangeName( m_aDataSequencesToExport );
1722     lcl_TableData aData( lcl_getDataForLocalTable( m_aDataSequencesToExport
1723                                 , xAnyDescriptionAccess, maCategoriesRange
1724                                 , mbRowSourceColumns, xRangeConversion ));
1725 
1726     tStringVector::const_iterator aDataRangeIter( aData.aDataRangeRepresentations.begin());
1727     const tStringVector::const_iterator aDataRangeEndIter( aData.aDataRangeRepresentations.end());
1728 
1729     tStringVector::const_iterator aRowDescriptions_RangeIter( aData.aRowDescriptions_Ranges.begin());
1730     const tStringVector::const_iterator aRowDescriptions_RangeEnd( aData.aRowDescriptions_Ranges.end());
1731 
1732     // declare columns
1733     {
1734         SvXMLElementExport aHeaderColumns( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, sal_True, sal_True );
1735         SvXMLElementExport aHeaderColumn( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True );
1736     }
1737     {
1738         SvXMLElementExport aColumns( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMNS, sal_True, sal_True );
1739 
1740         sal_Int32 nNextIndex = 0;
1741         for( size_t nN=0; nN< aData.aHiddenColumns.size(); nN++ )
1742         {
1743             //i91578 display of hidden values (copy paste scenario; export hidden flag thus it can be used during migration to locale table upon paste )
1744             sal_Int32 nHiddenIndex = aData.aHiddenColumns[nN];
1745             if( nHiddenIndex > nNextIndex )
1746             {
1747                 sal_Int64 nRepeat = static_cast< sal_Int64 >( nHiddenIndex - nNextIndex );
1748                 if(nRepeat>1)
1749                     mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED,
1750                                    OUString::valueOf( nRepeat ));
1751                 SvXMLElementExport aColumn( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True );
1752             }
1753             mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_VISIBILITY, GetXMLToken( XML_COLLAPSE ) );
1754             SvXMLElementExport aColumn( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True );
1755             nNextIndex = nHiddenIndex+1;
1756         }
1757 
1758         sal_Int32 nEndIndex = aData.aColumnDescriptions.size()-1;
1759         if( nEndIndex >= nNextIndex )
1760         {
1761             sal_Int64 nRepeat = static_cast< sal_Int64 >( nEndIndex - nNextIndex + 1 );
1762             if(nRepeat>1)
1763                 mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED,
1764                                OUString::valueOf( nRepeat ));
1765             SvXMLElementExport aColumn( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True );
1766         }
1767     }
1768 
1769     // export rows with content
1770     //export header row
1771     {
1772         SvXMLElementExport aHeaderRows( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, sal_True, sal_True );
1773         SvXMLElementExport aRow( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True );
1774 
1775         //first one empty cell for the row descriptions
1776         {
1777             SvXMLElementExport aEmptyCell( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True );
1778             SvXMLElementExport aEmptyParagraph( mrExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_True );
1779         }
1780 
1781         //export column descriptions
1782         tStringVector::const_iterator aColumnDescriptions_RangeIter( aData.aColumnDescriptions_Ranges.begin());
1783         const tStringVector::const_iterator aColumnDescriptions_RangeEnd( aData.aColumnDescriptions_Ranges.end());
1784         const Sequence< Sequence< uno::Any > >& rComplexColumnDescriptions = aData.aComplexColumnDescriptions;
1785         sal_Int32 nComplexCount = rComplexColumnDescriptions.getLength();
1786         sal_Int32 nC = 0;
1787         for( tStringVector::const_iterator aIt( aData.aColumnDescriptions.begin())
1788              ; (aIt != aData.aColumnDescriptions.end())
1789              ; aIt++, nC++ )
1790         {
1791             bool bExportString = true;
1792             if( nC < nComplexCount )
1793             {
1794                 const Sequence< uno::Any >& rComplexLabel = rComplexColumnDescriptions[nC];
1795                 if( rComplexLabel.getLength()>0 )
1796                 {
1797                     double fValue=0.0;
1798                     if( rComplexLabel[0] >>=fValue )
1799                     {
1800                         bExportString = false;
1801 
1802                         SvXMLUnitConverter::convertDouble( msStringBuffer, fValue );
1803                         msString = msStringBuffer.makeStringAndClear();
1804                         mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT );
1805                         mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE, msString );
1806                     }
1807                 }
1808             }
1809             if( bExportString )
1810             {
1811                 mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING );
1812             }
1813 
1814             SvXMLElementExport aCell( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True );
1815             exportText( *aIt );
1816             if( nC < nComplexCount )
1817                 lcl_exportComplexLabel( rComplexColumnDescriptions[nC], mrExport );
1818             if( !bHasOwnData && aColumnDescriptions_RangeIter != aColumnDescriptions_RangeEnd )
1819             {
1820                 // remind the original range to allow a correct re-association when copying via clipboard
1821                 if ((*aColumnDescriptions_RangeIter).getLength())
1822                     SchXMLTools::exportRangeToSomewhere( mrExport, *aColumnDescriptions_RangeIter );
1823                 ++aColumnDescriptions_RangeIter;
1824             }
1825         }
1826         OSL_ASSERT( bHasOwnData || aColumnDescriptions_RangeIter == aColumnDescriptions_RangeEnd );
1827     } // closing row and header-rows elements
1828 
1829     // export value rows
1830     {
1831         SvXMLElementExport aRows( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_ROWS, sal_True, sal_True );
1832         tStringVector::const_iterator aRowDescriptionsIter( aData.aRowDescriptions.begin());
1833         const Sequence< Sequence< uno::Any > >& rComplexRowDescriptions = aData.aComplexRowDescriptions;
1834         sal_Int32 nComplexCount = rComplexRowDescriptions.getLength();
1835         sal_Int32 nC = 0;
1836 
1837         for( t2DNumberContainer::const_iterator aRowIt( aData.aDataInRows.begin())
1838             ; aRowIt != aData.aDataInRows.end()
1839             ; ++aRowIt, ++nC )
1840         {
1841             SvXMLElementExport aRow( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True );
1842 
1843             //export row descriptions
1844             {
1845                 bool bExportString = true;
1846                 if( nC < nComplexCount )
1847                 {
1848                     const Sequence< uno::Any >& rComplexLabel = rComplexRowDescriptions[nC];
1849                     if( rComplexLabel.getLength()>0 )
1850                     {
1851                         double fValue=0.0;
1852                         if( rComplexLabel[0] >>=fValue )
1853                         {
1854                             bExportString = false;
1855 
1856                             SvXMLUnitConverter::convertDouble( msStringBuffer, fValue );
1857                             msString = msStringBuffer.makeStringAndClear();
1858                             mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT );
1859                             mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE, msString );
1860                         }
1861                     }
1862                 }
1863                 if( bExportString )
1864                 {
1865                     mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING );
1866                 }
1867 
1868                 SvXMLElementExport aCell( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True );
1869                 if( aRowDescriptionsIter != aData.aRowDescriptions.end())
1870                 {
1871                     exportText( *aRowDescriptionsIter );
1872                     if( nC < nComplexCount )
1873                         lcl_exportComplexLabel( rComplexRowDescriptions[nC], mrExport );
1874                     if( !bHasOwnData && aRowDescriptions_RangeIter != aRowDescriptions_RangeEnd )
1875                     {
1876                         // remind the original range to allow a correct re-association when copying via clipboard
1877                         SchXMLTools::exportRangeToSomewhere( mrExport, *aRowDescriptions_RangeIter );
1878                         ++aRowDescriptions_RangeIter;
1879                     }
1880                     ++aRowDescriptionsIter;
1881                 }
1882             }
1883 
1884             //export row values
1885             for( t2DNumberContainer::value_type::const_iterator aColIt( aRowIt->begin());
1886                  aColIt != aRowIt->end(); ++aColIt )
1887             {
1888                 SvXMLUnitConverter::convertDouble( msStringBuffer, *aColIt );
1889                 msString = msStringBuffer.makeStringAndClear();
1890                 mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT );
1891                 mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE, msString );
1892                 SvXMLElementExport aCell( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True );
1893                 exportText( msString, false ); // do not convert tabs and lfs
1894                 if( ( !bHasOwnData && aDataRangeIter != aDataRangeEndIter ) &&
1895                     ( mbRowSourceColumns || (aColIt == aRowIt->begin()) ) )
1896                 {
1897                     // remind the original range to allow a correct re-association when copying via clipboard
1898                     if ((*aDataRangeIter).getLength())
1899                         SchXMLTools::exportRangeToSomewhere( mrExport, *aDataRangeIter );
1900                     ++aDataRangeIter;
1901                 }
1902             }
1903         }
1904     }
1905 
1906     // if range iterator was used it should have reached its end
1907     OSL_ASSERT( bHasOwnData || (aDataRangeIter == aDataRangeEndIter) );
1908     OSL_ASSERT( bHasOwnData || (aRowDescriptions_RangeIter == aRowDescriptions_RangeEnd) );
1909 }
1910 
1911 namespace
1912 {
1913 
1914 Reference< chart2::XCoordinateSystem > lcl_getCooSys( const Reference< chart2::XDiagram > & xNewDiagram )
1915 {
1916     Reference< chart2::XCoordinateSystem > xCooSys;
1917     Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xNewDiagram, uno::UNO_QUERY );
1918     if(xCooSysCnt.is())
1919     {
1920         Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems() );
1921         if(aCooSysSeq.getLength()>0)
1922             xCooSys = aCooSysSeq[0];
1923     }
1924     return xCooSys;
1925 }
1926 
1927 Reference< chart2::XAxis > lcl_getAxis( const Reference< chart2::XCoordinateSystem >& xCooSys,
1928         enum XMLTokenEnum eDimension, bool bPrimary=true )
1929 {
1930     Reference< chart2::XAxis > xNewAxis;
1931     try
1932     {
1933         if( xCooSys.is() )
1934         {
1935             sal_Int32 nDimensionIndex=0;
1936             switch( eDimension )
1937             {
1938             case XML_X:
1939                 nDimensionIndex=0;
1940                 break;
1941             case XML_Y:
1942                 nDimensionIndex=1;
1943                 break;
1944             case XML_Z:
1945                 nDimensionIndex=2;
1946                 break;
1947             default:
1948                 break;
1949             }
1950 
1951             xNewAxis = xCooSys->getAxisByDimension( nDimensionIndex, bPrimary ? 0 : 1 );
1952         }
1953     }
1954     catch( const uno::Exception & )
1955     {
1956     }
1957     return xNewAxis;
1958 }
1959 
1960 }
1961 
1962 void SchXMLExportHelper_Impl::exportPlotArea(
1963     Reference< chart::XDiagram > xDiagram,
1964     Reference< chart2::XDiagram > xNewDiagram,
1965     const awt::Size & rPageSize,
1966     sal_Bool bExportContent,
1967     sal_Bool bIncludeTable )
1968 {
1969 	DBG_ASSERT( xDiagram.is(), "Invalid XDiagram as parameter" );
1970 	if( ! xDiagram.is())
1971 		return;
1972 
1973 	// variables for autostyles
1974 	Reference< beans::XPropertySet > xPropSet;
1975 	std::vector< XMLPropertyState > aPropertyStates;
1976 
1977 	sal_Bool bIs3DChart = sal_False;
1978 	drawing::HomogenMatrix aTransMatrix;
1979 
1980     msStringBuffer.setLength( 0 );
1981 
1982     // plot-area element
1983 	// -----------------
1984 
1985 	SvXMLElementExport* pElPlotArea = 0;
1986 	// get property states for autostyles
1987 	xPropSet = Reference< beans::XPropertySet >( xDiagram, uno::UNO_QUERY );
1988 	if( xPropSet.is())
1989 	{
1990 		if( mxExpPropMapper.is())
1991 			aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1992 	}
1993 	if( bExportContent )
1994 	{
1995 		UniReference< XMLShapeExport > rShapeExport;
1996 
1997 		// write style name
1998         AddAutoStyleAttribute( aPropertyStates );
1999 
2000         if( msChartAddress.getLength() )
2001         {
2002             if( !bIncludeTable )
2003                 mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, msChartAddress );
2004 
2005             Reference< chart::XChartDocument > xDoc( mrExport.GetModel(), uno::UNO_QUERY );
2006             if( xDoc.is() )
2007             {
2008                 Reference< beans::XPropertySet > xDocProp( xDoc, uno::UNO_QUERY );
2009                 if( xDocProp.is())
2010                 {
2011                     Any aAny;
2012                     sal_Bool bFirstCol = false, bFirstRow = false;
2013 
2014                     try
2015                     {
2016                         aAny = xDocProp->getPropertyValue(
2017                             OUString( RTL_CONSTASCII_USTRINGPARAM( "DataSourceLabelsInFirstColumn" )));
2018                         aAny >>= bFirstCol;
2019                         aAny = xDocProp->getPropertyValue(
2020                             OUString( RTL_CONSTASCII_USTRINGPARAM( "DataSourceLabelsInFirstRow" )));
2021                         aAny >>= bFirstRow;
2022 
2023                         if( bFirstCol || bFirstRow )
2024                         {
2025                             mrExport.AddAttribute( XML_NAMESPACE_CHART,
2026                                                    ::xmloff::token::GetXMLToken( ::xmloff::token::XML_DATA_SOURCE_HAS_LABELS ),
2027                                                    ( bFirstCol
2028                                                      ? ( bFirstRow
2029                                                          ?  ::xmloff::token::GetXMLToken( ::xmloff::token::XML_BOTH )
2030                                                          :  ::xmloff::token::GetXMLToken( ::xmloff::token::XML_COLUMN ))
2031                                                      : ::xmloff::token::GetXMLToken( ::xmloff::token::XML_ROW )));
2032                         }
2033                     }
2034                     catch( beans::UnknownPropertyException & )
2035                     {
2036                         DBG_ERRORFILE( "Properties missing" );
2037                     }
2038                 }
2039             }
2040         }
2041 
2042         // #i72973#, #144135# only export table-number-list in OOo format (also for binary)
2043         Reference< beans::XPropertySet > xExportInfo( mrExport.getExportInfo());
2044         if( msTableNumberList.getLength() &&
2045             xExportInfo.is())
2046         {
2047             try
2048             {
2049                 OUString sExportTableNumListPropName( RTL_CONSTASCII_USTRINGPARAM("ExportTableNumberList"));
2050                 Reference< beans::XPropertySetInfo > xInfo( xExportInfo->getPropertySetInfo());
2051                 bool bExportTableNumberList = false;
2052                 if( xInfo.is() && xInfo->hasPropertyByName( sExportTableNumListPropName ) &&
2053                     (xExportInfo->getPropertyValue( sExportTableNumListPropName ) >>= bExportTableNumberList) &&
2054                     bExportTableNumberList )
2055                 {
2056                     // this attribute is for charts embedded in calc documents only.
2057                     // With this you are able to store a file again in 5.0 binary format
2058                     mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_TABLE_NUMBER_LIST, msTableNumberList );
2059                 }
2060             }
2061 			catch( uno::Exception & rEx )
2062             {
2063 #ifdef DBG_UTIL
2064                 String aStr( rEx.Message );
2065                 ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US );
2066                 DBG_ERROR1( "chart:TableNumberList property caught: %s", aBStr.GetBuffer());
2067 #else
2068                 (void)rEx; // avoid warning
2069 #endif
2070             }
2071         }
2072 
2073         // attributes
2074 		Reference< drawing::XShape > xShape ( xDiagram, uno::UNO_QUERY );
2075 		if( xShape.is())
2076 		{
2077 			addPosition( xShape );
2078 			addSize( xShape );
2079 		}
2080 
2081 		if( xPropSet.is())
2082 		{
2083 			Any aAny;
2084 
2085 			// 3d attributes
2086 			try
2087 			{
2088 				aAny = xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Dim3D" )));
2089 				aAny >>= bIs3DChart;
2090 
2091 				if( bIs3DChart )
2092 				{
2093 					rShapeExport = mrExport.GetShapeExport();
2094 					if( rShapeExport.is())
2095 						rShapeExport->export3DSceneAttributes( xPropSet );
2096 				}
2097 			}
2098 			catch( uno::Exception & rEx )
2099 			{
2100 #ifdef DBG_UTIL
2101                 String aStr( rEx.Message );
2102                 ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US );
2103                 DBG_ERROR1( "chart:exportPlotAreaException caught: %s", aBStr.GetBuffer());
2104 #else
2105                 (void)rEx; // avoid warning
2106 #endif
2107 			}
2108 		}
2109 
2110 		// plot-area element
2111 		pElPlotArea = new SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_PLOT_AREA, sal_True, sal_True );
2112 
2113         //inner position rectangle element
2114         exportCoordinateRegion( xDiagram );
2115 
2116 		// light sources (inside plot area element)
2117 		if( bIs3DChart &&
2118 			rShapeExport.is())
2119 			rShapeExport->export3DLamps( xPropSet );
2120 	}
2121 	else	// autostyles
2122 	{
2123         CollectAutoStyle( aPropertyStates );
2124 	}
2125 	// remove property states for autostyles
2126 	aPropertyStates.clear();
2127 
2128     // axis elements
2129 	// -------------
2130 	exportAxes( xDiagram, xNewDiagram, bExportContent );
2131 
2132 	// series elements
2133 	// ---------------
2134     Reference< chart2::XAxis > xSecondYAxis = lcl_getAxis( lcl_getCooSys( xNewDiagram ), XML_Y, false );
2135     exportSeries( xNewDiagram, rPageSize, bExportContent, xSecondYAxis.is() );
2136 
2137     // stock-chart elements
2138     OUString sChartType ( xDiagram->getDiagramType());
2139     if( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.StockDiagram" )))
2140     {
2141         Reference< chart::XStatisticDisplay > xStockPropProvider( xDiagram, uno::UNO_QUERY );
2142         if( xStockPropProvider.is())
2143         {
2144             // stock-gain-marker
2145             Reference< beans::XPropertySet > xStockPropSet = xStockPropProvider->getUpBar();
2146             if( xStockPropSet.is())
2147             {
2148                 aPropertyStates.clear();
2149                 aPropertyStates = mxExpPropMapper->Filter( xStockPropSet );
2150 
2151                 if( !aPropertyStates.empty() )
2152                 {
2153                     if( bExportContent )
2154                     {
2155                         AddAutoStyleAttribute( aPropertyStates );
2156 
2157                         SvXMLElementExport aGain( mrExport, XML_NAMESPACE_CHART, XML_STOCK_GAIN_MARKER, sal_True, sal_True );
2158                     }
2159                     else
2160                     {
2161                         CollectAutoStyle( aPropertyStates );
2162                     }
2163                 }
2164             }
2165 
2166             // stock-loss-marker
2167             xStockPropSet = xStockPropProvider->getDownBar();
2168             if( xStockPropSet.is())
2169             {
2170                 aPropertyStates.clear();
2171                 aPropertyStates = mxExpPropMapper->Filter( xStockPropSet );
2172 
2173                 if( !aPropertyStates.empty() )
2174                 {
2175                     if( bExportContent )
2176                     {
2177                         AddAutoStyleAttribute( aPropertyStates );
2178 
2179                         SvXMLElementExport aGain( mrExport, XML_NAMESPACE_CHART, XML_STOCK_LOSS_MARKER, sal_True, sal_True );
2180                     }
2181                     else
2182                     {
2183                         CollectAutoStyle( aPropertyStates );
2184                     }
2185                 }
2186             }
2187 
2188             // stock-range-line
2189             xStockPropSet = xStockPropProvider->getMinMaxLine();
2190             if( xStockPropSet.is())
2191             {
2192                 aPropertyStates.clear();
2193                 aPropertyStates = mxExpPropMapper->Filter( xStockPropSet );
2194 
2195                 if( !aPropertyStates.empty() )
2196                 {
2197                     if( bExportContent )
2198                     {
2199                         AddAutoStyleAttribute( aPropertyStates );
2200 
2201                         SvXMLElementExport aGain( mrExport, XML_NAMESPACE_CHART, XML_STOCK_RANGE_LINE, sal_True, sal_True );
2202                     }
2203                     else
2204                     {
2205                         CollectAutoStyle( aPropertyStates );
2206                     }
2207                 }
2208             }
2209         }
2210     }
2211 
2212 	// wall and floor element
2213 	// ----------------------
2214 
2215 	Reference< chart::X3DDisplay > xWallFloorSupplier( xDiagram, uno::UNO_QUERY );
2216 	if( mxExpPropMapper.is() &&
2217 		xWallFloorSupplier.is())
2218 	{
2219 		// remove property states for autostyles
2220 		aPropertyStates.clear();
2221 
2222 		Reference< beans::XPropertySet > xWallPropSet( xWallFloorSupplier->getWall(), uno::UNO_QUERY );
2223 		if( xWallPropSet.is())
2224 		{
2225 			aPropertyStates = mxExpPropMapper->Filter( xWallPropSet );
2226 
2227 			if( !aPropertyStates.empty() )
2228 			{
2229 				// write element
2230 				if( bExportContent )
2231 				{
2232 					// add style name attribute
2233                     AddAutoStyleAttribute( aPropertyStates );
2234 
2235 					SvXMLElementExport aWall( mrExport, XML_NAMESPACE_CHART, XML_WALL, sal_True, sal_True );
2236 				}
2237 				else	// autostyles
2238 				{
2239                     CollectAutoStyle( aPropertyStates );
2240 				}
2241 			}
2242 		}
2243 
2244         // floor element
2245         // -------------
2246 
2247 		// remove property states for autostyles
2248 		aPropertyStates.clear();
2249 
2250 		Reference< beans::XPropertySet > xFloorPropSet( xWallFloorSupplier->getFloor(), uno::UNO_QUERY );
2251 		if( xFloorPropSet.is())
2252 		{
2253 			aPropertyStates = mxExpPropMapper->Filter( xFloorPropSet );
2254 
2255 			if( !aPropertyStates.empty() )
2256 			{
2257 				// write element
2258 				if( bExportContent )
2259 				{
2260 					// add style name attribute
2261                     AddAutoStyleAttribute( aPropertyStates );
2262 
2263 					SvXMLElementExport aFloor( mrExport, XML_NAMESPACE_CHART, XML_FLOOR, sal_True, sal_True );
2264 				}
2265 				else	// autostyles
2266 				{
2267                     CollectAutoStyle( aPropertyStates );
2268 				}
2269 			}
2270 		}
2271 	}
2272 
2273 	if( pElPlotArea )
2274 		delete pElPlotArea;
2275 }
2276 
2277 void SchXMLExportHelper_Impl::exportCoordinateRegion( const uno::Reference< chart::XDiagram >& xDiagram )
2278 {
2279     const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2280     if( nCurrentODFVersion <= SvtSaveOptions::ODFVER_012 )//do not export to ODF 1.2 or older
2281         return;
2282     if( nCurrentODFVersion != SvtSaveOptions::ODFVER_LATEST )//export only if extensions are enabled //#i100778# todo: change this dependent on fileformat evolution
2283         return;
2284 
2285     Reference< chart::XDiagramPositioning > xDiaPos( xDiagram, uno::UNO_QUERY );
2286     DBG_ASSERT( xDiaPos.is(), "Invalid xDiaPos as parameter" );
2287 	if( !xDiaPos.is() )
2288 		return;
2289 
2290     awt::Rectangle aRect( xDiaPos->calculateDiagramPositionExcludingAxes() );
2291     addPosition( awt::Point(aRect.X,aRect.Y) );
2292     addSize( awt::Size(aRect.Width,aRect.Height) );
2293 
2294     SvXMLElementExport aCoordinateRegion( mrExport, XML_NAMESPACE_CHART_EXT, XML_COORDINATE_REGION, sal_True, sal_True );//#i100778# todo: change to chart namespace in future - dependent on fileformat
2295 }
2296 
2297 namespace
2298 {
2299     XMLTokenEnum lcl_getTimeUnitToken( sal_Int32 nTimeUnit )
2300     {
2301         XMLTokenEnum eToken = XML_DAYS;
2302         switch( nTimeUnit )
2303         {
2304         case ::com::sun::star::chart::TimeUnit::YEAR:
2305             eToken = XML_YEARS;
2306             break;
2307         case ::com::sun::star::chart::TimeUnit::MONTH:
2308             eToken = XML_MONTHS;
2309             break;
2310         default://days
2311             break;
2312         }
2313         return eToken;
2314     }
2315 }
2316 
2317 void SchXMLExportHelper_Impl::exportDateScale( const Reference< beans::XPropertySet > xAxisProps )
2318 {
2319     if( !xAxisProps.is() )
2320         return;
2321 
2322     chart::TimeIncrement aIncrement;
2323     if( (xAxisProps->getPropertyValue( OUString::createFromAscii( "TimeIncrement" )) >>= aIncrement) )
2324     {
2325         sal_Int32 nTimeResolution = ::com::sun::star::chart::TimeUnit::DAY;
2326         if( aIncrement.TimeResolution >>= nTimeResolution )
2327             mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_BASE_TIME_UNIT, lcl_getTimeUnitToken( nTimeResolution ) );
2328 
2329         OUStringBuffer aValue;
2330         chart::TimeInterval aInterval;
2331         if( aIncrement.MajorTimeInterval >>= aInterval )
2332         {
2333             SvXMLUnitConverter::convertNumber( aValue, aInterval.Number );
2334             mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_MAJOR_INTERVAL_VALUE, aValue.makeStringAndClear() );
2335             mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_MAJOR_INTERVAL_UNIT, lcl_getTimeUnitToken( aInterval.TimeUnit ) );
2336         }
2337         if( aIncrement.MinorTimeInterval >>= aInterval )
2338         {
2339             SvXMLUnitConverter::convertNumber( aValue, aInterval.Number );
2340             mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_MINOR_INTERVAL_VALUE, aValue.makeStringAndClear() );
2341             mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_MINOR_INTERVAL_UNIT, lcl_getTimeUnitToken( aInterval.TimeUnit ) );
2342         }
2343 
2344         SvXMLElementExport aDateScale( mrExport, XML_NAMESPACE_CHART_EXT, XML_DATE_SCALE, sal_True, sal_True );//#i25706#todo: change namespace for next ODF version
2345     }
2346 }
2347 
2348 void SchXMLExportHelper_Impl::exportAxisTitle( const Reference< beans::XPropertySet > xTitleProps, bool bExportContent )
2349 {
2350     if( !xTitleProps.is() )
2351         return;
2352     std::vector< XMLPropertyState > aPropertyStates = mxExpPropMapper->Filter( xTitleProps );
2353     if( bExportContent )
2354     {
2355         OUString aText;
2356         Any aAny( xTitleProps->getPropertyValue(
2357             OUString( RTL_CONSTASCII_USTRINGPARAM( "String" ))));
2358         aAny >>= aText;
2359 
2360         Reference< drawing::XShape > xShape( xTitleProps, uno::UNO_QUERY );
2361         if( xShape.is())
2362             addPosition( xShape );
2363 
2364         AddAutoStyleAttribute( aPropertyStates );
2365         SvXMLElementExport aTitle( mrExport, XML_NAMESPACE_CHART, XML_TITLE, sal_True, sal_True );
2366 
2367         // paragraph containing title
2368         exportText( aText );
2369     }
2370     else
2371     {
2372         CollectAutoStyle( aPropertyStates );
2373     }
2374     aPropertyStates.clear();
2375 }
2376 
2377 void SchXMLExportHelper_Impl::exportGrid( const Reference< beans::XPropertySet > xGridProperties, bool bMajor, bool bExportContent )
2378 {
2379     if( !xGridProperties.is() )
2380         return;
2381     std::vector< XMLPropertyState > aPropertyStates = mxExpPropMapper->Filter( xGridProperties );
2382     if( bExportContent )
2383     {
2384         AddAutoStyleAttribute( aPropertyStates );
2385         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS, bMajor ? XML_MAJOR : XML_MINOR );
2386         SvXMLElementExport aGrid( mrExport, XML_NAMESPACE_CHART, XML_GRID, sal_True, sal_True );
2387     }
2388     else
2389     {
2390         CollectAutoStyle( aPropertyStates );
2391     }
2392     aPropertyStates.clear();
2393 }
2394 
2395 namespace
2396 {
2397 
2398 //returns true if a date scale needs to be exported
2399 bool lcl_exportAxisType( const Reference< chart2::XAxis > xChart2Axis, SvXMLExport& rExport)
2400 {
2401     bool bExportDateScale = false;
2402     if( !xChart2Axis.is() )
2403         return bExportDateScale;
2404 
2405     const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2406     if( nCurrentODFVersion != SvtSaveOptions::ODFVER_LATEST ) //#i25706#todo: change version for next ODF version
2407         return bExportDateScale;
2408 
2409     chart2::ScaleData aScale( xChart2Axis->getScaleData() );
2410     //#i25706#todo: change namespace for next ODF version
2411     sal_uInt16 nNameSpace = XML_NAMESPACE_CHART_EXT;
2412 
2413     switch(aScale.AxisType)
2414     {
2415     case chart2::AxisType::CATEGORY:
2416         if( aScale.AutoDateAxis )
2417         {
2418             rExport.AddAttribute( nNameSpace, XML_AXIS_TYPE, XML_AUTO );
2419             bExportDateScale = true;
2420         }
2421         else
2422             rExport.AddAttribute( nNameSpace, XML_AXIS_TYPE, XML_TEXT );
2423         break;
2424     case chart2::AxisType::DATE:
2425         rExport.AddAttribute( nNameSpace, XML_AXIS_TYPE, XML_DATE );
2426         bExportDateScale = true;
2427         break;
2428     default: //AUTOMATIC
2429         rExport.AddAttribute( nNameSpace, XML_AXIS_TYPE, XML_AUTO );
2430         break;
2431     }
2432 
2433     return bExportDateScale;
2434 }
2435 
2436 }
2437 
2438 void SchXMLExportHelper_Impl::exportAxis(
2439     enum XMLTokenEnum eDimension,
2440     enum XMLTokenEnum eAxisName,
2441     const Reference< beans::XPropertySet > xAxisProps,
2442     const Reference< chart2::XAxis >& xChart2Axis,
2443     const OUString& rCategoriesRange,
2444     bool bHasTitle, bool bHasMajorGrid, bool bHasMinorGrid,
2445     bool bExportContent )
2446 {
2447     static const OUString sNumFormat( OUString::createFromAscii( "NumberFormat" ));
2448     std::vector< XMLPropertyState > aPropertyStates;
2449     SvXMLElementExport* pAxis = NULL;
2450 
2451     // get property states for autostyles
2452     if( xAxisProps.is() && mxExpPropMapper.is() )
2453     {
2454         lcl_exportNumberFormat( sNumFormat, xAxisProps, mrExport );
2455         aPropertyStates = mxExpPropMapper->Filter( xAxisProps );
2456     }
2457 
2458     bool bExportDateScale = false;
2459     if( bExportContent )
2460     {
2461         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_DIMENSION, eDimension );
2462         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_NAME, eAxisName );
2463         AddAutoStyleAttribute( aPropertyStates ); // write style name
2464         if( rCategoriesRange.getLength() )
2465             bExportDateScale = lcl_exportAxisType( xChart2Axis, mrExport );
2466 
2467         // open axis element
2468         pAxis = new SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_AXIS, sal_True, sal_True );
2469     }
2470     else
2471     {
2472         CollectAutoStyle( aPropertyStates );
2473     }
2474     aPropertyStates.clear();
2475 
2476     //date scale
2477     if( bExportDateScale )
2478         exportDateScale( xAxisProps );
2479 
2480     Reference< beans::XPropertySet > xTitleProps;
2481     Reference< beans::XPropertySet > xMajorGridProps;
2482     Reference< beans::XPropertySet > xMinorGridProps;
2483     Reference< chart::XAxis > xAxis( xAxisProps, uno::UNO_QUERY );
2484     if( xAxis.is() )
2485     {
2486         xTitleProps = bHasTitle ? xAxis->getAxisTitle() : 0;
2487         xMajorGridProps = bHasMajorGrid ? xAxis->getMajorGrid() : 0;
2488         xMinorGridProps = bHasMinorGrid ? xAxis->getMinorGrid() : 0;
2489     }
2490 
2491     // axis-title
2492     exportAxisTitle( xTitleProps , bExportContent );
2493 
2494     // categories if we have a categories chart
2495     if( bExportContent && rCategoriesRange.getLength() )
2496     {
2497         mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, rCategoriesRange );
2498         SvXMLElementExport aCategories( mrExport, XML_NAMESPACE_CHART, XML_CATEGORIES, sal_True, sal_True );
2499     }
2500 
2501     // grid
2502     exportGrid( xMajorGridProps, true, bExportContent );
2503     exportGrid( xMinorGridProps, false, bExportContent );
2504 
2505     if( pAxis )
2506     {
2507         //close axis element
2508         delete pAxis;
2509         pAxis = NULL;
2510     }
2511 }
2512 
2513 void SchXMLExportHelper_Impl::exportAxes(
2514     const Reference< chart::XDiagram > & xDiagram,
2515     const Reference< chart2::XDiagram > & xNewDiagram,
2516     sal_Bool bExportContent )
2517 {
2518 	DBG_ASSERT( xDiagram.is(), "Invalid XDiagram as parameter" );
2519 	if( ! xDiagram.is())
2520 		return;
2521 
2522 	// get some properties from document first
2523 	sal_Bool bHasXAxis = sal_False,
2524 		bHasYAxis = sal_False,
2525 		bHasZAxis = sal_False,
2526 		bHasSecondaryXAxis = sal_False,
2527 		bHasSecondaryYAxis = sal_False;
2528 	sal_Bool bHasXAxisTitle = sal_False,
2529 		bHasYAxisTitle = sal_False,
2530 		bHasZAxisTitle = sal_False,
2531 		bHasSecondaryXAxisTitle = sal_False,
2532 		bHasSecondaryYAxisTitle = sal_False;
2533 	sal_Bool bHasXAxisMajorGrid = sal_False,
2534 		bHasXAxisMinorGrid = sal_False,
2535 		bHasYAxisMajorGrid = sal_False,
2536 		bHasYAxisMinorGrid = sal_False,
2537 		bHasZAxisMajorGrid = sal_False,
2538 		bHasZAxisMinorGrid = sal_False;
2539 
2540     // get multiple properties using XMultiPropertySet
2541 	MultiPropertySetHandler	aDiagramProperties (xDiagram);
2542 
2543 	aDiagramProperties.Add (
2544 		OUString(RTL_CONSTASCII_USTRINGPARAM("HasXAxis")), bHasXAxis);
2545 	aDiagramProperties.Add (
2546 		OUString(RTL_CONSTASCII_USTRINGPARAM("HasYAxis")), bHasYAxis);
2547 	aDiagramProperties.Add (
2548 		OUString(RTL_CONSTASCII_USTRINGPARAM("HasZAxis")), bHasZAxis);
2549 	aDiagramProperties.Add (
2550 		OUString(RTL_CONSTASCII_USTRINGPARAM("HasSecondaryXAxis")), bHasSecondaryXAxis);
2551 	aDiagramProperties.Add (
2552 		OUString(RTL_CONSTASCII_USTRINGPARAM("HasSecondaryYAxis")), bHasSecondaryYAxis);
2553 
2554 	aDiagramProperties.Add (
2555 		OUString (RTL_CONSTASCII_USTRINGPARAM ("HasXAxisTitle")), bHasXAxisTitle);
2556 	aDiagramProperties.Add (
2557 		OUString (RTL_CONSTASCII_USTRINGPARAM ("HasYAxisTitle")), bHasYAxisTitle);
2558 	aDiagramProperties.Add (
2559 		OUString (RTL_CONSTASCII_USTRINGPARAM ("HasZAxisTitle")), bHasZAxisTitle);
2560 	aDiagramProperties.Add (
2561 		OUString (RTL_CONSTASCII_USTRINGPARAM ("HasSecondaryXAxisTitle")), bHasSecondaryXAxisTitle);
2562 	aDiagramProperties.Add (
2563 		OUString (RTL_CONSTASCII_USTRINGPARAM ("HasSecondaryYAxisTitle")), bHasSecondaryYAxisTitle);
2564 
2565 	aDiagramProperties.Add (
2566 		OUString (RTL_CONSTASCII_USTRINGPARAM ("HasXAxisGrid")), bHasXAxisMajorGrid);
2567 	aDiagramProperties.Add (
2568 		OUString (RTL_CONSTASCII_USTRINGPARAM ("HasYAxisGrid")), bHasYAxisMajorGrid);
2569 	aDiagramProperties.Add (
2570 		OUString (RTL_CONSTASCII_USTRINGPARAM ("HasZAxisGrid")), bHasZAxisMajorGrid);
2571 
2572 	aDiagramProperties.Add (
2573 		OUString (RTL_CONSTASCII_USTRINGPARAM ("HasXAxisHelpGrid")), bHasXAxisMinorGrid);
2574 	aDiagramProperties.Add (
2575 		OUString (RTL_CONSTASCII_USTRINGPARAM ("HasYAxisHelpGrid")), bHasYAxisMinorGrid);
2576 	aDiagramProperties.Add (
2577 		OUString (RTL_CONSTASCII_USTRINGPARAM ("HasZAxisHelpGrid")), bHasZAxisMinorGrid);
2578 
2579     if ( ! aDiagramProperties.GetProperties ())
2580     {
2581         DBG_WARNING ("Required properties not found in Chart diagram");
2582     }
2583 
2584     Reference< chart2::XCoordinateSystem > xCooSys( lcl_getCooSys(xNewDiagram) );
2585 
2586     // write an axis element also if the axis itself is not visible, but a grid or a title
2587 
2588     OUString aCategoriesRange;
2589     Reference< chart::XAxisSupplier > xAxisSupp( xDiagram, uno::UNO_QUERY );
2590 
2591     // x axis
2592 	// -------
2593     Reference< ::com::sun::star::chart2::XAxis > xNewAxis = lcl_getAxis( xCooSys, XML_X );
2594     if( xNewAxis.is() )
2595     {
2596         Reference< beans::XPropertySet > xAxisProps( xAxisSupp.is() ? xAxisSupp->getAxis(0) : 0, uno::UNO_QUERY );
2597         if( mbHasCategoryLabels && bExportContent )
2598         {
2599             Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xNewDiagram ) );
2600             if( xCategories.is() )
2601             {
2602                 Reference< chart2::data::XDataSequence > xValues( xCategories->getValues() );
2603                 if( xValues.is() )
2604                 {
2605                     Reference< chart2::XChartDocument > xNewDoc( mrExport.GetModel(), uno::UNO_QUERY );
2606                     maCategoriesRange = xValues->getSourceRangeRepresentation();
2607                     aCategoriesRange = lcl_ConvertRange( maCategoriesRange, xNewDoc );
2608                 }
2609             }
2610         }
2611         exportAxis( XML_X, XML_PRIMARY_X, xAxisProps, xNewAxis, aCategoriesRange, bHasXAxisTitle, bHasXAxisMajorGrid, bHasXAxisMinorGrid, bExportContent );
2612         aCategoriesRange = OUString();
2613     }
2614 
2615     // secondary x axis
2616     // -------
2617     Reference< chart::XSecondAxisTitleSupplier > xSecondTitleSupp( xDiagram, uno::UNO_QUERY );
2618     xNewAxis = lcl_getAxis( xCooSys, XML_X, false );
2619     if( xNewAxis.is() )
2620     {
2621         Reference< beans::XPropertySet > xAxisProps( xAxisSupp.is() ? xAxisSupp->getSecondaryAxis(0) : 0, uno::UNO_QUERY );
2622         exportAxis( XML_X, XML_SECONDARY_X, xAxisProps, xNewAxis, aCategoriesRange, bHasSecondaryXAxisTitle, false, false, bExportContent );
2623     }
2624 
2625 	// y axis
2626 	// -------
2627     xNewAxis = lcl_getAxis( xCooSys, XML_Y );
2628     if( xNewAxis.is() )
2629     {
2630         Reference< beans::XPropertySet > xAxisProps( xAxisSupp.is() ? xAxisSupp->getAxis(1) : 0, uno::UNO_QUERY );
2631         exportAxis( XML_Y, XML_PRIMARY_Y, xAxisProps, xNewAxis, aCategoriesRange, bHasYAxisTitle, bHasYAxisMajorGrid, bHasYAxisMinorGrid, bExportContent );
2632     }
2633 
2634     // secondary y axis
2635     // -------
2636     xNewAxis = lcl_getAxis( xCooSys, XML_Y, false );
2637     if( xNewAxis.is() )
2638     {
2639         Reference< beans::XPropertySet > xAxisProps( xAxisSupp.is() ? xAxisSupp->getSecondaryAxis(1) : 0, uno::UNO_QUERY );
2640         exportAxis( XML_Y, XML_SECONDARY_Y, xAxisProps, xNewAxis, aCategoriesRange, bHasSecondaryYAxisTitle, false, false, bExportContent );
2641     }
2642 
2643 	// z axis
2644 	// -------
2645     xNewAxis = lcl_getAxis( xCooSys, XML_Z );
2646     if( xNewAxis.is() )
2647     {
2648         Reference< beans::XPropertySet > xAxisProps( xAxisSupp.is() ? xAxisSupp->getAxis(2) : 0, uno::UNO_QUERY );
2649         exportAxis( XML_Z, XML_PRIMARY_Z, xAxisProps, xNewAxis, aCategoriesRange, bHasZAxisTitle, bHasZAxisMajorGrid, bHasZAxisMinorGrid, bExportContent );
2650     }
2651 }
2652 
2653 namespace
2654 {
2655     bool lcl_hasNoValuesButText( const uno::Reference< chart2::data::XDataSequence >& xDataSequence )
2656     {
2657         if( !xDataSequence.is() )
2658             return false;//have no data
2659 
2660         Sequence< uno::Any > aData;
2661         Reference< chart2::data::XNumericalDataSequence > xNumericalDataSequence( xDataSequence, uno::UNO_QUERY );
2662         if( xNumericalDataSequence.is() )
2663         {
2664             Sequence< double >  aDoubles( xNumericalDataSequence->getNumericalData() );
2665             sal_Int32 nCount = aDoubles.getLength();
2666             for( sal_Int32 i = 0; i < nCount; ++i )
2667             {
2668                 if( !::rtl::math::isNan( aDoubles[i] ) )
2669                     return false;//have double value
2670             }
2671         }
2672         else
2673         {
2674             aData = xDataSequence->getData();
2675             double fDouble = 0.0;
2676             sal_Int32 nCount = aData.getLength();
2677             for( sal_Int32 i = 0; i < nCount; ++i )
2678             {
2679                 if( (aData[i] >>= fDouble) && !::rtl::math::isNan( fDouble ) )
2680                     return false;//have double value
2681             }
2682 
2683         }
2684         //no values found
2685 
2686         Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xDataSequence, uno::UNO_QUERY );
2687         if( xTextualDataSequence.is() )
2688         {
2689             uno::Sequence< rtl::OUString > aStrings( xTextualDataSequence->getTextualData() );
2690             sal_Int32 nCount = aStrings.getLength();
2691             for( sal_Int32 i = 0; i < nCount; ++i )
2692             {
2693                 if( aStrings[i].getLength() )
2694                     return true;//have text
2695             }
2696         }
2697         else
2698         {
2699             if( !aData.getLength() )
2700                 aData = xDataSequence->getData();
2701             uno::Any aAny;
2702             OUString aString;
2703             sal_Int32 nCount = aData.getLength();
2704             for( sal_Int32 i = 0; i < nCount; ++i )
2705             {
2706                 if( (aData[i]>>=aString) && aString.getLength() )
2707                     return true;//have text
2708             }
2709         }
2710         //no doubles and no texts
2711         return false;
2712     }
2713 }
2714 
2715 void SchXMLExportHelper_Impl::exportSeries(
2716     const Reference< chart2::XDiagram > & xNewDiagram,
2717     const awt::Size & rPageSize,
2718     sal_Bool bExportContent,
2719     sal_Bool bHasTwoYAxes )
2720 {
2721     Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( xNewDiagram, uno::UNO_QUERY );
2722     if( ! xBCooSysCnt.is())
2723         return;
2724     Reference< chart2::XChartDocument > xNewDoc( mrExport.GetModel(), uno::UNO_QUERY );
2725 
2726     OUString aFirstXDomainRange;
2727     OUString aFirstYDomainRange;
2728 
2729 	std::vector< XMLPropertyState > aPropertyStates;
2730 
2731     const OUString sNumFormat( OUString::createFromAscii( "NumberFormat" ));
2732     const OUString sPercentageNumFormat( OUString::createFromAscii( "PercentageNumberFormat" ));
2733 
2734     Sequence< Reference< chart2::XCoordinateSystem > >
2735         aCooSysSeq( xBCooSysCnt->getCoordinateSystems());
2736     for( sal_Int32 nCSIdx=0; nCSIdx<aCooSysSeq.getLength(); ++nCSIdx )
2737     {
2738         Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCSIdx], uno::UNO_QUERY );
2739         if( ! xCTCnt.is())
2740             continue;
2741         Sequence< Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes());
2742         for( sal_Int32 nCTIdx=0; nCTIdx<aCTSeq.getLength(); ++nCTIdx )
2743         {
2744             Reference< chart2::XDataSeriesContainer > xDSCnt( aCTSeq[nCTIdx], uno::UNO_QUERY );
2745             if( ! xDSCnt.is())
2746                 continue;
2747             // note: if xDSCnt.is() then also aCTSeq[nCTIdx]
2748             OUString aChartType( aCTSeq[nCTIdx]->getChartType());
2749             OUString aLabelRole = aCTSeq[nCTIdx]->getRoleOfSequenceForSeriesLabel();
2750 
2751             // special export for stock charts
2752             if( aChartType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.CandleStickChartType")))
2753             {
2754                 sal_Bool bJapaneseCandleSticks = sal_False;
2755                 Reference< beans::XPropertySet > xCTProp( aCTSeq[nCTIdx], uno::UNO_QUERY );
2756                 if( xCTProp.is())
2757                     xCTProp->getPropertyValue( OUString::createFromAscii("Japanese")) >>= bJapaneseCandleSticks;
2758                 exportCandleStickSeries(
2759                     xDSCnt->getDataSeries(), xNewDiagram, bJapaneseCandleSticks, bExportContent );
2760                 continue;
2761             }
2762 
2763             // export dataseries for current chart-type
2764             Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries());
2765             for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
2766             {
2767                 // export series
2768                 Reference< chart2::data::XDataSource > xSource( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY );
2769                 if( xSource.is())
2770                 {
2771                     SvXMLElementExport* pSeries = NULL;
2772                     Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
2773                         xSource->getDataSequences());
2774                     sal_Int32 nMainSequenceIndex = -1;
2775                     sal_Int32 nSeriesLength = 0;
2776                     sal_Int32 nAttachedAxis = chart::ChartAxisAssign::PRIMARY_Y;
2777                     sal_Bool bHasMeanValueLine = false;
2778                     chart::ChartRegressionCurveType eRegressionType( chart::ChartRegressionCurveType_NONE );
2779                     chart::ChartErrorIndicatorType eErrorType( chart::ChartErrorIndicatorType_NONE );
2780                     sal_Int32 nErrorBarStyle( chart::ErrorBarStyle::NONE );
2781                     Reference< beans::XPropertySet > xPropSet;
2782                     tLabelValuesDataPair aSeriesLabelValuesPair;
2783 
2784                     // search for main sequence and create a series element
2785                     {
2786                         Reference< chart2::data::XDataSequence > xValuesSeq;
2787                         Reference< chart2::data::XDataSequence > xLabelSeq;
2788                         sal_Int32 nSeqIdx=0;
2789                         for( ; nSeqIdx<aSeqCnt.getLength(); ++nSeqIdx )
2790                         {
2791                             OUString aRole;
2792                             Reference< chart2::data::XDataSequence > xTempValueSeq( aSeqCnt[nSeqIdx]->getValues() );
2793                             if( nMainSequenceIndex==-1 )
2794                             {
2795                                 Reference< beans::XPropertySet > xSeqProp( xTempValueSeq, uno::UNO_QUERY );
2796                                 if( xSeqProp.is())
2797                                     xSeqProp->getPropertyValue(OUString::createFromAscii("Role")) >>= aRole;
2798                                 // "main" sequence
2799                                 if( aRole.equals( aLabelRole ))
2800                                 {
2801                                     xValuesSeq.set( xTempValueSeq );
2802                                     xLabelSeq.set( aSeqCnt[nSeqIdx]->getLabel());
2803                                     nMainSequenceIndex = nSeqIdx;
2804                                 }
2805                             }
2806                             sal_Int32 nSequenceLength = (xTempValueSeq.is()? xTempValueSeq->getData().getLength() : sal_Int32(0));
2807                             if( nSeriesLength < nSequenceLength )
2808                                 nSeriesLength = nSequenceLength;
2809                         }
2810 
2811                         // have found the main sequence, then xValuesSeq and
2812                         // xLabelSeq contain those.  Otherwise both are empty
2813                         {
2814                             // get property states for autostyles
2815                             try
2816                             {
2817                                 xPropSet = SchXMLSeriesHelper::createOldAPISeriesPropertySet(
2818                                     aSeriesSeq[nSeriesIdx], mrExport.GetModel() );
2819                             }
2820                             catch( uno::Exception & rEx )
2821                             {
2822                                 (void)rEx; // avoid warning for pro build
2823                                 OSL_TRACE(
2824                                     OUStringToOString(
2825                                         OUString( RTL_CONSTASCII_USTRINGPARAM(
2826                                                       "Series not found or no XPropertySet: " )) +
2827                                         rEx.Message,
2828                                         RTL_TEXTENCODING_ASCII_US ).getStr());
2829                                 continue;
2830                             }
2831                             if( xPropSet.is())
2832                             {
2833                                 // determine attached axis
2834                                 try
2835                                 {
2836                                     Any aAny( xPropSet->getPropertyValue(
2837                                                   OUString( RTL_CONSTASCII_USTRINGPARAM( "Axis" ))));
2838                                     aAny >>= nAttachedAxis;
2839 
2840                                     aAny = xPropSet->getPropertyValue(
2841                                         OUString( RTL_CONSTASCII_USTRINGPARAM ( "MeanValue" )));
2842                                     aAny >>= bHasMeanValueLine;
2843 
2844                                     aAny = xPropSet->getPropertyValue(
2845                                         OUString( RTL_CONSTASCII_USTRINGPARAM( "RegressionCurves" )));
2846                                     aAny >>= eRegressionType;
2847 
2848                                     aAny = xPropSet->getPropertyValue(
2849                                         OUString( RTL_CONSTASCII_USTRINGPARAM( "ErrorIndicator" )));
2850                                     aAny >>= eErrorType;
2851 
2852                                     aAny = xPropSet->getPropertyValue(
2853                                         OUString( RTL_CONSTASCII_USTRINGPARAM( "ErrorBarStyle" )));
2854                                     aAny >>= nErrorBarStyle;
2855                                 }
2856                                 catch( beans::UnknownPropertyException & rEx )
2857                                 {
2858                                     (void)rEx; // avoid warning for pro build
2859                                     OSL_TRACE(
2860                                         OUStringToOString(
2861                                             OUString( RTL_CONSTASCII_USTRINGPARAM(
2862                                                           "Required property not found in DataRowProperties: " )) +
2863                                             rEx.Message,
2864                                             RTL_TEXTENCODING_ASCII_US ).getStr());
2865                                 }
2866 
2867                                 const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2868                                 if( nCurrentODFVersion >= SvtSaveOptions::ODFVER_012 )
2869                                 {
2870                                     lcl_exportNumberFormat( sNumFormat, xPropSet, mrExport );
2871                                     lcl_exportNumberFormat( sPercentageNumFormat, xPropSet, mrExport );
2872                                 }
2873 
2874                                 if( mxExpPropMapper.is())
2875                                     aPropertyStates = mxExpPropMapper->Filter( xPropSet );
2876                             }
2877 
2878                             if( bExportContent )
2879                             {
2880                                 if( bHasTwoYAxes )
2881                                 {
2882                                     if( nAttachedAxis == chart::ChartAxisAssign::SECONDARY_Y )
2883                                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_SECONDARY_Y );
2884                                     else
2885                                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_PRIMARY_Y );
2886                                 }
2887 
2888                                 // write style name
2889                                 AddAutoStyleAttribute( aPropertyStates );
2890 
2891                                 if( xValuesSeq.is())
2892                                     mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_VALUES_CELL_RANGE_ADDRESS,
2893                                                            lcl_ConvertRange(
2894                                                                xValuesSeq->getSourceRangeRepresentation(),
2895                                                                xNewDoc ));
2896                                 else
2897                                     // #i75297# allow empty series, export empty range to have all ranges on import
2898                                     mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_VALUES_CELL_RANGE_ADDRESS, OUString());
2899 
2900                                 if( xLabelSeq.is())
2901                                     mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_LABEL_CELL_ADDRESS,
2902                                                            lcl_ConvertRange(
2903                                                                xLabelSeq->getSourceRangeRepresentation(),
2904                                                                xNewDoc ));
2905                                 if( xLabelSeq.is() || xValuesSeq.is() )
2906                                     aSeriesLabelValuesPair = tLabelValuesDataPair( xLabelSeq, xValuesSeq );
2907 
2908                                 // chart-type for mixed types
2909                                 enum XMLTokenEnum eCTToken(
2910                                     SchXMLTools::getTokenByChartType( aChartType, false /* bUseOldNames */ ));
2911                                 //@todo: get token for current charttype
2912                                 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS,
2913                                                        mrExport.GetNamespaceMap().GetQNameByKey(
2914                                                            XML_NAMESPACE_CHART, GetXMLToken( eCTToken )));
2915 
2916                                 // open series element until end of for loop
2917                                 pSeries = new SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_SERIES, sal_True, sal_True );
2918                             }
2919                             else	// autostyles
2920                             {
2921                                 CollectAutoStyle( aPropertyStates );
2922                             }
2923                             // remove property states for autostyles
2924                             aPropertyStates.clear();
2925                         }
2926                     }
2927 
2928                     // export domain elements if we have a series parent element
2929                     if( pSeries )
2930                     {
2931                         // domain elements
2932                         if( bExportContent )
2933                         {
2934                             bool bIsScatterChart = aChartType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.ScatterChartType"));
2935                             bool bIsBubbleChart = aChartType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.BubbleChartType"));
2936                             Reference< chart2::data::XDataSequence > xYValuesForBubbleChart;
2937                             if( bIsBubbleChart )
2938                             {
2939                                 Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString::createFromAscii("values-y" ) ) );
2940                                 if( xSequence.is() )
2941                                 {
2942                                     xYValuesForBubbleChart = xSequence->getValues();
2943                                     if( !lcl_exportDomainForThisSequence( xYValuesForBubbleChart, aFirstYDomainRange, mrExport ) )
2944                                         xYValuesForBubbleChart = 0;
2945                                 }
2946                             }
2947                             if( bIsScatterChart || bIsBubbleChart )
2948                             {
2949                                 Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString::createFromAscii("values-x" ) ) );
2950                                 if( xSequence.is() )
2951                                 {
2952                                     Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() );
2953                                     if( lcl_exportDomainForThisSequence( xValues, aFirstXDomainRange, mrExport ) )
2954                                         m_aDataSequencesToExport.push_back( tLabelValuesDataPair( 0, xValues ));
2955                                 }
2956                                 else if( nSeriesIdx==0 )
2957                                 {
2958                                     //might be that the categories are used as x-values (e.g. for date axis) -> export them accordingly
2959                                     Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xNewDiagram ) );
2960                                     if( xCategories.is() )
2961                                     {
2962                                         Reference< chart2::data::XDataSequence > xValues( xCategories->getValues() );
2963                                         if( !lcl_hasNoValuesButText( xValues ) )
2964                                             lcl_exportDomainForThisSequence( xValues, aFirstXDomainRange, mrExport );
2965                                     }
2966                                 }
2967                             }
2968                             if( xYValuesForBubbleChart.is() )
2969                                 m_aDataSequencesToExport.push_back( tLabelValuesDataPair( 0, xYValuesForBubbleChart ));
2970                         }
2971                     }
2972 
2973                     // add sequences for main sequence after domain sequences,
2974                     // so that the export of the local table has the correct order
2975                     if( bExportContent &&
2976                         (aSeriesLabelValuesPair.first.is() || aSeriesLabelValuesPair.second.is()))
2977                         m_aDataSequencesToExport.push_back( aSeriesLabelValuesPair );
2978 
2979                     // statistical objects:
2980                     // regression curves and mean value lines
2981                     if( bHasMeanValueLine &&
2982                         xPropSet.is() &&
2983                         mxExpPropMapper.is() )
2984                     {
2985                         Reference< beans::XPropertySet > xStatProp;
2986                         try
2987                         {
2988                             Any aPropAny( xPropSet->getPropertyValue(
2989                                             OUString( RTL_CONSTASCII_USTRINGPARAM( "DataMeanValueProperties" ))));
2990                             aPropAny >>= xStatProp;
2991                         }
2992                         catch( uno::Exception & rEx )
2993                         {
2994                             (void)rEx; // avoid warning for pro build
2995                             DBG_ERROR1( "Exception caught during Export of series - optional DataMeanValueProperties not available: %s",
2996                                         OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
2997                         }
2998 
2999                         if( xStatProp.is() )
3000                         {
3001                             aPropertyStates = mxExpPropMapper->Filter( xStatProp );
3002 
3003                             if( !aPropertyStates.empty() )
3004                             {
3005                                 // write element
3006                                 if( bExportContent )
3007                                 {
3008                                     // add style name attribute
3009                                     AddAutoStyleAttribute( aPropertyStates );
3010 
3011                                     SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_MEAN_VALUE, sal_True, sal_True );
3012                                 }
3013                                 else	// autostyles
3014                                 {
3015                                     CollectAutoStyle( aPropertyStates );
3016                                 }
3017                             }
3018                         }
3019                     }
3020 
3021                     if( eRegressionType != chart::ChartRegressionCurveType_NONE &&
3022                         xPropSet.is() &&
3023                         mxExpPropMapper.is() )
3024                     {
3025                         exportRegressionCurve( aSeriesSeq[nSeriesIdx], xPropSet, rPageSize, bExportContent );
3026                     }
3027 
3028                     if( nErrorBarStyle != chart::ErrorBarStyle::NONE &&
3029                         eErrorType != chart::ChartErrorIndicatorType_NONE &&
3030                         xPropSet.is() &&
3031                         mxExpPropMapper.is() )
3032                     {
3033                         Reference< beans::XPropertySet > xStatProp;
3034                         try
3035                         {
3036                             Any aPropAny( xPropSet->getPropertyValue(
3037                                             OUString( RTL_CONSTASCII_USTRINGPARAM( "DataErrorProperties" ))));
3038                             aPropAny >>= xStatProp;
3039                         }
3040                         catch( uno::Exception & rEx )
3041                         {
3042                             (void)rEx; // avoid warning for pro build
3043                             DBG_ERROR1( "Exception caught during Export of series - optional DataErrorProperties not available: %s",
3044                                         OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
3045                         }
3046 
3047                         if( xStatProp.is() )
3048                         {
3049                             if( bExportContent &&
3050                                 nErrorBarStyle == chart::ErrorBarStyle::FROM_DATA )
3051                             {
3052                                 // register data ranges for error bars for export in local table
3053                                 ::std::vector< Reference< chart2::data::XDataSequence > > aErrorBarSequences(
3054                                     lcl_getErrorBarSequences( xStatProp ));
3055                                 for( ::std::vector< Reference< chart2::data::XDataSequence > >::const_iterator aIt(
3056                                          aErrorBarSequences.begin()); aIt != aErrorBarSequences.end(); ++aIt )
3057                                 {
3058                                     m_aDataSequencesToExport.push_back( tLabelValuesDataPair( 0, *aIt ));
3059                                 }
3060                             }
3061 
3062                             aPropertyStates = mxExpPropMapper->Filter( xStatProp );
3063 
3064                             if( !aPropertyStates.empty() )
3065                             {
3066                                 // write element
3067                                 if( bExportContent )
3068                                 {
3069                                     // add style name attribute
3070                                     AddAutoStyleAttribute( aPropertyStates );
3071 
3072                                     const SvtSaveOptions::ODFDefaultVersion nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
3073                                     if( nCurrentVersion >= SvtSaveOptions::ODFVER_012 )
3074                                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_DIMENSION, XML_Y );//#i114149#
3075                                     SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_ERROR_INDICATOR, sal_True, sal_True );
3076                                 }
3077                                 else	// autostyles
3078                                 {
3079                                     CollectAutoStyle( aPropertyStates );
3080                                 }
3081                             }
3082                         }
3083                     }
3084 
3085                     exportDataPoints(
3086                         uno::Reference< beans::XPropertySet >( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY ),
3087                         nSeriesLength, xNewDiagram, bExportContent );
3088 
3089                     // close series element
3090                     if( pSeries )
3091                         delete pSeries;
3092                 }
3093             }
3094             aPropertyStates.clear();
3095         }
3096     }
3097 }
3098 
3099 void SchXMLExportHelper_Impl::exportRegressionCurve(
3100     const Reference< chart2::XDataSeries > & xSeries,
3101     const Reference< beans::XPropertySet > & xSeriesProp,
3102     const awt::Size & rPageSize,
3103     sal_Bool bExportContent )
3104 {
3105     OSL_ASSERT( mxExpPropMapper.is());
3106 
3107 	std::vector< XMLPropertyState > aPropertyStates;
3108 	std::vector< XMLPropertyState > aEquationPropertyStates;
3109     Reference< beans::XPropertySet > xStatProp;
3110     try
3111     {
3112         Any aPropAny( xSeriesProp->getPropertyValue(
3113                           OUString( RTL_CONSTASCII_USTRINGPARAM( "DataRegressionProperties" ))));
3114         aPropAny >>= xStatProp;
3115     }
3116     catch( uno::Exception & rEx )
3117     {
3118         (void)rEx; // avoid warning for pro build
3119         DBG_ERROR1( "Exception caught during Export of series - optional DataRegressionProperties not available: %s",
3120                     OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
3121     }
3122 
3123     if( xStatProp.is() )
3124     {
3125         Reference< chart2::XRegressionCurve > xRegCurve( SchXMLTools::getRegressionCurve( xSeries ));
3126         Reference< beans::XPropertySet > xEquationProperties;
3127         if( xRegCurve.is())
3128             xEquationProperties.set( xRegCurve->getEquationProperties());
3129 
3130         bool bShowEquation = false;
3131         bool bShowRSquared = false;
3132         bool bExportEquation = false;
3133         aPropertyStates = mxExpPropMapper->Filter( xStatProp );
3134         if( xEquationProperties.is())
3135         {
3136             xEquationProperties->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "ShowEquation" )))
3137                 >>= bShowEquation;
3138             xEquationProperties->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "ShowCorrelationCoefficient" )))
3139                 >>= bShowRSquared;
3140             bExportEquation = ( bShowEquation || bShowRSquared );
3141             const SvtSaveOptions::ODFDefaultVersion nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
3142             if( nCurrentVersion < SvtSaveOptions::ODFVER_012 )
3143                 bExportEquation=false;
3144             if( bExportEquation )
3145             {
3146                 // number format
3147                 sal_Int32 nNumberFormat = 0;
3148                 if( ( xEquationProperties->getPropertyValue(
3149                           OUString( RTL_CONSTASCII_USTRINGPARAM( "NumberFormat" ))) >>= nNumberFormat ) &&
3150                     nNumberFormat != -1 )
3151                 {
3152                     mrExport.addDataStyle( nNumberFormat );
3153                 }
3154                 aEquationPropertyStates = mxExpPropMapper->Filter( xEquationProperties );
3155             }
3156         }
3157 
3158         if( !aPropertyStates.empty() || bExportEquation )
3159         {
3160             // write element
3161             if( bExportContent )
3162             {
3163                 // add style name attribute
3164                 if( !aPropertyStates.empty())
3165                     AddAutoStyleAttribute( aPropertyStates );
3166                 SvXMLElementExport aRegressionExport( mrExport, XML_NAMESPACE_CHART, XML_REGRESSION_CURVE, sal_True, sal_True );
3167                 if( bExportEquation )
3168                 {
3169                     // default is true
3170                     if( !bShowEquation )
3171                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_DISPLAY_EQUATION, XML_FALSE );
3172                     // default is false
3173                     if( bShowRSquared )
3174                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_DISPLAY_R_SQUARE, XML_TRUE );
3175 
3176                     // export position
3177                     chart2::RelativePosition aRelativePosition;
3178                     if( xEquationProperties->getPropertyValue(
3179                             OUString( RTL_CONSTASCII_USTRINGPARAM("RelativePosition"))) >>= aRelativePosition )
3180                     {
3181                         double fX = aRelativePosition.Primary * rPageSize.Width;
3182                         double fY = aRelativePosition.Secondary * rPageSize.Height;
3183                         awt::Point aPos;
3184                         aPos.X = static_cast< sal_Int32 >( ::rtl::math::round( fX ));
3185                         aPos.Y = static_cast< sal_Int32 >( ::rtl::math::round( fY ));
3186                         addPosition( aPos );
3187                     }
3188 
3189                     if( !aEquationPropertyStates.empty())
3190                         AddAutoStyleAttribute( aEquationPropertyStates );
3191 
3192                     SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_EQUATION, sal_True, sal_True );
3193                 }
3194             }
3195             else	// autostyles
3196             {
3197                 if( !aPropertyStates.empty())
3198                     CollectAutoStyle( aPropertyStates );
3199                 if( bExportEquation && !aEquationPropertyStates.empty())
3200                     CollectAutoStyle( aEquationPropertyStates );
3201             }
3202         }
3203     }
3204 }
3205 
3206 void SchXMLExportHelper_Impl::exportCandleStickSeries(
3207     const Sequence< Reference< chart2::XDataSeries > > & aSeriesSeq,
3208     const Reference< chart2::XDiagram > & xDiagram,
3209     sal_Bool bJapaneseCandleSticks,
3210     sal_Bool bExportContent )
3211 {
3212 // 	std::vector< XMLPropertyState > aPropertyStates;
3213 
3214     for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
3215     {
3216         Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nSeriesIdx] );
3217         sal_Int32 nAttachedAxis = lcl_isSeriesAttachedToFirstAxis( xSeries )
3218             ? chart::ChartAxisAssign::PRIMARY_Y
3219             : chart::ChartAxisAssign::SECONDARY_Y;
3220 
3221         Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
3222         if( xSource.is())
3223         {
3224             // export series in correct order (as we don't store roles)
3225             // with japanese candlesticks: open, low, high, close
3226             // otherwise: low, high, close
3227             Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
3228                 xSource->getDataSequences());
3229 
3230             sal_Int32 nSeriesLength =
3231                 lcl_getSequenceLengthByRole( aSeqCnt, OUString::createFromAscii("values-last"));
3232 
3233             if( bExportContent )
3234             {
3235                 Reference< chart2::XChartDocument > xNewDoc( mrExport.GetModel(), uno::UNO_QUERY );
3236                 //@todo: export data points
3237 
3238                 // open
3239                 if( bJapaneseCandleSticks )
3240                 {
3241                     tLabelAndValueRange aRanges( lcl_getLabelAndValueRangeByRole(
3242                         aSeqCnt, OUString::createFromAscii("values-first"),  xNewDoc, m_aDataSequencesToExport ));
3243                     if( aRanges.second.getLength())
3244                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_VALUES_CELL_RANGE_ADDRESS, aRanges.second );
3245                     if( aRanges.first.getLength())
3246                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_LABEL_CELL_ADDRESS, aRanges.first );
3247                     if( nAttachedAxis == chart::ChartAxisAssign::SECONDARY_Y )
3248                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_SECONDARY_Y );
3249                     else
3250                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_PRIMARY_Y );
3251                     SvXMLElementExport aOpenSeries( mrExport, XML_NAMESPACE_CHART, XML_SERIES, sal_True, sal_True );
3252                     // export empty data points
3253                     exportDataPoints( 0, nSeriesLength, xDiagram, bExportContent );
3254                 }
3255 
3256                 // low
3257                 {
3258                     tLabelAndValueRange aRanges( lcl_getLabelAndValueRangeByRole(
3259                         aSeqCnt, OUString::createFromAscii("values-min"),  xNewDoc, m_aDataSequencesToExport ));
3260                     if( aRanges.second.getLength())
3261                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_VALUES_CELL_RANGE_ADDRESS, aRanges.second );
3262                     if( aRanges.first.getLength())
3263                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_LABEL_CELL_ADDRESS, aRanges.first );
3264                     if( nAttachedAxis == chart::ChartAxisAssign::SECONDARY_Y )
3265                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_SECONDARY_Y );
3266                     else
3267                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_PRIMARY_Y );
3268                     SvXMLElementExport aLowSeries( mrExport, XML_NAMESPACE_CHART, XML_SERIES, sal_True, sal_True );
3269                     // export empty data points
3270                     exportDataPoints( 0, nSeriesLength, xDiagram, bExportContent );
3271                 }
3272 
3273                 // high
3274                 {
3275                     tLabelAndValueRange aRanges( lcl_getLabelAndValueRangeByRole(
3276                         aSeqCnt, OUString::createFromAscii("values-max"),  xNewDoc, m_aDataSequencesToExport ));
3277                     if( aRanges.second.getLength())
3278                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_VALUES_CELL_RANGE_ADDRESS, aRanges.second );
3279                     if( aRanges.first.getLength())
3280                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_LABEL_CELL_ADDRESS, aRanges.first );
3281                     if( nAttachedAxis == chart::ChartAxisAssign::SECONDARY_Y )
3282                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_SECONDARY_Y );
3283                     else
3284                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_PRIMARY_Y );
3285                     SvXMLElementExport aHighSeries( mrExport, XML_NAMESPACE_CHART, XML_SERIES, sal_True, sal_True );
3286                     // export empty data points
3287                     exportDataPoints( 0, nSeriesLength, xDiagram, bExportContent );
3288                 }
3289 
3290                 // close
3291                 {
3292                     tLabelAndValueRange aRanges( lcl_getLabelAndValueRangeByRole(
3293                         aSeqCnt, OUString::createFromAscii("values-last"),  xNewDoc, m_aDataSequencesToExport ));
3294                     if( aRanges.second.getLength())
3295                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_VALUES_CELL_RANGE_ADDRESS, aRanges.second );
3296                     if( aRanges.first.getLength())
3297                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_LABEL_CELL_ADDRESS, aRanges.first );
3298                     if( nAttachedAxis == chart::ChartAxisAssign::SECONDARY_Y )
3299                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_SECONDARY_Y );
3300                     else
3301                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_PRIMARY_Y );
3302                     // write style name
3303 //                     AddAutoStyleAttribute( aPropertyStates );
3304                     // chart type
3305 //                     mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS,
3306 //                                            mrExport.GetNamespaceMap().GetQNameByKey(
3307 //                                                XML_NAMESPACE_CHART, GetXMLToken( XML_STOCK )));
3308                     SvXMLElementExport aCloseSeries( mrExport, XML_NAMESPACE_CHART, XML_SERIES, sal_True, sal_True );
3309                     // export empty data points
3310                     exportDataPoints( 0, nSeriesLength, xDiagram, bExportContent );
3311                 }
3312             }
3313             else	// autostyles
3314             {
3315                 // for close series
3316 //                 CollectAutoStyle( aPropertyStates );
3317             }
3318             // remove property states for autostyles
3319 //             aPropertyStates.clear();
3320         }
3321     }
3322 }
3323 
3324 void SchXMLExportHelper_Impl::exportDataPoints(
3325     const uno::Reference< beans::XPropertySet > & xSeriesProperties,
3326     sal_Int32 nSeriesLength,
3327     const uno::Reference< chart2::XDiagram > & xDiagram,
3328     sal_Bool bExportContent )
3329 {
3330     // data-points
3331     // -----------
3332     // write data-points only if they contain autostyles
3333     // objects with equal autostyles are grouped using the attribute
3334     // repeat="number"
3335 
3336     // Note: if only the nth data-point has autostyles there is an element
3337     // without style and repeat="n-1" attribute written in advance.
3338 
3339     // the sequence aDataPointSeq contains indices of data-points that
3340     // do have own attributes.  This increases the performance substantially.
3341 
3342     // more performant version for #93600#
3343     if( mxExpPropMapper.is())
3344     {
3345         uno::Reference< chart2::XDataSeries > xSeries( xSeriesProperties, uno::UNO_QUERY );
3346 
3347         std::vector< XMLPropertyState > aPropertyStates;
3348 
3349         const OUString sNumFormat( OUString::createFromAscii( "NumberFormat" ));
3350         const OUString sPercentageNumFormat( OUString::createFromAscii( "PercentageNumberFormat" ));
3351 
3352         bool bVaryColorsByPoint = false;
3353         Sequence< sal_Int32 > aDataPointSeq;
3354         if( xSeriesProperties.is())
3355         {
3356             Any aAny = xSeriesProperties->getPropertyValue(
3357                 OUString( RTL_CONSTASCII_USTRINGPARAM( "AttributedDataPoints" )));
3358             aAny >>= aDataPointSeq;
3359             xSeriesProperties->getPropertyValue(
3360                 OUString( RTL_CONSTASCII_USTRINGPARAM( "VaryColorsByPoint" ))) >>= bVaryColorsByPoint;
3361         }
3362 
3363 
3364         sal_Int32 nSize = aDataPointSeq.getLength();
3365         DBG_ASSERT( nSize <= nSeriesLength, "Too many point attributes" );
3366 
3367         const sal_Int32 * pPoints = aDataPointSeq.getConstArray();
3368         sal_Int32 nElement;
3369         sal_Int32 nRepeat;
3370         Reference< chart2::XColorScheme > xColorScheme;
3371         if( xDiagram.is())
3372             xColorScheme.set( xDiagram->getDefaultColorScheme());
3373 
3374         ::std::list< SchXMLDataPointStruct > aDataPointList;
3375 
3376         sal_Int32 nLastIndex = -1;
3377         sal_Int32 nCurrIndex = 0;
3378 
3379         // collect elements
3380         if( bVaryColorsByPoint && xColorScheme.is() )
3381         {
3382             ::std::set< sal_Int32 > aAttrPointSet;
3383             ::std::copy( pPoints, pPoints + aDataPointSeq.getLength(),
3384                             ::std::inserter( aAttrPointSet, aAttrPointSet.begin()));
3385             const ::std::set< sal_Int32 >::const_iterator aEndIt( aAttrPointSet.end());
3386             for( nElement = 0; nElement < nSeriesLength; ++nElement )
3387             {
3388                 aPropertyStates.clear();
3389                 uno::Reference< beans::XPropertySet > xPropSet;
3390                 bool bExportNumFmt = false;
3391                 if( aAttrPointSet.find( nElement ) != aEndIt )
3392                 {
3393                     try
3394                     {
3395                         xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
3396                                     xSeries, nElement, mrExport.GetModel() );
3397                         bExportNumFmt = true;
3398                     }
3399                     catch( uno::Exception & rEx )
3400                     {
3401                         (void)rEx; // avoid warning for pro build
3402                         DBG_ERROR1( "Exception caught during Export of data point: %s",
3403                                     OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
3404                     }
3405                 }
3406                 else
3407                 {
3408                     // property set only containing the color
3409                     xPropSet.set( new ::xmloff::chart::ColorPropertySet(
3410                                         xColorScheme->getColorByIndex( nElement )));
3411                 }
3412                 DBG_ASSERT( xPropSet.is(), "Pie Segments should have properties" );
3413                 if( xPropSet.is())
3414                 {
3415                     const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
3416                     if( nCurrentODFVersion >= SvtSaveOptions::ODFVER_012 && bExportNumFmt )
3417                     {
3418                         lcl_exportNumberFormat( sNumFormat, xPropSet, mrExport );
3419                         lcl_exportNumberFormat( sPercentageNumFormat, xPropSet, mrExport );
3420                     }
3421 
3422                     aPropertyStates = mxExpPropMapper->Filter( xPropSet );
3423                     if( !aPropertyStates.empty() )
3424                     {
3425                         if( bExportContent )
3426                         {
3427                             // write data-point with style
3428                             DBG_ASSERT( ! maAutoStyleNameQueue.empty(), "Autostyle queue empty!" );
3429 
3430                             SchXMLDataPointStruct aPoint;
3431                             aPoint.maStyleName = maAutoStyleNameQueue.front();
3432                             maAutoStyleNameQueue.pop();
3433                             aDataPointList.push_back( aPoint );
3434                         }
3435                         else
3436                         {
3437                             CollectAutoStyle( aPropertyStates );
3438                         }
3439                     }
3440                 }
3441             }
3442             DBG_ASSERT( !bExportContent || (static_cast<sal_Int32>(aDataPointList.size()) == nSeriesLength),
3443                         "not enough data points on content export" );
3444         }
3445         else
3446         {
3447             for( nElement = 0; nElement < nSize; ++nElement )
3448             {
3449                 aPropertyStates.clear();
3450                 nCurrIndex = pPoints[ nElement ];
3451                 //assuming sorted indices in pPoints
3452 
3453                 if( nCurrIndex<0 || nCurrIndex>=nSeriesLength )
3454                     break;
3455 
3456                 // write leading empty data points
3457                 if( nCurrIndex - nLastIndex > 1 )
3458                 {
3459                     SchXMLDataPointStruct aPoint;
3460                     aPoint.mnRepeat = nCurrIndex - nLastIndex - 1;
3461                     aDataPointList.push_back( aPoint );
3462                 }
3463 
3464                 uno::Reference< beans::XPropertySet > xPropSet;
3465                 // get property states
3466                 try
3467                 {
3468                     xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
3469                                     xSeries, nCurrIndex, mrExport.GetModel() );
3470                 }
3471                 catch( uno::Exception & rEx )
3472                 {
3473                     (void)rEx; // avoid warning for pro build
3474                     DBG_ERROR1( "Exception caught during Export of data point: %s",
3475                                 OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
3476                 }
3477                 if( xPropSet.is())
3478                 {
3479                     const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
3480                     if( nCurrentODFVersion >= SvtSaveOptions::ODFVER_012 )
3481                     {
3482                         lcl_exportNumberFormat( sNumFormat, xPropSet, mrExport );
3483                         lcl_exportNumberFormat( sPercentageNumFormat, xPropSet, mrExport );
3484                     }
3485 
3486                     aPropertyStates = mxExpPropMapper->Filter( xPropSet );
3487                     if( !aPropertyStates.empty() )
3488                     {
3489                         if( bExportContent )
3490                         {
3491                             // write data-point with style
3492                             DBG_ASSERT( ! maAutoStyleNameQueue.empty(), "Autostyle queue empty!" );
3493                             SchXMLDataPointStruct aPoint;
3494                             aPoint.maStyleName = maAutoStyleNameQueue.front();
3495                             maAutoStyleNameQueue.pop();
3496 
3497                             aDataPointList.push_back( aPoint );
3498                             nLastIndex = nCurrIndex;
3499                         }
3500                         else
3501                         {
3502                             CollectAutoStyle( aPropertyStates );
3503                         }
3504                         continue;
3505                     }
3506                 }
3507 
3508                 // if we get here the property states are empty
3509                 SchXMLDataPointStruct aPoint;
3510                 aDataPointList.push_back( aPoint );
3511 
3512                 nLastIndex = nCurrIndex;
3513             }
3514             // final empty elements
3515             nRepeat = nSeriesLength - nLastIndex - 1;
3516             if( nRepeat > 0 )
3517             {
3518                 SchXMLDataPointStruct aPoint;
3519                 aPoint.mnRepeat = nRepeat;
3520                 aDataPointList.push_back( aPoint );
3521             }
3522         }
3523 
3524         if( bExportContent )
3525         {
3526             // write elements (merge equal ones)
3527             ::std::list< SchXMLDataPointStruct >::iterator aIter = aDataPointList.begin();
3528             SchXMLDataPointStruct aPoint;
3529             SchXMLDataPointStruct aLastPoint;
3530 
3531             // initialize so that it doesn't matter if
3532             // the element is counted in the first iteration
3533             aLastPoint.mnRepeat = 0;
3534 
3535             for( ; aIter != aDataPointList.end(); ++aIter )
3536             {
3537                 aPoint = (*aIter);
3538 
3539                 if( aPoint.maStyleName == aLastPoint.maStyleName )
3540                     aPoint.mnRepeat += aLastPoint.mnRepeat;
3541                 else if( aLastPoint.mnRepeat > 0 )
3542                 {
3543                     // write last element
3544                     if( aLastPoint.maStyleName.getLength() )
3545                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_STYLE_NAME, aLastPoint.maStyleName );
3546 
3547                     if( aLastPoint.mnRepeat > 1 )
3548                         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_REPEATED,
3549                                             OUString::valueOf( (sal_Int64)( aLastPoint.mnRepeat ) ));
3550 
3551                     SvXMLElementExport aPointElem( mrExport, XML_NAMESPACE_CHART, XML_DATA_POINT, sal_True, sal_True );
3552                 }
3553                 aLastPoint = aPoint;
3554             }
3555             // write last element if it hasn't been written in last iteration
3556             if( aPoint.maStyleName == aLastPoint.maStyleName )
3557             {
3558                 if( aLastPoint.maStyleName.getLength() )
3559                     mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_STYLE_NAME, aLastPoint.maStyleName );
3560 
3561                 if( aLastPoint.mnRepeat > 1 )
3562                     mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_REPEATED,
3563                                         OUString::valueOf( (sal_Int64)( aLastPoint.mnRepeat ) ));
3564 
3565                 SvXMLElementExport aPointElem( mrExport, XML_NAMESPACE_CHART, XML_DATA_POINT, sal_True, sal_True );
3566             }
3567         }
3568     }
3569 }
3570 
3571 
3572 void SchXMLExportHelper_Impl::getCellAddress( sal_Int32 nCol, sal_Int32 nRow )
3573 {
3574 	msStringBuffer.append( (sal_Unicode)'.' );
3575 	if( nCol < 26 )
3576 		msStringBuffer.append( (sal_Unicode)('A' + nCol) );
3577 	else if( nCol < 702 )
3578 	{
3579 		msStringBuffer.append( (sal_Unicode)('A' + nCol / 26 - 1 ));
3580 		msStringBuffer.append( (sal_Unicode)('A' + nCol % 26) );
3581 	}
3582 	else
3583 	{
3584 		msStringBuffer.append( (sal_Unicode)('A' + nCol / 702 - 1 ));
3585 		msStringBuffer.append( (sal_Unicode)('A' + (nCol % 702) / 26 ));
3586 		msStringBuffer.append( (sal_Unicode)('A' + nCol % 26) );
3587 	}
3588 
3589 	msStringBuffer.append( nRow + (sal_Int32)1 );
3590 }
3591 
3592 void SchXMLExportHelper_Impl::addPosition( const awt::Point & rPosition )
3593 {
3594     mrExport.GetMM100UnitConverter().convertMeasure( msStringBuffer, rPosition.X );
3595     msString = msStringBuffer.makeStringAndClear();
3596     mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X, msString );
3597 
3598     mrExport.GetMM100UnitConverter().convertMeasure( msStringBuffer, rPosition.Y );
3599     msString = msStringBuffer.makeStringAndClear();
3600     mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y, msString );
3601 }
3602 
3603 void SchXMLExportHelper_Impl::addPosition( Reference< drawing::XShape > xShape )
3604 {
3605 	if( xShape.is())
3606         addPosition( xShape->getPosition());
3607 }
3608 
3609 void SchXMLExportHelper_Impl::addSize( const awt::Size & rSize, bool bIsOOoNamespace)
3610 {
3611     mrExport.GetMM100UnitConverter().convertMeasure( msStringBuffer, rSize.Width );
3612     msString = msStringBuffer.makeStringAndClear();
3613     mrExport.AddAttribute( bIsOOoNamespace ? XML_NAMESPACE_CHART_EXT : XML_NAMESPACE_SVG , XML_WIDTH,  msString );
3614 
3615 
3616     mrExport.GetMM100UnitConverter().convertMeasure( msStringBuffer, rSize.Height);
3617     msString = msStringBuffer.makeStringAndClear();
3618     mrExport.AddAttribute( bIsOOoNamespace ? XML_NAMESPACE_CHART_EXT : XML_NAMESPACE_SVG, XML_HEIGHT, msString );
3619 }
3620 
3621 void SchXMLExportHelper_Impl::addSize( Reference< drawing::XShape > xShape, bool bIsOOoNamespace )
3622 {
3623 	if( xShape.is())
3624         addSize( xShape->getSize(), bIsOOoNamespace );
3625 }
3626 
3627 awt::Size SchXMLExportHelper_Impl::getPageSize( const Reference< chart2::XChartDocument > & xChartDoc ) const
3628 {
3629     awt::Size aSize( 8000, 7000 );
3630     uno::Reference< embed::XVisualObject > xVisualObject( xChartDoc, uno::UNO_QUERY );
3631     DBG_ASSERT( xVisualObject.is(),"need XVisualObject for page size" );
3632     if( xVisualObject.is() )
3633         aSize = xVisualObject->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
3634 
3635     return aSize;
3636 }
3637 
3638 void SchXMLExportHelper_Impl::CollectAutoStyle( const std::vector< XMLPropertyState >& aStates )
3639 {
3640     if( !aStates.empty() )
3641         maAutoStyleNameQueue.push( GetAutoStylePoolP().Add( XML_STYLE_FAMILY_SCH_CHART_ID, aStates ));
3642 }
3643 
3644 void SchXMLExportHelper_Impl::AddAutoStyleAttribute( const std::vector< XMLPropertyState >& aStates )
3645 {
3646     if( !aStates.empty() )
3647     {
3648         DBG_ASSERT( ! maAutoStyleNameQueue.empty(), "Autostyle queue empty!" );
3649 
3650         mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_STYLE_NAME,  maAutoStyleNameQueue.front() );
3651         maAutoStyleNameQueue.pop();
3652     }
3653 }
3654 
3655 void SchXMLExportHelper_Impl::exportText( const OUString& rText, bool bConvertTabsLFs )
3656 {
3657     SchXMLTools::exportText( mrExport, rText, bConvertTabsLFs );
3658 }
3659 
3660 // ========================================
3661 // class SchXMLExport
3662 // ========================================
3663 
3664 // #110680#
3665 SchXMLExport::SchXMLExport(
3666 	const Reference< lang::XMultiServiceFactory >& xServiceFactory,
3667 	sal_uInt16 nExportFlags )
3668 :	SvXMLExport( xServiceFactory, MAP_CM, ::xmloff::token::XML_CHART, nExportFlags ),
3669 	maAutoStylePool( *this ),
3670 	maExportHelper( *this, maAutoStylePool )
3671 {
3672     if( getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST )
3673         _GetNamespaceMap().Add( GetXMLToken(XML_NP_CHART_EXT), GetXMLToken(XML_N_CHART_EXT), XML_NAMESPACE_CHART_EXT);
3674 }
3675 
3676 
3677 SchXMLExport::~SchXMLExport()
3678 {
3679 	// stop progress view
3680 	if( mxStatusIndicator.is())
3681 	{
3682 		mxStatusIndicator->end();
3683 		mxStatusIndicator->reset();
3684 	}
3685 }
3686 
3687 sal_uInt32 SchXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum eClass )
3688 {
3689     Reference< chart2::XChartDocument > xChartDoc( GetModel(), uno::UNO_QUERY );
3690     maExportHelper.m_pImpl->InitRangeSegmentationProperties( xChartDoc );
3691     return SvXMLExport::exportDoc( eClass );
3692 }
3693 
3694 void SchXMLExport::_ExportStyles( sal_Bool bUsed )
3695 {
3696 	SvXMLExport::_ExportStyles( bUsed );
3697 }
3698 
3699 void SchXMLExport::_ExportMasterStyles()
3700 {
3701 	// not available in chart
3702 	DBG_WARNING( "Master Style Export requested. Not available for Chart" );
3703 }
3704 
3705 void SchXMLExport::_ExportAutoStyles()
3706 {
3707 	// there are no styles that require their own autostyles
3708 	if( getExportFlags() & EXPORT_CONTENT )
3709 	{
3710 		Reference< chart::XChartDocument > xChartDoc( GetModel(), uno::UNO_QUERY );
3711 		if( xChartDoc.is())
3712 		{
3713 			maExportHelper.m_pImpl->collectAutoStyles( xChartDoc );
3714 			maExportHelper.m_pImpl->exportAutoStyles();
3715 		}
3716 		else
3717 		{
3718 			DBG_ERROR( "Couldn't export chart due to wrong XModel (must be XChartDocument)" );
3719 		}
3720 	}
3721 }
3722 
3723 void SchXMLExport::_ExportContent()
3724 {
3725 	Reference< chart::XChartDocument > xChartDoc( GetModel(), uno::UNO_QUERY );
3726 	if( xChartDoc.is())
3727 	{
3728 		// determine if data comes from the outside
3729 		sal_Bool bIncludeTable = sal_True;
3730 
3731         Reference< chart2::XChartDocument > xNewDoc( xChartDoc, uno::UNO_QUERY );
3732         if( xNewDoc.is())
3733         {
3734             // check if we have own data.  If so we must not export the complete
3735             // range string, as this is our only indicator for having own or
3736             // external data. @todo: fix this in the file format!
3737             Reference< lang::XServiceInfo > xDPServiceInfo( xNewDoc->getDataProvider(), uno::UNO_QUERY );
3738             if( ! (xDPServiceInfo.is() &&
3739                    xDPServiceInfo->getImplementationName().equalsAsciiL(
3740                        RTL_CONSTASCII_STRINGPARAM( "com.sun.star.comp.chart.InternalDataProvider" ))))
3741             {
3742                 bIncludeTable = sal_False;
3743             }
3744         }
3745         else
3746         {
3747             Reference< lang::XServiceInfo > xServ( xChartDoc, uno::UNO_QUERY );
3748             if( xServ.is())
3749             {
3750                 if( xServ->supportsService(
3751                         OUString::createFromAscii( "com.sun.star.chart.ChartTableAddressSupplier" )))
3752                 {
3753                     Reference< beans::XPropertySet > xProp( xServ, uno::UNO_QUERY );
3754                     if( xProp.is())
3755                     {
3756                         Any aAny;
3757                         try
3758                         {
3759                             OUString sChartAddress;
3760                             aAny = xProp->getPropertyValue(
3761                                 OUString::createFromAscii( "ChartRangeAddress" ));
3762                             aAny >>= sChartAddress;
3763                             maExportHelper.m_pImpl->SetChartRangeAddress( sChartAddress );
3764 
3765                             OUString sTableNumberList;
3766                             aAny = xProp->getPropertyValue(
3767                                 OUString::createFromAscii( "TableNumberList" ));
3768                             aAny >>= sTableNumberList;
3769                             maExportHelper.m_pImpl->SetTableNumberList( sTableNumberList );
3770 
3771                             // do not include own table if there are external addresses
3772                             bIncludeTable = (sChartAddress.getLength() == 0);
3773                         }
3774                         catch( beans::UnknownPropertyException & )
3775                         {
3776                             DBG_ERROR( "Property ChartRangeAddress not supported by ChartDocument" );
3777                         }
3778                     }
3779                 }
3780             }
3781         }
3782         maExportHelper.m_pImpl->exportChart( xChartDoc, bIncludeTable );
3783 	}
3784 	else
3785 	{
3786 		DBG_ERROR( "Couldn't export chart due to wrong XModel" );
3787 	}
3788 }
3789 
3790 void SchXMLExport::SetProgress( sal_Int32 nPercentage )
3791 {
3792 	// set progress view
3793 	if( mxStatusIndicator.is())
3794 		mxStatusIndicator->setValue( nPercentage );
3795 }
3796 
3797 UniReference< XMLPropertySetMapper > SchXMLExport::GetPropertySetMapper() const
3798 {
3799     return maExportHelper.m_pImpl->GetPropertySetMapper();
3800 }
3801 
3802 void SchXMLExportHelper_Impl::InitRangeSegmentationProperties( const Reference< chart2::XChartDocument > & xChartDoc )
3803 {
3804     if( xChartDoc.is())
3805         try
3806         {
3807             Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
3808             OSL_ENSURE( xDataProvider.is(), "No DataProvider" );
3809             if( xDataProvider.is())
3810             {
3811                 Reference< chart2::data::XDataSource > xDataSource( lcl_pressUsedDataIntoRectangularFormat( xChartDoc, mbHasCategoryLabels ));
3812                 Sequence< beans::PropertyValue > aArgs( xDataProvider->detectArguments( xDataSource ));
3813                 ::rtl::OUString sCellRange, sBrokenRange;
3814                 bool bBrokenRangeAvailable = false;
3815                 for( sal_Int32 i=0; i<aArgs.getLength(); ++i )
3816                 {
3817                     if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CellRangeRepresentation")))
3818                         aArgs[i].Value >>= sCellRange;
3819                     else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("BrokenCellRangeForExport")))
3820                     {
3821                         if( aArgs[i].Value >>= sBrokenRange )
3822                             bBrokenRangeAvailable = true;
3823                     }
3824                     else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DataRowSource")))
3825                     {
3826                         chart::ChartDataRowSource eRowSource;
3827                         aArgs[i].Value >>= eRowSource;
3828                         mbRowSourceColumns = ( eRowSource == chart::ChartDataRowSource_COLUMNS );
3829                     }
3830                     else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("FirstCellAsLabel")))
3831                         aArgs[i].Value >>= mbHasSeriesLabels;
3832                     else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("SequenceMapping")))
3833                         aArgs[i].Value >>= maSequenceMapping;
3834                     else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("TableNumberList")))
3835                         aArgs[i].Value >>= msTableNumberList;
3836                 }
3837 
3838                 // #i79009# For Writer we have to export a broken version of the
3839                 // range, where every row number is noe too large, so that older
3840                 // version can correctly read those files.
3841                 msChartAddress = (bBrokenRangeAvailable ? sBrokenRange : sCellRange);
3842                 if( msChartAddress.getLength() > 0 )
3843                 {
3844                     // convert format to XML-conform one
3845                     Reference< chart2::data::XRangeXMLConversion > xConversion( xDataProvider, uno::UNO_QUERY );
3846                     if( xConversion.is())
3847                         msChartAddress = xConversion->convertRangeToXML( msChartAddress );
3848                 }
3849             }
3850         }
3851         catch( uno::Exception & ex )
3852         {
3853             (void)ex; // avoid warning for pro build
3854             OSL_ENSURE( false, OUStringToOString(
3855                             OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
3856                             OUString::createFromAscii( typeid( ex ).name()) +
3857                             OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
3858                             ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
3859         }
3860 }
3861 
3862 // export components ========================================
3863 
3864 // first version: everything goes in one storage
3865 
3866 Sequence< OUString > SAL_CALL SchXMLExport_getSupportedServiceNames() throw()
3867 {
3868 	const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLExporter" ) );
3869 	const Sequence< OUString > aSeq( &aServiceName, 1 );
3870 	return aSeq;
3871 }
3872 
3873 OUString SAL_CALL SchXMLExport_getImplementationName() throw()
3874 {
3875 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Compact" ) );
3876 }
3877 
3878 Reference< uno::XInterface > SAL_CALL SchXMLExport_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
3879 {
3880 	// #110680#
3881     // #103997# removed some flags from EXPORT_ALL
3882 	// return (cppu::OWeakObject*)new SchXMLExport( EXPORT_ALL ^ ( EXPORT_SETTINGS | EXPORT_MASTERSTYLES | EXPORT_SCRIPTS ));
3883 	return (cppu::OWeakObject*)new SchXMLExport( rSMgr, EXPORT_ALL ^ ( EXPORT_SETTINGS | EXPORT_MASTERSTYLES | EXPORT_SCRIPTS ));
3884 }
3885 
3886 // Oasis format
3887 Sequence< OUString > SAL_CALL SchXMLExport_Oasis_getSupportedServiceNames() throw()
3888 {
3889 	const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisExporter" ) );
3890 	const Sequence< OUString > aSeq( &aServiceName, 1 );
3891 	return aSeq;
3892 }
3893 
3894 OUString SAL_CALL SchXMLExport_Oasis_getImplementationName() throw()
3895 {
3896 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Oasis.Compact" ) );
3897 }
3898 
3899 Reference< uno::XInterface > SAL_CALL SchXMLExport_Oasis_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
3900 {
3901     // #103997# removed some flags from EXPORT_ALL
3902 	return (cppu::OWeakObject*)new SchXMLExport( rSMgr,
3903         (EXPORT_ALL ^ ( EXPORT_SETTINGS | EXPORT_MASTERSTYLES | EXPORT_SCRIPTS )) | EXPORT_OASIS );
3904 }
3905 
3906 // ============================================================
3907 
3908 // multiple storage version: one for content / styles / meta
3909 
3910 Sequence< OUString > SAL_CALL SchXMLExport_Styles_getSupportedServiceNames() throw()
3911 {
3912 	const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLStylesExporter" ));
3913 	const Sequence< OUString > aSeq( &aServiceName, 1 );
3914 	return aSeq;
3915 }
3916 
3917 OUString SAL_CALL SchXMLExport_Styles_getImplementationName() throw()
3918 {
3919 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Styles" ));
3920 }
3921 
3922 Reference< uno::XInterface > SAL_CALL SchXMLExport_Styles_createInstance(const Reference< lang::XMultiServiceFactory >& rSMgr) throw( uno::Exception )
3923 {
3924 	// #110680#
3925 	// return (cppu::OWeakObject*)new SchXMLExport( EXPORT_STYLES );
3926 	return (cppu::OWeakObject*)new SchXMLExport( rSMgr, EXPORT_STYLES );
3927 }
3928 
3929 // Oasis format
3930 Sequence< OUString > SAL_CALL SchXMLExport_Oasis_Styles_getSupportedServiceNames() throw()
3931 {
3932 	const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisStylesExporter" ));
3933 	const Sequence< OUString > aSeq( &aServiceName, 1 );
3934 	return aSeq;
3935 }
3936 
3937 OUString SAL_CALL SchXMLExport_Oasis_Styles_getImplementationName() throw()
3938 {
3939 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Oasis.Styles" ));
3940 }
3941 
3942 Reference< uno::XInterface > SAL_CALL SchXMLExport_Oasis_Styles_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
3943 {
3944 	return (cppu::OWeakObject*)new SchXMLExport( rSMgr, EXPORT_STYLES | EXPORT_OASIS );
3945 }
3946 
3947 // ------------------------------------------------------------
3948 
3949 Sequence< OUString > SAL_CALL SchXMLExport_Content_getSupportedServiceNames() throw()
3950 {
3951 	const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLContentExporter" ));
3952 	const Sequence< OUString > aSeq( &aServiceName, 1 );
3953 	return aSeq;
3954 }
3955 
3956 OUString SAL_CALL SchXMLExport_Content_getImplementationName() throw()
3957 {
3958 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Content" ));
3959 }
3960 
3961 Reference< uno::XInterface > SAL_CALL SchXMLExport_Content_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
3962 {
3963 	// #110680#
3964 	// return (cppu::OWeakObject*)new SchXMLExport( EXPORT_AUTOSTYLES | EXPORT_CONTENT | EXPORT_FONTDECLS );
3965 	return (cppu::OWeakObject*)new SchXMLExport( rSMgr, EXPORT_AUTOSTYLES | EXPORT_CONTENT | EXPORT_FONTDECLS );
3966 }
3967 
3968 // Oasis format
3969 Sequence< OUString > SAL_CALL SchXMLExport_Oasis_Content_getSupportedServiceNames() throw()
3970 {
3971 	const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisContentExporter" ));
3972 	const Sequence< OUString > aSeq( &aServiceName, 1 );
3973 	return aSeq;
3974 }
3975 
3976 OUString SAL_CALL SchXMLExport_Oasis_Content_getImplementationName() throw()
3977 {
3978 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Oasis.Content" ));
3979 }
3980 
3981 Reference< uno::XInterface > SAL_CALL SchXMLExport_Oasis_Content_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
3982 {
3983 	return (cppu::OWeakObject*)new SchXMLExport( rSMgr, EXPORT_AUTOSTYLES | EXPORT_CONTENT | EXPORT_FONTDECLS | EXPORT_OASIS );
3984 }
3985 
3986 // ------------------------------------------------------------
3987 
3988 // Sequence< OUString > SAL_CALL SchXMLExport_Meta_getSupportedServiceNames() throw()
3989 // {
3990 // 	const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLMetaExporter" ));
3991 // 	const Sequence< OUString > aSeq( &aServiceName, 1 );
3992 // 	return aSeq;
3993 // }
3994 
3995 // OUString SAL_CALL SchXMLExport_Meta_getImplementationName() throw()
3996 // {
3997 // 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Meta" ));
3998 // }
3999 
4000 // Reference< uno::XInterface > SAL_CALL SchXMLExport_Meta_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
4001 // {
4002 // 	return (cppu::OWeakObject*)new SchXMLExport( EXPORT_META );
4003 // }
4004 
4005 // Oasis format
4006 Sequence< OUString > SAL_CALL SchXMLExport_Oasis_Meta_getSupportedServiceNames() throw()
4007 {
4008 	const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisMetaExporter" ));
4009 	const Sequence< OUString > aSeq( &aServiceName, 1 );
4010 	return aSeq;
4011 }
4012 
4013 OUString SAL_CALL SchXMLExport_Oasis_Meta_getImplementationName() throw()
4014 {
4015 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Oasis.Meta" ));
4016 }
4017 
4018 Reference< uno::XInterface > SAL_CALL SchXMLExport_Oasis_Meta_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
4019 {
4020 	return (cppu::OWeakObject*)new SchXMLExport( rSMgr, EXPORT_META | EXPORT_OASIS  );
4021 }
4022 
4023 
4024 // XServiceInfo
4025 OUString SAL_CALL SchXMLExport::getImplementationName() throw( uno::RuntimeException )
4026 {
4027     switch( getExportFlags())
4028     {
4029         case EXPORT_ALL:
4030             return SchXMLExport_getImplementationName();
4031         case EXPORT_STYLES:
4032             return SchXMLExport_Styles_getImplementationName();
4033         case ( EXPORT_AUTOSTYLES | EXPORT_CONTENT | EXPORT_FONTDECLS ):
4034             return SchXMLExport_Content_getImplementationName();
4035 //         case EXPORT_META:
4036 //             return SchXMLExport_Meta_getImplementationName();
4037 
4038         // Oasis format
4039         case ( EXPORT_ALL | EXPORT_OASIS ):
4040             return SchXMLExport_Oasis_getImplementationName();
4041         case ( EXPORT_STYLES | EXPORT_OASIS ):
4042             return SchXMLExport_Oasis_Styles_getImplementationName();
4043         case ( EXPORT_AUTOSTYLES | EXPORT_CONTENT | EXPORT_FONTDECLS | EXPORT_OASIS  ):
4044             return SchXMLExport_Oasis_Content_getImplementationName();
4045         case ( EXPORT_META | EXPORT_OASIS ):
4046             return SchXMLExport_Oasis_Meta_getImplementationName();
4047 
4048         case EXPORT_SETTINGS:
4049         // there is no settings component in chart
4050         default:
4051             return OUString::createFromAscii( "SchXMLExport" );
4052     }
4053 }
4054