1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <sax/tools/converter.hxx>
23 #include <xmloff/xmlprmap.hxx>
25 #include "SchXMLExport.hxx"
26 #include "XMLChartPropertySetMapper.hxx"
27 #include "ColorPropertySet.hxx"
28 #include "SchXMLTools.hxx"
29 #include "SchXMLEnumConverter.hxx"
31 #include <tools/debug.hxx>
32 #include <rtl/logfile.hxx>
33 #include <comphelper/processfactory.hxx>
34 #include <tools/globname.hxx>
35 #include <comphelper/classids.hxx>
37 #include <xmloff/nmspmap.hxx>
38 #include "xmloff/xmlnmspe.hxx"
39 #include <xmloff/xmltoken.hxx>
40 #include <xmloff/families.hxx>
41 #include <xmloff/xmlaustp.hxx>
42 #include <xmloff/xmluconv.hxx>
43 #include <xmloff/xmlmetae.hxx>
44 #include <xmloff/SchXMLSeriesHelper.hxx>
45 #include "xexptran.hxx"
46 #include <rtl/math.hxx>
47 // header for any2enum
48 #include <comphelper/extract.hxx>
54 #include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
55 #include <com/sun/star/lang/XServiceInfo.hpp>
56 #include <com/sun/star/lang/XServiceName.hpp>
57 #include <com/sun/star/beans/XPropertySet.hpp>
58 #include <com/sun/star/uno/XComponentContext.hpp>
59 #include <com/sun/star/util/XRefreshable.hpp>
61 #include <com/sun/star/chart/XAxis.hpp>
62 #include <com/sun/star/chart/XAxisSupplier.hpp>
63 #include <com/sun/star/chart/XChartDocument.hpp>
64 #include <com/sun/star/chart/ChartLegendPosition.hpp>
65 #include <com/sun/star/chart/ChartLegendExpansion.hpp>
66 #include <com/sun/star/chart/ChartDataRowSource.hpp>
67 #include <com/sun/star/chart/ChartAxisAssign.hpp>
68 #include <com/sun/star/chart/ChartAxisType.hpp>
69 #include <com/sun/star/chart/TimeIncrement.hpp>
70 #include <com/sun/star/chart/TimeInterval.hpp>
71 #include <com/sun/star/chart/TimeUnit.hpp>
72 #include <com/sun/star/chart/ChartSeriesAddress.hpp>
73 #include <com/sun/star/chart/X3DDisplay.hpp>
74 #include <com/sun/star/chart/XStatisticDisplay.hpp>
75 #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
76 #include <com/sun/star/chart/XDiagramPositioning.hpp>
78 #include <com/sun/star/chart2/XAnyDescriptionAccess.hpp>
79 #include <com/sun/star/chart2/AxisType.hpp>
80 #include <com/sun/star/chart2/XChartDocument.hpp>
81 #include <com/sun/star/chart2/XDiagram.hpp>
82 #include <com/sun/star/chart2/RelativePosition.hpp>
83 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
84 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
85 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
86 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
87 #include <com/sun/star/chart2/data/XDataSource.hpp>
88 #include <com/sun/star/chart2/data/XDataSink.hpp>
89 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
90 #include <com/sun/star/chart2/data/XDataProvider.hpp>
91 #include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
92 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
93 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
94 #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
96 #include <com/sun/star/util/MeasureUnit.hpp>
97 #include <com/sun/star/util/XStringMapping.hpp>
98 #include <com/sun/star/drawing/HomogenMatrix.hpp>
99 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
100 #include <com/sun/star/drawing/XShapes.hpp>
101 #include <com/sun/star/embed/Aspects.hpp>
102 #include <com/sun/star/embed/XVisualObject.hpp>
103 #include <com/sun/star/container/XChild.hpp>
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 // ========================================
119 // class SchXMLExportHelper_Impl
120 // ========================================
122 class SchXMLExportHelper_Impl
125 // first: data sequence for label, second: data sequence for values.
126 typedef ::std::pair
< ::com::sun::star::uno::Reference
< ::com::sun::star::chart2::data::XDataSequence
>,
127 ::com::sun::star::uno::Reference
< ::com::sun::star::chart2::data::XDataSequence
> > tLabelValuesDataPair
;
128 typedef ::std::vector
< tLabelValuesDataPair
> tDataSequenceCont
;
131 SchXMLExportHelper_Impl( SvXMLExport
& rExport
,
132 SvXMLAutoStylePoolP
& rASPool
);
134 virtual ~SchXMLExportHelper_Impl();
137 /// parse chart and collect all auto-styles used in current pool
138 void collectAutoStyles( com::sun::star::uno::Reference
<
139 com::sun::star::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 ist the outer element of a chart. So these attributes can easily
153 be parsed again by the container
155 void exportChart( com::sun::star::uno::Reference
<
156 com::sun::star::chart::XChartDocument
> rChartDoc
,
157 sal_Bool bIncludeTable
);
159 UniReference
< XMLPropertySetMapper
> GetPropertySetMapper() const;
161 void SetChartRangeAddress( const OUString
& rAddress
)
162 { msChartAddress
= rAddress
; }
163 void SetTableNumberList( const OUString
& rList
)
164 { msTableNumberList
= rList
; }
166 void InitRangeSegmentationProperties(
167 const ::com::sun::star::uno::Reference
<
168 ::com::sun::star::chart2::XChartDocument
> & xChartDoc
);
170 ::com::sun::star::awt::Size
getPageSize(
171 const ::com::sun::star::uno::Reference
<
172 ::com::sun::star::chart2::XChartDocument
> & xChartDoc
) const;
174 /** first parseDocument: collect autostyles and store names in this queue
175 second parseDocument: export content and use names from this queue
177 ::std::queue
< OUString
> maAutoStyleNameQueue
;
178 void CollectAutoStyle(
179 const std::vector
< XMLPropertyState
>& aStates
);
180 void AddAutoStyleAttribute(
181 const std::vector
< XMLPropertyState
>& aStates
);
183 SvXMLAutoStylePoolP
& GetAutoStylePoolP()
184 { return mrAutoStylePool
; }
186 /// if bExportContent is false the auto-styles are collected
187 void parseDocument( com::sun::star::uno::Reference
<
188 com::sun::star::chart::XChartDocument
>& rChartDoc
,
189 sal_Bool bExportContent
,
190 sal_Bool bIncludeTable
= sal_False
);
193 com::sun::star::uno::Reference
< com::sun::star::chart::XDiagram
> xDiagram
,
194 com::sun::star::uno::Reference
< com::sun::star::chart2::XDiagram
> xNewDiagram
,
195 const ::com::sun::star::awt::Size
& rPageSize
,
196 sal_Bool bExportContent
,
197 sal_Bool bIncludeTable
);
198 void exportCoordinateRegion( const com::sun::star::uno::Reference
< com::sun::star::chart::XDiagram
>& xDiagram
);
199 void exportAxes( const com::sun::star::uno::Reference
< com::sun::star::chart::XDiagram
> & xDiagram
,
200 const com::sun::star::uno::Reference
< com::sun::star::chart2::XDiagram
> & xNewDiagram
,
201 sal_Bool bExportContent
);
202 void exportAxis( enum XMLTokenEnum eDimension
, enum XMLTokenEnum eAxisName
,
203 const Reference
< beans::XPropertySet
> xAxisProps
, const Reference
< chart2::XAxis
>& xChart2Axis
,
204 const OUString
& rCategoriesRanges
,
205 bool bHasTitle
, bool bHasMajorGrid
, bool bHasMinorGrid
, bool bExportContent
);
206 void exportGrid( const Reference
< beans::XPropertySet
> xGridProperties
, bool bMajor
, bool bExportContent
);
207 void exportDateScale( const Reference
< beans::XPropertySet
> xAxisProps
);
208 void exportAxisTitle( const Reference
< beans::XPropertySet
> xTitleProps
, bool bExportContent
);
211 const com::sun::star::uno::Reference
< com::sun::star::chart2::XDiagram
> & xNewDiagram
,
212 const ::com::sun::star::awt::Size
& rPageSize
,
213 sal_Bool bExportContent
,
214 sal_Bool bHasTwoYAxes
);
215 void exportCandleStickSeries(
216 const ::com::sun::star::uno::Sequence
<
217 ::com::sun::star::uno::Reference
<
218 ::com::sun::star::chart2::XDataSeries
> > & aSeriesSeq
,
219 const ::com::sun::star::uno::Reference
<
220 ::com::sun::star::chart2::XDiagram
> & xDiagram
,
221 sal_Bool bJapaneseCandleSticks
,
222 sal_Bool bExportContent
);
223 void exportDataPoints(
224 const ::com::sun::star::uno::Reference
<
225 ::com::sun::star::beans::XPropertySet
> & xSeriesProperties
,
226 sal_Int32 nSeriesLength
,
227 const ::com::sun::star::uno::Reference
<
228 ::com::sun::star::chart2::XDiagram
> & xDiagram
,
229 sal_Bool bExportContent
);
230 void exportRegressionCurve(
231 const ::com::sun::star::uno::Reference
<
232 ::com::sun::star::chart2::XDataSeries
> & xSeries
,
233 const ::com::sun::star::uno::Reference
<
234 ::com::sun::star::beans::XPropertySet
> & xSeriesProp
,
235 const ::com::sun::star::awt::Size
& rPageSize
,
236 sal_Bool bExportContent
);
238 void exportErrorBar (
239 const ::com::sun::star::uno::Reference
<beans::XPropertySet
> &xSeriesProp
, bool bYError
,
240 bool bExportContent
);
242 /// add svg position as attribute for current element
243 void addPosition( const ::com::sun::star::awt::Point
& rPosition
);
244 void addPosition( com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
> xShape
);
245 /// add svg size as attribute for current element
246 void addSize( const ::com::sun::star::awt::Size
& rSize
, bool bIsOOoNamespace
= false );
247 void addSize( com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
> xShape
, bool bIsOOoNamespace
= false );
248 /// fills the member msString with the appropriate String (i.e. "A3")
249 void getCellAddress( sal_Int32 nCol
, sal_Int32 nRow
);
250 /// exports a string as a paragraph element
251 void exportText( const OUString
& rText
, bool bConvertTabsLFs
= false );
252 void exportErrorBarRanges();
255 SchXMLExportHelper_Impl(SchXMLExportHelper_Impl
&); // not defined
256 SchXMLExportHelper_Impl
operator =(SchXMLExportHelper_Impl
&); // not defined
259 SvXMLExport
& mrExport
;
260 SvXMLAutoStylePoolP
& mrAutoStylePool
;
261 UniReference
< XMLPropertySetMapper
> mxPropertySetMapper
;
262 UniReference
< XMLChartExportPropertyMapper
> mxExpPropMapper
;
264 OUString msTableName
;
265 OUStringBuffer msStringBuffer
;
268 // members filled by InitRangeSegmentationProperties (retrieved from DataProvider)
269 sal_Bool mbHasSeriesLabels
;
270 sal_Bool mbHasCategoryLabels
; //if the categories are only automatically generated this will be false
271 sal_Bool mbRowSourceColumns
;
272 OUString msChartAddress
;
273 OUString msTableNumberList
;
274 ::com::sun::star::uno::Sequence
< sal_Int32
> maSequenceMapping
;
278 ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShapes
> mxAdditionalShapes
;
280 tDataSequenceCont m_aDataSequencesToExport
;
281 OUString maCategoriesRange
;
287 class lcl_MatchesRole
: public ::std::unary_function
< Reference
< chart2::data::XLabeledDataSequence
>, bool >
290 explicit lcl_MatchesRole( const OUString
& aRole
) :
294 bool operator () ( const Reference
< chart2::data::XLabeledDataSequence
> & xSeq
) const
298 Reference
< beans::XPropertySet
> xProp( xSeq
->getValues(), uno::UNO_QUERY
);
301 return ( xProp
.is() &&
302 (xProp
->getPropertyValue(
303 OUString( "Role" ) ) >>= aRole
) &&
304 m_aRole
.equals( aRole
));
311 template< typename T
>
312 void lcl_SequenceToVectorAppend( const Sequence
< T
> & rSource
, ::std::vector
< T
> & rDestination
)
314 rDestination
.reserve( rDestination
.size() + rSource
.getLength());
315 ::std::copy( rSource
.getConstArray(), rSource
.getConstArray() + rSource
.getLength(),
316 ::std::back_inserter( rDestination
));
319 template< typename T
>
320 void lcl_SequenceToVector( const Sequence
< T
> & rSource
, ::std::vector
< T
> & rDestination
)
322 rDestination
.clear();
323 lcl_SequenceToVectorAppend( rSource
, rDestination
);
326 Reference
< chart2::data::XLabeledDataSequence
> lcl_getCategories( const Reference
< chart2::XDiagram
> & xDiagram
)
328 Reference
< chart2::data::XLabeledDataSequence
> xResult
;
331 Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt(
332 xDiagram
, uno::UNO_QUERY_THROW
);
333 Sequence
< Reference
< chart2::XCoordinateSystem
> > aCooSysSeq(
334 xCooSysCnt
->getCoordinateSystems());
335 for( sal_Int32 i
=0; i
<aCooSysSeq
.getLength(); ++i
)
337 Reference
< chart2::XCoordinateSystem
> xCooSys( aCooSysSeq
[i
] );
338 SAL_WARN_IF( !xCooSys
.is(), "xmloff.chart", "xCooSys is NULL" );
339 for( sal_Int32 nN
= xCooSys
->getDimension(); nN
--; )
341 const sal_Int32 nMaxAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nN
);
342 for(sal_Int32 nI
=0; nI
<=nMaxAxisIndex
; ++nI
)
344 Reference
< chart2::XAxis
> xAxis
= xCooSys
->getAxisByDimension( nN
, nI
);
345 SAL_WARN_IF( !xAxis
.is(), "xmloff.chart", "xAxis is NULL");
348 chart2::ScaleData aScaleData
= xAxis
->getScaleData();
349 if( aScaleData
.Categories
.is())
351 xResult
.set( aScaleData
.Categories
);
359 catch( const uno::Exception
& ex
)
361 SAL_WARN("xmloff.chart", "Exception caught. Type: " << OUString::createFromAscii( typeid( ex
).name()) << ", Message: " << ex
.Message
);
367 Reference
< chart2::data::XDataSource
> lcl_createDataSource(
368 const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aData
)
370 Reference
< uno::XComponentContext
> xContext(
371 comphelper::getProcessComponentContext() );
372 Reference
< chart2::data::XDataSink
> xSink(
373 xContext
->getServiceManager()->createInstanceWithContext(
374 "com.sun.star.chart2.data.DataSource", xContext
),
375 uno::UNO_QUERY_THROW
);
376 xSink
->setData( aData
);
378 return Reference
< chart2::data::XDataSource
>( xSink
, uno::UNO_QUERY
);
381 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > lcl_getAllSeriesSequences( const Reference
< chart2::XChartDocument
>& xChartDoc
)
383 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aContainer
;
386 Reference
< chart2::XDiagram
> xDiagram( xChartDoc
->getFirstDiagram());
387 ::std::vector
< Reference
< chart2::XDataSeries
> > aSeriesVector( SchXMLSeriesHelper::getDataSeriesFromDiagram( xDiagram
));
388 for( ::std::vector
< Reference
< chart2::XDataSeries
> >::const_iterator
aSeriesIt( aSeriesVector
.begin() )
389 ; aSeriesIt
!= aSeriesVector
.end(); ++aSeriesIt
)
391 Reference
< chart2::data::XDataSource
> xDataSource( *aSeriesIt
, uno::UNO_QUERY
);
392 if( !xDataSource
.is() )
394 uno::Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aDataSequences( xDataSource
->getDataSequences() );
395 lcl_SequenceToVectorAppend( aDataSequences
, aContainer
);
399 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aRet( aContainer
.size());
400 ::std::copy( aContainer
.begin(), aContainer
.end(), aRet
.getArray());
405 Reference
< chart2::data::XLabeledDataSequence
>
406 lcl_getDataSequenceByRole(
407 const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aLabeledSeq
,
408 const OUString
& rRole
)
410 Reference
< chart2::data::XLabeledDataSequence
> aNoResult
;
412 const Reference
< chart2::data::XLabeledDataSequence
> * pBegin
= aLabeledSeq
.getConstArray();
413 const Reference
< chart2::data::XLabeledDataSequence
> * pEnd
= pBegin
+ aLabeledSeq
.getLength();
414 const Reference
< chart2::data::XLabeledDataSequence
> * pMatch
=
415 ::std::find_if( pBegin
, pEnd
, lcl_MatchesRole( rRole
));
423 Reference
< chart2::data::XDataSource
> lcl_pressUsedDataIntoRectangularFormat( const Reference
< chart2::XChartDocument
>& xChartDoc
, sal_Bool
& rOutSourceHasCategoryLabels
)
425 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aLabeledSeqVector
;
427 //categories are always the first sequence
428 Reference
< chart2::XDiagram
> xDiagram( xChartDoc
->getFirstDiagram());
429 Reference
< chart2::data::XLabeledDataSequence
> xCategories( lcl_getCategories( xDiagram
) );
430 if( xCategories
.is() )
431 aLabeledSeqVector
.push_back( xCategories
);
432 rOutSourceHasCategoryLabels
= sal_Bool(xCategories
.is());
434 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeriesSeqVector(
435 lcl_getAllSeriesSequences( xChartDoc
) );
437 //the first x-values is always the next sequence //todo ... other x-values get lost for old format
438 Reference
< chart2::data::XLabeledDataSequence
> xXValues(
439 lcl_getDataSequenceByRole( aSeriesSeqVector
, OUString( "values-x" ) ) );
441 aLabeledSeqVector
.push_back( xXValues
);
443 //add all other sequences now without x-values
444 lcl_MatchesRole
aHasXValues( OUString( "values-x" ) );
445 for( sal_Int32 nN
=0; nN
<aSeriesSeqVector
.getLength(); nN
++ )
447 if( !aHasXValues( aSeriesSeqVector
[nN
] ) )
448 aLabeledSeqVector
.push_back( aSeriesSeqVector
[nN
] );
451 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeq( aLabeledSeqVector
.size() );
452 ::std::copy( aLabeledSeqVector
.begin(), aLabeledSeqVector
.end(), aSeq
.getArray() );
454 return lcl_createDataSource( aSeq
);
457 bool lcl_isSeriesAttachedToFirstAxis(
458 const Reference
< chart2::XDataSeries
> & xDataSeries
)
464 sal_Int32 nAxisIndex
= 0;
465 Reference
< beans::XPropertySet
> xProp( xDataSeries
, uno::UNO_QUERY_THROW
);
467 xProp
->getPropertyValue( OUString( "AttachedAxisIndex" ) ) >>= nAxisIndex
;
468 bResult
= (0==nAxisIndex
);
470 catch( const uno::Exception
& ex
)
472 SAL_WARN("xmloff.chart", "Exception caught. Type: " << OUString::createFromAscii( typeid( ex
).name()) << ", Message: " << ex
.Message
);
478 OUString
lcl_ConvertRange( const OUString
& rRange
, const Reference
< chart2::XChartDocument
> & xDoc
)
480 OUString aResult
= rRange
;
483 Reference
< chart2::data::XRangeXMLConversion
> xConversion(
484 xDoc
->getDataProvider(), uno::UNO_QUERY
);
485 if( xConversion
.is())
486 aResult
= xConversion
->convertRangeToXML( rRange
);
490 typedef ::std::pair
< OUString
, OUString
> tLabelAndValueRange
;
492 tLabelAndValueRange
lcl_getLabelAndValueRangeByRole(
493 const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aSeqCnt
,
494 const OUString
& rRole
,
495 const Reference
< chart2::XChartDocument
> & xDoc
,
496 SchXMLExportHelper_Impl::tDataSequenceCont
& rOutSequencesToExport
)
498 tLabelAndValueRange aResult
;
500 Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq(
501 lcl_getDataSequenceByRole( aSeqCnt
, rRole
));
502 if( xLabeledSeq
.is())
504 Reference
< chart2::data::XDataSequence
> xLabelSeq( xLabeledSeq
->getLabel());
506 aResult
.first
= lcl_ConvertRange( xLabelSeq
->getSourceRangeRepresentation(), xDoc
);
508 Reference
< chart2::data::XDataSequence
> xValueSeq( xLabeledSeq
->getValues());
510 aResult
.second
= lcl_ConvertRange( xValueSeq
->getSourceRangeRepresentation(), xDoc
);
512 if( xLabelSeq
.is() || xValueSeq
.is())
513 rOutSequencesToExport
.push_back( SchXMLExportHelper_Impl::tLabelValuesDataPair( xLabelSeq
, xValueSeq
));
519 sal_Int32
lcl_getSequenceLengthByRole(
520 const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aSeqCnt
,
521 const OUString
& rRole
)
523 Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq(
524 lcl_getDataSequenceByRole( aSeqCnt
, rRole
));
525 if( xLabeledSeq
.is())
527 Reference
< chart2::data::XDataSequence
> xSeq( xLabeledSeq
->getValues());
528 return xSeq
->getData().getLength();
533 OUString
lcl_flattenStringSequence( const Sequence
< OUString
> & rSequence
)
535 OUStringBuffer aResult
;
536 bool bPrecedeWithSpace
= false;
537 for( sal_Int32 nIndex
=0; nIndex
<rSequence
.getLength(); ++nIndex
)
539 if( !rSequence
[nIndex
].isEmpty())
541 if( bPrecedeWithSpace
)
542 aResult
.append( static_cast< sal_Unicode
>( ' ' ));
543 aResult
.append( rSequence
[nIndex
] );
544 bPrecedeWithSpace
= true;
547 return aResult
.makeStringAndClear();
550 void lcl_getLabelStringSequence( Sequence
< OUString
>& rOutLabels
, const Reference
< chart2::data::XDataSequence
> & xLabelSeq
)
552 uno::Reference
< chart2::data::XTextualDataSequence
> xTextualDataSequence( xLabelSeq
, uno::UNO_QUERY
);
553 if( xTextualDataSequence
.is())
555 rOutLabels
= xTextualDataSequence
->getTextualData();
557 else if( xLabelSeq
.is())
559 Sequence
< uno::Any
> aAnies( xLabelSeq
->getData());
560 rOutLabels
.realloc( aAnies
.getLength());
561 for( sal_Int32 i
=0; i
<aAnies
.getLength(); ++i
)
562 aAnies
[i
] >>= rOutLabels
[i
];
566 sal_Int32
lcl_getMaxSequenceLength(
567 const SchXMLExportHelper_Impl::tDataSequenceCont
& rContainer
)
569 sal_Int32 nResult
= 0;
570 for( SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator
aIt( rContainer
.begin());
571 aIt
!= rContainer
.end(); ++aIt
)
573 if( aIt
->second
.is())
575 sal_Int32 nSeqLength
= aIt
->second
->getData().getLength();
576 if( nSeqLength
> nResult
)
577 nResult
= nSeqLength
;
583 uno::Sequence
< OUString
> lcl_DataSequenceToStringSequence(
584 const uno::Reference
< chart2::data::XDataSequence
>& xDataSequence
)
586 uno::Sequence
< OUString
> aResult
;
587 if(!xDataSequence
.is())
590 uno::Reference
< chart2::data::XTextualDataSequence
> xTextualDataSequence( xDataSequence
, uno::UNO_QUERY
);
591 if( xTextualDataSequence
.is() )
593 aResult
= xTextualDataSequence
->getTextualData();
597 uno::Sequence
< uno::Any
> aValues
= xDataSequence
->getData();
598 aResult
.realloc(aValues
.getLength());
600 for(sal_Int32 nN
=aValues
.getLength();nN
--;)
601 aValues
[nN
] >>= aResult
[nN
];
606 ::std::vector
< double > lcl_getAllValuesFromSequence( const Reference
< chart2::data::XDataSequence
> & xSeq
)
609 ::rtl::math::setNan( &fNan
);
610 ::std::vector
< double > aResult
;
614 uno::Sequence
< double > aValuesSequence
;
615 Reference
< chart2::data::XNumericalDataSequence
> xNumSeq( xSeq
, uno::UNO_QUERY
);
618 aValuesSequence
= xNumSeq
->getNumericalData();
622 Sequence
< uno::Any
> aAnies( xSeq
->getData() );
623 aValuesSequence
.realloc( aAnies
.getLength() );
624 for( sal_Int32 i
=0; i
<aAnies
.getLength(); ++i
)
625 aAnies
[i
] >>= aValuesSequence
[i
];
628 //special handling for x-values (if x-values do point to categories, indices are used instead )
629 Reference
< beans::XPropertySet
> xProp( xSeq
, uno::UNO_QUERY
);
633 xProp
->getPropertyValue( OUString( "Role" ) ) >>= aRole
;
634 if( aRole
.match( OUString( "values-x" ) ) )
636 //lcl_clearIfNoValuesButTextIsContained - replace by indices if the values are not appropriate
637 bool bHasValue
=false;
639 sal_Int32 nCount
= aValuesSequence
.getLength();
640 for( sal_Int32 j
= 0; j
< nCount
; ++j
)
642 if( !::rtl::math::isNan( aValuesSequence
[j
] ) )
650 //no double value is countained
652 uno::Sequence
< OUString
> aStrings( lcl_DataSequenceToStringSequence( xSeq
) );
653 sal_Int32 nTextCount
= aStrings
.getLength();
654 for( sal_Int32 j
= 0; j
< nTextCount
; ++j
)
656 if( !aStrings
[j
].isEmpty() )
663 if( !bHasValue
&& bHasText
)
665 for( sal_Int32 j
= 0; j
< nCount
; ++j
)
666 aValuesSequence
[j
] = j
+1;
671 ::std::copy( aValuesSequence
.getConstArray(), aValuesSequence
.getConstArray() + aValuesSequence
.getLength(),
672 ::std::back_inserter( aResult
));
676 bool lcl_SequenceHasUnhiddenData( const uno::Reference
< chart2::data::XDataSequence
>& xDataSequence
)
678 if( !xDataSequence
.is() )
680 uno::Reference
< beans::XPropertySet
> xProp( xDataSequence
, uno::UNO_QUERY
);
683 uno::Sequence
< sal_Int32
> aHiddenValues
;
686 xProp
->getPropertyValue( OUString( "HiddenValues" ) ) >>= aHiddenValues
;
687 if( !aHiddenValues
.getLength() )
690 catch( const uno::Exception
& )
695 if( xDataSequence
->getData().getLength() )
700 typedef vector
< OUString
> tStringVector
;
701 typedef vector
< double > tDoubleVector
;
702 typedef vector
< vector
< OUString
> > t2DStringVector
;
703 typedef vector
< vector
< double > > t2DNumberContainer
;
707 t2DNumberContainer aDataInRows
;
708 tStringVector aDataRangeRepresentations
;
710 tStringVector aColumnDescriptions
;
711 tStringVector aColumnDescriptions_Ranges
;
713 tStringVector aRowDescriptions
;
714 tStringVector aRowDescriptions_Ranges
;
716 Sequence
< Sequence
< uno::Any
> > aComplexColumnDescriptions
;//outer index is columns - inner index is level
717 Sequence
< Sequence
< uno::Any
> > aComplexRowDescriptions
;//outer index is rows - inner index is level
719 ::std::vector
< sal_Int32
> aHiddenColumns
;
722 // ::std::bind2nd( ::std::mem_fun_ref( &T::resize ), nSize ) does not work
726 lcl_resize( typename
T::size_type nSize
, typename
T::value_type fDefaultValue
) : m_nSize( nSize
), m_fDefaultValue( fDefaultValue
) {}
727 void operator()( T
& t
)
728 { t
.resize( m_nSize
, m_fDefaultValue
); }
730 typename
T::size_type m_nSize
;
731 typename
T::value_type m_fDefaultValue
;
735 typedef ::std::map
< sal_Int32
, SchXMLExportHelper_Impl::tLabelValuesDataPair
>
738 struct lcl_SequenceToMapElement
:
739 public ::std::unary_function
< lcl_DataSequenceMap::mapped_type
, lcl_DataSequenceMap::value_type
>
741 lcl_SequenceToMapElement()
743 result_type
operator() ( const argument_type
& rContent
)
745 sal_Int32 nIndex
= -1;
746 if( rContent
.second
.is()) //has values
748 OUString
aRangeRep( rContent
.second
->getSourceRangeRepresentation());
749 nIndex
= aRangeRep
.toInt32();
751 else if( rContent
.first
.is()) //has labels
752 nIndex
= rContent
.first
->getSourceRangeRepresentation().copy( sizeof("label ")).toInt32();
753 return result_type( nIndex
, rContent
);
757 void lcl_ReorderInternalSequencesAccordingToTheirRangeName(
758 SchXMLExportHelper_Impl::tDataSequenceCont
& rInOutSequences
)
760 lcl_DataSequenceMap aIndexSequenceMap
;
761 ::std::transform( rInOutSequences
.begin(), rInOutSequences
.end(),
762 ::std::inserter( aIndexSequenceMap
, aIndexSequenceMap
.begin()),
763 lcl_SequenceToMapElement());
765 rInOutSequences
.clear();
766 sal_Int32 nIndex
= 0;
767 for( lcl_DataSequenceMap::const_iterator aIt
= aIndexSequenceMap
.begin();
768 aIt
!= aIndexSequenceMap
.end(); ++aIt
, ++nIndex
)
772 // fill empty columns
773 for( ; nIndex
< aIt
->first
; ++nIndex
)
774 rInOutSequences
.push_back(
775 SchXMLExportHelper_Impl::tDataSequenceCont::value_type(
776 (uno::Reference
< chart2::data::XDataSequence
>)0,
777 (uno::Reference
< chart2::data::XDataSequence
>)0 ));
778 OSL_ASSERT( nIndex
== aIt
->first
);
779 rInOutSequences
.push_back( aIt
->second
);
784 lcl_TableData
lcl_getDataForLocalTable(
785 const SchXMLExportHelper_Impl::tDataSequenceCont
& aSequencesToExport
,
786 const Reference
< chart2::XAnyDescriptionAccess
>& xAnyDescriptionAccess
,
787 const OUString
& rCategoriesRange
,
788 bool bSeriesFromColumns
,
789 const Reference
< chart2::data::XRangeXMLConversion
> & xRangeConversion
)
791 lcl_TableData aResult
;
795 Sequence
< OUString
> aSimpleCategories
;
796 if( xAnyDescriptionAccess
.is() )
799 if( bSeriesFromColumns
)
801 aSimpleCategories
= xAnyDescriptionAccess
->getRowDescriptions();
802 aResult
.aComplexRowDescriptions
= xAnyDescriptionAccess
->getAnyRowDescriptions();
806 aSimpleCategories
= xAnyDescriptionAccess
->getColumnDescriptions();
807 aResult
.aComplexColumnDescriptions
= xAnyDescriptionAccess
->getAnyColumnDescriptions();
811 //series values and series labels
812 SchXMLExportHelper_Impl::tDataSequenceCont::size_type nNumSequences
= aSequencesToExport
.size();
813 SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator
aBegin( aSequencesToExport
.begin());
814 SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator
aEnd( aSequencesToExport
.end());
815 SchXMLExportHelper_Impl::tDataSequenceCont::const_iterator
aIt( aBegin
);
817 size_t nMaxSequenceLength( lcl_getMaxSequenceLength( aSequencesToExport
));
818 size_t nCategoriesLength( aSimpleCategories
.getLength() );
819 if( nCategoriesLength
> nMaxSequenceLength
)
821 aSimpleCategories
.realloc(nMaxSequenceLength
);//#i110617#
822 nCategoriesLength
= nMaxSequenceLength
;
824 size_t nNumColumns( bSeriesFromColumns
? nNumSequences
: nMaxSequenceLength
);
825 size_t nNumRows( bSeriesFromColumns
? nMaxSequenceLength
: nNumSequences
);
828 aResult
.aDataInRows
.resize( nNumRows
);
830 ::rtl::math::setNan( &fNan
);
831 ::std::for_each( aResult
.aDataInRows
.begin(), aResult
.aDataInRows
.end(),
832 lcl_resize
< t2DNumberContainer::value_type
>( nNumColumns
, fNan
));
833 aResult
.aColumnDescriptions
.resize( nNumColumns
);
834 aResult
.aComplexColumnDescriptions
.realloc( nNumColumns
);
835 aResult
.aRowDescriptions
.resize( nNumRows
);
836 aResult
.aComplexRowDescriptions
.realloc( nNumRows
);
838 tStringVector
& rCategories
= bSeriesFromColumns
? aResult
.aRowDescriptions
: aResult
.aColumnDescriptions
;
839 tStringVector
& rLabels
= bSeriesFromColumns
? aResult
.aColumnDescriptions
: aResult
.aRowDescriptions
;
842 lcl_SequenceToVector( aSimpleCategories
, rCategories
);
843 if( !rCategoriesRange
.isEmpty() )
845 OUString
aRange(rCategoriesRange
);
846 if( xRangeConversion
.is())
847 aRange
= xRangeConversion
->convertRangeToXML( aRange
);
848 if( bSeriesFromColumns
)
849 aResult
.aRowDescriptions_Ranges
.push_back( aRange
);
851 aResult
.aColumnDescriptions_Ranges
.push_back( aRange
);
854 // iterate over all sequences
856 Sequence
< Sequence
< OUString
> > aComplexLabels(nNumSequences
);
857 for( ; aIt
!= aEnd
; ++aIt
, ++nSeqIdx
)
860 Sequence
< OUString
>& rCurrentComplexLabel
= aComplexLabels
[nSeqIdx
];
863 lcl_getLabelStringSequence( rCurrentComplexLabel
, aIt
->first
);
864 rLabels
[nSeqIdx
] = lcl_flattenStringSequence( rCurrentComplexLabel
);
865 aRange
= aIt
->first
->getSourceRangeRepresentation();
866 if( xRangeConversion
.is())
867 aRange
= xRangeConversion
->convertRangeToXML( aRange
);
869 else if( aIt
->second
.is())
871 rCurrentComplexLabel
.realloc(1);
872 rLabels
[nSeqIdx
] = rCurrentComplexLabel
[0] = lcl_flattenStringSequence(
873 aIt
->second
->generateLabel( chart2::data::LabelOrigin_SHORT_SIDE
));
875 if( bSeriesFromColumns
)
876 aResult
.aColumnDescriptions_Ranges
.push_back( aRange
);
878 aResult
.aRowDescriptions_Ranges
.push_back( aRange
);
880 ::std::vector
< double > aNumbers( lcl_getAllValuesFromSequence( aIt
->second
));
881 if( bSeriesFromColumns
)
883 const sal_Int32
nSize( static_cast< sal_Int32
>( aNumbers
.size()));
884 for( sal_Int32 nIdx
=0; nIdx
<nSize
; ++nIdx
)
885 aResult
.aDataInRows
[nIdx
][nSeqIdx
] = aNumbers
[nIdx
];
888 aResult
.aDataInRows
[nSeqIdx
] = aNumbers
;
890 if( aIt
->second
.is())
892 aRange
= aIt
->second
->getSourceRangeRepresentation();
893 if( xRangeConversion
.is())
894 aRange
= xRangeConversion
->convertRangeToXML( aRange
);
896 aResult
.aDataRangeRepresentations
.push_back( aRange
);
899 if( !lcl_SequenceHasUnhiddenData(aIt
->first
) && !lcl_SequenceHasUnhiddenData(aIt
->second
) )
900 aResult
.aHiddenColumns
.push_back(nSeqIdx
);
902 Sequence
< Sequence
< Any
> >& rComplexAnyLabels
= bSeriesFromColumns
? aResult
.aComplexColumnDescriptions
: aResult
.aComplexRowDescriptions
;//#i116544#
903 rComplexAnyLabels
.realloc(aComplexLabels
.getLength());
904 for( sal_Int32 nN
=0; nN
<aComplexLabels
.getLength();nN
++ )
906 Sequence
< OUString
>& rSource
= aComplexLabels
[nN
];
907 Sequence
< Any
>& rTarget
= rComplexAnyLabels
[nN
];
908 rTarget
.realloc( rSource
.getLength() );
909 for( sal_Int32 i
=0; i
<rSource
.getLength(); i
++ )
910 rTarget
[i
] = uno::makeAny( rSource
[i
] );
913 catch( const uno::Exception
& rEx
)
915 SAL_INFO("xmloff.chart", "something went wrong during table data collection: " << rEx
.Message
);
921 void lcl_exportNumberFormat( const OUString
& rPropertyName
, const Reference
< beans::XPropertySet
>& xPropSet
,
922 SvXMLExport
& rExport
)
926 sal_Int32 nNumberFormat
= 0;
927 Any aNumAny
= xPropSet
->getPropertyValue( rPropertyName
);
928 if( (aNumAny
>>= nNumberFormat
) && (nNumberFormat
!= -1) )
929 rExport
.addDataStyle( nNumberFormat
);
933 ::std::vector
< Reference
< chart2::data::XDataSequence
> >
934 lcl_getErrorBarSequences( const Reference
< beans::XPropertySet
> & xErrorBarProp
)
936 ::std::vector
< Reference
< chart2::data::XDataSequence
> > aResult
;
937 Reference
< chart2::data::XDataSource
> xErrorBarDataSource( xErrorBarProp
, uno::UNO_QUERY
);
938 if( !xErrorBarDataSource
.is())
941 const OUString
aRolePrefix( "error-bars-" );
943 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSequences(
944 xErrorBarDataSource
->getDataSequences());
945 for( sal_Int32 nI
=0; nI
< aSequences
.getLength(); ++nI
)
949 if( aSequences
[nI
].is())
951 Reference
< chart2::data::XDataSequence
> xSequence( aSequences
[nI
]->getValues());
952 Reference
< beans::XPropertySet
> xSeqProp( xSequence
, uno::UNO_QUERY_THROW
);
954 if( ( xSeqProp
->getPropertyValue(
955 OUString( "Role" )) >>= aRole
) &&
956 aRole
.match( aRolePrefix
))
958 aResult
.push_back( xSequence
);
962 catch( const uno::Exception
& rEx
)
964 OString
aBStr(OUStringToOString(rEx
.Message
, RTL_TEXTENCODING_ASCII_US
));
965 SAL_INFO("xmloff.chart", "chart:exporting error bar ranges: " << aBStr
);
972 bool lcl_exportDomainForThisSequence( const Reference
< chart2::data::XDataSequence
> xValues
, OUString
& rFirstRangeForThisDomainIndex
, SvXMLExport
& rExport
)
974 bool bDomainExported
= false;
977 Reference
< chart2::XChartDocument
> xNewDoc( rExport
.GetModel(), uno::UNO_QUERY
);
978 OUString
aRange( lcl_ConvertRange( xValues
->getSourceRangeRepresentation(), xNewDoc
) );
980 //work around error in OOo 2.0 (problems with multiple series having a domain element)
981 if( rFirstRangeForThisDomainIndex
.isEmpty() || !aRange
.equals(rFirstRangeForThisDomainIndex
) )
983 rExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, aRange
);
984 SvXMLElementExport
aDomain( rExport
, XML_NAMESPACE_CHART
, XML_DOMAIN
, sal_True
, sal_True
);
985 bDomainExported
= true;
988 if( rFirstRangeForThisDomainIndex
.isEmpty() )
989 rFirstRangeForThisDomainIndex
= aRange
;
991 return bDomainExported
;
994 } // anonymous namespace
996 struct SchXMLDataPointStruct
998 OUString maStyleName
;
1001 SchXMLDataPointStruct() : mnRepeat( 1 ) {}
1004 // ========================================
1005 // class SchXMLExportHelper
1006 // ========================================
1008 SchXMLExportHelper::SchXMLExportHelper( SvXMLExport
& rExport
, SvXMLAutoStylePoolP
& rASPool
)
1009 : m_pImpl( new SchXMLExportHelper_Impl( rExport
, rASPool
) )
1013 SchXMLExportHelper::~SchXMLExportHelper()
1018 const OUString
& SchXMLExportHelper::getChartCLSID()
1020 return m_pImpl
->msCLSID
;
1023 UniReference
< XMLPropertySetMapper
> SchXMLExportHelper_Impl::GetPropertySetMapper() const
1025 return mxPropertySetMapper
;
1028 void SchXMLExportHelper_Impl::exportAutoStyles()
1030 if( mxExpPropMapper
.is())
1032 //ToDo: when embedded in calc/writer this is not necessary because the
1033 // numberformatter is shared between both documents
1034 mrExport
.exportAutoDataStyles();
1036 // export chart auto styles
1037 mrAutoStylePool
.exportXML(
1038 XML_STYLE_FAMILY_SCH_CHART_ID
1039 , mrExport
.GetDocHandler(),
1040 mrExport
.GetMM100UnitConverter(),
1041 mrExport
.GetNamespaceMap()
1044 // export auto styles for additional shapes
1045 mrExport
.GetShapeExport()->exportAutoStyles();
1046 // and for text in additional shapes
1047 mrExport
.GetTextParagraphExport()->exportTextAutoStyles();
1054 SchXMLExportHelper_Impl::SchXMLExportHelper_Impl(
1055 SvXMLExport
& rExport
,
1056 SvXMLAutoStylePoolP
& rASPool
) :
1057 mrExport( rExport
),
1058 mrAutoStylePool( rASPool
),
1059 mbHasSeriesLabels( sal_False
),
1060 mbHasCategoryLabels( sal_False
),
1061 mbRowSourceColumns( sal_True
),
1062 msCLSID( OUString( SvGlobalName( SO3_SCH_CLASSID
).GetHexName()))
1064 msTableName
= OUString( "local-table" );
1066 // create property set mapper
1067 mxPropertySetMapper
= new XMLChartPropertySetMapper( true);
1068 mxExpPropMapper
= new XMLChartExportPropertyMapper( mxPropertySetMapper
, rExport
);
1070 // register chart auto-style family
1071 mrAutoStylePool
.AddFamily(
1072 XML_STYLE_FAMILY_SCH_CHART_ID
,
1073 OUString( XML_STYLE_FAMILY_SCH_CHART_NAME
),
1074 mxExpPropMapper
.get(),
1075 OUString( XML_STYLE_FAMILY_SCH_CHART_PREFIX
));
1077 // register shape family
1078 mrAutoStylePool
.AddFamily(
1079 XML_STYLE_FAMILY_SD_GRAPHICS_ID
,
1080 OUString( XML_STYLE_FAMILY_SD_GRAPHICS_NAME
),
1081 mxExpPropMapper
.get(),
1082 OUString( XML_STYLE_FAMILY_SD_GRAPHICS_PREFIX
));
1083 // register paragraph family also for shapes
1084 mrAutoStylePool
.AddFamily(
1085 XML_STYLE_FAMILY_TEXT_PARAGRAPH
,
1086 GetXMLToken( XML_PARAGRAPH
),
1087 mxExpPropMapper
.get(),
1089 // register text family also for shapes
1090 mrAutoStylePool
.AddFamily(
1091 XML_STYLE_FAMILY_TEXT_TEXT
,
1092 GetXMLToken( XML_TEXT
),
1093 mxExpPropMapper
.get(),
1097 SchXMLExportHelper_Impl::~SchXMLExportHelper_Impl()
1101 void SchXMLExportHelper_Impl::collectAutoStyles( Reference
< chart::XChartDocument
> rChartDoc
)
1103 parseDocument( rChartDoc
, sal_False
);
1106 void SchXMLExportHelper_Impl::exportChart( Reference
< chart::XChartDocument
> rChartDoc
,
1107 sal_Bool bIncludeTable
)
1109 parseDocument( rChartDoc
, sal_True
, bIncludeTable
);
1110 SAL_WARN_IF( !maAutoStyleNameQueue
.empty(), "xmloff.chart", "There are still remaining autostyle names in the queue" );
1113 static OUString
lcl_GetStringFromNumberSequence( const ::com::sun::star::uno::Sequence
< sal_Int32
>& rSequenceMapping
, bool bRemoveOneFromEachIndex
/*should be true if having categories*/ )
1115 const sal_Int32
* pArray
= rSequenceMapping
.getConstArray();
1116 const sal_Int32 nSize
= rSequenceMapping
.getLength();
1118 OUStringBuffer aBuf
;
1119 bool bHasPredecessor
= false;
1120 for( i
= 0; i
< nSize
; ++i
)
1122 sal_Int32 nIndex
= pArray
[ i
];
1123 if( bRemoveOneFromEachIndex
)
1128 aBuf
.append( static_cast< sal_Unicode
>( ' ' ));
1129 aBuf
.append( nIndex
, 10 );
1130 bHasPredecessor
= true;
1133 return aBuf
.makeStringAndClear();
1136 /// if bExportContent is false the auto-styles are collected
1137 void SchXMLExportHelper_Impl::parseDocument( Reference
< chart::XChartDocument
>& rChartDoc
,
1138 sal_Bool bExportContent
,
1139 sal_Bool bIncludeTable
)
1141 Reference
< chart2::XChartDocument
> xNewDoc( rChartDoc
, uno::UNO_QUERY
);
1142 if( !rChartDoc
.is() || !xNewDoc
.is() )
1144 SAL_WARN("xmloff.chart", "No XChartDocument was given for export." );
1148 mxExpPropMapper
->setChartDoc(xNewDoc
);
1150 awt::Size
aPageSize( getPageSize( xNewDoc
));
1151 if( bExportContent
)
1152 addSize( aPageSize
);
1153 Reference
< chart::XDiagram
> xDiagram
= rChartDoc
->getDiagram();
1154 Reference
< chart2::XDiagram
> xNewDiagram
;
1156 xNewDiagram
.set( xNewDoc
->getFirstDiagram());
1158 //todo remove if model changes are notified and view is updated automatically
1159 if( bExportContent
)
1161 Reference
< util::XRefreshable
> xRefreshable( xNewDoc
, uno::UNO_QUERY
);
1162 if( xRefreshable
.is() )
1163 xRefreshable
->refresh();
1166 // get Properties of ChartDocument
1167 sal_Bool bHasMainTitle
= sal_False
;
1168 sal_Bool bHasSubTitle
= sal_False
;
1169 sal_Bool bHasLegend
= sal_False
;
1170 util::DateTime
aNullDate(0,0,0,0,30,12,1899, false);
1172 std::vector
< XMLPropertyState
> aPropertyStates
;
1174 Reference
< beans::XPropertySet
> xDocPropSet( rChartDoc
, uno::UNO_QUERY
);
1175 if( xDocPropSet
.is())
1179 Any
aAny( xDocPropSet
->getPropertyValue(
1180 OUString( "HasMainTitle" )));
1181 aAny
>>= bHasMainTitle
;
1182 aAny
= xDocPropSet
->getPropertyValue(
1183 OUString( "HasSubTitle" ));
1184 aAny
>>= bHasSubTitle
;
1185 aAny
= xDocPropSet
->getPropertyValue(
1186 OUString( "HasLegend" ));
1187 aAny
>>= bHasLegend
;
1188 if ( bIncludeTable
)
1190 OUString
sNullDate( "NullDate" );
1191 aAny
= xDocPropSet
->getPropertyValue(sNullDate
);
1192 if ( !aAny
.hasValue() )
1194 Reference
<container::XChild
> xChild(rChartDoc
, uno::UNO_QUERY
);
1197 Reference
< beans::XPropertySet
> xParentDoc( xChild
->getParent(),uno::UNO_QUERY
);
1198 if ( xParentDoc
.is() && xParentDoc
->getPropertySetInfo()->hasPropertyByName(sNullDate
) )
1199 aAny
= xParentDoc
->getPropertyValue(sNullDate
);
1206 catch( const beans::UnknownPropertyException
& )
1208 SAL_WARN("xmloff.chart", "Required property not found in ChartDocument" );
1212 if ( bIncludeTable
&& (aNullDate
.Day
!= 30 || aNullDate
.Month
!= 12 || aNullDate
.Year
!= 1899 ) )
1214 SvXMLElementExport
aSet( mrExport
, XML_NAMESPACE_TABLE
, XML_CALCULATION_SETTINGS
, sal_True
, sal_True
);
1216 OUStringBuffer sBuffer
;
1217 ::sax::Converter::convertDateTime(sBuffer
, aNullDate
);
1218 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
,XML_DATE_VALUE
,sBuffer
.makeStringAndClear());
1219 SvXMLElementExport
aNull( mrExport
, XML_NAMESPACE_TABLE
, XML_NULL_DATE
, sal_True
, sal_True
);
1226 SvXMLElementExport
* pElChart
= 0;
1227 // get property states for autostyles
1228 if( mxExpPropMapper
.is())
1230 Reference
< beans::XPropertySet
> xPropSet( rChartDoc
->getArea(), uno::UNO_QUERY
);
1232 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1235 if( bExportContent
)
1237 //export data provider in xlink:href attribute
1238 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
1239 if( nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
)
1241 OUString
aDataProviderURL( ".." );
1242 if( xNewDoc
->hasInternalDataProvider() )
1243 aDataProviderURL
= OUString( "." );
1244 else //special handling for data base data provider necessary
1246 Reference
< chart2::data::XDatabaseDataProvider
> xDBDataProvider( xNewDoc
->getDataProvider(), uno::UNO_QUERY
);
1247 if( xDBDataProvider
.is() )
1248 aDataProviderURL
= OUString( "." );
1250 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, aDataProviderURL
);
1251 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
1254 OUString
sChartType( xDiagram
->getDiagramType() );
1258 if( !sChartType
.isEmpty())
1260 enum XMLTokenEnum eXMLChartType
= SchXMLTools::getTokenByChartType( sChartType
, true /* bUseOldNames */ );
1262 SAL_WARN_IF( eXMLChartType
== XML_TOKEN_INVALID
, "xmloff.chart", "invalid chart class" );
1263 if( eXMLChartType
== XML_TOKEN_INVALID
)
1264 eXMLChartType
= XML_BAR
;
1266 if( eXMLChartType
== XML_ADD_IN
)
1268 // sChartType is the servie-name of the add-in
1269 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_CLASS
,
1270 mrExport
.GetNamespaceMap().GetQNameByKey(
1271 XML_NAMESPACE_OOO
, sChartType
) );
1273 else if( eXMLChartType
!= XML_TOKEN_INVALID
)
1275 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_CLASS
,
1276 mrExport
.GetNamespaceMap().GetQNameByKey(
1277 XML_NAMESPACE_CHART
, GetXMLToken(eXMLChartType
)) );
1280 //column-mapping or row-mapping
1281 if( maSequenceMapping
.getLength() )
1283 enum XMLTokenEnum eTransToken
= ::xmloff::token::XML_ROW_MAPPING
;
1284 if( mbRowSourceColumns
)
1285 eTransToken
= ::xmloff::token::XML_COLUMN_MAPPING
;
1286 OUString
aSequenceMappingStr( lcl_GetStringFromNumberSequence(
1287 maSequenceMapping
, mbHasCategoryLabels
&& !xNewDoc
->hasInternalDataProvider() ) );
1289 mrExport
.AddAttribute( XML_NAMESPACE_CHART
,
1290 ::xmloff::token::GetXMLToken( eTransToken
),
1291 aSequenceMappingStr
);
1295 AddAutoStyleAttribute( aPropertyStates
);
1298 pElChart
= new SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_CHART
, sal_True
, sal_True
);
1302 CollectAutoStyle( aPropertyStates
);
1304 // remove property states for autostyles
1305 aPropertyStates
.clear();
1312 // get property states for autostyles
1313 if( mxExpPropMapper
.is())
1315 Reference
< beans::XPropertySet
> xPropSet( rChartDoc
->getTitle(), uno::UNO_QUERY
);
1317 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1319 if( bExportContent
)
1321 Reference
< drawing::XShape
> xShape
= rChartDoc
->getTitle();
1322 if( xShape
.is()) // && "hasTitleBeenMoved"
1323 addPosition( xShape
);
1326 AddAutoStyleAttribute( aPropertyStates
);
1329 SvXMLElementExport
aElTitle( mrExport
, XML_NAMESPACE_CHART
, XML_TITLE
, sal_True
, sal_True
);
1332 Reference
< beans::XPropertySet
> xPropSet( xShape
, uno::UNO_QUERY
);
1335 Any
aAny( xPropSet
->getPropertyValue(
1336 OUString( "String" )));
1339 exportText( aText
);
1344 CollectAutoStyle( aPropertyStates
);
1346 // remove property states for autostyles
1347 aPropertyStates
.clear();
1355 // get property states for autostyles
1356 if( mxExpPropMapper
.is())
1358 Reference
< beans::XPropertySet
> xPropSet( rChartDoc
->getSubTitle(), uno::UNO_QUERY
);
1360 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1363 if( bExportContent
)
1365 Reference
< drawing::XShape
> xShape
= rChartDoc
->getSubTitle();
1367 addPosition( xShape
);
1370 AddAutoStyleAttribute( aPropertyStates
);
1372 // element (has no subelements)
1373 SvXMLElementExport
aElSubTitle( mrExport
, XML_NAMESPACE_CHART
, XML_SUBTITLE
, sal_True
, sal_True
);
1376 Reference
< beans::XPropertySet
> xPropSet( xShape
, uno::UNO_QUERY
);
1379 Any
aAny( xPropSet
->getPropertyValue(
1380 OUString( "String" )));
1383 exportText( aText
);
1388 CollectAutoStyle( aPropertyStates
);
1390 // remove property states for autostyles
1391 aPropertyStates
.clear();
1398 // get property states for autostyles
1399 if( mxExpPropMapper
.is())
1401 Reference
< beans::XPropertySet
> xPropSet( rChartDoc
->getLegend(), uno::UNO_QUERY
);
1403 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1406 if( bExportContent
)
1408 Reference
< beans::XPropertySet
> xProp( rChartDoc
->getLegend(), uno::UNO_QUERY
);
1411 // export legend anchor position
1414 Any
aAny( xProp
->getPropertyValue( OUString( "Alignment" )));
1415 if( SchXMLEnumConverter::getLegendPositionConverter().exportXML( msString
, aAny
, mrExport
.GetMM100UnitConverter() ) )
1416 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LEGEND_POSITION
, msString
);
1418 catch( const beans::UnknownPropertyException
& )
1420 SAL_WARN("xmloff.chart", "Property Align not found in ChartLegend" );
1423 // export absolute legend position
1424 Reference
< drawing::XShape
> xLegendShape( xProp
, uno::UNO_QUERY
);
1425 addPosition( xLegendShape
);
1427 // export legend size
1428 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
1429 if( xLegendShape
.is() && nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
)
1433 chart::ChartLegendExpansion nLegendExpansion
= chart::ChartLegendExpansion_HIGH
;
1434 OUString aExpansionString
;
1435 Any
aAny( xProp
->getPropertyValue( OUString( "Expansion" )));
1436 bool bHasExpansion
= (aAny
>>= nLegendExpansion
);
1437 if( bHasExpansion
&& SchXMLEnumConverter::getLegendExpansionConverter().exportXML( aExpansionString
, aAny
, mrExport
.GetMM100UnitConverter() ) )
1439 mrExport
.AddAttribute( XML_NAMESPACE_STYLE
, XML_LEGEND_EXPANSION
, aExpansionString
);
1440 if( nLegendExpansion
== chart::ChartLegendExpansion_CUSTOM
)
1442 awt::Size
aSize( xLegendShape
->getSize() );
1443 addSize( aSize
, true );
1444 OUStringBuffer aAspectRatioString
;
1445 ::sax::Converter::convertDouble(
1447 double(aSize
.Width
)/double(aSize
.Height
));
1448 mrExport
.AddAttribute( XML_NAMESPACE_STYLE
, XML_LEGEND_EXPANSION_ASPECT_RATIO
, aAspectRatioString
.makeStringAndClear() );
1452 catch( const beans::UnknownPropertyException
& )
1454 SAL_WARN("xmloff.chart", "Property Expansion not found in ChartLegend" );
1460 AddAutoStyleAttribute( aPropertyStates
);
1463 SvXMLElementExport
aLegend( mrExport
, XML_NAMESPACE_CHART
, XML_LEGEND
, sal_True
, sal_True
);
1467 CollectAutoStyle( aPropertyStates
);
1469 // remove property states for autostyles
1470 aPropertyStates
.clear();
1473 // plot-area element
1474 // -----------------
1476 exportPlotArea( xDiagram
, xNewDiagram
, aPageSize
, bExportContent
, bIncludeTable
);
1478 // export additional shapes
1479 // ------------------------
1480 if( xDocPropSet
.is() )
1482 if( bExportContent
)
1484 if( mxAdditionalShapes
.is())
1486 // can't call exportShapes with all shapes because the
1487 // initialisation happened with the complete draw page and not
1488 // the XShapes object used here. Thus the shapes have to be
1489 // exported one by one
1490 UniReference
< XMLShapeExport
> rShapeExport
= mrExport
.GetShapeExport();
1491 Reference
< drawing::XShape
> xShape
;
1492 const sal_Int32
nShapeCount( mxAdditionalShapes
->getCount());
1493 for( sal_Int32 nShapeId
= 0; nShapeId
< nShapeCount
; nShapeId
++ )
1495 mxAdditionalShapes
->getByIndex( nShapeId
) >>= xShape
;
1496 SAL_WARN_IF( !xShape
.is(), "xmloff.chart", "Shape without an XShape?" );
1500 rShapeExport
->exportShape( xShape
);
1502 // this would be the easier way if it worked:
1503 //mrExport.GetShapeExport()->exportShapes( mxAdditionalShapes );
1508 // get a sequence of non-chart shapes (inserted via clipboard)
1511 Any aShapesAny
= xDocPropSet
->getPropertyValue( OUString( "AdditionalShapes" ));
1512 aShapesAny
>>= mxAdditionalShapes
;
1514 catch( const uno::Exception
& rEx
)
1516 SAL_INFO("xmloff.chart", "AdditionalShapes not found: " << rEx
.Message
);
1519 if( mxAdditionalShapes
.is())
1521 // seek shapes has to be called for the whole page because in
1522 // the shape export the vector of shapes is accessed via the
1523 // ZOrder which might be (actually is) larger than the number of
1524 // shapes in mxAdditionalShapes
1525 Reference
< drawing::XDrawPageSupplier
> xSupplier( rChartDoc
, uno::UNO_QUERY
);
1526 SAL_WARN_IF( !xSupplier
.is(), "xmloff.chart", "Cannot retrieve draw page to initialize shape export" );
1527 if( xSupplier
.is() )
1529 Reference
< drawing::XShapes
> xDrawPage( xSupplier
->getDrawPage(), uno::UNO_QUERY
);
1530 SAL_WARN_IF( !xDrawPage
.is(), "xmloff.chart", "Invalid draw page for initializing shape export" );
1532 mrExport
.GetShapeExport()->seekShapes( xDrawPage
);
1535 // can't call collectShapesAutoStyles with all shapes because
1536 // the initialisation happened with the complete draw page and
1537 // not the XShapes object used here. Thus the shapes have to be
1538 // exported one by one
1539 UniReference
< XMLShapeExport
> rShapeExport
= mrExport
.GetShapeExport();
1540 Reference
< drawing::XShape
> xShape
;
1541 const sal_Int32
nShapeCount( mxAdditionalShapes
->getCount());
1542 for( sal_Int32 nShapeId
= 0; nShapeId
< nShapeCount
; nShapeId
++ )
1544 mxAdditionalShapes
->getByIndex( nShapeId
) >>= xShape
;
1545 SAL_WARN_IF( !xShape
.is(), "xmloff.chart", "Shape without an XShape?" );
1549 rShapeExport
->collectShapeAutoStyles( xShape
);
1556 // (is included as subelement of chart)
1557 // ------------------------------------
1558 if( bExportContent
)
1560 // #85929# always export table, otherwise clipboard may loose data
1564 // close <chart:chart> element
1569 static void lcl_exportComplexLabel( const Sequence
< uno::Any
>& rComplexLabel
, SvXMLExport
& rExport
)
1571 sal_Int32 nLength
= rComplexLabel
.getLength();
1574 SvXMLElementExport
aTextList( rExport
, XML_NAMESPACE_TEXT
, XML_LIST
, sal_True
, sal_True
);
1575 for(sal_Int32 nN
=0; nN
<nLength
; nN
++)
1577 SvXMLElementExport
aListItem( rExport
, XML_NAMESPACE_TEXT
, XML_LIST_ITEM
, sal_True
, sal_True
);
1579 if( !(rComplexLabel
[nN
]>>=aString
) )
1583 SchXMLTools::exportText( rExport
, aString
, false /*bConvertTabsLFs*/ );
1587 void SchXMLExportHelper_Impl::exportTable()
1591 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_NAME
, msTableName
);
1595 bool bProtected
= false;
1596 Reference
< beans::XPropertySet
> xProps( mrExport
.GetModel(), uno::UNO_QUERY_THROW
);
1597 if ( ( xProps
->getPropertyValue( OUString( "DisableDataTableDialog" ) ) >>= bProtected
) &&
1600 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_PROTECTED
, XML_TRUE
);
1603 catch ( const uno::Exception
& )
1607 SvXMLElementExport
aTable( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE
, sal_True
, sal_True
);
1609 bool bHasOwnData
= false;
1610 Reference
< chart2::XChartDocument
> xNewDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
1611 Reference
< chart2::data::XRangeXMLConversion
> xRangeConversion
;
1614 bHasOwnData
= xNewDoc
->hasInternalDataProvider();
1615 xRangeConversion
.set( xNewDoc
->getDataProvider(), uno::UNO_QUERY
);
1618 Reference
< chart2::XAnyDescriptionAccess
> xAnyDescriptionAccess
;
1620 Reference
< chart::XChartDocument
> xChartDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
1621 if( xChartDoc
.is() )
1622 xAnyDescriptionAccess
= Reference
< chart2::XAnyDescriptionAccess
>( xChartDoc
->getData(), uno::UNO_QUERY
);
1626 lcl_ReorderInternalSequencesAccordingToTheirRangeName( m_aDataSequencesToExport
);
1627 lcl_TableData
aData( lcl_getDataForLocalTable( m_aDataSequencesToExport
1628 , xAnyDescriptionAccess
, maCategoriesRange
1629 , mbRowSourceColumns
, xRangeConversion
));
1631 tStringVector::const_iterator
aDataRangeIter( aData
.aDataRangeRepresentations
.begin());
1632 const tStringVector::const_iterator
aDataRangeEndIter( aData
.aDataRangeRepresentations
.end());
1634 tStringVector::const_iterator
aRowDescriptions_RangeIter( aData
.aRowDescriptions_Ranges
.begin());
1635 const tStringVector::const_iterator
aRowDescriptions_RangeEnd( aData
.aRowDescriptions_Ranges
.end());
1639 SvXMLElementExport
aHeaderColumns( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_COLUMNS
, sal_True
, sal_True
);
1640 SvXMLElementExport
aHeaderColumn( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, sal_True
, sal_True
);
1643 SvXMLElementExport
aColumns( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMNS
, sal_True
, sal_True
);
1645 sal_Int32 nNextIndex
= 0;
1646 for( size_t nN
=0; nN
< aData
.aHiddenColumns
.size(); nN
++ )
1648 //i91578 display of hidden values (copy paste scenario; export hidden flag thus it can be used during migration to locale table upon paste )
1649 sal_Int32 nHiddenIndex
= aData
.aHiddenColumns
[nN
];
1650 if( nHiddenIndex
> nNextIndex
)
1652 sal_Int64 nRepeat
= static_cast< sal_Int64
>( nHiddenIndex
- nNextIndex
);
1654 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
,
1655 OUString::valueOf( nRepeat
));
1656 SvXMLElementExport
aColumn( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, sal_True
, sal_True
);
1658 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_VISIBILITY
, GetXMLToken( XML_COLLAPSE
) );
1659 SvXMLElementExport
aColumn( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, sal_True
, sal_True
);
1660 nNextIndex
= nHiddenIndex
+1;
1663 sal_Int32 nEndIndex
= aData
.aColumnDescriptions
.size()-1;
1664 if( nEndIndex
>= nNextIndex
)
1666 sal_Int64 nRepeat
= static_cast< sal_Int64
>( nEndIndex
- nNextIndex
+ 1 );
1668 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
,
1669 OUString::valueOf( nRepeat
));
1670 SvXMLElementExport
aColumn( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, sal_True
, sal_True
);
1674 // export rows with content
1677 SvXMLElementExport
aHeaderRows( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_ROWS
, sal_True
, sal_True
);
1678 SvXMLElementExport
aRow( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, sal_True
, sal_True
);
1680 //first one empty cell for the row descriptions
1682 SvXMLElementExport
aEmptyCell( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, sal_True
, sal_True
);
1683 SvXMLElementExport
aEmptyParagraph( mrExport
, XML_NAMESPACE_TEXT
, XML_P
, sal_True
, sal_True
);
1686 //export column descriptions
1687 tStringVector::const_iterator
aColumnDescriptions_RangeIter( aData
.aColumnDescriptions_Ranges
.begin());
1688 const tStringVector::const_iterator
aColumnDescriptions_RangeEnd( aData
.aColumnDescriptions_Ranges
.end());
1689 const Sequence
< Sequence
< uno::Any
> >& rComplexColumnDescriptions
= aData
.aComplexColumnDescriptions
;
1690 sal_Int32 nComplexCount
= rComplexColumnDescriptions
.getLength();
1692 for( tStringVector::const_iterator
aIt( aData
.aColumnDescriptions
.begin())
1693 ; (aIt
!= aData
.aColumnDescriptions
.end())
1696 bool bExportString
= true;
1697 if( nC
< nComplexCount
)
1699 const Sequence
< uno::Any
>& rComplexLabel
= rComplexColumnDescriptions
[nC
];
1700 if( rComplexLabel
.getLength()>0 )
1703 if( rComplexLabel
[0] >>=fValue
)
1705 bExportString
= false;
1707 ::sax::Converter::convertDouble(
1708 msStringBuffer
, fValue
);
1709 msString
= msStringBuffer
.makeStringAndClear();
1710 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
1711 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE
, msString
);
1717 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_STRING
);
1720 SvXMLElementExport
aCell( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, sal_True
, sal_True
);
1722 if( nC
< nComplexCount
)
1723 lcl_exportComplexLabel( rComplexColumnDescriptions
[nC
], mrExport
);
1724 if( !bHasOwnData
&& aColumnDescriptions_RangeIter
!= aColumnDescriptions_RangeEnd
)
1726 // remind the original range to allow a correct re-association when copying via clipboard
1727 if (!(*aColumnDescriptions_RangeIter
).isEmpty())
1728 SchXMLTools::exportRangeToSomewhere( mrExport
, *aColumnDescriptions_RangeIter
);
1729 ++aColumnDescriptions_RangeIter
;
1732 SAL_WARN_IF( !bHasOwnData
&& (aColumnDescriptions_RangeIter
!= aColumnDescriptions_RangeEnd
), "xmloff.chart", "bHasOwnData == false && aColumnDescriptions_RangeIter != aColumnDescriptions_RangeEnd" );
1733 } // closing row and header-rows elements
1735 // export value rows
1737 SvXMLElementExport
aRows( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_ROWS
, sal_True
, sal_True
);
1738 tStringVector::const_iterator
aRowDescriptionsIter( aData
.aRowDescriptions
.begin());
1739 const Sequence
< Sequence
< uno::Any
> >& rComplexRowDescriptions
= aData
.aComplexRowDescriptions
;
1740 sal_Int32 nComplexCount
= rComplexRowDescriptions
.getLength();
1743 for( t2DNumberContainer::const_iterator
aRowIt( aData
.aDataInRows
.begin())
1744 ; aRowIt
!= aData
.aDataInRows
.end()
1747 SvXMLElementExport
aRow( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, sal_True
, sal_True
);
1749 //export row descriptions
1751 bool bExportString
= true;
1752 if( nC
< nComplexCount
)
1754 const Sequence
< uno::Any
>& rComplexLabel
= rComplexRowDescriptions
[nC
];
1755 if( rComplexLabel
.getLength()>0 )
1758 if( rComplexLabel
[0] >>=fValue
)
1760 bExportString
= false;
1762 ::sax::Converter::convertDouble(msStringBuffer
, fValue
);
1763 msString
= msStringBuffer
.makeStringAndClear();
1764 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
1765 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE
, msString
);
1771 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_STRING
);
1774 SvXMLElementExport
aCell( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, sal_True
, sal_True
);
1775 if( aRowDescriptionsIter
!= aData
.aRowDescriptions
.end())
1777 exportText( *aRowDescriptionsIter
);
1778 if( nC
< nComplexCount
)
1779 lcl_exportComplexLabel( rComplexRowDescriptions
[nC
], mrExport
);
1780 if( !bHasOwnData
&& aRowDescriptions_RangeIter
!= aRowDescriptions_RangeEnd
)
1782 // remind the original range to allow a correct re-association when copying via clipboard
1783 SchXMLTools::exportRangeToSomewhere( mrExport
, *aRowDescriptions_RangeIter
);
1784 ++aRowDescriptions_RangeIter
;
1786 ++aRowDescriptionsIter
;
1791 for( t2DNumberContainer::value_type::const_iterator
aColIt( aRowIt
->begin());
1792 aColIt
!= aRowIt
->end(); ++aColIt
)
1794 ::sax::Converter::convertDouble( msStringBuffer
, *aColIt
);
1795 msString
= msStringBuffer
.makeStringAndClear();
1796 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
1797 mrExport
.AddAttribute( XML_NAMESPACE_OFFICE
, XML_VALUE
, msString
);
1798 SvXMLElementExport
aCell( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, sal_True
, sal_True
);
1799 exportText( msString
, false ); // do not convert tabs and lfs
1800 if( ( !bHasOwnData
&& aDataRangeIter
!= aDataRangeEndIter
) &&
1801 ( mbRowSourceColumns
|| (aColIt
== aRowIt
->begin()) ) )
1803 // remind the original range to allow a correct re-association when copying via clipboard
1804 if (!(*aDataRangeIter
).isEmpty())
1805 SchXMLTools::exportRangeToSomewhere( mrExport
, *aDataRangeIter
);
1812 // if range iterator was used it should have reached its end
1813 SAL_WARN_IF( !bHasOwnData
&& (aDataRangeIter
!= aDataRangeEndIter
), "xmloff.chart", "bHasOwnData == false && aDataRangeIter != aDataRangeEndIter" );
1814 SAL_WARN_IF( !bHasOwnData
&& (aRowDescriptions_RangeIter
!= aRowDescriptions_RangeEnd
), "xmloff.chart", "bHasOwnData == false && aRowDescriptions_RangeIter != aRowDescriptions_RangeEnd" );
1820 Reference
< chart2::XCoordinateSystem
> lcl_getCooSys( const Reference
< chart2::XDiagram
> & xNewDiagram
)
1822 Reference
< chart2::XCoordinateSystem
> xCooSys
;
1823 Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt( xNewDiagram
, uno::UNO_QUERY
);
1826 Sequence
< Reference
< chart2::XCoordinateSystem
> > aCooSysSeq( xCooSysCnt
->getCoordinateSystems() );
1827 if(aCooSysSeq
.getLength()>0)
1828 xCooSys
= aCooSysSeq
[0];
1833 Reference
< chart2::XAxis
> lcl_getAxis( const Reference
< chart2::XCoordinateSystem
>& xCooSys
,
1834 enum XMLTokenEnum eDimension
, bool bPrimary
=true )
1836 Reference
< chart2::XAxis
> xNewAxis
;
1841 sal_Int32 nDimensionIndex
=0;
1842 switch( eDimension
)
1857 xNewAxis
= xCooSys
->getAxisByDimension( nDimensionIndex
, bPrimary
? 0 : 1 );
1860 catch( const uno::Exception
& )
1868 void SchXMLExportHelper_Impl::exportPlotArea(
1869 Reference
< chart::XDiagram
> xDiagram
,
1870 Reference
< chart2::XDiagram
> xNewDiagram
,
1871 const awt::Size
& rPageSize
,
1872 sal_Bool bExportContent
,
1873 sal_Bool bIncludeTable
)
1875 SAL_WARN_IF( !xDiagram
.is(), "xmloff.chart", "Invalid XDiagram as parameter" );
1876 if( ! xDiagram
.is())
1879 // variables for autostyles
1880 Reference
< beans::XPropertySet
> xPropSet
;
1881 std::vector
< XMLPropertyState
> aPropertyStates
;
1883 sal_Bool bIs3DChart
= sal_False
;
1884 drawing::HomogenMatrix aTransMatrix
;
1886 msStringBuffer
.setLength( 0 );
1888 // plot-area element
1889 // -----------------
1891 SvXMLElementExport
* pElPlotArea
= 0;
1892 // get property states for autostyles
1893 xPropSet
= Reference
< beans::XPropertySet
>( xDiagram
, uno::UNO_QUERY
);
1896 if( mxExpPropMapper
.is())
1897 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
1899 if( bExportContent
)
1901 UniReference
< XMLShapeExport
> rShapeExport
;
1904 AddAutoStyleAttribute( aPropertyStates
);
1906 if( !msChartAddress
.isEmpty() )
1908 if( !bIncludeTable
)
1909 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, msChartAddress
);
1911 Reference
< chart::XChartDocument
> xDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
1914 Reference
< beans::XPropertySet
> xDocProp( xDoc
, uno::UNO_QUERY
);
1918 sal_Bool bFirstCol
= false, bFirstRow
= false;
1922 aAny
= xDocProp
->getPropertyValue(
1923 OUString( "DataSourceLabelsInFirstColumn" ));
1925 aAny
= xDocProp
->getPropertyValue(
1926 OUString( "DataSourceLabelsInFirstRow" ));
1929 if( bFirstCol
|| bFirstRow
)
1931 mrExport
.AddAttribute( XML_NAMESPACE_CHART
,
1932 ::xmloff::token::GetXMLToken( ::xmloff::token::XML_DATA_SOURCE_HAS_LABELS
),
1935 ? ::xmloff::token::GetXMLToken( ::xmloff::token::XML_BOTH
)
1936 : ::xmloff::token::GetXMLToken( ::xmloff::token::XML_COLUMN
))
1937 : ::xmloff::token::GetXMLToken( ::xmloff::token::XML_ROW
)));
1940 catch( const beans::UnknownPropertyException
& )
1942 SAL_WARN("xmloff.chart", "Properties missing" );
1948 // #i72973#, #144135# only export table-number-list in OOo format (also for binary)
1949 Reference
< beans::XPropertySet
> xExportInfo( mrExport
.getExportInfo());
1950 if( !msTableNumberList
.isEmpty() && xExportInfo
.is())
1954 OUString
sExportTableNumListPropName( "ExportTableNumberList");
1955 Reference
< beans::XPropertySetInfo
> xInfo( xExportInfo
->getPropertySetInfo());
1956 bool bExportTableNumberList
= false;
1957 if( xInfo
.is() && xInfo
->hasPropertyByName( sExportTableNumListPropName
) &&
1958 (xExportInfo
->getPropertyValue( sExportTableNumListPropName
) >>= bExportTableNumberList
) &&
1959 bExportTableNumberList
)
1961 // this attribute is for charts embedded in calc documents only.
1962 // With this you are able to store a file again in 5.0 binary format
1963 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_TABLE_NUMBER_LIST
, msTableNumberList
);
1966 catch( const uno::Exception
& rEx
)
1968 OString
aBStr(OUStringToOString(rEx
.Message
, RTL_TEXTENCODING_ASCII_US
));
1969 SAL_INFO("xmloff.chart", "chart:TableNumberList property caught: " << aBStr
);
1974 Reference
< drawing::XShape
> xShape ( xDiagram
, uno::UNO_QUERY
);
1977 addPosition( xShape
);
1988 aAny
= xPropSet
->getPropertyValue( OUString( "Dim3D" ));
1989 aAny
>>= bIs3DChart
;
1993 rShapeExport
= mrExport
.GetShapeExport();
1994 if( rShapeExport
.is())
1995 rShapeExport
->export3DSceneAttributes( xPropSet
);
1998 catch( const uno::Exception
& rEx
)
2000 OString
aBStr(OUStringToOString(rEx
.Message
, RTL_TEXTENCODING_ASCII_US
));
2001 SAL_INFO("xmloff.chart", "chart:exportPlotAreaException caught: " << aBStr
);
2005 // plot-area element
2006 pElPlotArea
= new SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_PLOT_AREA
, sal_True
, sal_True
);
2008 //inner position rectangle element
2009 exportCoordinateRegion( xDiagram
);
2011 // light sources (inside plot area element)
2014 rShapeExport
->export3DLamps( xPropSet
);
2018 CollectAutoStyle( aPropertyStates
);
2020 // remove property states for autostyles
2021 aPropertyStates
.clear();
2025 exportAxes( xDiagram
, xNewDiagram
, bExportContent
);
2029 Reference
< chart2::XAxis
> xSecondYAxis
= lcl_getAxis( lcl_getCooSys( xNewDiagram
), XML_Y
, false );
2030 exportSeries( xNewDiagram
, rPageSize
, bExportContent
, xSecondYAxis
.is() );
2032 // stock-chart elements
2033 OUString
sChartType ( xDiagram
->getDiagramType());
2034 if( 0 == sChartType
.reverseCompareTo( "com.sun.star.chart.StockDiagram" ))
2036 Reference
< chart::XStatisticDisplay
> xStockPropProvider( xDiagram
, uno::UNO_QUERY
);
2037 if( xStockPropProvider
.is())
2039 // stock-gain-marker
2040 Reference
< beans::XPropertySet
> xStockPropSet
= xStockPropProvider
->getUpBar();
2041 if( xStockPropSet
.is())
2043 aPropertyStates
.clear();
2044 aPropertyStates
= mxExpPropMapper
->Filter( xStockPropSet
);
2046 if( !aPropertyStates
.empty() )
2048 if( bExportContent
)
2050 AddAutoStyleAttribute( aPropertyStates
);
2052 SvXMLElementExport
aGain( mrExport
, XML_NAMESPACE_CHART
, XML_STOCK_GAIN_MARKER
, sal_True
, sal_True
);
2056 CollectAutoStyle( aPropertyStates
);
2061 // stock-loss-marker
2062 xStockPropSet
= xStockPropProvider
->getDownBar();
2063 if( xStockPropSet
.is())
2065 aPropertyStates
.clear();
2066 aPropertyStates
= mxExpPropMapper
->Filter( xStockPropSet
);
2068 if( !aPropertyStates
.empty() )
2070 if( bExportContent
)
2072 AddAutoStyleAttribute( aPropertyStates
);
2074 SvXMLElementExport
aGain( mrExport
, XML_NAMESPACE_CHART
, XML_STOCK_LOSS_MARKER
, sal_True
, sal_True
);
2078 CollectAutoStyle( aPropertyStates
);
2084 xStockPropSet
= xStockPropProvider
->getMinMaxLine();
2085 if( xStockPropSet
.is())
2087 aPropertyStates
.clear();
2088 aPropertyStates
= mxExpPropMapper
->Filter( xStockPropSet
);
2090 if( !aPropertyStates
.empty() )
2092 if( bExportContent
)
2094 AddAutoStyleAttribute( aPropertyStates
);
2096 SvXMLElementExport
aGain( mrExport
, XML_NAMESPACE_CHART
, XML_STOCK_RANGE_LINE
, sal_True
, sal_True
);
2100 CollectAutoStyle( aPropertyStates
);
2107 // wall and floor element
2108 // ----------------------
2110 Reference
< chart::X3DDisplay
> xWallFloorSupplier( xDiagram
, uno::UNO_QUERY
);
2111 if( mxExpPropMapper
.is() &&
2112 xWallFloorSupplier
.is())
2114 // remove property states for autostyles
2115 aPropertyStates
.clear();
2117 Reference
< beans::XPropertySet
> xWallPropSet( xWallFloorSupplier
->getWall(), uno::UNO_QUERY
);
2118 if( xWallPropSet
.is())
2120 aPropertyStates
= mxExpPropMapper
->Filter( xWallPropSet
);
2122 if( !aPropertyStates
.empty() )
2125 if( bExportContent
)
2127 // add style name attribute
2128 AddAutoStyleAttribute( aPropertyStates
);
2130 SvXMLElementExport
aWall( mrExport
, XML_NAMESPACE_CHART
, XML_WALL
, sal_True
, sal_True
);
2134 CollectAutoStyle( aPropertyStates
);
2142 // remove property states for autostyles
2143 aPropertyStates
.clear();
2145 Reference
< beans::XPropertySet
> xFloorPropSet( xWallFloorSupplier
->getFloor(), uno::UNO_QUERY
);
2146 if( xFloorPropSet
.is())
2148 aPropertyStates
= mxExpPropMapper
->Filter( xFloorPropSet
);
2150 if( !aPropertyStates
.empty() )
2153 if( bExportContent
)
2155 // add style name attribute
2156 AddAutoStyleAttribute( aPropertyStates
);
2158 SvXMLElementExport
aFloor( mrExport
, XML_NAMESPACE_CHART
, XML_FLOOR
, sal_True
, sal_True
);
2162 CollectAutoStyle( aPropertyStates
);
2172 void SchXMLExportHelper_Impl::exportCoordinateRegion( const uno::Reference
< chart::XDiagram
>& xDiagram
)
2174 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2175 if( nCurrentODFVersion
<= SvtSaveOptions::ODFVER_012
)//do not export to ODF 1.2 or older
2178 Reference
< chart::XDiagramPositioning
> xDiaPos( xDiagram
, uno::UNO_QUERY
);
2179 SAL_WARN_IF( !xDiaPos
.is(), "xmloff.chart", "Invalid xDiaPos as parameter" );
2183 awt::Rectangle
aRect( xDiaPos
->calculateDiagramPositionExcludingAxes() );
2184 addPosition( awt::Point(aRect
.X
,aRect
.Y
) );
2185 addSize( awt::Size(aRect
.Width
,aRect
.Height
) );
2187 SvXMLElementExport
aCoordinateRegion( mrExport
, XML_NAMESPACE_CHART_EXT
, XML_COORDINATE_REGION
, sal_True
, sal_True
);//#i100778# todo: change to chart namespace in future - dependent on fileformat
2192 XMLTokenEnum
lcl_getTimeUnitToken( sal_Int32 nTimeUnit
)
2194 XMLTokenEnum eToken
= XML_DAYS
;
2197 case ::com::sun::star::chart::TimeUnit::YEAR
:
2200 case ::com::sun::star::chart::TimeUnit::MONTH
:
2201 eToken
= XML_MONTHS
;
2210 void SchXMLExportHelper_Impl::exportDateScale( const Reference
< beans::XPropertySet
> xAxisProps
)
2212 if( !xAxisProps
.is() )
2215 chart::TimeIncrement aIncrement
;
2216 if( (xAxisProps
->getPropertyValue( OUString( "TimeIncrement" )) >>= aIncrement
) )
2218 sal_Int32 nTimeResolution
= ::com::sun::star::chart::TimeUnit::DAY
;
2219 if( aIncrement
.TimeResolution
>>= nTimeResolution
)
2220 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_BASE_TIME_UNIT
, lcl_getTimeUnitToken( nTimeResolution
) );
2222 OUStringBuffer aValue
;
2223 chart::TimeInterval aInterval
;
2224 if( aIncrement
.MajorTimeInterval
>>= aInterval
)
2226 ::sax::Converter::convertNumber( aValue
, aInterval
.Number
);
2227 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_MAJOR_INTERVAL_VALUE
, aValue
.makeStringAndClear() );
2228 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_MAJOR_INTERVAL_UNIT
, lcl_getTimeUnitToken( aInterval
.TimeUnit
) );
2230 if( aIncrement
.MinorTimeInterval
>>= aInterval
)
2232 ::sax::Converter::convertNumber( aValue
, aInterval
.Number
);
2233 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_MINOR_INTERVAL_VALUE
, aValue
.makeStringAndClear() );
2234 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_MINOR_INTERVAL_UNIT
, lcl_getTimeUnitToken( aInterval
.TimeUnit
) );
2237 SvXMLElementExport
aDateScale( mrExport
, XML_NAMESPACE_CHART_EXT
, XML_DATE_SCALE
, sal_True
, sal_True
);//#i25706#todo: change namespace for next ODF version
2241 void SchXMLExportHelper_Impl::exportAxisTitle( const Reference
< beans::XPropertySet
> xTitleProps
, bool bExportContent
)
2243 if( !xTitleProps
.is() )
2245 std::vector
< XMLPropertyState
> aPropertyStates
= mxExpPropMapper
->Filter( xTitleProps
);
2246 if( bExportContent
)
2249 Any
aAny( xTitleProps
->getPropertyValue(
2250 OUString( "String" )));
2253 Reference
< drawing::XShape
> xShape( xTitleProps
, uno::UNO_QUERY
);
2255 addPosition( xShape
);
2257 AddAutoStyleAttribute( aPropertyStates
);
2258 SvXMLElementExport
aTitle( mrExport
, XML_NAMESPACE_CHART
, XML_TITLE
, sal_True
, sal_True
);
2260 // paragraph containing title
2261 exportText( aText
);
2265 CollectAutoStyle( aPropertyStates
);
2267 aPropertyStates
.clear();
2270 void SchXMLExportHelper_Impl::exportGrid( const Reference
< beans::XPropertySet
> xGridProperties
, bool bMajor
, bool bExportContent
)
2272 if( !xGridProperties
.is() )
2274 std::vector
< XMLPropertyState
> aPropertyStates
= mxExpPropMapper
->Filter( xGridProperties
);
2275 if( bExportContent
)
2277 AddAutoStyleAttribute( aPropertyStates
);
2278 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_CLASS
, bMajor
? XML_MAJOR
: XML_MINOR
);
2279 SvXMLElementExport
aGrid( mrExport
, XML_NAMESPACE_CHART
, XML_GRID
, sal_True
, sal_True
);
2283 CollectAutoStyle( aPropertyStates
);
2285 aPropertyStates
.clear();
2291 //returns true if a date scale needs to be exported
2292 bool lcl_exportAxisType( const Reference
< chart2::XAxis
> xChart2Axis
, SvXMLExport
& rExport
)
2294 bool bExportDateScale
= false;
2295 if( !xChart2Axis
.is() )
2296 return bExportDateScale
;
2298 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2299 if( nCurrentODFVersion
<= SvtSaveOptions::ODFVER_012
)//do not export to ODF 1.2 or older
2300 return bExportDateScale
;
2302 chart2::ScaleData
aScale( xChart2Axis
->getScaleData() );
2303 //#i25706#todo: change namespace for next ODF version
2304 sal_uInt16 nNameSpace
= XML_NAMESPACE_CHART_EXT
;
2306 switch(aScale
.AxisType
)
2308 case chart2::AxisType::CATEGORY
:
2309 if( aScale
.AutoDateAxis
)
2311 rExport
.AddAttribute( nNameSpace
, XML_AXIS_TYPE
, XML_AUTO
);
2312 bExportDateScale
= true;
2315 rExport
.AddAttribute( nNameSpace
, XML_AXIS_TYPE
, XML_TEXT
);
2317 case chart2::AxisType::DATE
:
2318 rExport
.AddAttribute( nNameSpace
, XML_AXIS_TYPE
, XML_DATE
);
2319 bExportDateScale
= true;
2321 default: //AUTOMATIC
2322 rExport
.AddAttribute( nNameSpace
, XML_AXIS_TYPE
, XML_AUTO
);
2326 return bExportDateScale
;
2331 void SchXMLExportHelper_Impl::exportAxis(
2332 enum XMLTokenEnum eDimension
,
2333 enum XMLTokenEnum eAxisName
,
2334 const Reference
< beans::XPropertySet
> xAxisProps
,
2335 const Reference
< chart2::XAxis
>& xChart2Axis
,
2336 const OUString
& rCategoriesRange
,
2337 bool bHasTitle
, bool bHasMajorGrid
, bool bHasMinorGrid
,
2338 bool bExportContent
)
2340 static const OUString
sNumFormat( OUString( "NumberFormat" ));
2341 std::vector
< XMLPropertyState
> aPropertyStates
;
2342 SvXMLElementExport
* pAxis
= NULL
;
2344 // get property states for autostyles
2345 if( xAxisProps
.is() && mxExpPropMapper
.is() )
2347 lcl_exportNumberFormat( sNumFormat
, xAxisProps
, mrExport
);
2348 aPropertyStates
= mxExpPropMapper
->Filter( xAxisProps
);
2351 bool bExportDateScale
= false;
2352 if( bExportContent
)
2354 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_DIMENSION
, eDimension
);
2355 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_NAME
, eAxisName
);
2356 AddAutoStyleAttribute( aPropertyStates
); // write style name
2357 if( !rCategoriesRange
.isEmpty() )
2358 bExportDateScale
= lcl_exportAxisType( xChart2Axis
, mrExport
);
2360 // open axis element
2361 pAxis
= new SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_AXIS
, sal_True
, sal_True
);
2365 CollectAutoStyle( aPropertyStates
);
2367 aPropertyStates
.clear();
2370 if( bExportDateScale
)
2371 exportDateScale( xAxisProps
);
2373 Reference
< beans::XPropertySet
> xTitleProps
;
2374 Reference
< beans::XPropertySet
> xMajorGridProps
;
2375 Reference
< beans::XPropertySet
> xMinorGridProps
;
2376 Reference
< chart::XAxis
> xAxis( xAxisProps
, uno::UNO_QUERY
);
2379 xTitleProps
= bHasTitle
? xAxis
->getAxisTitle() : 0;
2380 xMajorGridProps
= bHasMajorGrid
? xAxis
->getMajorGrid() : 0;
2381 xMinorGridProps
= bHasMinorGrid
? xAxis
->getMinorGrid() : 0;
2385 exportAxisTitle( xTitleProps
, bExportContent
);
2387 // categories if we have a categories chart
2388 if( bExportContent
&& !rCategoriesRange
.isEmpty() )
2390 mrExport
.AddAttribute( XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, rCategoriesRange
);
2391 SvXMLElementExport
aCategories( mrExport
, XML_NAMESPACE_CHART
, XML_CATEGORIES
, sal_True
, sal_True
);
2395 exportGrid( xMajorGridProps
, true, bExportContent
);
2396 exportGrid( xMinorGridProps
, false, bExportContent
);
2400 //close axis element
2406 void SchXMLExportHelper_Impl::exportAxes(
2407 const Reference
< chart::XDiagram
> & xDiagram
,
2408 const Reference
< chart2::XDiagram
> & xNewDiagram
,
2409 sal_Bool bExportContent
)
2411 SAL_WARN_IF( !xDiagram
.is(), "xmloff.chart", "Invalid XDiagram as parameter" );
2412 if( ! xDiagram
.is())
2415 // get some properties from document first
2416 sal_Bool bHasXAxis
= sal_False
,
2417 bHasYAxis
= sal_False
,
2418 bHasZAxis
= sal_False
,
2419 bHasSecondaryXAxis
= sal_False
,
2420 bHasSecondaryYAxis
= sal_False
;
2421 sal_Bool bHasXAxisTitle
= sal_False
,
2422 bHasYAxisTitle
= sal_False
,
2423 bHasZAxisTitle
= sal_False
,
2424 bHasSecondaryXAxisTitle
= sal_False
,
2425 bHasSecondaryYAxisTitle
= sal_False
;
2426 sal_Bool bHasXAxisMajorGrid
= sal_False
,
2427 bHasXAxisMinorGrid
= sal_False
,
2428 bHasYAxisMajorGrid
= sal_False
,
2429 bHasYAxisMinorGrid
= sal_False
,
2430 bHasZAxisMajorGrid
= sal_False
,
2431 bHasZAxisMinorGrid
= sal_False
;
2433 // get multiple properties using XMultiPropertySet
2434 MultiPropertySetHandler
aDiagramProperties (xDiagram
);
2436 aDiagramProperties
.Add (
2437 OUString("HasXAxis"), bHasXAxis
);
2438 aDiagramProperties
.Add (
2439 OUString("HasYAxis"), bHasYAxis
);
2440 aDiagramProperties
.Add (
2441 OUString("HasZAxis"), bHasZAxis
);
2442 aDiagramProperties
.Add (
2443 OUString("HasSecondaryXAxis"), bHasSecondaryXAxis
);
2444 aDiagramProperties
.Add (
2445 OUString("HasSecondaryYAxis"), bHasSecondaryYAxis
);
2447 aDiagramProperties
.Add (
2448 OUString ("HasXAxisTitle"), bHasXAxisTitle
);
2449 aDiagramProperties
.Add (
2450 OUString ("HasYAxisTitle"), bHasYAxisTitle
);
2451 aDiagramProperties
.Add (
2452 OUString ("HasZAxisTitle"), bHasZAxisTitle
);
2453 aDiagramProperties
.Add (
2454 OUString ("HasSecondaryXAxisTitle"), bHasSecondaryXAxisTitle
);
2455 aDiagramProperties
.Add (
2456 OUString ("HasSecondaryYAxisTitle"), bHasSecondaryYAxisTitle
);
2458 aDiagramProperties
.Add (
2459 OUString ("HasXAxisGrid"), bHasXAxisMajorGrid
);
2460 aDiagramProperties
.Add (
2461 OUString ("HasYAxisGrid"), bHasYAxisMajorGrid
);
2462 aDiagramProperties
.Add (
2463 OUString ("HasZAxisGrid"), bHasZAxisMajorGrid
);
2465 aDiagramProperties
.Add (
2466 OUString ("HasXAxisHelpGrid"), bHasXAxisMinorGrid
);
2467 aDiagramProperties
.Add (
2468 OUString ("HasYAxisHelpGrid"), bHasYAxisMinorGrid
);
2469 aDiagramProperties
.Add (
2470 OUString ("HasZAxisHelpGrid"), bHasZAxisMinorGrid
);
2472 if ( ! aDiagramProperties
.GetProperties ())
2474 SAL_INFO("xmloff.chart", "Required properties not found in Chart diagram");
2477 Reference
< chart2::XCoordinateSystem
> xCooSys( lcl_getCooSys(xNewDiagram
) );
2479 // write an axis element also if the axis itself is not visible, but a grid or a title
2481 OUString aCategoriesRange
;
2482 Reference
< chart::XAxisSupplier
> xAxisSupp( xDiagram
, uno::UNO_QUERY
);
2486 Reference
< ::com::sun::star::chart2::XAxis
> xNewAxis
= lcl_getAxis( xCooSys
, XML_X
);
2489 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getAxis(0) : 0, uno::UNO_QUERY
);
2490 if( mbHasCategoryLabels
&& bExportContent
)
2492 Reference
< chart2::data::XLabeledDataSequence
> xCategories( lcl_getCategories( xNewDiagram
) );
2493 if( xCategories
.is() )
2495 Reference
< chart2::data::XDataSequence
> xValues( xCategories
->getValues() );
2498 Reference
< chart2::XChartDocument
> xNewDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
2499 maCategoriesRange
= xValues
->getSourceRangeRepresentation();
2500 aCategoriesRange
= lcl_ConvertRange( maCategoriesRange
, xNewDoc
);
2504 exportAxis( XML_X
, XML_PRIMARY_X
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasXAxisTitle
, bHasXAxisMajorGrid
, bHasXAxisMinorGrid
, bExportContent
);
2505 aCategoriesRange
= OUString();
2510 Reference
< chart::XSecondAxisTitleSupplier
> xSecondTitleSupp( xDiagram
, uno::UNO_QUERY
);
2511 xNewAxis
= lcl_getAxis( xCooSys
, XML_X
, false );
2514 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getSecondaryAxis(0) : 0, uno::UNO_QUERY
);
2515 exportAxis( XML_X
, XML_SECONDARY_X
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasSecondaryXAxisTitle
, false, false, bExportContent
);
2520 xNewAxis
= lcl_getAxis( xCooSys
, XML_Y
);
2523 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getAxis(1) : 0, uno::UNO_QUERY
);
2524 exportAxis( XML_Y
, XML_PRIMARY_Y
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasYAxisTitle
, bHasYAxisMajorGrid
, bHasYAxisMinorGrid
, bExportContent
);
2529 xNewAxis
= lcl_getAxis( xCooSys
, XML_Y
, false );
2532 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getSecondaryAxis(1) : 0, uno::UNO_QUERY
);
2533 exportAxis( XML_Y
, XML_SECONDARY_Y
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasSecondaryYAxisTitle
, false, false, bExportContent
);
2538 xNewAxis
= lcl_getAxis( xCooSys
, XML_Z
);
2541 Reference
< beans::XPropertySet
> xAxisProps( xAxisSupp
.is() ? xAxisSupp
->getAxis(2) : 0, uno::UNO_QUERY
);
2542 exportAxis( XML_Z
, XML_PRIMARY_Z
, xAxisProps
, xNewAxis
, aCategoriesRange
, bHasZAxisTitle
, bHasZAxisMajorGrid
, bHasZAxisMinorGrid
, bExportContent
);
2548 bool lcl_hasNoValuesButText( const uno::Reference
< chart2::data::XDataSequence
>& xDataSequence
)
2550 if( !xDataSequence
.is() )
2551 return false;//have no data
2553 Sequence
< uno::Any
> aData
;
2554 Reference
< chart2::data::XNumericalDataSequence
> xNumericalDataSequence( xDataSequence
, uno::UNO_QUERY
);
2555 if( xNumericalDataSequence
.is() )
2557 Sequence
< double > aDoubles( xNumericalDataSequence
->getNumericalData() );
2558 sal_Int32 nCount
= aDoubles
.getLength();
2559 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
2561 if( !::rtl::math::isNan( aDoubles
[i
] ) )
2562 return false;//have double value
2567 aData
= xDataSequence
->getData();
2568 double fDouble
= 0.0;
2569 sal_Int32 nCount
= aData
.getLength();
2570 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
2572 if( (aData
[i
] >>= fDouble
) && !::rtl::math::isNan( fDouble
) )
2573 return false;//have double value
2579 Reference
< chart2::data::XTextualDataSequence
> xTextualDataSequence( xDataSequence
, uno::UNO_QUERY
);
2580 if( xTextualDataSequence
.is() )
2582 uno::Sequence
< OUString
> aStrings( xTextualDataSequence
->getTextualData() );
2583 sal_Int32 nCount
= aStrings
.getLength();
2584 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
2586 if( !aStrings
[i
].isEmpty() )
2587 return true;//have text
2592 if( !aData
.getLength() )
2593 aData
= xDataSequence
->getData();
2596 sal_Int32 nCount
= aData
.getLength();
2597 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
2599 if( (aData
[i
]>>=aString
) && !aString
.isEmpty() )
2600 return true;//have text
2603 //no doubles and no texts
2608 void SchXMLExportHelper_Impl::exportSeries(
2609 const Reference
< chart2::XDiagram
> & xNewDiagram
,
2610 const awt::Size
& rPageSize
,
2611 sal_Bool bExportContent
,
2612 sal_Bool bHasTwoYAxes
)
2614 Reference
< chart2::XCoordinateSystemContainer
> xBCooSysCnt( xNewDiagram
, uno::UNO_QUERY
);
2615 if( ! xBCooSysCnt
.is())
2617 Reference
< chart2::XChartDocument
> xNewDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
2619 OUString aFirstXDomainRange
;
2620 OUString aFirstYDomainRange
;
2622 std::vector
< XMLPropertyState
> aPropertyStates
;
2624 const OUString
sNumFormat("NumberFormat");
2625 const OUString
sPercentageNumFormat( "PercentageNumberFormat");
2627 Sequence
< Reference
< chart2::XCoordinateSystem
> >
2628 aCooSysSeq( xBCooSysCnt
->getCoordinateSystems());
2629 for( sal_Int32 nCSIdx
=0; nCSIdx
<aCooSysSeq
.getLength(); ++nCSIdx
)
2631 Reference
< chart2::XChartTypeContainer
> xCTCnt( aCooSysSeq
[nCSIdx
], uno::UNO_QUERY
);
2634 Sequence
< Reference
< chart2::XChartType
> > aCTSeq( xCTCnt
->getChartTypes());
2635 for( sal_Int32 nCTIdx
=0; nCTIdx
<aCTSeq
.getLength(); ++nCTIdx
)
2637 Reference
< chart2::XDataSeriesContainer
> xDSCnt( aCTSeq
[nCTIdx
], uno::UNO_QUERY
);
2640 // note: if xDSCnt.is() then also aCTSeq[nCTIdx]
2641 OUString
aChartType( aCTSeq
[nCTIdx
]->getChartType());
2642 OUString aLabelRole
= aCTSeq
[nCTIdx
]->getRoleOfSequenceForSeriesLabel();
2644 // special export for stock charts
2645 if ( aChartType
== "com.sun.star.chart2.CandleStickChartType" )
2647 sal_Bool bJapaneseCandleSticks
= sal_False
;
2648 Reference
< beans::XPropertySet
> xCTProp( aCTSeq
[nCTIdx
], uno::UNO_QUERY
);
2650 xCTProp
->getPropertyValue( OUString( "Japanese" )) >>= bJapaneseCandleSticks
;
2651 exportCandleStickSeries(
2652 xDSCnt
->getDataSeries(), xNewDiagram
, bJapaneseCandleSticks
, bExportContent
);
2656 // export dataseries for current chart-type
2657 Sequence
< Reference
< chart2::XDataSeries
> > aSeriesSeq( xDSCnt
->getDataSeries());
2658 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<aSeriesSeq
.getLength(); ++nSeriesIdx
)
2661 Reference
< chart2::data::XDataSource
> xSource( aSeriesSeq
[nSeriesIdx
], uno::UNO_QUERY
);
2664 SvXMLElementExport
* pSeries
= NULL
;
2665 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeqCnt(
2666 xSource
->getDataSequences());
2667 sal_Int32 nMainSequenceIndex
= -1;
2668 sal_Int32 nSeriesLength
= 0;
2669 sal_Int32 nAttachedAxis
= chart::ChartAxisAssign::PRIMARY_Y
;
2670 sal_Bool bHasMeanValueLine
= false;
2671 chart::ChartRegressionCurveType
eRegressionType( chart::ChartRegressionCurveType_NONE
);
2672 Reference
< beans::XPropertySet
> xPropSet
;
2673 tLabelValuesDataPair aSeriesLabelValuesPair
;
2675 // search for main sequence and create a series element
2677 Reference
< chart2::data::XDataSequence
> xValuesSeq
;
2678 Reference
< chart2::data::XDataSequence
> xLabelSeq
;
2679 sal_Int32 nSeqIdx
=0;
2680 for( ; nSeqIdx
<aSeqCnt
.getLength(); ++nSeqIdx
)
2683 Reference
< chart2::data::XDataSequence
> xTempValueSeq( aSeqCnt
[nSeqIdx
]->getValues() );
2684 if( nMainSequenceIndex
==-1 )
2686 Reference
< beans::XPropertySet
> xSeqProp( xTempValueSeq
, uno::UNO_QUERY
);
2688 xSeqProp
->getPropertyValue(OUString( "Role" )) >>= aRole
;
2690 if( aRole
.equals( aLabelRole
))
2692 xValuesSeq
.set( xTempValueSeq
);
2693 xLabelSeq
.set( aSeqCnt
[nSeqIdx
]->getLabel());
2694 nMainSequenceIndex
= nSeqIdx
;
2697 sal_Int32 nSequenceLength
= (xTempValueSeq
.is()? xTempValueSeq
->getData().getLength() : sal_Int32(0));
2698 if( nSeriesLength
< nSequenceLength
)
2699 nSeriesLength
= nSequenceLength
;
2702 // have found the main sequence, then xValuesSeq and
2703 // xLabelSeq contain those. Otherwise both are empty
2705 // get property states for autostyles
2708 xPropSet
= SchXMLSeriesHelper::createOldAPISeriesPropertySet(
2709 aSeriesSeq
[nSeriesIdx
], mrExport
.GetModel() );
2711 catch( const uno::Exception
& rEx
)
2713 SAL_INFO("xmloff.chart", "Series not found or no XPropertySet: " << rEx
.Message
);
2718 // determine attached axis
2721 Any
aAny( xPropSet
->getPropertyValue(
2722 OUString( "Axis" )));
2723 aAny
>>= nAttachedAxis
;
2725 aAny
= xPropSet
->getPropertyValue(
2726 OUString( "MeanValue" ));
2727 aAny
>>= bHasMeanValueLine
;
2729 aAny
= xPropSet
->getPropertyValue(
2730 OUString( "RegressionCurves" ));
2731 aAny
>>= eRegressionType
;
2733 catch( const beans::UnknownPropertyException
& rEx
)
2735 SAL_INFO("xmloff.chart", "Required property not found in DataRowProperties: " << rEx
.Message
);
2738 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2739 if( nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
)
2741 lcl_exportNumberFormat( sNumFormat
, xPropSet
, mrExport
);
2742 lcl_exportNumberFormat( sPercentageNumFormat
, xPropSet
, mrExport
);
2745 if( mxExpPropMapper
.is())
2746 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
2749 if( bExportContent
)
2753 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
2754 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
2756 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
2760 AddAutoStyleAttribute( aPropertyStates
);
2762 if( xValuesSeq
.is())
2763 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
,
2765 xValuesSeq
->getSourceRangeRepresentation(),
2768 // #i75297# allow empty series, export empty range to have all ranges on import
2769 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, OUString());
2772 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
,
2774 xLabelSeq
->getSourceRangeRepresentation(),
2776 if( xLabelSeq
.is() || xValuesSeq
.is() )
2777 aSeriesLabelValuesPair
= tLabelValuesDataPair( xLabelSeq
, xValuesSeq
);
2779 // chart-type for mixed types
2780 enum XMLTokenEnum
eCTToken(
2781 SchXMLTools::getTokenByChartType( aChartType
, false /* bUseOldNames */ ));
2782 //@todo: get token for current charttype
2783 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_CLASS
,
2784 mrExport
.GetNamespaceMap().GetQNameByKey(
2785 XML_NAMESPACE_CHART
, GetXMLToken( eCTToken
)));
2787 // open series element until end of for loop
2788 pSeries
= new SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, sal_True
, sal_True
);
2792 CollectAutoStyle( aPropertyStates
);
2794 // remove property states for autostyles
2795 aPropertyStates
.clear();
2799 // export domain elements if we have a series parent element
2803 if( bExportContent
)
2805 bool bIsScatterChart
= aChartType
== "com.sun.star.chart2.ScatterChartType";
2806 bool bIsBubbleChart
= aChartType
== "com.sun.star.chart2.BubbleChartType";
2807 Reference
< chart2::data::XDataSequence
> xYValuesForBubbleChart
;
2808 if( bIsBubbleChart
)
2810 Reference
< chart2::data::XLabeledDataSequence
> xSequence( lcl_getDataSequenceByRole( aSeqCnt
, OUString( "values-y" ) ) );
2811 if( xSequence
.is() )
2813 xYValuesForBubbleChart
= xSequence
->getValues();
2814 if( !lcl_exportDomainForThisSequence( xYValuesForBubbleChart
, aFirstYDomainRange
, mrExport
) )
2815 xYValuesForBubbleChart
= 0;
2818 if( bIsScatterChart
|| bIsBubbleChart
)
2820 Reference
< chart2::data::XLabeledDataSequence
> xSequence( lcl_getDataSequenceByRole( aSeqCnt
, OUString( "values-x" ) ) );
2821 if( xSequence
.is() )
2823 Reference
< chart2::data::XDataSequence
> xValues( xSequence
->getValues() );
2824 if( lcl_exportDomainForThisSequence( xValues
, aFirstXDomainRange
, mrExport
) )
2825 m_aDataSequencesToExport
.push_back( tLabelValuesDataPair(
2826 (uno::Reference
< chart2::data::XDataSequence
>)0, xValues
));
2828 else if( nSeriesIdx
==0 )
2830 //might be that the categories are used as x-values (e.g. for date axis) -> export them accordingly
2831 Reference
< chart2::data::XLabeledDataSequence
> xCategories( lcl_getCategories( xNewDiagram
) );
2832 if( xCategories
.is() )
2834 Reference
< chart2::data::XDataSequence
> xValues( xCategories
->getValues() );
2835 if( !lcl_hasNoValuesButText( xValues
) )
2836 lcl_exportDomainForThisSequence( xValues
, aFirstXDomainRange
, mrExport
);
2840 if( xYValuesForBubbleChart
.is() )
2841 m_aDataSequencesToExport
.push_back( tLabelValuesDataPair(
2842 (uno::Reference
< chart2::data::XDataSequence
>)0, xYValuesForBubbleChart
));
2846 // add sequences for main sequence after domain sequences,
2847 // so that the export of the local table has the correct order
2848 if( bExportContent
&&
2849 (aSeriesLabelValuesPair
.first
.is() || aSeriesLabelValuesPair
.second
.is()))
2850 m_aDataSequencesToExport
.push_back( aSeriesLabelValuesPair
);
2852 // statistical objects:
2853 // regression curves and mean value lines
2854 if( bHasMeanValueLine
&&
2856 mxExpPropMapper
.is() )
2858 Reference
< beans::XPropertySet
> xStatProp
;
2861 Any
aPropAny( xPropSet
->getPropertyValue(
2862 OUString( "DataMeanValueProperties" )));
2863 aPropAny
>>= xStatProp
;
2865 catch( const uno::Exception
& rEx
)
2867 SAL_INFO("xmloff.chart", "Exception caught during Export of series - optional DataMeanValueProperties not available: " << rEx
.Message
);
2870 if( xStatProp
.is() )
2872 aPropertyStates
= mxExpPropMapper
->Filter( xStatProp
);
2874 if( !aPropertyStates
.empty() )
2877 if( bExportContent
)
2879 // add style name attribute
2880 AddAutoStyleAttribute( aPropertyStates
);
2882 SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_MEAN_VALUE
, sal_True
, sal_True
);
2886 CollectAutoStyle( aPropertyStates
);
2892 if( eRegressionType
!= chart::ChartRegressionCurveType_NONE
&&
2894 mxExpPropMapper
.is() )
2896 exportRegressionCurve( aSeriesSeq
[nSeriesIdx
], xPropSet
, rPageSize
, bExportContent
);
2899 exportErrorBar( xPropSet
,false, bExportContent
); // X ErrorBar
2900 exportErrorBar( xPropSet
,true, bExportContent
); // Y ErrorBar
2903 uno::Reference
< beans::XPropertySet
>( aSeriesSeq
[nSeriesIdx
], uno::UNO_QUERY
),
2904 nSeriesLength
, xNewDiagram
, bExportContent
);
2906 // close series element
2911 aPropertyStates
.clear();
2916 void SchXMLExportHelper_Impl::exportRegressionCurve(
2917 const Reference
< chart2::XDataSeries
> & xSeries
,
2918 const Reference
< beans::XPropertySet
> & xSeriesProp
,
2919 const awt::Size
& rPageSize
,
2920 sal_Bool bExportContent
)
2922 OSL_ASSERT( mxExpPropMapper
.is());
2924 std::vector
< XMLPropertyState
> aPropertyStates
;
2925 std::vector
< XMLPropertyState
> aEquationPropertyStates
;
2926 Reference
< beans::XPropertySet
> xStatProp
;
2929 Any
aPropAny( xSeriesProp
->getPropertyValue(
2930 OUString( "DataRegressionProperties" )));
2931 aPropAny
>>= xStatProp
;
2933 catch( const uno::Exception
& rEx
)
2935 SAL_INFO("xmloff.chart", "Exception caught during Export of series - optional DataRegressionProperties not available: " << rEx
.Message
);
2938 if( xStatProp
.is() )
2940 Reference
< chart2::XRegressionCurve
> xRegCurve( SchXMLTools::getRegressionCurve( xSeries
));
2941 Reference
< beans::XPropertySet
> xEquationProperties
;
2943 xEquationProperties
.set( xRegCurve
->getEquationProperties());
2945 bool bShowEquation
= false;
2946 bool bShowRSquared
= false;
2947 bool bExportEquation
= false;
2948 aPropertyStates
= mxExpPropMapper
->Filter( xStatProp
);
2949 if( xEquationProperties
.is())
2951 xEquationProperties
->getPropertyValue( OUString( "ShowEquation" ))
2953 xEquationProperties
->getPropertyValue( OUString( "ShowCorrelationCoefficient" ))
2955 bExportEquation
= ( bShowEquation
|| bShowRSquared
);
2956 const SvtSaveOptions::ODFDefaultVersion
nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
2957 if( nCurrentVersion
< SvtSaveOptions::ODFVER_012
)
2958 bExportEquation
=false;
2959 if( bExportEquation
)
2962 sal_Int32 nNumberFormat
= 0;
2963 if( ( xEquationProperties
->getPropertyValue(
2964 OUString( "NumberFormat" )) >>= nNumberFormat
) &&
2965 nNumberFormat
!= -1 )
2967 mrExport
.addDataStyle( nNumberFormat
);
2969 aEquationPropertyStates
= mxExpPropMapper
->Filter( xEquationProperties
);
2973 if( !aPropertyStates
.empty() || bExportEquation
)
2976 if( bExportContent
)
2978 // add style name attribute
2979 if( !aPropertyStates
.empty())
2980 AddAutoStyleAttribute( aPropertyStates
);
2981 SvXMLElementExport
aRegressionExport( mrExport
, XML_NAMESPACE_CHART
, XML_REGRESSION_CURVE
, sal_True
, sal_True
);
2982 if( bExportEquation
)
2985 if( !bShowEquation
)
2986 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_DISPLAY_EQUATION
, XML_FALSE
);
2989 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_DISPLAY_R_SQUARE
, XML_TRUE
);
2992 chart2::RelativePosition aRelativePosition
;
2993 if( xEquationProperties
->getPropertyValue(
2994 OUString( "RelativePosition")) >>= aRelativePosition
)
2996 double fX
= aRelativePosition
.Primary
* rPageSize
.Width
;
2997 double fY
= aRelativePosition
.Secondary
* rPageSize
.Height
;
2999 aPos
.X
= static_cast< sal_Int32
>( ::rtl::math::round( fX
));
3000 aPos
.Y
= static_cast< sal_Int32
>( ::rtl::math::round( fY
));
3001 addPosition( aPos
);
3004 if( !aEquationPropertyStates
.empty())
3005 AddAutoStyleAttribute( aEquationPropertyStates
);
3007 SvXMLElementExport( mrExport
, XML_NAMESPACE_CHART
, XML_EQUATION
, sal_True
, sal_True
);
3012 if( !aPropertyStates
.empty())
3013 CollectAutoStyle( aPropertyStates
);
3014 if( bExportEquation
&& !aEquationPropertyStates
.empty())
3015 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 /// Dont 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
>)0, *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
, sal_True
, sal_True
);
3095 CollectAutoStyle( aPropertyStates
);
3102 void SchXMLExportHelper_Impl::exportCandleStickSeries(
3103 const Sequence
< Reference
< chart2::XDataSeries
> > & aSeriesSeq
,
3104 const Reference
< chart2::XDiagram
> & xDiagram
,
3105 sal_Bool bJapaneseCandleSticks
,
3106 sal_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
, OUString( "values-last" ));
3128 if( bExportContent
)
3130 Reference
< chart2::XChartDocument
> xNewDoc( mrExport
.GetModel(), uno::UNO_QUERY
);
3131 //@todo: export data points
3134 if( bJapaneseCandleSticks
)
3136 tLabelAndValueRange
aRanges( lcl_getLabelAndValueRangeByRole(
3137 aSeqCnt
, OUString( "values-first" ), xNewDoc
, m_aDataSequencesToExport
));
3138 if( !aRanges
.second
.isEmpty())
3139 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, aRanges
.second
);
3140 if( !aRanges
.first
.isEmpty())
3141 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
, aRanges
.first
);
3142 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
3143 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
3145 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
3146 SvXMLElementExport
aOpenSeries( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, sal_True
, sal_True
);
3147 // export empty data points
3148 exportDataPoints( 0, nSeriesLength
, xDiagram
, bExportContent
);
3153 tLabelAndValueRange
aRanges( lcl_getLabelAndValueRangeByRole(
3154 aSeqCnt
, OUString( "values-min" ), xNewDoc
, m_aDataSequencesToExport
));
3155 if( !aRanges
.second
.isEmpty())
3156 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, aRanges
.second
);
3157 if( !aRanges
.first
.isEmpty())
3158 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
, aRanges
.first
);
3159 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
3160 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
3162 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
3163 SvXMLElementExport
aLowSeries( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, sal_True
, sal_True
);
3164 // export empty data points
3165 exportDataPoints( 0, nSeriesLength
, xDiagram
, bExportContent
);
3170 tLabelAndValueRange
aRanges( lcl_getLabelAndValueRangeByRole(
3171 aSeqCnt
, OUString( "values-max" ), xNewDoc
, m_aDataSequencesToExport
));
3172 if( !aRanges
.second
.isEmpty())
3173 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, aRanges
.second
);
3174 if( !aRanges
.first
.isEmpty())
3175 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
, aRanges
.first
);
3176 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
3177 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
3179 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
3180 SvXMLElementExport
aHighSeries( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, sal_True
, sal_True
);
3181 // export empty data points
3182 exportDataPoints( 0, nSeriesLength
, xDiagram
, bExportContent
);
3187 tLabelAndValueRange
aRanges( lcl_getLabelAndValueRangeByRole(
3188 aSeqCnt
, OUString( "values-last" ), xNewDoc
, m_aDataSequencesToExport
));
3189 if( !aRanges
.second
.isEmpty())
3190 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_VALUES_CELL_RANGE_ADDRESS
, aRanges
.second
);
3191 if( !aRanges
.first
.isEmpty())
3192 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_LABEL_CELL_ADDRESS
, aRanges
.first
);
3193 if( nAttachedAxis
== chart::ChartAxisAssign::SECONDARY_Y
)
3194 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_SECONDARY_Y
);
3196 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_ATTACHED_AXIS
, XML_PRIMARY_Y
);
3197 SvXMLElementExport
aCloseSeries( mrExport
, XML_NAMESPACE_CHART
, XML_SERIES
, sal_True
, sal_True
);
3198 // export empty data points
3199 exportDataPoints( 0, nSeriesLength
, xDiagram
, bExportContent
);
3206 // remove property states for autostyles
3211 void SchXMLExportHelper_Impl::exportDataPoints(
3212 const uno::Reference
< beans::XPropertySet
> & xSeriesProperties
,
3213 sal_Int32 nSeriesLength
,
3214 const uno::Reference
< chart2::XDiagram
> & xDiagram
,
3215 sal_Bool bExportContent
)
3219 // write data-points only if they contain autostyles
3220 // objects with equal autostyles are grouped using the attribute
3223 // Note: if only the nth data-point has autostyles there is an element
3224 // without style and repeat="n-1" attribute written in advance.
3226 // the sequence aDataPointSeq contains indices of data-points that
3227 // do have own attributes. This increases the performance substantially.
3229 // more performant version for #93600#
3230 if( mxExpPropMapper
.is())
3232 uno::Reference
< chart2::XDataSeries
> xSeries( xSeriesProperties
, uno::UNO_QUERY
);
3234 std::vector
< XMLPropertyState
> aPropertyStates
;
3236 const OUString
sNumFormat("NumberFormat");
3237 const OUString
sPercentageNumFormat( "PercentageNumberFormat");
3239 bool bVaryColorsByPoint
= false;
3240 Sequence
< sal_Int32
> aDataPointSeq
;
3241 if( xSeriesProperties
.is())
3243 Any aAny
= xSeriesProperties
->getPropertyValue(
3244 OUString( "AttributedDataPoints" ));
3245 aAny
>>= aDataPointSeq
;
3246 xSeriesProperties
->getPropertyValue(
3247 OUString( "VaryColorsByPoint" )) >>= bVaryColorsByPoint
;
3251 sal_Int32 nSize
= aDataPointSeq
.getLength();
3252 SAL_WARN_IF( nSize
> nSeriesLength
, "xmloff.chart", "Too many point attributes" );
3254 const sal_Int32
* pPoints
= aDataPointSeq
.getConstArray();
3257 Reference
< chart2::XColorScheme
> xColorScheme
;
3259 xColorScheme
.set( xDiagram
->getDefaultColorScheme());
3261 ::std::list
< SchXMLDataPointStruct
> aDataPointList
;
3263 sal_Int32 nLastIndex
= -1;
3264 sal_Int32 nCurrIndex
= 0;
3267 if( bVaryColorsByPoint
&& xColorScheme
.is() )
3269 ::std::set
< sal_Int32
> aAttrPointSet
;
3270 ::std::copy( pPoints
, pPoints
+ aDataPointSeq
.getLength(),
3271 ::std::inserter( aAttrPointSet
, aAttrPointSet
.begin()));
3272 const ::std::set
< sal_Int32
>::const_iterator
aEndIt( aAttrPointSet
.end());
3273 for( nElement
= 0; nElement
< nSeriesLength
; ++nElement
)
3275 aPropertyStates
.clear();
3276 uno::Reference
< beans::XPropertySet
> xPropSet
;
3277 bool bExportNumFmt
= false;
3278 if( aAttrPointSet
.find( nElement
) != aEndIt
)
3282 xPropSet
= SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
3283 xSeries
, nElement
, mrExport
.GetModel() );
3284 bExportNumFmt
= true;
3286 catch( const uno::Exception
& rEx
)
3288 SAL_INFO("xmloff.chart", "Exception caught during Export of data point: " << rEx
.Message
);
3293 // property set only containing the color
3294 xPropSet
.set( new ::xmloff::chart::ColorPropertySet(
3295 xColorScheme
->getColorByIndex( nElement
)));
3297 SAL_WARN_IF( !xPropSet
.is(), "xmloff.chart", "Pie Segments should have properties" );
3300 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
3301 if( nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
&& bExportNumFmt
)
3303 lcl_exportNumberFormat( sNumFormat
, xPropSet
, mrExport
);
3304 lcl_exportNumberFormat( sPercentageNumFormat
, xPropSet
, mrExport
);
3307 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
3308 if( !aPropertyStates
.empty() )
3310 if( bExportContent
)
3312 // write data-point with style
3313 SAL_WARN_IF( maAutoStyleNameQueue
.empty(), "xmloff.chart", "Autostyle queue empty!" );
3315 SchXMLDataPointStruct aPoint
;
3316 aPoint
.maStyleName
= maAutoStyleNameQueue
.front();
3317 maAutoStyleNameQueue
.pop();
3318 aDataPointList
.push_back( aPoint
);
3322 CollectAutoStyle( aPropertyStates
);
3327 SAL_WARN_IF( bExportContent
&& (static_cast<sal_Int32
>(aDataPointList
.size()) != nSeriesLength
), "xmloff.chart", "not enough data points on content export" );
3331 for( nElement
= 0; nElement
< nSize
; ++nElement
)
3333 aPropertyStates
.clear();
3334 nCurrIndex
= pPoints
[ nElement
];
3335 //assuming sorted indices in pPoints
3337 if( nCurrIndex
<0 || nCurrIndex
>=nSeriesLength
)
3340 // write leading empty data points
3341 if( nCurrIndex
- nLastIndex
> 1 )
3343 SchXMLDataPointStruct aPoint
;
3344 aPoint
.mnRepeat
= nCurrIndex
- nLastIndex
- 1;
3345 aDataPointList
.push_back( aPoint
);
3348 uno::Reference
< beans::XPropertySet
> xPropSet
;
3349 // get property states
3352 xPropSet
= SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
3353 xSeries
, nCurrIndex
, mrExport
.GetModel() );
3355 catch( const uno::Exception
& rEx
)
3357 SAL_INFO("xmloff.chart", "Exception caught during Export of data point: " << rEx
.Message
);
3361 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
3362 if( nCurrentODFVersion
>= SvtSaveOptions::ODFVER_012
)
3364 lcl_exportNumberFormat( sNumFormat
, xPropSet
, mrExport
);
3365 lcl_exportNumberFormat( sPercentageNumFormat
, xPropSet
, mrExport
);
3368 aPropertyStates
= mxExpPropMapper
->Filter( xPropSet
);
3369 if( !aPropertyStates
.empty() )
3371 if( bExportContent
)
3373 // write data-point with style
3374 SAL_WARN_IF( maAutoStyleNameQueue
.empty(), "xmloff.chart", "Autostyle queue empty!" );
3375 SchXMLDataPointStruct aPoint
;
3376 aPoint
.maStyleName
= maAutoStyleNameQueue
.front();
3377 maAutoStyleNameQueue
.pop();
3379 aDataPointList
.push_back( aPoint
);
3380 nLastIndex
= nCurrIndex
;
3384 CollectAutoStyle( aPropertyStates
);
3390 // if we get here the property states are empty
3391 SchXMLDataPointStruct aPoint
;
3392 aDataPointList
.push_back( aPoint
);
3394 nLastIndex
= nCurrIndex
;
3396 // final empty elements
3397 nRepeat
= nSeriesLength
- nLastIndex
- 1;
3400 SchXMLDataPointStruct aPoint
;
3401 aPoint
.mnRepeat
= nRepeat
;
3402 aDataPointList
.push_back( aPoint
);
3406 if( bExportContent
)
3408 // write elements (merge equal ones)
3409 ::std::list
< SchXMLDataPointStruct
>::iterator aIter
= aDataPointList
.begin();
3410 SchXMLDataPointStruct aPoint
;
3411 SchXMLDataPointStruct aLastPoint
;
3413 // initialize so that it doesn't matter if
3414 // the element is counted in the first iteration
3415 aLastPoint
.mnRepeat
= 0;
3417 for( ; aIter
!= aDataPointList
.end(); ++aIter
)
3421 if( aPoint
.maStyleName
== aLastPoint
.maStyleName
)
3422 aPoint
.mnRepeat
+= aLastPoint
.mnRepeat
;
3423 else if( aLastPoint
.mnRepeat
> 0 )
3425 // write last element
3426 if( !aLastPoint
.maStyleName
.isEmpty() )
3427 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_STYLE_NAME
, aLastPoint
.maStyleName
);
3429 if( aLastPoint
.mnRepeat
> 1 )
3430 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_REPEATED
,
3431 OUString::valueOf( (sal_Int64
)( aLastPoint
.mnRepeat
) ));
3433 SvXMLElementExport
aPointElem( mrExport
, XML_NAMESPACE_CHART
, XML_DATA_POINT
, sal_True
, sal_True
);
3435 aLastPoint
= aPoint
;
3437 // write last element if it hasn't been written in last iteration
3438 if( aPoint
.maStyleName
== aLastPoint
.maStyleName
)
3440 if( !aLastPoint
.maStyleName
.isEmpty() )
3441 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_STYLE_NAME
, aLastPoint
.maStyleName
);
3443 if( aLastPoint
.mnRepeat
> 1 )
3444 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_REPEATED
,
3445 OUString::valueOf( (sal_Int64
)( aLastPoint
.mnRepeat
) ));
3447 SvXMLElementExport
aPointElem( mrExport
, XML_NAMESPACE_CHART
, XML_DATA_POINT
, sal_True
, sal_True
);
3453 void SchXMLExportHelper_Impl::addPosition( const awt::Point
& rPosition
)
3455 mrExport
.GetMM100UnitConverter().convertMeasureToXML(
3456 msStringBuffer
, rPosition
.X
);
3457 msString
= msStringBuffer
.makeStringAndClear();
3458 mrExport
.AddAttribute( XML_NAMESPACE_SVG
, XML_X
, msString
);
3460 mrExport
.GetMM100UnitConverter().convertMeasureToXML(
3461 msStringBuffer
, rPosition
.Y
);
3462 msString
= msStringBuffer
.makeStringAndClear();
3463 mrExport
.AddAttribute( XML_NAMESPACE_SVG
, XML_Y
, msString
);
3466 void SchXMLExportHelper_Impl::addPosition( Reference
< drawing::XShape
> xShape
)
3469 addPosition( xShape
->getPosition());
3472 void SchXMLExportHelper_Impl::addSize( const awt::Size
& rSize
, bool bIsOOoNamespace
)
3474 mrExport
.GetMM100UnitConverter().convertMeasureToXML(
3475 msStringBuffer
, rSize
.Width
);
3476 msString
= msStringBuffer
.makeStringAndClear();
3477 mrExport
.AddAttribute( bIsOOoNamespace
? XML_NAMESPACE_CHART_EXT
: XML_NAMESPACE_SVG
, XML_WIDTH
, msString
);
3480 mrExport
.GetMM100UnitConverter().convertMeasureToXML(
3481 msStringBuffer
, rSize
.Height
);
3482 msString
= msStringBuffer
.makeStringAndClear();
3483 mrExport
.AddAttribute( bIsOOoNamespace
? XML_NAMESPACE_CHART_EXT
: XML_NAMESPACE_SVG
, XML_HEIGHT
, msString
);
3486 void SchXMLExportHelper_Impl::addSize( Reference
< drawing::XShape
> xShape
, bool bIsOOoNamespace
)
3489 addSize( xShape
->getSize(), bIsOOoNamespace
);
3492 awt::Size
SchXMLExportHelper_Impl::getPageSize( const Reference
< chart2::XChartDocument
> & xChartDoc
) const
3494 awt::Size
aSize( 8000, 7000 );
3495 uno::Reference
< embed::XVisualObject
> xVisualObject( xChartDoc
, uno::UNO_QUERY
);
3496 SAL_WARN_IF( !xVisualObject
.is(), "xmloff.chart", "need XVisualObject for page size" );
3497 if( xVisualObject
.is() )
3498 aSize
= xVisualObject
->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT
);
3503 void SchXMLExportHelper_Impl::CollectAutoStyle( const std::vector
< XMLPropertyState
>& aStates
)
3505 if( !aStates
.empty() )
3506 maAutoStyleNameQueue
.push( GetAutoStylePoolP().Add( XML_STYLE_FAMILY_SCH_CHART_ID
, aStates
));
3509 void SchXMLExportHelper_Impl::AddAutoStyleAttribute( const std::vector
< XMLPropertyState
>& aStates
)
3511 if( !aStates
.empty() )
3513 SAL_WARN_IF( maAutoStyleNameQueue
.empty(), "xmloff.chart", "Autostyle queue empty!" );
3515 mrExport
.AddAttribute( XML_NAMESPACE_CHART
, XML_STYLE_NAME
, maAutoStyleNameQueue
.front() );
3516 maAutoStyleNameQueue
.pop();
3520 void SchXMLExportHelper_Impl::exportText( const OUString
& rText
, bool bConvertTabsLFs
)
3522 SchXMLTools::exportText( mrExport
, rText
, bConvertTabsLFs
);
3525 // ========================================
3526 // class SchXMLExport
3527 // ========================================
3529 SchXMLExport::SchXMLExport(
3530 const Reference
< uno::XComponentContext
>& xContext
,
3531 sal_uInt16 nExportFlags
)
3532 : SvXMLExport( util::MeasureUnit::CM
, xContext
,
3533 ::xmloff::token::XML_CHART
, nExportFlags
),
3534 maAutoStylePool( *this ),
3535 maExportHelper( *this, maAutoStylePool
)
3537 if( getDefaultVersion() > SvtSaveOptions::ODFVER_012
)
3538 _GetNamespaceMap().Add( GetXMLToken(XML_NP_CHART_EXT
), GetXMLToken(XML_N_CHART_EXT
), XML_NAMESPACE_CHART_EXT
);
3542 SchXMLExport::~SchXMLExport()
3544 // stop progress view
3545 if( mxStatusIndicator
.is())
3547 mxStatusIndicator
->end();
3548 mxStatusIndicator
->reset();
3552 sal_uInt32
SchXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum eClass
)
3554 Reference
< chart2::XChartDocument
> xChartDoc( GetModel(), uno::UNO_QUERY
);
3555 maExportHelper
.m_pImpl
->InitRangeSegmentationProperties( xChartDoc
);
3556 return SvXMLExport::exportDoc( eClass
);
3559 void SchXMLExport::_ExportStyles( sal_Bool bUsed
)
3561 SvXMLExport::_ExportStyles( bUsed
);
3564 void SchXMLExport::_ExportMasterStyles()
3566 // not available in chart
3567 SAL_INFO("xmloff.chart", "Master Style Export requested. Not available for Chart" );
3570 void SchXMLExport::_ExportAutoStyles()
3572 // there are no styles that require their own autostyles
3573 if( getExportFlags() & EXPORT_CONTENT
)
3575 Reference
< chart::XChartDocument
> xChartDoc( GetModel(), uno::UNO_QUERY
);
3578 maExportHelper
.m_pImpl
->collectAutoStyles( xChartDoc
);
3579 maExportHelper
.m_pImpl
->exportAutoStyles();
3583 SAL_WARN("xmloff.chart", "Couldn't export chart due to wrong XModel (must be XChartDocument)" );
3588 void SchXMLExport::_ExportContent()
3590 Reference
< chart::XChartDocument
> xChartDoc( GetModel(), uno::UNO_QUERY
);
3593 // determine if data comes from the outside
3594 sal_Bool bIncludeTable
= sal_True
;
3596 Reference
< chart2::XChartDocument
> xNewDoc( xChartDoc
, uno::UNO_QUERY
);
3599 // check if we have own data. If so we must not export the complete
3600 // range string, as this is our only indicator for having own or
3601 // external data. @todo: fix this in the file format!
3602 Reference
< lang::XServiceInfo
> xDPServiceInfo( xNewDoc
->getDataProvider(), uno::UNO_QUERY
);
3603 if( ! (xDPServiceInfo
.is() && xDPServiceInfo
->getImplementationName() == "com.sun.star.comp.chart.InternalDataProvider" ))
3605 bIncludeTable
= sal_False
;
3610 Reference
< lang::XServiceInfo
> xServ( xChartDoc
, uno::UNO_QUERY
);
3613 if( xServ
->supportsService(
3614 OUString( "com.sun.star.chart.ChartTableAddressSupplier" )))
3616 Reference
< beans::XPropertySet
> xProp( xServ
, uno::UNO_QUERY
);
3622 OUString sChartAddress
;
3623 aAny
= xProp
->getPropertyValue(
3624 OUString( "ChartRangeAddress" ));
3625 aAny
>>= sChartAddress
;
3626 maExportHelper
.m_pImpl
->SetChartRangeAddress( sChartAddress
);
3628 OUString sTableNumberList
;
3629 aAny
= xProp
->getPropertyValue(
3630 OUString( "TableNumberList" ));
3631 aAny
>>= sTableNumberList
;
3632 maExportHelper
.m_pImpl
->SetTableNumberList( sTableNumberList
);
3634 // do not include own table if there are external addresses
3635 bIncludeTable
= sChartAddress
.isEmpty();
3637 catch( const beans::UnknownPropertyException
& )
3639 SAL_WARN("xmloff.chart", "Property ChartRangeAddress not supported by ChartDocument" );
3645 maExportHelper
.m_pImpl
->exportChart( xChartDoc
, bIncludeTable
);
3649 SAL_WARN("xmloff.chart", "Couldn't export chart due to wrong XModel" );
3653 UniReference
< XMLPropertySetMapper
> SchXMLExport::GetPropertySetMapper() const
3655 return maExportHelper
.m_pImpl
->GetPropertySetMapper();
3658 void SchXMLExportHelper_Impl::InitRangeSegmentationProperties( const Reference
< chart2::XChartDocument
> & xChartDoc
)
3663 Reference
< chart2::data::XDataProvider
> xDataProvider( xChartDoc
->getDataProvider() );
3664 SAL_WARN_IF( !xDataProvider
.is(), "xmloff.chart", "No DataProvider" );
3665 if( xDataProvider
.is())
3667 Reference
< chart2::data::XDataSource
> xDataSource( lcl_pressUsedDataIntoRectangularFormat( xChartDoc
, mbHasCategoryLabels
));
3668 Sequence
< beans::PropertyValue
> aArgs( xDataProvider
->detectArguments( xDataSource
));
3669 OUString sCellRange
, sBrokenRange
;
3670 bool bBrokenRangeAvailable
= false;
3671 for( sal_Int32 i
=0; i
<aArgs
.getLength(); ++i
)
3673 if ( aArgs
[i
].Name
== "CellRangeRepresentation" )
3674 aArgs
[i
].Value
>>= sCellRange
;
3675 else if ( aArgs
[i
].Name
== "BrokenCellRangeForExport" )
3677 if( aArgs
[i
].Value
>>= sBrokenRange
)
3678 bBrokenRangeAvailable
= true;
3680 else if ( aArgs
[i
].Name
== "DataRowSource" )
3682 chart::ChartDataRowSource eRowSource
;
3683 aArgs
[i
].Value
>>= eRowSource
;
3684 mbRowSourceColumns
= ( eRowSource
== chart::ChartDataRowSource_COLUMNS
);
3686 else if ( aArgs
[i
].Name
== "FirstCellAsLabel" )
3687 aArgs
[i
].Value
>>= mbHasSeriesLabels
;
3688 else if ( aArgs
[i
].Name
== "SequenceMapping" )
3689 aArgs
[i
].Value
>>= maSequenceMapping
;
3690 else if ( aArgs
[i
].Name
== "TableNumberList" )
3691 aArgs
[i
].Value
>>= msTableNumberList
;
3694 // #i79009# For Writer we have to export a broken version of the
3695 // range, where every row number is noe too large, so that older
3696 // version can correctly read those files.
3697 msChartAddress
= (bBrokenRangeAvailable
? sBrokenRange
: sCellRange
);
3698 if( !msChartAddress
.isEmpty() )
3700 // convert format to XML-conform one
3701 Reference
< chart2::data::XRangeXMLConversion
> xConversion( xDataProvider
, uno::UNO_QUERY
);
3702 if( xConversion
.is())
3703 msChartAddress
= xConversion
->convertRangeToXML( msChartAddress
);
3707 catch( const uno::Exception
& ex
)
3709 SAL_WARN("xmloff.chart", "Exception caught. Type: " << OUString::createFromAscii( typeid( ex
).name()) << ", Message: " << ex
.Message
);
3713 // export components ========================================
3715 // first version: everything goes in one storage
3717 Sequence
< OUString
> SAL_CALL
SchXMLExport_getSupportedServiceNames() throw()
3719 const OUString
aServiceName( "com.sun.star.comp.Chart.XMLExporter" );
3720 const Sequence
< OUString
> aSeq( &aServiceName
, 1 );
3724 OUString SAL_CALL
SchXMLExport_getImplementationName() throw()
3726 return OUString( "SchXMLExport.Compact" );
3729 Reference
< uno::XInterface
> SAL_CALL
SchXMLExport_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
) throw( uno::Exception
)
3732 // #103997# removed some flags from EXPORT_ALL
3733 return (cppu::OWeakObject
*)new SchXMLExport( comphelper::getComponentContext(rSMgr
), EXPORT_ALL
^ ( EXPORT_SETTINGS
| EXPORT_MASTERSTYLES
| EXPORT_SCRIPTS
));
3737 Sequence
< OUString
> SAL_CALL
SchXMLExport_Oasis_getSupportedServiceNames() throw()
3739 const OUString
aServiceName( "com.sun.star.comp.Chart.XMLOasisExporter" );
3740 const Sequence
< OUString
> aSeq( &aServiceName
, 1 );
3744 OUString SAL_CALL
SchXMLExport_Oasis_getImplementationName() throw()
3746 return OUString( "SchXMLExport.Oasis.Compact" );
3749 Reference
< uno::XInterface
> SAL_CALL
SchXMLExport_Oasis_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
) throw( uno::Exception
)
3751 // #103997# removed some flags from EXPORT_ALL
3752 return (cppu::OWeakObject
*)new SchXMLExport( comphelper::getComponentContext(rSMgr
),
3753 (EXPORT_ALL
^ ( EXPORT_SETTINGS
| EXPORT_MASTERSTYLES
| EXPORT_SCRIPTS
)) | EXPORT_OASIS
);
3756 // ============================================================
3758 // multiple storage version: one for content / styles / meta
3760 Sequence
< OUString
> SAL_CALL
SchXMLExport_Styles_getSupportedServiceNames() throw()
3762 const OUString
aServiceName( "com.sun.star.comp.Chart.XMLStylesExporter" );
3763 const Sequence
< OUString
> aSeq( &aServiceName
, 1 );
3767 OUString SAL_CALL
SchXMLExport_Styles_getImplementationName() throw()
3769 return OUString( "SchXMLExport.Styles" );
3772 Reference
< uno::XInterface
> SAL_CALL
SchXMLExport_Styles_createInstance(const Reference
< lang::XMultiServiceFactory
>& rSMgr
) throw( uno::Exception
)
3775 return (cppu::OWeakObject
*)new SchXMLExport( comphelper::getComponentContext(rSMgr
), EXPORT_STYLES
);
3779 Sequence
< OUString
> SAL_CALL
SchXMLExport_Oasis_Styles_getSupportedServiceNames() throw()
3781 const OUString
aServiceName( "com.sun.star.comp.Chart.XMLOasisStylesExporter" );
3782 const Sequence
< OUString
> aSeq( &aServiceName
, 1 );
3786 OUString SAL_CALL
SchXMLExport_Oasis_Styles_getImplementationName() throw()
3788 return OUString( "SchXMLExport.Oasis.Styles" );
3791 Reference
< uno::XInterface
> SAL_CALL
SchXMLExport_Oasis_Styles_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
) throw( uno::Exception
)
3793 return (cppu::OWeakObject
*)new SchXMLExport( comphelper::getComponentContext(rSMgr
), EXPORT_STYLES
| EXPORT_OASIS
);
3796 // ------------------------------------------------------------
3798 Sequence
< OUString
> SAL_CALL
SchXMLExport_Content_getSupportedServiceNames() throw()
3800 const OUString
aServiceName( "com.sun.star.comp.Chart.XMLContentExporter" );
3801 const Sequence
< OUString
> aSeq( &aServiceName
, 1 );
3805 OUString SAL_CALL
SchXMLExport_Content_getImplementationName() throw()
3807 return OUString( "SchXMLExport.Content" );
3810 Reference
< uno::XInterface
> SAL_CALL
SchXMLExport_Content_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
) throw( uno::Exception
)
3813 return (cppu::OWeakObject
*)new SchXMLExport( comphelper::getComponentContext(rSMgr
), EXPORT_AUTOSTYLES
| EXPORT_CONTENT
| EXPORT_FONTDECLS
);
3817 Sequence
< OUString
> SAL_CALL
SchXMLExport_Oasis_Content_getSupportedServiceNames() throw()
3819 const OUString
aServiceName( "com.sun.star.comp.Chart.XMLOasisContentExporter" );
3820 const Sequence
< OUString
> aSeq( &aServiceName
, 1 );
3824 OUString SAL_CALL
SchXMLExport_Oasis_Content_getImplementationName() throw()
3826 return OUString( "SchXMLExport.Oasis.Content" );
3829 Reference
< uno::XInterface
> SAL_CALL
SchXMLExport_Oasis_Content_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
) throw( uno::Exception
)
3831 return (cppu::OWeakObject
*)new SchXMLExport( comphelper::getComponentContext(rSMgr
), EXPORT_AUTOSTYLES
| EXPORT_CONTENT
| EXPORT_FONTDECLS
| EXPORT_OASIS
);
3834 // ------------------------------------------------------------
3837 Sequence
< OUString
> SAL_CALL
SchXMLExport_Oasis_Meta_getSupportedServiceNames() throw()
3839 const OUString
aServiceName( "com.sun.star.comp.Chart.XMLOasisMetaExporter" );
3840 const Sequence
< OUString
> aSeq( &aServiceName
, 1 );
3844 OUString SAL_CALL
SchXMLExport_Oasis_Meta_getImplementationName() throw()
3846 return OUString( "SchXMLExport.Oasis.Meta" );
3849 Reference
< uno::XInterface
> SAL_CALL
SchXMLExport_Oasis_Meta_createInstance(const Reference
< lang::XMultiServiceFactory
> & rSMgr
) throw( uno::Exception
)
3851 return (cppu::OWeakObject
*)new SchXMLExport( comphelper::getComponentContext(rSMgr
), EXPORT_META
| EXPORT_OASIS
);
3856 OUString SAL_CALL
SchXMLExport::getImplementationName() throw( uno::RuntimeException
)
3858 switch( getExportFlags())
3861 return SchXMLExport_getImplementationName();
3863 return SchXMLExport_Styles_getImplementationName();
3864 case ( EXPORT_AUTOSTYLES
| EXPORT_CONTENT
| EXPORT_FONTDECLS
):
3865 return SchXMLExport_Content_getImplementationName();
3868 case ( EXPORT_ALL
| EXPORT_OASIS
):
3869 return SchXMLExport_Oasis_getImplementationName();
3870 case ( EXPORT_STYLES
| EXPORT_OASIS
):
3871 return SchXMLExport_Oasis_Styles_getImplementationName();
3872 case ( EXPORT_AUTOSTYLES
| EXPORT_CONTENT
| EXPORT_FONTDECLS
| EXPORT_OASIS
):
3873 return SchXMLExport_Oasis_Content_getImplementationName();
3874 case ( EXPORT_META
| EXPORT_OASIS
):
3875 return SchXMLExport_Oasis_Meta_getImplementationName();
3877 case EXPORT_SETTINGS
:
3878 // there is no settings component in chart
3880 return OUString( "SchXMLExport" );
3884 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */