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 .
20 #include <sal/config.h>
22 #include <sax/tools/converter.hxx>
24 #include <xmloff/xmlprmap.hxx>
26 #include "SchXMLExport.hxx"
27 #include "XMLChartPropertySetMapper.hxx"
28 #include "ColorPropertySet.hxx"
29 #include "SchXMLTools.hxx"
30 #include "SchXMLEnumConverter.hxx"
33 #include <comphelper/processfactory.hxx>
34 #include <tools/globname.hxx>
35 #include <comphelper/classids.hxx>
36 #include <comphelper/sequence.hxx>
38 #include <xmloff/nmspmap.hxx>
39 #include <xmloff/xmlnmspe.hxx>
40 #include <xmloff/xmltoken.hxx>
41 #include <xmloff/families.hxx>
42 #include <xmloff/xmlaustp.hxx>
43 #include <xmloff/xmluconv.hxx>
44 #include <xmloff/xmlmetae.hxx>
45 #include <xmloff/SchXMLSeriesHelper.hxx>
46 #include "xexptran.hxx"
47 #include <rtl/math.hxx>
48 #include <comphelper/extract.hxx>
54 #include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
55 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
56 #include <com/sun/star/lang/XServiceInfo.hpp>
57 #include <com/sun/star/lang/XServiceName.hpp>
58 #include <com/sun/star/beans/XPropertySet.hpp>
59 #include <com/sun/star/uno/XComponentContext.hpp>
60 #include <com/sun/star/util/XRefreshable.hpp>
62 #include <com/sun/star/chart/XAxis.hpp>
63 #include <com/sun/star/chart/XAxisSupplier.hpp>
64 #include <com/sun/star/chart/XChartDocument.hpp>
65 #include <com/sun/star/chart/ChartLegendPosition.hpp>
66 #include <com/sun/star/chart/ChartLegendExpansion.hpp>
67 #include <com/sun/star/chart/ChartDataRowSource.hpp>
68 #include <com/sun/star/chart/ChartAxisAssign.hpp>
69 #include <com/sun/star/chart/ChartAxisType.hpp>
70 #include <com/sun/star/chart/TimeIncrement.hpp>
71 #include <com/sun/star/chart/TimeInterval.hpp>
72 #include <com/sun/star/chart/TimeUnit.hpp>
73 #include <com/sun/star/chart/ChartSeriesAddress.hpp>
74 #include <com/sun/star/chart/X3DDisplay.hpp>
75 #include <com/sun/star/chart/XStatisticDisplay.hpp>
76 #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
77 #include <com/sun/star/chart/XDiagramPositioning.hpp>
79 #include <com/sun/star/chart2/XAnyDescriptionAccess.hpp>
80 #include <com/sun/star/chart2/AxisType.hpp>
81 #include <com/sun/star/chart2/XChartDocument.hpp>
82 #include <com/sun/star/chart2/XDiagram.hpp>
83 #include <com/sun/star/chart2/RelativePosition.hpp>
84 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
85 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
86 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
87 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
88 #include <com/sun/star/chart2/data/XDataSource.hpp>
89 #include <com/sun/star/chart2/data/XDataSink.hpp>
90 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
91 #include <com/sun/star/chart2/data/XDataProvider.hpp>
92 #include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
93 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
94 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
95 #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
97 #include <com/sun/star/util/MeasureUnit.hpp>
98 #include <com/sun/star/util/XStringMapping.hpp>
99 #include <com/sun/star/drawing/HomogenMatrix.hpp>
100 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
101 #include <com/sun/star/drawing/XShapes.hpp>
102 #include <com/sun/star/embed/Aspects.hpp>
103 #include <com/sun/star/embed/XVisualObject.hpp>
104 #include <com/sun/star/container/XChild.hpp>
106 #include "MultiPropertySetHandler.hxx"
107 #include "PropertyMap.hxx"
109 using namespace com::sun::star
;
110 using namespace ::xmloff::token
;
112 using namespace ::com::sun::star
;
113 using ::com::sun::star::uno::Sequence
;
114 using ::com::sun::star::uno::Reference
;
115 using ::com::sun::star::uno::Any
;
118 // class SchXMLExportHelper_Impl
120 class SchXMLExportHelper_Impl
123 // first: data sequence for label, second: data sequence for values.
124 typedef ::std::pair
< css::uno::Reference
< css::chart2::data::XDataSequence
>,
125 css::uno::Reference
< css::chart2::data::XDataSequence
> > tLabelValuesDataPair
;
126 typedef ::std::vector
< tLabelValuesDataPair
> tDataSequenceCont
;
129 SchXMLExportHelper_Impl( SvXMLExport
& rExport
,
130 SvXMLAutoStylePoolP
& rASPool
);
132 virtual ~SchXMLExportHelper_Impl();
134 SchXMLExportHelper_Impl(const SchXMLExportHelper_Impl
&) = delete;
135 SchXMLExportHelper_Impl
& operator=(const SchXMLExportHelper_Impl
&) = delete;
138 /// parse chart and collect all auto-styles used in current pool
139 void collectAutoStyles( css::uno::Reference
< css::chart::XChartDocument
> rChartDoc
);
141 /// write the styles collected into the current pool as <style:style> elements
142 void exportAutoStyles();
144 /** export the <chart:chart> element corresponding to rChartDoc
145 if bIncludeTable is true, the chart data is exported as <table:table>
146 element (inside the chart element).
148 Otherwise the external references stored in the chart document are used
149 for writing the corresponding attributes at series
151 All attributes contained in xAttrList are written at the chart element,
152 which is the outer element of a chart. So these attributes can easily
153 be parsed again by the container
155 void exportChart( css::uno::Reference
< css::chart::XChartDocument
> rChartDoc
,
156 bool bIncludeTable
);
158 const rtl::Reference
<XMLPropertySetMapper
>& GetPropertySetMapper() const;
160 void SetChartRangeAddress( const OUString
& rAddress
)
161 { msChartAddress
= rAddress
; }
162 void SetTableNumberList( const OUString
& rList
)
163 { msTableNumberList
= rList
; }
165 void InitRangeSegmentationProperties(
166 const css::uno::Reference
< css::chart2::XChartDocument
> & xChartDoc
);
168 static css::awt::Size
getPageSize(
169 const css::uno::Reference
< css::chart2::XChartDocument
> & xChartDoc
);
171 /** first parseDocument: collect autostyles and store names in this queue
172 second parseDocument: export content and use names from this queue
174 ::std::queue
< OUString
> maAutoStyleNameQueue
;
175 void CollectAutoStyle(
176 const std::vector
< XMLPropertyState
>& aStates
);
177 void AddAutoStyleAttribute(
178 const std::vector
< XMLPropertyState
>& aStates
);
180 SvXMLAutoStylePoolP
& GetAutoStylePoolP()
181 { return mrAutoStylePool
; }
183 /// if bExportContent is false the auto-styles are collected
184 void parseDocument( css::uno::Reference
< css::chart::XChartDocument
>& rChartDoc
,
186 bool bIncludeTable
= false );
189 const css::uno::Reference
< css::chart::XDiagram
>& xDiagram
,
190 const css::uno::Reference
< css::chart2::XDiagram
>& xNewDiagram
,
191 const css::awt::Size
& rPageSize
,
193 bool bIncludeTable
);
194 void exportCoordinateRegion( const css::uno::Reference
< css::chart::XDiagram
>& xDiagram
);
195 void exportAxes( const css::uno::Reference
< css::chart::XDiagram
> & xDiagram
,
196 const css::uno::Reference
< css::chart2::XDiagram
> & xNewDiagram
,
197 bool bExportContent
);
198 void exportAxis( enum XMLTokenEnum eDimension
, enum XMLTokenEnum eAxisName
,
199 const Reference
< beans::XPropertySet
>& rAxisProps
, const Reference
< chart2::XAxis
>& rChart2Axis
,
200 const OUString
& rCategoriesRanges
,
201 bool bHasTitle
, bool bHasMajorGrid
, bool bHasMinorGrid
, bool bExportContent
);
202 void exportGrid( const Reference
< beans::XPropertySet
>& rGridProperties
, bool bMajor
, bool bExportContent
);
203 void exportDateScale( const Reference
< beans::XPropertySet
>& rAxisProps
);
204 void exportAxisTitle( const Reference
< beans::XPropertySet
>& rTitleProps
, bool bExportContent
);
207 const css::uno::Reference
< css::chart2::XDiagram
> & xNewDiagram
,
208 const css::awt::Size
& rPageSize
,
212 void exportPropertyMapping(
213 const css::uno::Reference
< css::chart2::data::XDataSource
> & xSource
,
214 Sequence
< OUString
>& rSupportedMappings
);
216 void exportCandleStickSeries(
217 const css::uno::Sequence
<
218 css::uno::Reference
< css::chart2::XDataSeries
> > & aSeriesSeq
,
219 const css::uno::Reference
< css::chart2::XDiagram
> & xDiagram
,
220 bool bJapaneseCandleSticks
,
221 bool bExportContent
);
222 void exportDataPoints(
223 const css::uno::Reference
< css::beans::XPropertySet
> & xSeriesProperties
,
224 sal_Int32 nSeriesLength
,
225 const css::uno::Reference
< css::chart2::XDiagram
> & xDiagram
,
226 bool bExportContent
);
228 void exportRegressionCurve(
229 const css::uno::Reference
<css::chart2::XDataSeries
>& xSeries
,
230 const css::awt::Size
& rPageSize
,
231 bool bExportContent
);
233 void exportErrorBar (
234 const css::uno::Reference
<beans::XPropertySet
> &xSeriesProp
, bool bYError
,
235 bool bExportContent
);
237 /// add svg position as attribute for current element
238 void addPosition( const css::awt::Point
& rPosition
);
239 void addPosition( const css::uno::Reference
< css::drawing::XShape
>& xShape
);
240 /// add svg size as attribute for current element
241 void addSize( const css::awt::Size
& rSize
, bool bIsOOoNamespace
= false );
242 void addSize( const css::uno::Reference
< css::drawing::XShape
>& xShape
);
243 /// exports a string as a paragraph element
244 void exportText( const OUString
& rText
);
247 SvXMLExport
& mrExport
;
248 SvXMLAutoStylePoolP
& mrAutoStylePool
;
249 rtl::Reference
< XMLPropertySetMapper
> mxPropertySetMapper
;
250 rtl::Reference
< XMLChartExportPropertyMapper
> mxExpPropMapper
;
252 OUString msTableName
;
253 OUStringBuffer msStringBuffer
;
256 // members filled by InitRangeSegmentationProperties (retrieved from DataProvider)
257 bool mbHasSeriesLabels
;
258 bool mbHasCategoryLabels
; //if the categories are only automatically generated this will be false
259 bool mbRowSourceColumns
;
260 OUString msChartAddress
;
261 OUString msTableNumberList
;
262 css::uno::Sequence
< sal_Int32
> maSequenceMapping
;
266 OUString maSrcShellID
;
267 OUString maDestShellID
;
269 css::uno::Reference
< css::drawing::XShapes
> mxAdditionalShapes
;
271 tDataSequenceCont m_aDataSequencesToExport
;
272 OUString maCategoriesRange
;
278 class lcl_MatchesRole
: public ::std::unary_function
< Reference
< chart2::data::XLabeledDataSequence
>, bool >
281 explicit lcl_MatchesRole( const OUString
& aRole
) :
285 bool operator () ( const Reference
< chart2::data::XLabeledDataSequence
> & xSeq
) const
289 Reference
< beans::XPropertySet
> xProp( xSeq
->getValues(), uno::UNO_QUERY
);
292 return ( xProp
.is() &&
293 (xProp
->getPropertyValue( "Role" ) >>= aRole
) &&
294 m_aRole
.equals( aRole
));
301 template< typename T
>
302 void lcl_SequenceToVectorAppend( const Sequence
< T
> & rSource
, ::std::vector
< T
> & rDestination
)
304 rDestination
.reserve( rDestination
.size() + rSource
.getLength());
305 ::std::copy( rSource
.begin(), rSource
.end(),
306 ::std::back_inserter( rDestination
));
309 template< typename T
>
310 void lcl_SequenceToVector( const Sequence
< T
> & rSource
, ::std::vector
< T
> & rDestination
)
312 rDestination
.clear();
313 lcl_SequenceToVectorAppend( rSource
, rDestination
);
316 Reference
< chart2::data::XLabeledDataSequence
> lcl_getCategories( const Reference
< chart2::XDiagram
> & xDiagram
)
318 Reference
< chart2::data::XLabeledDataSequence
> xResult
;
321 Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt(
322 xDiagram
, uno::UNO_QUERY_THROW
);
323 Sequence
< Reference
< chart2::XCoordinateSystem
> > aCooSysSeq(
324 xCooSysCnt
->getCoordinateSystems());
325 for( sal_Int32 i
=0; i
<aCooSysSeq
.getLength(); ++i
)
327 Reference
< chart2::XCoordinateSystem
> xCooSys( aCooSysSeq
[i
] );
328 SAL_WARN_IF( !xCooSys
.is(), "xmloff.chart", "xCooSys is NULL" );
329 for( sal_Int32 nN
= xCooSys
->getDimension(); nN
--; )
331 const sal_Int32 nMaxAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nN
);
332 for(sal_Int32 nI
=0; nI
<=nMaxAxisIndex
; ++nI
)
334 Reference
< chart2::XAxis
> xAxis
= xCooSys
->getAxisByDimension( nN
, nI
);
335 SAL_WARN_IF( !xAxis
.is(), "xmloff.chart", "xAxis is NULL");
338 chart2::ScaleData aScaleData
= xAxis
->getScaleData();
339 if( aScaleData
.Categories
.is())
341 xResult
.set( aScaleData
.Categories
);
349 catch( const uno::Exception
& ex
)
351 SAL_WARN("xmloff.chart", "Exception caught. Type: " << OUString::createFromAscii( typeid( ex
).name()) << ", Message: " << ex
.Message
);
357 Reference
< chart2::data::XDataSource
> lcl_createDataSource(
358 const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aData
)
360 Reference
< uno::XComponentContext
> xContext(
361 comphelper::getProcessComponentContext() );
362 Reference
< chart2::data::XDataSink
> xSink(
363 xContext
->getServiceManager()->createInstanceWithContext(
364 "com.sun.star.chart2.data.DataSource", xContext
),
365 uno::UNO_QUERY_THROW
);
366 xSink
->setData( aData
);
368 return Reference
< chart2::data::XDataSource
>( xSink
, uno::UNO_QUERY
);
371 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > lcl_getAllSeriesSequences( const Reference
< chart2::XChartDocument
>& xChartDoc
)
373 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aContainer
;
376 Reference
< chart2::XDiagram
> xDiagram( xChartDoc
->getFirstDiagram());
377 ::std::vector
< Reference
< chart2::XDataSeries
> > aSeriesVector( SchXMLSeriesHelper::getDataSeriesFromDiagram( xDiagram
));
378 for( ::std::vector
< Reference
< chart2::XDataSeries
> >::const_iterator
aSeriesIt( aSeriesVector
.begin() )
379 ; aSeriesIt
!= aSeriesVector
.end(); ++aSeriesIt
)
381 Reference
< chart2::data::XDataSource
> xDataSource( *aSeriesIt
, uno::UNO_QUERY
);
382 if( !xDataSource
.is() )
384 uno::Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aDataSequences( xDataSource
->getDataSequences() );
385 lcl_SequenceToVectorAppend( aDataSequences
, aContainer
);
389 return comphelper::containerToSequence
< Reference
< chart2::data::XLabeledDataSequence
> >( aContainer
);
392 Reference
< chart2::data::XLabeledDataSequence
>
393 lcl_getDataSequenceByRole(
394 const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aLabeledSeq
,
395 const OUString
& rRole
)
397 Reference
< chart2::data::XLabeledDataSequence
> aNoResult
;
399 const Reference
< chart2::data::XLabeledDataSequence
> * pBegin
= aLabeledSeq
.getConstArray();
400 const Reference
< chart2::data::XLabeledDataSequence
> * pEnd
= pBegin
+ aLabeledSeq
.getLength();
401 const Reference
< chart2::data::XLabeledDataSequence
> * pMatch
=
402 ::std::find_if( pBegin
, pEnd
, lcl_MatchesRole( rRole
));
410 Reference
< chart2::data::XDataSource
> lcl_pressUsedDataIntoRectangularFormat( const Reference
< chart2::XChartDocument
>& xChartDoc
, bool& rOutSourceHasCategoryLabels
)
412 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aLabeledSeqVector
;
414 //categories are always the first sequence
415 Reference
< chart2::XDiagram
> xDiagram( xChartDoc
->getFirstDiagram());
416 Reference
< chart2::data::XLabeledDataSequence
> xCategories( lcl_getCategories( xDiagram
) );
417 if( xCategories
.is() )
418 aLabeledSeqVector
.push_back( xCategories
);
419 rOutSourceHasCategoryLabels
= xCategories
.is();
421 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeriesSeqVector(
422 lcl_getAllSeriesSequences( xChartDoc
) );
424 //the first x-values is always the next sequence //todo ... other x-values get lost for old format
425 Reference
< chart2::data::XLabeledDataSequence
> xXValues(
426 lcl_getDataSequenceByRole( aSeriesSeqVector
, "values-x" ) );
428 aLabeledSeqVector
.push_back( xXValues
);
430 //add all other sequences now without x-values
431 lcl_MatchesRole
aHasXValues( OUString( "values-x" ) );
432 for( sal_Int32 nN
=0; nN
<aSeriesSeqVector
.getLength(); nN
++ )
434 if( !aHasXValues( aSeriesSeqVector
[nN
] ) )
435 aLabeledSeqVector
.push_back( aSeriesSeqVector
[nN
] );
438 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeq( comphelper::containerToSequence(aLabeledSeqVector
) );
440 return lcl_createDataSource( aSeq
);
443 bool lcl_isSeriesAttachedToFirstAxis(
444 const Reference
< chart2::XDataSeries
> & xDataSeries
)
450 sal_Int32 nAxisIndex
= 0;
451 Reference
< beans::XPropertySet
> xProp( xDataSeries
, uno::UNO_QUERY_THROW
);
453 xProp
->getPropertyValue("AttachedAxisIndex") >>= nAxisIndex
;
454 bResult
= (0==nAxisIndex
);
456 catch( const uno::Exception
& ex
)
458 SAL_WARN("xmloff.chart", "Exception caught. Type: " << OUString::createFromAscii( typeid( ex
).name()) << ", Message: " << ex
.Message
);
464 OUString
lcl_ConvertRange( const OUString
& rRange
, const Reference
< chart2::XChartDocument
> & xDoc
)
466 OUString aResult
= rRange
;
469 Reference
< chart2::data::XRangeXMLConversion
> xConversion(
470 xDoc
->getDataProvider(), uno::UNO_QUERY
);
471 if( xConversion
.is())
472 aResult
= xConversion
->convertRangeToXML( rRange
);
476 typedef ::std::pair
< OUString
, OUString
> tLabelAndValueRange
;
478 tLabelAndValueRange
lcl_getLabelAndValueRangeByRole(
479 const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aSeqCnt
,
480 const OUString
& rRole
,
481 const Reference
< chart2::XChartDocument
> & xDoc
,
482 SchXMLExportHelper_Impl::tDataSequenceCont
& rOutSequencesToExport
)
484 tLabelAndValueRange aResult
;
486 Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq(
487 lcl_getDataSequenceByRole( aSeqCnt
, rRole
));
488 if( xLabeledSeq
.is())
490 Reference
< chart2::data::XDataSequence
> xLabelSeq( xLabeledSeq
->getLabel());
492 aResult
.first
= lcl_ConvertRange( xLabelSeq
->getSourceRangeRepresentation(), xDoc
);
494 Reference
< chart2::data::XDataSequence
> xValueSeq( xLabeledSeq
->getValues());
496 aResult
.second
= lcl_ConvertRange( xValueSeq
->getSourceRangeRepresentation(), xDoc
);
498 if( xLabelSeq
.is() || xValueSeq
.is())
499 rOutSequencesToExport
.push_back( SchXMLExportHelper_Impl::tLabelValuesDataPair( xLabelSeq
, xValueSeq
));
505 sal_Int32
lcl_getSequenceLengthByRole(
506 const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aSeqCnt
,
507 const OUString
& rRole
)
509 Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq(
510 lcl_getDataSequenceByRole( aSeqCnt
, rRole
));
511 if( xLabeledSeq
.is())
513 Reference
< chart2::data::XDataSequence
> xSeq( xLabeledSeq
->getValues());
514 return xSeq
->getData().getLength();
519 OUString
lcl_flattenStringSequence( const Sequence
< OUString
> & rSequence
)
521 OUStringBuffer aResult
;
522 bool bPrecedeWithSpace
= false;
523 for( sal_Int32 nIndex
=0; nIndex
<rSequence
.getLength(); ++nIndex
)
525 if( !rSequence
[nIndex
].isEmpty())
527 if( bPrecedeWithSpace
)
528 aResult
.append( ' ' );
529 aResult
.append( rSequence
[nIndex
] );
530 bPrecedeWithSpace
= true;
533 return aResult
.makeStringAndClear();
536 void lcl_getLabelStringSequence( Sequence
< OUString
>& rOutLabels
, const Reference
< chart2::data::XDataSequence
> & xLabelSeq
)
538 uno::Reference
< chart2::data::XTextualDataSequence
> xTextualDataSequence( xLabelSeq
, uno::UNO_QUERY
);
539 if( xTextualDataSequence
.is())
541 rOutLabels
= xTextualDataSequence
->getTextualData();
543 else if( xLabelSeq
.is())
545 Sequence
< uno::Any
> aAnies( xLabelSeq
->getData());
546 rOutLabels
.realloc( aAnies
.getLength());
547 for( sal_Int32 i
=0; i
<aAnies
.getLength(); ++i
)
548 aAnies
[i
] >>= rOutLabels
[i
];
552 sal_Int32
lcl_getMaxSequenceLength(
553 const SchXMLExportHelper_Impl::tDataSequenceCont
& rContainer
)
555 sal_Int32 nResult
= 0;
556 for( SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator
aIt( rContainer
.begin());
557 aIt
!= rContainer
.end(); ++aIt
)
559 if( aIt
->second
.is())
561 sal_Int32 nSeqLength
= aIt
->second
->getData().getLength();
562 if( nSeqLength
> nResult
)
563 nResult
= nSeqLength
;
569 uno::Sequence
< OUString
> lcl_DataSequenceToStringSequence(
570 const uno::Reference
< chart2::data::XDataSequence
>& xDataSequence
)
572 uno::Sequence
< OUString
> aResult
;
573 if(!xDataSequence
.is())
576 uno::Reference
< chart2::data::XTextualDataSequence
> xTextualDataSequence( xDataSequence
, uno::UNO_QUERY
);
577 if( xTextualDataSequence
.is() )
579 aResult
= xTextualDataSequence
->getTextualData();
583 uno::Sequence
< uno::Any
> aValues
= xDataSequence
->getData();
584 aResult
.realloc(aValues
.getLength());
586 for(sal_Int32 nN
=aValues
.getLength();nN
--;)
587 aValues
[nN
] >>= aResult
[nN
];
592 ::std::vector
< double > lcl_getAllValuesFromSequence( const Reference
< chart2::data::XDataSequence
> & xSeq
)
595 ::rtl::math::setNan( &fNan
);
596 ::std::vector
< double > aResult
;
600 uno::Sequence
< double > aValuesSequence
;
601 Reference
< chart2::data::XNumericalDataSequence
> xNumSeq( xSeq
, uno::UNO_QUERY
);
604 aValuesSequence
= xNumSeq
->getNumericalData();
608 Sequence
< uno::Any
> aAnies( xSeq
->getData() );
609 aValuesSequence
.realloc( aAnies
.getLength() );
610 for( sal_Int32 i
=0; i
<aAnies
.getLength(); ++i
)
611 aAnies
[i
] >>= aValuesSequence
[i
];
614 //special handling for x-values (if x-values do point to categories, indices are used instead )
615 Reference
< beans::XPropertySet
> xProp( xSeq
, uno::UNO_QUERY
);
619 xProp
->getPropertyValue("Role") >>= aRole
;
620 if( aRole
.match("values-x") )
622 //lcl_clearIfNoValuesButTextIsContained - replace by indices if the values are not appropriate
623 bool bHasValue
=false;
625 sal_Int32 nCount
= aValuesSequence
.getLength();
626 for( sal_Int32 j
= 0; j
< nCount
; ++j
)
628 if( !::rtl::math::isNan( aValuesSequence
[j
] ) )
636 //no double value is contained
638 uno::Sequence
< OUString
> aStrings( lcl_DataSequenceToStringSequence( xSeq
) );
639 sal_Int32 nTextCount
= aStrings
.getLength();
640 for( sal_Int32 j
= 0; j
< nTextCount
; ++j
)
642 if( !aStrings
[j
].isEmpty() )
649 if( !bHasValue
&& bHasText
)
651 for( sal_Int32 j
= 0; j
< nCount
; ++j
)
652 aValuesSequence
[j
] = j
+1;
657 ::std::copy( aValuesSequence
.begin(), aValuesSequence
.end(),
658 ::std::back_inserter( aResult
));
662 bool lcl_SequenceHasUnhiddenData( const uno::Reference
< chart2::data::XDataSequence
>& xDataSequence
)
664 if( !xDataSequence
.is() )
666 uno::Reference
< beans::XPropertySet
> xProp( xDataSequence
, uno::UNO_QUERY
);
669 uno::Sequence
< sal_Int32
> aHiddenValues
;
672 xProp
->getPropertyValue("HiddenValues") >>= aHiddenValues
;
673 if( !aHiddenValues
.getLength() )
676 catch( const uno::Exception
& )
681 if( xDataSequence
->getData().getLength() )
686 typedef vector
< OUString
> tStringVector
;
687 typedef vector
< vector
< double > > t2DNumberContainer
;
691 t2DNumberContainer aDataInRows
;
692 tStringVector aDataRangeRepresentations
;
694 tStringVector aColumnDescriptions
;
695 tStringVector aColumnDescriptions_Ranges
;
697 tStringVector aRowDescriptions
;
698 tStringVector aRowDescriptions_Ranges
;
700 Sequence
< Sequence
< uno::Any
> > aComplexColumnDescriptions
;//outer index is columns - inner index is level
701 Sequence
< Sequence
< uno::Any
> > aComplexRowDescriptions
;//outer index is rows - inner index is level
703 ::std::vector
< sal_Int32
> aHiddenColumns
;
706 typedef ::std::map
< sal_Int32
, SchXMLExportHelper_Impl::tLabelValuesDataPair
>
709 struct lcl_SequenceToMapElement
:
710 public ::std::unary_function
< lcl_DataSequenceMap::mapped_type
, lcl_DataSequenceMap::value_type
>
712 lcl_SequenceToMapElement()
714 result_type
operator() ( const argument_type
& rContent
)
716 sal_Int32 nIndex
= -1;
717 if( rContent
.second
.is()) //has values
719 OUString
aRangeRep( rContent
.second
->getSourceRangeRepresentation());
720 nIndex
= aRangeRep
.toInt32();
722 else if( rContent
.first
.is()) //has labels
723 nIndex
= rContent
.first
->getSourceRangeRepresentation().copy( sizeof("label ")).toInt32();
724 return result_type( nIndex
, rContent
);
728 void lcl_ReorderInternalSequencesAccordingToTheirRangeName(
729 SchXMLExportHelper_Impl::tDataSequenceCont
& rInOutSequences
)
731 lcl_DataSequenceMap aIndexSequenceMap
;
732 ::std::transform( rInOutSequences
.begin(), rInOutSequences
.end(),
733 ::std::inserter( aIndexSequenceMap
, aIndexSequenceMap
.begin()),
734 lcl_SequenceToMapElement());
736 rInOutSequences
.clear();
737 sal_Int32 nIndex
= 0;
738 for( lcl_DataSequenceMap::const_iterator aIt
= aIndexSequenceMap
.begin();
739 aIt
!= aIndexSequenceMap
.end(); ++aIt
, ++nIndex
)
743 // fill empty columns
744 for( ; nIndex
< aIt
->first
; ++nIndex
)
745 rInOutSequences
.push_back(
746 SchXMLExportHelper_Impl::tDataSequenceCont::value_type(
747 uno::Reference
< chart2::data::XDataSequence
>(),
748 uno::Reference
< chart2::data::XDataSequence
>() ));
749 OSL_ASSERT( nIndex
== aIt
->first
);
750 rInOutSequences
.push_back( aIt
->second
);
754 lcl_TableData
lcl_getDataForLocalTable(
755 const SchXMLExportHelper_Impl::tDataSequenceCont
& aSequencesToExport
,
756 const Reference
< chart2::XAnyDescriptionAccess
>& xAnyDescriptionAccess
,
757 const OUString
& rCategoriesRange
,
758 bool bSeriesFromColumns
,
759 const Reference
< chart2::data::XRangeXMLConversion
> & xRangeConversion
)
761 lcl_TableData aResult
;
765 Sequence
< OUString
> aSimpleCategories
;
766 if( xAnyDescriptionAccess
.is() )
769 if( bSeriesFromColumns
)
771 aSimpleCategories
= xAnyDescriptionAccess
->getRowDescriptions();
772 aResult
.aComplexRowDescriptions
= xAnyDescriptionAccess
->getAnyRowDescriptions();
776 aSimpleCategories
= xAnyDescriptionAccess
->getColumnDescriptions();
777 aResult
.aComplexColumnDescriptions
= xAnyDescriptionAccess
->getAnyColumnDescriptions();
781 //series values and series labels
782 SchXMLExportHelper_Impl::tDataSequenceCont::size_type nNumSequences
= aSequencesToExport
.size();
783 SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator
aBegin( aSequencesToExport
.begin());
784 SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator
aEnd( aSequencesToExport
.end());
785 SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator
aIt( aBegin
);
787 auto nMaxSequenceLength( lcl_getMaxSequenceLength( aSequencesToExport
));
788 if( aSimpleCategories
.getLength() > nMaxSequenceLength
)
790 aSimpleCategories
.realloc(nMaxSequenceLength
);//#i110617#
792 size_t nNumColumns( bSeriesFromColumns
? nNumSequences
: nMaxSequenceLength
);
793 size_t nNumRows( bSeriesFromColumns
? nMaxSequenceLength
: nNumSequences
);
796 aResult
.aDataInRows
.resize( nNumRows
);
798 ::rtl::math::setNan( &fNan
);
800 for (auto& aData
: aResult
.aDataInRows
)
801 aData
.resize(nNumColumns
, fNan
);
802 aResult
.aColumnDescriptions
.resize( nNumColumns
);
803 aResult
.aComplexColumnDescriptions
.realloc( nNumColumns
);
804 aResult
.aRowDescriptions
.resize( nNumRows
);
805 aResult
.aComplexRowDescriptions
.realloc( nNumRows
);
807 tStringVector
& rCategories
= bSeriesFromColumns
? aResult
.aRowDescriptions
: aResult
.aColumnDescriptions
;
808 tStringVector
& rLabels
= bSeriesFromColumns
? aResult
.aColumnDescriptions
: aResult
.aRowDescriptions
;
811 lcl_SequenceToVector( aSimpleCategories
, rCategories
);
812 if( !rCategoriesRange
.isEmpty() )
814 OUString
aRange(rCategoriesRange
);
815 if( xRangeConversion
.is())
816 aRange
= xRangeConversion
->convertRangeToXML( aRange
);
817 if( bSeriesFromColumns
)
818 aResult
.aRowDescriptions_Ranges
.push_back( aRange
);
820 aResult
.aColumnDescriptions_Ranges
.push_back( aRange
);
823 // iterate over all sequences
825 Sequence
< Sequence
< OUString
> > aComplexLabels(nNumSequences
);
826 for( ; aIt
!= aEnd
; ++aIt
, ++nSeqIdx
)
829 Sequence
< OUString
>& rCurrentComplexLabel
= aComplexLabels
[nSeqIdx
];
832 lcl_getLabelStringSequence( rCurrentComplexLabel
, aIt
->first
);
833 rLabels
[nSeqIdx
] = lcl_flattenStringSequence( rCurrentComplexLabel
);
834 aRange
= aIt
->first
->getSourceRangeRepresentation();
835 if( xRangeConversion
.is())
836 aRange
= xRangeConversion
->convertRangeToXML( aRange
);
838 else if( aIt
->second
.is())
840 rCurrentComplexLabel
.realloc(1);
841 rLabels
[nSeqIdx
] = rCurrentComplexLabel
[0] = lcl_flattenStringSequence(
842 aIt
->second
->generateLabel( chart2::data::LabelOrigin_SHORT_SIDE
));
844 if( bSeriesFromColumns
)
845 aResult
.aColumnDescriptions_Ranges
.push_back( aRange
);
847 aResult
.aRowDescriptions_Ranges
.push_back( aRange
);
849 ::std::vector
< double > aNumbers( lcl_getAllValuesFromSequence( aIt
->second
));
850 if( bSeriesFromColumns
)
852 const sal_Int32
nSize( static_cast< sal_Int32
>( aNumbers
.size()));
853 for( sal_Int32 nIdx
=0; nIdx
<nSize
; ++nIdx
)
854 aResult
.aDataInRows
[nIdx
][nSeqIdx
] = aNumbers
[nIdx
];
857 aResult
.aDataInRows
[nSeqIdx
] = aNumbers
;
859 if( aIt
->second
.is())
861 aRange
= aIt
->second
->getSourceRangeRepresentation();
862 if( xRangeConversion
.is())
863 aRange
= xRangeConversion
->convertRangeToXML( aRange
);
865 aResult
.aDataRangeRepresentations
.push_back( aRange
);
868 if( !lcl_SequenceHasUnhiddenData(aIt
->first
) && !lcl_SequenceHasUnhiddenData(aIt
->second
) )
869 aResult
.aHiddenColumns
.push_back(nSeqIdx
);
871 Sequence
< Sequence
< Any
> >& rComplexAnyLabels
= bSeriesFromColumns
? aResult
.aComplexColumnDescriptions
: aResult
.aComplexRowDescriptions
;//#i116544#
872 rComplexAnyLabels
.realloc(aComplexLabels
.getLength());
873 for( sal_Int32 nN
=0; nN
<aComplexLabels
.getLength();nN
++ )
875 Sequence
< OUString
>& rSource
= aComplexLabels
[nN
];
876 Sequence
< Any
>& rTarget
= rComplexAnyLabels
[nN
];
877 rTarget
.realloc( rSource
.getLength() );
878 for( sal_Int32 i
=0; i
<rSource
.getLength(); i
++ )
879 rTarget
[i
] = uno::makeAny( rSource
[i
] );
882 catch( const uno::Exception
& rEx
)
884 SAL_INFO("xmloff.chart", "something went wrong during table data collection: " << rEx
.Message
);
890 void lcl_exportNumberFormat( const OUString
& rPropertyName
, const Reference
< beans::XPropertySet
>& xPropSet
,
891 SvXMLExport
& rExport
)
895 sal_Int32 nNumberFormat
= 0;
896 Any aNumAny
= xPropSet
->getPropertyValue( rPropertyName
);
897 if( (aNumAny
>>= nNumberFormat
) && (nNumberFormat
!= -1) )
898 rExport
.addDataStyle( nNumberFormat
);
902 ::std::vector
< Reference
< chart2::data::XDataSequence
> >
903 lcl_getErrorBarSequences( const Reference
< beans::XPropertySet
> & xErrorBarProp
)
905 ::std::vector
< Reference
< chart2::data::XDataSequence
> > aResult
;
906 Reference
< chart2::data::XDataSource
> xErrorBarDataSource( xErrorBarProp
, uno::UNO_QUERY
);
907 if( !xErrorBarDataSource
.is())
910 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSequences(
911 xErrorBarDataSource
->getDataSequences());
912 for( sal_Int32 nI
=0; nI
< aSequences
.getLength(); ++nI
)
916 if( aSequences
[nI
].is())
918 Reference
< chart2::data::XDataSequence
> xSequence( aSequences
[nI
]->getValues());
919 Reference
< beans::XPropertySet
> xSeqProp( xSequence
, uno::UNO_QUERY_THROW
);
921 if( ( xSeqProp
->getPropertyValue( "Role" ) >>= aRole
) &&
922 aRole
.match( "error-bars-" ))
924 aResult
.push_back( xSequence
);
928 catch( const uno::Exception
& rEx
)
930 OString
aBStr(OUStringToOString(rEx
.Message
, RTL_TEXTENCODING_ASCII_US
));
931 SAL_INFO("xmloff.chart", "chart:exporting error bar ranges: " << aBStr
);
938 bool lcl_exportDomainForThisSequence( const Reference
< chart2::data::XDataSequence
>& rValues
, OUString
& rFirstRangeForThisDomainIndex
, SvXMLExport
& rExport
)
940 bool bDomainExported
= false;
943 Reference
< chart2::XChartDocument
> xNewDoc( rExport
.GetModel(), uno::UNO_QUERY
);
944 OUString
aRange( lcl_ConvertRange( rValues
->getSourceRangeRepresentation(), xNewDoc
) );
946 //work around error in OOo 2.0 (problems with multiple series having a domain element)
947 if( rFirstRangeForThisDomainIndex
.isEmpty() || !aRange
.equals(rFirstRangeForThisDomainIndex
) )
949 rExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, aRange
);
950 SvXMLElementExport
aDomain( rExport
, XML_NAMESPACE_CHART
, XML_DOMAIN
, true, true );
951 bDomainExported
= true;
954 if( rFirstRangeForThisDomainIndex
.isEmpty() )
955 rFirstRangeForThisDomainIndex
= aRange
;
957 return bDomainExported
;
960 } // anonymous namespace
962 struct SchXMLDataPointStruct
964 OUString maStyleName
;
967 SchXMLDataPointStruct() : mnRepeat( 1 ) {}
970 // class SchXMLExportHelper
972 SchXMLExportHelper::SchXMLExportHelper( SvXMLExport
& rExport
, SvXMLAutoStylePoolP
& rASPool
)
973 : m_pImpl( new SchXMLExportHelper_Impl( rExport
, rASPool
) )
977 SchXMLExportHelper::~SchXMLExportHelper()
981 const OUString
& SchXMLExportHelper::getChartCLSID()
983 return m_pImpl
->msCLSID
;
986 void SchXMLExportHelper::SetSourceShellID( const OUString
& rShellID
)
988 m_pImpl
->maSrcShellID
= rShellID
;
991 void SchXMLExportHelper::SetDestinationShellID( const OUString
& rShellID
)
993 m_pImpl
->maDestShellID
= rShellID
;
996 const rtl::Reference
< XMLPropertySetMapper
>& SchXMLExportHelper_Impl::GetPropertySetMapper() const
998 return mxPropertySetMapper
;
1001 void SchXMLExportHelper_Impl::exportAutoStyles()
1003 if( mxExpPropMapper
.is())
1005 //ToDo: when embedded in calc/writer this is not necessary because the
1006 // numberformatter is shared between both documents
1007 mrExport
.exportAutoDataStyles();
1009 // export chart auto styles
1010 mrAutoStylePool
.exportXML(
1011 XML_STYLE_FAMILY_SCH_CHART_ID
1012 , mrExport
.GetDocHandler(),
1013 mrExport
.GetMM100UnitConverter(),
1014 mrExport
.GetNamespaceMap()
1017 // export auto styles for additional shapes
1018 mrExport
.GetShapeExport()->exportAutoStyles();
1019 // and for text in additional shapes
1020 mrExport
.GetTextParagraphExport()->exportTextAutoStyles();
1026 SchXMLExportHelper_Impl::SchXMLExportHelper_Impl(
1027 SvXMLExport
& rExport
,
1028 SvXMLAutoStylePoolP
& rASPool
) :
1029 mrExport( rExport
),
1030 mrAutoStylePool( rASPool
),
1031 mbHasSeriesLabels( false ),
1032 mbHasCategoryLabels( false ),
1033 mbRowSourceColumns( true ),
1034 msCLSID( OUString( SvGlobalName( SO3_SCH_CLASSID
).GetHexName()))
1036 msTableName
= "local-table";
1038 // create property set mapper
1039 mxPropertySetMapper
= new XMLChartPropertySetMapper( true);
1040 mxExpPropMapper
= new XMLChartExportPropertyMapper( mxPropertySetMapper
, rExport
);
1042 // register chart auto-style family
1043 mrAutoStylePool
.AddFamily(
1044 XML_STYLE_FAMILY_SCH_CHART_ID
,
1045 OUString( XML_STYLE_FAMILY_SCH_CHART_NAME
),
1046 mxExpPropMapper
.get(),
1047 OUString( XML_STYLE_FAMILY_SCH_CHART_PREFIX
));
1049 // register shape family
1050 mrAutoStylePool
.AddFamily(
1051 XML_STYLE_FAMILY_SD_GRAPHICS_ID
,
1052 OUString( XML_STYLE_FAMILY_SD_GRAPHICS_NAME
),
1053 mxExpPropMapper
.get(),
1054 OUString( XML_STYLE_FAMILY_SD_GRAPHICS_PREFIX
));
1055 // register paragraph family also for shapes
1056 mrAutoStylePool
.AddFamily(
1057 XML_STYLE_FAMILY_TEXT_PARAGRAPH
,
1058 GetXMLToken( XML_PARAGRAPH
),
1059 mxExpPropMapper
.get(),
1061 // register text family also for shapes
1062 mrAutoStylePool
.AddFamily(
1063 XML_STYLE_FAMILY_TEXT_TEXT
,
1064 GetXMLToken( XML_TEXT
),
1065 mxExpPropMapper
.get(),
1069 SchXMLExportHelper_Impl::~SchXMLExportHelper_Impl()
1073 void SchXMLExportHelper_Impl::collectAutoStyles( Reference
< chart::XChartDocument
> rChartDoc
)
1075 parseDocument( rChartDoc
, false );
1078 void SchXMLExportHelper_Impl::exportChart( Reference
< chart::XChartDocument
> rChartDoc
,
1079 bool bIncludeTable
)
1081 parseDocument( rChartDoc
, true, bIncludeTable
);
1082 SAL_WARN_IF( !maAutoStyleNameQueue
.empty(), "xmloff.chart", "There are still remaining autostyle names in the queue" );
1085 static OUString
lcl_GetStringFromNumberSequence( const css::uno::Sequence
< sal_Int32
>& rSequenceMapping
, bool bRemoveOneFromEachIndex
/*should be true if having categories*/ )
1087 const sal_Int32
* pArray
= rSequenceMapping
.getConstArray();
1088 const sal_Int32 nSize
= rSequenceMapping
.getLength();
1090 OUStringBuffer aBuf
;
1091 bool bHasPredecessor
= false;
1092 for( i
= 0; i
< nSize
; ++i
)
1094 sal_Int32 nIndex
= pArray
[ i
];
1095 if( bRemoveOneFromEachIndex
)
1101 aBuf
.append( nIndex
);
1102 bHasPredecessor
= true;
1105 return aBuf
.makeStringAndClear();
1108 /// if bExportContent is false the auto-styles are collected
1109 void SchXMLExportHelper_Impl::parseDocument( Reference
< chart::XChartDocument
>& rChartDoc
,
1110 bool bExportContent
,
1111 bool bIncludeTable
)
1113 Reference
< chart2::XChartDocument
> xNewDoc( rChartDoc
, uno::UNO_QUERY
);
1114 if( !rChartDoc
.is() || !xNewDoc
.is() )
1116 SAL_WARN("xmloff.chart", "No XChartDocument was given for export." );
1120 mxExpPropMapper
->setChartDoc(xNewDoc
);
1122 awt::Size
aPageSize( getPageSize( xNewDoc
));
1123 if( bExportContent
)
1124 addSize( aPageSize
);
1125 Reference
< chart::XDiagram
> xDiagram
= rChartDoc
->getDiagram();
1126 Reference
< chart2::XDiagram
> xNewDiagram
;
1128 xNewDiagram
.set( xNewDoc
->getFirstDiagram());
1130 //todo remove if model changes are notified and view is updated automatically
1131 if( bExportContent
)
1133 Reference
< util::XRefreshable
> xRefreshable( xNewDoc
, uno::UNO_QUERY
);
1134 if( xRefreshable
.is() )
1135 xRefreshable
->refresh();
1138 // get Properties of ChartDocument
1139 bool bHasMainTitle
= false;
1140 bool bHasSubTitle
= false;
1141 bool bHasLegend
= false;
1142 util::DateTime
aNullDate(0,0,0,0,30,12,1899, false);
1144 std::vector
< XMLPropertyState
> aPropertyStates
;
1146 Reference
< beans::XPropertySet
> xDocPropSet( rChartDoc
, uno::UNO_QUERY
);
1147 if( xDocPropSet
.is())
1151 Any aAny
= xDocPropSet
->getPropertyValue("HasMainTitle");
1152 aAny
>>= bHasMainTitle
;
1153 aAny
= xDocPropSet
->getPropertyValue("HasSubTitle");
1154 aAny
>>= bHasSubTitle
;
1155 aAny
= xDocPropSet
->getPropertyValue("HasLegend");
1156 aAny
>>= bHasLegend
;
1157 if ( bIncludeTable
)
1159 aAny
= xDocPropSet
->getPropertyValue("NullDate");
1160 if ( !aAny
.hasValue() )
1162 Reference
<container::XChild
> xChild(rChartDoc
, uno::UNO_QUERY
);
1165 Reference
< beans::XPropertySet
> xParentDoc( xChild
->getParent(),uno::UNO_QUERY
);
1166 if ( xParentDoc
.is() && xParentDoc
->getPropertySetInfo()->hasPropertyByName("NullDate") )
1167 aAny
= xParentDoc
->getPropertyValue("NullDate");
1174 catch( const beans::UnknownPropertyException
& )
1176 SAL_WARN("xmloff.chart", "Required property not found in ChartDocument" );
1180 if ( bIncludeTable
&& (aNullDate
.Day
!= 30 || aNullDate
.Month
!= 12 || aNullDate
.Year
!= 1899 ) )
1182 SvXMLElementExport
aSet( mrExport
, XML_NAMESPACE_TABLE
, XML_CALCULATION_SETTINGS
, true, true );
1184 OUStringBuffer sBuffer
;
1185 ::sax::Converter::convertDateTime(sBuffer
, aNullDate
, nullptr);
1186 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
,XML_DATE_VALUE
,sBuffer
.makeStringAndClear());
1187 SvXMLElementExport
aNull( mrExport
, XML_NAMESPACE_TABLE
, XML_NULL_DATE
, true, true );
1192 std::unique_ptr
<SvXMLElementExport
> xElChart
;
1194 // get property states for autostyles
1195 if( mxExpPropMapper
.is())
1197 Reference
< beans::XPropertySet
> xPropSet( rChartDoc
->getArea(), uno::UNO_QUERY
);
1199 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1202 if( bExportContent
)
1204 //export data provider in xlink:href attribute
1205 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
1206 if( nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
)
1208 OUString
aDataProviderURL( ".." );
1209 if( xNewDoc
->hasInternalDataProvider() )
1210 aDataProviderURL
= ".";
1211 else //special handling for data base data provider necessary
1213 Reference
< chart2::data::XDatabaseDataProvider
> xDBDataProvider( xNewDoc
->getDataProvider(), uno::UNO_QUERY
);
1214 if( xDBDataProvider
.is() )
1215 aDataProviderURL
= ".";
1217 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, aDataProviderURL
);
1218 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
1221 OUString
sChartType( xDiagram
->getDiagramType() );
1225 if( !sChartType
.isEmpty())
1227 enum XMLTokenEnum eXMLChartType
= SchXMLTools::getTokenByChartType( sChartType
, true /* bUseOldNames */ );
1229 SAL_WARN_IF( eXMLChartType
== XML_TOKEN_INVALID
, "xmloff.chart", "invalid chart class" );
1230 if( eXMLChartType
== XML_TOKEN_INVALID
)
1231 eXMLChartType
= XML_BAR
;
1233 if( eXMLChartType
== XML_ADD_IN
)
1235 // sChartType is the servie-name of the add-in
1236 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_CLASS
,
1237 mrExport
.GetNamespaceMap().GetQNameByKey(
1238 XML_NAMESPACE_OOO
, sChartType
) );
1240 else if( eXMLChartType
!= XML_TOKEN_INVALID
)
1242 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_CLASS
,
1243 mrExport
.GetNamespaceMap().GetQNameByKey(
1244 XML_NAMESPACE_CHART
, GetXMLToken(eXMLChartType
)) );
1247 //column-mapping or row-mapping
1248 if( maSequenceMapping
.getLength() )
1250 enum XMLTokenEnum eTransToken
= ::xmloff::token::XML_ROW_MAPPING
;
1251 if( mbRowSourceColumns
)
1252 eTransToken
= ::xmloff::token::XML_COLUMN_MAPPING
;
1253 OUString
aSequenceMappingStr( lcl_GetStringFromNumberSequence(
1254 maSequenceMapping
, mbHasCategoryLabels
&& !xNewDoc
->hasInternalDataProvider() ) );
1256 mrExport
.AddAttribute( XML_NAMESPACE_CHART
,
1257 ::xmloff::token::GetXMLToken( eTransToken
),
1258 aSequenceMappingStr
);
1262 AddAutoStyleAttribute( aPropertyStates
);
1265 xElChart
.reset(new SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_CHART
, true, true ));
1269 CollectAutoStyle( aPropertyStates
);
1271 // remove property states for autostyles
1272 aPropertyStates
.clear();
1277 // get property states for autostyles
1278 if( mxExpPropMapper
.is())
1280 Reference
< beans::XPropertySet
> xPropSet( rChartDoc
->getTitle(), uno::UNO_QUERY
);
1282 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1284 if( bExportContent
)
1286 Reference
< drawing::XShape
> xShape
= rChartDoc
->getTitle();
1287 if( xShape
.is()) // && "hasTitleBeenMoved"
1288 addPosition( xShape
);
1291 AddAutoStyleAttribute( aPropertyStates
);
1294 SvXMLElementExport
aElTitle( mrExport
, XML_NAMESPACE_CHART
, XML_TITLE
, true, true );
1297 Reference
< beans::XPropertySet
> xPropSet( xShape
, uno::UNO_QUERY
);
1300 Any
aAny( xPropSet
->getPropertyValue( "String" ));
1303 exportText( aText
);
1308 CollectAutoStyle( aPropertyStates
);
1310 // remove property states for autostyles
1311 aPropertyStates
.clear();
1317 // get property states for autostyles
1318 if( mxExpPropMapper
.is())
1320 Reference
< beans::XPropertySet
> xPropSet( rChartDoc
->getSubTitle(), uno::UNO_QUERY
);
1322 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1325 if( bExportContent
)
1327 Reference
< drawing::XShape
> xShape
= rChartDoc
->getSubTitle();
1329 addPosition( xShape
);
1332 AddAutoStyleAttribute( aPropertyStates
);
1334 // element (has no subelements)
1335 SvXMLElementExport
aElSubTitle( mrExport
, XML_NAMESPACE_CHART
, XML_SUBTITLE
, true, true );
1338 Reference
< beans::XPropertySet
> xPropSet( xShape
, uno::UNO_QUERY
);
1341 Any
aAny( xPropSet
->getPropertyValue( "String" ));
1344 exportText( aText
);
1349 CollectAutoStyle( aPropertyStates
);
1351 // remove property states for autostyles
1352 aPropertyStates
.clear();
1358 // get property states for autostyles
1359 if( mxExpPropMapper
.is())
1361 Reference
< beans::XPropertySet
> xPropSet( rChartDoc
->getLegend(), uno::UNO_QUERY
);
1363 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1366 if( bExportContent
)
1368 Reference
< beans::XPropertySet
> xProp( rChartDoc
->getLegend(), uno::UNO_QUERY
);
1371 // export legend anchor position
1374 Any
aAny( xProp
->getPropertyValue("Alignment"));
1375 if( SchXMLEnumConverter::getLegendPositionConverter().exportXML( msString
, aAny
, mrExport
.GetMM100UnitConverter() ) )
1376 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LEGEND_POSITION
, msString
);
1378 catch( const beans::UnknownPropertyException
& )
1380 SAL_WARN("xmloff.chart", "Property Align not found in ChartLegend" );
1383 // export absolute legend position
1384 Reference
< drawing::XShape
> xLegendShape( xProp
, uno::UNO_QUERY
);
1385 addPosition( xLegendShape
);
1387 // export legend size
1388 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
1389 if( xLegendShape
.is() && nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
)
1393 chart::ChartLegendExpansion nLegendExpansion
= chart::ChartLegendExpansion_HIGH
;
1394 OUString aExpansionString
;
1395 Any
aAny( xProp
->getPropertyValue("Expansion"));
1396 bool bHasExpansion
= (aAny
>>= nLegendExpansion
);
1397 if( bHasExpansion
&& SchXMLEnumConverter::getLegendExpansionConverter().exportXML( aExpansionString
, aAny
, mrExport
.GetMM100UnitConverter() ) )
1399 mrExport
.AddAttribute( XML_NAMESPACE_STYLE
, XML_LEGEND_EXPANSION
, aExpansionString
);
1400 if( nLegendExpansion
== chart::ChartLegendExpansion_CUSTOM
)
1402 awt::Size
aSize( xLegendShape
->getSize() );
1403 addSize( aSize
, true );
1404 OUStringBuffer aAspectRatioString
;
1405 ::sax::Converter::convertDouble(
1409 : double(aSize
.Width
)/double(aSize
.Height
)));
1410 mrExport
.AddAttribute( XML_NAMESPACE_STYLE
, XML_LEGEND_EXPANSION_ASPECT_RATIO
, aAspectRatioString
.makeStringAndClear() );
1414 catch( const beans::UnknownPropertyException
& )
1416 SAL_WARN("xmloff.chart", "Property Expansion not found in ChartLegend" );
1422 AddAutoStyleAttribute( aPropertyStates
);
1425 SvXMLElementExport
aLegend( mrExport
, XML_NAMESPACE_CHART
, XML_LEGEND
, true, true );
1429 CollectAutoStyle( aPropertyStates
);
1431 // remove property states for autostyles
1432 aPropertyStates
.clear();
1435 // plot-area element
1437 exportPlotArea( xDiagram
, xNewDiagram
, aPageSize
, bExportContent
, bIncludeTable
);
1439 // export additional shapes
1440 if( xDocPropSet
.is() )
1442 if( bExportContent
)
1444 if( mxAdditionalShapes
.is())
1446 // can't call exportShapes with all shapes because the
1447 // initialisation happened with the complete draw page and not
1448 // the XShapes object used here. Thus the shapes have to be
1449 // exported one by one
1450 rtl::Reference
< XMLShapeExport
> rShapeExport
= mrExport
.GetShapeExport();
1451 Reference
< drawing::XShape
> xShape
;
1452 const sal_Int32
nShapeCount( mxAdditionalShapes
->getCount());
1453 for( sal_Int32 nShapeId
= 0; nShapeId
< nShapeCount
; nShapeId
++ )
1455 mxAdditionalShapes
->getByIndex( nShapeId
) >>= xShape
;
1456 SAL_WARN_IF( !xShape
.is(), "xmloff.chart", "Shape without an XShape?" );
1460 rShapeExport
->exportShape( xShape
);
1462 // this would be the easier way if it worked:
1463 //mrExport.GetShapeExport()->exportShapes( mxAdditionalShapes );
1468 // get a sequence of non-chart shapes (inserted via clipboard)
1471 Any aShapesAny
= xDocPropSet
->getPropertyValue("AdditionalShapes");
1472 aShapesAny
>>= mxAdditionalShapes
;
1474 catch( const uno::Exception
& rEx
)
1476 SAL_INFO("xmloff.chart", "AdditionalShapes not found: " << rEx
.Message
);
1479 if( mxAdditionalShapes
.is())
1481 // seek shapes has to be called for the whole page because in
1482 // the shape export the vector of shapes is accessed via the
1483 // ZOrder which might be (actually is) larger than the number of
1484 // shapes in mxAdditionalShapes
1485 Reference
< drawing::XDrawPageSupplier
> xSupplier( rChartDoc
, uno::UNO_QUERY
);
1486 SAL_WARN_IF( !xSupplier
.is(), "xmloff.chart", "Cannot retrieve draw page to initialize shape export" );
1487 if( xSupplier
.is() )
1489 Reference
< drawing::XShapes
> xDrawPage( xSupplier
->getDrawPage(), uno::UNO_QUERY
);
1490 SAL_WARN_IF( !xDrawPage
.is(), "xmloff.chart", "Invalid draw page for initializing shape export" );
1492 mrExport
.GetShapeExport()->seekShapes( xDrawPage
);
1495 // can't call collectShapesAutoStyles with all shapes because
1496 // the initialisation happened with the complete draw page and
1497 // not the XShapes object used here. Thus the shapes have to be
1498 // exported one by one
1499 rtl::Reference
< XMLShapeExport
> rShapeExport
= mrExport
.GetShapeExport();
1500 Reference
< drawing::XShape
> xShape
;
1501 const sal_Int32
nShapeCount( mxAdditionalShapes
->getCount());
1502 for( sal_Int32 nShapeId
= 0; nShapeId
< nShapeCount
; nShapeId
++ )
1504 mxAdditionalShapes
->getByIndex( nShapeId
) >>= xShape
;
1505 SAL_WARN_IF( !xShape
.is(), "xmloff.chart", "Shape without an XShape?" );
1509 rShapeExport
->collectShapeAutoStyles( xShape
);
1516 // (is included as subelement of chart)
1517 if( bExportContent
)
1519 // #85929# always export table, otherwise clipboard may lose data
1524 static void lcl_exportComplexLabel( const Sequence
< uno::Any
>& rComplexLabel
, SvXMLExport
& rExport
)
1526 sal_Int32 nLength
= rComplexLabel
.getLength();
1529 SvXMLElementExport
aTextList( rExport
, XML_NAMESPACE_TEXT
, XML_LIST
, true, true );
1530 for(sal_Int32 nN
=0; nN
<nLength
; nN
++)
1532 SvXMLElementExport
aListItem( rExport
, XML_NAMESPACE_TEXT
, XML_LIST_ITEM
, true, true );
1534 if( !(rComplexLabel
[nN
]>>=aString
) )
1538 SchXMLTools::exportText( rExport
, aString
, false /*bConvertTabsLFs*/ );
1542 void SchXMLExportHelper_Impl::exportTable()
1545 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_NAME
, msTableName
);
1549 bool bProtected
= false;
1550 Reference
< beans::XPropertySet
> xProps( mrExport
.GetModel(), uno::UNO_QUERY_THROW
);
1551 if ( ( xProps
->getPropertyValue("DisableDataTableDialog") >>= bProtected
) &&
1554 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_PROTECTED
, XML_TRUE
);
1557 catch ( const uno::Exception
& )
1561 SvXMLElementExport
aTable( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE
, true, true );
1563 bool bHasOwnData
= false;
1564 Reference
< chart2::XChartDocument
> xNewDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
1565 Reference
< chart2::data::XRangeXMLConversion
> xRangeConversion
;
1568 bHasOwnData
= xNewDoc
->hasInternalDataProvider();
1569 xRangeConversion
.set( xNewDoc
->getDataProvider(), uno::UNO_QUERY
);
1572 Reference
< chart2::XAnyDescriptionAccess
> xAnyDescriptionAccess
;
1574 Reference
< chart::XChartDocument
> xChartDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
1575 if( xChartDoc
.is() )
1576 xAnyDescriptionAccess
.set( xChartDoc
->getData(), uno::UNO_QUERY
);
1580 lcl_ReorderInternalSequencesAccordingToTheirRangeName( m_aDataSequencesToExport
);
1581 lcl_TableData
aData( lcl_getDataForLocalTable( m_aDataSequencesToExport
1582 , xAnyDescriptionAccess
, maCategoriesRange
1583 , mbRowSourceColumns
, xRangeConversion
));
1585 tStringVector::const_iterator
aDataRangeIter( aData
.aDataRangeRepresentations
.begin());
1586 const tStringVector::const_iterator
aDataRangeEndIter( aData
.aDataRangeRepresentations
.end());
1588 tStringVector::const_iterator
aRowDescriptions_RangeIter( aData
.aRowDescriptions_Ranges
.begin());
1589 const tStringVector::const_iterator
aRowDescriptions_RangeEnd( aData
.aRowDescriptions_Ranges
.end());
1593 SvXMLElementExport
aHeaderColumns( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_COLUMNS
, true, true );
1594 SvXMLElementExport
aHeaderColumn( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, true, true );
1597 SvXMLElementExport
aColumns( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMNS
, true, true );
1599 sal_Int32 nNextIndex
= 0;
1600 for(sal_Int32 nHiddenIndex
: aData
.aHiddenColumns
)
1602 //i91578 display of hidden values (copy paste scenario; export hidden flag thus it can be used during migration to locale table upon paste )
1603 if( nHiddenIndex
> nNextIndex
)
1605 sal_Int64 nRepeat
= static_cast< sal_Int64
>( nHiddenIndex
- nNextIndex
);
1607 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
,
1608 OUString::number( nRepeat
));
1609 SvXMLElementExport
aColumn( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, true, true );
1611 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_VISIBILITY
, GetXMLToken( XML_COLLAPSE
) );
1612 SvXMLElementExport
aColumn( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, true, true );
1613 nNextIndex
= nHiddenIndex
+1;
1616 sal_Int32 nEndIndex
= aData
.aColumnDescriptions
.size()-1;
1617 if( nEndIndex
>= nNextIndex
)
1619 sal_Int64 nRepeat
= static_cast< sal_Int64
>( nEndIndex
- nNextIndex
+ 1 );
1621 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
,
1622 OUString::number( nRepeat
));
1623 SvXMLElementExport
aColumn( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, true, true );
1627 // export rows with content
1630 SvXMLElementExport
aHeaderRows( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_ROWS
, true, true );
1631 SvXMLElementExport
aRow( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, true, true );
1633 //first one empty cell for the row descriptions
1635 SvXMLElementExport
aEmptyCell( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true );
1636 SvXMLElementExport
aEmptyParagraph( mrExport
, XML_NAMESPACE_TEXT
, XML_P
, true, true );
1639 //export column descriptions
1640 tStringVector::const_iterator
aColumnDescriptions_RangeIter( aData
.aColumnDescriptions_Ranges
.begin());
1641 const tStringVector::const_iterator
aColumnDescriptions_RangeEnd( aData
.aColumnDescriptions_Ranges
.end());
1642 const Sequence
< Sequence
< uno::Any
> >& rComplexColumnDescriptions
= aData
.aComplexColumnDescriptions
;
1643 sal_Int32 nComplexCount
= rComplexColumnDescriptions
.getLength();
1645 for( tStringVector::const_iterator
aIt( aData
.aColumnDescriptions
.begin())
1646 ; (aIt
!= aData
.aColumnDescriptions
.end())
1649 bool bExportString
= true;
1650 if( nC
< nComplexCount
)
1652 const Sequence
< uno::Any
>& rComplexLabel
= rComplexColumnDescriptions
[nC
];
1653 if( rComplexLabel
.getLength()>0 )
1656 if( rComplexLabel
[0] >>=fValue
)
1658 bExportString
= false;
1660 ::sax::Converter::convertDouble(
1661 msStringBuffer
, fValue
);
1662 msString
= msStringBuffer
.makeStringAndClear();
1663 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
1664 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE
, msString
);
1670 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_STRING
);
1673 SvXMLElementExport
aCell( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true );
1675 if( nC
< nComplexCount
)
1676 lcl_exportComplexLabel( rComplexColumnDescriptions
[nC
], mrExport
);
1677 if( !bHasOwnData
&& aColumnDescriptions_RangeIter
!= aColumnDescriptions_RangeEnd
)
1679 // remind the original range to allow a correct re-association when copying via clipboard
1680 if (!(*aColumnDescriptions_RangeIter
).isEmpty())
1681 SchXMLTools::exportRangeToSomewhere( mrExport
, *aColumnDescriptions_RangeIter
);
1682 ++aColumnDescriptions_RangeIter
;
1685 SAL_WARN_IF( !bHasOwnData
&& (aColumnDescriptions_RangeIter
!= aColumnDescriptions_RangeEnd
), "xmloff.chart", "bHasOwnData == false && aColumnDescriptions_RangeIter != aColumnDescriptions_RangeEnd" );
1686 } // closing row and header-rows elements
1688 // export value rows
1690 SvXMLElementExport
aRows( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_ROWS
, true, true );
1691 tStringVector::const_iterator
aRowDescriptionsIter( aData
.aRowDescriptions
.begin());
1692 const Sequence
< Sequence
< uno::Any
> >& rComplexRowDescriptions
= aData
.aComplexRowDescriptions
;
1693 sal_Int32 nComplexCount
= rComplexRowDescriptions
.getLength();
1696 for( t2DNumberContainer::const_iterator
aRowIt( aData
.aDataInRows
.begin())
1697 ; aRowIt
!= aData
.aDataInRows
.end()
1700 SvXMLElementExport
aRow( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, true, true );
1702 //export row descriptions
1704 bool bExportString
= true;
1705 if( nC
< nComplexCount
)
1707 const Sequence
< uno::Any
>& rComplexLabel
= rComplexRowDescriptions
[nC
];
1708 if( rComplexLabel
.getLength()>0 )
1711 if( rComplexLabel
[0] >>=fValue
)
1713 bExportString
= false;
1715 ::sax::Converter::convertDouble(msStringBuffer
, fValue
);
1716 msString
= msStringBuffer
.makeStringAndClear();
1717 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
1718 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE
, msString
);
1724 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_STRING
);
1727 SvXMLElementExport
aCell( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true );
1728 if( aRowDescriptionsIter
!= aData
.aRowDescriptions
.end())
1730 exportText( *aRowDescriptionsIter
);
1731 if( nC
< nComplexCount
)
1732 lcl_exportComplexLabel( rComplexRowDescriptions
[nC
], mrExport
);
1733 if( !bHasOwnData
&& aRowDescriptions_RangeIter
!= aRowDescriptions_RangeEnd
)
1735 // remind the original range to allow a correct re-association when copying via clipboard
1736 SchXMLTools::exportRangeToSomewhere( mrExport
, *aRowDescriptions_RangeIter
);
1737 ++aRowDescriptions_RangeIter
;
1739 ++aRowDescriptionsIter
;
1744 for( t2DNumberContainer::value_type::const_iterator
aColIt( aRowIt
->begin());
1745 aColIt
!= aRowIt
->end(); ++aColIt
)
1747 ::sax::Converter::convertDouble( msStringBuffer
, *aColIt
);
1748 msString
= msStringBuffer
.makeStringAndClear();
1749 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
1750 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE
, msString
);
1751 SvXMLElementExport
aCell( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true );
1752 exportText( msString
); // do not convert tabs and lfs
1753 if( ( !bHasOwnData
&& aDataRangeIter
!= aDataRangeEndIter
) &&
1754 ( mbRowSourceColumns
|| (aColIt
== aRowIt
->begin()) ) )
1756 // remind the original range to allow a correct re-association when copying via clipboard
1757 if (!(*aDataRangeIter
).isEmpty())
1758 SchXMLTools::exportRangeToSomewhere( mrExport
, *aDataRangeIter
);
1765 // if range iterator was used it should have reached its end
1766 SAL_WARN_IF( !bHasOwnData
&& (aDataRangeIter
!= aDataRangeEndIter
), "xmloff.chart", "bHasOwnData == false && aDataRangeIter != aDataRangeEndIter" );
1767 SAL_WARN_IF( !bHasOwnData
&& (aRowDescriptions_RangeIter
!= aRowDescriptions_RangeEnd
), "xmloff.chart", "bHasOwnData == false && aRowDescriptions_RangeIter != aRowDescriptions_RangeEnd" );
1773 Reference
< chart2::XCoordinateSystem
> lcl_getCooSys( const Reference
< chart2::XDiagram
> & xNewDiagram
)
1775 Reference
< chart2::XCoordinateSystem
> xCooSys
;
1776 Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt( xNewDiagram
, uno::UNO_QUERY
);
1779 Sequence
< Reference
< chart2::XCoordinateSystem
> > aCooSysSeq( xCooSysCnt
->getCoordinateSystems() );
1780 if(aCooSysSeq
.getLength()>0)
1781 xCooSys
= aCooSysSeq
[0];
1786 Reference
< chart2::XAxis
> lcl_getAxis( const Reference
< chart2::XCoordinateSystem
>& xCooSys
,
1787 enum XMLTokenEnum eDimension
, bool bPrimary
=true )
1789 Reference
< chart2::XAxis
> xNewAxis
;
1794 sal_Int32 nDimensionIndex
=0;
1795 switch( eDimension
)
1810 xNewAxis
= xCooSys
->getAxisByDimension( nDimensionIndex
, bPrimary
? 0 : 1 );
1813 catch( const uno::Exception
& )
1821 void SchXMLExportHelper_Impl::exportPlotArea(
1822 const Reference
< chart::XDiagram
>& xDiagram
,
1823 const Reference
< chart2::XDiagram
>& xNewDiagram
,
1824 const awt::Size
& rPageSize
,
1825 bool bExportContent
,
1826 bool bIncludeTable
)
1828 SAL_WARN_IF( !xDiagram
.is(), "xmloff.chart", "Invalid XDiagram as parameter" );
1829 if( ! xDiagram
.is())
1832 // variables for autostyles
1833 Reference
< beans::XPropertySet
> xPropSet
;
1834 std::vector
< XMLPropertyState
> aPropertyStates
;
1836 msStringBuffer
.setLength( 0 );
1838 // plot-area element
1840 std::unique_ptr
<SvXMLElementExport
> xElPlotArea
;
1841 // get property states for autostyles
1842 xPropSet
.set( xDiagram
, uno::UNO_QUERY
);
1845 if( mxExpPropMapper
.is())
1846 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1848 if( bExportContent
)
1850 rtl::Reference
< XMLShapeExport
> rShapeExport
;
1853 AddAutoStyleAttribute( aPropertyStates
);
1855 if( !msChartAddress
.isEmpty() )
1857 if( !bIncludeTable
)
1858 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, msChartAddress
);
1860 Reference
< chart::XChartDocument
> xDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
1863 Reference
< beans::XPropertySet
> xDocProp( xDoc
, uno::UNO_QUERY
);
1870 bool bFirstCol
= false, bFirstRow
= false;
1872 aAny
= xDocProp
->getPropertyValue( "DataSourceLabelsInFirstColumn" );
1874 aAny
= xDocProp
->getPropertyValue( "DataSourceLabelsInFirstRow" );
1877 if( bFirstCol
|| bFirstRow
)
1879 mrExport
.AddAttribute( XML_NAMESPACE_CHART
,
1880 ::xmloff::token::GetXMLToken( ::xmloff::token::XML_DATA_SOURCE_HAS_LABELS
),
1883 ? ::xmloff::token::GetXMLToken( ::xmloff::token::XML_BOTH
)
1884 : ::xmloff::token::GetXMLToken( ::xmloff::token::XML_COLUMN
))
1885 : ::xmloff::token::GetXMLToken( ::xmloff::token::XML_ROW
)));
1888 catch( const beans::UnknownPropertyException
& )
1890 SAL_WARN("xmloff.chart", "Properties missing" );
1897 Reference
< drawing::XShape
> xShape ( xDiagram
, uno::UNO_QUERY
);
1900 addPosition( xShape
);
1904 bool bIs3DChart
= false;
1913 aAny
= xPropSet
->getPropertyValue("Dim3D");
1914 aAny
>>= bIs3DChart
;
1918 rShapeExport
= mrExport
.GetShapeExport();
1919 if( rShapeExport
.is())
1920 rShapeExport
->export3DSceneAttributes( xPropSet
);
1923 catch( const uno::Exception
& rEx
)
1925 OString
aBStr(OUStringToOString(rEx
.Message
, RTL_TEXTENCODING_ASCII_US
));
1926 SAL_INFO("xmloff.chart", "chart:exportPlotAreaException caught: " << aBStr
);
1930 // plot-area element
1931 xElPlotArea
.reset(new SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_PLOT_AREA
, true, true ));
1933 //inner position rectangle element
1934 exportCoordinateRegion( xDiagram
);
1936 // light sources (inside plot area element)
1939 rShapeExport
->export3DLamps( xPropSet
);
1943 CollectAutoStyle( aPropertyStates
);
1945 // remove property states for autostyles
1946 aPropertyStates
.clear();
1949 exportAxes( xDiagram
, xNewDiagram
, bExportContent
);
1952 Reference
< chart2::XAxis
> xSecondYAxis
= lcl_getAxis( lcl_getCooSys( xNewDiagram
), XML_Y
, false );
1953 exportSeries( xNewDiagram
, rPageSize
, bExportContent
, xSecondYAxis
.is() );
1955 // stock-chart elements
1956 OUString
sChartType ( xDiagram
->getDiagramType());
1957 if( sChartType
== "com.sun.star.chart.StockDiagram" )
1959 Reference
< chart::XStatisticDisplay
> xStockPropProvider( xDiagram
, uno::UNO_QUERY
);
1960 if( xStockPropProvider
.is())
1962 // stock-gain-marker
1963 Reference
< beans::XPropertySet
> xStockPropSet
= xStockPropProvider
->getUpBar();
1964 if( xStockPropSet
.is())
1966 aPropertyStates
.clear();
1967 aPropertyStates
= mxExpPropMapper
->Filter( xStockPropSet
);
1969 if( !aPropertyStates
.empty() )
1971 if( bExportContent
)
1973 AddAutoStyleAttribute( aPropertyStates
);
1975 SvXMLElementExport
aGain( mrExport
, XML_NAMESPACE_CHART
, XML_STOCK_GAIN_MARKER
, true, true );
1979 CollectAutoStyle( aPropertyStates
);
1984 // stock-loss-marker
1985 xStockPropSet
= xStockPropProvider
->getDownBar();
1986 if( xStockPropSet
.is())
1988 aPropertyStates
.clear();
1989 aPropertyStates
= mxExpPropMapper
->Filter( xStockPropSet
);
1991 if( !aPropertyStates
.empty() )
1993 if( bExportContent
)
1995 AddAutoStyleAttribute( aPropertyStates
);
1997 SvXMLElementExport
aGain( mrExport
, XML_NAMESPACE_CHART
, XML_STOCK_LOSS_MARKER
, true, true );
2001 CollectAutoStyle( aPropertyStates
);
2007 xStockPropSet
= xStockPropProvider
->getMinMaxLine();
2008 if( xStockPropSet
.is())
2010 aPropertyStates
.clear();
2011 aPropertyStates
= mxExpPropMapper
->Filter( xStockPropSet
);
2013 if( !aPropertyStates
.empty() )
2015 if( bExportContent
)
2017 AddAutoStyleAttribute( aPropertyStates
);
2019 SvXMLElementExport
aGain( mrExport
, XML_NAMESPACE_CHART
, XML_STOCK_RANGE_LINE
, true, true );
2023 CollectAutoStyle( aPropertyStates
);
2030 // wall and floor element
2031 Reference
< chart::X3DDisplay
> xWallFloorSupplier( xDiagram
, uno::UNO_QUERY
);
2032 if( mxExpPropMapper
.is() &&
2033 xWallFloorSupplier
.is())
2035 // remove property states for autostyles
2036 aPropertyStates
.clear();
2038 Reference
< beans::XPropertySet
> xWallPropSet( xWallFloorSupplier
->getWall(), uno::UNO_QUERY
);
2039 if( xWallPropSet
.is())
2041 aPropertyStates
= mxExpPropMapper
->Filter( xWallPropSet
);
2043 if( !aPropertyStates
.empty() )
2046 if( bExportContent
)
2048 // add style name attribute
2049 AddAutoStyleAttribute( aPropertyStates
);
2051 SvXMLElementExport
aWall( mrExport
, XML_NAMESPACE_CHART
, XML_WALL
, true, true );
2055 CollectAutoStyle( aPropertyStates
);
2061 // remove property states for autostyles
2062 aPropertyStates
.clear();
2064 Reference
< beans::XPropertySet
> xFloorPropSet( xWallFloorSupplier
->getFloor(), uno::UNO_QUERY
);
2065 if( xFloorPropSet
.is())
2067 aPropertyStates
= mxExpPropMapper
->Filter( xFloorPropSet
);
2069 if( !aPropertyStates
.empty() )
2072 if( bExportContent
)
2074 // add style name attribute
2075 AddAutoStyleAttribute( aPropertyStates
);
2077 SvXMLElementExport
aFloor( mrExport
, XML_NAMESPACE_CHART
, XML_FLOOR
, true, true );
2081 CollectAutoStyle( aPropertyStates
);
2088 void SchXMLExportHelper_Impl::exportCoordinateRegion( const uno::Reference
< chart::XDiagram
>& xDiagram
)
2090 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2091 if( nCurrentODFVersion
<= SvtSaveOptions::ODFVER_012
)//do not export to ODF 1.2 or older
2094 Reference
< chart::XDiagramPositioning
> xDiaPos( xDiagram
, uno::UNO_QUERY
);
2095 SAL_WARN_IF( !xDiaPos
.is(), "xmloff.chart", "Invalid xDiaPos as parameter" );
2099 awt::Rectangle
aRect( xDiaPos
->calculateDiagramPositionExcludingAxes() );
2100 addPosition( awt::Point(aRect
.X
,aRect
.Y
) );
2101 addSize( awt::Size(aRect
.Width
,aRect
.Height
) );
2103 SvXMLElementExport
aCoordinateRegion( mrExport
, XML_NAMESPACE_CHART_EXT
, XML_COORDINATE_REGION
, true, true );//#i100778# todo: change to chart namespace in future - dependent on fileformat
2108 XMLTokenEnum
lcl_getTimeUnitToken( sal_Int32 nTimeUnit
)
2110 XMLTokenEnum eToken
= XML_DAYS
;
2113 case css::chart::TimeUnit::YEAR
:
2116 case css::chart::TimeUnit::MONTH
:
2117 eToken
= XML_MONTHS
;
2126 void SchXMLExportHelper_Impl::exportDateScale( const Reference
< beans::XPropertySet
>& rAxisProps
)
2128 if( !rAxisProps
.is() )
2131 chart::TimeIncrement aIncrement
;
2132 if( (rAxisProps
->getPropertyValue("TimeIncrement") >>= aIncrement
) )
2134 sal_Int32 nTimeResolution
= css::chart::TimeUnit::DAY
;
2135 if( aIncrement
.TimeResolution
>>= nTimeResolution
)
2136 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_BASE_TIME_UNIT
, lcl_getTimeUnitToken( nTimeResolution
) );
2138 OUStringBuffer aValue
;
2139 chart::TimeInterval aInterval
;
2140 if( aIncrement
.MajorTimeInterval
>>= aInterval
)
2142 ::sax::Converter::convertNumber( aValue
, aInterval
.Number
);
2143 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_MAJOR_INTERVAL_VALUE
, aValue
.makeStringAndClear() );
2144 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_MAJOR_INTERVAL_UNIT
, lcl_getTimeUnitToken( aInterval
.TimeUnit
) );
2146 if( aIncrement
.MinorTimeInterval
>>= aInterval
)
2148 ::sax::Converter::convertNumber( aValue
, aInterval
.Number
);
2149 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_MINOR_INTERVAL_VALUE
, aValue
.makeStringAndClear() );
2150 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_MINOR_INTERVAL_UNIT
, lcl_getTimeUnitToken( aInterval
.TimeUnit
) );
2153 SvXMLElementExport
aDateScale( mrExport
, XML_NAMESPACE_CHART_EXT
, XML_DATE_SCALE
, true, true );//#i25706#todo: change namespace for next ODF version
2157 void SchXMLExportHelper_Impl::exportAxisTitle( const Reference
< beans::XPropertySet
>& rTitleProps
, bool bExportContent
)
2159 if( !rTitleProps
.is() )
2161 std::vector
< XMLPropertyState
> aPropertyStates
= mxExpPropMapper
->Filter( rTitleProps
);
2162 if( bExportContent
)
2165 Any
aAny( rTitleProps
->getPropertyValue( "String" ));
2168 Reference
< drawing::XShape
> xShape( rTitleProps
, uno::UNO_QUERY
);
2170 addPosition( xShape
);
2172 AddAutoStyleAttribute( aPropertyStates
);
2173 SvXMLElementExport
aTitle( mrExport
, XML_NAMESPACE_CHART
, XML_TITLE
, true, true );
2175 // paragraph containing title
2176 exportText( aText
);
2180 CollectAutoStyle( aPropertyStates
);
2182 aPropertyStates
.clear();
2185 void SchXMLExportHelper_Impl::exportGrid( const Reference
< beans::XPropertySet
>& rGridProperties
, bool bMajor
, bool bExportContent
)
2187 if( !rGridProperties
.is() )
2189 std::vector
< XMLPropertyState
> aPropertyStates
= mxExpPropMapper
->Filter( rGridProperties
);
2190 if( bExportContent
)
2192 AddAutoStyleAttribute( aPropertyStates
);
2193 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_CLASS
, bMajor
? XML_MAJOR
: XML_MINOR
);
2194 SvXMLElementExport
aGrid( mrExport
, XML_NAMESPACE_CHART
, XML_GRID
, true, true );
2198 CollectAutoStyle( aPropertyStates
);
2200 aPropertyStates
.clear();
2206 //returns true if a date scale needs to be exported
2207 bool lcl_exportAxisType( const Reference
< chart2::XAxis
>& rChart2Axis
, SvXMLExport
& rExport
)
2209 bool bExportDateScale
= false;
2210 if( !rChart2Axis
.is() )
2211 return bExportDateScale
;
2213 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2214 if( nCurrentODFVersion
<= SvtSaveOptions::ODFVER_012
)//do not export to ODF 1.2 or older
2215 return bExportDateScale
;
2217 chart2::ScaleData
aScale( rChart2Axis
->getScaleData() );
2218 //#i25706#todo: change namespace for next ODF version
2219 sal_uInt16 nNameSpace
= XML_NAMESPACE_CHART_EXT
;
2221 switch(aScale
.AxisType
)
2223 case chart2::AxisType::CATEGORY
:
2224 if( aScale
.AutoDateAxis
)
2226 rExport
.AddAttribute( nNameSpace
, XML_AXIS_TYPE
, XML_AUTO
);
2227 bExportDateScale
= true;
2230 rExport
.AddAttribute( nNameSpace
, XML_AXIS_TYPE
, XML_TEXT
);
2232 case chart2::AxisType::DATE
:
2233 rExport
.AddAttribute( nNameSpace
, XML_AXIS_TYPE
, XML_DATE
);
2234 bExportDateScale
= true;
2236 default: //AUTOMATIC
2237 rExport
.AddAttribute( nNameSpace
, XML_AXIS_TYPE
, XML_AUTO
);
2241 return bExportDateScale
;
2244 void disableLinkedNumberFormat(
2245 std::vector
<XMLPropertyState
>& rPropStates
, const rtl::Reference
<XMLPropertySetMapper
>& rMapper
)
2247 for (XMLPropertyState
& rState
: rPropStates
)
2249 if (rState
.mnIndex
< 0 || rMapper
->GetEntryCount() <= rState
.mnIndex
)
2252 OUString aXMLName
= rMapper
->GetEntryXMLName(rState
.mnIndex
);
2254 if (aXMLName
!= "link-data-style-to-source")
2257 // Entry found. Set the value to false and bail out.
2258 rState
.maValue
<<= false;
2262 // Entry not found. Insert a new entry for this.
2263 sal_Int32 nIndex
= rMapper
->GetEntryIndex(XML_NAMESPACE_CHART
, "link-data-style-to-source", 0);
2264 XMLPropertyState
aState(nIndex
);
2265 aState
.maValue
<<= false;
2266 rPropStates
.push_back(aState
);
2271 void SchXMLExportHelper_Impl::exportAxis(
2272 enum XMLTokenEnum eDimension
,
2273 enum XMLTokenEnum eAxisName
,
2274 const Reference
< beans::XPropertySet
>& rAxisProps
,
2275 const Reference
< chart2::XAxis
>& rChart2Axis
,
2276 const OUString
& rCategoriesRange
,
2277 bool bHasTitle
, bool bHasMajorGrid
, bool bHasMinorGrid
,
2278 bool bExportContent
)
2280 std::vector
< XMLPropertyState
> aPropertyStates
;
2281 SvXMLElementExport
* pAxis
= nullptr;
2283 // get property states for autostyles
2284 if( rAxisProps
.is() && mxExpPropMapper
.is() )
2286 lcl_exportNumberFormat( "NumberFormat", rAxisProps
, mrExport
);
2287 aPropertyStates
= mxExpPropMapper
->Filter( rAxisProps
);
2289 if (!maSrcShellID
.isEmpty() && !maDestShellID
.isEmpty() && maSrcShellID
!= maDestShellID
)
2291 // Disable link to source number format property when pasting to
2292 // a different doc shell. These shell ID's should be both empty
2293 // during real ODF export.
2294 disableLinkedNumberFormat(aPropertyStates
, mxExpPropMapper
->getPropertySetMapper());
2298 bool bExportDateScale
= false;
2299 if( bExportContent
)
2301 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_DIMENSION
, eDimension
);
2302 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_NAME
, eAxisName
);
2303 AddAutoStyleAttribute( aPropertyStates
); // write style name
2304 if( !rCategoriesRange
.isEmpty() )
2305 bExportDateScale
= lcl_exportAxisType( rChart2Axis
, mrExport
);
2307 // open axis element
2308 pAxis
= new SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_AXIS
, true, true );
2312 CollectAutoStyle( aPropertyStates
);
2314 aPropertyStates
.clear();
2317 if( bExportDateScale
)
2318 exportDateScale( rAxisProps
);
2320 Reference
< beans::XPropertySet
> xTitleProps
;
2321 Reference
< beans::XPropertySet
> xMajorGridProps
;
2322 Reference
< beans::XPropertySet
> xMinorGridProps
;
2323 Reference
< chart::XAxis
> xAxis( rAxisProps
, uno::UNO_QUERY
);
2326 xTitleProps
= bHasTitle
? xAxis
->getAxisTitle() : nullptr;
2327 xMajorGridProps
= bHasMajorGrid
? xAxis
->getMajorGrid() : nullptr;
2328 xMinorGridProps
= bHasMinorGrid
? xAxis
->getMinorGrid() : nullptr;
2332 exportAxisTitle( xTitleProps
, bExportContent
);
2334 // categories if we have a categories chart
2335 if( bExportContent
&& !rCategoriesRange
.isEmpty() )
2337 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, rCategoriesRange
);
2338 SvXMLElementExport
aCategories( mrExport
, XML_NAMESPACE_CHART
, XML_CATEGORIES
, true, true );
2342 exportGrid( xMajorGridProps
, true, bExportContent
);
2343 exportGrid( xMinorGridProps
, false, bExportContent
);
2347 //close axis element
2353 void SchXMLExportHelper_Impl::exportAxes(
2354 const Reference
< chart::XDiagram
> & xDiagram
,
2355 const Reference
< chart2::XDiagram
> & xNewDiagram
,
2356 bool bExportContent
)
2358 SAL_WARN_IF( !xDiagram
.is(), "xmloff.chart", "Invalid XDiagram as parameter" );
2359 if( ! xDiagram
.is())
2362 // get some properties from document first
2363 bool bHasXAxis
= false,
2366 bHasSecondaryXAxis
= false,
2367 bHasSecondaryYAxis
= false;
2368 bool bHasXAxisTitle
= false,
2369 bHasYAxisTitle
= false,
2370 bHasZAxisTitle
= false,
2371 bHasSecondaryXAxisTitle
= false,
2372 bHasSecondaryYAxisTitle
= false;
2373 bool bHasXAxisMajorGrid
= false,
2374 bHasXAxisMinorGrid
= false,
2375 bHasYAxisMajorGrid
= false,
2376 bHasYAxisMinorGrid
= false,
2377 bHasZAxisMajorGrid
= false,
2378 bHasZAxisMinorGrid
= false;
2380 // get multiple properties using XMultiPropertySet
2381 MultiPropertySetHandler
aDiagramProperties (xDiagram
);
2383 aDiagramProperties
.Add ("HasXAxis", bHasXAxis
);
2384 aDiagramProperties
.Add ("HasYAxis", bHasYAxis
);
2385 aDiagramProperties
.Add ("HasZAxis", bHasZAxis
);
2386 aDiagramProperties
.Add ("HasSecondaryXAxis", bHasSecondaryXAxis
);
2387 aDiagramProperties
.Add ("HasSecondaryYAxis", bHasSecondaryYAxis
);
2389 aDiagramProperties
.Add ("HasXAxisTitle", bHasXAxisTitle
);
2390 aDiagramProperties
.Add ("HasYAxisTitle", bHasYAxisTitle
);
2391 aDiagramProperties
.Add ("HasZAxisTitle", bHasZAxisTitle
);
2392 aDiagramProperties
.Add ("HasSecondaryXAxisTitle", bHasSecondaryXAxisTitle
);
2393 aDiagramProperties
.Add ("HasSecondaryYAxisTitle", bHasSecondaryYAxisTitle
);
2395 aDiagramProperties
.Add ("HasXAxisGrid", bHasXAxisMajorGrid
);
2396 aDiagramProperties
.Add ("HasYAxisGrid", bHasYAxisMajorGrid
);
2397 aDiagramProperties
.Add ("HasZAxisGrid", bHasZAxisMajorGrid
);
2399 aDiagramProperties
.Add ("HasXAxisHelpGrid", bHasXAxisMinorGrid
);
2400 aDiagramProperties
.Add ("HasYAxisHelpGrid", bHasYAxisMinorGrid
);
2401 aDiagramProperties
.Add ("HasZAxisHelpGrid", bHasZAxisMinorGrid
);
2403 if ( ! aDiagramProperties
.GetProperties ())
2405 SAL_INFO("xmloff.chart", "Required properties not found in Chart diagram");
2408 Reference
< chart2::XCoordinateSystem
> xCooSys( lcl_getCooSys(xNewDiagram
) );
2410 // write an axis element also if the axis itself is not visible, but a grid or a title
2412 OUString aCategoriesRange
;
2413 Reference
< chart::XAxisSupplier
> xAxisSupp( xDiagram
, uno::UNO_QUERY
);
2417 Reference
< css::chart2::XAxis
> xNewAxis
= lcl_getAxis( xCooSys
, XML_X
);
2420 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getAxis(0) : nullptr, uno::UNO_QUERY
);
2421 if( mbHasCategoryLabels
&& bExportContent
)
2423 Reference
< chart2::data::XLabeledDataSequence
> xCategories( lcl_getCategories( xNewDiagram
) );
2424 if( xCategories
.is() )
2426 Reference
< chart2::data::XDataSequence
> xValues( xCategories
->getValues() );
2429 Reference
< chart2::XChartDocument
> xNewDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
2430 maCategoriesRange
= xValues
->getSourceRangeRepresentation();
2431 aCategoriesRange
= lcl_ConvertRange( maCategoriesRange
, xNewDoc
);
2435 exportAxis( XML_X
, XML_PRIMARY_X
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasXAxisTitle
, bHasXAxisMajorGrid
, bHasXAxisMinorGrid
, bExportContent
);
2436 aCategoriesRange
.clear();
2441 Reference
< chart::XSecondAxisTitleSupplier
> xSecondTitleSupp( xDiagram
, uno::UNO_QUERY
);
2442 xNewAxis
= lcl_getAxis( xCooSys
, XML_X
, false );
2445 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getSecondaryAxis(0) : nullptr, uno::UNO_QUERY
);
2446 exportAxis( XML_X
, XML_SECONDARY_X
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasSecondaryXAxisTitle
, false, false, bExportContent
);
2451 xNewAxis
= lcl_getAxis( xCooSys
, XML_Y
);
2454 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getAxis(1) : nullptr, uno::UNO_QUERY
);
2455 exportAxis( XML_Y
, XML_PRIMARY_Y
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasYAxisTitle
, bHasYAxisMajorGrid
, bHasYAxisMinorGrid
, bExportContent
);
2460 xNewAxis
= lcl_getAxis( xCooSys
, XML_Y
, false );
2463 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getSecondaryAxis(1) : nullptr, uno::UNO_QUERY
);
2464 exportAxis( XML_Y
, XML_SECONDARY_Y
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasSecondaryYAxisTitle
, false, false, bExportContent
);
2469 xNewAxis
= lcl_getAxis( xCooSys
, XML_Z
);
2472 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getAxis(2) : nullptr, uno::UNO_QUERY
);
2473 exportAxis( XML_Z
, XML_PRIMARY_Z
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasZAxisTitle
, bHasZAxisMajorGrid
, bHasZAxisMinorGrid
, bExportContent
);
2479 bool lcl_hasNoValuesButText( const uno::Reference
< chart2::data::XDataSequence
>& xDataSequence
)
2481 if( !xDataSequence
.is() )
2482 return false;//have no data
2484 Sequence
< uno::Any
> aData
;
2485 Reference
< chart2::data::XNumericalDataSequence
> xNumericalDataSequence( xDataSequence
, uno::UNO_QUERY
);
2486 if( xNumericalDataSequence
.is() )
2488 Sequence
< double > aDoubles( xNumericalDataSequence
->getNumericalData() );
2489 sal_Int32 nCount
= aDoubles
.getLength();
2490 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
2492 if( !::rtl::math::isNan( aDoubles
[i
] ) )
2493 return false;//have double value
2498 aData
= xDataSequence
->getData();
2499 double fDouble
= 0.0;
2500 sal_Int32 nCount
= aData
.getLength();
2501 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
2503 if( (aData
[i
] >>= fDouble
) && !::rtl::math::isNan( fDouble
) )
2504 return false;//have double value
2510 Reference
< chart2::data::XTextualDataSequence
> xTextualDataSequence( xDataSequence
, uno::UNO_QUERY
);
2511 if( xTextualDataSequence
.is() )
2513 uno::Sequence
< OUString
> aStrings( xTextualDataSequence
->getTextualData() );
2514 sal_Int32 nCount
= aStrings
.getLength();
2515 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
2517 if( !aStrings
[i
].isEmpty() )
2518 return true;//have text
2523 if( !aData
.getLength() )
2524 aData
= xDataSequence
->getData();
2526 sal_Int32 nCount
= aData
.getLength();
2527 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
2529 if( (aData
[i
]>>=aString
) && !aString
.isEmpty() )
2530 return true;//have text
2533 //no doubles and no texts
2538 void SchXMLExportHelper_Impl::exportSeries(
2539 const Reference
< chart2::XDiagram
> & xNewDiagram
,
2540 const awt::Size
& rPageSize
,
2541 bool bExportContent
,
2544 Reference
< chart2::XCoordinateSystemContainer
> xBCooSysCnt( xNewDiagram
, uno::UNO_QUERY
);
2545 if( ! xBCooSysCnt
.is())
2547 Reference
< chart2::XChartDocument
> xNewDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
2549 OUString aFirstXDomainRange
;
2550 OUString aFirstYDomainRange
;
2552 std::vector
< XMLPropertyState
> aPropertyStates
;
2554 Sequence
< Reference
< chart2::XCoordinateSystem
> >
2555 aCooSysSeq( xBCooSysCnt
->getCoordinateSystems());
2556 for( sal_Int32 nCSIdx
=0; nCSIdx
<aCooSysSeq
.getLength(); ++nCSIdx
)
2558 Reference
< chart2::XChartTypeContainer
> xCTCnt( aCooSysSeq
[nCSIdx
], uno::UNO_QUERY
);
2561 Sequence
< Reference
< chart2::XChartType
> > aCTSeq( xCTCnt
->getChartTypes());
2562 for( sal_Int32 nCTIdx
=0; nCTIdx
<aCTSeq
.getLength(); ++nCTIdx
)
2564 Reference
< chart2::XDataSeriesContainer
> xDSCnt( aCTSeq
[nCTIdx
], uno::UNO_QUERY
);
2567 // note: if xDSCnt.is() then also aCTSeq[nCTIdx]
2568 OUString
aChartType( aCTSeq
[nCTIdx
]->getChartType());
2569 OUString aLabelRole
= aCTSeq
[nCTIdx
]->getRoleOfSequenceForSeriesLabel();
2571 // special export for stock charts
2572 if ( aChartType
== "com.sun.star.chart2.CandleStickChartType" )
2574 bool bJapaneseCandleSticks
= false;
2575 Reference
< beans::XPropertySet
> xCTProp( aCTSeq
[nCTIdx
], uno::UNO_QUERY
);
2577 xCTProp
->getPropertyValue("Japanese") >>= bJapaneseCandleSticks
;
2578 exportCandleStickSeries(
2579 xDSCnt
->getDataSeries(), xNewDiagram
, bJapaneseCandleSticks
, bExportContent
);
2583 // export dataseries for current chart-type
2584 Sequence
< Reference
< chart2::XDataSeries
> > aSeriesSeq( xDSCnt
->getDataSeries());
2585 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<aSeriesSeq
.getLength(); ++nSeriesIdx
)
2588 Reference
< chart2::data::XDataSource
> xSource( aSeriesSeq
[nSeriesIdx
], uno::UNO_QUERY
);
2591 SvXMLElementExport
* pSeries
= nullptr;
2592 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeqCnt(
2593 xSource
->getDataSequences());
2594 sal_Int32 nMainSequenceIndex
= -1;
2595 sal_Int32 nSeriesLength
= 0;
2596 sal_Int32 nAttachedAxis
= chart::ChartAxisAssign::PRIMARY_Y
;
2597 bool bHasMeanValueLine
= false;
2598 Reference
< beans::XPropertySet
> xPropSet
;
2599 tLabelValuesDataPair aSeriesLabelValuesPair
;
2601 // search for main sequence and create a series element
2603 Reference
< chart2::data::XDataSequence
> xValuesSeq
;
2604 Reference
< chart2::data::XDataSequence
> xLabelSeq
;
2605 sal_Int32 nSeqIdx
=0;
2606 for( ; nSeqIdx
<aSeqCnt
.getLength(); ++nSeqIdx
)
2609 Reference
< chart2::data::XDataSequence
> xTempValueSeq( aSeqCnt
[nSeqIdx
]->getValues() );
2610 if( nMainSequenceIndex
==-1 )
2612 Reference
< beans::XPropertySet
> xSeqProp( xTempValueSeq
, uno::UNO_QUERY
);
2614 xSeqProp
->getPropertyValue("Role") >>= aRole
;
2616 if( aRole
.equals( aLabelRole
))
2618 xValuesSeq
.set( xTempValueSeq
);
2619 xLabelSeq
.set( aSeqCnt
[nSeqIdx
]->getLabel());
2620 nMainSequenceIndex
= nSeqIdx
;
2623 sal_Int32 nSequenceLength
= (xTempValueSeq
.is()? xTempValueSeq
->getData().getLength() : sal_Int32(0));
2624 if( nSeriesLength
< nSequenceLength
)
2625 nSeriesLength
= nSequenceLength
;
2628 // have found the main sequence, then xValuesSeq and
2629 // xLabelSeq contain those. Otherwise both are empty
2631 // get property states for autostyles
2634 xPropSet
= SchXMLSeriesHelper::createOldAPISeriesPropertySet(
2635 aSeriesSeq
[nSeriesIdx
], mrExport
.GetModel() );
2637 catch( const uno::Exception
& rEx
)
2639 SAL_INFO("xmloff.chart", "Series not found or no XPropertySet: " << rEx
.Message
);
2644 // determine attached axis
2647 Any
aAny( xPropSet
->getPropertyValue( "Axis" ));
2648 aAny
>>= nAttachedAxis
;
2650 aAny
= xPropSet
->getPropertyValue( "MeanValue" );
2651 aAny
>>= bHasMeanValueLine
;
2653 catch( const beans::UnknownPropertyException
& rEx
)
2655 SAL_INFO("xmloff.chart", "Required property not found in DataRowProperties: " << rEx
.Message
);
2658 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2659 if( nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
)
2661 lcl_exportNumberFormat( "NumberFormat", xPropSet
, mrExport
);
2662 lcl_exportNumberFormat( "PercentageNumberFormat", xPropSet
, mrExport
);
2665 if( mxExpPropMapper
.is())
2666 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
2669 if( bExportContent
)
2673 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
2674 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
2676 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
2680 AddAutoStyleAttribute( aPropertyStates
);
2682 if( xValuesSeq
.is())
2683 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
,
2685 xValuesSeq
->getSourceRangeRepresentation(),
2688 // #i75297# allow empty series, export empty range to have all ranges on import
2689 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, OUString());
2693 // Check if the label is direct string value rather than a reference.
2694 bool bHasString
= false;
2695 uno::Reference
<beans::XPropertySet
> xLSProp(xLabelSeq
, uno::UNO_QUERY
);
2700 xLSProp
->getPropertyValue("HasStringLabel") >>= bHasString
;
2702 catch (const beans::UnknownPropertyException
&) {}
2705 OUString aRange
= xLabelSeq
->getSourceRangeRepresentation();
2709 mrExport
.AddAttribute(
2710 XML_NAMESPACE_LO_EXT
, XML_LABEL_STRING
, aRange
);
2714 mrExport
.AddAttribute(
2715 XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
,
2717 xLabelSeq
->getSourceRangeRepresentation(), xNewDoc
));
2721 if( xLabelSeq
.is() || xValuesSeq
.is() )
2722 aSeriesLabelValuesPair
= tLabelValuesDataPair( xLabelSeq
, xValuesSeq
);
2724 // chart-type for mixed types
2725 enum XMLTokenEnum
eCTToken(
2726 SchXMLTools::getTokenByChartType( aChartType
, false /* bUseOldNames */ ));
2727 //@todo: get token for current charttype
2728 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_CLASS
,
2729 mrExport
.GetNamespaceMap().GetQNameByKey(
2730 XML_NAMESPACE_CHART
, GetXMLToken( eCTToken
)));
2732 // open series element until end of for loop
2733 pSeries
= new SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, true, true );
2737 CollectAutoStyle( aPropertyStates
);
2739 // remove property states for autostyles
2740 aPropertyStates
.clear();
2744 // export domain elements if we have a series parent element
2748 if( bExportContent
)
2750 bool bIsScatterChart
= aChartType
== "com.sun.star.chart2.ScatterChartType";
2751 bool bIsBubbleChart
= aChartType
== "com.sun.star.chart2.BubbleChartType";
2752 Reference
< chart2::data::XDataSequence
> xYValuesForBubbleChart
;
2753 if( bIsBubbleChart
)
2755 Reference
< chart2::data::XLabeledDataSequence
> xSequence( lcl_getDataSequenceByRole( aSeqCnt
, "values-y" ) );
2756 if( xSequence
.is() )
2758 xYValuesForBubbleChart
= xSequence
->getValues();
2759 if( !lcl_exportDomainForThisSequence( xYValuesForBubbleChart
, aFirstYDomainRange
, mrExport
) )
2760 xYValuesForBubbleChart
= nullptr;
2763 if( bIsScatterChart
|| bIsBubbleChart
)
2765 Reference
< chart2::data::XLabeledDataSequence
> xSequence( lcl_getDataSequenceByRole( aSeqCnt
, "values-x" ) );
2766 if( xSequence
.is() )
2768 Reference
< chart2::data::XDataSequence
> xValues( xSequence
->getValues() );
2769 if( lcl_exportDomainForThisSequence( xValues
, aFirstXDomainRange
, mrExport
) )
2770 m_aDataSequencesToExport
.push_back( tLabelValuesDataPair(
2771 uno::Reference
< chart2::data::XDataSequence
>(), xValues
));
2773 else if( nSeriesIdx
==0 )
2775 //might be that the categories are used as x-values (e.g. for date axis) -> export them accordingly
2776 Reference
< chart2::data::XLabeledDataSequence
> xCategories( lcl_getCategories( xNewDiagram
) );
2777 if( xCategories
.is() )
2779 Reference
< chart2::data::XDataSequence
> xValues( xCategories
->getValues() );
2780 if( !lcl_hasNoValuesButText( xValues
) )
2781 lcl_exportDomainForThisSequence( xValues
, aFirstXDomainRange
, mrExport
);
2785 if( xYValuesForBubbleChart
.is() )
2786 m_aDataSequencesToExport
.push_back( tLabelValuesDataPair(
2787 uno::Reference
< chart2::data::XDataSequence
>(), xYValuesForBubbleChart
));
2791 // add sequences for main sequence after domain sequences,
2792 // so that the export of the local table has the correct order
2793 if( bExportContent
&&
2794 (aSeriesLabelValuesPair
.first
.is() || aSeriesLabelValuesPair
.second
.is()))
2795 m_aDataSequencesToExport
.push_back( aSeriesLabelValuesPair
);
2797 // statistical objects:
2798 // regression curves and mean value lines
2799 if( bHasMeanValueLine
&&
2801 mxExpPropMapper
.is() )
2803 Reference
< beans::XPropertySet
> xStatProp
;
2806 Any
aPropAny( xPropSet
->getPropertyValue( "DataMeanValueProperties" ));
2807 aPropAny
>>= xStatProp
;
2809 catch( const uno::Exception
& rEx
)
2811 SAL_INFO("xmloff.chart", "Exception caught during Export of series - optional DataMeanValueProperties not available: " << rEx
.Message
);
2814 if( xStatProp
.is() )
2816 aPropertyStates
= mxExpPropMapper
->Filter( xStatProp
);
2818 if( !aPropertyStates
.empty() )
2821 if( bExportContent
)
2823 // add style name attribute
2824 AddAutoStyleAttribute( aPropertyStates
);
2826 SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_MEAN_VALUE
, true, true );
2830 CollectAutoStyle( aPropertyStates
);
2836 if( xPropSet
.is() &&
2837 mxExpPropMapper
.is() )
2839 exportRegressionCurve( aSeriesSeq
[nSeriesIdx
], rPageSize
, bExportContent
);
2842 exportErrorBar( xPropSet
,false, bExportContent
); // X ErrorBar
2843 exportErrorBar( xPropSet
,true, bExportContent
); // Y ErrorBar
2846 uno::Reference
< beans::XPropertySet
>( aSeriesSeq
[nSeriesIdx
], uno::UNO_QUERY
),
2847 nSeriesLength
, xNewDiagram
, bExportContent
);
2849 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2850 if( bExportContent
&& nCurrentODFVersion
> SvtSaveOptions::ODFVER_012
)//do not export to ODF 1.2 or older
2852 Sequence
< OUString
> aSupportedMappings
= aCTSeq
[nCTIdx
]->getSupportedPropertyRoles();
2853 exportPropertyMapping( xSource
, aSupportedMappings
);
2856 // close series element
2860 aPropertyStates
.clear();
2865 void SchXMLExportHelper_Impl::exportPropertyMapping(
2866 const Reference
< chart2::data::XDataSource
> & xSource
, Sequence
< OUString
>& rSupportedMappings
)
2868 Reference
< chart2::XChartDocument
> xNewDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
2869 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeqCnt(
2870 xSource
->getDataSequences());
2872 for(sal_Int32 i
= 0, n
= rSupportedMappings
.getLength(); i
< n
; ++i
)
2874 Reference
< chart2::data::XLabeledDataSequence
> xSequence( lcl_getDataSequenceByRole( aSeqCnt
, rSupportedMappings
[i
] ) );
2877 Reference
< chart2::data::XDataSequence
> xValues( xSequence
->getValues() );
2880 mrExport
.AddAttribute( XML_NAMESPACE_LO_EXT
, XML_PROPERTY
, rSupportedMappings
[i
]);
2881 mrExport
.AddAttribute( XML_NAMESPACE_LO_EXT
, XML_CELL_RANGE_ADDRESS
,
2883 xValues
->getSourceRangeRepresentation(),
2885 SvXMLElementExport( mrExport
, XML_NAMESPACE_LO_EXT
, XML_PROPERTY_MAPPING
, true, true );
2887 // register range for data table export
2888 m_aDataSequencesToExport
.push_back( tLabelValuesDataPair(
2889 uno::Reference
< chart2::data::XDataSequence
>(), xValues
));
2895 void SchXMLExportHelper_Impl::exportRegressionCurve(
2896 const Reference
< chart2::XDataSeries
>& xSeries
,
2897 const awt::Size
& rPageSize
,
2898 bool bExportContent
)
2900 OSL_ASSERT( mxExpPropMapper
.is());
2902 std::vector
< XMLPropertyState
> aPropertyStates
;
2903 std::vector
< XMLPropertyState
> aEquationPropertyStates
;
2905 Reference
< chart2::XRegressionCurveContainer
> xRegressionCurveContainer( xSeries
, uno::UNO_QUERY
);
2906 if( xRegressionCurveContainer
.is() )
2908 Sequence
< Reference
< chart2::XRegressionCurve
> > aRegCurveSeq
= xRegressionCurveContainer
->getRegressionCurves();
2910 const Reference
< chart2::XRegressionCurve
>* pBeg
= aRegCurveSeq
.getConstArray();
2911 const Reference
< chart2::XRegressionCurve
>* pEnd
= pBeg
+ aRegCurveSeq
.getLength();
2912 const Reference
< chart2::XRegressionCurve
>* pIt
;
2914 for( pIt
= pBeg
; pIt
!= pEnd
; pIt
++ )
2916 Reference
< chart2::XRegressionCurve
> xRegCurve
= *pIt
;
2917 if (!xRegCurve
.is())
2920 Reference
< beans::XPropertySet
> xProperties( xRegCurve
, uno::UNO_QUERY
);
2921 if( !xProperties
.is() )
2924 Reference
< lang::XServiceName
> xServiceName( xProperties
, uno::UNO_QUERY
);
2925 if( !xServiceName
.is() )
2928 bool bShowEquation
= false;
2929 bool bShowRSquared
= false;
2930 bool bExportEquation
= false;
2933 aService
= xServiceName
->getServiceName();
2935 aPropertyStates
= mxExpPropMapper
->Filter( xProperties
);
2937 // Add service name (which is regression type)
2938 sal_Int32 nIndex
= GetPropertySetMapper()->FindEntryIndex(XML_SCH_CONTEXT_SPECIAL_REGRESSION_TYPE
);
2939 XMLPropertyState
property(nIndex
, uno::makeAny(aService
));
2940 aPropertyStates
.push_back(property
);
2942 Reference
< beans::XPropertySet
> xEquationProperties
;
2943 xEquationProperties
.set( xRegCurve
->getEquationProperties() );
2944 if( xEquationProperties
.is())
2946 xEquationProperties
->getPropertyValue( "ShowEquation") >>= bShowEquation
;
2947 xEquationProperties
->getPropertyValue( "ShowCorrelationCoefficient") >>= bShowRSquared
;
2949 bExportEquation
= ( bShowEquation
|| bShowRSquared
);
2950 const SvtSaveOptions::ODFDefaultVersion
nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
2951 if( nCurrentVersion
< SvtSaveOptions::ODFVER_012
)
2953 bExportEquation
=false;
2955 if( bExportEquation
)
2958 sal_Int32 nNumberFormat
= 0;
2959 if( (xEquationProperties
->getPropertyValue("NumberFormat") >>= nNumberFormat
) &&
2960 nNumberFormat
!= -1 )
2962 mrExport
.addDataStyle( nNumberFormat
);
2964 aEquationPropertyStates
= mxExpPropMapper
->Filter( xEquationProperties
);
2968 if( !aPropertyStates
.empty() || bExportEquation
)
2971 if( bExportContent
)
2973 // add style name attribute
2974 if( !aPropertyStates
.empty())
2976 AddAutoStyleAttribute( aPropertyStates
);
2979 SvXMLElementExport
aRegressionExport( mrExport
, XML_NAMESPACE_CHART
, XML_REGRESSION_CURVE
, true, true );
2980 if( bExportEquation
)
2982 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_DISPLAY_EQUATION
, (bShowEquation
? XML_TRUE
: XML_FALSE
) );
2983 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_DISPLAY_R_SQUARE
, (bShowRSquared
? XML_TRUE
: XML_FALSE
) );
2986 chart2::RelativePosition aRelativePosition
;
2987 if( xEquationProperties
->getPropertyValue( "RelativePosition" ) >>= aRelativePosition
)
2989 double fX
= aRelativePosition
.Primary
* rPageSize
.Width
;
2990 double fY
= aRelativePosition
.Secondary
* rPageSize
.Height
;
2992 aPos
.X
= static_cast< sal_Int32
>( ::rtl::math::round( fX
));
2993 aPos
.Y
= static_cast< sal_Int32
>( ::rtl::math::round( fY
));
2994 addPosition( aPos
);
2997 if( !aEquationPropertyStates
.empty())
2999 AddAutoStyleAttribute( aEquationPropertyStates
);
3002 SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_EQUATION
, true, true );
3007 if( !aPropertyStates
.empty())
3009 CollectAutoStyle( aPropertyStates
);
3011 if( bExportEquation
&& !aEquationPropertyStates
.empty())
3013 CollectAutoStyle( aEquationPropertyStates
);
3021 void SchXMLExportHelper_Impl::exportErrorBar( const Reference
<beans::XPropertySet
> &xSeriesProp
,
3022 bool bYError
, bool bExportContent
)
3024 assert(mxExpPropMapper
.is());
3026 const SvtSaveOptions::ODFDefaultVersion
nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
3028 /// Don't export X ErrorBars for older ODF versions.
3029 if ( !bYError
&& nCurrentVersion
< SvtSaveOptions::ODFVER_012
)
3032 if (xSeriesProp
.is())
3034 bool bNegative
= false, bPositive
= false;
3035 sal_Int32 nErrorBarStyle
= chart::ErrorBarStyle::NONE
;
3036 Reference
< beans::XPropertySet
> xErrorBarProp
;
3042 aAny
= xSeriesProp
->getPropertyValue( bYError
? OUString("ErrorBarY") : OUString("ErrorBarX") );
3043 aAny
>>= xErrorBarProp
;
3045 if ( xErrorBarProp
.is() )
3047 aAny
= xErrorBarProp
->getPropertyValue("ShowNegativeError" );
3050 aAny
= xErrorBarProp
->getPropertyValue("ShowPositiveError" );
3053 aAny
= xErrorBarProp
->getPropertyValue("ErrorBarStyle" );
3054 aAny
>>= nErrorBarStyle
;
3057 catch( const beans::UnknownPropertyException
& rEx
)
3059 SAL_INFO("xmloff.chart", "Required property not found in DataRowProperties: " << rEx
.Message
);
3062 if( nErrorBarStyle
!= chart::ErrorBarStyle::NONE
&& (bNegative
|| bPositive
))
3064 if( bExportContent
&& nErrorBarStyle
== chart::ErrorBarStyle::FROM_DATA
)
3066 uno::Reference
< chart2::XChartDocument
> xNewDoc(mrExport
.GetModel(), uno::UNO_QUERY
);
3068 // register data ranges for error bars for export in local table
3069 ::std::vector
< Reference
< chart2::data::XDataSequence
> > aErrorBarSequences(
3070 lcl_getErrorBarSequences( xErrorBarProp
));
3071 for( ::std::vector
< Reference
< chart2::data::XDataSequence
> >::const_iterator
aIt(
3072 aErrorBarSequences
.begin()); aIt
!= aErrorBarSequences
.end(); ++aIt
)
3074 m_aDataSequencesToExport
.push_back( tLabelValuesDataPair(
3075 uno::Reference
< chart2::data::XDataSequence
>(), *aIt
));
3079 std::vector
< XMLPropertyState
> aPropertyStates
= mxExpPropMapper
->Filter( xErrorBarProp
);
3081 if( !aPropertyStates
.empty() )
3084 if( bExportContent
)
3086 // add style name attribute
3087 AddAutoStyleAttribute( aPropertyStates
);
3089 if( nCurrentVersion
>= SvtSaveOptions::ODFVER_012
)
3090 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_DIMENSION
, bYError
? XML_Y
: XML_X
);//#i114149#
3091 SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_ERROR_INDICATOR
, true, true );
3095 CollectAutoStyle( aPropertyStates
);
3102 void SchXMLExportHelper_Impl::exportCandleStickSeries(
3103 const Sequence
< Reference
< chart2::XDataSeries
> > & aSeriesSeq
,
3104 const Reference
< chart2::XDiagram
> & xDiagram
,
3105 bool bJapaneseCandleSticks
,
3106 bool bExportContent
)
3109 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<aSeriesSeq
.getLength(); ++nSeriesIdx
)
3111 Reference
< chart2::XDataSeries
> xSeries( aSeriesSeq
[nSeriesIdx
] );
3112 sal_Int32 nAttachedAxis
= lcl_isSeriesAttachedToFirstAxis( xSeries
)
3113 ? chart::ChartAxisAssign::PRIMARY_Y
3114 : chart::ChartAxisAssign::SECONDARY_Y
;
3116 Reference
< chart2::data::XDataSource
> xSource( xSeries
, uno::UNO_QUERY
);
3119 // export series in correct order (as we don't store roles)
3120 // with japanese candlesticks: open, low, high, close
3121 // otherwise: low, high, close
3122 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeqCnt(
3123 xSource
->getDataSequences());
3125 sal_Int32 nSeriesLength
=
3126 lcl_getSequenceLengthByRole( aSeqCnt
, "values-last");
3128 if( bExportContent
)
3130 Reference
< chart2::XChartDocument
> xNewDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
3131 //@todo: export data points
3133 //TODO: moggi: same code three times
3135 if( bJapaneseCandleSticks
)
3137 tLabelAndValueRange
aRanges( lcl_getLabelAndValueRangeByRole(
3138 aSeqCnt
, "values-first", xNewDoc
, m_aDataSequencesToExport
));
3139 if( !aRanges
.second
.isEmpty())
3140 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, aRanges
.second
);
3141 if( !aRanges
.first
.isEmpty())
3142 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
, aRanges
.first
);
3143 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
3144 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
3146 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
3147 SvXMLElementExport
aOpenSeries( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, true, true );
3148 // export empty data points
3149 exportDataPoints( nullptr, nSeriesLength
, xDiagram
, bExportContent
);
3154 tLabelAndValueRange
aRanges( lcl_getLabelAndValueRangeByRole(
3155 aSeqCnt
, "values-min", xNewDoc
, m_aDataSequencesToExport
));
3156 if( !aRanges
.second
.isEmpty())
3157 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, aRanges
.second
);
3158 if( !aRanges
.first
.isEmpty())
3159 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
, aRanges
.first
);
3160 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
3161 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
3163 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
3164 SvXMLElementExport
aLowSeries( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, true, true );
3165 // export empty data points
3166 exportDataPoints( nullptr, nSeriesLength
, xDiagram
, bExportContent
);
3171 tLabelAndValueRange
aRanges( lcl_getLabelAndValueRangeByRole(
3172 aSeqCnt
, "values-max", xNewDoc
, m_aDataSequencesToExport
));
3173 if( !aRanges
.second
.isEmpty())
3174 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, aRanges
.second
);
3175 if( !aRanges
.first
.isEmpty())
3176 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
, aRanges
.first
);
3177 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
3178 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
3180 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
3181 SvXMLElementExport
aHighSeries( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, true, true );
3182 // export empty data points
3183 exportDataPoints( nullptr, nSeriesLength
, xDiagram
, bExportContent
);
3188 tLabelAndValueRange
aRanges( lcl_getLabelAndValueRangeByRole(
3189 aSeqCnt
, "values-last", xNewDoc
, m_aDataSequencesToExport
));
3190 if( !aRanges
.second
.isEmpty())
3191 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, aRanges
.second
);
3192 if( !aRanges
.first
.isEmpty())
3193 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
, aRanges
.first
);
3194 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
3195 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
3197 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
3198 SvXMLElementExport
aCloseSeries( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, true, true );
3199 // export empty data points
3200 exportDataPoints( nullptr, nSeriesLength
, xDiagram
, bExportContent
);
3207 // remove property states for autostyles
3212 void SchXMLExportHelper_Impl::exportDataPoints(
3213 const uno::Reference
< beans::XPropertySet
> & xSeriesProperties
,
3214 sal_Int32 nSeriesLength
,
3215 const uno::Reference
< chart2::XDiagram
> & xDiagram
,
3216 bool bExportContent
)
3220 // write data-points only if they contain autostyles
3221 // objects with equal autostyles are grouped using the attribute
3224 // Note: if only the nth data-point has autostyles there is an element
3225 // without style and repeat="n-1" attribute written in advance.
3227 // the sequence aDataPointSeq contains indices of data-points that
3228 // do have own attributes. This increases the performance substantially.
3230 // more performant version for #93600#
3231 if (!mxExpPropMapper
.is())
3234 uno::Reference
< chart2::XDataSeries
> xSeries( xSeriesProperties
, uno::UNO_QUERY
);
3236 std::vector
< XMLPropertyState
> aPropertyStates
;
3238 bool bVaryColorsByPoint
= false;
3239 Sequence
< sal_Int32
> aDataPointSeq
;
3240 if( xSeriesProperties
.is())
3242 xSeriesProperties
->getPropertyValue("AttributedDataPoints") >>= aDataPointSeq
;
3243 xSeriesProperties
->getPropertyValue("VaryColorsByPoint") >>= bVaryColorsByPoint
;
3246 sal_Int32 nSize
= aDataPointSeq
.getLength();
3247 SAL_WARN_IF( nSize
> nSeriesLength
, "xmloff.chart", "Too many point attributes" );
3249 const sal_Int32
* pPoints
= aDataPointSeq
.getConstArray();
3252 Reference
< chart2::XColorScheme
> xColorScheme
;
3254 xColorScheme
.set( xDiagram
->getDefaultColorScheme());
3256 ::std::list
< SchXMLDataPointStruct
> aDataPointList
;
3258 sal_Int32 nLastIndex
= -1;
3259 sal_Int32 nCurrIndex
= 0;
3262 if( bVaryColorsByPoint
&& xColorScheme
.is() )
3264 ::std::set
< sal_Int32
> aAttrPointSet
;
3265 ::std::copy( pPoints
, pPoints
+ aDataPointSeq
.getLength(),
3266 ::std::inserter( aAttrPointSet
, aAttrPointSet
.begin()));
3267 const ::std::set
< sal_Int32
>::const_iterator
aEndIt( aAttrPointSet
.end());
3268 for( nElement
= 0; nElement
< nSeriesLength
; ++nElement
)
3270 aPropertyStates
.clear();
3271 uno::Reference
< beans::XPropertySet
> xPropSet
;
3272 bool bExportNumFmt
= false;
3273 if( aAttrPointSet
.find( nElement
) != aEndIt
)
3277 xPropSet
= SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
3278 xSeries
, nElement
, mrExport
.GetModel() );
3279 bExportNumFmt
= true;
3281 catch( const uno::Exception
& rEx
)
3283 SAL_INFO("xmloff.chart", "Exception caught during Export of data point: " << rEx
.Message
);
3288 // property set only containing the color
3289 xPropSet
.set( new ::xmloff::chart::ColorPropertySet(
3290 xColorScheme
->getColorByIndex( nElement
)));
3292 SAL_WARN_IF( !xPropSet
.is(), "xmloff.chart", "Pie Segments should have properties" );
3295 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
3296 if( nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
&& bExportNumFmt
)
3298 lcl_exportNumberFormat( "NumberFormat", xPropSet
, mrExport
);
3299 lcl_exportNumberFormat( "PercentageNumberFormat", xPropSet
, mrExport
);
3302 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
3303 if( !aPropertyStates
.empty() )
3305 if( bExportContent
)
3307 // write data-point with style
3308 SAL_WARN_IF( maAutoStyleNameQueue
.empty(), "xmloff.chart", "Autostyle queue empty!" );
3310 SchXMLDataPointStruct aPoint
;
3311 aPoint
.maStyleName
= maAutoStyleNameQueue
.front();
3312 maAutoStyleNameQueue
.pop();
3313 aDataPointList
.push_back( aPoint
);
3317 CollectAutoStyle( aPropertyStates
);
3322 SAL_WARN_IF( bExportContent
&& (static_cast<sal_Int32
>(aDataPointList
.size()) != nSeriesLength
), "xmloff.chart", "not enough data points on content export" );
3326 for( nElement
= 0; nElement
< nSize
; ++nElement
)
3328 aPropertyStates
.clear();
3329 nCurrIndex
= pPoints
[ nElement
];
3330 //assuming sorted indices in pPoints
3332 if( nCurrIndex
<0 || nCurrIndex
>=nSeriesLength
)
3335 // write leading empty data points
3336 if( nCurrIndex
- nLastIndex
> 1 )
3338 SchXMLDataPointStruct aPoint
;
3339 aPoint
.mnRepeat
= nCurrIndex
- nLastIndex
- 1;
3340 aDataPointList
.push_back( aPoint
);
3343 uno::Reference
< beans::XPropertySet
> xPropSet
;
3344 // get property states
3347 xPropSet
= SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
3348 xSeries
, nCurrIndex
, mrExport
.GetModel() );
3350 catch( const uno::Exception
& rEx
)
3352 SAL_INFO("xmloff.chart", "Exception caught during Export of data point: " << rEx
.Message
);
3356 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
3357 if( nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
)
3359 lcl_exportNumberFormat( "NumberFormat", xPropSet
, mrExport
);
3360 lcl_exportNumberFormat( "PercentageNumberFormat", xPropSet
, mrExport
);
3363 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
3364 if( !aPropertyStates
.empty() )
3366 if( bExportContent
)
3368 // write data-point with style
3369 SAL_WARN_IF( maAutoStyleNameQueue
.empty(), "xmloff.chart", "Autostyle queue empty!" );
3370 SchXMLDataPointStruct aPoint
;
3371 aPoint
.maStyleName
= maAutoStyleNameQueue
.front();
3372 maAutoStyleNameQueue
.pop();
3374 aDataPointList
.push_back( aPoint
);
3375 nLastIndex
= nCurrIndex
;
3379 CollectAutoStyle( aPropertyStates
);
3385 // if we get here the property states are empty
3386 SchXMLDataPointStruct aPoint
;
3387 aDataPointList
.push_back( aPoint
);
3389 nLastIndex
= nCurrIndex
;
3391 // final empty elements
3392 nRepeat
= nSeriesLength
- nLastIndex
- 1;
3395 SchXMLDataPointStruct aPoint
;
3396 aPoint
.mnRepeat
= nRepeat
;
3397 aDataPointList
.push_back( aPoint
);
3401 if (!bExportContent
)
3404 // write elements (merge equal ones)
3405 ::std::list
< SchXMLDataPointStruct
>::iterator aIter
= aDataPointList
.begin();
3406 SchXMLDataPointStruct aPoint
;
3407 SchXMLDataPointStruct aLastPoint
;
3409 // initialize so that it doesn't matter if
3410 // the element is counted in the first iteration
3411 aLastPoint
.mnRepeat
= 0;
3413 for( ; aIter
!= aDataPointList
.end(); ++aIter
)
3417 if( aPoint
.maStyleName
== aLastPoint
.maStyleName
)
3418 aPoint
.mnRepeat
+= aLastPoint
.mnRepeat
;
3419 else if( aLastPoint
.mnRepeat
> 0 )
3421 // write last element
3422 if( !aLastPoint
.maStyleName
.isEmpty() )
3423 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_STYLE_NAME
, aLastPoint
.maStyleName
);
3425 if( aLastPoint
.mnRepeat
> 1 )
3426 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_REPEATED
,
3427 OUString::number( ( aLastPoint
.mnRepeat
) ));
3429 SvXMLElementExport
aPointElem( mrExport
, XML_NAMESPACE_CHART
, XML_DATA_POINT
, true, true );
3431 aLastPoint
= aPoint
;
3433 // write last element if it hasn't been written in last iteration
3434 if( aPoint
.maStyleName
== aLastPoint
.maStyleName
)
3436 if( !aLastPoint
.maStyleName
.isEmpty() )
3437 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_STYLE_NAME
, aLastPoint
.maStyleName
);
3439 if( aLastPoint
.mnRepeat
> 1 )
3440 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_REPEATED
,
3441 OUString::number( ( aLastPoint
.mnRepeat
) ));
3443 SvXMLElementExport
aPointElem( mrExport
, XML_NAMESPACE_CHART
, XML_DATA_POINT
, true, true );
3447 void SchXMLExportHelper_Impl::addPosition( const awt::Point
& rPosition
)
3449 mrExport
.GetMM100UnitConverter().convertMeasureToXML(
3450 msStringBuffer
, rPosition
.X
);
3451 msString
= msStringBuffer
.makeStringAndClear();
3452 mrExport
.AddAttribute( XML_NAMESPACE_SVG
, XML_X
, msString
);
3454 mrExport
.GetMM100UnitConverter().convertMeasureToXML(
3455 msStringBuffer
, rPosition
.Y
);
3456 msString
= msStringBuffer
.makeStringAndClear();
3457 mrExport
.AddAttribute( XML_NAMESPACE_SVG
, XML_Y
, msString
);
3460 void SchXMLExportHelper_Impl::addPosition( const Reference
< drawing::XShape
>& xShape
)
3463 addPosition( xShape
->getPosition());
3466 void SchXMLExportHelper_Impl::addSize( const awt::Size
& rSize
, bool bIsOOoNamespace
)
3468 mrExport
.GetMM100UnitConverter().convertMeasureToXML(
3469 msStringBuffer
, rSize
.Width
);
3470 msString
= msStringBuffer
.makeStringAndClear();
3471 mrExport
.AddAttribute( bIsOOoNamespace
? XML_NAMESPACE_CHART_EXT
: XML_NAMESPACE_SVG
, XML_WIDTH
, msString
);
3473 mrExport
.GetMM100UnitConverter().convertMeasureToXML(
3474 msStringBuffer
, rSize
.Height
);
3475 msString
= msStringBuffer
.makeStringAndClear();
3476 mrExport
.AddAttribute( bIsOOoNamespace
? XML_NAMESPACE_CHART_EXT
: XML_NAMESPACE_SVG
, XML_HEIGHT
, msString
);
3479 void SchXMLExportHelper_Impl::addSize( const Reference
< drawing::XShape
>& xShape
)
3482 addSize( xShape
->getSize() );
3485 awt::Size
SchXMLExportHelper_Impl::getPageSize( const Reference
< chart2::XChartDocument
> & xChartDoc
)
3487 awt::Size
aSize( 8000, 7000 );
3488 uno::Reference
< embed::XVisualObject
> xVisualObject( xChartDoc
, uno::UNO_QUERY
);
3489 SAL_WARN_IF( !xVisualObject
.is(), "xmloff.chart", "need XVisualObject for page size" );
3490 if( xVisualObject
.is() )
3491 aSize
= xVisualObject
->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT
);
3496 void SchXMLExportHelper_Impl::CollectAutoStyle( const std::vector
< XMLPropertyState
>& aStates
)
3498 if( !aStates
.empty() )
3499 maAutoStyleNameQueue
.push( GetAutoStylePoolP().Add( XML_STYLE_FAMILY_SCH_CHART_ID
, aStates
));
3502 void SchXMLExportHelper_Impl::AddAutoStyleAttribute( const std::vector
< XMLPropertyState
>& aStates
)
3504 if( !aStates
.empty() )
3506 SAL_WARN_IF( maAutoStyleNameQueue
.empty(), "xmloff.chart", "Autostyle queue empty!" );
3508 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_STYLE_NAME
, maAutoStyleNameQueue
.front() );
3509 maAutoStyleNameQueue
.pop();
3513 void SchXMLExportHelper_Impl::exportText( const OUString
& rText
)
3515 SchXMLTools::exportText( mrExport
, rText
, false/*bConvertTabsLFs*/ );
3518 // class SchXMLExport
3520 SchXMLExport::SchXMLExport(
3521 const Reference
< uno::XComponentContext
>& xContext
,
3522 OUString
const & implementationName
, SvXMLExportFlags nExportFlags
)
3523 : SvXMLExport( util::MeasureUnit::CM
, xContext
, implementationName
,
3524 ::xmloff::token::XML_CHART
, nExportFlags
),
3525 maAutoStylePool( new SchXMLAutoStylePoolP(*this) ),
3526 maExportHelper( new SchXMLExportHelper(*this, *maAutoStylePool
.get()) )
3528 if( getDefaultVersion() > SvtSaveOptions::ODFVER_012
)
3529 GetNamespaceMap_().Add( GetXMLToken(XML_NP_CHART_EXT
), GetXMLToken(XML_N_CHART_EXT
), XML_NAMESPACE_CHART_EXT
);
3532 SchXMLExport::~SchXMLExport()
3534 // stop progress view
3535 if( mxStatusIndicator
.is())
3537 mxStatusIndicator
->end();
3538 mxStatusIndicator
->reset();
3542 sal_uInt32
SchXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum eClass
)
3544 maExportHelper
->SetSourceShellID(GetSourceShellID());
3545 maExportHelper
->SetDestinationShellID(GetDestinationShellID());
3547 Reference
< chart2::XChartDocument
> xChartDoc( GetModel(), uno::UNO_QUERY
);
3548 maExportHelper
->m_pImpl
->InitRangeSegmentationProperties( xChartDoc
);
3549 return SvXMLExport::exportDoc( eClass
);
3552 void SchXMLExport::ExportStyles_( bool bUsed
)
3554 SvXMLExport::ExportStyles_( bUsed
);
3557 void SchXMLExport::ExportMasterStyles_()
3559 // not available in chart
3560 SAL_INFO("xmloff.chart", "Master Style Export requested. Not available for Chart" );
3563 void SchXMLExport::ExportAutoStyles_()
3565 // there are no styles that require their own autostyles
3566 if( getExportFlags() & SvXMLExportFlags::CONTENT
)
3568 Reference
< chart::XChartDocument
> xChartDoc( GetModel(), uno::UNO_QUERY
);
3571 maExportHelper
->m_pImpl
->collectAutoStyles( xChartDoc
);
3572 maExportHelper
->m_pImpl
->exportAutoStyles();
3576 SAL_WARN("xmloff.chart", "Couldn't export chart due to wrong XModel (must be XChartDocument)" );
3581 void SchXMLExport::ExportContent_()
3583 Reference
< chart::XChartDocument
> xChartDoc( GetModel(), uno::UNO_QUERY
);
3586 // determine if data comes from the outside
3587 bool bIncludeTable
= true;
3589 Reference
< chart2::XChartDocument
> xNewDoc( xChartDoc
, uno::UNO_QUERY
);
3592 // check if we have own data. If so we must not export the complete
3593 // range string, as this is our only indicator for having own or
3594 // external data. @todo: fix this in the file format!
3595 Reference
< lang::XServiceInfo
> xDPServiceInfo( xNewDoc
->getDataProvider(), uno::UNO_QUERY
);
3596 if( ! (xDPServiceInfo
.is() && xDPServiceInfo
->getImplementationName() == "com.sun.star.comp.chart.InternalDataProvider" ))
3598 bIncludeTable
= false;
3603 Reference
< lang::XServiceInfo
> xServ( xChartDoc
, uno::UNO_QUERY
);
3606 if( xServ
->supportsService( "com.sun.star.chart.ChartTableAddressSupplier" ))
3608 Reference
< beans::XPropertySet
> xProp( xServ
, uno::UNO_QUERY
);
3614 OUString sChartAddress
;
3615 aAny
= xProp
->getPropertyValue( "ChartRangeAddress" );
3616 aAny
>>= sChartAddress
;
3617 maExportHelper
->m_pImpl
->SetChartRangeAddress( sChartAddress
);
3619 OUString sTableNumberList
;
3620 aAny
= xProp
->getPropertyValue( "TableNumberList" );
3621 aAny
>>= sTableNumberList
;
3622 maExportHelper
->m_pImpl
->SetTableNumberList( sTableNumberList
);
3624 // do not include own table if there are external addresses
3625 bIncludeTable
= sChartAddress
.isEmpty();
3627 catch( const beans::UnknownPropertyException
& )
3629 SAL_WARN("xmloff.chart", "Property ChartRangeAddress not supported by ChartDocument" );
3635 maExportHelper
->m_pImpl
->exportChart( xChartDoc
, bIncludeTable
);
3639 SAL_WARN("xmloff.chart", "Couldn't export chart due to wrong XModel" );
3643 rtl::Reference
< XMLPropertySetMapper
> SchXMLExport::GetPropertySetMapper() const
3645 return maExportHelper
->m_pImpl
->GetPropertySetMapper();
3648 void SchXMLExportHelper_Impl::InitRangeSegmentationProperties( const Reference
< chart2::XChartDocument
> & xChartDoc
)
3653 Reference
< chart2::data::XDataProvider
> xDataProvider( xChartDoc
->getDataProvider() );
3654 SAL_WARN_IF( !xDataProvider
.is(), "xmloff.chart", "No DataProvider" );
3655 if( xDataProvider
.is())
3657 Reference
< chart2::data::XDataSource
> xDataSource( lcl_pressUsedDataIntoRectangularFormat( xChartDoc
, mbHasCategoryLabels
));
3658 Sequence
< beans::PropertyValue
> aArgs( xDataProvider
->detectArguments( xDataSource
));
3659 OUString sCellRange
, sBrokenRange
;
3660 bool bBrokenRangeAvailable
= false;
3661 for( sal_Int32 i
=0; i
<aArgs
.getLength(); ++i
)
3663 if ( aArgs
[i
].Name
== "CellRangeRepresentation" )
3664 aArgs
[i
].Value
>>= sCellRange
;
3665 else if ( aArgs
[i
].Name
== "BrokenCellRangeForExport" )
3667 if( aArgs
[i
].Value
>>= sBrokenRange
)
3668 bBrokenRangeAvailable
= true;
3670 else if ( aArgs
[i
].Name
== "DataRowSource" )
3672 chart::ChartDataRowSource eRowSource
;
3673 aArgs
[i
].Value
>>= eRowSource
;
3674 mbRowSourceColumns
= ( eRowSource
== chart::ChartDataRowSource_COLUMNS
);
3676 else if ( aArgs
[i
].Name
== "FirstCellAsLabel" )
3677 aArgs
[i
].Value
>>= mbHasSeriesLabels
;
3678 else if ( aArgs
[i
].Name
== "SequenceMapping" )
3679 aArgs
[i
].Value
>>= maSequenceMapping
;
3680 else if ( aArgs
[i
].Name
== "TableNumberList" )
3681 aArgs
[i
].Value
>>= msTableNumberList
;
3684 // #i79009# For Writer we have to export a broken version of the
3685 // range, where every row number is noe too large, so that older
3686 // version can correctly read those files.
3687 msChartAddress
= (bBrokenRangeAvailable
? sBrokenRange
: sCellRange
);
3688 if( !msChartAddress
.isEmpty() )
3690 // convert format to XML-conform one
3691 Reference
< chart2::data::XRangeXMLConversion
> xConversion( xDataProvider
, uno::UNO_QUERY
);
3692 if( xConversion
.is())
3693 msChartAddress
= xConversion
->convertRangeToXML( msChartAddress
);
3697 catch( const uno::Exception
& ex
)
3699 SAL_WARN("xmloff.chart", "Exception caught. Type: " << OUString::createFromAscii( typeid( ex
).name()) << ", Message: " << ex
.Message
);
3703 // first version: everything goes in one storage
3705 Sequence
< OUString
> SAL_CALL
SchXMLExport_getSupportedServiceNames() throw()
3707 return Sequence
< OUString
> { "com.sun.star.comp.Chart.XMLExporter" };
3710 OUString SAL_CALL
SchXMLExport_getImplementationName() throw()
3712 return OUString( "SchXMLExport.Compact" );
3715 Reference
< uno::XInterface
> SAL_CALL
SchXMLExport_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
) throw( uno::Exception
)
3717 // #103997# removed some flags from EXPORT_ALL
3718 return static_cast<cppu::OWeakObject
*>(new SchXMLExport( comphelper::getComponentContext(rSMgr
), SchXMLExport_getImplementationName(), SvXMLExportFlags::ALL
^ ( SvXMLExportFlags::SETTINGS
| SvXMLExportFlags::MASTERSTYLES
| SvXMLExportFlags::SCRIPTS
)));
3722 Sequence
< OUString
> SAL_CALL
SchXMLExport_Oasis_getSupportedServiceNames() throw()
3724 return Sequence
< OUString
> { "com.sun.star.comp.Chart.XMLOasisExporter" };
3727 OUString SAL_CALL
SchXMLExport_Oasis_getImplementationName() throw()
3729 return OUString( "SchXMLExport.Oasis.Compact" );
3732 Reference
< uno::XInterface
> SAL_CALL
SchXMLExport_Oasis_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
) throw( uno::Exception
)
3734 // #103997# removed some flags from EXPORT_ALL
3735 return static_cast<cppu::OWeakObject
*>(new SchXMLExport( comphelper::getComponentContext(rSMgr
),
3736 SchXMLExport_Oasis_getImplementationName(),
3737 (SvXMLExportFlags::ALL
^ ( SvXMLExportFlags::SETTINGS
| SvXMLExportFlags::MASTERSTYLES
| SvXMLExportFlags::SCRIPTS
)) | SvXMLExportFlags::OASIS
));
3740 // multiple storage version: one for content / styles / meta
3742 Sequence
< OUString
> SAL_CALL
SchXMLExport_Styles_getSupportedServiceNames() throw()
3744 return Sequence
< OUString
> { "com.sun.star.comp.Chart.XMLStylesExporter" };
3747 OUString SAL_CALL
SchXMLExport_Styles_getImplementationName() throw()
3749 return OUString( "SchXMLExport.Styles" );
3752 Reference
< uno::XInterface
> SAL_CALL
SchXMLExport_Styles_createInstance(const Reference
< lang::XMultiServiceFactory
>& rSMgr
) throw( uno::Exception
)
3754 return static_cast<cppu::OWeakObject
*>(new SchXMLExport( comphelper::getComponentContext(rSMgr
), SchXMLExport_Styles_getImplementationName(), SvXMLExportFlags::STYLES
));
3758 Sequence
< OUString
> SAL_CALL
SchXMLExport_Oasis_Styles_getSupportedServiceNames() throw()
3760 return Sequence
< OUString
> { "com.sun.star.comp.Chart.XMLOasisStylesExporter" };
3763 OUString SAL_CALL
SchXMLExport_Oasis_Styles_getImplementationName() throw()
3765 return OUString( "SchXMLExport.Oasis.Styles" );
3768 Reference
< uno::XInterface
> SAL_CALL
SchXMLExport_Oasis_Styles_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
) throw( uno::Exception
)
3770 return static_cast<cppu::OWeakObject
*>(new SchXMLExport( comphelper::getComponentContext(rSMgr
), SchXMLExport_Oasis_Styles_getImplementationName(), SvXMLExportFlags::STYLES
| SvXMLExportFlags::OASIS
));
3773 Sequence
< OUString
> SAL_CALL
SchXMLExport_Content_getSupportedServiceNames() throw()
3775 return Sequence
< OUString
> { "com.sun.star.comp.Chart.XMLContentExporter" };
3778 OUString SAL_CALL
SchXMLExport_Content_getImplementationName() throw()
3780 return OUString( "SchXMLExport.Content" );
3783 Reference
< uno::XInterface
> SAL_CALL
SchXMLExport_Content_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
) throw( uno::Exception
)
3785 return static_cast<cppu::OWeakObject
*>(new SchXMLExport( comphelper::getComponentContext(rSMgr
), SchXMLExport_Content_getImplementationName(), SvXMLExportFlags::AUTOSTYLES
| SvXMLExportFlags::CONTENT
| SvXMLExportFlags::FONTDECLS
));
3789 Sequence
< OUString
> SAL_CALL
SchXMLExport_Oasis_Content_getSupportedServiceNames() throw()
3791 return Sequence
< OUString
> { "com.sun.star.comp.Chart.XMLOasisContentExporter" };
3794 OUString SAL_CALL
SchXMLExport_Oasis_Content_getImplementationName() throw()
3796 return OUString( "SchXMLExport.Oasis.Content" );
3799 Reference
< uno::XInterface
> SAL_CALL
SchXMLExport_Oasis_Content_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
) throw( uno::Exception
)
3801 return static_cast<cppu::OWeakObject
*>(new SchXMLExport( comphelper::getComponentContext(rSMgr
), SchXMLExport_Oasis_Content_getImplementationName(), SvXMLExportFlags::AUTOSTYLES
| SvXMLExportFlags::CONTENT
| SvXMLExportFlags::FONTDECLS
| SvXMLExportFlags::OASIS
));
3805 Sequence
< OUString
> SAL_CALL
SchXMLExport_Oasis_Meta_getSupportedServiceNames() throw()
3807 return Sequence
< OUString
> { "com.sun.star.comp.Chart.XMLOasisMetaExporter" };
3810 OUString SAL_CALL
SchXMLExport_Oasis_Meta_getImplementationName() throw()
3812 return OUString( "SchXMLExport.Oasis.Meta" );
3815 Reference
< uno::XInterface
> SAL_CALL
SchXMLExport_Oasis_Meta_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
) throw( uno::Exception
)
3817 return static_cast<cppu::OWeakObject
*>(new SchXMLExport( comphelper::getComponentContext(rSMgr
), SchXMLExport_Oasis_Meta_getImplementationName(), SvXMLExportFlags::META
| SvXMLExportFlags::OASIS
));
3820 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */