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