1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <sal/config.h>
22 #include <sal/log.hxx>
24 #include <sax/tools/converter.hxx>
26 #include <xmloff/xmlprmap.hxx>
28 #include <SchXMLExport.hxx>
29 #include <XMLChartPropertySetMapper.hxx>
30 #include "ColorPropertySet.hxx"
31 #include "SchXMLTools.hxx"
32 #include "SchXMLEnumConverter.hxx"
35 #include <comphelper/processfactory.hxx>
36 #include <tools/globname.hxx>
37 #include <comphelper/classids.hxx>
38 #include <comphelper/sequence.hxx>
40 #include <xmloff/nmspmap.hxx>
41 #include <xmloff/xmlnmspe.hxx>
42 #include <xmloff/xmltoken.hxx>
43 #include <xmloff/families.hxx>
44 #include <xmloff/xmlaustp.hxx>
45 #include <xmloff/xmluconv.hxx>
46 #include <xmloff/SchXMLSeriesHelper.hxx>
47 #include <rtl/math.hxx>
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>
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/ChartLegendExpansion.hpp>
66 #include <com/sun/star/chart/ChartDataRowSource.hpp>
67 #include <com/sun/star/chart/ChartAxisAssign.hpp>
68 #include <com/sun/star/chart/TimeIncrement.hpp>
69 #include <com/sun/star/chart/TimeInterval.hpp>
70 #include <com/sun/star/chart/TimeUnit.hpp>
71 #include <com/sun/star/chart/X3DDisplay.hpp>
72 #include <com/sun/star/chart/XStatisticDisplay.hpp>
73 #include <com/sun/star/chart/XDiagramPositioning.hpp>
75 #include <com/sun/star/chart2/XAnyDescriptionAccess.hpp>
76 #include <com/sun/star/chart2/AxisType.hpp>
77 #include <com/sun/star/chart2/XChartDocument.hpp>
78 #include <com/sun/star/chart2/XDiagram.hpp>
79 #include <com/sun/star/chart2/RelativePosition.hpp>
80 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
81 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
82 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
83 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
84 #include <com/sun/star/chart2/XDataPointCustomLabelField.hpp>
85 #include <com/sun/star/chart2/data/XDataSource.hpp>
86 #include <com/sun/star/chart2/data/XDataSink.hpp>
87 #include <com/sun/star/chart2/data/XDataProvider.hpp>
88 #include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
89 #include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
90 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
91 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
92 #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
94 #include <com/sun/star/util/MeasureUnit.hpp>
95 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
96 #include <com/sun/star/drawing/XShapes.hpp>
97 #include <com/sun/star/embed/Aspects.hpp>
98 #include <com/sun/star/embed/XVisualObject.hpp>
99 #include <com/sun/star/container/XChild.hpp>
101 #include <tools/diagnose_ex.h>
102 #include "MultiPropertySetHandler.hxx"
103 #include "PropertyMap.hxx"
105 using namespace com::sun::star
;
106 using namespace ::xmloff::token
;
108 using ::com::sun::star::uno::Sequence
;
109 using ::com::sun::star::uno::Reference
;
110 using ::com::sun::star::uno::Any
;
116 using CustomLabelSeq
= Sequence
<Reference
<chart2::XDataPointCustomLabelField
>>;
118 struct SchXMLDataPointStruct
120 OUString maStyleName
;
122 CustomLabelSeq mCustomLabelText
;
124 SchXMLDataPointStruct() : mnRepeat( 1 ) {}
128 // class SchXMLExportHelper_Impl
130 class SchXMLExportHelper_Impl
133 // first: data sequence for label, second: data sequence for values.
134 typedef ::std::pair
< css::uno::Reference
< css::chart2::data::XDataSequence
>,
135 css::uno::Reference
< css::chart2::data::XDataSequence
> > tLabelValuesDataPair
;
136 typedef ::std::vector
< tLabelValuesDataPair
> tDataSequenceCont
;
139 SchXMLExportHelper_Impl( SvXMLExport
& rExport
,
140 SvXMLAutoStylePoolP
& rASPool
);
142 SchXMLExportHelper_Impl(const SchXMLExportHelper_Impl
&) = delete;
143 SchXMLExportHelper_Impl
& operator=(const SchXMLExportHelper_Impl
&) = delete;
146 /// parse chart and collect all auto-styles used in current pool
147 void collectAutoStyles( css::uno::Reference
< css::chart::XChartDocument
> const & rChartDoc
);
149 /// write the styles collected into the current pool as <style:style> elements
150 void exportAutoStyles();
152 /** export the <chart:chart> element corresponding to rChartDoc
153 if bIncludeTable is true, the chart data is exported as <table:table>
154 element (inside the chart element).
156 Otherwise the external references stored in the chart document are used
157 for writing the corresponding attributes at series
159 All attributes contained in xAttrList are written at the chart element,
160 which is the outer element of a chart. So these attributes can easily
161 be parsed again by the container
163 void exportChart( css::uno::Reference
< css::chart::XChartDocument
> const & rChartDoc
,
164 bool bIncludeTable
);
166 const rtl::Reference
<XMLPropertySetMapper
>& GetPropertySetMapper() const;
168 void SetChartRangeAddress( const OUString
& rAddress
)
169 { msChartAddress
= rAddress
; }
171 void InitRangeSegmentationProperties(
172 const css::uno::Reference
< css::chart2::XChartDocument
> & xChartDoc
);
174 static css::awt::Size
getPageSize(
175 const css::uno::Reference
< css::chart2::XChartDocument
> & xChartDoc
);
177 /** first parseDocument: collect autostyles and store names in this queue
178 second parseDocument: export content and use names from this queue
180 ::std::queue
< OUString
> maAutoStyleNameQueue
;
181 void CollectAutoStyle(
182 const std::vector
< XMLPropertyState
>& aStates
);
183 void AddAutoStyleAttribute(
184 const std::vector
< XMLPropertyState
>& aStates
);
186 SvXMLAutoStylePoolP
& GetAutoStylePoolP()
187 { return mrAutoStylePool
; }
189 /// if bExportContent is false the auto-styles are collected
190 void parseDocument( css::uno::Reference
< css::chart::XChartDocument
> const & rChartDoc
,
192 bool bIncludeTable
= false );
195 const css::uno::Reference
< css::chart::XDiagram
>& xDiagram
,
196 const css::uno::Reference
< css::chart2::XDiagram
>& xNewDiagram
,
197 const css::awt::Size
& rPageSize
,
199 bool bIncludeTable
);
200 void exportCoordinateRegion( const css::uno::Reference
< css::chart::XDiagram
>& xDiagram
);
201 void exportAxes( const css::uno::Reference
< css::chart::XDiagram
> & xDiagram
,
202 const css::uno::Reference
< css::chart2::XDiagram
> & xNewDiagram
,
203 bool bExportContent
);
204 void exportAxis( enum XMLTokenEnum eDimension
, enum XMLTokenEnum eAxisName
,
205 const Reference
< beans::XPropertySet
>& rAxisProps
, const Reference
< chart2::XAxis
>& rChart2Axis
,
206 const OUString
& rCategoriesRanges
,
207 bool bHasTitle
, bool bHasMajorGrid
, bool bHasMinorGrid
, bool bExportContent
);
208 void exportGrid( const Reference
< beans::XPropertySet
>& rGridProperties
, bool bMajor
, bool bExportContent
);
209 void exportDateScale( const Reference
< beans::XPropertySet
>& rAxisProps
);
210 void exportAxisTitle( const Reference
< beans::XPropertySet
>& rTitleProps
, bool bExportContent
);
213 const css::uno::Reference
< css::chart2::XDiagram
> & xNewDiagram
,
214 const css::awt::Size
& rPageSize
,
218 void exportPropertyMapping(
219 const css::uno::Reference
< css::chart2::data::XDataSource
> & xSource
,
220 const Sequence
< OUString
>& rSupportedMappings
);
222 void exportCandleStickSeries(
223 const css::uno::Sequence
<
224 css::uno::Reference
< css::chart2::XDataSeries
> > & aSeriesSeq
,
225 const css::uno::Reference
< css::chart2::XDiagram
> & xDiagram
,
226 bool bJapaneseCandleSticks
,
227 bool bExportContent
);
228 void exportDataPoints(
229 const css::uno::Reference
< css::beans::XPropertySet
> & xSeriesProperties
,
230 sal_Int32 nSeriesLength
,
231 const css::uno::Reference
< css::chart2::XDiagram
> & xDiagram
,
232 bool bExportContent
);
234 void exportCustomLabel(const CustomLabelSeq
& xCustomLabel
);
236 void exportRegressionCurve(
237 const css::uno::Reference
<css::chart2::XDataSeries
>& xSeries
,
238 const css::awt::Size
& rPageSize
,
239 bool bExportContent
);
241 void exportErrorBar (
242 const css::uno::Reference
<beans::XPropertySet
> &xSeriesProp
, bool bYError
,
243 bool bExportContent
);
245 /// add svg position as attribute for current element
246 void addPosition( const css::awt::Point
& rPosition
);
247 void addPosition( const css::uno::Reference
< css::drawing::XShape
>& xShape
);
248 /// add svg size as attribute for current element
249 void addSize( const css::awt::Size
& rSize
, bool bIsOOoNamespace
= false );
250 void addSize( const css::uno::Reference
< css::drawing::XShape
>& xShape
);
251 /// exports a string as a paragraph element
252 void exportText( const OUString
& rText
);
255 SvXMLExport
& mrExport
;
256 SvXMLAutoStylePoolP
& mrAutoStylePool
;
257 rtl::Reference
< XMLPropertySetMapper
> mxPropertySetMapper
;
258 rtl::Reference
< XMLChartExportPropertyMapper
> mxExpPropMapper
;
260 static constexpr OUStringLiteral gsTableName
= "local-table";
261 OUStringBuffer msStringBuffer
;
264 // members filled by InitRangeSegmentationProperties (retrieved from DataProvider)
265 bool mbHasCategoryLabels
; //if the categories are only automatically generated this will be false
266 bool mbRowSourceColumns
;
267 OUString msChartAddress
;
268 css::uno::Sequence
< sal_Int32
> maSequenceMapping
;
270 OUString
const msCLSID
;
272 OUString maSrcShellID
;
273 OUString maDestShellID
;
275 css::uno::Reference
< css::drawing::XShapes
> mxAdditionalShapes
;
277 tDataSequenceCont m_aDataSequencesToExport
;
278 OUString maCategoriesRange
;
284 CustomLabelSeq
lcl_getCustomLabelField(sal_Int32 nDataPointIndex
,
285 const uno::Reference
< chart2::XDataSeries
>& rSeries
)
288 return CustomLabelSeq();
290 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
291 if( nCurrentODFVersion
<= SvtSaveOptions::ODFVER_012
)//do not export to ODF 1.2 or older
292 return CustomLabelSeq();
294 if(Reference
<beans::XPropertySet
> xLabels
= rSeries
->getDataPointByIndex(nDataPointIndex
); xLabels
.is())
296 if(Any aAny
= xLabels
->getPropertyValue("CustomLabelFields"); aAny
.hasValue())
298 Sequence
<uno::Reference
<chart2::XDataPointCustomLabelField
>> aCustomLabels
;
299 aAny
>>= aCustomLabels
;
300 return aCustomLabels
;
303 return CustomLabelSeq();
306 class lcl_MatchesRole
309 explicit lcl_MatchesRole( const OUString
& aRole
) :
313 bool operator () ( const Reference
< chart2::data::XLabeledDataSequence
> & xSeq
) const
317 Reference
< beans::XPropertySet
> xProp( xSeq
->getValues(), uno::UNO_QUERY
);
320 return ( xProp
.is() &&
321 (xProp
->getPropertyValue( "Role" ) >>= aRole
) &&
326 OUString
const m_aRole
;
329 template< typename T
>
330 void lcl_SequenceToVectorAppend( const Sequence
< T
> & rSource
, ::std::vector
< T
> & rDestination
)
332 rDestination
.reserve( rDestination
.size() + rSource
.getLength());
333 ::std::copy( rSource
.begin(), rSource
.end(),
334 ::std::back_inserter( rDestination
));
337 template< typename T
>
338 void lcl_SequenceToVector( const Sequence
< T
> & rSource
, ::std::vector
< T
> & rDestination
)
340 rDestination
.clear();
341 lcl_SequenceToVectorAppend( rSource
, rDestination
);
344 Reference
< chart2::data::XLabeledDataSequence
> lcl_getCategories( const Reference
< chart2::XDiagram
> & xDiagram
)
346 Reference
< chart2::data::XLabeledDataSequence
> xResult
;
349 Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt(
350 xDiagram
, uno::UNO_QUERY_THROW
);
351 const Sequence
< Reference
< chart2::XCoordinateSystem
> > aCooSysSeq(
352 xCooSysCnt
->getCoordinateSystems());
353 for( const auto& rCooSys
: aCooSysSeq
)
355 Reference
< chart2::XCoordinateSystem
> xCooSys( rCooSys
);
356 SAL_WARN_IF( !xCooSys
.is(), "xmloff.chart", "xCooSys is NULL" );
357 for( sal_Int32 nN
= xCooSys
->getDimension(); nN
--; )
359 const sal_Int32 nMaxAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nN
);
360 for(sal_Int32 nI
=0; nI
<=nMaxAxisIndex
; ++nI
)
362 Reference
< chart2::XAxis
> xAxis
= xCooSys
->getAxisByDimension( nN
, nI
);
363 SAL_WARN_IF( !xAxis
.is(), "xmloff.chart", "xAxis is NULL");
366 chart2::ScaleData aScaleData
= xAxis
->getScaleData();
367 if( aScaleData
.Categories
.is())
369 xResult
.set( aScaleData
.Categories
);
377 catch( const uno::Exception
& )
379 DBG_UNHANDLED_EXCEPTION("xmloff.chart");
385 Reference
< chart2::data::XDataSource
> lcl_createDataSource(
386 const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aData
)
388 Reference
< uno::XComponentContext
> xContext(
389 comphelper::getProcessComponentContext() );
390 Reference
< chart2::data::XDataSink
> xSink(
391 xContext
->getServiceManager()->createInstanceWithContext(
392 "com.sun.star.chart2.data.DataSource", xContext
),
393 uno::UNO_QUERY_THROW
);
394 xSink
->setData( aData
);
396 return Reference
< chart2::data::XDataSource
>( xSink
, uno::UNO_QUERY
);
399 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > lcl_getAllSeriesSequences( const Reference
< chart2::XChartDocument
>& xChartDoc
)
401 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aContainer
;
404 Reference
< chart2::XDiagram
> xDiagram( xChartDoc
->getFirstDiagram());
405 ::std::vector
< Reference
< chart2::XDataSeries
> > aSeriesVector( SchXMLSeriesHelper::getDataSeriesFromDiagram( xDiagram
));
406 for( const auto& rSeries
: aSeriesVector
)
408 Reference
< chart2::data::XDataSource
> xDataSource( rSeries
, uno::UNO_QUERY
);
409 if( !xDataSource
.is() )
411 uno::Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aDataSequences( xDataSource
->getDataSequences() );
412 lcl_SequenceToVectorAppend( aDataSequences
, aContainer
);
416 return comphelper::containerToSequence( aContainer
);
419 Reference
< chart2::data::XLabeledDataSequence
>
420 lcl_getDataSequenceByRole(
421 const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aLabeledSeq
,
422 const OUString
& rRole
)
424 Reference
< chart2::data::XLabeledDataSequence
> aNoResult
;
426 const Reference
< chart2::data::XLabeledDataSequence
> * pBegin
= aLabeledSeq
.getConstArray();
427 const Reference
< chart2::data::XLabeledDataSequence
> * pEnd
= pBegin
+ aLabeledSeq
.getLength();
428 const Reference
< chart2::data::XLabeledDataSequence
> * pMatch
=
429 ::std::find_if( pBegin
, pEnd
, lcl_MatchesRole( rRole
));
437 Reference
< chart2::data::XDataSource
> lcl_pressUsedDataIntoRectangularFormat( const Reference
< chart2::XChartDocument
>& xChartDoc
, bool& rOutSourceHasCategoryLabels
)
439 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aLabeledSeqVector
;
441 //categories are always the first sequence
442 Reference
< chart2::XDiagram
> xDiagram( xChartDoc
->getFirstDiagram());
443 Reference
< chart2::data::XLabeledDataSequence
> xCategories( lcl_getCategories( xDiagram
) );
444 if( xCategories
.is() )
445 aLabeledSeqVector
.push_back( xCategories
);
446 rOutSourceHasCategoryLabels
= xCategories
.is();
448 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeriesSeqVector(
449 lcl_getAllSeriesSequences( xChartDoc
) );
451 //the first x-values is always the next sequence //todo ... other x-values get lost for old format
452 Reference
< chart2::data::XLabeledDataSequence
> xXValues(
453 lcl_getDataSequenceByRole( aSeriesSeqVector
, "values-x" ) );
455 aLabeledSeqVector
.push_back( xXValues
);
457 //add all other sequences now without x-values
458 lcl_MatchesRole
aHasXValues( "values-x" );
459 std::copy_if(aSeriesSeqVector
.begin(), aSeriesSeqVector
.end(), std::back_inserter(aLabeledSeqVector
),
460 [&aHasXValues
](const auto& rSeriesSeq
) { return !aHasXValues( rSeriesSeq
); });
462 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeq( comphelper::containerToSequence(aLabeledSeqVector
) );
464 return lcl_createDataSource( aSeq
);
467 bool lcl_isSeriesAttachedToFirstAxis(
468 const Reference
< chart2::XDataSeries
> & xDataSeries
)
474 sal_Int32 nAxisIndex
= 0;
475 Reference
< beans::XPropertySet
> xProp( xDataSeries
, uno::UNO_QUERY_THROW
);
476 xProp
->getPropertyValue("AttachedAxisIndex") >>= nAxisIndex
;
477 bResult
= (0==nAxisIndex
);
479 catch( const uno::Exception
& )
481 DBG_UNHANDLED_EXCEPTION("xmloff.chart");
487 OUString
lcl_ConvertRange( const OUString
& rRange
, const Reference
< chart2::XChartDocument
> & xDoc
)
489 OUString aResult
= rRange
;
492 Reference
< chart2::data::XRangeXMLConversion
> xConversion(
493 xDoc
->getDataProvider(), uno::UNO_QUERY
);
494 if( xConversion
.is())
495 aResult
= xConversion
->convertRangeToXML( rRange
);
499 typedef ::std::pair
< OUString
, OUString
> tLabelAndValueRange
;
501 tLabelAndValueRange
lcl_getLabelAndValueRangeByRole(
502 const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aSeqCnt
,
503 const OUString
& rRole
,
504 const Reference
< chart2::XChartDocument
> & xDoc
,
505 SchXMLExportHelper_Impl::tDataSequenceCont
& rOutSequencesToExport
)
507 tLabelAndValueRange aResult
;
509 Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq(
510 lcl_getDataSequenceByRole( aSeqCnt
, rRole
));
511 if( xLabeledSeq
.is())
513 Reference
< chart2::data::XDataSequence
> xLabelSeq( xLabeledSeq
->getLabel());
515 aResult
.first
= lcl_ConvertRange( xLabelSeq
->getSourceRangeRepresentation(), xDoc
);
517 Reference
< chart2::data::XDataSequence
> xValueSeq( xLabeledSeq
->getValues());
519 aResult
.second
= lcl_ConvertRange( xValueSeq
->getSourceRangeRepresentation(), xDoc
);
521 if( xLabelSeq
.is() || xValueSeq
.is())
522 rOutSequencesToExport
.emplace_back( xLabelSeq
, xValueSeq
);
528 sal_Int32
lcl_getSequenceLengthByRole(
529 const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aSeqCnt
,
530 const OUString
& rRole
)
532 Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq(
533 lcl_getDataSequenceByRole( aSeqCnt
, rRole
));
534 if( xLabeledSeq
.is())
536 Reference
< chart2::data::XDataSequence
> xSeq( xLabeledSeq
->getValues());
537 return xSeq
->getData().getLength();
542 OUString
lcl_flattenStringSequence( const Sequence
< OUString
> & rSequence
)
544 OUStringBuffer aResult
;
545 bool bPrecedeWithSpace
= false;
546 for( const auto& rString
: rSequence
)
548 if( !rString
.isEmpty())
550 if( bPrecedeWithSpace
)
551 aResult
.append( ' ' );
552 aResult
.append( rString
);
553 bPrecedeWithSpace
= true;
556 return aResult
.makeStringAndClear();
559 void lcl_getLabelStringSequence( Sequence
< OUString
>& rOutLabels
, const Reference
< chart2::data::XDataSequence
> & xLabelSeq
)
561 uno::Reference
< chart2::data::XTextualDataSequence
> xTextualDataSequence( xLabelSeq
, uno::UNO_QUERY
);
562 if( xTextualDataSequence
.is())
564 rOutLabels
= xTextualDataSequence
->getTextualData();
566 else if( xLabelSeq
.is())
568 Sequence
< uno::Any
> aAnies( xLabelSeq
->getData());
569 rOutLabels
.realloc( aAnies
.getLength());
570 for( sal_Int32 i
=0; i
<aAnies
.getLength(); ++i
)
571 aAnies
[i
] >>= rOutLabels
[i
];
575 sal_Int32
lcl_getMaxSequenceLength(
576 const SchXMLExportHelper_Impl::tDataSequenceCont
& rContainer
)
578 sal_Int32 nResult
= 0;
579 for( const auto& rDataSequence
: rContainer
)
581 if( rDataSequence
.second
.is())
583 sal_Int32 nSeqLength
= rDataSequence
.second
->getData().getLength();
584 if( nSeqLength
> nResult
)
585 nResult
= nSeqLength
;
591 uno::Sequence
< OUString
> lcl_DataSequenceToStringSequence(
592 const uno::Reference
< chart2::data::XDataSequence
>& xDataSequence
)
594 uno::Sequence
< OUString
> aResult
;
595 if(!xDataSequence
.is())
598 uno::Reference
< chart2::data::XTextualDataSequence
> xTextualDataSequence( xDataSequence
, uno::UNO_QUERY
);
599 if( xTextualDataSequence
.is() )
601 aResult
= xTextualDataSequence
->getTextualData();
605 uno::Sequence
< uno::Any
> aValues
= xDataSequence
->getData();
606 aResult
.realloc(aValues
.getLength());
608 for(sal_Int32 nN
=aValues
.getLength();nN
--;)
609 aValues
[nN
] >>= aResult
[nN
];
614 ::std::vector
< double > lcl_getAllValuesFromSequence( const Reference
< chart2::data::XDataSequence
> & xSeq
)
617 ::rtl::math::setNan( &fNan
);
618 ::std::vector
< double > aResult
;
622 uno::Sequence
< double > aValuesSequence
;
623 Reference
< chart2::data::XNumericalDataSequence
> xNumSeq( xSeq
, uno::UNO_QUERY
);
626 aValuesSequence
= xNumSeq
->getNumericalData();
630 Sequence
< uno::Any
> aAnies( xSeq
->getData() );
631 aValuesSequence
.realloc( aAnies
.getLength() );
632 for( sal_Int32 i
=0; i
<aAnies
.getLength(); ++i
)
633 aAnies
[i
] >>= aValuesSequence
[i
];
636 //special handling for x-values (if x-values do point to categories, indices are used instead )
637 Reference
< beans::XPropertySet
> xProp( xSeq
, uno::UNO_QUERY
);
641 xProp
->getPropertyValue("Role") >>= aRole
;
642 if( aRole
.match("values-x") )
644 //lcl_clearIfNoValuesButTextIsContained - replace by indices if the values are not appropriate
645 bool bHasValue
= std::any_of(aValuesSequence
.begin(), aValuesSequence
.end(),
646 [](double fValue
) { return !::rtl::math::isNan( fValue
); });
649 //no double value is contained
651 uno::Sequence
< OUString
> aStrings( lcl_DataSequenceToStringSequence( xSeq
) );
652 bool bHasText
= std::any_of(aStrings
.begin(), aStrings
.end(),
653 [](const OUString
& rString
) { return !rString
.isEmpty(); });
656 std::iota(aValuesSequence
.begin(), aValuesSequence
.end(), 1);
662 ::std::copy( aValuesSequence
.begin(), aValuesSequence
.end(),
663 ::std::back_inserter( aResult
));
667 bool lcl_SequenceHasUnhiddenData( const uno::Reference
< chart2::data::XDataSequence
>& xDataSequence
)
669 if( !xDataSequence
.is() )
671 uno::Reference
< beans::XPropertySet
> xProp( xDataSequence
, uno::UNO_QUERY
);
674 uno::Sequence
< sal_Int32
> aHiddenValues
;
677 xProp
->getPropertyValue("HiddenValues") >>= aHiddenValues
;
678 if( !aHiddenValues
.hasElements() )
681 catch( const uno::Exception
& )
686 return xDataSequence
->getData().hasElements();
689 typedef vector
< OUString
> tStringVector
;
690 typedef vector
< vector
< double > > t2DNumberContainer
;
694 t2DNumberContainer aDataInRows
;
695 tStringVector aDataRangeRepresentations
;
697 tStringVector aColumnDescriptions
;
698 tStringVector aColumnDescriptions_Ranges
;
700 tStringVector aRowDescriptions
;
701 tStringVector aRowDescriptions_Ranges
;
703 Sequence
< Sequence
< uno::Any
> > aComplexColumnDescriptions
;//outer index is columns - inner index is level
704 Sequence
< Sequence
< uno::Any
> > aComplexRowDescriptions
;//outer index is rows - inner index is level
706 ::std::vector
< sal_Int32
> aHiddenColumns
;
709 typedef ::std::map
< sal_Int32
, SchXMLExportHelper_Impl::tLabelValuesDataPair
>
712 struct lcl_SequenceToMapElement
714 std::pair
<const sal_Int32
, SchXMLExportHelper_Impl::tLabelValuesDataPair
>
715 operator() (const SchXMLExportHelper_Impl::tLabelValuesDataPair
& rContent
)
717 sal_Int32 nIndex
= -1;
718 if( rContent
.second
.is()) //has values
720 OUString
aRangeRep( rContent
.second
->getSourceRangeRepresentation());
721 nIndex
= aRangeRep
.toInt32();
723 else if( rContent
.first
.is()) //has labels
724 nIndex
= rContent
.first
->getSourceRangeRepresentation().copy( sizeof("label ")).toInt32();
725 return std::make_pair(nIndex
, rContent
);
729 void lcl_ReorderInternalSequencesAccordingToTheirRangeName(
730 SchXMLExportHelper_Impl::tDataSequenceCont
& rInOutSequences
)
732 lcl_DataSequenceMap aIndexSequenceMap
;
733 ::std::transform( rInOutSequences
.begin(), rInOutSequences
.end(),
734 ::std::inserter( aIndexSequenceMap
, aIndexSequenceMap
.begin()),
735 lcl_SequenceToMapElement());
737 rInOutSequences
.clear();
738 sal_Int32 nIndex
= 0;
739 for( const auto& rEntry
: aIndexSequenceMap
)
741 if( rEntry
.first
>= 0 )
743 // fill empty columns
744 rInOutSequences
.insert(
745 rInOutSequences
.end(),
746 rEntry
.first
- nIndex
,
747 SchXMLExportHelper_Impl::tDataSequenceCont::value_type(
748 uno::Reference
< chart2::data::XDataSequence
>(),
749 uno::Reference
< chart2::data::XDataSequence
>() ));
750 nIndex
= rEntry
.first
;
751 rInOutSequences
.push_back( rEntry
.second
);
758 lcl_TableData
lcl_getDataForLocalTable(
759 const SchXMLExportHelper_Impl::tDataSequenceCont
& aSequencesToExport
,
760 const Reference
< chart2::XAnyDescriptionAccess
>& xAnyDescriptionAccess
,
761 const OUString
& rCategoriesRange
,
762 bool bSeriesFromColumns
,
763 const Reference
< chart2::data::XRangeXMLConversion
> & xRangeConversion
)
765 lcl_TableData aResult
;
769 Sequence
< OUString
> aSimpleCategories
;
770 if( xAnyDescriptionAccess
.is() )
773 if( bSeriesFromColumns
)
775 aSimpleCategories
= xAnyDescriptionAccess
->getRowDescriptions();
776 aResult
.aComplexRowDescriptions
= xAnyDescriptionAccess
->getAnyRowDescriptions();
780 aSimpleCategories
= xAnyDescriptionAccess
->getColumnDescriptions();
781 aResult
.aComplexColumnDescriptions
= xAnyDescriptionAccess
->getAnyColumnDescriptions();
785 //series values and series labels
786 SchXMLExportHelper_Impl::tDataSequenceCont::size_type nNumSequences
= aSequencesToExport
.size();
788 auto nMaxSequenceLength( lcl_getMaxSequenceLength( aSequencesToExport
));
789 if( aSimpleCategories
.getLength() > nMaxSequenceLength
)
791 aSimpleCategories
.realloc(nMaxSequenceLength
);//#i110617#
793 size_t nNumColumns( bSeriesFromColumns
? nNumSequences
: nMaxSequenceLength
);
794 size_t nNumRows( bSeriesFromColumns
? nMaxSequenceLength
: nNumSequences
);
797 aResult
.aDataInRows
.resize( nNumRows
);
799 ::rtl::math::setNan( &fNan
);
801 for (auto& aData
: aResult
.aDataInRows
)
802 aData
.resize(nNumColumns
, fNan
);
803 aResult
.aColumnDescriptions
.resize( nNumColumns
);
804 aResult
.aComplexColumnDescriptions
.realloc( nNumColumns
);
805 aResult
.aRowDescriptions
.resize( nNumRows
);
806 aResult
.aComplexRowDescriptions
.realloc( nNumRows
);
808 tStringVector
& rCategories
= bSeriesFromColumns
? aResult
.aRowDescriptions
: aResult
.aColumnDescriptions
;
809 tStringVector
& rLabels
= bSeriesFromColumns
? aResult
.aColumnDescriptions
: aResult
.aRowDescriptions
;
812 lcl_SequenceToVector( aSimpleCategories
, rCategories
);
813 if( !rCategoriesRange
.isEmpty() )
815 OUString
aRange(rCategoriesRange
);
816 if( xRangeConversion
.is())
817 aRange
= xRangeConversion
->convertRangeToXML( aRange
);
818 if( bSeriesFromColumns
)
819 aResult
.aRowDescriptions_Ranges
.push_back( aRange
);
821 aResult
.aColumnDescriptions_Ranges
.push_back( aRange
);
824 // iterate over all sequences
826 Sequence
< Sequence
< OUString
> > aComplexLabels(nNumSequences
);
827 for( const auto& rDataSequence
: aSequencesToExport
)
830 Sequence
< OUString
>& rCurrentComplexLabel
= aComplexLabels
[nSeqIdx
];
831 if( rDataSequence
.first
.is())
833 lcl_getLabelStringSequence( rCurrentComplexLabel
, rDataSequence
.first
);
834 rLabels
[nSeqIdx
] = lcl_flattenStringSequence( rCurrentComplexLabel
);
835 aRange
= rDataSequence
.first
->getSourceRangeRepresentation();
836 if( xRangeConversion
.is())
837 aRange
= xRangeConversion
->convertRangeToXML( aRange
);
839 else if( rDataSequence
.second
.is())
841 rCurrentComplexLabel
.realloc(1);
842 rLabels
[nSeqIdx
] = rCurrentComplexLabel
[0] = lcl_flattenStringSequence(
843 rDataSequence
.second
->generateLabel( chart2::data::LabelOrigin_SHORT_SIDE
));
845 if( bSeriesFromColumns
)
846 aResult
.aColumnDescriptions_Ranges
.push_back( aRange
);
848 aResult
.aRowDescriptions_Ranges
.push_back( aRange
);
850 ::std::vector
< double > aNumbers( lcl_getAllValuesFromSequence( rDataSequence
.second
));
851 if( bSeriesFromColumns
)
853 const sal_Int32
nSize( static_cast< sal_Int32
>( aNumbers
.size()));
854 for( sal_Int32 nIdx
=0; nIdx
<nSize
; ++nIdx
)
855 aResult
.aDataInRows
[nIdx
][nSeqIdx
] = aNumbers
[nIdx
];
858 aResult
.aDataInRows
[nSeqIdx
] = aNumbers
;
860 if( rDataSequence
.second
.is())
862 aRange
= rDataSequence
.second
->getSourceRangeRepresentation();
863 if( xRangeConversion
.is())
864 aRange
= xRangeConversion
->convertRangeToXML( aRange
);
866 aResult
.aDataRangeRepresentations
.push_back( aRange
);
869 if( !lcl_SequenceHasUnhiddenData(rDataSequence
.first
) && !lcl_SequenceHasUnhiddenData(rDataSequence
.second
) )
870 aResult
.aHiddenColumns
.push_back(nSeqIdx
);
874 Sequence
< Sequence
< Any
> >& rComplexAnyLabels
= bSeriesFromColumns
? aResult
.aComplexColumnDescriptions
: aResult
.aComplexRowDescriptions
;//#i116544#
875 rComplexAnyLabels
.realloc(aComplexLabels
.getLength());
876 for( sal_Int32 nN
=0; nN
<aComplexLabels
.getLength();nN
++ )
878 Sequence
< OUString
>& rSource
= aComplexLabels
[nN
];
879 Sequence
< Any
>& rTarget
= rComplexAnyLabels
[nN
];
880 rTarget
.realloc( rSource
.getLength() );
881 for( sal_Int32 i
=0; i
<rSource
.getLength(); i
++ )
882 rTarget
[i
] <<= rSource
[i
];
885 catch( const uno::Exception
& )
887 TOOLS_INFO_EXCEPTION("xmloff.chart", "something went wrong during table data collection");
893 void lcl_exportNumberFormat( const OUString
& rPropertyName
, const Reference
< beans::XPropertySet
>& xPropSet
,
894 SvXMLExport
& rExport
)
898 sal_Int32 nNumberFormat
= 0;
899 Any aNumAny
= xPropSet
->getPropertyValue( rPropertyName
);
900 if( (aNumAny
>>= nNumberFormat
) && (nNumberFormat
!= -1) )
901 rExport
.addDataStyle( nNumberFormat
);
905 ::std::vector
< Reference
< chart2::data::XDataSequence
> >
906 lcl_getErrorBarSequences( const Reference
< beans::XPropertySet
> & xErrorBarProp
)
908 ::std::vector
< Reference
< chart2::data::XDataSequence
> > aResult
;
909 Reference
< chart2::data::XDataSource
> xErrorBarDataSource( xErrorBarProp
, uno::UNO_QUERY
);
910 if( !xErrorBarDataSource
.is())
913 const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSequences(
914 xErrorBarDataSource
->getDataSequences());
915 for( const auto& rSequence
: aSequences
)
921 Reference
< chart2::data::XDataSequence
> xSequence( rSequence
->getValues());
922 Reference
< beans::XPropertySet
> xSeqProp( xSequence
, uno::UNO_QUERY_THROW
);
924 if( ( xSeqProp
->getPropertyValue( "Role" ) >>= aRole
) &&
925 aRole
.match( "error-bars-" ))
927 aResult
.push_back( xSequence
);
931 catch( const uno::Exception
& )
933 TOOLS_INFO_EXCEPTION("xmloff.chart", "chart:exporting error bar ranges" );
940 bool lcl_exportDomainForThisSequence( const Reference
< chart2::data::XDataSequence
>& rValues
, OUString
& rFirstRangeForThisDomainIndex
, SvXMLExport
& rExport
)
942 bool bDomainExported
= false;
945 Reference
< chart2::XChartDocument
> xNewDoc( rExport
.GetModel(), uno::UNO_QUERY
);
946 OUString
aRange( lcl_ConvertRange( rValues
->getSourceRangeRepresentation(), xNewDoc
) );
948 //work around error in OOo 2.0 (problems with multiple series having a domain element)
949 if( rFirstRangeForThisDomainIndex
.isEmpty() || aRange
!= rFirstRangeForThisDomainIndex
)
951 rExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, aRange
);
952 SvXMLElementExport
aDomain( rExport
, XML_NAMESPACE_CHART
, XML_DOMAIN
, true, true );
953 bDomainExported
= true;
956 if( rFirstRangeForThisDomainIndex
.isEmpty() )
957 rFirstRangeForThisDomainIndex
= aRange
;
959 return bDomainExported
;
962 } // anonymous namespace
964 // class SchXMLExportHelper
966 SchXMLExportHelper::SchXMLExportHelper( SvXMLExport
& rExport
, SvXMLAutoStylePoolP
& rASPool
)
967 : m_pImpl( new SchXMLExportHelper_Impl( rExport
, rASPool
) )
971 SchXMLExportHelper::~SchXMLExportHelper()
975 const OUString
& SchXMLExportHelper::getChartCLSID() const
977 return m_pImpl
->msCLSID
;
980 void SchXMLExportHelper::SetSourceShellID( const OUString
& rShellID
)
982 m_pImpl
->maSrcShellID
= rShellID
;
985 void SchXMLExportHelper::SetDestinationShellID( const OUString
& rShellID
)
987 m_pImpl
->maDestShellID
= rShellID
;
990 const rtl::Reference
< XMLPropertySetMapper
>& SchXMLExportHelper_Impl::GetPropertySetMapper() const
992 return mxPropertySetMapper
;
995 void SchXMLExportHelper_Impl::exportAutoStyles()
997 if( mxExpPropMapper
.is())
999 //ToDo: when embedded in calc/writer this is not necessary because the
1000 // numberformatter is shared between both documents
1001 mrExport
.exportAutoDataStyles();
1003 // export chart auto styles
1004 mrAutoStylePool
.exportXML( XML_STYLE_FAMILY_SCH_CHART_ID
);
1006 // export auto styles for additional shapes
1007 mrExport
.GetShapeExport()->exportAutoStyles();
1008 // and for text in additional shapes
1009 mrExport
.GetTextParagraphExport()->exportTextAutoStyles();
1015 SchXMLExportHelper_Impl::SchXMLExportHelper_Impl(
1016 SvXMLExport
& rExport
,
1017 SvXMLAutoStylePoolP
& rASPool
) :
1018 mrExport( rExport
),
1019 mrAutoStylePool( rASPool
),
1020 mxPropertySetMapper( new XMLChartPropertySetMapper( true ) ),
1021 mxExpPropMapper( new XMLChartExportPropertyMapper( mxPropertySetMapper
, rExport
) ),
1022 mbHasCategoryLabels( false ),
1023 mbRowSourceColumns( true ),
1024 msCLSID( SvGlobalName( SO3_SCH_CLASSID
).GetHexName() )
1026 // register chart auto-style family
1027 mrAutoStylePool
.AddFamily(
1028 XML_STYLE_FAMILY_SCH_CHART_ID
,
1029 OUString( XML_STYLE_FAMILY_SCH_CHART_NAME
),
1030 mxExpPropMapper
.get(),
1031 OUString( XML_STYLE_FAMILY_SCH_CHART_PREFIX
));
1033 // register shape family
1034 mrAutoStylePool
.AddFamily(
1035 XML_STYLE_FAMILY_SD_GRAPHICS_ID
,
1036 OUString( XML_STYLE_FAMILY_SD_GRAPHICS_NAME
),
1037 mxExpPropMapper
.get(),
1038 OUString( XML_STYLE_FAMILY_SD_GRAPHICS_PREFIX
));
1039 // register paragraph family also for shapes
1040 mrAutoStylePool
.AddFamily(
1041 XML_STYLE_FAMILY_TEXT_PARAGRAPH
,
1042 GetXMLToken( XML_PARAGRAPH
),
1043 mxExpPropMapper
.get(),
1045 // register text family also for shapes
1046 mrAutoStylePool
.AddFamily(
1047 XML_STYLE_FAMILY_TEXT_TEXT
,
1048 GetXMLToken( XML_TEXT
),
1049 mxExpPropMapper
.get(),
1053 void SchXMLExportHelper_Impl::collectAutoStyles( Reference
< chart::XChartDocument
> const & rChartDoc
)
1055 parseDocument( rChartDoc
, false );
1058 void SchXMLExportHelper_Impl::exportChart( Reference
< chart::XChartDocument
> const & rChartDoc
,
1059 bool bIncludeTable
)
1061 parseDocument( rChartDoc
, true, bIncludeTable
);
1062 SAL_WARN_IF( !maAutoStyleNameQueue
.empty(), "xmloff.chart", "There are still remaining autostyle names in the queue" );
1065 static OUString
lcl_GetStringFromNumberSequence( const css::uno::Sequence
< sal_Int32
>& rSequenceMapping
, bool bRemoveOneFromEachIndex
/*should be true if having categories*/ )
1067 OUStringBuffer aBuf
;
1068 bool bHasPredecessor
= false;
1069 for( sal_Int32 nIndex
: rSequenceMapping
)
1071 if( bRemoveOneFromEachIndex
)
1077 aBuf
.append( nIndex
);
1078 bHasPredecessor
= true;
1081 return aBuf
.makeStringAndClear();
1084 /// if bExportContent is false the auto-styles are collected
1085 void SchXMLExportHelper_Impl::parseDocument( Reference
< chart::XChartDocument
> const & rChartDoc
,
1086 bool bExportContent
,
1087 bool bIncludeTable
)
1089 Reference
< chart2::XChartDocument
> xNewDoc( rChartDoc
, uno::UNO_QUERY
);
1090 if( !rChartDoc
.is() || !xNewDoc
.is() )
1092 SAL_WARN("xmloff.chart", "No XChartDocument was given for export." );
1096 mxExpPropMapper
->setChartDoc(xNewDoc
);
1098 awt::Size
aPageSize( getPageSize( xNewDoc
));
1099 if( bExportContent
)
1100 addSize( aPageSize
);
1101 Reference
< chart::XDiagram
> xDiagram
= rChartDoc
->getDiagram();
1102 Reference
< chart2::XDiagram
> xNewDiagram
;
1104 xNewDiagram
.set( xNewDoc
->getFirstDiagram());
1106 //todo remove if model changes are notified and view is updated automatically
1107 if( bExportContent
)
1109 Reference
< util::XRefreshable
> xRefreshable( xNewDoc
, uno::UNO_QUERY
);
1110 if( xRefreshable
.is() )
1111 xRefreshable
->refresh();
1114 // get Properties of ChartDocument
1115 bool bHasMainTitle
= false;
1116 bool bHasSubTitle
= false;
1117 bool bHasLegend
= false;
1118 util::DateTime
aNullDate(0,0,0,0,30,12,1899, false);
1120 std::vector
< XMLPropertyState
> aPropertyStates
;
1122 Reference
< beans::XPropertySet
> xDocPropSet( rChartDoc
, uno::UNO_QUERY
);
1123 if( xDocPropSet
.is())
1127 Any aAny
= xDocPropSet
->getPropertyValue("HasMainTitle");
1128 aAny
>>= bHasMainTitle
;
1129 aAny
= xDocPropSet
->getPropertyValue("HasSubTitle");
1130 aAny
>>= bHasSubTitle
;
1131 aAny
= xDocPropSet
->getPropertyValue("HasLegend");
1132 aAny
>>= bHasLegend
;
1133 if ( bIncludeTable
)
1135 aAny
= xDocPropSet
->getPropertyValue("NullDate");
1136 if ( !aAny
.hasValue() )
1138 Reference
<container::XChild
> xChild(rChartDoc
, uno::UNO_QUERY
);
1141 Reference
< beans::XPropertySet
> xParentDoc( xChild
->getParent(),uno::UNO_QUERY
);
1142 if ( xParentDoc
.is() && xParentDoc
->getPropertySetInfo()->hasPropertyByName("NullDate") )
1143 aAny
= xParentDoc
->getPropertyValue("NullDate");
1150 catch( const beans::UnknownPropertyException
& )
1152 SAL_WARN("xmloff.chart", "Required property not found in ChartDocument" );
1156 if ( bIncludeTable
&& (aNullDate
.Day
!= 30 || aNullDate
.Month
!= 12 || aNullDate
.Year
!= 1899 ) )
1158 SvXMLElementExport
aSet( mrExport
, XML_NAMESPACE_TABLE
, XML_CALCULATION_SETTINGS
, true, true );
1160 OUStringBuffer sBuffer
;
1161 ::sax::Converter::convertDateTime(sBuffer
, aNullDate
, nullptr);
1162 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
,XML_DATE_VALUE
,sBuffer
.makeStringAndClear());
1163 SvXMLElementExport
aNull( mrExport
, XML_NAMESPACE_TABLE
, XML_NULL_DATE
, true, true );
1168 std::unique_ptr
<SvXMLElementExport
> xElChart
;
1170 // get property states for autostyles
1171 if( mxExpPropMapper
.is())
1173 Reference
< beans::XPropertySet
> xPropSet
= rChartDoc
->getArea();
1175 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1178 if( bExportContent
)
1180 //export data provider in xlink:href attribute
1181 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
1182 if( nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
)
1184 OUString
aDataProviderURL( ".." );
1185 if( xNewDoc
->hasInternalDataProvider() )
1186 aDataProviderURL
= ".";
1187 else //special handling for data base data provider necessary
1189 Reference
< chart2::data::XDatabaseDataProvider
> xDBDataProvider( xNewDoc
->getDataProvider(), uno::UNO_QUERY
);
1190 if( xDBDataProvider
.is() )
1191 aDataProviderURL
= ".";
1193 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, aDataProviderURL
);
1194 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
1197 Reference
<chart2::data::XPivotTableDataProvider
> xPivotTableDataProvider(xNewDoc
->getDataProvider(), uno::UNO_QUERY
);
1198 if (xPivotTableDataProvider
.is() && nCurrentODFVersion
> SvtSaveOptions::ODFVER_012
)
1200 OUString sPivotTableName
= xPivotTableDataProvider
->getPivotTableName();
1201 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_DATA_PILOT_SOURCE
, sPivotTableName
);
1204 OUString
sChartType( xDiagram
->getDiagramType() );
1208 if( !sChartType
.isEmpty())
1210 enum XMLTokenEnum eXMLChartType
= SchXMLTools::getTokenByChartType( sChartType
, true /* bUseOldNames */ );
1212 SAL_WARN_IF( eXMLChartType
== XML_TOKEN_INVALID
, "xmloff.chart", "invalid chart class" );
1213 if( eXMLChartType
== XML_TOKEN_INVALID
)
1214 eXMLChartType
= XML_BAR
;
1216 if( eXMLChartType
== XML_ADD_IN
)
1218 // sChartType is the service-name of the add-in
1219 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_CLASS
,
1220 mrExport
.GetNamespaceMap().GetQNameByKey(
1221 XML_NAMESPACE_OOO
, sChartType
) );
1223 else if( eXMLChartType
!= XML_TOKEN_INVALID
)
1225 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_CLASS
,
1226 mrExport
.GetNamespaceMap().GetQNameByKey(
1227 XML_NAMESPACE_CHART
, GetXMLToken(eXMLChartType
)) );
1230 //column-mapping or row-mapping
1231 if( maSequenceMapping
.hasElements() )
1233 enum XMLTokenEnum eTransToken
= ::xmloff::token::XML_ROW_MAPPING
;
1234 if( mbRowSourceColumns
)
1235 eTransToken
= ::xmloff::token::XML_COLUMN_MAPPING
;
1236 OUString
aSequenceMappingStr( lcl_GetStringFromNumberSequence(
1237 maSequenceMapping
, mbHasCategoryLabels
&& !xNewDoc
->hasInternalDataProvider() ) );
1239 mrExport
.AddAttribute( XML_NAMESPACE_CHART
,
1240 ::xmloff::token::GetXMLToken( eTransToken
),
1241 aSequenceMappingStr
);
1245 AddAutoStyleAttribute( aPropertyStates
);
1248 xElChart
.reset(new SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_CHART
, true, true ));
1252 CollectAutoStyle( aPropertyStates
);
1254 // remove property states for autostyles
1255 aPropertyStates
.clear();
1260 // get property states for autostyles
1261 if( mxExpPropMapper
.is())
1263 Reference
< beans::XPropertySet
> xPropSet( rChartDoc
->getTitle(), uno::UNO_QUERY
);
1265 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1267 if( bExportContent
)
1269 Reference
< drawing::XShape
> xShape
= rChartDoc
->getTitle();
1270 if( xShape
.is()) // && "hasTitleBeenMoved"
1271 addPosition( xShape
);
1274 AddAutoStyleAttribute( aPropertyStates
);
1277 SvXMLElementExport
aElTitle( mrExport
, XML_NAMESPACE_CHART
, XML_TITLE
, true, true );
1280 Reference
< beans::XPropertySet
> xPropSet( xShape
, uno::UNO_QUERY
);
1283 Any
aAny( xPropSet
->getPropertyValue( "String" ));
1286 exportText( aText
);
1291 CollectAutoStyle( aPropertyStates
);
1293 // remove property states for autostyles
1294 aPropertyStates
.clear();
1300 // get property states for autostyles
1301 if( mxExpPropMapper
.is())
1303 Reference
< beans::XPropertySet
> xPropSet( rChartDoc
->getSubTitle(), uno::UNO_QUERY
);
1305 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1308 if( bExportContent
)
1310 Reference
< drawing::XShape
> xShape
= rChartDoc
->getSubTitle();
1312 addPosition( xShape
);
1315 AddAutoStyleAttribute( aPropertyStates
);
1317 // element (has no subelements)
1318 SvXMLElementExport
aElSubTitle( mrExport
, XML_NAMESPACE_CHART
, XML_SUBTITLE
, true, true );
1321 Reference
< beans::XPropertySet
> xPropSet( xShape
, uno::UNO_QUERY
);
1324 Any
aAny( xPropSet
->getPropertyValue( "String" ));
1327 exportText( aText
);
1332 CollectAutoStyle( aPropertyStates
);
1334 // remove property states for autostyles
1335 aPropertyStates
.clear();
1341 // get property states for autostyles
1342 if( mxExpPropMapper
.is())
1344 Reference
< beans::XPropertySet
> xPropSet( rChartDoc
->getLegend(), uno::UNO_QUERY
);
1346 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1349 if( bExportContent
)
1351 Reference
< beans::XPropertySet
> xProp( rChartDoc
->getLegend(), uno::UNO_QUERY
);
1354 // export legend anchor position
1357 Any
aAny( xProp
->getPropertyValue("Alignment"));
1358 if( SchXMLEnumConverter::getLegendPositionConverter().exportXML( msString
, aAny
, mrExport
.GetMM100UnitConverter() ) )
1359 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LEGEND_POSITION
, msString
);
1361 catch( const beans::UnknownPropertyException
& )
1363 SAL_WARN("xmloff.chart", "Property Align not found in ChartLegend" );
1366 // export absolute legend position
1367 Reference
< drawing::XShape
> xLegendShape( xProp
, uno::UNO_QUERY
);
1368 addPosition( xLegendShape
);
1370 // export legend size
1371 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
1372 if( xLegendShape
.is() && nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
)
1376 chart::ChartLegendExpansion nLegendExpansion
= chart::ChartLegendExpansion_HIGH
;
1377 OUString aExpansionString
;
1378 Any
aAny( xProp
->getPropertyValue("Expansion"));
1379 bool bHasExpansion
= (aAny
>>= nLegendExpansion
);
1380 if( bHasExpansion
&& SchXMLEnumConverter::getLegendExpansionConverter().exportXML( aExpansionString
, aAny
, mrExport
.GetMM100UnitConverter() ) )
1382 mrExport
.AddAttribute( XML_NAMESPACE_STYLE
, XML_LEGEND_EXPANSION
, aExpansionString
);
1383 if( nLegendExpansion
== chart::ChartLegendExpansion_CUSTOM
)
1385 awt::Size
aSize( xLegendShape
->getSize() );
1386 // tdf#131966: chart legend attributes width and height shouldn't be exported to ODF 1.2 (strict)
1387 if (nCurrentODFVersion
> SvtSaveOptions::ODFVER_012
)
1388 addSize( aSize
, true );
1389 OUStringBuffer aAspectRatioString
;
1390 ::sax::Converter::convertDouble(
1394 : double(aSize
.Width
)/double(aSize
.Height
)));
1395 mrExport
.AddAttribute( XML_NAMESPACE_STYLE
, XML_LEGEND_EXPANSION_ASPECT_RATIO
, aAspectRatioString
.makeStringAndClear() );
1399 catch( const beans::UnknownPropertyException
& )
1401 SAL_WARN("xmloff.chart", "Property Expansion not found in ChartLegend" );
1407 AddAutoStyleAttribute( aPropertyStates
);
1410 SvXMLElementExport
aLegend( mrExport
, XML_NAMESPACE_CHART
, XML_LEGEND
, true, true );
1414 CollectAutoStyle( aPropertyStates
);
1416 // remove property states for autostyles
1417 aPropertyStates
.clear();
1420 // plot-area element
1422 exportPlotArea( xDiagram
, xNewDiagram
, aPageSize
, bExportContent
, bIncludeTable
);
1424 // export additional shapes
1425 if( xDocPropSet
.is() )
1427 if( bExportContent
)
1429 if( mxAdditionalShapes
.is())
1431 // can't call exportShapes with all shapes because the
1432 // initialisation happened with the complete draw page and not
1433 // the XShapes object used here. Thus the shapes have to be
1434 // exported one by one
1435 rtl::Reference
< XMLShapeExport
> rShapeExport
= mrExport
.GetShapeExport();
1436 Reference
< drawing::XShape
> xShape
;
1437 const sal_Int32
nShapeCount( mxAdditionalShapes
->getCount());
1438 for( sal_Int32 nShapeId
= 0; nShapeId
< nShapeCount
; nShapeId
++ )
1440 mxAdditionalShapes
->getByIndex( nShapeId
) >>= xShape
;
1441 SAL_WARN_IF( !xShape
.is(), "xmloff.chart", "Shape without an XShape?" );
1445 rShapeExport
->exportShape( xShape
);
1447 // this would be the easier way if it worked:
1448 //mrExport.GetShapeExport()->exportShapes( mxAdditionalShapes );
1453 // get a sequence of non-chart shapes (inserted via clipboard)
1456 Any aShapesAny
= xDocPropSet
->getPropertyValue("AdditionalShapes");
1457 aShapesAny
>>= mxAdditionalShapes
;
1459 catch( const uno::Exception
& )
1461 TOOLS_INFO_EXCEPTION("xmloff.chart", "AdditionalShapes not found" );
1464 if( mxAdditionalShapes
.is())
1466 // seek shapes has to be called for the whole page because in
1467 // the shape export the vector of shapes is accessed via the
1468 // ZOrder which might be (actually is) larger than the number of
1469 // shapes in mxAdditionalShapes
1470 Reference
< drawing::XDrawPageSupplier
> xSupplier( rChartDoc
, uno::UNO_QUERY
);
1471 SAL_WARN_IF( !xSupplier
.is(), "xmloff.chart", "Cannot retrieve draw page to initialize shape export" );
1472 if( xSupplier
.is() )
1474 Reference
< drawing::XShapes
> xDrawPage
= xSupplier
->getDrawPage();
1475 SAL_WARN_IF( !xDrawPage
.is(), "xmloff.chart", "Invalid draw page for initializing shape export" );
1477 mrExport
.GetShapeExport()->seekShapes( xDrawPage
);
1480 // can't call collectShapesAutoStyles with all shapes because
1481 // the initialisation happened with the complete draw page and
1482 // not the XShapes object used here. Thus the shapes have to be
1483 // exported one by one
1484 rtl::Reference
< XMLShapeExport
> rShapeExport
= mrExport
.GetShapeExport();
1485 Reference
< drawing::XShape
> xShape
;
1486 const sal_Int32
nShapeCount( mxAdditionalShapes
->getCount());
1487 for( sal_Int32 nShapeId
= 0; nShapeId
< nShapeCount
; nShapeId
++ )
1489 mxAdditionalShapes
->getByIndex( nShapeId
) >>= xShape
;
1490 SAL_WARN_IF( !xShape
.is(), "xmloff.chart", "Shape without an XShape?" );
1494 rShapeExport
->collectShapeAutoStyles( xShape
);
1501 // (is included as subelement of chart)
1502 if( bExportContent
)
1504 // #85929# always export table, otherwise clipboard may lose data
1509 static void lcl_exportComplexLabel( const Sequence
< uno::Any
>& rComplexLabel
, SvXMLExport
& rExport
)
1511 sal_Int32 nLength
= rComplexLabel
.getLength();
1514 SvXMLElementExport
aTextList( rExport
, XML_NAMESPACE_TEXT
, XML_LIST
, true, true );
1515 for(const auto& rElem
: rComplexLabel
)
1517 SvXMLElementExport
aListItem( rExport
, XML_NAMESPACE_TEXT
, XML_LIST_ITEM
, true, true );
1519 if( !(rElem
>>= aString
) )
1523 SchXMLTools::exportText( rExport
, aString
, false /*bConvertTabsLFs*/ );
1527 void SchXMLExportHelper_Impl::exportTable()
1530 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_NAME
, gsTableName
);
1534 bool bProtected
= false;
1535 Reference
< beans::XPropertySet
> xProps( mrExport
.GetModel(), uno::UNO_QUERY_THROW
);
1536 if ( ( xProps
->getPropertyValue("DisableDataTableDialog") >>= bProtected
) &&
1539 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_PROTECTED
, XML_TRUE
);
1542 catch ( const uno::Exception
& )
1546 SvXMLElementExport
aTable( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE
, true, true );
1548 bool bHasOwnData
= false;
1549 Reference
< chart2::XChartDocument
> xNewDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
1550 Reference
< chart2::data::XRangeXMLConversion
> xRangeConversion
;
1553 bHasOwnData
= xNewDoc
->hasInternalDataProvider();
1554 xRangeConversion
.set( xNewDoc
->getDataProvider(), uno::UNO_QUERY
);
1557 Reference
< chart2::XAnyDescriptionAccess
> xAnyDescriptionAccess
;
1559 Reference
< chart::XChartDocument
> xChartDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
1560 if( xChartDoc
.is() )
1561 xAnyDescriptionAccess
.set( xChartDoc
->getData(), uno::UNO_QUERY
);
1565 lcl_ReorderInternalSequencesAccordingToTheirRangeName( m_aDataSequencesToExport
);
1566 lcl_TableData
aData( lcl_getDataForLocalTable( m_aDataSequencesToExport
1567 , xAnyDescriptionAccess
, maCategoriesRange
1568 , mbRowSourceColumns
, xRangeConversion
));
1570 tStringVector::const_iterator
aDataRangeIter( aData
.aDataRangeRepresentations
.begin());
1571 const tStringVector::const_iterator
aDataRangeEndIter( aData
.aDataRangeRepresentations
.end());
1573 tStringVector::const_iterator
aRowDescriptions_RangeIter( aData
.aRowDescriptions_Ranges
.begin());
1574 const tStringVector::const_iterator
aRowDescriptions_RangeEnd( aData
.aRowDescriptions_Ranges
.end());
1578 SvXMLElementExport
aHeaderColumns( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_COLUMNS
, true, true );
1579 SvXMLElementExport
aHeaderColumn( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, true, true );
1582 SvXMLElementExport
aColumns( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMNS
, true, true );
1584 sal_Int32 nNextIndex
= 0;
1585 for(sal_Int32 nHiddenIndex
: aData
.aHiddenColumns
)
1587 //i91578 display of hidden values (copy paste scenario; export hidden flag thus it can be used during migration to locale table upon paste )
1588 if( nHiddenIndex
> nNextIndex
)
1590 sal_Int64 nRepeat
= static_cast< sal_Int64
>( nHiddenIndex
- nNextIndex
);
1592 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
,
1593 OUString::number( nRepeat
));
1594 SvXMLElementExport
aColumn( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, true, true );
1596 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_VISIBILITY
, GetXMLToken( XML_COLLAPSE
) );
1597 SvXMLElementExport
aColumn( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, true, true );
1598 nNextIndex
= nHiddenIndex
+1;
1601 sal_Int32 nEndIndex
= aData
.aColumnDescriptions
.size()-1;
1602 if( nEndIndex
>= nNextIndex
)
1604 sal_Int64 nRepeat
= static_cast< sal_Int64
>( nEndIndex
- nNextIndex
+ 1 );
1606 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
,
1607 OUString::number( nRepeat
));
1608 SvXMLElementExport
aColumn( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, true, true );
1612 // export rows with content
1615 SvXMLElementExport
aHeaderRows( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_ROWS
, true, true );
1616 SvXMLElementExport
aRow( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, true, true );
1618 //first one empty cell for the row descriptions
1620 SvXMLElementExport
aEmptyCell( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true );
1621 SvXMLElementExport
aEmptyParagraph( mrExport
, XML_NAMESPACE_TEXT
, XML_P
, true, true );
1624 //export column descriptions
1625 tStringVector::const_iterator
aColumnDescriptions_RangeIter( aData
.aColumnDescriptions_Ranges
.begin());
1626 const tStringVector::const_iterator
aColumnDescriptions_RangeEnd( aData
.aColumnDescriptions_Ranges
.end());
1627 const Sequence
< Sequence
< uno::Any
> >& rComplexColumnDescriptions
= aData
.aComplexColumnDescriptions
;
1628 sal_Int32 nComplexCount
= rComplexColumnDescriptions
.getLength();
1630 for( const auto& rDesc
: aData
.aColumnDescriptions
)
1632 bool bExportString
= true;
1633 if( nC
< nComplexCount
)
1635 const Sequence
< uno::Any
>& rComplexLabel
= rComplexColumnDescriptions
[nC
];
1636 if( rComplexLabel
.hasElements() )
1639 if( rComplexLabel
[0] >>=fValue
)
1641 bExportString
= false;
1643 ::sax::Converter::convertDouble(
1644 msStringBuffer
, fValue
);
1645 msString
= msStringBuffer
.makeStringAndClear();
1646 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
1647 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE
, msString
);
1653 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_STRING
);
1656 SvXMLElementExport
aCell( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true );
1657 exportText( rDesc
);
1658 if( nC
< nComplexCount
)
1659 lcl_exportComplexLabel( rComplexColumnDescriptions
[nC
], mrExport
);
1660 if( !bHasOwnData
&& aColumnDescriptions_RangeIter
!= aColumnDescriptions_RangeEnd
)
1662 // remind the original range to allow a correct re-association when copying via clipboard
1663 if (!(*aColumnDescriptions_RangeIter
).isEmpty())
1664 SchXMLTools::exportRangeToSomewhere( mrExport
, *aColumnDescriptions_RangeIter
);
1665 ++aColumnDescriptions_RangeIter
;
1670 SAL_WARN_IF( !bHasOwnData
&& (aColumnDescriptions_RangeIter
!= aColumnDescriptions_RangeEnd
), "xmloff.chart", "bHasOwnData == false && aColumnDescriptions_RangeIter != aColumnDescriptions_RangeEnd" );
1671 } // closing row and header-rows elements
1673 // export value rows
1675 SvXMLElementExport
aRows( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_ROWS
, true, true );
1676 tStringVector::const_iterator
aRowDescriptionsIter( aData
.aRowDescriptions
.begin());
1677 const Sequence
< Sequence
< uno::Any
> >& rComplexRowDescriptions
= aData
.aComplexRowDescriptions
;
1678 sal_Int32 nComplexCount
= rComplexRowDescriptions
.getLength();
1681 for( const auto& rRow
: aData
.aDataInRows
)
1683 SvXMLElementExport
aRow( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, true, true );
1685 //export row descriptions
1687 bool bExportString
= true;
1688 if( nC
< nComplexCount
)
1690 const Sequence
< uno::Any
>& rComplexLabel
= rComplexRowDescriptions
[nC
];
1691 if( rComplexLabel
.hasElements() )
1694 if( rComplexLabel
[0] >>=fValue
)
1696 bExportString
= false;
1698 ::sax::Converter::convertDouble(msStringBuffer
, fValue
);
1699 msString
= msStringBuffer
.makeStringAndClear();
1700 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
1701 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE
, msString
);
1707 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_STRING
);
1710 SvXMLElementExport
aCell( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true );
1711 if( aRowDescriptionsIter
!= aData
.aRowDescriptions
.end())
1713 exportText( *aRowDescriptionsIter
);
1714 if( nC
< nComplexCount
)
1715 lcl_exportComplexLabel( rComplexRowDescriptions
[nC
], mrExport
);
1716 if( !bHasOwnData
&& aRowDescriptions_RangeIter
!= aRowDescriptions_RangeEnd
)
1718 // remind the original range to allow a correct re-association when copying via clipboard
1719 SchXMLTools::exportRangeToSomewhere( mrExport
, *aRowDescriptions_RangeIter
);
1720 ++aRowDescriptions_RangeIter
;
1722 ++aRowDescriptionsIter
;
1727 for( t2DNumberContainer::value_type::const_iterator
aColIt( rRow
.begin());
1728 aColIt
!= rRow
.end(); ++aColIt
)
1730 ::sax::Converter::convertDouble( msStringBuffer
, *aColIt
);
1731 msString
= msStringBuffer
.makeStringAndClear();
1732 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
1733 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE
, msString
);
1734 SvXMLElementExport
aCell( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true );
1735 exportText( msString
); // do not convert tabs and lfs
1736 if( ( !bHasOwnData
&& aDataRangeIter
!= aDataRangeEndIter
) &&
1737 ( mbRowSourceColumns
|| (aColIt
== rRow
.begin()) ) )
1739 // remind the original range to allow a correct re-association when copying via clipboard
1740 if (!(*aDataRangeIter
).isEmpty())
1741 SchXMLTools::exportRangeToSomewhere( mrExport
, *aDataRangeIter
);
1750 // if range iterator was used it should have reached its end
1751 SAL_WARN_IF( !bHasOwnData
&& (aDataRangeIter
!= aDataRangeEndIter
), "xmloff.chart", "bHasOwnData == false && aDataRangeIter != aDataRangeEndIter" );
1752 SAL_WARN_IF( !bHasOwnData
&& (aRowDescriptions_RangeIter
!= aRowDescriptions_RangeEnd
), "xmloff.chart", "bHasOwnData == false && aRowDescriptions_RangeIter != aRowDescriptions_RangeEnd" );
1758 Reference
< chart2::XCoordinateSystem
> lcl_getCooSys( const Reference
< chart2::XDiagram
> & xNewDiagram
)
1760 Reference
< chart2::XCoordinateSystem
> xCooSys
;
1761 Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt( xNewDiagram
, uno::UNO_QUERY
);
1764 Sequence
< Reference
< chart2::XCoordinateSystem
> > aCooSysSeq( xCooSysCnt
->getCoordinateSystems() );
1765 if(aCooSysSeq
.hasElements())
1766 xCooSys
= aCooSysSeq
[0];
1771 Reference
< chart2::XAxis
> lcl_getAxis( const Reference
< chart2::XCoordinateSystem
>& xCooSys
,
1772 enum XMLTokenEnum eDimension
, bool bPrimary
=true )
1774 Reference
< chart2::XAxis
> xNewAxis
;
1779 sal_Int32 nDimensionIndex
=0;
1780 switch( eDimension
)
1795 xNewAxis
= xCooSys
->getAxisByDimension( nDimensionIndex
, bPrimary
? 0 : 1 );
1798 catch( const uno::Exception
& )
1806 void SchXMLExportHelper_Impl::exportPlotArea(
1807 const Reference
< chart::XDiagram
>& xDiagram
,
1808 const Reference
< chart2::XDiagram
>& xNewDiagram
,
1809 const awt::Size
& rPageSize
,
1810 bool bExportContent
,
1811 bool bIncludeTable
)
1813 SAL_WARN_IF( !xDiagram
.is(), "xmloff.chart", "Invalid XDiagram as parameter" );
1814 if( ! xDiagram
.is())
1817 // variables for autostyles
1818 Reference
< beans::XPropertySet
> xPropSet
;
1819 std::vector
< XMLPropertyState
> aPropertyStates
;
1821 msStringBuffer
.setLength( 0 );
1823 // plot-area element
1825 std::unique_ptr
<SvXMLElementExport
> xElPlotArea
;
1826 // get property states for autostyles
1827 xPropSet
.set( xDiagram
, uno::UNO_QUERY
);
1830 if( mxExpPropMapper
.is())
1831 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1833 if( bExportContent
)
1835 rtl::Reference
< XMLShapeExport
> rShapeExport
;
1838 AddAutoStyleAttribute( aPropertyStates
);
1840 if( !msChartAddress
.isEmpty() )
1842 if( !bIncludeTable
)
1843 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, msChartAddress
);
1845 Reference
< chart::XChartDocument
> xDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
1848 Reference
< beans::XPropertySet
> xDocProp( xDoc
, uno::UNO_QUERY
);
1855 bool bFirstCol
= false, bFirstRow
= false;
1857 aAny
= xDocProp
->getPropertyValue( "DataSourceLabelsInFirstColumn" );
1859 aAny
= xDocProp
->getPropertyValue( "DataSourceLabelsInFirstRow" );
1862 if( bFirstCol
|| bFirstRow
)
1864 mrExport
.AddAttribute( XML_NAMESPACE_CHART
,
1865 ::xmloff::token::GetXMLToken( ::xmloff::token::XML_DATA_SOURCE_HAS_LABELS
),
1868 ? ::xmloff::token::GetXMLToken( ::xmloff::token::XML_BOTH
)
1869 : ::xmloff::token::GetXMLToken( ::xmloff::token::XML_COLUMN
))
1870 : ::xmloff::token::GetXMLToken( ::xmloff::token::XML_ROW
)));
1873 catch( const beans::UnknownPropertyException
& )
1875 SAL_WARN("xmloff.chart", "Properties missing" );
1884 addPosition( xDiagram
);
1885 addSize( xDiagram
);
1888 bool bIs3DChart
= false;
1897 aAny
= xPropSet
->getPropertyValue("Dim3D");
1898 aAny
>>= bIs3DChart
;
1902 rShapeExport
= mrExport
.GetShapeExport();
1903 if( rShapeExport
.is())
1904 rShapeExport
->export3DSceneAttributes( xPropSet
);
1907 catch( const uno::Exception
& )
1909 TOOLS_INFO_EXCEPTION("xmloff.chart", "chart:exportPlotAreaException caught");
1913 // plot-area element
1914 xElPlotArea
.reset(new SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_PLOT_AREA
, true, true ));
1916 //inner position rectangle element
1917 exportCoordinateRegion( xDiagram
);
1919 // light sources (inside plot area element)
1922 rShapeExport
->export3DLamps( xPropSet
);
1926 CollectAutoStyle( aPropertyStates
);
1928 // remove property states for autostyles
1929 aPropertyStates
.clear();
1932 exportAxes( xDiagram
, xNewDiagram
, bExportContent
);
1935 Reference
< chart2::XAxis
> xSecondYAxis
= lcl_getAxis( lcl_getCooSys( xNewDiagram
), XML_Y
, false );
1936 exportSeries( xNewDiagram
, rPageSize
, bExportContent
, xSecondYAxis
.is() );
1938 // stock-chart elements
1939 OUString
sChartType ( xDiagram
->getDiagramType());
1940 if( sChartType
== "com.sun.star.chart.StockDiagram" )
1942 Reference
< chart::XStatisticDisplay
> xStockPropProvider( xDiagram
, uno::UNO_QUERY
);
1943 if( xStockPropProvider
.is())
1945 // stock-gain-marker
1946 Reference
< beans::XPropertySet
> xStockPropSet
= xStockPropProvider
->getUpBar();
1947 if( xStockPropSet
.is())
1949 aPropertyStates
.clear();
1950 aPropertyStates
= mxExpPropMapper
->Filter( xStockPropSet
);
1952 if( !aPropertyStates
.empty() )
1954 if( bExportContent
)
1956 AddAutoStyleAttribute( aPropertyStates
);
1958 SvXMLElementExport
aGain( mrExport
, XML_NAMESPACE_CHART
, XML_STOCK_GAIN_MARKER
, true, true );
1962 CollectAutoStyle( aPropertyStates
);
1967 // stock-loss-marker
1968 xStockPropSet
= xStockPropProvider
->getDownBar();
1969 if( xStockPropSet
.is())
1971 aPropertyStates
.clear();
1972 aPropertyStates
= mxExpPropMapper
->Filter( xStockPropSet
);
1974 if( !aPropertyStates
.empty() )
1976 if( bExportContent
)
1978 AddAutoStyleAttribute( aPropertyStates
);
1980 SvXMLElementExport
aGain( mrExport
, XML_NAMESPACE_CHART
, XML_STOCK_LOSS_MARKER
, true, true );
1984 CollectAutoStyle( aPropertyStates
);
1990 xStockPropSet
= xStockPropProvider
->getMinMaxLine();
1991 if( xStockPropSet
.is())
1993 aPropertyStates
.clear();
1994 aPropertyStates
= mxExpPropMapper
->Filter( xStockPropSet
);
1996 if( !aPropertyStates
.empty() )
1998 if( bExportContent
)
2000 AddAutoStyleAttribute( aPropertyStates
);
2002 SvXMLElementExport
aGain( mrExport
, XML_NAMESPACE_CHART
, XML_STOCK_RANGE_LINE
, true, true );
2006 CollectAutoStyle( aPropertyStates
);
2013 // wall and floor element
2014 Reference
< chart::X3DDisplay
> xWallFloorSupplier( xDiagram
, uno::UNO_QUERY
);
2015 if( mxExpPropMapper
.is() &&
2016 xWallFloorSupplier
.is())
2018 // remove property states for autostyles
2019 aPropertyStates
.clear();
2021 Reference
< beans::XPropertySet
> xWallPropSet
= xWallFloorSupplier
->getWall();
2022 if( xWallPropSet
.is())
2024 aPropertyStates
= mxExpPropMapper
->Filter( xWallPropSet
);
2026 if( !aPropertyStates
.empty() )
2029 if( bExportContent
)
2031 // add style name attribute
2032 AddAutoStyleAttribute( aPropertyStates
);
2034 SvXMLElementExport
aWall( mrExport
, XML_NAMESPACE_CHART
, XML_WALL
, true, true );
2038 CollectAutoStyle( aPropertyStates
);
2044 // remove property states for autostyles
2045 aPropertyStates
.clear();
2047 Reference
< beans::XPropertySet
> xFloorPropSet
= xWallFloorSupplier
->getFloor();
2048 if( xFloorPropSet
.is())
2050 aPropertyStates
= mxExpPropMapper
->Filter( xFloorPropSet
);
2052 if( !aPropertyStates
.empty() )
2055 if( bExportContent
)
2057 // add style name attribute
2058 AddAutoStyleAttribute( aPropertyStates
);
2060 SvXMLElementExport
aFloor( mrExport
, XML_NAMESPACE_CHART
, XML_FLOOR
, true, true );
2064 CollectAutoStyle( aPropertyStates
);
2071 void SchXMLExportHelper_Impl::exportCoordinateRegion( const uno::Reference
< chart::XDiagram
>& xDiagram
)
2073 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2074 if( nCurrentODFVersion
<= SvtSaveOptions::ODFVER_012
)//do not export to ODF 1.2 or older
2077 Reference
< chart::XDiagramPositioning
> xDiaPos( xDiagram
, uno::UNO_QUERY
);
2078 SAL_WARN_IF( !xDiaPos
.is(), "xmloff.chart", "Invalid xDiaPos as parameter" );
2082 awt::Rectangle
aRect( xDiaPos
->calculateDiagramPositionExcludingAxes() );
2083 addPosition( awt::Point(aRect
.X
,aRect
.Y
) );
2084 addSize( awt::Size(aRect
.Width
,aRect
.Height
) );
2086 SvXMLElementExport
aCoordinateRegion( mrExport
, XML_NAMESPACE_CHART_EXT
, XML_COORDINATE_REGION
, true, true );//#i100778# todo: change to chart namespace in future - dependent on fileformat
2091 XMLTokenEnum
lcl_getTimeUnitToken( sal_Int32 nTimeUnit
)
2093 XMLTokenEnum eToken
= XML_DAYS
;
2096 case css::chart::TimeUnit::YEAR
:
2099 case css::chart::TimeUnit::MONTH
:
2100 eToken
= XML_MONTHS
;
2109 void SchXMLExportHelper_Impl::exportDateScale( const Reference
< beans::XPropertySet
>& rAxisProps
)
2111 if( !rAxisProps
.is() )
2114 chart::TimeIncrement aIncrement
;
2115 if( rAxisProps
->getPropertyValue("TimeIncrement") >>= aIncrement
)
2117 sal_Int32 nTimeResolution
= css::chart::TimeUnit::DAY
;
2118 if( aIncrement
.TimeResolution
>>= nTimeResolution
)
2119 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_BASE_TIME_UNIT
, lcl_getTimeUnitToken( nTimeResolution
) );
2121 chart::TimeInterval aInterval
;
2122 if( aIncrement
.MajorTimeInterval
>>= aInterval
)
2124 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_MAJOR_INTERVAL_VALUE
, OUString::number(aInterval
.Number
) );
2125 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_MAJOR_INTERVAL_UNIT
, lcl_getTimeUnitToken( aInterval
.TimeUnit
) );
2127 if( aIncrement
.MinorTimeInterval
>>= aInterval
)
2129 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_MINOR_INTERVAL_VALUE
, OUString::number(aInterval
.Number
) );
2130 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_MINOR_INTERVAL_UNIT
, lcl_getTimeUnitToken( aInterval
.TimeUnit
) );
2133 SvXMLElementExport
aDateScale( mrExport
, XML_NAMESPACE_CHART_EXT
, XML_DATE_SCALE
, true, true );//#i25706#todo: change namespace for next ODF version
2137 void SchXMLExportHelper_Impl::exportAxisTitle( const Reference
< beans::XPropertySet
>& rTitleProps
, bool bExportContent
)
2139 if( !rTitleProps
.is() )
2141 std::vector
< XMLPropertyState
> aPropertyStates
= mxExpPropMapper
->Filter( rTitleProps
);
2142 if( bExportContent
)
2145 Any
aAny( rTitleProps
->getPropertyValue( "String" ));
2148 Reference
< drawing::XShape
> xShape( rTitleProps
, uno::UNO_QUERY
);
2150 addPosition( xShape
);
2152 AddAutoStyleAttribute( aPropertyStates
);
2153 SvXMLElementExport
aTitle( mrExport
, XML_NAMESPACE_CHART
, XML_TITLE
, true, true );
2155 // paragraph containing title
2156 exportText( aText
);
2160 CollectAutoStyle( aPropertyStates
);
2162 aPropertyStates
.clear();
2165 void SchXMLExportHelper_Impl::exportGrid( const Reference
< beans::XPropertySet
>& rGridProperties
, bool bMajor
, bool bExportContent
)
2167 if( !rGridProperties
.is() )
2169 std::vector
< XMLPropertyState
> aPropertyStates
= mxExpPropMapper
->Filter( rGridProperties
);
2170 if( bExportContent
)
2172 AddAutoStyleAttribute( aPropertyStates
);
2173 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_CLASS
, bMajor
? XML_MAJOR
: XML_MINOR
);
2174 SvXMLElementExport
aGrid( mrExport
, XML_NAMESPACE_CHART
, XML_GRID
, true, true );
2178 CollectAutoStyle( aPropertyStates
);
2180 aPropertyStates
.clear();
2186 //returns true if a date scale needs to be exported
2187 bool lcl_exportAxisType( const Reference
< chart2::XAxis
>& rChart2Axis
, SvXMLExport
& rExport
)
2189 bool bExportDateScale
= false;
2190 if( !rChart2Axis
.is() )
2191 return bExportDateScale
;
2193 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2194 if( nCurrentODFVersion
<= SvtSaveOptions::ODFVER_012
)//do not export to ODF 1.2 or older
2195 return bExportDateScale
;
2197 chart2::ScaleData
aScale( rChart2Axis
->getScaleData() );
2198 //#i25706#todo: change namespace for next ODF version
2199 sal_uInt16 nNameSpace
= XML_NAMESPACE_CHART_EXT
;
2201 switch(aScale
.AxisType
)
2203 case chart2::AxisType::CATEGORY
:
2204 if( aScale
.AutoDateAxis
)
2206 rExport
.AddAttribute( nNameSpace
, XML_AXIS_TYPE
, XML_AUTO
);
2207 bExportDateScale
= true;
2210 rExport
.AddAttribute( nNameSpace
, XML_AXIS_TYPE
, XML_TEXT
);
2212 case chart2::AxisType::DATE
:
2213 rExport
.AddAttribute( nNameSpace
, XML_AXIS_TYPE
, XML_DATE
);
2214 bExportDateScale
= true;
2216 default: //AUTOMATIC
2217 rExport
.AddAttribute( nNameSpace
, XML_AXIS_TYPE
, XML_AUTO
);
2221 return bExportDateScale
;
2224 void disableLinkedNumberFormat(
2225 std::vector
<XMLPropertyState
>& rPropStates
, const rtl::Reference
<XMLPropertySetMapper
>& rMapper
)
2227 for (XMLPropertyState
& rState
: rPropStates
)
2229 if (rState
.mnIndex
< 0 || rMapper
->GetEntryCount() <= rState
.mnIndex
)
2232 OUString aXMLName
= rMapper
->GetEntryXMLName(rState
.mnIndex
);
2234 if (aXMLName
!= "link-data-style-to-source")
2237 // Entry found. Set the value to false and bail out.
2238 rState
.maValue
<<= false;
2242 // Entry not found. Insert a new entry for this.
2243 sal_Int32 nIndex
= rMapper
->GetEntryIndex(XML_NAMESPACE_CHART
, "link-data-style-to-source", 0);
2244 XMLPropertyState
aState(nIndex
);
2245 aState
.maValue
<<= false;
2246 rPropStates
.push_back(aState
);
2251 void SchXMLExportHelper_Impl::exportAxis(
2252 enum XMLTokenEnum eDimension
,
2253 enum XMLTokenEnum eAxisName
,
2254 const Reference
< beans::XPropertySet
>& rAxisProps
,
2255 const Reference
< chart2::XAxis
>& rChart2Axis
,
2256 const OUString
& rCategoriesRange
,
2257 bool bHasTitle
, bool bHasMajorGrid
, bool bHasMinorGrid
,
2258 bool bExportContent
)
2260 std::vector
< XMLPropertyState
> aPropertyStates
;
2261 std::unique_ptr
<SvXMLElementExport
> pAxis
;
2263 // get property states for autostyles
2264 if( rAxisProps
.is() && mxExpPropMapper
.is() )
2266 lcl_exportNumberFormat( "NumberFormat", rAxisProps
, mrExport
);
2267 aPropertyStates
= mxExpPropMapper
->Filter( rAxisProps
);
2269 if (!maSrcShellID
.isEmpty() && !maDestShellID
.isEmpty() && maSrcShellID
!= maDestShellID
)
2271 // Disable link to source number format property when pasting to
2272 // a different doc shell. These shell ID's should be both empty
2273 // during real ODF export.
2274 disableLinkedNumberFormat(aPropertyStates
, mxExpPropMapper
->getPropertySetMapper());
2278 bool bExportDateScale
= false;
2279 if( bExportContent
)
2281 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_DIMENSION
, eDimension
);
2282 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_NAME
, eAxisName
);
2283 AddAutoStyleAttribute( aPropertyStates
); // write style name
2284 if( !rCategoriesRange
.isEmpty() )
2285 bExportDateScale
= lcl_exportAxisType( rChart2Axis
, mrExport
);
2287 // open axis element
2288 pAxis
.reset(new SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_AXIS
, true, true ));
2292 CollectAutoStyle( aPropertyStates
);
2294 aPropertyStates
.clear();
2297 if( bExportDateScale
)
2298 exportDateScale( rAxisProps
);
2300 Reference
< beans::XPropertySet
> xTitleProps
;
2301 Reference
< beans::XPropertySet
> xMajorGridProps
;
2302 Reference
< beans::XPropertySet
> xMinorGridProps
;
2303 Reference
< chart::XAxis
> xAxis( rAxisProps
, uno::UNO_QUERY
);
2306 xTitleProps
= bHasTitle
? xAxis
->getAxisTitle() : nullptr;
2307 xMajorGridProps
= bHasMajorGrid
? xAxis
->getMajorGrid() : nullptr;
2308 xMinorGridProps
= bHasMinorGrid
? xAxis
->getMinorGrid() : nullptr;
2312 exportAxisTitle( xTitleProps
, bExportContent
);
2314 // categories if we have a categories chart
2315 if( bExportContent
&& !rCategoriesRange
.isEmpty() )
2317 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, rCategoriesRange
);
2318 SvXMLElementExport
aCategories( mrExport
, XML_NAMESPACE_CHART
, XML_CATEGORIES
, true, true );
2322 exportGrid( xMajorGridProps
, true, bExportContent
);
2323 exportGrid( xMinorGridProps
, false, bExportContent
);
2326 void SchXMLExportHelper_Impl::exportAxes(
2327 const Reference
< chart::XDiagram
> & xDiagram
,
2328 const Reference
< chart2::XDiagram
> & xNewDiagram
,
2329 bool bExportContent
)
2331 SAL_WARN_IF( !xDiagram
.is(), "xmloff.chart", "Invalid XDiagram as parameter" );
2332 if( ! xDiagram
.is())
2335 // get some properties from document first
2336 bool bHasXAxis
= false,
2339 bHasSecondaryXAxis
= false,
2340 bHasSecondaryYAxis
= false;
2341 bool bHasXAxisTitle
= false,
2342 bHasYAxisTitle
= false,
2343 bHasZAxisTitle
= false,
2344 bHasSecondaryXAxisTitle
= false,
2345 bHasSecondaryYAxisTitle
= false;
2346 bool bHasXAxisMajorGrid
= false,
2347 bHasXAxisMinorGrid
= false,
2348 bHasYAxisMajorGrid
= false,
2349 bHasYAxisMinorGrid
= false,
2350 bHasZAxisMajorGrid
= false,
2351 bHasZAxisMinorGrid
= false;
2353 // get multiple properties using XMultiPropertySet
2354 MultiPropertySetHandler
aDiagramProperties (xDiagram
);
2356 aDiagramProperties
.Add ("HasXAxis", bHasXAxis
);
2357 aDiagramProperties
.Add ("HasYAxis", bHasYAxis
);
2358 aDiagramProperties
.Add ("HasZAxis", bHasZAxis
);
2359 aDiagramProperties
.Add ("HasSecondaryXAxis", bHasSecondaryXAxis
);
2360 aDiagramProperties
.Add ("HasSecondaryYAxis", bHasSecondaryYAxis
);
2362 aDiagramProperties
.Add ("HasXAxisTitle", bHasXAxisTitle
);
2363 aDiagramProperties
.Add ("HasYAxisTitle", bHasYAxisTitle
);
2364 aDiagramProperties
.Add ("HasZAxisTitle", bHasZAxisTitle
);
2365 aDiagramProperties
.Add ("HasSecondaryXAxisTitle", bHasSecondaryXAxisTitle
);
2366 aDiagramProperties
.Add ("HasSecondaryYAxisTitle", bHasSecondaryYAxisTitle
);
2368 aDiagramProperties
.Add ("HasXAxisGrid", bHasXAxisMajorGrid
);
2369 aDiagramProperties
.Add ("HasYAxisGrid", bHasYAxisMajorGrid
);
2370 aDiagramProperties
.Add ("HasZAxisGrid", bHasZAxisMajorGrid
);
2372 aDiagramProperties
.Add ("HasXAxisHelpGrid", bHasXAxisMinorGrid
);
2373 aDiagramProperties
.Add ("HasYAxisHelpGrid", bHasYAxisMinorGrid
);
2374 aDiagramProperties
.Add ("HasZAxisHelpGrid", bHasZAxisMinorGrid
);
2376 if ( ! aDiagramProperties
.GetProperties ())
2378 SAL_INFO("xmloff.chart", "Required properties not found in Chart diagram");
2381 Reference
< chart2::XCoordinateSystem
> xCooSys( lcl_getCooSys(xNewDiagram
) );
2383 // write an axis element also if the axis itself is not visible, but a grid or a title
2385 OUString aCategoriesRange
;
2386 Reference
< chart::XAxisSupplier
> xAxisSupp( xDiagram
, uno::UNO_QUERY
);
2390 Reference
< css::chart2::XAxis
> xNewAxis
= lcl_getAxis( xCooSys
, XML_X
);
2393 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getAxis(0) : nullptr, uno::UNO_QUERY
);
2394 if( mbHasCategoryLabels
&& bExportContent
)
2396 Reference
< chart2::data::XLabeledDataSequence
> xCategories( lcl_getCategories( xNewDiagram
) );
2397 if( xCategories
.is() )
2399 Reference
< chart2::data::XDataSequence
> xValues( xCategories
->getValues() );
2402 Reference
< chart2::XChartDocument
> xNewDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
2403 maCategoriesRange
= xValues
->getSourceRangeRepresentation();
2404 aCategoriesRange
= lcl_ConvertRange( maCategoriesRange
, xNewDoc
);
2408 exportAxis( XML_X
, XML_PRIMARY_X
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasXAxisTitle
, bHasXAxisMajorGrid
, bHasXAxisMinorGrid
, bExportContent
);
2409 aCategoriesRange
.clear();
2414 xNewAxis
= lcl_getAxis( xCooSys
, XML_X
, false );
2417 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getSecondaryAxis(0) : nullptr, uno::UNO_QUERY
);
2418 exportAxis( XML_X
, XML_SECONDARY_X
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasSecondaryXAxisTitle
, false, false, bExportContent
);
2423 xNewAxis
= lcl_getAxis( xCooSys
, XML_Y
);
2426 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getAxis(1) : nullptr, uno::UNO_QUERY
);
2427 exportAxis( XML_Y
, XML_PRIMARY_Y
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasYAxisTitle
, bHasYAxisMajorGrid
, bHasYAxisMinorGrid
, bExportContent
);
2432 xNewAxis
= lcl_getAxis( xCooSys
, XML_Y
, false );
2435 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getSecondaryAxis(1) : nullptr, uno::UNO_QUERY
);
2436 exportAxis( XML_Y
, XML_SECONDARY_Y
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasSecondaryYAxisTitle
, false, false, bExportContent
);
2441 xNewAxis
= lcl_getAxis( xCooSys
, XML_Z
);
2444 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getAxis(2) : nullptr, uno::UNO_QUERY
);
2445 exportAxis( XML_Z
, XML_PRIMARY_Z
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasZAxisTitle
, bHasZAxisMajorGrid
, bHasZAxisMinorGrid
, bExportContent
);
2451 bool lcl_hasNoValuesButText( const uno::Reference
< chart2::data::XDataSequence
>& xDataSequence
)
2453 if( !xDataSequence
.is() )
2454 return false;//have no data
2456 Sequence
< uno::Any
> aData
;
2457 Reference
< chart2::data::XNumericalDataSequence
> xNumericalDataSequence( xDataSequence
, uno::UNO_QUERY
);
2458 if( xNumericalDataSequence
.is() )
2460 Sequence
< double > aDoubles( xNumericalDataSequence
->getNumericalData() );
2461 if (std::any_of(aDoubles
.begin(), aDoubles
.end(), [](double fDouble
) { return !::rtl::math::isNan( fDouble
); }))
2462 return false;//have double value
2466 aData
= xDataSequence
->getData();
2467 double fDouble
= 0.0;
2468 bool bHaveDouble
= std::any_of(aData
.begin(), aData
.end(),
2469 [&fDouble
](const uno::Any
& rData
) { return (rData
>>= fDouble
) && !::rtl::math::isNan( fDouble
); });
2471 return false;//have double value
2475 Reference
< chart2::data::XTextualDataSequence
> xTextualDataSequence( xDataSequence
, uno::UNO_QUERY
);
2476 if( xTextualDataSequence
.is() )
2478 uno::Sequence
< OUString
> aStrings( xTextualDataSequence
->getTextualData() );
2479 if (std::any_of(aStrings
.begin(), aStrings
.end(), [](const OUString
& rString
) { return !rString
.isEmpty(); }))
2480 return true;//have text
2484 if( !aData
.hasElements() )
2485 aData
= xDataSequence
->getData();
2487 bool bHaveText
= std::any_of(aData
.begin(), aData
.end(),
2488 [&aString
](const uno::Any
& rData
) { return (rData
>>= aString
) && !aString
.isEmpty(); });
2490 return true;//have text
2492 //no doubles and no texts
2497 void SchXMLExportHelper_Impl::exportSeries(
2498 const Reference
< chart2::XDiagram
> & xNewDiagram
,
2499 const awt::Size
& rPageSize
,
2500 bool bExportContent
,
2503 Reference
< chart2::XCoordinateSystemContainer
> xBCooSysCnt( xNewDiagram
, uno::UNO_QUERY
);
2504 if( ! xBCooSysCnt
.is())
2506 Reference
< chart2::XChartDocument
> xNewDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
2508 OUString aFirstXDomainRange
;
2509 OUString aFirstYDomainRange
;
2511 std::vector
< XMLPropertyState
> aPropertyStates
;
2513 const Sequence
< Reference
< chart2::XCoordinateSystem
> >
2514 aCooSysSeq( xBCooSysCnt
->getCoordinateSystems());
2515 for( const auto& rCooSys
: aCooSysSeq
)
2517 Reference
< chart2::XChartTypeContainer
> xCTCnt( rCooSys
, uno::UNO_QUERY
);
2520 const Sequence
< Reference
< chart2::XChartType
> > aCTSeq( xCTCnt
->getChartTypes());
2521 for( const auto& rChartType
: aCTSeq
)
2523 Reference
< chart2::XDataSeriesContainer
> xDSCnt( rChartType
, uno::UNO_QUERY
);
2526 // note: if xDSCnt.is() then also aCTSeq[nCTIdx]
2527 OUString
aChartType( rChartType
->getChartType());
2528 OUString aLabelRole
= rChartType
->getRoleOfSequenceForSeriesLabel();
2530 // special export for stock charts
2531 if ( aChartType
== "com.sun.star.chart2.CandleStickChartType" )
2533 bool bJapaneseCandleSticks
= false;
2534 Reference
< beans::XPropertySet
> xCTProp( rChartType
, uno::UNO_QUERY
);
2536 xCTProp
->getPropertyValue("Japanese") >>= bJapaneseCandleSticks
;
2537 exportCandleStickSeries(
2538 xDSCnt
->getDataSeries(), xNewDiagram
, bJapaneseCandleSticks
, bExportContent
);
2542 // export dataseries for current chart-type
2543 Sequence
< Reference
< chart2::XDataSeries
> > aSeriesSeq( xDSCnt
->getDataSeries());
2544 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<aSeriesSeq
.getLength(); ++nSeriesIdx
)
2547 Reference
< chart2::data::XDataSource
> xSource( aSeriesSeq
[nSeriesIdx
], uno::UNO_QUERY
);
2550 std::unique_ptr
<SvXMLElementExport
> pSeries
;
2551 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeqCnt(
2552 xSource
->getDataSequences());
2553 sal_Int32 nMainSequenceIndex
= -1;
2554 sal_Int32 nSeriesLength
= 0;
2555 sal_Int32 nAttachedAxis
= chart::ChartAxisAssign::PRIMARY_Y
;
2556 bool bHasMeanValueLine
= false;
2557 Reference
< beans::XPropertySet
> xPropSet
;
2558 tLabelValuesDataPair aSeriesLabelValuesPair
;
2560 // search for main sequence and create a series element
2562 Reference
< chart2::data::XDataSequence
> xValuesSeq
;
2563 Reference
< chart2::data::XDataSequence
> xLabelSeq
;
2564 sal_Int32 nSeqIdx
=0;
2565 for( ; nSeqIdx
<aSeqCnt
.getLength(); ++nSeqIdx
)
2568 Reference
< chart2::data::XDataSequence
> xTempValueSeq( aSeqCnt
[nSeqIdx
]->getValues() );
2569 if( nMainSequenceIndex
==-1 )
2571 Reference
< beans::XPropertySet
> xSeqProp( xTempValueSeq
, uno::UNO_QUERY
);
2573 xSeqProp
->getPropertyValue("Role") >>= aRole
;
2575 if( aRole
== aLabelRole
)
2577 xValuesSeq
.set( xTempValueSeq
);
2578 xLabelSeq
.set( aSeqCnt
[nSeqIdx
]->getLabel());
2579 nMainSequenceIndex
= nSeqIdx
;
2582 sal_Int32 nSequenceLength
= (xTempValueSeq
.is()? xTempValueSeq
->getData().getLength() : sal_Int32(0));
2583 if( nSeriesLength
< nSequenceLength
)
2584 nSeriesLength
= nSequenceLength
;
2587 // have found the main sequence, then xValuesSeq and
2588 // xLabelSeq contain those. Otherwise both are empty
2590 // get property states for autostyles
2593 xPropSet
= SchXMLSeriesHelper::createOldAPISeriesPropertySet(
2594 aSeriesSeq
[nSeriesIdx
], mrExport
.GetModel() );
2596 catch( const uno::Exception
& )
2598 TOOLS_INFO_EXCEPTION("xmloff.chart", "Series not found or no XPropertySet" );
2603 // determine attached axis
2606 Any
aAny( xPropSet
->getPropertyValue( "Axis" ));
2607 aAny
>>= nAttachedAxis
;
2609 aAny
= xPropSet
->getPropertyValue( "MeanValue" );
2610 aAny
>>= bHasMeanValueLine
;
2612 catch( const beans::UnknownPropertyException
& )
2614 TOOLS_INFO_EXCEPTION("xmloff.chart", "Required property not found in DataRowProperties" );
2617 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2618 if( nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
)
2620 lcl_exportNumberFormat( "NumberFormat", xPropSet
, mrExport
);
2621 lcl_exportNumberFormat( "PercentageNumberFormat", xPropSet
, mrExport
);
2624 if( mxExpPropMapper
.is())
2625 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
2628 if( bExportContent
)
2632 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
2633 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
2635 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
2639 AddAutoStyleAttribute( aPropertyStates
);
2641 if( xValuesSeq
.is())
2642 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
,
2644 xValuesSeq
->getSourceRangeRepresentation(),
2647 // #i75297# allow empty series, export empty range to have all ranges on import
2648 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, OUString());
2650 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2651 if( nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
)
2655 Any aAny
= xPropSet
->getPropertyValue("ShowLegendEntry");
2656 if (!aAny
.get
<bool>())
2658 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_HIDE_LEGEND
, OUString::boolean(true));
2665 // Check if the label is direct string value rather than a reference.
2666 bool bHasString
= false;
2667 uno::Reference
<beans::XPropertySet
> xLSProp(xLabelSeq
, uno::UNO_QUERY
);
2672 xLSProp
->getPropertyValue("HasStringLabel") >>= bHasString
;
2674 catch (const beans::UnknownPropertyException
&) {}
2677 OUString aRange
= xLabelSeq
->getSourceRangeRepresentation();
2681 mrExport
.AddAttribute(
2682 XML_NAMESPACE_LO_EXT
, XML_LABEL_STRING
, aRange
);
2686 mrExport
.AddAttribute(
2687 XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
,
2689 xLabelSeq
->getSourceRangeRepresentation(), xNewDoc
));
2693 if( xLabelSeq
.is() || xValuesSeq
.is() )
2694 aSeriesLabelValuesPair
= tLabelValuesDataPair( xLabelSeq
, xValuesSeq
);
2696 // chart-type for mixed types
2697 enum XMLTokenEnum
eCTToken(
2698 SchXMLTools::getTokenByChartType( aChartType
, false /* bUseOldNames */ ));
2699 //@todo: get token for current charttype
2700 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_CLASS
,
2701 mrExport
.GetNamespaceMap().GetQNameByKey(
2702 XML_NAMESPACE_CHART
, GetXMLToken( eCTToken
)));
2704 // open series element until end of for loop
2705 pSeries
.reset(new SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, true, true ));
2709 CollectAutoStyle( aPropertyStates
);
2711 // remove property states for autostyles
2712 aPropertyStates
.clear();
2716 // export domain elements if we have a series parent element
2720 if( bExportContent
)
2722 bool bIsScatterChart
= aChartType
== "com.sun.star.chart2.ScatterChartType";
2723 bool bIsBubbleChart
= aChartType
== "com.sun.star.chart2.BubbleChartType";
2724 Reference
< chart2::data::XDataSequence
> xYValuesForBubbleChart
;
2725 if( bIsBubbleChart
)
2727 Reference
< chart2::data::XLabeledDataSequence
> xSequence( lcl_getDataSequenceByRole( aSeqCnt
, "values-y" ) );
2728 if( xSequence
.is() )
2730 xYValuesForBubbleChart
= xSequence
->getValues();
2731 if( !lcl_exportDomainForThisSequence( xYValuesForBubbleChart
, aFirstYDomainRange
, mrExport
) )
2732 xYValuesForBubbleChart
= nullptr;
2735 if( bIsScatterChart
|| bIsBubbleChart
)
2737 Reference
< chart2::data::XLabeledDataSequence
> xSequence( lcl_getDataSequenceByRole( aSeqCnt
, "values-x" ) );
2738 if( xSequence
.is() )
2740 Reference
< chart2::data::XDataSequence
> xValues( xSequence
->getValues() );
2741 if( lcl_exportDomainForThisSequence( xValues
, aFirstXDomainRange
, mrExport
) )
2742 m_aDataSequencesToExport
.emplace_back(
2743 uno::Reference
< chart2::data::XDataSequence
>(), xValues
);
2745 else if( nSeriesIdx
==0 )
2747 //might be that the categories are used as x-values (e.g. for date axis) -> export them accordingly
2748 Reference
< chart2::data::XLabeledDataSequence
> xCategories( lcl_getCategories( xNewDiagram
) );
2749 if( xCategories
.is() )
2751 Reference
< chart2::data::XDataSequence
> xValues( xCategories
->getValues() );
2752 if( !lcl_hasNoValuesButText( xValues
) )
2753 lcl_exportDomainForThisSequence( xValues
, aFirstXDomainRange
, mrExport
);
2757 if( xYValuesForBubbleChart
.is() )
2758 m_aDataSequencesToExport
.emplace_back(
2759 uno::Reference
< chart2::data::XDataSequence
>(), xYValuesForBubbleChart
);
2763 // add sequences for main sequence after domain sequences,
2764 // so that the export of the local table has the correct order
2765 if( bExportContent
&&
2766 (aSeriesLabelValuesPair
.first
.is() || aSeriesLabelValuesPair
.second
.is()))
2767 m_aDataSequencesToExport
.push_back( aSeriesLabelValuesPair
);
2769 // statistical objects:
2770 // regression curves and mean value lines
2771 if( bHasMeanValueLine
&&
2773 mxExpPropMapper
.is() )
2775 Reference
< beans::XPropertySet
> xStatProp
;
2778 Any
aPropAny( xPropSet
->getPropertyValue( "DataMeanValueProperties" ));
2779 aPropAny
>>= xStatProp
;
2781 catch( const uno::Exception
& )
2783 TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught during Export of series - optional DataMeanValueProperties not available" );
2786 if( xStatProp
.is() )
2788 aPropertyStates
= mxExpPropMapper
->Filter( xStatProp
);
2790 if( !aPropertyStates
.empty() )
2793 if( bExportContent
)
2795 // add style name attribute
2796 AddAutoStyleAttribute( aPropertyStates
);
2798 SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_MEAN_VALUE
, true, true );
2802 CollectAutoStyle( aPropertyStates
);
2808 if( xPropSet
.is() &&
2809 mxExpPropMapper
.is() )
2811 exportRegressionCurve( aSeriesSeq
[nSeriesIdx
], rPageSize
, bExportContent
);
2814 exportErrorBar( xPropSet
,false, bExportContent
); // X ErrorBar
2815 exportErrorBar( xPropSet
,true, bExportContent
); // Y ErrorBar
2818 uno::Reference
< beans::XPropertySet
>( aSeriesSeq
[nSeriesIdx
], uno::UNO_QUERY
),
2819 nSeriesLength
, xNewDiagram
, bExportContent
);
2821 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2822 if( bExportContent
&& nCurrentODFVersion
> SvtSaveOptions::ODFVER_012
)//do not export to ODF 1.2 or older
2824 Sequence
< OUString
> aSupportedMappings
= rChartType
->getSupportedPropertyRoles();
2825 exportPropertyMapping( xSource
, aSupportedMappings
);
2828 // close series element
2832 aPropertyStates
.clear();
2837 void SchXMLExportHelper_Impl::exportPropertyMapping(
2838 const Reference
< chart2::data::XDataSource
> & xSource
, const Sequence
< OUString
>& rSupportedMappings
)
2840 Reference
< chart2::XChartDocument
> xNewDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
2841 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeqCnt(
2842 xSource
->getDataSequences());
2844 for(const auto& rSupportedMapping
: rSupportedMappings
)
2846 Reference
< chart2::data::XLabeledDataSequence
> xSequence( lcl_getDataSequenceByRole( aSeqCnt
, rSupportedMapping
) );
2849 Reference
< chart2::data::XDataSequence
> xValues( xSequence
->getValues() );
2852 mrExport
.AddAttribute( XML_NAMESPACE_LO_EXT
, XML_PROPERTY
, rSupportedMapping
);
2853 mrExport
.AddAttribute( XML_NAMESPACE_LO_EXT
, XML_CELL_RANGE_ADDRESS
,
2855 xValues
->getSourceRangeRepresentation(),
2857 SvXMLElementExport( mrExport
, XML_NAMESPACE_LO_EXT
, XML_PROPERTY_MAPPING
, true, true );
2859 // register range for data table export
2860 m_aDataSequencesToExport
.emplace_back(
2861 uno::Reference
< chart2::data::XDataSequence
>(), xValues
);
2867 void SchXMLExportHelper_Impl::exportRegressionCurve(
2868 const Reference
< chart2::XDataSeries
>& xSeries
,
2869 const awt::Size
& rPageSize
,
2870 bool bExportContent
)
2872 OSL_ASSERT( mxExpPropMapper
.is());
2874 Reference
< chart2::XRegressionCurveContainer
> xRegressionCurveContainer( xSeries
, uno::UNO_QUERY
);
2875 if( xRegressionCurveContainer
.is() )
2877 const Sequence
< Reference
< chart2::XRegressionCurve
> > aRegCurveSeq
= xRegressionCurveContainer
->getRegressionCurves();
2879 for( const auto& xRegCurve
: aRegCurveSeq
)
2881 std::vector
< XMLPropertyState
> aEquationPropertyStates
;
2882 if (!xRegCurve
.is())
2885 Reference
< beans::XPropertySet
> xProperties( xRegCurve
, uno::UNO_QUERY
);
2886 if( !xProperties
.is() )
2889 Reference
< lang::XServiceName
> xServiceName( xProperties
, uno::UNO_QUERY
);
2890 if( !xServiceName
.is() )
2893 bool bShowEquation
= false;
2894 bool bShowRSquared
= false;
2895 bool bExportEquation
= false;
2897 OUString aService
= xServiceName
->getServiceName();
2899 std::vector
< XMLPropertyState
> aPropertyStates
= mxExpPropMapper
->Filter( xProperties
);
2901 // Add service name (which is regression type)
2902 sal_Int32 nIndex
= GetPropertySetMapper()->FindEntryIndex(XML_SCH_CONTEXT_SPECIAL_REGRESSION_TYPE
);
2903 XMLPropertyState
property(nIndex
, uno::makeAny(aService
));
2904 aPropertyStates
.push_back(property
);
2906 Reference
< beans::XPropertySet
> xEquationProperties
;
2907 xEquationProperties
.set( xRegCurve
->getEquationProperties() );
2908 if( xEquationProperties
.is())
2910 xEquationProperties
->getPropertyValue( "ShowEquation") >>= bShowEquation
;
2911 xEquationProperties
->getPropertyValue( "ShowCorrelationCoefficient") >>= bShowRSquared
;
2913 bExportEquation
= ( bShowEquation
|| bShowRSquared
);
2914 const SvtSaveOptions::ODFDefaultVersion
nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
2915 if( nCurrentVersion
< SvtSaveOptions::ODFVER_012
)
2917 bExportEquation
=false;
2919 if( bExportEquation
)
2922 sal_Int32 nNumberFormat
= 0;
2923 if( (xEquationProperties
->getPropertyValue("NumberFormat") >>= nNumberFormat
) &&
2924 nNumberFormat
!= -1 )
2926 mrExport
.addDataStyle( nNumberFormat
);
2928 aEquationPropertyStates
= mxExpPropMapper
->Filter( xEquationProperties
);
2932 if( !aPropertyStates
.empty() || bExportEquation
)
2935 if( bExportContent
)
2937 // add style name attribute
2938 if( !aPropertyStates
.empty())
2940 AddAutoStyleAttribute( aPropertyStates
);
2943 SvXMLElementExport
aRegressionExport( mrExport
, XML_NAMESPACE_CHART
, XML_REGRESSION_CURVE
, true, true );
2944 if( bExportEquation
)
2946 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_DISPLAY_EQUATION
, (bShowEquation
? XML_TRUE
: XML_FALSE
) );
2947 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_DISPLAY_R_SQUARE
, (bShowRSquared
? XML_TRUE
: XML_FALSE
) );
2950 chart2::RelativePosition aRelativePosition
;
2951 if( xEquationProperties
->getPropertyValue( "RelativePosition" ) >>= aRelativePosition
)
2953 double fX
= aRelativePosition
.Primary
* rPageSize
.Width
;
2954 double fY
= aRelativePosition
.Secondary
* rPageSize
.Height
;
2956 aPos
.X
= static_cast< sal_Int32
>( ::rtl::math::round( fX
));
2957 aPos
.Y
= static_cast< sal_Int32
>( ::rtl::math::round( fY
));
2958 addPosition( aPos
);
2961 if( !aEquationPropertyStates
.empty())
2963 AddAutoStyleAttribute( aEquationPropertyStates
);
2966 SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_EQUATION
, true, true );
2971 if( !aPropertyStates
.empty())
2973 CollectAutoStyle( aPropertyStates
);
2975 if( bExportEquation
&& !aEquationPropertyStates
.empty())
2977 CollectAutoStyle( aEquationPropertyStates
);
2985 void SchXMLExportHelper_Impl::exportErrorBar( const Reference
<beans::XPropertySet
> &xSeriesProp
,
2986 bool bYError
, bool bExportContent
)
2988 assert(mxExpPropMapper
.is());
2990 const SvtSaveOptions::ODFDefaultVersion
nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
2992 /// Don't export X ErrorBars for older ODF versions.
2993 if ( !bYError
&& nCurrentVersion
< SvtSaveOptions::ODFVER_012
)
2996 if (xSeriesProp
.is())
2998 bool bNegative
= false, bPositive
= false;
2999 sal_Int32 nErrorBarStyle
= chart::ErrorBarStyle::NONE
;
3000 Reference
< beans::XPropertySet
> xErrorBarProp
;
3004 Any aAny
= xSeriesProp
->getPropertyValue( bYError
? OUString("ErrorBarY") : OUString("ErrorBarX") );
3005 aAny
>>= xErrorBarProp
;
3007 if ( xErrorBarProp
.is() )
3009 aAny
= xErrorBarProp
->getPropertyValue("ShowNegativeError" );
3012 aAny
= xErrorBarProp
->getPropertyValue("ShowPositiveError" );
3015 aAny
= xErrorBarProp
->getPropertyValue("ErrorBarStyle" );
3016 aAny
>>= nErrorBarStyle
;
3019 catch( const beans::UnknownPropertyException
& )
3021 TOOLS_INFO_EXCEPTION("xmloff.chart", "Required property not found in DataRowProperties" );
3024 if( nErrorBarStyle
!= chart::ErrorBarStyle::NONE
&& (bNegative
|| bPositive
))
3026 if( bExportContent
&& nErrorBarStyle
== chart::ErrorBarStyle::FROM_DATA
)
3028 // register data ranges for error bars for export in local table
3029 ::std::vector
< Reference
< chart2::data::XDataSequence
> > aErrorBarSequences(
3030 lcl_getErrorBarSequences( xErrorBarProp
));
3031 for( const auto& rErrorBarSequence
: aErrorBarSequences
)
3033 m_aDataSequencesToExport
.emplace_back(
3034 uno::Reference
< chart2::data::XDataSequence
>(), rErrorBarSequence
);
3038 std::vector
< XMLPropertyState
> aPropertyStates
= mxExpPropMapper
->Filter( xErrorBarProp
);
3040 if( !aPropertyStates
.empty() )
3043 if( bExportContent
)
3045 // add style name attribute
3046 AddAutoStyleAttribute( aPropertyStates
);
3048 if( nCurrentVersion
>= SvtSaveOptions::ODFVER_012
)
3049 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_DIMENSION
, bYError
? XML_Y
: XML_X
);//#i114149#
3050 SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_ERROR_INDICATOR
, true, true );
3054 CollectAutoStyle( aPropertyStates
);
3061 void SchXMLExportHelper_Impl::exportCandleStickSeries(
3062 const Sequence
< Reference
< chart2::XDataSeries
> > & aSeriesSeq
,
3063 const Reference
< chart2::XDiagram
> & xDiagram
,
3064 bool bJapaneseCandleSticks
,
3065 bool bExportContent
)
3068 for( const auto& xSeries
: aSeriesSeq
)
3070 sal_Int32 nAttachedAxis
= lcl_isSeriesAttachedToFirstAxis( xSeries
)
3071 ? chart::ChartAxisAssign::PRIMARY_Y
3072 : chart::ChartAxisAssign::SECONDARY_Y
;
3074 Reference
< chart2::data::XDataSource
> xSource( xSeries
, uno::UNO_QUERY
);
3077 // export series in correct order (as we don't store roles)
3078 // with japanese candlesticks: open, low, high, close
3079 // otherwise: low, high, close
3080 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeqCnt(
3081 xSource
->getDataSequences());
3083 sal_Int32 nSeriesLength
=
3084 lcl_getSequenceLengthByRole( aSeqCnt
, "values-last");
3086 if( bExportContent
)
3088 Reference
< chart2::XChartDocument
> xNewDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
3089 //@todo: export data points
3091 //TODO: moggi: same code three times
3093 if( bJapaneseCandleSticks
)
3095 tLabelAndValueRange
aRanges( lcl_getLabelAndValueRangeByRole(
3096 aSeqCnt
, "values-first", xNewDoc
, m_aDataSequencesToExport
));
3097 if( !aRanges
.second
.isEmpty())
3098 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, aRanges
.second
);
3099 if( !aRanges
.first
.isEmpty())
3100 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
, aRanges
.first
);
3101 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
3102 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
3104 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
3105 SvXMLElementExport
aOpenSeries( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, true, true );
3106 // export empty data points
3107 exportDataPoints( nullptr, nSeriesLength
, xDiagram
, bExportContent
);
3112 tLabelAndValueRange
aRanges( lcl_getLabelAndValueRangeByRole(
3113 aSeqCnt
, "values-min", xNewDoc
, m_aDataSequencesToExport
));
3114 if( !aRanges
.second
.isEmpty())
3115 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, aRanges
.second
);
3116 if( !aRanges
.first
.isEmpty())
3117 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
, aRanges
.first
);
3118 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
3119 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
3121 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
3122 SvXMLElementExport
aLowSeries( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, true, true );
3123 // export empty data points
3124 exportDataPoints( nullptr, nSeriesLength
, xDiagram
, bExportContent
);
3129 tLabelAndValueRange
aRanges( lcl_getLabelAndValueRangeByRole(
3130 aSeqCnt
, "values-max", xNewDoc
, m_aDataSequencesToExport
));
3131 if( !aRanges
.second
.isEmpty())
3132 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, aRanges
.second
);
3133 if( !aRanges
.first
.isEmpty())
3134 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
, aRanges
.first
);
3135 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
3136 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
3138 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
3139 SvXMLElementExport
aHighSeries( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, true, true );
3140 // export empty data points
3141 exportDataPoints( nullptr, nSeriesLength
, xDiagram
, bExportContent
);
3146 tLabelAndValueRange
aRanges( lcl_getLabelAndValueRangeByRole(
3147 aSeqCnt
, "values-last", xNewDoc
, m_aDataSequencesToExport
));
3148 if( !aRanges
.second
.isEmpty())
3149 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, aRanges
.second
);
3150 if( !aRanges
.first
.isEmpty())
3151 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
, aRanges
.first
);
3152 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
3153 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
3155 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
3156 SvXMLElementExport
aCloseSeries( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, true, true );
3157 // export empty data points
3158 exportDataPoints( nullptr, nSeriesLength
, xDiagram
, bExportContent
);
3165 // remove property states for autostyles
3170 void SchXMLExportHelper_Impl::exportDataPoints(
3171 const uno::Reference
< beans::XPropertySet
> & xSeriesProperties
,
3172 sal_Int32 nSeriesLength
,
3173 const uno::Reference
< chart2::XDiagram
> & xDiagram
,
3174 bool bExportContent
)
3178 // write data-points only if they contain autostyles
3179 // objects with equal autostyles are grouped using the attribute
3182 // Note: if only the nth data-point has autostyles there is an element
3183 // without style and repeat="n-1" attribute written in advance.
3185 // the sequence aDataPointSeq contains indices of data-points that
3186 // do have own attributes. This increases the performance substantially.
3188 // more performant version for #93600#
3189 if (!mxExpPropMapper
.is())
3192 uno::Reference
< chart2::XDataSeries
> xSeries( xSeriesProperties
, uno::UNO_QUERY
);
3194 std::vector
< XMLPropertyState
> aPropertyStates
;
3196 bool bVaryColorsByPoint
= false;
3197 Sequence
< sal_Int32
> aDataPointSeq
;
3198 if( xSeriesProperties
.is())
3200 xSeriesProperties
->getPropertyValue("AttributedDataPoints") >>= aDataPointSeq
;
3201 xSeriesProperties
->getPropertyValue("VaryColorsByPoint") >>= bVaryColorsByPoint
;
3204 sal_Int32 nSize
= aDataPointSeq
.getLength();
3205 SAL_WARN_IF( nSize
> nSeriesLength
, "xmloff.chart", "Too many point attributes" );
3207 const sal_Int32
* pPoints
= aDataPointSeq
.getConstArray();
3210 Reference
< chart2::XColorScheme
> xColorScheme
;
3212 xColorScheme
.set( xDiagram
->getDefaultColorScheme());
3214 ::std::vector
< SchXMLDataPointStruct
> aDataPointVector
;
3216 sal_Int32 nLastIndex
= -1;
3219 if( bVaryColorsByPoint
&& xColorScheme
.is() )
3221 ::std::set
< sal_Int32
> aAttrPointSet
;
3222 ::std::copy( pPoints
, pPoints
+ aDataPointSeq
.getLength(),
3223 ::std::inserter( aAttrPointSet
, aAttrPointSet
.begin()));
3224 const ::std::set
< sal_Int32
>::const_iterator
aEndIt( aAttrPointSet
.end());
3225 for( nElement
= 0; nElement
< nSeriesLength
; ++nElement
)
3227 aPropertyStates
.clear();
3228 uno::Reference
< beans::XPropertySet
> xPropSet
;
3229 bool bExportNumFmt
= false;
3230 if( aAttrPointSet
.find( nElement
) != aEndIt
)
3234 xPropSet
= SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
3235 xSeries
, nElement
, mrExport
.GetModel() );
3236 bExportNumFmt
= true;
3238 catch( const uno::Exception
& )
3240 TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught during Export of data point" );
3245 // property set only containing the color
3246 xPropSet
.set( new ::xmloff::chart::ColorPropertySet(
3247 xColorScheme
->getColorByIndex( nElement
)));
3249 SAL_WARN_IF( !xPropSet
.is(), "xmloff.chart", "Pie Segments should have properties" );
3252 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
3253 if( nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
&& bExportNumFmt
)
3255 lcl_exportNumberFormat( "NumberFormat", xPropSet
, mrExport
);
3256 lcl_exportNumberFormat( "PercentageNumberFormat", xPropSet
, mrExport
);
3259 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
3260 if( !aPropertyStates
.empty() )
3262 if( bExportContent
)
3264 // write data-point with style
3265 SAL_WARN_IF( maAutoStyleNameQueue
.empty(), "xmloff.chart", "Autostyle queue empty!" );
3267 SchXMLDataPointStruct aPoint
;
3268 aPoint
.maStyleName
= maAutoStyleNameQueue
.front();
3270 aPoint
.mCustomLabelText
= lcl_getCustomLabelField(nElement
, xSeries
);
3271 maAutoStyleNameQueue
.pop();
3272 aDataPointVector
.push_back( aPoint
);
3276 CollectAutoStyle( aPropertyStates
);
3281 SAL_WARN_IF( bExportContent
&& (static_cast<sal_Int32
>(aDataPointVector
.size()) != nSeriesLength
), "xmloff.chart", "not enough data points on content export" );
3285 for( sal_Int32 nCurrIndex
: aDataPointSeq
)
3287 aPropertyStates
.clear();
3288 //assuming sorted indices in pPoints
3290 if( nCurrIndex
<0 || nCurrIndex
>=nSeriesLength
)
3293 // write leading empty data points
3294 if( nCurrIndex
- nLastIndex
> 1 )
3296 SchXMLDataPointStruct aPoint
;
3297 aPoint
.mnRepeat
= nCurrIndex
- nLastIndex
- 1;
3298 aDataPointVector
.push_back( aPoint
);
3301 uno::Reference
< beans::XPropertySet
> xPropSet
;
3302 // get property states
3305 xPropSet
= SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
3306 xSeries
, nCurrIndex
, mrExport
.GetModel() );
3308 catch( const uno::Exception
& )
3310 TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught during Export of data point" );
3314 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
3315 if( nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
)
3317 lcl_exportNumberFormat( "NumberFormat", xPropSet
, mrExport
);
3318 lcl_exportNumberFormat( "PercentageNumberFormat", xPropSet
, mrExport
);
3321 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
3322 if( !aPropertyStates
.empty() )
3324 if( bExportContent
)
3326 // write data-point with style
3327 SAL_WARN_IF( maAutoStyleNameQueue
.empty(), "xmloff.chart", "Autostyle queue empty!" );
3328 SchXMLDataPointStruct aPoint
;
3329 aPoint
.maStyleName
= maAutoStyleNameQueue
.front();
3330 aPoint
.mCustomLabelText
= lcl_getCustomLabelField(nCurrIndex
, xSeries
);
3331 maAutoStyleNameQueue
.pop();
3333 aDataPointVector
.push_back( aPoint
);
3334 nLastIndex
= nCurrIndex
;
3338 CollectAutoStyle( aPropertyStates
);
3344 // if we get here the property states are empty
3345 SchXMLDataPointStruct aPoint
;
3346 aDataPointVector
.push_back( aPoint
);
3348 nLastIndex
= nCurrIndex
;
3350 // final empty elements
3351 nRepeat
= nSeriesLength
- nLastIndex
- 1;
3354 SchXMLDataPointStruct aPoint
;
3355 aPoint
.mnRepeat
= nRepeat
;
3356 aDataPointVector
.push_back( aPoint
);
3360 if (!bExportContent
)
3363 // write elements (merge equal ones)
3364 SchXMLDataPointStruct aPoint
;
3365 SchXMLDataPointStruct aLastPoint
;
3367 // initialize so that it doesn't matter if
3368 // the element is counted in the first iteration
3369 aLastPoint
.mnRepeat
= 0;
3371 for( const auto& rPoint
: aDataPointVector
)
3375 if( aPoint
.maStyleName
== aLastPoint
.maStyleName
&& aLastPoint
.mCustomLabelText
.getLength() < 1 )
3376 aPoint
.mnRepeat
+= aLastPoint
.mnRepeat
;
3377 else if( aLastPoint
.mnRepeat
> 0 )
3379 // write last element
3380 if( !aLastPoint
.maStyleName
.isEmpty() )
3381 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_STYLE_NAME
, aLastPoint
.maStyleName
);
3383 if( aLastPoint
.mnRepeat
> 1 )
3384 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_REPEATED
,
3385 OUString::number( ( aLastPoint
.mnRepeat
) ));
3387 SvXMLElementExport
aPointElem( mrExport
, XML_NAMESPACE_CHART
, XML_DATA_POINT
, true, true );
3388 exportCustomLabel(aLastPoint
.mCustomLabelText
);
3390 aLastPoint
= aPoint
;
3392 // write last element if it hasn't been written in last iteration
3393 if( aPoint
.maStyleName
== aLastPoint
.maStyleName
)
3395 if( !aLastPoint
.maStyleName
.isEmpty() )
3396 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_STYLE_NAME
, aLastPoint
.maStyleName
);
3398 if( aLastPoint
.mnRepeat
> 1 )
3399 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_REPEATED
,
3400 OUString::number( ( aLastPoint
.mnRepeat
) ));
3402 SvXMLElementExport
aPointElem( mrExport
, XML_NAMESPACE_CHART
, XML_DATA_POINT
, true, true );
3403 exportCustomLabel(aLastPoint
.mCustomLabelText
);
3407 void SchXMLExportHelper_Impl::exportCustomLabel( const CustomLabelSeq
& xCustomLabel
)
3409 if( xCustomLabel
.getLength() < 1 )
3410 return; // nothing to export
3412 SvXMLElementExport
aLabelElem( mrExport
, XML_NAMESPACE_CHART
, XML_DATA_LABEL
, true, true);
3413 SvXMLElementExport
aPara( mrExport
, XML_NAMESPACE_TEXT
, XML_P
, true, false );
3414 for( const Reference
<chart2::XDataPointCustomLabelField
>& label
: xCustomLabel
)
3417 SvXMLElementExport
aSpan( mrExport
, XML_NAMESPACE_TEXT
, XML_SPAN
, true, false);
3418 mrExport
.GetDocHandler()->characters(label
->getString());
3422 void SchXMLExportHelper_Impl::addPosition( const awt::Point
& rPosition
)
3424 mrExport
.GetMM100UnitConverter().convertMeasureToXML(
3425 msStringBuffer
, rPosition
.X
);
3426 msString
= msStringBuffer
.makeStringAndClear();
3427 mrExport
.AddAttribute( XML_NAMESPACE_SVG
, XML_X
, msString
);
3429 mrExport
.GetMM100UnitConverter().convertMeasureToXML(
3430 msStringBuffer
, rPosition
.Y
);
3431 msString
= msStringBuffer
.makeStringAndClear();
3432 mrExport
.AddAttribute( XML_NAMESPACE_SVG
, XML_Y
, msString
);
3435 void SchXMLExportHelper_Impl::addPosition( const Reference
< drawing::XShape
>& xShape
)
3438 addPosition( xShape
->getPosition());
3441 void SchXMLExportHelper_Impl::addSize( const awt::Size
& rSize
, bool bIsOOoNamespace
)
3443 mrExport
.GetMM100UnitConverter().convertMeasureToXML(
3444 msStringBuffer
, rSize
.Width
);
3445 msString
= msStringBuffer
.makeStringAndClear();
3446 mrExport
.AddAttribute( bIsOOoNamespace
? XML_NAMESPACE_CHART_EXT
: XML_NAMESPACE_SVG
, XML_WIDTH
, msString
);
3448 mrExport
.GetMM100UnitConverter().convertMeasureToXML(
3449 msStringBuffer
, rSize
.Height
);
3450 msString
= msStringBuffer
.makeStringAndClear();
3451 mrExport
.AddAttribute( bIsOOoNamespace
? XML_NAMESPACE_CHART_EXT
: XML_NAMESPACE_SVG
, XML_HEIGHT
, msString
);
3454 void SchXMLExportHelper_Impl::addSize( const Reference
< drawing::XShape
>& xShape
)
3457 addSize( xShape
->getSize() );
3460 awt::Size
SchXMLExportHelper_Impl::getPageSize( const Reference
< chart2::XChartDocument
> & xChartDoc
)
3462 awt::Size
aSize( 8000, 7000 );
3463 uno::Reference
< embed::XVisualObject
> xVisualObject( xChartDoc
, uno::UNO_QUERY
);
3464 SAL_WARN_IF( !xVisualObject
.is(), "xmloff.chart", "need XVisualObject for page size" );
3465 if( xVisualObject
.is() )
3466 aSize
= xVisualObject
->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT
);
3471 void SchXMLExportHelper_Impl::CollectAutoStyle( const std::vector
< XMLPropertyState
>& aStates
)
3473 if( !aStates
.empty() )
3474 maAutoStyleNameQueue
.push( GetAutoStylePoolP().Add( XML_STYLE_FAMILY_SCH_CHART_ID
, aStates
));
3477 void SchXMLExportHelper_Impl::AddAutoStyleAttribute( const std::vector
< XMLPropertyState
>& aStates
)
3479 if( !aStates
.empty() )
3481 SAL_WARN_IF( maAutoStyleNameQueue
.empty(), "xmloff.chart", "Autostyle queue empty!" );
3483 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_STYLE_NAME
, maAutoStyleNameQueue
.front() );
3484 maAutoStyleNameQueue
.pop();
3488 void SchXMLExportHelper_Impl::exportText( const OUString
& rText
)
3490 SchXMLTools::exportText( mrExport
, rText
, false/*bConvertTabsLFs*/ );
3493 // class SchXMLExport
3495 SchXMLExport::SchXMLExport(const Reference
<uno::XComponentContext
>& xContext
,
3496 OUString
const& implementationName
, SvXMLExportFlags nExportFlags
)
3497 : SvXMLExport(util::MeasureUnit::CM
, xContext
, implementationName
, ::xmloff::token::XML_CHART
,
3499 , maAutoStylePool(new SchXMLAutoStylePoolP(*this))
3500 , maExportHelper(new SchXMLExportHelper(*this, *maAutoStylePool
))
3502 if( getDefaultVersion() > SvtSaveOptions::ODFVER_012
)
3503 GetNamespaceMap_().Add( GetXMLToken(XML_NP_CHART_EXT
), GetXMLToken(XML_N_CHART_EXT
), XML_NAMESPACE_CHART_EXT
);
3506 SchXMLExport::~SchXMLExport()
3510 ErrCode
SchXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum eClass
)
3512 maExportHelper
->SetSourceShellID(GetSourceShellID());
3513 maExportHelper
->SetDestinationShellID(GetDestinationShellID());
3515 Reference
< chart2::XChartDocument
> xChartDoc( GetModel(), uno::UNO_QUERY
);
3516 maExportHelper
->m_pImpl
->InitRangeSegmentationProperties( xChartDoc
);
3517 return SvXMLExport::exportDoc( eClass
);
3520 void SchXMLExport::ExportMasterStyles_()
3522 // not available in chart
3523 SAL_INFO("xmloff.chart", "Master Style Export requested. Not available for Chart" );
3526 void SchXMLExport::collectAutoStyles()
3528 SvXMLExport::collectAutoStyles();
3530 if (mbAutoStylesCollected
)
3533 // there are no styles that require their own autostyles
3534 if( getExportFlags() & SvXMLExportFlags::CONTENT
)
3536 Reference
< chart::XChartDocument
> xChartDoc( GetModel(), uno::UNO_QUERY
);
3539 maExportHelper
->m_pImpl
->collectAutoStyles( xChartDoc
);
3543 SAL_WARN("xmloff.chart", "Couldn't export chart due to wrong XModel (must be XChartDocument)" );
3546 mbAutoStylesCollected
= true;
3549 void SchXMLExport::ExportAutoStyles_()
3551 collectAutoStyles();
3553 if( getExportFlags() & SvXMLExportFlags::CONTENT
)
3555 Reference
< chart::XChartDocument
> xChartDoc( GetModel(), uno::UNO_QUERY
);
3558 maExportHelper
->m_pImpl
->exportAutoStyles();
3562 SAL_WARN("xmloff.chart", "Couldn't export chart due to wrong XModel (must be XChartDocument)" );
3567 void SchXMLExport::ExportContent_()
3569 Reference
< chart::XChartDocument
> xChartDoc( GetModel(), uno::UNO_QUERY
);
3572 // determine if data comes from the outside
3573 bool bIncludeTable
= true;
3575 Reference
< chart2::XChartDocument
> xNewDoc( xChartDoc
, uno::UNO_QUERY
);
3578 // check if we have own data. If so we must not export the complete
3579 // range string, as this is our only indicator for having own or
3580 // external data. @todo: fix this in the file format!
3581 Reference
< lang::XServiceInfo
> xDPServiceInfo( xNewDoc
->getDataProvider(), uno::UNO_QUERY
);
3582 if( ! (xDPServiceInfo
.is() && xDPServiceInfo
->getImplementationName() == "com.sun.star.comp.chart.InternalDataProvider" ))
3584 bIncludeTable
= false;
3589 Reference
< lang::XServiceInfo
> xServ( xChartDoc
, uno::UNO_QUERY
);
3592 if( xServ
->supportsService( "com.sun.star.chart.ChartTableAddressSupplier" ))
3594 Reference
< beans::XPropertySet
> xProp( xServ
, uno::UNO_QUERY
);
3600 OUString sChartAddress
;
3601 aAny
= xProp
->getPropertyValue( "ChartRangeAddress" );
3602 aAny
>>= sChartAddress
;
3603 maExportHelper
->m_pImpl
->SetChartRangeAddress( sChartAddress
);
3605 // do not include own table if there are external addresses
3606 bIncludeTable
= sChartAddress
.isEmpty();
3608 catch( const beans::UnknownPropertyException
& )
3610 SAL_WARN("xmloff.chart", "Property ChartRangeAddress not supported by ChartDocument" );
3616 maExportHelper
->m_pImpl
->exportChart( xChartDoc
, bIncludeTable
);
3620 SAL_WARN("xmloff.chart", "Couldn't export chart due to wrong XModel" );
3624 rtl::Reference
< XMLPropertySetMapper
> const & SchXMLExport::GetPropertySetMapper() const
3626 return maExportHelper
->m_pImpl
->GetPropertySetMapper();
3629 void SchXMLExportHelper_Impl::InitRangeSegmentationProperties( const Reference
< chart2::XChartDocument
> & xChartDoc
)
3634 Reference
< chart2::data::XDataProvider
> xDataProvider( xChartDoc
->getDataProvider() );
3635 SAL_WARN_IF( !xDataProvider
.is(), "xmloff.chart", "No DataProvider" );
3636 if( xDataProvider
.is())
3638 Reference
< chart2::data::XDataSource
> xDataSource( lcl_pressUsedDataIntoRectangularFormat( xChartDoc
, mbHasCategoryLabels
));
3639 const Sequence
< beans::PropertyValue
> aArgs( xDataProvider
->detectArguments( xDataSource
));
3640 OUString sCellRange
, sBrokenRange
;
3641 bool bBrokenRangeAvailable
= false;
3642 for( const auto& rArg
: aArgs
)
3644 if ( rArg
.Name
== "CellRangeRepresentation" )
3645 rArg
.Value
>>= sCellRange
;
3646 else if ( rArg
.Name
== "BrokenCellRangeForExport" )
3648 if( rArg
.Value
>>= sBrokenRange
)
3649 bBrokenRangeAvailable
= true;
3651 else if ( rArg
.Name
== "DataRowSource" )
3653 chart::ChartDataRowSource eRowSource
;
3654 rArg
.Value
>>= eRowSource
;
3655 mbRowSourceColumns
= ( eRowSource
== chart::ChartDataRowSource_COLUMNS
);
3657 else if ( rArg
.Name
== "SequenceMapping" )
3658 rArg
.Value
>>= maSequenceMapping
;
3661 // #i79009# For Writer we have to export a broken version of the
3662 // range, where every row number is not too large, so that older
3663 // version can correctly read those files.
3664 msChartAddress
= (bBrokenRangeAvailable
? sBrokenRange
: sCellRange
);
3665 if( !msChartAddress
.isEmpty() )
3667 // convert format to XML-conform one
3668 Reference
< chart2::data::XRangeXMLConversion
> xConversion( xDataProvider
, uno::UNO_QUERY
);
3669 if( xConversion
.is())
3670 msChartAddress
= xConversion
->convertRangeToXML( msChartAddress
);
3674 catch( const uno::Exception
& )
3676 DBG_UNHANDLED_EXCEPTION("xmloff.chart");
3680 // first version: everything goes in one storage
3682 Sequence
< OUString
> SchXMLExport_getSupportedServiceNames() throw()
3684 return Sequence
< OUString
> { "com.sun.star.comp.Chart.XMLExporter" };
3687 OUString
SchXMLExport_getImplementationName() throw()
3689 return "SchXMLExport.Compact";
3692 Reference
< uno::XInterface
> SchXMLExport_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
)
3694 // #103997# removed some flags from EXPORT_ALL
3695 return static_cast<cppu::OWeakObject
*>(new SchXMLExport( comphelper::getComponentContext(rSMgr
), SchXMLExport_getImplementationName(), SvXMLExportFlags::ALL
^ ( SvXMLExportFlags::SETTINGS
| SvXMLExportFlags::MASTERSTYLES
| SvXMLExportFlags::SCRIPTS
)));
3699 Sequence
< OUString
> SchXMLExport_Oasis_getSupportedServiceNames() throw()
3701 return Sequence
< OUString
> { "com.sun.star.comp.Chart.XMLOasisExporter" };
3704 OUString
SchXMLExport_Oasis_getImplementationName() throw()
3706 return "SchXMLExport.Oasis.Compact";
3709 Reference
< uno::XInterface
> SchXMLExport_Oasis_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
)
3711 // #103997# removed some flags from EXPORT_ALL
3712 return static_cast<cppu::OWeakObject
*>(new SchXMLExport( comphelper::getComponentContext(rSMgr
),
3713 SchXMLExport_Oasis_getImplementationName(),
3714 (SvXMLExportFlags::ALL
^ ( SvXMLExportFlags::SETTINGS
| SvXMLExportFlags::MASTERSTYLES
| SvXMLExportFlags::SCRIPTS
)) | SvXMLExportFlags::OASIS
));
3717 // multiple storage version: one for content / styles / meta
3719 Sequence
< OUString
> SchXMLExport_Styles_getSupportedServiceNames() throw()
3721 return Sequence
< OUString
> { "com.sun.star.comp.Chart.XMLStylesExporter" };
3724 OUString
SchXMLExport_Styles_getImplementationName() throw()
3726 return "SchXMLExport.Styles";
3729 Reference
< uno::XInterface
> SchXMLExport_Styles_createInstance(const Reference
< lang::XMultiServiceFactory
>& rSMgr
)
3731 return static_cast<cppu::OWeakObject
*>(new SchXMLExport( comphelper::getComponentContext(rSMgr
), SchXMLExport_Styles_getImplementationName(), SvXMLExportFlags::STYLES
));
3735 Sequence
< OUString
> SchXMLExport_Oasis_Styles_getSupportedServiceNames() throw()
3737 return Sequence
< OUString
> { "com.sun.star.comp.Chart.XMLOasisStylesExporter" };
3740 OUString
SchXMLExport_Oasis_Styles_getImplementationName() throw()
3742 return "SchXMLExport.Oasis.Styles";
3745 Reference
< uno::XInterface
> SchXMLExport_Oasis_Styles_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
)
3747 return static_cast<cppu::OWeakObject
*>(new SchXMLExport( comphelper::getComponentContext(rSMgr
), SchXMLExport_Oasis_Styles_getImplementationName(), SvXMLExportFlags::STYLES
| SvXMLExportFlags::OASIS
));
3750 Sequence
< OUString
> SchXMLExport_Content_getSupportedServiceNames() throw()
3752 return Sequence
< OUString
> { "com.sun.star.comp.Chart.XMLContentExporter" };
3755 OUString
SchXMLExport_Content_getImplementationName() throw()
3757 return "SchXMLExport.Content";
3760 Reference
< uno::XInterface
> SchXMLExport_Content_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
)
3762 return static_cast<cppu::OWeakObject
*>(new SchXMLExport( comphelper::getComponentContext(rSMgr
), SchXMLExport_Content_getImplementationName(), SvXMLExportFlags::AUTOSTYLES
| SvXMLExportFlags::CONTENT
| SvXMLExportFlags::FONTDECLS
));
3766 Sequence
< OUString
> SchXMLExport_Oasis_Content_getSupportedServiceNames() throw()
3768 return Sequence
< OUString
> { "com.sun.star.comp.Chart.XMLOasisContentExporter" };
3771 OUString
SchXMLExport_Oasis_Content_getImplementationName() throw()
3773 return "SchXMLExport.Oasis.Content";
3776 Reference
< uno::XInterface
> SchXMLExport_Oasis_Content_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
)
3778 return static_cast<cppu::OWeakObject
*>(new SchXMLExport( comphelper::getComponentContext(rSMgr
), SchXMLExport_Oasis_Content_getImplementationName(), SvXMLExportFlags::AUTOSTYLES
| SvXMLExportFlags::CONTENT
| SvXMLExportFlags::FONTDECLS
| SvXMLExportFlags::OASIS
));
3782 Sequence
< OUString
> SchXMLExport_Oasis_Meta_getSupportedServiceNames() throw()
3784 return Sequence
< OUString
> { "com.sun.star.comp.Chart.XMLOasisMetaExporter" };
3787 OUString
SchXMLExport_Oasis_Meta_getImplementationName() throw()
3789 return "SchXMLExport.Oasis.Meta";
3792 Reference
< uno::XInterface
> SchXMLExport_Oasis_Meta_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
)
3794 return static_cast<cppu::OWeakObject
*>(new SchXMLExport( comphelper::getComponentContext(rSMgr
), SchXMLExport_Oasis_Meta_getImplementationName(), SvXMLExportFlags::META
| SvXMLExportFlags::OASIS
));
3797 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */