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