1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmloff.hxx"
26
27 #include <xmloff/xmlprmap.hxx>
28
29 #include "SchXMLExport.hxx"
30 #include "XMLChartPropertySetMapper.hxx"
31 #include "SchXMLSeriesHelper.hxx"
32 #include "ColorPropertySet.hxx"
33 #include "SchXMLTools.hxx"
34 #include "SchXMLEnumConverter.hxx"
35
36 #include <tools/debug.hxx>
37 #include <rtl/logfile.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <tools/globname.hxx>
40 #include <sot/clsids.hxx>
41
42 #include <xmloff/nmspmap.hxx>
43 #include "xmloff/xmlnmspe.hxx"
44 #include <xmloff/xmltoken.hxx>
45 #include <xmloff/families.hxx>
46 #include <xmloff/xmlaustp.hxx>
47 #include <xmloff/xmluconv.hxx>
48 #include <xmloff/xmlmetae.hxx>
49 #include "xexptran.hxx"
50 #include <rtl/math.hxx>
51 // header for any2enum
52 #include <comphelper/extract.hxx>
53
54 #include <list>
55 #include <typeinfo>
56 #include <algorithm>
57 #include <iterator>
58
59 #include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
60 #include <com/sun/star/lang/XServiceInfo.hpp>
61 #include <com/sun/star/lang/XServiceName.hpp>
62 #include <com/sun/star/beans/XPropertySet.hpp>
63 #include <com/sun/star/uno/XComponentContext.hpp>
64 #include <com/sun/star/util/XRefreshable.hpp>
65
66 #include <com/sun/star/chart/XAxis.hpp>
67 #include <com/sun/star/chart/XAxisSupplier.hpp>
68 #include <com/sun/star/chart/XChartDocument.hpp>
69 #include <com/sun/star/chart/ChartLegendPosition.hpp>
70 #include <com/sun/star/chart/ChartLegendExpansion.hpp>
71 #include <com/sun/star/chart/ChartDataRowSource.hpp>
72 #include <com/sun/star/chart/ChartAxisAssign.hpp>
73 #include <com/sun/star/chart/ChartAxisType.hpp>
74 #include <com/sun/star/chart/TimeIncrement.hpp>
75 #include <com/sun/star/chart/TimeInterval.hpp>
76 #include <com/sun/star/chart/TimeUnit.hpp>
77 #include <com/sun/star/chart/ChartSeriesAddress.hpp>
78 #include <com/sun/star/chart/X3DDisplay.hpp>
79 #include <com/sun/star/chart/XStatisticDisplay.hpp>
80 #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
81 #include <com/sun/star/chart/XDiagramPositioning.hpp>
82
83 #include <com/sun/star/chart2/XAnyDescriptionAccess.hpp>
84 #include <com/sun/star/chart2/AxisType.hpp>
85 #include <com/sun/star/chart2/XChartDocument.hpp>
86 #include <com/sun/star/chart2/XDiagram.hpp>
87 #include <com/sun/star/chart2/RelativePosition.hpp>
88 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
89 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
90 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
91 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
92 #include <com/sun/star/chart2/data/XDataSource.hpp>
93 #include <com/sun/star/chart2/data/XDataSink.hpp>
94 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
95 #include <com/sun/star/chart2/data/XDataProvider.hpp>
96 #include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
97 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
98 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
99 #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
100
101 #include <com/sun/star/util/XStringMapping.hpp>
102 #include <com/sun/star/drawing/HomogenMatrix.hpp>
103 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
104 #include <com/sun/star/drawing/XShapes.hpp>
105 #include <com/sun/star/embed/Aspects.hpp>
106 #include <com/sun/star/embed/XVisualObject.hpp>
107 #include <com/sun/star/container/XChild.hpp>
108
109
110 #include "MultiPropertySetHandler.hxx"
111 #include "PropertyMap.hxx"
112
113 using namespace com::sun::star;
114 using namespace ::xmloff::token;
115
116 using ::rtl::OUString;
117 using ::rtl::OUStringBuffer;
118 using ::rtl::OUStringToOString;
119 using ::com::sun::star::uno::Sequence;
120 using ::com::sun::star::uno::Reference;
121 using ::com::sun::star::uno::Any;
122 using ::std::vector;
123
124 // ========================================
125 // class SchXMLExportHelper_Impl
126 // ========================================
127
128 class SchXMLExportHelper_Impl
129 {
130 public:
131 // first: data sequence for label, second: data sequence for values.
132 typedef ::std::pair< ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >,
133 ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence > > tLabelValuesDataPair;
134 typedef ::std::vector< tLabelValuesDataPair > tDataSequenceCont;
135
136 public:
137 SchXMLExportHelper_Impl( SvXMLExport& rExport,
138 SvXMLAutoStylePoolP& rASPool );
139
140 virtual ~SchXMLExportHelper_Impl();
141
142 // auto-styles
143 /// parse chart and collect all auto-styles used in current pool
144 void collectAutoStyles( com::sun::star::uno::Reference<
145 com::sun::star::chart::XChartDocument > rChartDoc );
146
147 /// write the styles collected into the current pool as <style:style> elements
148 void exportAutoStyles();
149
150 /** export the <chart:chart> element corresponding to rChartDoc
151 if bIncludeTable is true, the chart data is exported as <table:table>
152 element (inside the chart element).
153
154 Otherwise the external references stored in the chart document are used
155 for writing the corresponding attributes at series
156
157 All attributes contained in xAttrList are written at the chart element,
158 which ist the outer element of a chart. So these attributes can easily
159 be parsed again by the container
160 */
161 void exportChart( com::sun::star::uno::Reference<
162 com::sun::star::chart::XChartDocument > rChartDoc,
163 sal_Bool bIncludeTable );
164
165 UniReference< XMLPropertySetMapper > GetPropertySetMapper() const;
166
SetChartRangeAddress(const::rtl::OUString & rAddress)167 void SetChartRangeAddress( const ::rtl::OUString& rAddress )
168 { msChartAddress = rAddress; }
SetTableNumberList(const::rtl::OUString & rList)169 void SetTableNumberList( const ::rtl::OUString& rList )
170 { msTableNumberList = rList; }
171
172 void InitRangeSegmentationProperties(
173 const ::com::sun::star::uno::Reference<
174 ::com::sun::star::chart2::XChartDocument > & xChartDoc );
175
176 ::com::sun::star::awt::Size getPageSize(
177 const ::com::sun::star::uno::Reference<
178 ::com::sun::star::chart2::XChartDocument > & xChartDoc ) const;
179
180 /** first parseDocument: collect autostyles and store names in this queue
181 second parseDocument: export content and use names from this queue
182 */
183 ::std::queue< ::rtl::OUString > maAutoStyleNameQueue;
184 void CollectAutoStyle(
185 const std::vector< XMLPropertyState >& aStates );
186 void AddAutoStyleAttribute(
187 const std::vector< XMLPropertyState >& aStates );
188
GetAutoStylePoolP()189 SvXMLAutoStylePoolP& GetAutoStylePoolP()
190 { return mrAutoStylePool; }
191
192 /// if bExportContent is false the auto-styles are collected
193 void parseDocument( com::sun::star::uno::Reference<
194 com::sun::star::chart::XChartDocument >& rChartDoc,
195 sal_Bool bExportContent,
196 sal_Bool bIncludeTable = sal_False );
197 void exportTable();
198 void exportPlotArea(
199 com::sun::star::uno::Reference< com::sun::star::chart::XDiagram > xDiagram,
200 com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > xNewDiagram,
201 const ::com::sun::star::awt::Size & rPageSize,
202 sal_Bool bExportContent,
203 sal_Bool bIncludeTable );
204 void exportCoordinateRegion( const com::sun::star::uno::Reference< com::sun::star::chart::XDiagram >& xDiagram );
205 void exportAxes( const com::sun::star::uno::Reference< com::sun::star::chart::XDiagram > & xDiagram,
206 const com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > & xNewDiagram,
207 sal_Bool bExportContent );
208 void exportAxis( enum XMLTokenEnum eDimension, enum XMLTokenEnum eAxisName,
209 const Reference< beans::XPropertySet > xAxisProps, const Reference< chart2::XAxis >& xChart2Axis,
210 const OUString& rCategoriesRanges,
211 bool bHasTitle, bool bHasMajorGrid, bool bHasMinorGrid, bool bExportContent );
212 void exportGrid( const Reference< beans::XPropertySet > xGridProperties, bool bMajor, bool bExportContent );
213 void exportDateScale( const Reference< beans::XPropertySet > xAxisProps );
214 void exportAxisTitle( const Reference< beans::XPropertySet > xTitleProps, bool bExportContent );
215
216 void exportSeries(
217 const com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > & xNewDiagram,
218 const ::com::sun::star::awt::Size & rPageSize,
219 sal_Bool bExportContent,
220 sal_Bool bHasTwoYAxes );
221 void exportCandleStickSeries(
222 const ::com::sun::star::uno::Sequence<
223 ::com::sun::star::uno::Reference<
224 ::com::sun::star::chart2::XDataSeries > > & aSeriesSeq,
225 const ::com::sun::star::uno::Reference<
226 ::com::sun::star::chart2::XDiagram > & xDiagram,
227 sal_Bool bJapaneseCandleSticks,
228 sal_Bool bExportContent );
229 void exportDataPoints(
230 const ::com::sun::star::uno::Reference<
231 ::com::sun::star::beans::XPropertySet > & xSeriesProperties,
232 sal_Int32 nSeriesLength,
233 const ::com::sun::star::uno::Reference<
234 ::com::sun::star::chart2::XDiagram > & xDiagram,
235 sal_Bool bExportContent );
236 void exportRegressionCurve(
237 const ::com::sun::star::uno::Reference<
238 ::com::sun::star::chart2::XDataSeries > & xSeries,
239 const ::com::sun::star::uno::Reference<
240 ::com::sun::star::beans::XPropertySet > & xSeriesProp,
241 const ::com::sun::star::awt::Size & rPageSize,
242 sal_Bool bExportContent );
243
244 /// add svg position as attribute for current element
245 void addPosition( const ::com::sun::star::awt::Point & rPosition );
246 void addPosition( com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape );
247 /// add svg size as attribute for current element
248 void addSize( const ::com::sun::star::awt::Size & rSize, bool bIsOOoNamespace = false );
249 void addSize( com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape, bool bIsOOoNamespace = false );
250 /// fills the member msString with the appropriate String (i.e. "A3")
251 void getCellAddress( sal_Int32 nCol, sal_Int32 nRow );
252 /// exports a string as a paragraph element
253 void exportText( const ::rtl::OUString& rText, bool bConvertTabsLFs = false );
254 void exportErrorBarRanges();
255
256 SchXMLExportHelper_Impl(SchXMLExportHelper_Impl &); // not defined
257 void operator =(SchXMLExportHelper_Impl &); // not defined
258
259 public:
260 SvXMLExport& mrExport;
261 SvXMLAutoStylePoolP& mrAutoStylePool;
262 UniReference< XMLPropertyHandlerFactory > mxPropertyHandlerFactory;
263 UniReference< XMLPropertySetMapper > mxPropertySetMapper;
264 UniReference< XMLChartExportPropertyMapper > mxExpPropMapper;
265
266 rtl::OUString msTableName;
267 rtl::OUStringBuffer msStringBuffer;
268 rtl::OUString msString;
269
270 // members filled by InitRangeSegmentationProperties (retrieved from DataProvider)
271 sal_Bool mbHasSeriesLabels;
272 sal_Bool mbHasCategoryLabels; //if the categories are only automatically generated this will be false
273 sal_Bool mbRowSourceColumns;
274 rtl::OUString msChartAddress;
275 rtl::OUString msTableNumberList;
276 ::com::sun::star::uno::Sequence< sal_Int32 > maSequenceMapping;
277
278 rtl::OUString msCLSID;
279
280 ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > mxAdditionalShapes;
281
282 tDataSequenceCont m_aDataSequencesToExport;
283 rtl::OUString maCategoriesRange;
284 };
285
286 namespace
287 {
lcl_getComponentContext()288 Reference< uno::XComponentContext > lcl_getComponentContext()
289 {
290 Reference< uno::XComponentContext > xContext;
291 try
292 {
293 Reference< beans::XPropertySet > xFactProp( comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
294 if( xFactProp.is())
295 xFactProp->getPropertyValue(OUString::createFromAscii("DefaultContext")) >>= xContext;
296 }
297 catch( uno::Exception& )
298 {}
299
300 return xContext;
301 }
302
303 class lcl_MatchesRole : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool >
304 {
305 public:
lcl_MatchesRole(const OUString & aRole)306 explicit lcl_MatchesRole( const OUString & aRole ) :
307 m_aRole( aRole )
308 {}
309
operator ()(const Reference<chart2::data::XLabeledDataSequence> & xSeq) const310 bool operator () ( const Reference< chart2::data::XLabeledDataSequence > & xSeq ) const
311 {
312 if( !xSeq.is() )
313 return false;
314 Reference< beans::XPropertySet > xProp( xSeq->getValues(), uno::UNO_QUERY );
315 OUString aRole;
316
317 return ( xProp.is() &&
318 (xProp->getPropertyValue(
319 OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )) ) >>= aRole ) &&
320 m_aRole.equals( aRole ));
321 }
322
323 private:
324 OUString m_aRole;
325 };
326
327 template< typename T >
lcl_SequenceToVectorAppend(const Sequence<T> & rSource,::std::vector<T> & rDestination)328 void lcl_SequenceToVectorAppend( const Sequence< T > & rSource, ::std::vector< T > & rDestination )
329 {
330 rDestination.reserve( rDestination.size() + rSource.getLength());
331 ::std::copy( rSource.getConstArray(), rSource.getConstArray() + rSource.getLength(),
332 ::std::back_inserter( rDestination ));
333 }
334
335 template< typename T >
lcl_SequenceToVector(const Sequence<T> & rSource,::std::vector<T> & rDestination)336 void lcl_SequenceToVector( const Sequence< T > & rSource, ::std::vector< T > & rDestination )
337 {
338 rDestination.clear();
339 lcl_SequenceToVectorAppend( rSource, rDestination );
340 }
341
lcl_getCategories(const Reference<chart2::XDiagram> & xDiagram)342 Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const Reference< chart2::XDiagram > & xDiagram )
343 {
344 Reference< chart2::data::XLabeledDataSequence > xResult;
345 try
346 {
347 Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
348 xDiagram, uno::UNO_QUERY_THROW );
349 Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
350 xCooSysCnt->getCoordinateSystems());
351 for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
352 {
353 Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[i] );
354 OSL_ASSERT( xCooSys.is());
355 for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
356 {
357 const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
358 for(sal_Int32 nI=0; nI<=nMaxAxisIndex; ++nI)
359 {
360 Reference< chart2::XAxis > xAxis = xCooSys->getAxisByDimension( nN, nI );
361 OSL_ASSERT( xAxis.is());
362 if( xAxis.is())
363 {
364 chart2::ScaleData aScaleData = xAxis->getScaleData();
365 if( aScaleData.Categories.is())
366 {
367 xResult.set( aScaleData.Categories );
368 break;
369 }
370 }
371 }
372 }
373 }
374 }
375 catch( uno::Exception & ex )
376 {
377 (void)ex; // avoid warning for pro build
378 OSL_ENSURE( false, OUStringToOString(
379 OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
380 OUString::createFromAscii( typeid( ex ).name()) +
381 OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
382 ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
383 }
384
385 return xResult;
386 }
387
lcl_createDataSource(const Sequence<Reference<chart2::data::XLabeledDataSequence>> & aData)388 Reference< chart2::data::XDataSource > lcl_createDataSource(
389 const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aData )
390 {
391 Reference< chart2::data::XDataSink > xSink;
392 Reference< uno::XComponentContext > xContext( lcl_getComponentContext());
393 if( xContext.is() )
394 xSink.set(
395 xContext->getServiceManager()->createInstanceWithContext(
396 OUString::createFromAscii("com.sun.star.chart2.data.DataSource"),
397 xContext ), uno::UNO_QUERY_THROW );
398 if( xSink.is())
399 xSink->setData( aData );
400
401 return Reference< chart2::data::XDataSource >( xSink, uno::UNO_QUERY );
402 }
403
lcl_getAllSeriesSequences(const Reference<chart2::XChartDocument> & xChartDoc)404 Sequence< Reference< chart2::data::XLabeledDataSequence > > lcl_getAllSeriesSequences( const Reference< chart2::XChartDocument >& xChartDoc )
405 {
406 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aContainer;
407 if( xChartDoc.is() )
408 {
409 Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
410 ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( SchXMLSeriesHelper::getDataSeriesFromDiagram( xDiagram ));
411 for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aSeriesIt( aSeriesVector.begin() )
412 ; aSeriesIt != aSeriesVector.end(); ++aSeriesIt )
413 {
414 Reference< chart2::data::XDataSource > xDataSource( *aSeriesIt, uno::UNO_QUERY );
415 if( !xDataSource.is() )
416 continue;
417 uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > aDataSequences( xDataSource->getDataSequences() );
418 lcl_SequenceToVectorAppend( aDataSequences, aContainer );
419 }
420 }
421
422 Sequence< Reference< chart2::data::XLabeledDataSequence > > aRet( aContainer.size());
423 ::std::copy( aContainer.begin(), aContainer.end(), aRet.getArray());
424
425 return aRet;
426 }
427
428 Reference< chart2::data::XLabeledDataSequence >
lcl_getDataSequenceByRole(const Sequence<Reference<chart2::data::XLabeledDataSequence>> & aLabeledSeq,const OUString & rRole)429 lcl_getDataSequenceByRole(
430 const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aLabeledSeq,
431 const OUString & rRole )
432 {
433 Reference< chart2::data::XLabeledDataSequence > aNoResult;
434
435 const Reference< chart2::data::XLabeledDataSequence > * pBegin = aLabeledSeq.getConstArray();
436 const Reference< chart2::data::XLabeledDataSequence > * pEnd = pBegin + aLabeledSeq.getLength();
437 const Reference< chart2::data::XLabeledDataSequence > * pMatch =
438 ::std::find_if( pBegin, pEnd, lcl_MatchesRole( rRole ));
439
440 if( pMatch != pEnd )
441 return *pMatch;
442
443 return aNoResult;
444 }
445
lcl_pressUsedDataIntoRectangularFormat(const Reference<chart2::XChartDocument> & xChartDoc,sal_Bool & rOutSourceHasCategoryLabels)446 Reference< chart2::data::XDataSource > lcl_pressUsedDataIntoRectangularFormat( const Reference< chart2::XChartDocument >& xChartDoc, sal_Bool& rOutSourceHasCategoryLabels )
447 {
448 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aLabeledSeqVector;
449
450 //categories are always the first sequence
451 Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
452 Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xDiagram ) );
453 if( xCategories.is() )
454 aLabeledSeqVector.push_back( xCategories );
455 rOutSourceHasCategoryLabels = sal_Bool(xCategories.is());
456
457 Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeriesSeqVector(
458 lcl_getAllSeriesSequences( xChartDoc ) );
459
460 //the first x-values is always the next sequence //todo ... other x-values get lost for old format
461 Reference< chart2::data::XLabeledDataSequence > xXValues(
462 lcl_getDataSequenceByRole( aSeriesSeqVector, OUString::createFromAscii("values-x" ) ) );
463 if( xXValues.is() )
464 aLabeledSeqVector.push_back( xXValues );
465
466 //add all other sequences now without x-values
467 lcl_MatchesRole aHasXValues( OUString::createFromAscii("values-x" ) );
468 for( sal_Int32 nN=0; nN<aSeriesSeqVector.getLength(); nN++ )
469 {
470 if( !aHasXValues( aSeriesSeqVector[nN] ) )
471 aLabeledSeqVector.push_back( aSeriesSeqVector[nN] );
472 }
473
474 Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( aLabeledSeqVector.size() );
475 ::std::copy( aLabeledSeqVector.begin(), aLabeledSeqVector.end(), aSeq.getArray() );
476
477 return lcl_createDataSource( aSeq );
478 }
479
lcl_isSeriesAttachedToFirstAxis(const Reference<chart2::XDataSeries> & xDataSeries)480 bool lcl_isSeriesAttachedToFirstAxis(
481 const Reference< chart2::XDataSeries > & xDataSeries )
482 {
483 bool bResult=true;
484
485 try
486 {
487 sal_Int32 nAxisIndex = 0;
488 Reference< beans::XPropertySet > xProp( xDataSeries, uno::UNO_QUERY_THROW );
489 if( xProp.is() )
490 xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("AttachedAxisIndex") ) ) >>= nAxisIndex;
491 bResult = (0==nAxisIndex);
492 }
493 catch( uno::Exception & ex )
494 {
495 (void)ex; // avoid warning for pro build
496 OSL_ENSURE( false, OUStringToOString(
497 OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
498 OUString::createFromAscii( typeid( ex ).name()) +
499 OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
500 ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
501 }
502
503 return bResult;
504 }
505
lcl_ConvertRange(const::rtl::OUString & rRange,const Reference<chart2::XChartDocument> & xDoc)506 OUString lcl_ConvertRange( const ::rtl::OUString & rRange, const Reference< chart2::XChartDocument > & xDoc )
507 {
508 OUString aResult = rRange;
509 if( !xDoc.is() )
510 return aResult;
511 Reference< chart2::data::XRangeXMLConversion > xConversion(
512 xDoc->getDataProvider(), uno::UNO_QUERY );
513 if( xConversion.is())
514 aResult = xConversion->convertRangeToXML( rRange );
515 return aResult;
516 }
517
518 typedef ::std::pair< OUString, OUString > tLabelAndValueRange;
519
lcl_getLabelAndValueRangeByRole(const Sequence<Reference<chart2::data::XLabeledDataSequence>> & aSeqCnt,const OUString & rRole,const Reference<chart2::XChartDocument> & xDoc,SchXMLExportHelper_Impl::tDataSequenceCont & rOutSequencesToExport)520 tLabelAndValueRange lcl_getLabelAndValueRangeByRole(
521 const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aSeqCnt,
522 const OUString & rRole,
523 const Reference< chart2::XChartDocument > & xDoc,
524 SchXMLExportHelper_Impl::tDataSequenceCont & rOutSequencesToExport )
525 {
526 tLabelAndValueRange aResult;
527
528 Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
529 lcl_getDataSequenceByRole( aSeqCnt, rRole ));
530 if( xLabeledSeq.is())
531 {
532 Reference< chart2::data::XDataSequence > xLabelSeq( xLabeledSeq->getLabel());
533 if( xLabelSeq.is())
534 aResult.first = lcl_ConvertRange( xLabelSeq->getSourceRangeRepresentation(), xDoc );
535
536 Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues());
537 if( xValueSeq.is())
538 aResult.second = lcl_ConvertRange( xValueSeq->getSourceRangeRepresentation(), xDoc );
539
540 if( xLabelSeq.is() || xValueSeq.is())
541 rOutSequencesToExport.push_back( SchXMLExportHelper_Impl::tLabelValuesDataPair( xLabelSeq, xValueSeq ));
542 }
543
544 return aResult;
545 }
546
lcl_getSequenceLengthByRole(const Sequence<Reference<chart2::data::XLabeledDataSequence>> & aSeqCnt,const OUString & rRole)547 sal_Int32 lcl_getSequenceLengthByRole(
548 const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aSeqCnt,
549 const OUString & rRole )
550 {
551 Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
552 lcl_getDataSequenceByRole( aSeqCnt, rRole ));
553 if( xLabeledSeq.is())
554 {
555 Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getValues());
556 return xSeq->getData().getLength();
557 }
558 return 0;
559 }
560
lcl_hasChartType(const Reference<chart2::XDiagram> & xDiagram,const OUString & rChartType)561 bool lcl_hasChartType( const Reference< chart2::XDiagram > & xDiagram, const OUString & rChartType )
562 {
563 try
564 {
565 Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
566 Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
567 for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
568 {
569 Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
570 Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
571 for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
572 {
573 if( aChartTypes[nCTIdx]->getChartType().equals( rChartType ))
574 return true;
575 }
576 }
577 }
578 catch( uno::Exception & )
579 {
580 DBG_ERROR( "Exception while searching for chart type in diagram" );
581 }
582 return false;
583 }
584
lcl_flattenStringSequence(const Sequence<OUString> & rSequence)585 OUString lcl_flattenStringSequence( const Sequence< OUString > & rSequence )
586 {
587 OUStringBuffer aResult;
588 bool bPrecedeWithSpace = false;
589 for( sal_Int32 nIndex=0; nIndex<rSequence.getLength(); ++nIndex )
590 {
591 if( rSequence[nIndex].getLength())
592 {
593 if( bPrecedeWithSpace )
594 aResult.append( static_cast< sal_Unicode >( ' ' ));
595 aResult.append( rSequence[nIndex] );
596 bPrecedeWithSpace = true;
597 }
598 }
599 return aResult.makeStringAndClear();
600 }
601
lcl_getLabelStringSequence(Sequence<OUString> & rOutLabels,const Reference<chart2::data::XDataSequence> & xLabelSeq)602 void lcl_getLabelStringSequence( Sequence< OUString >& rOutLabels, const Reference< chart2::data::XDataSequence > & xLabelSeq )
603 {
604 uno::Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xLabelSeq, uno::UNO_QUERY );
605 if( xTextualDataSequence.is())
606 {
607 rOutLabels = xTextualDataSequence->getTextualData();
608 }
609 else if( xLabelSeq.is())
610 {
611 Sequence< uno::Any > aAnies( xLabelSeq->getData());
612 rOutLabels.realloc( aAnies.getLength());
613 for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
614 aAnies[i] >>= rOutLabels[i];
615 }
616 }
617
lcl_getMaxSequenceLength(const SchXMLExportHelper_Impl::tDataSequenceCont & rContainer)618 sal_Int32 lcl_getMaxSequenceLength(
619 const SchXMLExportHelper_Impl::tDataSequenceCont & rContainer )
620 {
621 sal_Int32 nResult = 0;
622 for( SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator aIt( rContainer.begin());
623 aIt != rContainer.end(); ++aIt )
624 {
625 if( aIt->second.is())
626 {
627 sal_Int32 nSeqLength = aIt->second->getData().getLength();
628 if( nSeqLength > nResult )
629 nResult = nSeqLength;
630 }
631 }
632 return nResult;
633 }
634
lcl_DataSequenceToStringSequence(const uno::Reference<chart2::data::XDataSequence> & xDataSequence)635 uno::Sequence< rtl::OUString > lcl_DataSequenceToStringSequence(
636 const uno::Reference< chart2::data::XDataSequence >& xDataSequence )
637 {
638 uno::Sequence< rtl::OUString > aResult;
639 if(!xDataSequence.is())
640 return aResult;
641
642 uno::Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xDataSequence, uno::UNO_QUERY );
643 if( xTextualDataSequence.is() )
644 {
645 aResult = xTextualDataSequence->getTextualData();
646 }
647 else
648 {
649 uno::Sequence< uno::Any > aValues = xDataSequence->getData();
650 aResult.realloc(aValues.getLength());
651
652 for(sal_Int32 nN=aValues.getLength();nN--;)
653 aValues[nN] >>= aResult[nN];
654 }
655
656 return aResult;
657 }
lcl_getAllValuesFromSequence(const Reference<chart2::data::XDataSequence> & xSeq)658 ::std::vector< double > lcl_getAllValuesFromSequence( const Reference< chart2::data::XDataSequence > & xSeq )
659 {
660 double fNan = 0.0;
661 ::rtl::math::setNan( &fNan );
662 ::std::vector< double > aResult;
663 if(!xSeq.is())
664 return aResult;
665
666 uno::Sequence< double > aValuesSequence;
667 Reference< chart2::data::XNumericalDataSequence > xNumSeq( xSeq, uno::UNO_QUERY );
668 if( xNumSeq.is() )
669 {
670 aValuesSequence = xNumSeq->getNumericalData();
671 }
672 else
673 {
674 Sequence< uno::Any > aAnies( xSeq->getData() );
675 aValuesSequence.realloc( aAnies.getLength() );
676 for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
677 aAnies[i] >>= aValuesSequence[i];
678 }
679
680 //special handling for x-values (if x-values do point to categories, indices are used instead )
681 Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY );
682 if( xProp.is() )
683 {
684 OUString aRole;
685 xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Role") ) ) >>= aRole;
686 if( aRole.match( OUString( RTL_CONSTASCII_USTRINGPARAM( "values-x") ) ) )
687 {
688 //lcl_clearIfNoValuesButTextIsContained - replace by indices if the values are not appropriate
689 bool bHasValue=false;
690 bool bHasText=false;
691 sal_Int32 nCount = aValuesSequence.getLength();
692 for( sal_Int32 j = 0; j < nCount; ++j )
693 {
694 if( !::rtl::math::isNan( aValuesSequence[j] ) )
695 {
696 bHasValue=true;
697 break;
698 }
699 }
700 if(!bHasValue)
701 {
702 //no double value is countained
703 //is there any text?
704 uno::Sequence< rtl::OUString > aStrings( lcl_DataSequenceToStringSequence( xSeq ) );
705 sal_Int32 nTextCount = aStrings.getLength();
706 for( sal_Int32 j = 0; j < nTextCount; ++j )
707 {
708 if( aStrings[j].getLength() )
709 {
710 bHasText=true;
711 break;
712 }
713 }
714 }
715 if( !bHasValue && bHasText )
716 {
717 for( sal_Int32 j = 0; j < nCount; ++j )
718 aValuesSequence[j] = j+1;
719 }
720 }
721 }
722
723 ::std::copy( aValuesSequence.getConstArray(), aValuesSequence.getConstArray() + aValuesSequence.getLength(),
724 ::std::back_inserter( aResult ));
725 return aResult;
726 }
727
lcl_SequenceHasUnhiddenData(const uno::Reference<chart2::data::XDataSequence> & xDataSequence)728 bool lcl_SequenceHasUnhiddenData( const uno::Reference< chart2::data::XDataSequence >& xDataSequence )
729 {
730 if( !xDataSequence.is() )
731 return false;
732 uno::Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY );
733 if( xProp.is() )
734 {
735 uno::Sequence< sal_Int32 > aHiddenValues;
736 try
737 {
738 xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "HiddenValues" ) ) ) >>= aHiddenValues;
739 if( !aHiddenValues.getLength() )
740 return true;
741 }
742 catch( uno::Exception& e )
743 {
744 (void)e; // avoid warning
745 return true;
746 }
747 }
748 if( xDataSequence->getData().getLength() )
749 return true;
750 return false;
751 }
752
753 typedef vector< OUString > tStringVector;
754 typedef vector< double > tDoubleVector;
755 typedef vector< vector< OUString > > t2DStringVector;
756 typedef vector< vector< double > > t2DNumberContainer;
757
758 struct lcl_TableData
759 {
760 t2DNumberContainer aDataInRows;
761 tStringVector aDataRangeRepresentations;
762
763 tStringVector aColumnDescriptions;
764 tStringVector aColumnDescriptions_Ranges;
765
766 tStringVector aRowDescriptions;
767 tStringVector aRowDescriptions_Ranges;
768
769 Sequence< Sequence< uno::Any > > aComplexColumnDescriptions;//outer index is columns - inner index is level
770 Sequence< Sequence< uno::Any > > aComplexRowDescriptions;//outer index is rows - inner index is level
771
772 ::std::vector< sal_Int32 > aHiddenColumns;
773 };
774
775 // ::std::bind2nd( ::std::mem_fun_ref( &T::resize ), nSize ) does not work
776 template< class T >
777 struct lcl_resize
778 {
lcl_resize__anon2a707c240111::lcl_resize779 lcl_resize( typename T::size_type nSize, typename T::value_type fDefaultValue ) : m_nSize( nSize ), m_fDefaultValue( fDefaultValue ) {}
operator ()__anon2a707c240111::lcl_resize780 void operator()( T & t )
781 { t.resize( m_nSize, m_fDefaultValue ); }
782 private:
783 typename T::size_type m_nSize;
784 typename T::value_type m_fDefaultValue;
785 };
786
787
788 typedef ::std::map< sal_Int32, SchXMLExportHelper_Impl::tLabelValuesDataPair >
789 lcl_DataSequenceMap;
790
791 struct lcl_SequenceToMapElement :
792 public ::std::unary_function< lcl_DataSequenceMap::mapped_type, lcl_DataSequenceMap::value_type >
793 {
lcl_SequenceToMapElement__anon2a707c240111::lcl_SequenceToMapElement794 lcl_SequenceToMapElement()
795 {}
operator ()__anon2a707c240111::lcl_SequenceToMapElement796 result_type operator() ( const argument_type & rContent )
797 {
798 sal_Int32 nIndex = -1;
799 if( rContent.second.is()) //has values
800 {
801 OUString aRangeRep( rContent.second->getSourceRangeRepresentation());
802 nIndex = aRangeRep.toInt32();
803 }
804 else if( rContent.first.is()) //has labels
805 nIndex = rContent.first->getSourceRangeRepresentation().copy( sizeof("label ")).toInt32();
806 return result_type( nIndex, rContent );
807 }
808 };
809
lcl_ReorderInternalSequencesAccordingToTheirRangeName(SchXMLExportHelper_Impl::tDataSequenceCont & rInOutSequences)810 void lcl_ReorderInternalSequencesAccordingToTheirRangeName(
811 SchXMLExportHelper_Impl::tDataSequenceCont & rInOutSequences )
812 {
813 lcl_DataSequenceMap aIndexSequenceMap;
814 ::std::transform( rInOutSequences.begin(), rInOutSequences.end(),
815 ::std::inserter( aIndexSequenceMap, aIndexSequenceMap.begin()),
816 lcl_SequenceToMapElement());
817
818 rInOutSequences.clear();
819 sal_Int32 nIndex = 0;
820 for( lcl_DataSequenceMap::const_iterator aIt = aIndexSequenceMap.begin();
821 aIt != aIndexSequenceMap.end(); ++aIt, ++nIndex )
822 {
823 if( aIt->first < 0 )
824 continue;
825 // fill empty columns
826 for( ; nIndex < aIt->first; ++nIndex )
827 rInOutSequences.push_back(
828 SchXMLExportHelper_Impl::tDataSequenceCont::value_type( 0, 0 ));
829 OSL_ASSERT( nIndex == aIt->first );
830 rInOutSequences.push_back( aIt->second );
831 }
832 }
833
834
lcl_getDataForLocalTable(const SchXMLExportHelper_Impl::tDataSequenceCont & aSequencesToExport,const Reference<chart2::XAnyDescriptionAccess> & xAnyDescriptionAccess,const OUString & rCategoriesRange,bool bSeriesFromColumns,const Reference<chart2::data::XRangeXMLConversion> & xRangeConversion)835 lcl_TableData lcl_getDataForLocalTable(
836 const SchXMLExportHelper_Impl::tDataSequenceCont & aSequencesToExport,
837 const Reference< chart2::XAnyDescriptionAccess >& xAnyDescriptionAccess,
838 const OUString& rCategoriesRange,
839 bool bSeriesFromColumns,
840 const Reference< chart2::data::XRangeXMLConversion > & xRangeConversion )
841 {
842 lcl_TableData aResult;
843
844 try
845 {
846 Sequence< OUString > aSimpleCategories;
847 if( xAnyDescriptionAccess.is() )
848 {
849 //categories
850 if( bSeriesFromColumns )
851 {
852 aSimpleCategories = xAnyDescriptionAccess->getRowDescriptions();
853 aResult.aComplexRowDescriptions = xAnyDescriptionAccess->getAnyRowDescriptions();
854 }
855 else
856 {
857 aSimpleCategories = xAnyDescriptionAccess->getColumnDescriptions();
858 aResult.aComplexColumnDescriptions = xAnyDescriptionAccess->getAnyColumnDescriptions();
859 }
860 }
861
862 //series values and series labels
863 SchXMLExportHelper_Impl::tDataSequenceCont::size_type nNumSequences = aSequencesToExport.size();
864 SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator aBegin( aSequencesToExport.begin());
865 SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator aEnd( aSequencesToExport.end());
866 SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator aIt( aBegin );
867
868 size_t nMaxSequenceLength( lcl_getMaxSequenceLength( aSequencesToExport ));
869 size_t nCategoriesLength( aSimpleCategories.getLength() );
870 if( nCategoriesLength > nMaxSequenceLength )
871 {
872 aSimpleCategories.realloc(nMaxSequenceLength);//#i110617#
873 nCategoriesLength = nMaxSequenceLength;
874 }
875 size_t nNumColumns( bSeriesFromColumns ? nNumSequences : nMaxSequenceLength );
876 size_t nNumRows( bSeriesFromColumns ? nMaxSequenceLength : nNumSequences );
877
878 // resize data
879 aResult.aDataInRows.resize( nNumRows );
880 double fNan = 0.0;
881 ::rtl::math::setNan( &fNan );
882 ::std::for_each( aResult.aDataInRows.begin(), aResult.aDataInRows.end(),
883 lcl_resize< t2DNumberContainer::value_type >( nNumColumns, fNan ));
884 aResult.aColumnDescriptions.resize( nNumColumns );
885 aResult.aComplexColumnDescriptions.realloc( nNumColumns );
886 aResult.aRowDescriptions.resize( nNumRows );
887 aResult.aComplexRowDescriptions.realloc( nNumRows );
888
889 tStringVector& rCategories = bSeriesFromColumns ? aResult.aRowDescriptions : aResult.aColumnDescriptions;
890 tStringVector& rLabels = bSeriesFromColumns ? aResult.aColumnDescriptions : aResult.aRowDescriptions;
891
892 //categories
893 lcl_SequenceToVector( aSimpleCategories, rCategories );
894 if( rCategoriesRange.getLength() )
895 {
896 OUString aRange(rCategoriesRange);
897 if( xRangeConversion.is())
898 aRange = xRangeConversion->convertRangeToXML( aRange );
899 if( bSeriesFromColumns )
900 aResult.aRowDescriptions_Ranges.push_back( aRange );
901 else
902 aResult.aColumnDescriptions_Ranges.push_back( aRange );
903 }
904
905 // iterate over all sequences
906 size_t nSeqIdx = 0;
907 Sequence< Sequence< OUString > > aComplexLabels(nNumSequences);
908 for( ; aIt != aEnd; ++aIt, ++nSeqIdx )
909 {
910 OUString aRange;
911 Sequence< OUString >& rCurrentComplexLabel = aComplexLabels[nSeqIdx];
912 if( aIt->first.is())
913 {
914 lcl_getLabelStringSequence( rCurrentComplexLabel, aIt->first );
915 rLabels[nSeqIdx] = lcl_flattenStringSequence( rCurrentComplexLabel );
916 aRange = aIt->first->getSourceRangeRepresentation();
917 if( xRangeConversion.is())
918 aRange = xRangeConversion->convertRangeToXML( aRange );
919 }
920 else if( aIt->second.is())
921 {
922 rCurrentComplexLabel.realloc(1);
923 rLabels[nSeqIdx] = rCurrentComplexLabel[0] = lcl_flattenStringSequence(
924 aIt->second->generateLabel( chart2::data::LabelOrigin_SHORT_SIDE ));
925 }
926 if( bSeriesFromColumns )
927 aResult.aColumnDescriptions_Ranges.push_back( aRange );
928 else
929 aResult.aRowDescriptions_Ranges.push_back( aRange );
930
931 ::std::vector< double > aNumbers( lcl_getAllValuesFromSequence( aIt->second ));
932 if( bSeriesFromColumns )
933 {
934 const sal_Int32 nSize( static_cast< sal_Int32 >( aNumbers.size()));
935 for( sal_Int32 nIdx=0; nIdx<nSize; ++nIdx )
936 aResult.aDataInRows[nIdx][nSeqIdx] = aNumbers[nIdx];
937 }
938 else
939 aResult.aDataInRows[nSeqIdx] = aNumbers;
940
941 if( aIt->second.is())
942 {
943 aRange = aIt->second->getSourceRangeRepresentation();
944 if( xRangeConversion.is())
945 aRange = xRangeConversion->convertRangeToXML( aRange );
946 }
947 aResult.aDataRangeRepresentations.push_back( aRange );
948
949 //is column hidden?
950 if( !lcl_SequenceHasUnhiddenData(aIt->first) && !lcl_SequenceHasUnhiddenData(aIt->second) )
951 aResult.aHiddenColumns.push_back(nSeqIdx);
952 }
953 Sequence< Sequence< Any > >& rComplexAnyLabels = bSeriesFromColumns ? aResult.aComplexColumnDescriptions : aResult.aComplexRowDescriptions;//#i116544#
954 rComplexAnyLabels.realloc(aComplexLabels.getLength());
955 for( sal_Int32 nN=0; nN<aComplexLabels.getLength();nN++ )
956 {
957 Sequence< OUString >& rSource = aComplexLabels[nN];
958 Sequence< Any >& rTarget = rComplexAnyLabels[nN];
959 rTarget.realloc( rSource.getLength() );
960 for( sal_Int32 i=0; i<rSource.getLength(); i++ )
961 rTarget[i] = uno::makeAny( rSource[i] );
962 }
963 }
964 catch( uno::Exception & rEx )
965 {
966 (void)rEx; // avoid warning for pro build
967 OSL_TRACE( OUStringToOString( OUString( RTL_CONSTASCII_USTRINGPARAM(
968 "something went wrong during table data collection: " )) + rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
969 }
970
971 return aResult;
972 }
973
lcl_exportNumberFormat(const OUString & rPropertyName,const Reference<beans::XPropertySet> & xPropSet,SvXMLExport & rExport)974 void lcl_exportNumberFormat( const OUString& rPropertyName, const Reference< beans::XPropertySet >& xPropSet,
975 SvXMLExport& rExport )
976 {
977 if( xPropSet.is())
978 {
979 sal_Int32 nNumberFormat = 0;
980 Any aNumAny = xPropSet->getPropertyValue( rPropertyName );
981 if( (aNumAny >>= nNumberFormat) && (nNumberFormat != -1) )
982 rExport.addDataStyle( nNumberFormat );
983 }
984 }
985
986 ::std::vector< Reference< chart2::data::XDataSequence > >
lcl_getErrorBarSequences(const Reference<beans::XPropertySet> & xErrorBarProp)987 lcl_getErrorBarSequences( const Reference< beans::XPropertySet > & xErrorBarProp )
988 {
989 ::std::vector< Reference< chart2::data::XDataSequence > > aResult;
990 Reference< chart2::data::XDataSource > xErrorBarDataSource( xErrorBarProp, uno::UNO_QUERY );
991 if( !xErrorBarDataSource.is())
992 return aResult;
993
994 const OUString aRolePrefix( RTL_CONSTASCII_USTRINGPARAM( "error-bars-" ));
995 // const OUString aXRolePrefix( aRolePrefix + OUString( RTL_CONSTASCII_USTRINGPARAM( "x-" )));
996 // const OUString aYRolePrefix( aRolePrefix + OUString( RTL_CONSTASCII_USTRINGPARAM( "y-" )));
997 // const OUString aPositivePostfix( RTL_CONSTASCII_USTRINGPARAM( "positive" ));
998 // const OUString aNegativePostfix( RTL_CONSTASCII_USTRINGPARAM( "negative" ));
999
1000 Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences(
1001 xErrorBarDataSource->getDataSequences());
1002 for( sal_Int32 nI=0; nI< aSequences.getLength(); ++nI )
1003 {
1004 try
1005 {
1006 if( aSequences[nI].is())
1007 {
1008 Reference< chart2::data::XDataSequence > xSequence( aSequences[nI]->getValues());
1009 Reference< beans::XPropertySet > xSeqProp( xSequence, uno::UNO_QUERY_THROW );
1010 OUString aRole;
1011 if( ( xSeqProp->getPropertyValue(
1012 OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" ))) >>= aRole ) &&
1013 aRole.match( aRolePrefix ))
1014 {
1015 aResult.push_back( xSequence );
1016 }
1017 }
1018 }
1019 catch( uno::Exception & rEx )
1020 {
1021 #ifdef DBG_UTIL
1022 String aStr( rEx.Message );
1023 ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US );
1024 DBG_ERROR1( "chart:exporting error bar ranges: %s", aBStr.GetBuffer());
1025 #else
1026 (void)rEx; // avoid warning
1027 #endif
1028 }
1029 }
1030
1031 return aResult;
1032 }
1033
lcl_exportDomainForThisSequence(const Reference<chart2::data::XDataSequence> xValues,rtl::OUString & rFirstRangeForThisDomainIndex,SvXMLExport & rExport)1034 bool lcl_exportDomainForThisSequence( const Reference< chart2::data::XDataSequence > xValues, rtl::OUString& rFirstRangeForThisDomainIndex, SvXMLExport& rExport )
1035 {
1036 bool bDomainExported = false;
1037 if( xValues.is())
1038 {
1039 Reference< chart2::XChartDocument > xNewDoc( rExport.GetModel(), uno::UNO_QUERY );
1040 OUString aRange( lcl_ConvertRange( xValues->getSourceRangeRepresentation(), xNewDoc ) );
1041
1042 //work around error in OOo 2.0 (problems with multiple series having a domain element)
1043 if( !rFirstRangeForThisDomainIndex.getLength() || !aRange.equals(rFirstRangeForThisDomainIndex) )
1044 {
1045 rExport.AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, aRange);
1046 SvXMLElementExport aDomain( rExport, XML_NAMESPACE_CHART, XML_DOMAIN, sal_True, sal_True );
1047 bDomainExported = true;
1048 }
1049
1050 if( !rFirstRangeForThisDomainIndex.getLength() )
1051 rFirstRangeForThisDomainIndex = aRange;
1052 }
1053 return bDomainExported;
1054 }
1055
1056 } // anonymous namespace
1057
1058 struct SchXMLDataPointStruct
1059 {
1060 OUString maStyleName;
1061 sal_Int32 mnRepeat;
1062
SchXMLDataPointStructSchXMLDataPointStruct1063 SchXMLDataPointStruct() : mnRepeat( 1 ) {}
1064 };
1065
1066 // ========================================
1067 // class SchXMLExportHelper
1068 // ========================================
1069
SchXMLExportHelper(SvXMLExport & rExport,SvXMLAutoStylePoolP & rASPool)1070 SchXMLExportHelper::SchXMLExportHelper( SvXMLExport& rExport, SvXMLAutoStylePoolP& rASPool )
1071 : m_pImpl( new SchXMLExportHelper_Impl( rExport, rASPool ) )
1072 {
1073 }
1074
~SchXMLExportHelper()1075 SchXMLExportHelper::~SchXMLExportHelper()
1076 {
1077 delete m_pImpl;
1078 }
1079
getChartCLSID()1080 const OUString& SchXMLExportHelper::getChartCLSID()
1081 {
1082 return m_pImpl->msCLSID;
1083 }
1084
GetPropertySetMapper() const1085 UniReference< XMLPropertySetMapper > SchXMLExportHelper_Impl::GetPropertySetMapper() const
1086 {
1087 return mxPropertySetMapper;
1088 }
1089
exportAutoStyles()1090 void SchXMLExportHelper_Impl::exportAutoStyles()
1091 {
1092 if( mxExpPropMapper.is())
1093 {
1094 //ToDo: when embedded in calc/writer this is not necessary because the
1095 // numberformatter is shared between both documents
1096 mrExport.exportAutoDataStyles();
1097
1098 // export chart auto styles
1099 mrAutoStylePool.exportXML(
1100 XML_STYLE_FAMILY_SCH_CHART_ID
1101 , mrExport.GetDocHandler(),
1102 mrExport.GetMM100UnitConverter(),
1103 mrExport.GetNamespaceMap()
1104 );
1105
1106 // export auto styles for additional shapes
1107 mrExport.GetShapeExport()->exportAutoStyles();
1108 // and for text in additional shapes
1109 mrExport.GetTextParagraphExport()->exportTextAutoStyles();
1110 }
1111 }
1112
1113 // private methods
1114 // ---------------
1115
SchXMLExportHelper_Impl(SvXMLExport & rExport,SvXMLAutoStylePoolP & rASPool)1116 SchXMLExportHelper_Impl::SchXMLExportHelper_Impl(
1117 SvXMLExport& rExport,
1118 SvXMLAutoStylePoolP& rASPool ) :
1119 mrExport( rExport ),
1120 mrAutoStylePool( rASPool ),
1121 mbHasSeriesLabels( sal_False ),
1122 mbHasCategoryLabels( sal_False ),
1123 mbRowSourceColumns( sal_True )
1124 // #110680#
1125 // this id depends on the ServiceManager used due to the binary filter stripping.
1126 // ,msCLSID( rtl::OUString( SvGlobalName( SO3_SCH_CLASSID ).GetHexName()))
1127 {
1128 // #110680#
1129 // changed initialisation for msCLSID. Compare the ServiceInfo name with
1130 // the known name of the LegacyServiceManager.
1131 Reference<lang::XServiceInfo> xServiceInfo( mrExport.getServiceFactory(), uno::UNO_QUERY );
1132 DBG_ASSERT( xServiceInfo.is(), "XMultiServiceFactory without xServiceInfo (!)" );
1133 OUString rdbURL = xServiceInfo->getImplementationName();
1134 OUString implLegacyServiceManagerName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.office.LegacyServiceManager" ) );
1135
1136 if( rdbURL.equals( implLegacyServiceManagerName ))
1137 {
1138 msCLSID = OUString( SvGlobalName( BF_SO3_SCH_CLASSID ).GetHexName());
1139 }
1140 else
1141 {
1142 msCLSID = OUString( SvGlobalName( SO3_SCH_CLASSID ).GetHexName());
1143 }
1144
1145 msTableName = OUString::createFromAscii( "local-table" );
1146
1147 // create factory
1148 mxPropertyHandlerFactory = new XMLChartPropHdlFactory;
1149
1150 if( mxPropertyHandlerFactory.is() )
1151 {
1152 // create property set mapper
1153 mxPropertySetMapper = new XMLChartPropertySetMapper;
1154 }
1155
1156 mxExpPropMapper = new XMLChartExportPropertyMapper( mxPropertySetMapper, rExport );
1157
1158 // register chart auto-style family
1159 mrAutoStylePool.AddFamily(
1160 XML_STYLE_FAMILY_SCH_CHART_ID,
1161 OUString::createFromAscii( XML_STYLE_FAMILY_SCH_CHART_NAME ),
1162 mxExpPropMapper.get(),
1163 OUString::createFromAscii( XML_STYLE_FAMILY_SCH_CHART_PREFIX ));
1164
1165 // register shape family
1166 mrAutoStylePool.AddFamily(
1167 XML_STYLE_FAMILY_SD_GRAPHICS_ID,
1168 OUString::createFromAscii( XML_STYLE_FAMILY_SD_GRAPHICS_NAME ),
1169 mxExpPropMapper.get(),
1170 OUString::createFromAscii( XML_STYLE_FAMILY_SD_GRAPHICS_PREFIX ));
1171 // register paragraph family also for shapes
1172 mrAutoStylePool.AddFamily(
1173 XML_STYLE_FAMILY_TEXT_PARAGRAPH,
1174 GetXMLToken( XML_PARAGRAPH ),
1175 mxExpPropMapper.get(),
1176 String( 'P' ));
1177 // register text family also for shapes
1178 mrAutoStylePool.AddFamily(
1179 XML_STYLE_FAMILY_TEXT_TEXT,
1180 GetXMLToken( XML_TEXT ),
1181 mxExpPropMapper.get(),
1182 String( 'T' ));
1183 }
1184
~SchXMLExportHelper_Impl()1185 SchXMLExportHelper_Impl::~SchXMLExportHelper_Impl()
1186 {
1187 }
1188
collectAutoStyles(Reference<chart::XChartDocument> rChartDoc)1189 void SchXMLExportHelper_Impl::collectAutoStyles( Reference< chart::XChartDocument > rChartDoc )
1190 {
1191 parseDocument( rChartDoc, sal_False );
1192 }
1193
exportChart(Reference<chart::XChartDocument> rChartDoc,sal_Bool bIncludeTable)1194 void SchXMLExportHelper_Impl::exportChart( Reference< chart::XChartDocument > rChartDoc,
1195 sal_Bool bIncludeTable )
1196 {
1197 parseDocument( rChartDoc, sal_True, bIncludeTable );
1198 DBG_ASSERT( maAutoStyleNameQueue.empty(), "There are still remaining autostyle names in the queue" );
1199 }
1200
lcl_GetStringFromNumberSequence(const::com::sun::star::uno::Sequence<sal_Int32> & rSequenceMapping,bool bRemoveOneFromEachIndex)1201 ::rtl::OUString lcl_GetStringFromNumberSequence( const ::com::sun::star::uno::Sequence< sal_Int32 >& rSequenceMapping, bool bRemoveOneFromEachIndex /*should be true if having categories*/ )
1202 {
1203 const sal_Int32* pArray = rSequenceMapping.getConstArray();
1204 const sal_Int32 nSize = rSequenceMapping.getLength();
1205 sal_Int32 i = 0;
1206 OUStringBuffer aBuf;
1207 bool bHasPredecessor = false;
1208 for( i = 0; i < nSize; ++i )
1209 {
1210 sal_Int32 nIndex = pArray[ i ];
1211 if( bRemoveOneFromEachIndex )
1212 --nIndex;
1213 if(nIndex>=0)
1214 {
1215 if(bHasPredecessor)
1216 aBuf.append( static_cast< sal_Unicode >( ' ' ));
1217 aBuf.append( nIndex, 10 );
1218 bHasPredecessor = true;
1219 }
1220 }
1221 return aBuf.makeStringAndClear();
1222 }
1223
1224 /// if bExportContent is false the auto-styles are collected
parseDocument(Reference<chart::XChartDocument> & rChartDoc,sal_Bool bExportContent,sal_Bool bIncludeTable)1225 void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument >& rChartDoc,
1226 sal_Bool bExportContent,
1227 sal_Bool bIncludeTable )
1228 {
1229 Reference< chart2::XChartDocument > xNewDoc( rChartDoc, uno::UNO_QUERY );
1230 if( !rChartDoc.is() || !xNewDoc.is() )
1231 {
1232 DBG_ERROR( "No XChartDocument was given for export." );
1233 return;
1234 }
1235
1236 awt::Size aPageSize( getPageSize( xNewDoc ));
1237 if( bExportContent )
1238 addSize( aPageSize );
1239 Reference< chart::XDiagram > xDiagram = rChartDoc->getDiagram();
1240 Reference< chart2::XDiagram > xNewDiagram;
1241 if( xNewDoc.is())
1242 xNewDiagram.set( xNewDoc->getFirstDiagram());
1243
1244 //todo remove if model changes are notified and view is updated automatically
1245 if( bExportContent )
1246 {
1247 Reference< util::XRefreshable > xRefreshable( xNewDoc, uno::UNO_QUERY );
1248 if( xRefreshable.is() )
1249 xRefreshable->refresh();
1250 }
1251
1252 // get Properties of ChartDocument
1253 sal_Bool bHasMainTitle = sal_False;
1254 sal_Bool bHasSubTitle = sal_False;
1255 sal_Bool bHasLegend = sal_False;
1256 util::DateTime aNullDate(0,0,0,0,30,12,1899);
1257
1258 std::vector< XMLPropertyState > aPropertyStates;
1259
1260 Reference< beans::XPropertySet > xDocPropSet( rChartDoc, uno::UNO_QUERY );
1261 if( xDocPropSet.is())
1262 {
1263 try
1264 {
1265 Any aAny( xDocPropSet->getPropertyValue(
1266 OUString( RTL_CONSTASCII_USTRINGPARAM( "HasMainTitle" ))));
1267 aAny >>= bHasMainTitle;
1268 aAny = xDocPropSet->getPropertyValue(
1269 OUString( RTL_CONSTASCII_USTRINGPARAM( "HasSubTitle" )));
1270 aAny >>= bHasSubTitle;
1271 aAny = xDocPropSet->getPropertyValue(
1272 OUString( RTL_CONSTASCII_USTRINGPARAM( "HasLegend" )));
1273 aAny >>= bHasLegend;
1274 if ( bIncludeTable )
1275 {
1276 OUString sNullDate( RTL_CONSTASCII_USTRINGPARAM( "NullDate" ));
1277 aAny = xDocPropSet->getPropertyValue(sNullDate);
1278 if ( !aAny.hasValue() )
1279 {
1280 Reference<container::XChild> xChild(rChartDoc, uno::UNO_QUERY );
1281 if ( xChild.is() )
1282 {
1283 Reference< beans::XPropertySet > xParentDoc( xChild->getParent(),uno::UNO_QUERY);
1284 if ( xParentDoc.is() && xParentDoc->getPropertySetInfo()->hasPropertyByName(sNullDate) )
1285 aAny = xParentDoc->getPropertyValue(sNullDate);
1286 }
1287 }
1288
1289 aAny >>= aNullDate;
1290 }
1291 }
1292 catch( beans::UnknownPropertyException & )
1293 {
1294 DBG_WARNING( "Required property not found in ChartDocument" );
1295 }
1296 } // if( xDocPropSet.is())
1297
1298 if ( bIncludeTable && (aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899 ) )
1299 {
1300 SvXMLElementExport aSet( mrExport, XML_NAMESPACE_TABLE, XML_CALCULATION_SETTINGS, sal_True, sal_True );
1301 {
1302 ::rtl::OUStringBuffer sBuffer;
1303 SvXMLUnitConverter::convertDateTime(sBuffer,aNullDate);
1304 mrExport.AddAttribute( XML_NAMESPACE_TABLE,XML_DATE_VALUE,sBuffer.makeStringAndClear());
1305 SvXMLElementExport aNull( mrExport, XML_NAMESPACE_TABLE, XML_NULL_DATE, sal_True, sal_True );
1306 }
1307 }
1308
1309 // chart element
1310 // -------------
1311
1312 SvXMLElementExport* pElChart = 0;
1313 // get property states for autostyles
1314 if( mxExpPropMapper.is())
1315 {
1316 Reference< beans::XPropertySet > xPropSet( rChartDoc->getArea(), uno::UNO_QUERY );
1317 if( xPropSet.is())
1318 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1319 }
1320
1321 if( bExportContent )
1322 {
1323 //export data provider in xlink:href attribute
1324 const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
1325 if( nCurrentODFVersion >= SvtSaveOptions::ODFVER_012 )
1326 {
1327 OUString aDataProviderURL( RTL_CONSTASCII_USTRINGPARAM( ".." ) );
1328 if( xNewDoc->hasInternalDataProvider() )
1329 aDataProviderURL = OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) );
1330 else //special handling for data base data provider necessary
1331 {
1332 Reference< chart2::data::XDatabaseDataProvider > xDBDataProvider( xNewDoc->getDataProvider(), uno::UNO_QUERY );
1333 if( xDBDataProvider.is() )
1334 aDataProviderURL = OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) );
1335 }
1336 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, aDataProviderURL );
1337 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
1338 }
1339
1340 OUString sChartType( xDiagram->getDiagramType() );
1341
1342 // attributes
1343 // determine class
1344 if( sChartType.getLength())
1345 {
1346 enum XMLTokenEnum eXMLChartType = SchXMLTools::getTokenByChartType( sChartType, true /* bUseOldNames */ );
1347
1348 DBG_ASSERT( eXMLChartType != XML_TOKEN_INVALID, "invalid chart class" );
1349 if( eXMLChartType == XML_TOKEN_INVALID )
1350 eXMLChartType = XML_BAR;
1351
1352 if( eXMLChartType == XML_ADD_IN )
1353 {
1354 // sChartType is the servie-name of the add-in
1355 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS,
1356 mrExport.GetNamespaceMap().GetQNameByKey(
1357 XML_NAMESPACE_OOO, sChartType) );
1358 }
1359 else if( eXMLChartType != XML_TOKEN_INVALID )
1360 {
1361 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS,
1362 mrExport.GetNamespaceMap().GetQNameByKey(
1363 XML_NAMESPACE_CHART, GetXMLToken(eXMLChartType )) );
1364 }
1365
1366 //column-mapping or row-mapping
1367 if( maSequenceMapping.getLength() )
1368 {
1369 enum XMLTokenEnum eTransToken = ::xmloff::token::XML_ROW_MAPPING;
1370 if( mbRowSourceColumns )
1371 eTransToken = ::xmloff::token::XML_COLUMN_MAPPING;
1372 ::rtl::OUString aSequenceMappingStr( lcl_GetStringFromNumberSequence(
1373 maSequenceMapping, mbHasCategoryLabels && !xNewDoc->hasInternalDataProvider() ) );
1374
1375 mrExport.AddAttribute( XML_NAMESPACE_CHART,
1376 ::xmloff::token::GetXMLToken( eTransToken ),
1377 aSequenceMappingStr );
1378 }
1379 }
1380 // write style name
1381 AddAutoStyleAttribute( aPropertyStates );
1382
1383 //element
1384 pElChart = new SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_CHART, sal_True, sal_True );
1385 }
1386 else // autostyles
1387 {
1388 CollectAutoStyle( aPropertyStates );
1389 }
1390 // remove property states for autostyles
1391 aPropertyStates.clear();
1392
1393 // title element
1394 // -------------
1395
1396 if( bHasMainTitle )
1397 {
1398 // get property states for autostyles
1399 if( mxExpPropMapper.is())
1400 {
1401 Reference< beans::XPropertySet > xPropSet( rChartDoc->getTitle(), uno::UNO_QUERY );
1402 if( xPropSet.is())
1403 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1404 }
1405 if( bExportContent )
1406 {
1407 Reference< drawing::XShape > xShape = rChartDoc->getTitle();
1408 if( xShape.is()) // && "hasTitleBeenMoved"
1409 addPosition( xShape );
1410
1411 // write style name
1412 AddAutoStyleAttribute( aPropertyStates );
1413
1414 // element
1415 SvXMLElementExport aElTitle( mrExport, XML_NAMESPACE_CHART, XML_TITLE, sal_True, sal_True );
1416
1417 // content (text:p)
1418 Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
1419 if( xPropSet.is())
1420 {
1421 Any aAny( xPropSet->getPropertyValue(
1422 OUString( RTL_CONSTASCII_USTRINGPARAM( "String" ))));
1423 OUString aText;
1424 aAny >>= aText;
1425 exportText( aText );
1426 }
1427 }
1428 else // autostyles
1429 {
1430 CollectAutoStyle( aPropertyStates );
1431 }
1432 // remove property states for autostyles
1433 aPropertyStates.clear();
1434 }
1435
1436 // subtitle element
1437 // ----------------
1438
1439 if( bHasSubTitle )
1440 {
1441 // get property states for autostyles
1442 if( mxExpPropMapper.is())
1443 {
1444 Reference< beans::XPropertySet > xPropSet( rChartDoc->getSubTitle(), uno::UNO_QUERY );
1445 if( xPropSet.is())
1446 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1447 }
1448
1449 if( bExportContent )
1450 {
1451 Reference< drawing::XShape > xShape = rChartDoc->getSubTitle();
1452 if( xShape.is())
1453 addPosition( xShape );
1454
1455 // write style name
1456 AddAutoStyleAttribute( aPropertyStates );
1457
1458 // element (has no subelements)
1459 SvXMLElementExport aElSubTitle( mrExport, XML_NAMESPACE_CHART, XML_SUBTITLE, sal_True, sal_True );
1460
1461 // content (text:p)
1462 Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
1463 if( xPropSet.is())
1464 {
1465 Any aAny( xPropSet->getPropertyValue(
1466 OUString( RTL_CONSTASCII_USTRINGPARAM( "String" ))));
1467 OUString aText;
1468 aAny >>= aText;
1469 exportText( aText );
1470 }
1471 }
1472 else // autostyles
1473 {
1474 CollectAutoStyle( aPropertyStates );
1475 }
1476 // remove property states for autostyles
1477 aPropertyStates.clear();
1478 }
1479
1480 // legend element
1481 // --------------
1482 if( bHasLegend )
1483 {
1484 // get property states for autostyles
1485 if( mxExpPropMapper.is())
1486 {
1487 Reference< beans::XPropertySet > xPropSet( rChartDoc->getLegend(), uno::UNO_QUERY );
1488 if( xPropSet.is())
1489 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1490 }
1491
1492 if( bExportContent )
1493 {
1494 Reference< beans::XPropertySet > xProp( rChartDoc->getLegend(), uno::UNO_QUERY );
1495 if( xProp.is())
1496 {
1497 // export legend anchor position
1498 try
1499 {
1500 Any aAny( xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Alignment" ))));
1501 if( SchXMLEnumConverter::getLegendPositionConverter().exportXML( msString, aAny, mrExport.GetMM100UnitConverter() ) )
1502 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_LEGEND_POSITION, msString );
1503 }
1504 catch( beans::UnknownPropertyException & )
1505 {
1506 DBG_WARNING( "Property Align not found in ChartLegend" );
1507 }
1508
1509 // export absolute legend position
1510 Reference< drawing::XShape > xLegendShape( xProp, uno::UNO_QUERY );
1511 addPosition( xLegendShape );
1512
1513 // export legend size
1514 const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
1515 if( xLegendShape.is() && nCurrentODFVersion >= SvtSaveOptions::ODFVER_012 && ( SvtSaveOptions::IsODFExtended( nCurrentODFVersion ) || nCurrentODFVersion >= SvtSaveOptions::ODFVER_013 ) )//do not export legend-expansion to ODF 1.0 and export size only if extensions are enabled or in ODF 1.3 //#i28670# todo: change this dependent on fileformat evolution
1516 {
1517 try
1518 {
1519 chart::ChartLegendExpansion nLegendExpansion = chart::ChartLegendExpansion_HIGH;
1520 OUString aExpansionString;
1521 Any aAny( xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Expansion" ))));
1522 bool bHasExpansion = (aAny >>= nLegendExpansion);
1523 if( bHasExpansion && SchXMLEnumConverter::getLegendExpansionConverter().exportXML( aExpansionString, aAny, mrExport.GetMM100UnitConverter() ) )
1524 {
1525 mrExport.AddAttribute( XML_NAMESPACE_STYLE, XML_LEGEND_EXPANSION, aExpansionString );
1526 if( nLegendExpansion == chart::ChartLegendExpansion_CUSTOM)
1527 {
1528 awt::Size aSize( xLegendShape->getSize() );
1529 addSize( aSize, nCurrentODFVersion < SvtSaveOptions::ODFVER_013 );
1530 rtl::OUStringBuffer aAspectRatioString;
1531 SvXMLUnitConverter::convertDouble(aAspectRatioString, double(aSize.Width)/double(aSize.Height));
1532 mrExport.AddAttribute( XML_NAMESPACE_STYLE, XML_LEGEND_EXPANSION_ASPECT_RATIO, aAspectRatioString.makeStringAndClear() );
1533 }
1534 }
1535 }
1536 catch( beans::UnknownPropertyException & )
1537 {
1538 DBG_WARNING( "Property Expansion not found in ChartLegend" );
1539 }
1540 }
1541 }
1542
1543 // write style name
1544 AddAutoStyleAttribute( aPropertyStates );
1545
1546 // element
1547 SvXMLElementExport aLegend( mrExport, XML_NAMESPACE_CHART, XML_LEGEND, sal_True, sal_True );
1548 }
1549 else // autostyles
1550 {
1551 CollectAutoStyle( aPropertyStates );
1552 }
1553 // remove property states for autostyles
1554 aPropertyStates.clear();
1555 }
1556
1557 // plot-area element
1558 // -----------------
1559 if( xDiagram.is())
1560 exportPlotArea( xDiagram, xNewDiagram, aPageSize, bExportContent, bIncludeTable );
1561
1562 // export additional shapes
1563 // ------------------------
1564 if( xDocPropSet.is() )
1565 {
1566 if( bExportContent )
1567 {
1568 if( mxAdditionalShapes.is())
1569 {
1570 // can't call exportShapes with all shapes because the
1571 // initialisation happened with the complete draw page and not
1572 // the XShapes object used here. Thus the shapes have to be
1573 // exported one by one
1574 UniReference< XMLShapeExport > rShapeExport = mrExport.GetShapeExport();
1575 Reference< drawing::XShape > xShape;
1576 const sal_Int32 nShapeCount( mxAdditionalShapes->getCount());
1577 for( sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++ )
1578 {
1579 mxAdditionalShapes->getByIndex( nShapeId ) >>= xShape;
1580 DBG_ASSERT( xShape.is(), "Shape without an XShape?" );
1581 if( ! xShape.is())
1582 continue;
1583
1584 rShapeExport->exportShape( xShape );
1585 }
1586 // this would be the easier way if it worked:
1587 //mrExport.GetShapeExport()->exportShapes( mxAdditionalShapes );
1588 }
1589 }
1590 else
1591 {
1592 // get a sequence of non-chart shapes (inserted via clipboard)
1593 try
1594 {
1595 Any aShapesAny = xDocPropSet->getPropertyValue( OUString::createFromAscii( "AdditionalShapes" ));
1596 aShapesAny >>= mxAdditionalShapes;
1597 if( mrExport.getDefaultVersion() >= SvtSaveOptions::ODFVER_010 && mrExport.getDefaultVersion() < SvtSaveOptions::ODFVER_013 && !SvtSaveOptions::IsODFExtended( mrExport.getDefaultVersion() ) )
1598 mxAdditionalShapes.clear();
1599 }
1600 catch( uno::Exception & rEx )
1601 {
1602 (void)rEx; // avoid warning for pro build
1603 OSL_TRACE(
1604 OUStringToOString(
1605 OUString( RTL_CONSTASCII_USTRINGPARAM(
1606 "AdditionalShapes not found: " )) +
1607 rEx.Message,
1608 RTL_TEXTENCODING_ASCII_US ).getStr());
1609 }
1610
1611 if( mxAdditionalShapes.is())
1612 {
1613 // seek shapes has to be called for the whole page because in
1614 // the shape export the vector of shapes is accessed via the
1615 // ZOrder which might be (actually is) larger than the number of
1616 // shapes in mxAdditionalShapes
1617 Reference< drawing::XDrawPageSupplier > xSupplier( rChartDoc, uno::UNO_QUERY );
1618 DBG_ASSERT( xSupplier.is(), "Cannot retrieve draw page to initialize shape export" );
1619 if( xSupplier.is() )
1620 {
1621 Reference< drawing::XShapes > xDrawPage( xSupplier->getDrawPage(), uno::UNO_QUERY );
1622 DBG_ASSERT( xDrawPage.is(), "Invalid draw page for initializing shape export" );
1623 if( xDrawPage.is())
1624 mrExport.GetShapeExport()->seekShapes( xDrawPage );
1625 }
1626
1627 // can't call collectShapesAutoStyles with all shapes because
1628 // the initialisation happened with the complete draw page and
1629 // not the XShapes object used here. Thus the shapes have to be
1630 // exported one by one
1631 UniReference< XMLShapeExport > rShapeExport = mrExport.GetShapeExport();
1632 Reference< drawing::XShape > xShape;
1633 const sal_Int32 nShapeCount( mxAdditionalShapes->getCount());
1634 for( sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++ )
1635 {
1636 mxAdditionalShapes->getByIndex( nShapeId ) >>= xShape;
1637 DBG_ASSERT( xShape.is(), "Shape without an XShape?" );
1638 if( ! xShape.is())
1639 continue;
1640
1641 rShapeExport->collectShapeAutoStyles( xShape );
1642 }
1643 // this would be the easier way if it worked:
1644 // mrExport.GetShapeExport()->collectShapesAutoStyles( mxAdditionalShapes );
1645 }
1646 }
1647 }
1648
1649 // table element
1650 // (is included as subelement of chart)
1651 // ------------------------------------
1652 if( bExportContent )
1653 {
1654 // #85929# always export table, otherwise clipboard may loose data
1655 exportTable();
1656 }
1657
1658 // close <chart:chart> element
1659 if( pElChart )
1660 delete pElChart;
1661 }
1662
lcl_exportComplexLabel(const Sequence<uno::Any> & rComplexLabel,SvXMLExport & rExport)1663 void lcl_exportComplexLabel( const Sequence< uno::Any >& rComplexLabel, SvXMLExport& rExport )
1664 {
1665 sal_Int32 nLength = rComplexLabel.getLength();
1666 if( nLength<=1 )
1667 return;
1668 SvXMLElementExport aTextList( rExport, XML_NAMESPACE_TEXT, XML_LIST, sal_True, sal_True );
1669 for(sal_Int32 nN=0; nN<nLength; nN++)
1670 {
1671 SvXMLElementExport aListItem( rExport, XML_NAMESPACE_TEXT, XML_LIST_ITEM, sal_True, sal_True );
1672 OUString aString;
1673 if( !(rComplexLabel[nN]>>=aString) )
1674 {
1675 //todo?
1676 }
1677 SchXMLTools::exportText( rExport, aString, false /*bConvertTabsLFs*/ );
1678 }
1679 }
1680
exportTable()1681 void SchXMLExportHelper_Impl::exportTable()
1682 {
1683 // table element
1684 // -------------
1685 mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, msTableName );
1686
1687 try
1688 {
1689 bool bProtected = false;
1690 Reference< beans::XPropertySet > xProps( mrExport.GetModel(), uno::UNO_QUERY_THROW );
1691 if ( ( xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DisableDataTableDialog" ) ) ) >>= bProtected ) &&
1692 bProtected )
1693 {
1694 mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE );
1695 }
1696 }
1697 catch ( uno::Exception& )
1698 {
1699 }
1700
1701 SvXMLElementExport aTable( mrExport, XML_NAMESPACE_TABLE, XML_TABLE, sal_True, sal_True );
1702
1703 bool bHasOwnData = false;
1704 Reference< chart2::XChartDocument > xNewDoc( mrExport.GetModel(), uno::UNO_QUERY );
1705 Reference< chart2::data::XRangeXMLConversion > xRangeConversion;
1706 if( xNewDoc.is())
1707 {
1708 bHasOwnData = xNewDoc->hasInternalDataProvider();
1709 xRangeConversion.set( xNewDoc->getDataProvider(), uno::UNO_QUERY );
1710 }
1711
1712 Reference< chart2::XAnyDescriptionAccess > xAnyDescriptionAccess;
1713 {
1714 Reference< chart::XChartDocument > xChartDoc( mrExport.GetModel(), uno::UNO_QUERY );
1715 if( xChartDoc.is() )
1716 xAnyDescriptionAccess = Reference< chart2::XAnyDescriptionAccess >( xChartDoc->getData(), uno::UNO_QUERY );
1717 }
1718
1719 if( bHasOwnData )
1720 lcl_ReorderInternalSequencesAccordingToTheirRangeName( m_aDataSequencesToExport );
1721 lcl_TableData aData( lcl_getDataForLocalTable( m_aDataSequencesToExport
1722 , xAnyDescriptionAccess, maCategoriesRange
1723 , mbRowSourceColumns, xRangeConversion ));
1724
1725 tStringVector::const_iterator aDataRangeIter( aData.aDataRangeRepresentations.begin());
1726 const tStringVector::const_iterator aDataRangeEndIter( aData.aDataRangeRepresentations.end());
1727
1728 tStringVector::const_iterator aRowDescriptions_RangeIter( aData.aRowDescriptions_Ranges.begin());
1729 const tStringVector::const_iterator aRowDescriptions_RangeEnd( aData.aRowDescriptions_Ranges.end());
1730
1731 // declare columns
1732 {
1733 SvXMLElementExport aHeaderColumns( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, sal_True, sal_True );
1734 SvXMLElementExport aHeaderColumn( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True );
1735 }
1736 if( !aData.aHiddenColumns.empty() || !aData.aColumnDescriptions.empty() )
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 if( !aData.aDataInRows.empty() )
1831 {
1832 SvXMLElementExport aRows( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_ROWS, sal_True, sal_True );
1833 tStringVector::const_iterator aRowDescriptionsIter( aData.aRowDescriptions.begin());
1834 const Sequence< Sequence< uno::Any > >& rComplexRowDescriptions = aData.aComplexRowDescriptions;
1835 sal_Int32 nComplexCount = rComplexRowDescriptions.getLength();
1836 sal_Int32 nC = 0;
1837
1838 for( t2DNumberContainer::const_iterator aRowIt( aData.aDataInRows.begin())
1839 ; aRowIt != aData.aDataInRows.end()
1840 ; ++aRowIt, ++nC )
1841 {
1842 SvXMLElementExport aRow( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True );
1843
1844 //export row descriptions
1845 {
1846 bool bExportString = true;
1847 if( nC < nComplexCount )
1848 {
1849 const Sequence< uno::Any >& rComplexLabel = rComplexRowDescriptions[nC];
1850 if( rComplexLabel.getLength()>0 )
1851 {
1852 double fValue=0.0;
1853 if( rComplexLabel[0] >>=fValue )
1854 {
1855 bExportString = false;
1856
1857 SvXMLUnitConverter::convertDouble( msStringBuffer, fValue );
1858 msString = msStringBuffer.makeStringAndClear();
1859 mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT );
1860 mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE, msString );
1861 }
1862 }
1863 }
1864 if( bExportString )
1865 {
1866 mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING );
1867 }
1868
1869 SvXMLElementExport aCell( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True );
1870 if( aRowDescriptionsIter != aData.aRowDescriptions.end())
1871 {
1872 exportText( *aRowDescriptionsIter );
1873 if( nC < nComplexCount )
1874 lcl_exportComplexLabel( rComplexRowDescriptions[nC], mrExport );
1875 if( !bHasOwnData && aRowDescriptions_RangeIter != aRowDescriptions_RangeEnd )
1876 {
1877 // remind the original range to allow a correct re-association when copying via clipboard
1878 SchXMLTools::exportRangeToSomewhere( mrExport, *aRowDescriptions_RangeIter );
1879 ++aRowDescriptions_RangeIter;
1880 }
1881 ++aRowDescriptionsIter;
1882 }
1883 }
1884
1885 //export row values
1886 for( t2DNumberContainer::value_type::const_iterator aColIt( aRowIt->begin());
1887 aColIt != aRowIt->end(); ++aColIt )
1888 {
1889 SvXMLUnitConverter::convertDouble( msStringBuffer, *aColIt );
1890 msString = msStringBuffer.makeStringAndClear();
1891 mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT );
1892 mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE, msString );
1893 SvXMLElementExport aCell( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True );
1894 exportText( msString, false ); // do not convert tabs and lfs
1895 if( ( !bHasOwnData && aDataRangeIter != aDataRangeEndIter ) &&
1896 ( mbRowSourceColumns || (aColIt == aRowIt->begin()) ) )
1897 {
1898 // remind the original range to allow a correct re-association when copying via clipboard
1899 if ((*aDataRangeIter).getLength())
1900 SchXMLTools::exportRangeToSomewhere( mrExport, *aDataRangeIter );
1901 ++aDataRangeIter;
1902 }
1903 }
1904 }
1905 }
1906
1907 // if range iterator was used it should have reached its end
1908 OSL_ASSERT( bHasOwnData || (aDataRangeIter == aDataRangeEndIter) );
1909 OSL_ASSERT( bHasOwnData || (aRowDescriptions_RangeIter == aRowDescriptions_RangeEnd) );
1910 }
1911
1912 namespace
1913 {
1914
lcl_getCooSys(const Reference<chart2::XDiagram> & xNewDiagram)1915 Reference< chart2::XCoordinateSystem > lcl_getCooSys( const Reference< chart2::XDiagram > & xNewDiagram )
1916 {
1917 Reference< chart2::XCoordinateSystem > xCooSys;
1918 Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xNewDiagram, uno::UNO_QUERY );
1919 if(xCooSysCnt.is())
1920 {
1921 Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems() );
1922 if(aCooSysSeq.getLength()>0)
1923 xCooSys = aCooSysSeq[0];
1924 }
1925 return xCooSys;
1926 }
1927
lcl_getAxis(const Reference<chart2::XCoordinateSystem> & xCooSys,enum XMLTokenEnum eDimension,bool bPrimary=true)1928 Reference< chart2::XAxis > lcl_getAxis( const Reference< chart2::XCoordinateSystem >& xCooSys,
1929 enum XMLTokenEnum eDimension, bool bPrimary=true )
1930 {
1931 Reference< chart2::XAxis > xNewAxis;
1932 try
1933 {
1934 if( xCooSys.is() )
1935 {
1936 sal_Int32 nDimensionIndex=0;
1937 switch( eDimension )
1938 {
1939 case XML_X:
1940 nDimensionIndex=0;
1941 break;
1942 case XML_Y:
1943 nDimensionIndex=1;
1944 break;
1945 case XML_Z:
1946 nDimensionIndex=2;
1947 break;
1948 default:
1949 break;
1950 }
1951
1952 xNewAxis = xCooSys->getAxisByDimension( nDimensionIndex, bPrimary ? 0 : 1 );
1953 }
1954 }
1955 catch( const uno::Exception & )
1956 {
1957 }
1958 return xNewAxis;
1959 }
1960
1961 }
1962
exportPlotArea(Reference<chart::XDiagram> xDiagram,Reference<chart2::XDiagram> xNewDiagram,const awt::Size & rPageSize,sal_Bool bExportContent,sal_Bool bIncludeTable)1963 void SchXMLExportHelper_Impl::exportPlotArea(
1964 Reference< chart::XDiagram > xDiagram,
1965 Reference< chart2::XDiagram > xNewDiagram,
1966 const awt::Size & rPageSize,
1967 sal_Bool bExportContent,
1968 sal_Bool bIncludeTable )
1969 {
1970 DBG_ASSERT( xDiagram.is(), "Invalid XDiagram as parameter" );
1971 if( ! xDiagram.is())
1972 return;
1973
1974 // variables for autostyles
1975 Reference< beans::XPropertySet > xPropSet;
1976 std::vector< XMLPropertyState > aPropertyStates;
1977
1978 sal_Bool bIs3DChart = sal_False;
1979 drawing::HomogenMatrix aTransMatrix;
1980
1981 msStringBuffer.setLength( 0 );
1982
1983 // plot-area element
1984 // -----------------
1985
1986 SvXMLElementExport* pElPlotArea = 0;
1987 // get property states for autostyles
1988 xPropSet = Reference< beans::XPropertySet >( xDiagram, uno::UNO_QUERY );
1989 if( xPropSet.is())
1990 {
1991 if( mxExpPropMapper.is())
1992 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1993 }
1994 if( bExportContent )
1995 {
1996 UniReference< XMLShapeExport > rShapeExport;
1997
1998 // write style name
1999 AddAutoStyleAttribute( aPropertyStates );
2000
2001 if( msChartAddress.getLength() )
2002 {
2003 if( !bIncludeTable )
2004 mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, msChartAddress );
2005
2006 Reference< chart::XChartDocument > xDoc( mrExport.GetModel(), uno::UNO_QUERY );
2007 if( xDoc.is() )
2008 {
2009 Reference< beans::XPropertySet > xDocProp( xDoc, uno::UNO_QUERY );
2010 if( xDocProp.is())
2011 {
2012 Any aAny;
2013 sal_Bool bFirstCol = false, bFirstRow = false;
2014
2015 try
2016 {
2017 aAny = xDocProp->getPropertyValue(
2018 OUString( RTL_CONSTASCII_USTRINGPARAM( "DataSourceLabelsInFirstColumn" )));
2019 aAny >>= bFirstCol;
2020 aAny = xDocProp->getPropertyValue(
2021 OUString( RTL_CONSTASCII_USTRINGPARAM( "DataSourceLabelsInFirstRow" )));
2022 aAny >>= bFirstRow;
2023
2024 if( bFirstCol || bFirstRow )
2025 {
2026 mrExport.AddAttribute( XML_NAMESPACE_CHART,
2027 ::xmloff::token::GetXMLToken( ::xmloff::token::XML_DATA_SOURCE_HAS_LABELS ),
2028 ( bFirstCol
2029 ? ( bFirstRow
2030 ? ::xmloff::token::GetXMLToken( ::xmloff::token::XML_BOTH )
2031 : ::xmloff::token::GetXMLToken( ::xmloff::token::XML_COLUMN ))
2032 : ::xmloff::token::GetXMLToken( ::xmloff::token::XML_ROW )));
2033 }
2034 }
2035 catch( beans::UnknownPropertyException & )
2036 {
2037 DBG_ERRORFILE( "Properties missing" );
2038 }
2039 }
2040 }
2041 }
2042
2043 // #i72973#, #144135# only export table-number-list in OOo format (also for binary)
2044 Reference< beans::XPropertySet > xExportInfo( mrExport.getExportInfo());
2045 if( msTableNumberList.getLength() &&
2046 xExportInfo.is())
2047 {
2048 try
2049 {
2050 OUString sExportTableNumListPropName( RTL_CONSTASCII_USTRINGPARAM("ExportTableNumberList"));
2051 Reference< beans::XPropertySetInfo > xInfo( xExportInfo->getPropertySetInfo());
2052 bool bExportTableNumberList = false;
2053 if( xInfo.is() && xInfo->hasPropertyByName( sExportTableNumListPropName ) &&
2054 (xExportInfo->getPropertyValue( sExportTableNumListPropName ) >>= bExportTableNumberList) &&
2055 bExportTableNumberList )
2056 {
2057 // this attribute is for charts embedded in calc documents only.
2058 // With this you are able to store a file again in 5.0 binary format
2059 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_TABLE_NUMBER_LIST, msTableNumberList );
2060 }
2061 }
2062 catch( uno::Exception & rEx )
2063 {
2064 #ifdef DBG_UTIL
2065 String aStr( rEx.Message );
2066 ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US );
2067 DBG_ERROR1( "chart:TableNumberList property caught: %s", aBStr.GetBuffer());
2068 #else
2069 (void)rEx; // avoid warning
2070 #endif
2071 }
2072 }
2073
2074 // attributes
2075 Reference< drawing::XShape > xShape ( xDiagram, uno::UNO_QUERY );
2076 if( xShape.is())
2077 {
2078 addPosition( xShape );
2079 addSize( xShape );
2080 }
2081
2082 if( xPropSet.is())
2083 {
2084 Any aAny;
2085
2086 // 3d attributes
2087 try
2088 {
2089 aAny = xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Dim3D" )));
2090 aAny >>= bIs3DChart;
2091
2092 if( bIs3DChart )
2093 {
2094 rShapeExport = mrExport.GetShapeExport();
2095 if( rShapeExport.is())
2096 rShapeExport->export3DSceneAttributes( xPropSet );
2097 }
2098 }
2099 catch( uno::Exception & rEx )
2100 {
2101 #ifdef DBG_UTIL
2102 String aStr( rEx.Message );
2103 ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US );
2104 DBG_ERROR1( "chart:exportPlotAreaException caught: %s", aBStr.GetBuffer());
2105 #else
2106 (void)rEx; // avoid warning
2107 #endif
2108 }
2109 }
2110
2111 // plot-area element
2112 pElPlotArea = new SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_PLOT_AREA, sal_True, sal_True );
2113
2114 //inner position rectangle element
2115 exportCoordinateRegion( xDiagram );
2116
2117 // light sources (inside plot area element)
2118 if( bIs3DChart &&
2119 rShapeExport.is())
2120 rShapeExport->export3DLamps( xPropSet );
2121 }
2122 else // autostyles
2123 {
2124 CollectAutoStyle( aPropertyStates );
2125 }
2126 // remove property states for autostyles
2127 aPropertyStates.clear();
2128
2129 // axis elements
2130 // -------------
2131 exportAxes( xDiagram, xNewDiagram, bExportContent );
2132
2133 // series elements
2134 // ---------------
2135 Reference< chart2::XAxis > xSecondYAxis = lcl_getAxis( lcl_getCooSys( xNewDiagram ), XML_Y, false );
2136 exportSeries( xNewDiagram, rPageSize, bExportContent, xSecondYAxis.is() );
2137
2138 // stock-chart elements
2139 OUString sChartType ( xDiagram->getDiagramType());
2140 if( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.StockDiagram" )))
2141 {
2142 Reference< chart::XStatisticDisplay > xStockPropProvider( xDiagram, uno::UNO_QUERY );
2143 if( xStockPropProvider.is())
2144 {
2145 // stock-gain-marker
2146 Reference< beans::XPropertySet > xStockPropSet = xStockPropProvider->getUpBar();
2147 if( xStockPropSet.is())
2148 {
2149 aPropertyStates.clear();
2150 aPropertyStates = mxExpPropMapper->Filter( xStockPropSet );
2151
2152 if( !aPropertyStates.empty() )
2153 {
2154 if( bExportContent )
2155 {
2156 AddAutoStyleAttribute( aPropertyStates );
2157
2158 SvXMLElementExport aGain( mrExport, XML_NAMESPACE_CHART, XML_STOCK_GAIN_MARKER, sal_True, sal_True );
2159 }
2160 else
2161 {
2162 CollectAutoStyle( aPropertyStates );
2163 }
2164 }
2165 }
2166
2167 // stock-loss-marker
2168 xStockPropSet = xStockPropProvider->getDownBar();
2169 if( xStockPropSet.is())
2170 {
2171 aPropertyStates.clear();
2172 aPropertyStates = mxExpPropMapper->Filter( xStockPropSet );
2173
2174 if( !aPropertyStates.empty() )
2175 {
2176 if( bExportContent )
2177 {
2178 AddAutoStyleAttribute( aPropertyStates );
2179
2180 SvXMLElementExport aGain( mrExport, XML_NAMESPACE_CHART, XML_STOCK_LOSS_MARKER, sal_True, sal_True );
2181 }
2182 else
2183 {
2184 CollectAutoStyle( aPropertyStates );
2185 }
2186 }
2187 }
2188
2189 // stock-range-line
2190 xStockPropSet = xStockPropProvider->getMinMaxLine();
2191 if( xStockPropSet.is())
2192 {
2193 aPropertyStates.clear();
2194 aPropertyStates = mxExpPropMapper->Filter( xStockPropSet );
2195
2196 if( !aPropertyStates.empty() )
2197 {
2198 if( bExportContent )
2199 {
2200 AddAutoStyleAttribute( aPropertyStates );
2201
2202 SvXMLElementExport aGain( mrExport, XML_NAMESPACE_CHART, XML_STOCK_RANGE_LINE, sal_True, sal_True );
2203 }
2204 else
2205 {
2206 CollectAutoStyle( aPropertyStates );
2207 }
2208 }
2209 }
2210 }
2211 }
2212
2213 // wall and floor element
2214 // ----------------------
2215
2216 Reference< chart::X3DDisplay > xWallFloorSupplier( xDiagram, uno::UNO_QUERY );
2217 if( mxExpPropMapper.is() &&
2218 xWallFloorSupplier.is())
2219 {
2220 // remove property states for autostyles
2221 aPropertyStates.clear();
2222
2223 Reference< beans::XPropertySet > xWallPropSet( xWallFloorSupplier->getWall(), uno::UNO_QUERY );
2224 if( xWallPropSet.is())
2225 {
2226 aPropertyStates = mxExpPropMapper->Filter( xWallPropSet );
2227
2228 if( !aPropertyStates.empty() )
2229 {
2230 // write element
2231 if( bExportContent )
2232 {
2233 // add style name attribute
2234 AddAutoStyleAttribute( aPropertyStates );
2235
2236 SvXMLElementExport aWall( mrExport, XML_NAMESPACE_CHART, XML_WALL, sal_True, sal_True );
2237 }
2238 else // autostyles
2239 {
2240 CollectAutoStyle( aPropertyStates );
2241 }
2242 }
2243 }
2244
2245 // floor element
2246 // -------------
2247
2248 // remove property states for autostyles
2249 aPropertyStates.clear();
2250
2251 Reference< beans::XPropertySet > xFloorPropSet( xWallFloorSupplier->getFloor(), uno::UNO_QUERY );
2252 if( xFloorPropSet.is())
2253 {
2254 aPropertyStates = mxExpPropMapper->Filter( xFloorPropSet );
2255
2256 if( !aPropertyStates.empty() )
2257 {
2258 // write element
2259 if( bExportContent )
2260 {
2261 // add style name attribute
2262 AddAutoStyleAttribute( aPropertyStates );
2263
2264 SvXMLElementExport aFloor( mrExport, XML_NAMESPACE_CHART, XML_FLOOR, sal_True, sal_True );
2265 }
2266 else // autostyles
2267 {
2268 CollectAutoStyle( aPropertyStates );
2269 }
2270 }
2271 }
2272 }
2273
2274 if( pElPlotArea )
2275 delete pElPlotArea;
2276 }
2277
exportCoordinateRegion(const uno::Reference<chart::XDiagram> & xDiagram)2278 void SchXMLExportHelper_Impl::exportCoordinateRegion( const uno::Reference< chart::XDiagram >& xDiagram )
2279 {
2280 const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2281 const sal_Bool bODF13( nCurrentODFVersion >= SvtSaveOptions::ODFVER_013 );
2282 if( !bODF13 && !SvtSaveOptions::IsODFExtended( nCurrentODFVersion ) )//ODF 1.2 and older have no coordinate region, extended mode writes it as an extension
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, bODF13 ? XML_NAMESPACE_CHART : XML_NAMESPACE_CHART_EXT, XML_COORDINATE_REGION, sal_True, sal_True );
2295 }
2296
2297 namespace
2298 {
lcl_getTimeUnitToken(sal_Int32 nTimeUnit)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
exportDateScale(const Reference<beans::XPropertySet> xAxisProps)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
exportAxisTitle(const Reference<beans::XPropertySet> xTitleProps,bool bExportContent)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
exportGrid(const Reference<beans::XPropertySet> xGridProperties,bool bMajor,bool bExportContent)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
lcl_exportAxisType(const Reference<chart2::XAxis> xChart2Axis,SvXMLExport & rExport)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( !SvtSaveOptions::IsODFExtended( nCurrentODFVersion ) ) //#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
exportAxis(enum XMLTokenEnum eDimension,enum XMLTokenEnum eAxisName,const Reference<beans::XPropertySet> xAxisProps,const Reference<chart2::XAxis> & xChart2Axis,const OUString & rCategoriesRange,bool bHasTitle,bool bHasMajorGrid,bool bHasMinorGrid,bool bExportContent)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
exportAxes(const Reference<chart::XDiagram> & xDiagram,const Reference<chart2::XDiagram> & xNewDiagram,sal_Bool bExportContent)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 {
lcl_hasNoValuesButText(const uno::Reference<chart2::data::XDataSequence> & xDataSequence)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
exportSeries(const Reference<chart2::XDiagram> & xNewDiagram,const awt::Size & rPageSize,sal_Bool bExportContent,sal_Bool bHasTwoYAxes)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
exportRegressionCurve(const Reference<chart2::XDataSeries> & xSeries,const Reference<beans::XPropertySet> & xSeriesProp,const awt::Size & rPageSize,sal_Bool bExportContent)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
exportCandleStickSeries(const Sequence<Reference<chart2::XDataSeries>> & aSeriesSeq,const Reference<chart2::XDiagram> & xDiagram,sal_Bool bJapaneseCandleSticks,sal_Bool bExportContent)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
exportDataPoints(const uno::Reference<beans::XPropertySet> & xSeriesProperties,sal_Int32 nSeriesLength,const uno::Reference<chart2::XDiagram> & xDiagram,sal_Bool bExportContent)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
getCellAddress(sal_Int32 nCol,sal_Int32 nRow)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
addPosition(const awt::Point & rPosition)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
addPosition(Reference<drawing::XShape> xShape)3603 void SchXMLExportHelper_Impl::addPosition( Reference< drawing::XShape > xShape )
3604 {
3605 if( xShape.is())
3606 addPosition( xShape->getPosition());
3607 }
3608
addSize(const awt::Size & rSize,bool bIsOOoNamespace)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
addSize(Reference<drawing::XShape> xShape,bool bIsOOoNamespace)3621 void SchXMLExportHelper_Impl::addSize( Reference< drawing::XShape > xShape, bool bIsOOoNamespace )
3622 {
3623 if( xShape.is())
3624 addSize( xShape->getSize(), bIsOOoNamespace );
3625 }
3626
getPageSize(const Reference<chart2::XChartDocument> & xChartDoc) const3627 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
CollectAutoStyle(const std::vector<XMLPropertyState> & aStates)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
AddAutoStyleAttribute(const std::vector<XMLPropertyState> & aStates)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
exportText(const OUString & rText,bool bConvertTabsLFs)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#
SchXMLExport(const Reference<lang::XMultiServiceFactory> & xServiceFactory,sal_uInt16 nExportFlags)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( SvtSaveOptions::IsODFExtended( getDefaultVersion() ) )
3673 _GetNamespaceMap().Add( GetXMLToken(XML_NP_CHART_EXT), GetXMLToken(XML_N_CHART_EXT), XML_NAMESPACE_CHART_EXT);
3674 }
3675
3676
~SchXMLExport()3677 SchXMLExport::~SchXMLExport()
3678 {
3679 // stop progress view
3680 if( mxStatusIndicator.is())
3681 {
3682 mxStatusIndicator->end();
3683 mxStatusIndicator->reset();
3684 }
3685 }
3686
exportDoc(enum::xmloff::token::XMLTokenEnum eClass)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
_ExportStyles(sal_Bool bUsed)3694 void SchXMLExport::_ExportStyles( sal_Bool bUsed )
3695 {
3696 SvXMLExport::_ExportStyles( bUsed );
3697 }
3698
_ExportMasterStyles()3699 void SchXMLExport::_ExportMasterStyles()
3700 {
3701 // not available in chart
3702 DBG_WARNING( "Master Style Export requested. Not available for Chart" );
3703 }
3704
_ExportAutoStyles()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
_ExportContent()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
SetProgress(sal_Int32 nPercentage)3790 void SchXMLExport::SetProgress( sal_Int32 nPercentage )
3791 {
3792 // set progress view
3793 if( mxStatusIndicator.is())
3794 mxStatusIndicator->setValue( nPercentage );
3795 }
3796
GetPropertySetMapper() const3797 UniReference< XMLPropertySetMapper > SchXMLExport::GetPropertySetMapper() const
3798 {
3799 return maExportHelper.m_pImpl->GetPropertySetMapper();
3800 }
3801
InitRangeSegmentationProperties(const Reference<chart2::XChartDocument> & xChartDoc)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
SchXMLExport_getSupportedServiceNames()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
SchXMLExport_getImplementationName()3873 OUString SAL_CALL SchXMLExport_getImplementationName() throw()
3874 {
3875 return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Compact" ) );
3876 }
3877
SchXMLExport_createInstance(const Reference<lang::XMultiServiceFactory> & rSMgr)3878 Reference< uno::XInterface > SAL_CALL SchXMLExport_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr)
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
SchXMLExport_Oasis_getSupportedServiceNames()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
SchXMLExport_Oasis_getImplementationName()3894 OUString SAL_CALL SchXMLExport_Oasis_getImplementationName() throw()
3895 {
3896 return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Oasis.Compact" ) );
3897 }
3898
SchXMLExport_Oasis_createInstance(const Reference<lang::XMultiServiceFactory> & rSMgr)3899 Reference< uno::XInterface > SAL_CALL SchXMLExport_Oasis_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr)
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
SchXMLExport_Styles_getSupportedServiceNames()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
SchXMLExport_Styles_getImplementationName()3917 OUString SAL_CALL SchXMLExport_Styles_getImplementationName() throw()
3918 {
3919 return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Styles" ));
3920 }
3921
SchXMLExport_Styles_createInstance(const Reference<lang::XMultiServiceFactory> & rSMgr)3922 Reference< uno::XInterface > SAL_CALL SchXMLExport_Styles_createInstance(const Reference< lang::XMultiServiceFactory >& rSMgr)
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
SchXMLExport_Oasis_Styles_getSupportedServiceNames()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
SchXMLExport_Oasis_Styles_getImplementationName()3937 OUString SAL_CALL SchXMLExport_Oasis_Styles_getImplementationName() throw()
3938 {
3939 return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Oasis.Styles" ));
3940 }
3941
SchXMLExport_Oasis_Styles_createInstance(const Reference<lang::XMultiServiceFactory> & rSMgr)3942 Reference< uno::XInterface > SAL_CALL SchXMLExport_Oasis_Styles_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr)
3943 {
3944 return (cppu::OWeakObject*)new SchXMLExport( rSMgr, EXPORT_STYLES | EXPORT_OASIS );
3945 }
3946
3947 // ------------------------------------------------------------
3948
SchXMLExport_Content_getSupportedServiceNames()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
SchXMLExport_Content_getImplementationName()3956 OUString SAL_CALL SchXMLExport_Content_getImplementationName() throw()
3957 {
3958 return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Content" ));
3959 }
3960
SchXMLExport_Content_createInstance(const Reference<lang::XMultiServiceFactory> & rSMgr)3961 Reference< uno::XInterface > SAL_CALL SchXMLExport_Content_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr)
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
SchXMLExport_Oasis_Content_getSupportedServiceNames()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
SchXMLExport_Oasis_Content_getImplementationName()3976 OUString SAL_CALL SchXMLExport_Oasis_Content_getImplementationName() throw()
3977 {
3978 return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Oasis.Content" ));
3979 }
3980
SchXMLExport_Oasis_Content_createInstance(const Reference<lang::XMultiServiceFactory> & rSMgr)3981 Reference< uno::XInterface > SAL_CALL SchXMLExport_Oasis_Content_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr)
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
SchXMLExport_Oasis_Meta_getSupportedServiceNames()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
SchXMLExport_Oasis_Meta_getImplementationName()4013 OUString SAL_CALL SchXMLExport_Oasis_Meta_getImplementationName() throw()
4014 {
4015 return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Oasis.Meta" ));
4016 }
4017
SchXMLExport_Oasis_Meta_createInstance(const Reference<lang::XMultiServiceFactory> & rSMgr)4018 Reference< uno::XInterface > SAL_CALL SchXMLExport_Oasis_Meta_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr)
4019 {
4020 return (cppu::OWeakObject*)new SchXMLExport( rSMgr, EXPORT_META | EXPORT_OASIS );
4021 }
4022
4023
4024 // XServiceInfo
getImplementationName()4025 OUString SAL_CALL SchXMLExport::getImplementationName()
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