Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <oox/token/tokens.hxx>
21 : #include "oox/core/xmlfilterbase.hxx"
22 : #include "oox/export/chartexport.hxx"
23 : #include "oox/export/utils.hxx"
24 : #include "oox/drawingml/chart/typegroupconverter.hxx"
25 :
26 : #include <cstdio>
27 :
28 : #include <com/sun/star/awt/Gradient.hpp>
29 : #include <com/sun/star/chart/XChartDocument.hpp>
30 : #include <com/sun/star/chart/ChartLegendPosition.hpp>
31 : #include <com/sun/star/chart/XTwoAxisXSupplier.hpp>
32 : #include <com/sun/star/chart/XTwoAxisYSupplier.hpp>
33 : #include <com/sun/star/chart/XAxisZSupplier.hpp>
34 : #include <com/sun/star/chart/XChartDataArray.hpp>
35 : #include <com/sun/star/chart/ChartDataRowSource.hpp>
36 : #include <com/sun/star/chart/ChartAxisAssign.hpp>
37 : #include <com/sun/star/chart/ChartSeriesAddress.hpp>
38 : #include <com/sun/star/chart/X3DDisplay.hpp>
39 : #include <com/sun/star/chart/XStatisticDisplay.hpp>
40 : #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
41 : #include <com/sun/star/chart/ChartSymbolType.hpp>
42 : #include <com/sun/star/chart/ChartAxisMarks.hpp>
43 : #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
44 : #include <com/sun/star/chart/ChartAxisPosition.hpp>
45 : #include <com/sun/star/chart/ChartSolidType.hpp>
46 : #include <com/sun/star/chart/DataLabelPlacement.hpp>
47 : #include <com/sun/star/chart/ErrorBarStyle.hpp>
48 :
49 : #include <com/sun/star/chart2/XChartDocument.hpp>
50 : #include <com/sun/star/chart2/XDiagram.hpp>
51 : #include <com/sun/star/chart2/RelativePosition.hpp>
52 : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
53 : #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
54 : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
55 : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
56 : #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
57 : #include <com/sun/star/chart2/DataPointLabel.hpp>
58 : #include <com/sun/star/chart2/Symbol.hpp>
59 : #include <com/sun/star/chart2/data/XDataSource.hpp>
60 : #include <com/sun/star/chart2/data/XDataSink.hpp>
61 : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
62 : #include <com/sun/star/chart2/data/XDataProvider.hpp>
63 : #include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
64 : #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
65 : #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
66 : #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
67 :
68 : #include <com/sun/star/beans/XPropertySet.hpp>
69 : #include <com/sun/star/beans/XPropertyState.hpp>
70 : #include <com/sun/star/container/XEnumerationAccess.hpp>
71 : #include <com/sun/star/drawing/XShape.hpp>
72 : #include <com/sun/star/drawing/FillStyle.hpp>
73 : #include <com/sun/star/drawing/BitmapMode.hpp>
74 : #include <com/sun/star/lang/XServiceName.hpp>
75 :
76 : #include <com/sun/star/table/CellAddress.hpp>
77 : #include <com/sun/star/sheet/XFormulaParser.hpp>
78 : #include <com/sun/star/sheet/XFormulaTokens.hpp>
79 : #include <com/sun/star/sheet/FormulaToken.hpp>
80 : #include <com/sun/star/sheet/AddressConvention.hpp>
81 :
82 : #include <com/sun/star/text/WritingMode.hpp>
83 : #include <com/sun/star/container/XNamed.hpp>
84 :
85 : #include <comphelper/processfactory.hxx>
86 : #include <xmloff/SchXMLSeriesHelper.hxx>
87 : #include "ColorPropertySet.hxx"
88 : #include <set>
89 :
90 : #include <rtl/math.hxx>
91 :
92 : using namespace ::com::sun::star;
93 : using namespace ::com::sun::star::uno;
94 : using namespace ::com::sun::star::drawing;
95 : using namespace ::oox::core;
96 : using ::com::sun::star::beans::PropertyState;
97 : using ::com::sun::star::beans::PropertyValue;
98 : using ::com::sun::star::beans::XPropertySet;
99 : using ::com::sun::star::beans::XPropertyState;
100 : using ::com::sun::star::container::XEnumeration;
101 : using ::com::sun::star::container::XEnumerationAccess;
102 : using ::com::sun::star::container::XIndexAccess;
103 : using ::com::sun::star::container::XNamed;
104 : using ::com::sun::star::io::XOutputStream;
105 : using ::com::sun::star::table::CellAddress;
106 : using ::com::sun::star::sheet::XFormulaParser;
107 : using ::com::sun::star::sheet::XFormulaTokens;
108 : using ::oox::core::XmlFilterBase;
109 : using ::sax_fastparser::FSHelperPtr;
110 :
111 : namespace cssc = com::sun::star::chart;
112 :
113 : DBG(extern void dump_pset(Reference< XPropertySet > rXPropSet));
114 :
115 : namespace oox { namespace drawingml {
116 :
117 0 : class lcl_MatchesRole : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool >
118 : {
119 : public:
120 0 : explicit lcl_MatchesRole( const OUString & aRole ) :
121 0 : m_aRole( aRole )
122 0 : {}
123 :
124 0 : bool operator () ( const Reference< chart2::data::XLabeledDataSequence > & xSeq ) const
125 : {
126 0 : if( !xSeq.is() )
127 0 : return false;
128 0 : Reference< beans::XPropertySet > xProp( xSeq->getValues(), uno::UNO_QUERY );
129 0 : OUString aRole;
130 :
131 0 : return ( xProp.is() &&
132 0 : (xProp->getPropertyValue(
133 0 : OUString( "Role" ) ) >>= aRole ) &&
134 0 : m_aRole.equals( aRole ));
135 : }
136 :
137 : private:
138 : OUString m_aRole;
139 : };
140 :
141 : template< typename T >
142 0 : void lcl_SequenceToVectorAppend( const Sequence< T > & rSource, ::std::vector< T > & rDestination )
143 : {
144 0 : rDestination.reserve( rDestination.size() + rSource.getLength());
145 0 : ::std::copy( rSource.getConstArray(), rSource.getConstArray() + rSource.getLength(),
146 0 : ::std::back_inserter( rDestination ));
147 0 : }
148 :
149 0 : Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const Reference< chart2::XDiagram > & xDiagram )
150 : {
151 0 : Reference< chart2::data::XLabeledDataSequence > xResult;
152 : try
153 : {
154 : Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
155 0 : xDiagram, uno::UNO_QUERY_THROW );
156 : Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
157 0 : xCooSysCnt->getCoordinateSystems());
158 0 : for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
159 : {
160 0 : Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[i] );
161 : OSL_ASSERT( xCooSys.is());
162 0 : for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
163 : {
164 0 : const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
165 0 : for(sal_Int32 nI=0; nI<=nMaxAxisIndex; ++nI)
166 : {
167 0 : Reference< chart2::XAxis > xAxis = xCooSys->getAxisByDimension( nN, nI );
168 : OSL_ASSERT( xAxis.is());
169 0 : if( xAxis.is())
170 : {
171 0 : chart2::ScaleData aScaleData = xAxis->getScaleData();
172 0 : if( aScaleData.Categories.is())
173 : {
174 0 : xResult.set( aScaleData.Categories );
175 0 : break;
176 0 : }
177 : }
178 0 : }
179 : }
180 0 : }
181 : }
182 0 : catch( const uno::Exception & ex )
183 : {
184 : (void)ex; // avoid warning for pro build
185 : OSL_FAIL( OUStringToOString(
186 : OUString( "Exception caught. Type: " ) +
187 : OUString::createFromAscii( typeid( ex ).name()) +
188 : OUString( ", Message: " ) +
189 : ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
190 : }
191 :
192 0 : return xResult;
193 : }
194 :
195 0 : Reference< chart2::data::XDataSource > lcl_createDataSource(
196 : const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aData )
197 : {
198 : Reference< uno::XComponentContext > xContext(
199 0 : comphelper::getProcessComponentContext() );
200 : Reference< chart2::data::XDataSink > xSink(
201 0 : xContext->getServiceManager()->createInstanceWithContext(
202 0 : "com.sun.star.chart2.data.DataSource", xContext ),
203 0 : uno::UNO_QUERY_THROW );
204 0 : if( xSink.is())
205 0 : xSink->setData( aData );
206 :
207 0 : return Reference< chart2::data::XDataSource >( xSink, uno::UNO_QUERY );
208 : }
209 :
210 0 : Sequence< Reference< chart2::data::XLabeledDataSequence > > lcl_getAllSeriesSequences( const Reference< chart2::XChartDocument >& xChartDoc )
211 : {
212 0 : ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aContainer;
213 0 : if( xChartDoc.is() )
214 : {
215 0 : Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
216 0 : ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( SchXMLSeriesHelper::getDataSeriesFromDiagram( xDiagram ));
217 0 : for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aSeriesIt( aSeriesVector.begin() )
218 0 : ; aSeriesIt != aSeriesVector.end(); ++aSeriesIt )
219 : {
220 0 : Reference< chart2::data::XDataSource > xDataSource( *aSeriesIt, uno::UNO_QUERY );
221 0 : if( !xDataSource.is() )
222 0 : continue;
223 0 : uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > aDataSequences( xDataSource->getDataSequences() );
224 0 : lcl_SequenceToVectorAppend( aDataSequences, aContainer );
225 0 : }
226 : }
227 :
228 0 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aRet( aContainer.size());
229 0 : ::std::copy( aContainer.begin(), aContainer.end(), aRet.getArray());
230 :
231 0 : return aRet;
232 : }
233 :
234 : Reference< chart2::data::XLabeledDataSequence >
235 0 : lcl_getDataSequenceByRole(
236 : const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aLabeledSeq,
237 : const OUString & rRole )
238 : {
239 0 : Reference< chart2::data::XLabeledDataSequence > aNoResult;
240 :
241 0 : const Reference< chart2::data::XLabeledDataSequence > * pBegin = aLabeledSeq.getConstArray();
242 0 : const Reference< chart2::data::XLabeledDataSequence > * pEnd = pBegin + aLabeledSeq.getLength();
243 : const Reference< chart2::data::XLabeledDataSequence > * pMatch =
244 0 : ::std::find_if( pBegin, pEnd, lcl_MatchesRole( rRole ));
245 :
246 0 : if( pMatch != pEnd )
247 0 : return *pMatch;
248 :
249 0 : return aNoResult;
250 : }
251 :
252 0 : Reference< chart2::data::XDataSource > lcl_pressUsedDataIntoRectangularFormat( const Reference< chart2::XChartDocument >& xChartDoc, bool& rOutSourceHasCategoryLabels )
253 : {
254 0 : ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aLabeledSeqVector;
255 :
256 : //categories are always the first sequence
257 0 : Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
258 0 : Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xDiagram ) );
259 0 : if( xCategories.is() )
260 0 : aLabeledSeqVector.push_back( xCategories );
261 0 : rOutSourceHasCategoryLabels = xCategories.is();
262 :
263 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeriesSeqVector(
264 0 : lcl_getAllSeriesSequences( xChartDoc ) );
265 :
266 : //the first x-values is always the next sequence //todo ... other x-values get lost for old format
267 : Reference< chart2::data::XLabeledDataSequence > xXValues(
268 0 : lcl_getDataSequenceByRole( aSeriesSeqVector, OUString("values-x") ) );
269 0 : if( xXValues.is() )
270 0 : aLabeledSeqVector.push_back( xXValues );
271 :
272 : //add all other sequences now without x-values
273 0 : lcl_MatchesRole aHasXValues( OUString("values-x") );
274 0 : for( sal_Int32 nN=0; nN<aSeriesSeqVector.getLength(); nN++ )
275 : {
276 0 : if( !aHasXValues( aSeriesSeqVector[nN] ) )
277 0 : aLabeledSeqVector.push_back( aSeriesSeqVector[nN] );
278 : }
279 :
280 0 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( aLabeledSeqVector.size() );
281 0 : ::std::copy( aLabeledSeqVector.begin(), aLabeledSeqVector.end(), aSeq.getArray() );
282 :
283 0 : return lcl_createDataSource( aSeq );
284 : }
285 :
286 0 : bool lcl_isSeriesAttachedToFirstAxis(
287 : const Reference< chart2::XDataSeries > & xDataSeries )
288 : {
289 0 : bool bResult=true;
290 :
291 : try
292 : {
293 0 : sal_Int32 nAxisIndex = 0;
294 0 : Reference< beans::XPropertySet > xProp( xDataSeries, uno::UNO_QUERY_THROW );
295 0 : if( xProp.is() )
296 0 : xProp->getPropertyValue("AttachedAxisIndex") >>= nAxisIndex;
297 0 : bResult = (0==nAxisIndex);
298 : }
299 0 : catch( const uno::Exception & ex )
300 : {
301 : (void)ex; // avoid warning for pro build
302 : OSL_FAIL( OUStringToOString(
303 : OUString( "Exception caught. Type: " ) +
304 : OUString::createFromAscii( typeid( ex ).name()) +
305 : OUString( ", Message: " ) +
306 : ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
307 : }
308 :
309 0 : return bResult;
310 : }
311 :
312 0 : OUString lcl_flattenStringSequence( const Sequence< OUString > & rSequence )
313 : {
314 0 : OUStringBuffer aResult;
315 0 : bool bPrecedeWithSpace = false;
316 0 : for( sal_Int32 nIndex=0; nIndex<rSequence.getLength(); ++nIndex )
317 : {
318 0 : if( !rSequence[nIndex].isEmpty())
319 : {
320 0 : if( bPrecedeWithSpace )
321 0 : aResult.append( ' ' );
322 0 : aResult.append( rSequence[nIndex] );
323 0 : bPrecedeWithSpace = true;
324 : }
325 : }
326 0 : return aResult.makeStringAndClear();
327 : }
328 :
329 0 : OUString lcl_getLabelString( const Reference< chart2::data::XDataSequence > & xLabelSeq )
330 : {
331 0 : Sequence< OUString > aLabels;
332 :
333 0 : uno::Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xLabelSeq, uno::UNO_QUERY );
334 0 : if( xTextualDataSequence.is())
335 : {
336 0 : aLabels = xTextualDataSequence->getTextualData();
337 : }
338 0 : else if( xLabelSeq.is())
339 : {
340 0 : Sequence< uno::Any > aAnies( xLabelSeq->getData());
341 0 : aLabels.realloc( aAnies.getLength());
342 0 : for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
343 0 : aAnies[i] >>= aLabels[i];
344 : }
345 :
346 0 : return lcl_flattenStringSequence( aLabels );
347 : }
348 :
349 0 : void lcl_fillCategoriesIntoStringVector(
350 : const Reference< chart2::data::XDataSequence > & xCategories,
351 : ::std::vector< OUString > & rOutCategories )
352 : {
353 : OSL_ASSERT( xCategories.is());
354 0 : if( !xCategories.is())
355 0 : return;
356 0 : Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xCategories, uno::UNO_QUERY );
357 0 : if( xTextualDataSequence.is())
358 : {
359 0 : rOutCategories.clear();
360 0 : Sequence< OUString > aTextData( xTextualDataSequence->getTextualData());
361 0 : ::std::copy( aTextData.getConstArray(), aTextData.getConstArray() + aTextData.getLength(),
362 0 : ::std::back_inserter( rOutCategories ));
363 : }
364 : else
365 : {
366 0 : Sequence< uno::Any > aAnies( xCategories->getData());
367 0 : rOutCategories.resize( aAnies.getLength());
368 0 : for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
369 0 : aAnies[i] >>= rOutCategories[i];
370 0 : }
371 : }
372 :
373 0 : ::std::vector< double > lcl_getAllValuesFromSequence( const Reference< chart2::data::XDataSequence > & xSeq )
374 : {
375 0 : double fNan = 0.0;
376 0 : ::rtl::math::setNan( &fNan );
377 0 : ::std::vector< double > aResult;
378 :
379 0 : Reference< chart2::data::XNumericalDataSequence > xNumSeq( xSeq, uno::UNO_QUERY );
380 0 : if( xNumSeq.is())
381 : {
382 0 : Sequence< double > aValues( xNumSeq->getNumericalData());
383 0 : ::std::copy( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(),
384 0 : ::std::back_inserter( aResult ));
385 : }
386 0 : else if( xSeq.is())
387 : {
388 0 : Sequence< uno::Any > aAnies( xSeq->getData());
389 0 : aResult.resize( aAnies.getLength(), fNan );
390 0 : for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
391 0 : aAnies[i] >>= aResult[i];
392 : }
393 0 : return aResult;
394 : }
395 :
396 0 : sal_Int32 lcl_getChartType( const OUString& sChartType )
397 : {
398 0 : chart::TypeId eChartTypeId = chart::TYPEID_UNKNOWN;
399 0 : if( sChartType == "com.sun.star.chart.BarDiagram"
400 0 : || sChartType == "com.sun.star.chart2.ColumnChartType" )
401 0 : eChartTypeId = chart::TYPEID_BAR;
402 0 : else if( sChartType == "com.sun.star.chart.AreaDiagram"
403 0 : || sChartType == "com.sun.star.chart2.AreaChartType" )
404 0 : eChartTypeId = chart::TYPEID_AREA;
405 0 : else if( sChartType == "com.sun.star.chart.LineDiagram"
406 0 : || sChartType == "com.sun.star.chart2.LineChartType" )
407 0 : eChartTypeId = chart::TYPEID_LINE;
408 0 : else if( sChartType == "com.sun.star.chart.PieDiagram"
409 0 : || sChartType == "com.sun.star.chart2.PieChartType" )
410 0 : eChartTypeId = chart::TYPEID_PIE;
411 0 : else if( sChartType == "com.sun.star.chart.DonutDiagram"
412 0 : || sChartType == "com.sun.star.chart2.DonutChartType" )
413 0 : eChartTypeId = chart::TYPEID_DOUGHNUT;
414 0 : else if( sChartType == "com.sun.star.chart.XYDiagram"
415 0 : || sChartType == "com.sun.star.chart2.ScatterChartType" )
416 0 : eChartTypeId = chart::TYPEID_SCATTER;
417 0 : else if( sChartType == "com.sun.star.chart.NetDiagram"
418 0 : || sChartType == "com.sun.star.chart2.NetChartType" )
419 0 : eChartTypeId = chart::TYPEID_RADARLINE;
420 0 : else if( sChartType == "com.sun.star.chart.FilledNetDiagram"
421 0 : || sChartType == "com.sun.star.chart2.FilledNetChartType" )
422 0 : eChartTypeId = chart::TYPEID_RADARAREA;
423 0 : else if( sChartType == "com.sun.star.chart.StockDiagram"
424 0 : || sChartType == "com.sun.star.chart2.CandleStickChartType" )
425 0 : eChartTypeId = chart::TYPEID_STOCK;
426 0 : else if( sChartType == "com.sun.star.chart.BubbleDiagram"
427 0 : || sChartType == "com.sun.star.chart2.BubbleChartType" )
428 0 : eChartTypeId = chart::TYPEID_BUBBLE;
429 :
430 0 : return eChartTypeId;
431 : }
432 :
433 0 : sal_Int32 lcl_generateRandomValue()
434 : {
435 : static sal_Int32 MAX_NUMBER = 100000000;
436 0 : return sal_Int32( rand() % MAX_NUMBER );
437 : }
438 :
439 0 : ChartExport::ChartExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, Reference< frame::XModel >& xModel, XmlFilterBase* pFB, DocumentType eDocumentType )
440 : : DrawingML( pFS, pFB, eDocumentType )
441 : , mnXmlNamespace( nXmlNamespace )
442 : , mnSeriesCount(0)
443 : , maFraction( 1, 576 )
444 : , mxChartModel( xModel )
445 : , mbHasCategoryLabels( false )
446 : , mbHasZAxis( false )
447 0 : , mbIs3DChart( false )
448 : {
449 0 : }
450 :
451 0 : sal_Int32 ChartExport::GetChartID( )
452 : {
453 0 : sal_Int32 nID = GetFB()->GetUniqueId();
454 0 : return nID;
455 : }
456 :
457 0 : sal_Int32 ChartExport::getChartType( )
458 : {
459 0 : OUString sChartType = mxDiagram->getDiagramType();
460 0 : return lcl_getChartType( sChartType );
461 : }
462 :
463 0 : OUString ChartExport::parseFormula( const OUString& rRange )
464 : {
465 0 : OUString aResult;
466 0 : Reference< XFormulaParser > xParser;
467 0 : uno::Reference< lang::XMultiServiceFactory > xSF( GetFB()->getModelFactory(), uno::UNO_QUERY );
468 0 : if( xSF.is() )
469 : {
470 : try
471 : {
472 0 : xParser.set( xSF->createInstance("com.sun.star.sheet.FormulaParser"), UNO_QUERY );
473 : }
474 0 : catch( Exception& )
475 : {
476 : }
477 : }
478 0 : if( xParser.is() )
479 : {
480 : OSL_TRACE("ChartExport::parseFormula, parser is valid");
481 0 : Reference< XPropertySet > xParserProps( xParser, uno::UNO_QUERY );
482 0 : if( xParserProps.is() )
483 : {
484 0 : xParserProps->setPropertyValue("FormulaConvention", uno::makeAny(::com::sun::star::sheet::AddressConvention::OOO) );
485 : }
486 0 : uno::Sequence<sheet::FormulaToken> aTokens = xParser->parseFormula( rRange, CellAddress( 0, 0, 0 ) );
487 0 : if( xParserProps.is() )
488 : {
489 0 : xParserProps->setPropertyValue("FormulaConvention", uno::makeAny(::com::sun::star::sheet::AddressConvention::XL_OOX) );
490 : }
491 0 : aResult = xParser->printFormula( aTokens, CellAddress( 0, 0, 0 ) );
492 : }
493 : else
494 : {
495 : OSL_TRACE("ChartExport::parseFormula, parser is invalid");
496 : //FIXME: currently just using simple converter, e.g $Sheet1.$A$1:$C$1 -> Sheet1!$A$1:$C$1
497 0 : OUString aRange( rRange );
498 0 : if( aRange.startsWith("$") )
499 0 : aRange = aRange.copy(1);
500 0 : aRange = aRange.replaceAll(".$", "!$" );
501 0 : aResult = aRange;
502 : }
503 :
504 : OSL_TRACE("ChartExport::parseFormula, the originla formula is %s, the new formula is %s ", OUStringToOString( rRange, RTL_TEXTENCODING_UTF8 ).getStr(), OUStringToOString( aResult, RTL_TEXTENCODING_UTF8 ).getStr());
505 0 : return aResult;
506 : }
507 :
508 0 : ChartExport& ChartExport::WriteChartObj( const Reference< XShape >& xShape, sal_Int32 nChartCount )
509 : {
510 : OSL_TRACE("ChartExport::WriteChartObj -- writer chart object");
511 0 : FSHelperPtr pFS = GetFS();
512 :
513 0 : pFS->startElementNS( mnXmlNamespace, XML_graphicFrame, FSEND );
514 :
515 0 : pFS->startElementNS( mnXmlNamespace, XML_nvGraphicFramePr, FSEND );
516 :
517 : // TODO: get the correct chart name chart id
518 0 : OUString sName = "Object 1";
519 0 : Reference< XNamed > xNamed( xShape, UNO_QUERY );
520 0 : if (xNamed.is())
521 0 : sName = xNamed->getName();
522 :
523 0 : sal_Int32 nID = GetChartID();
524 :
525 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
526 : XML_id, I32S( nID ),
527 : XML_name, USS( sName ),
528 0 : FSEND );
529 :
530 : pFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr,
531 0 : FSEND );
532 :
533 0 : if( GetDocumentType() == DOCUMENT_PPTX )
534 : pFS->singleElementNS( mnXmlNamespace, XML_nvPr,
535 0 : FSEND );
536 0 : pFS->endElementNS( mnXmlNamespace, XML_nvGraphicFramePr );
537 :
538 : // visual chart properties
539 0 : WriteShapeTransformation( xShape, mnXmlNamespace );
540 :
541 : // writer chart object
542 0 : pFS->startElement( FSNS( XML_a, XML_graphic ), FSEND );
543 : pFS->startElement( FSNS( XML_a, XML_graphicData ),
544 : XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/chart",
545 0 : FSEND );
546 0 : OUString sId;
547 0 : const char* sFullPath = NULL;
548 0 : const char* sRelativePath = NULL;
549 0 : switch( GetDocumentType() )
550 : {
551 : case DOCUMENT_DOCX:
552 : {
553 0 : sFullPath = "word/charts/chart";
554 0 : sRelativePath = "charts/chart";
555 0 : break;
556 : }
557 : case DOCUMENT_PPTX:
558 : {
559 0 : sFullPath = "ppt/charts/chart";
560 0 : sRelativePath = "../charts/chart";
561 0 : break;
562 : }
563 : case DOCUMENT_XLSX:
564 : {
565 0 : sFullPath = "xl/charts/chart";
566 0 : sRelativePath = "../charts/chart";
567 0 : break;
568 : }
569 : default:
570 : {
571 0 : sFullPath = "charts/chart";
572 0 : sRelativePath = "charts/chart";
573 0 : break;
574 : }
575 : }
576 : OUString sFullStream = OUStringBuffer()
577 0 : .appendAscii(sFullPath)
578 0 : .append(nChartCount)
579 0 : .appendAscii( ".xml" )
580 0 : .makeStringAndClear();
581 : OUString sRelativeStream = OUStringBuffer()
582 0 : .appendAscii(sRelativePath)
583 0 : .append(nChartCount)
584 0 : .appendAscii( ".xml" )
585 0 : .makeStringAndClear();
586 : FSHelperPtr pChart = CreateOutputStream(
587 : sFullStream,
588 : sRelativeStream,
589 : pFS->getOutputStream(),
590 : "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
591 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
592 0 : &sId );
593 :
594 : pFS->singleElement( FSNS( XML_c, XML_chart ),
595 : FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
596 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
597 : FSNS( XML_r, XML_id ), USS( sId ),
598 0 : FSEND );
599 :
600 0 : pFS->endElement( FSNS( XML_a, XML_graphicData ) );
601 0 : pFS->endElement( FSNS( XML_a, XML_graphic ) );
602 0 : pFS->endElementNS( mnXmlNamespace, XML_graphicFrame );
603 :
604 0 : SetFS( pChart );
605 0 : ExportContent();
606 :
607 0 : return *this;
608 : }
609 :
610 0 : void ChartExport::InitRangeSegmentationProperties( const Reference< chart2::XChartDocument > & xChartDoc )
611 : {
612 0 : if( xChartDoc.is())
613 : try
614 : {
615 0 : Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
616 : OSL_ENSURE( xDataProvider.is(), "No DataProvider" );
617 0 : if( xDataProvider.is())
618 : {
619 0 : Reference< chart2::data::XDataSource > xDataSource( lcl_pressUsedDataIntoRectangularFormat( xChartDoc, mbHasCategoryLabels ));
620 0 : Sequence< beans::PropertyValue > aArgs( xDataProvider->detectArguments( xDataSource ));
621 0 : OUString sCellRange, sBrokenRange;
622 0 : bool bBrokenRangeAvailable = false;
623 0 : for( sal_Int32 i=0; i<aArgs.getLength(); ++i )
624 : {
625 0 : if ( aArgs[i].Name == "CellRangeRepresentation" )
626 0 : aArgs[i].Value >>= sCellRange;
627 0 : else if ( aArgs[i].Name == "BrokenCellRangeForExport" )
628 : {
629 0 : if( aArgs[i].Value >>= sBrokenRange )
630 0 : bBrokenRangeAvailable = true;
631 : }
632 0 : else if ( aArgs[i].Name == "SequenceMapping" )
633 0 : aArgs[i].Value >>= maSequenceMapping;
634 : }
635 :
636 : // #i79009# For Writer we have to export a broken version of the
637 : // range, where every row number is noe too large, so that older
638 : // version can correctly read those files.
639 0 : msChartAddress = (bBrokenRangeAvailable ? sBrokenRange : sCellRange);
640 0 : if( !msChartAddress.isEmpty() )
641 : {
642 : // convert format to XML-conform one
643 0 : Reference< chart2::data::XRangeXMLConversion > xConversion( xDataProvider, uno::UNO_QUERY );
644 0 : if( xConversion.is())
645 0 : msChartAddress = xConversion->convertRangeToXML( msChartAddress );
646 0 : }
647 0 : }
648 : }
649 0 : catch( const uno::Exception & ex )
650 : {
651 : (void)ex; // avoid warning for pro build
652 : OSL_FAIL( OUStringToOString(
653 : OUString( "Exception caught. Type: " ) +
654 : OUString::createFromAscii( typeid( ex ).name()) +
655 : OUString( ", Message: " ) +
656 : ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
657 : }
658 0 : }
659 :
660 0 : void ChartExport::ExportContent()
661 : {
662 0 : Reference< chart2::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
663 : OSL_ASSERT( xChartDoc.is() );
664 0 : if( !xChartDoc.is() )
665 0 : return;
666 0 : InitRangeSegmentationProperties( xChartDoc );
667 : // TODO: export chart
668 0 : _ExportContent( );
669 : }
670 :
671 0 : void ChartExport::_ExportContent()
672 : {
673 0 : Reference< ::com::sun::star::chart::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
674 0 : if( xChartDoc.is())
675 : {
676 : // determine if data comes from the outside
677 0 : bool bIncludeTable = true;
678 :
679 0 : Reference< chart2::XChartDocument > xNewDoc( xChartDoc, uno::UNO_QUERY );
680 0 : if( xNewDoc.is())
681 : {
682 : // check if we have own data. If so we must not export the complete
683 : // range string, as this is our only indicator for having own or
684 : // external data. @todo: fix this in the file format!
685 0 : Reference< lang::XServiceInfo > xDPServiceInfo( xNewDoc->getDataProvider(), uno::UNO_QUERY );
686 0 : if( ! (xDPServiceInfo.is() && xDPServiceInfo->getImplementationName() == "com.sun.star.comp.chart.InternalDataProvider" ))
687 : {
688 0 : bIncludeTable = false;
689 0 : }
690 : }
691 : else
692 : {
693 0 : Reference< lang::XServiceInfo > xServ( xChartDoc, uno::UNO_QUERY );
694 0 : if( xServ.is())
695 : {
696 0 : if( xServ->supportsService(
697 0 : OUString("com.sun.star.chart.ChartTableAddressSupplier")))
698 : {
699 0 : Reference< beans::XPropertySet > xProp( xServ, uno::UNO_QUERY );
700 0 : if( xProp.is())
701 : {
702 0 : Any aAny;
703 : try
704 : {
705 0 : OUString sChartAddress;
706 0 : aAny = xProp->getPropertyValue(
707 0 : OUString("ChartRangeAddress"));
708 0 : aAny >>= msChartAddress;
709 : //maExportHelper.SetChartRangeAddress( sChartAddress );
710 :
711 : //maExportHelper.SetTableNumberList( sTableNumberList );
712 :
713 : // do not include own table if there are external addresses
714 0 : bIncludeTable = sChartAddress.isEmpty();
715 : }
716 0 : catch( beans::UnknownPropertyException & )
717 : {
718 : OSL_FAIL( "Property ChartRangeAddress not supported by ChartDocument" );
719 0 : }
720 0 : }
721 : }
722 0 : }
723 : }
724 0 : exportChartSpace( xChartDoc, bIncludeTable );
725 : }
726 : else
727 : {
728 : OSL_FAIL( "Couldn't export chart due to wrong XModel" );
729 0 : }
730 0 : }
731 :
732 0 : void ChartExport::exportChartSpace( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc,
733 : bool bIncludeTable )
734 : {
735 0 : FSHelperPtr pFS = GetFS();
736 : pFS->startElement( FSNS( XML_c, XML_chartSpace ),
737 : FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
738 : FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
739 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
740 0 : FSEND );
741 : // TODO: get the correct editing lanauge
742 : pFS->singleElement( FSNS( XML_c, XML_lang ),
743 : XML_val, "en-US",
744 0 : FSEND );
745 :
746 0 : if( !bIncludeTable )
747 : {
748 : // TODO:external data
749 : }
750 : //XML_chart
751 0 : exportChart(rChartDoc);
752 :
753 : // TODO: printSettings
754 : // TODO: style
755 : // TODO: text properties
756 : // TODO: shape properties
757 0 : Reference< XPropertySet > xPropSet( rChartDoc->getArea(), uno::UNO_QUERY );
758 0 : if( xPropSet.is() )
759 0 : exportShapeProps( xPropSet );
760 :
761 : //XML_externalData
762 0 : exportExternalData(rChartDoc);
763 :
764 0 : pFS->endElement( FSNS( XML_c, XML_chartSpace ) );
765 0 : }
766 :
767 0 : void ChartExport::exportExternalData( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc )
768 : {
769 : // Embedded external data is grab bagged for docx file hence adding export part of
770 : // external data for docx files only.
771 0 : if(GetDocumentType() != DOCUMENT_DOCX)
772 0 : return;
773 :
774 0 : OUString externalDataPath;
775 0 : Reference< beans::XPropertySet > xDocPropSet( rChartDoc->getDiagram(), uno::UNO_QUERY );
776 0 : if( xDocPropSet.is())
777 : {
778 : try
779 : {
780 0 : Any aAny( xDocPropSet->getPropertyValue(
781 0 : OUString( "ExternalData" )));
782 0 : aAny >>= externalDataPath;
783 : }
784 0 : catch( beans::UnknownPropertyException & )
785 : {
786 : DBG_WARNING( "Required property not found in ChartDocument" );
787 : }
788 : }
789 0 : if(!externalDataPath.isEmpty())
790 : {
791 : // Here adding external data entry to relationship.
792 0 : OUString relationPath = externalDataPath;
793 : // Converting absolute path to relative path.
794 0 : if( externalDataPath[ 0 ] != '.' && externalDataPath[ 1 ] != '.')
795 : {
796 0 : sal_Int32 nStartPos = 0;
797 0 : sal_Int32 nSepPos = externalDataPath.indexOf( '/', nStartPos );
798 0 : if( nSepPos > 0)
799 : {
800 0 : relationPath = relationPath.copy( nSepPos, ::std::max< sal_Int32 >( externalDataPath.getLength(), 0 ) - nSepPos );
801 0 : relationPath = OUStringBuffer( ".." ).append( relationPath ).makeStringAndClear();
802 : }
803 : }
804 0 : FSHelperPtr pFS = GetFS();
805 0 : OUString type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package";
806 0 : if (relationPath.endsWith(OUString(".bin")))
807 0 : type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject";
808 :
809 : OUString sRelId = GetFB()->addRelation(pFS->getOutputStream(),
810 : type,
811 0 : relationPath);
812 : pFS->singleElementNS( XML_c, XML_externalData,
813 : FSNS(XML_r, XML_id), OUStringToOString(sRelId, RTL_TEXTENCODING_UTF8),
814 0 : FSEND);
815 0 : }
816 : }
817 :
818 0 : void ChartExport::exportChart( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc )
819 : {
820 0 : Reference< chart2::XChartDocument > xNewDoc( rChartDoc, uno::UNO_QUERY );
821 0 : mxDiagram.set( rChartDoc->getDiagram() );
822 0 : if( xNewDoc.is())
823 0 : mxNewDiagram.set( xNewDoc->getFirstDiagram());
824 :
825 : // get Properties of ChartDocument
826 0 : sal_Bool bHasMainTitle = sal_False;
827 0 : sal_Bool bHasSubTitle = sal_False;
828 0 : sal_Bool bHasLegend = sal_False;
829 0 : Reference< beans::XPropertySet > xDocPropSet( rChartDoc, uno::UNO_QUERY );
830 0 : if( xDocPropSet.is())
831 : {
832 : try
833 : {
834 0 : Any aAny( xDocPropSet->getPropertyValue(
835 0 : OUString( "HasMainTitle" )));
836 0 : aAny >>= bHasMainTitle;
837 0 : aAny = xDocPropSet->getPropertyValue(
838 0 : OUString( "HasSubTitle" ));
839 0 : aAny >>= bHasSubTitle;
840 0 : aAny = xDocPropSet->getPropertyValue(
841 0 : OUString( "HasLegend" ));
842 0 : aAny >>= bHasLegend;
843 : }
844 0 : catch( beans::UnknownPropertyException & )
845 : {
846 : DBG_WARNING( "Required property not found in ChartDocument" );
847 : }
848 : } // if( xDocPropSet.is())
849 :
850 : // chart element
851 :
852 0 : FSHelperPtr pFS = GetFS();
853 : pFS->startElement( FSNS( XML_c, XML_chart ),
854 0 : FSEND );
855 :
856 : // title
857 0 : if( bHasMainTitle )
858 : {
859 0 : Reference< drawing::XShape > xShape = rChartDoc->getTitle();
860 0 : if( xShape.is() )
861 0 : exportTitle( xShape );
862 : }
863 0 : InitPlotArea( );
864 0 : if( mbIs3DChart )
865 : {
866 0 : exportView3D();
867 :
868 : // floor
869 0 : Reference< beans::XPropertySet > xFloor( mxNewDiagram->getFloor(), uno::UNO_QUERY );
870 0 : if( xFloor.is() )
871 : {
872 : pFS->startElement( FSNS( XML_c, XML_floor ),
873 0 : FSEND );
874 0 : exportShapeProps( xFloor );
875 0 : pFS->endElement( FSNS( XML_c, XML_floor ) );
876 : }
877 :
878 : // sideWall
879 :
880 : // backWall
881 0 : Reference< beans::XPropertySet > xBackWall( mxNewDiagram->getWall(), uno::UNO_QUERY );
882 0 : if( xBackWall.is() )
883 : {
884 : pFS->startElement( FSNS( XML_c, XML_backWall ),
885 0 : FSEND );
886 0 : exportShapeProps( xBackWall );
887 0 : pFS->endElement( FSNS( XML_c, XML_backWall ) );
888 0 : }
889 :
890 : }
891 : // plot area
892 0 : exportPlotArea( );
893 : // legend
894 0 : if( bHasLegend )
895 0 : exportLegend( rChartDoc );
896 : // only visible cells should be plotted on the chart
897 : pFS->singleElement( FSNS( XML_c, XML_plotVisOnly ),
898 : XML_val, "1",
899 0 : FSEND );
900 :
901 0 : pFS->endElement( FSNS( XML_c, XML_chart ) );
902 0 : }
903 :
904 0 : void ChartExport::exportLegend( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc )
905 : {
906 0 : FSHelperPtr pFS = GetFS();
907 : pFS->startElement( FSNS( XML_c, XML_legend ),
908 0 : FSEND );
909 :
910 0 : Reference< beans::XPropertySet > xProp( rChartDoc->getLegend(), uno::UNO_QUERY );
911 0 : if( xProp.is() )
912 : {
913 : // position
914 0 : ::com::sun::star::chart::ChartLegendPosition aLegendPos = ::com::sun::star::chart::ChartLegendPosition_NONE;
915 : try
916 : {
917 0 : Any aAny( xProp->getPropertyValue(
918 0 : OUString( "Alignment" )));
919 0 : aAny >>= aLegendPos;
920 : }
921 0 : catch( beans::UnknownPropertyException & )
922 : {
923 : DBG_WARNING( "Property Align not found in ChartLegend" );
924 : }
925 :
926 0 : const char* strPos = NULL;
927 0 : switch( aLegendPos )
928 : {
929 : case ::com::sun::star::chart::ChartLegendPosition_LEFT:
930 0 : strPos = "l";
931 0 : break;
932 : case ::com::sun::star::chart::ChartLegendPosition_RIGHT:
933 0 : strPos = "r";
934 0 : break;
935 : case ::com::sun::star::chart::ChartLegendPosition_TOP:
936 0 : strPos = "t";
937 0 : break;
938 : case ::com::sun::star::chart::ChartLegendPosition_BOTTOM:
939 0 : strPos = "b";
940 0 : break;
941 : case ::com::sun::star::chart::ChartLegendPosition_NONE:
942 : case ::com::sun::star::chart::ChartLegendPosition_MAKE_FIXED_SIZE:
943 : // nothing
944 0 : break;
945 : }
946 :
947 0 : if( strPos != NULL )
948 : {
949 : pFS->singleElement( FSNS( XML_c, XML_legendPos ),
950 : XML_val, strPos,
951 0 : FSEND );
952 : pFS->singleElement( FSNS( XML_c, XML_overlay ),
953 : XML_val, "0",
954 0 : FSEND );
955 : }
956 :
957 : // shape properties
958 0 : exportShapeProps( xProp );
959 : }
960 :
961 : // legendEntry
962 :
963 0 : pFS->endElement( FSNS( XML_c, XML_legend ) );
964 0 : }
965 :
966 0 : void ChartExport::exportTitle( Reference< XShape > xShape )
967 : {
968 0 : OUString sText;
969 0 : Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
970 0 : if( xPropSet.is())
971 : {
972 0 : xPropSet->getPropertyValue("String") >>= sText;
973 : }
974 0 : if( sText.isEmpty() )
975 0 : return;
976 :
977 0 : FSHelperPtr pFS = GetFS();
978 : pFS->startElement( FSNS( XML_c, XML_title ),
979 0 : FSEND );
980 :
981 : pFS->startElement( FSNS( XML_c, XML_tx ),
982 0 : FSEND );
983 : pFS->startElement( FSNS( XML_c, XML_rich ),
984 0 : FSEND );
985 :
986 : // TODO: bodyPr
987 0 : const char* sWritingMode = NULL;
988 0 : sal_Bool bVertical = sal_False;
989 0 : xPropSet->getPropertyValue("StackedText") >>= bVertical;
990 0 : if( bVertical )
991 0 : sWritingMode = "wordArtVert";
992 :
993 : pFS->singleElement( FSNS( XML_a, XML_bodyPr ),
994 : XML_vert, sWritingMode,
995 0 : FSEND );
996 : // TODO: lstStyle
997 : pFS->singleElement( FSNS( XML_a, XML_lstStyle ),
998 0 : FSEND );
999 : // FIXME: handle multipul paragraphs to parse aText
1000 : pFS->startElement( FSNS( XML_a, XML_p ),
1001 0 : FSEND );
1002 :
1003 : pFS->startElement( FSNS( XML_a, XML_pPr ),
1004 0 : FSEND );
1005 : pFS->singleElement( FSNS( XML_a, XML_defRPr ),
1006 0 : FSEND );
1007 0 : pFS->endElement( FSNS( XML_a, XML_pPr ) );
1008 :
1009 : pFS->startElement( FSNS( XML_a, XML_r ),
1010 0 : FSEND );
1011 0 : WriteRunProperties( xPropSet, false );
1012 : pFS->startElement( FSNS( XML_a, XML_t ),
1013 0 : FSEND );
1014 0 : pFS->writeEscaped( sText );
1015 0 : pFS->endElement( FSNS( XML_a, XML_t ) );
1016 0 : pFS->endElement( FSNS( XML_a, XML_r ) );
1017 :
1018 0 : pFS->endElement( FSNS( XML_a, XML_p ) );
1019 :
1020 0 : pFS->endElement( FSNS( XML_c, XML_rich ) );
1021 0 : pFS->endElement( FSNS( XML_c, XML_tx ) );
1022 :
1023 : // TODO:customize layout
1024 : pFS->singleElement( FSNS( XML_c, XML_layout ),
1025 0 : FSEND );
1026 :
1027 0 : pFS->endElement( FSNS( XML_c, XML_title ) );
1028 : }
1029 :
1030 0 : void ChartExport::exportPlotArea( )
1031 : {
1032 0 : Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( mxNewDiagram, uno::UNO_QUERY );
1033 0 : if( ! xBCooSysCnt.is())
1034 0 : return;
1035 :
1036 : // plot-area element
1037 :
1038 0 : FSHelperPtr pFS = GetFS();
1039 : pFS->startElement( FSNS( XML_c, XML_plotArea ),
1040 0 : FSEND );
1041 : // layout
1042 : pFS->singleElement( FSNS( XML_c, XML_layout ),
1043 0 : FSEND );
1044 :
1045 : // chart type
1046 : Sequence< Reference< chart2::XCoordinateSystem > >
1047 0 : aCooSysSeq( xBCooSysCnt->getCoordinateSystems());
1048 0 : for( sal_Int32 nCSIdx=0; nCSIdx<aCooSysSeq.getLength(); ++nCSIdx )
1049 : {
1050 :
1051 0 : Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCSIdx], uno::UNO_QUERY );
1052 0 : if( ! xCTCnt.is())
1053 0 : continue;
1054 0 : mnSeriesCount=0;
1055 0 : Sequence< Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes());
1056 0 : for( sal_Int32 nCTIdx=0; nCTIdx<aCTSeq.getLength(); ++nCTIdx )
1057 : {
1058 0 : Reference< chart2::XDataSeriesContainer > xDSCnt( aCTSeq[nCTIdx], uno::UNO_QUERY );
1059 0 : if( ! xDSCnt.is())
1060 0 : return;
1061 0 : Reference< chart2::XChartType > xChartType( aCTSeq[nCTIdx], uno::UNO_QUERY );
1062 0 : if( ! xChartType.is())
1063 0 : continue;
1064 : // note: if xDSCnt.is() then also aCTSeq[nCTIdx]
1065 0 : OUString aChartType( xChartType->getChartType());
1066 0 : sal_Int32 eChartType = lcl_getChartType( aChartType );
1067 0 : switch( eChartType )
1068 : {
1069 : case chart::TYPEID_BAR:
1070 : {
1071 0 : exportBarChart( xChartType );
1072 0 : break;
1073 : }
1074 : case chart::TYPEID_AREA:
1075 : {
1076 0 : exportAreaChart( xChartType );
1077 0 : break;
1078 : }
1079 : case chart::TYPEID_LINE:
1080 : {
1081 0 : exportLineChart( xChartType );
1082 0 : break;
1083 : }
1084 : case chart::TYPEID_BUBBLE:
1085 : {
1086 0 : exportBubbleChart( xChartType );
1087 0 : break;
1088 : }
1089 : case chart::TYPEID_OFPIE:
1090 : {
1091 0 : exportOfPieChart( xChartType );
1092 0 : break;
1093 : }
1094 : case chart::TYPEID_DOUGHNUT:
1095 : case chart::TYPEID_PIE:
1096 : {
1097 0 : exportPieChart( xChartType );
1098 0 : break;
1099 : }
1100 : case chart::TYPEID_RADARLINE:
1101 : case chart::TYPEID_RADARAREA:
1102 : {
1103 0 : exportRadarChart( xChartType );
1104 0 : break;
1105 : }
1106 : case chart::TYPEID_SCATTER:
1107 : {
1108 0 : exportScatterChart( xChartType );
1109 0 : break;
1110 : }
1111 : case chart::TYPEID_STOCK:
1112 : {
1113 0 : exportStockChart( xChartType );
1114 0 : break;
1115 : }
1116 : case chart::TYPEID_SURFACE:
1117 : {
1118 0 : exportSuffaceChart( xChartType );
1119 0 : break;
1120 : }
1121 : default:
1122 : {
1123 : OSL_TRACE("ChartExport::exportPlotArea -- not support chart type");
1124 0 : break;
1125 : }
1126 : }
1127 :
1128 0 : }
1129 0 : }
1130 : //Axis Data
1131 0 : exportAxes( );
1132 : // Data Table
1133 0 : exportDataTable();
1134 :
1135 : // shape properties
1136 : /*
1137 : * Export the Plot area Shape Properties
1138 : * eg: Fill and Outline
1139 : */
1140 0 : Reference< ::com::sun::star::chart::X3DDisplay > xWallFloorSupplier( mxDiagram, uno::UNO_QUERY );
1141 0 : if( xWallFloorSupplier.is() )
1142 : {
1143 0 : Reference< beans::XPropertySet > xWallPropSet( xWallFloorSupplier->getWall(), uno::UNO_QUERY );
1144 0 : if( xWallPropSet.is() )
1145 : {
1146 0 : exportPlotAreaShapeProps( xWallPropSet );
1147 0 : }
1148 : }
1149 :
1150 0 : pFS->endElement( FSNS( XML_c, XML_plotArea ) );
1151 :
1152 : }
1153 :
1154 0 : void ChartExport::exportPlotAreaShapeProps( Reference< XPropertySet > xPropSet )
1155 : {
1156 0 : FSHelperPtr pFS = GetFS();
1157 : pFS->startElement( FSNS( XML_c, XML_spPr ),
1158 0 : FSEND );
1159 :
1160 0 : exportFill( xPropSet );
1161 0 : WriteOutline( xPropSet );
1162 :
1163 0 : pFS->endElement( FSNS( XML_c, XML_spPr ) );
1164 0 : }
1165 :
1166 0 : void ChartExport::exportFill( Reference< XPropertySet > xPropSet )
1167 : {
1168 0 : if ( !GetProperty( xPropSet, "FillStyle" ) )
1169 0 : return;
1170 0 : FillStyle aFillStyle( FillStyle_NONE );
1171 0 : xPropSet->getPropertyValue( "FillStyle" ) >>= aFillStyle;
1172 0 : switch( aFillStyle )
1173 : {
1174 : case FillStyle_GRADIENT :
1175 0 : exportGradientFill( xPropSet );
1176 0 : break;
1177 : case FillStyle_BITMAP :
1178 0 : exportBitmapFill( xPropSet );
1179 0 : break;
1180 : default:
1181 0 : WriteFill( xPropSet );
1182 : }
1183 : }
1184 :
1185 0 : void ChartExport::exportBitmapFill( Reference< XPropertySet > xPropSet )
1186 : {
1187 0 : if( xPropSet.is() )
1188 : {
1189 0 : OUString sFillGradientName;
1190 0 : xPropSet->getPropertyValue("FillBitmapName") >>= sFillGradientName;
1191 :
1192 0 : uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY );
1193 : try
1194 : {
1195 0 : uno::Reference< container::XNameAccess > xGradient( xFact->createInstance("com.sun.star.drawing.BitmapTable"), uno::UNO_QUERY );
1196 0 : uno::Any rValue = xGradient->getByName( sFillGradientName );
1197 0 : OUString sBitmapURL;
1198 0 : if( (rValue >>= sBitmapURL) )
1199 : {
1200 0 : WriteBlipFill( xPropSet, sBitmapURL, XML_a, true, true );
1201 0 : }
1202 : }
1203 0 : catch (const uno::Exception & rEx)
1204 : {
1205 : SAL_INFO("oox", "ChartExport::exportBitmapFill " << rEx.Message);
1206 0 : }
1207 :
1208 : }
1209 0 : }
1210 :
1211 0 : void ChartExport::exportGradientFill( Reference< XPropertySet > xPropSet )
1212 : {
1213 0 : if( xPropSet.is() )
1214 : {
1215 0 : OUString sFillGradientName;
1216 0 : xPropSet->getPropertyValue("FillGradientName") >>= sFillGradientName;
1217 :
1218 0 : awt::Gradient aGradient;
1219 0 : uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY );
1220 : try
1221 : {
1222 0 : uno::Reference< container::XNameAccess > xGradient( xFact->createInstance("com.sun.star.drawing.GradientTable"), uno::UNO_QUERY );
1223 0 : uno::Any rValue = xGradient->getByName( sFillGradientName );
1224 0 : if( (rValue >>= aGradient) )
1225 : {
1226 0 : mpFS->startElementNS( XML_a, XML_gradFill, FSEND );
1227 0 : WriteGradientFill( aGradient );
1228 0 : mpFS->endElementNS( XML_a, XML_gradFill );
1229 0 : }
1230 : }
1231 0 : catch (const uno::Exception & rEx)
1232 : {
1233 : SAL_INFO("oox",
1234 : "ChartExport::exportGradientFill " << rEx.Message);
1235 0 : }
1236 :
1237 : }
1238 0 : }
1239 :
1240 0 : void ChartExport::exportDataTable( )
1241 : {
1242 0 : FSHelperPtr pFS = GetFS();
1243 0 : Reference< beans::XPropertySet > aPropSet( mxDiagram, uno::UNO_QUERY );
1244 :
1245 0 : sal_Bool bShowVBorder = sal_False;
1246 0 : sal_Bool bShowHBorder = sal_False;
1247 0 : sal_Bool bShowOutline = sal_False;
1248 :
1249 0 : if (GetProperty( aPropSet, "DataTableHBorder"))
1250 0 : mAny >>= bShowHBorder;
1251 0 : if (GetProperty( aPropSet, "DataTableVBorder"))
1252 0 : mAny >>= bShowVBorder;
1253 0 : if (GetProperty( aPropSet, "DataTableOutline"))
1254 0 : mAny >>= bShowOutline;
1255 :
1256 0 : if (bShowVBorder || bShowHBorder || bShowOutline)
1257 : {
1258 : pFS->startElement( FSNS( XML_c, XML_dTable),
1259 0 : FSEND );
1260 0 : if (bShowHBorder)
1261 : pFS->singleElement( FSNS( XML_c, XML_showHorzBorder ),
1262 : XML_val, "1",
1263 0 : FSEND );
1264 0 : if (bShowVBorder)
1265 : pFS->singleElement( FSNS( XML_c, XML_showVertBorder ),
1266 : XML_val, "1",
1267 0 : FSEND );
1268 0 : if (bShowOutline)
1269 : pFS->singleElement( FSNS( XML_c, XML_showOutline ),
1270 : XML_val, "1",
1271 0 : FSEND );
1272 :
1273 0 : pFS->endElement( FSNS( XML_c, XML_dTable));
1274 0 : }
1275 :
1276 0 : }
1277 0 : void ChartExport::exportAreaChart( Reference< chart2::XChartType > xChartType )
1278 : {
1279 0 : FSHelperPtr pFS = GetFS();
1280 0 : sal_Int32 nTypeId = XML_areaChart;
1281 0 : if( mbIs3DChart )
1282 0 : nTypeId = XML_area3DChart;
1283 : pFS->startElement( FSNS( XML_c, nTypeId ),
1284 0 : FSEND );
1285 :
1286 0 : exportGrouping( );
1287 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1288 0 : exportSeries( xChartType, nAttachedAxis );
1289 0 : exportAxesId( nAttachedAxis );
1290 :
1291 0 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1292 0 : }
1293 :
1294 0 : void ChartExport::exportBarChart( Reference< chart2::XChartType > xChartType )
1295 : {
1296 0 : sal_Int32 nTypeId = XML_barChart;
1297 0 : if( mbIs3DChart )
1298 0 : nTypeId = XML_bar3DChart;
1299 0 : FSHelperPtr pFS = GetFS();
1300 : pFS->startElement( FSNS( XML_c, nTypeId ),
1301 0 : FSEND );
1302 : // bar direction
1303 0 : sal_Bool bVertical = sal_False;
1304 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
1305 0 : if( GetProperty( xPropSet, "Vertical" ) )
1306 0 : mAny >>= bVertical;
1307 :
1308 0 : const char* bardir = bVertical? "bar":"col";
1309 : pFS->singleElement( FSNS( XML_c, XML_barDir ),
1310 : XML_val, bardir,
1311 0 : FSEND );
1312 :
1313 0 : exportGrouping( true );
1314 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1315 0 : exportSeries( xChartType, nAttachedAxis );
1316 :
1317 0 : Reference< XPropertySet > xTypeProp( xChartType, uno::UNO_QUERY );
1318 :
1319 0 : if( xTypeProp.is() && GetProperty( xTypeProp, "GapwidthSequence") )
1320 : {
1321 0 : uno::Sequence< sal_Int32 > aBarPositionSequence;
1322 0 : mAny >>= aBarPositionSequence;
1323 0 : if( aBarPositionSequence.getLength() )
1324 : {
1325 0 : sal_Int32 nGapWidth = aBarPositionSequence[0];
1326 : pFS->singleElement( FSNS( XML_c, XML_gapWidth ),
1327 : XML_val, I32S( nGapWidth ),
1328 0 : FSEND );
1329 0 : }
1330 : }
1331 :
1332 0 : if( mbIs3DChart )
1333 : {
1334 : // Shape
1335 : namespace cssc = ::com::sun::star::chart;
1336 0 : sal_Int32 nGeom3d = cssc::ChartSolidType::RECTANGULAR_SOLID;
1337 0 : if( xPropSet.is() && GetProperty( xPropSet, "SolidType") )
1338 0 : mAny >>= nGeom3d;
1339 0 : const char* sShapeType = NULL;
1340 0 : switch( nGeom3d )
1341 : {
1342 : case cssc::ChartSolidType::RECTANGULAR_SOLID:
1343 0 : sShapeType = "box";
1344 0 : break;
1345 : case cssc::ChartSolidType::CONE:
1346 0 : sShapeType = "cone";
1347 0 : break;
1348 : case cssc::ChartSolidType::CYLINDER:
1349 0 : sShapeType = "cylinder";
1350 0 : break;
1351 : case cssc::ChartSolidType::PYRAMID:
1352 0 : sShapeType = "pyramid";
1353 0 : break;
1354 : }
1355 : pFS->singleElement( FSNS( XML_c, XML_shape ),
1356 : XML_val, sShapeType,
1357 0 : FSEND );
1358 : }
1359 :
1360 : //overlap
1361 0 : if( !mbIs3DChart && xTypeProp.is() && GetProperty( xTypeProp, "OverlapSequence") )
1362 : {
1363 0 : uno::Sequence< sal_Int32 > aBarPositionSequence;
1364 0 : mAny >>= aBarPositionSequence;
1365 0 : if( aBarPositionSequence.getLength() )
1366 : {
1367 0 : sal_Int32 nOverlap = aBarPositionSequence[0];
1368 : pFS->singleElement( FSNS( XML_c, XML_overlap ),
1369 : XML_val, I32S( nOverlap ),
1370 0 : FSEND );
1371 0 : }
1372 : }
1373 :
1374 0 : exportAxesId( nAttachedAxis );
1375 :
1376 0 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1377 0 : }
1378 :
1379 0 : void ChartExport::exportBubbleChart( Reference< chart2::XChartType > xChartType )
1380 : {
1381 0 : FSHelperPtr pFS = GetFS();
1382 : pFS->startElement( FSNS( XML_c, XML_bubbleChart ),
1383 0 : FSEND );
1384 :
1385 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1386 0 : exportSeries( xChartType, nAttachedAxis );
1387 0 : exportAxesId( nAttachedAxis );
1388 :
1389 0 : pFS->endElement( FSNS( XML_c, XML_bubbleChart ) );
1390 0 : }
1391 :
1392 0 : void ChartExport::exportDoughnutChart( Reference< chart2::XChartType > xChartType )
1393 : {
1394 0 : FSHelperPtr pFS = GetFS();
1395 : pFS->startElement( FSNS( XML_c, XML_doughnutChart ),
1396 0 : FSEND );
1397 :
1398 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1399 0 : exportSeries( xChartType, nAttachedAxis );
1400 : // firstSliceAng
1401 0 : exportFirstSliceAng( );
1402 : //FIXME: holeSize
1403 0 : sal_Int32 nHoleSize = 50;
1404 : pFS->singleElement( FSNS( XML_c, XML_holeSize ),
1405 : XML_val, I32S( nHoleSize ),
1406 0 : FSEND );
1407 :
1408 0 : pFS->endElement( FSNS( XML_c, XML_doughnutChart ) );
1409 0 : }
1410 :
1411 0 : void ChartExport::exportLineChart( Reference< chart2::XChartType > xChartType )
1412 : {
1413 0 : FSHelperPtr pFS = GetFS();
1414 0 : sal_Int32 nTypeId = XML_lineChart;
1415 0 : if( mbIs3DChart )
1416 0 : nTypeId = XML_line3DChart;
1417 : pFS->startElement( FSNS( XML_c, nTypeId ),
1418 0 : FSEND );
1419 :
1420 0 : exportGrouping( );
1421 : // TODO: show marker symbol in series?
1422 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1423 0 : exportSeries( xChartType, nAttachedAxis );
1424 :
1425 : // show marker?
1426 0 : sal_Int32 nSymbolType = ::com::sun::star::chart::ChartSymbolType::NONE;
1427 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
1428 0 : if( GetProperty( xPropSet, "SymbolType" ) )
1429 0 : mAny >>= nSymbolType;
1430 :
1431 0 : if( !mbIs3DChart )
1432 : {
1433 0 : exportHiLowLines();
1434 0 : exportUpDownBars(xChartType);
1435 0 : const char* marker = nSymbolType == ::com::sun::star::chart::ChartSymbolType::NONE? "0":"1";
1436 : pFS->singleElement( FSNS( XML_c, XML_marker ),
1437 : XML_val, marker,
1438 0 : FSEND );
1439 : }
1440 :
1441 0 : exportAxesId( nAttachedAxis );
1442 :
1443 0 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1444 0 : }
1445 :
1446 0 : void ChartExport::exportOfPieChart( Reference< chart2::XChartType > /*xChartType*/ )
1447 : {
1448 : // TODO:
1449 0 : }
1450 :
1451 0 : void ChartExport::exportPieChart( Reference< chart2::XChartType > xChartType )
1452 : {
1453 0 : sal_Int32 eChartType = getChartType( );
1454 0 : if(eChartType == chart::TYPEID_DOUGHNUT)
1455 : {
1456 0 : exportDoughnutChart( xChartType );
1457 0 : return;
1458 : }
1459 0 : FSHelperPtr pFS = GetFS();
1460 0 : sal_Int32 nTypeId = XML_pieChart;
1461 0 : if( mbIs3DChart )
1462 0 : nTypeId = XML_pie3DChart;
1463 : pFS->startElement( FSNS( XML_c, nTypeId ),
1464 0 : FSEND );
1465 : // TODO: varyColors
1466 0 : const char* varyColors = "1";
1467 : pFS->singleElement( FSNS( XML_c, XML_varyColors ),
1468 : XML_val, varyColors,
1469 0 : FSEND );
1470 :
1471 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1472 0 : exportSeries( xChartType, nAttachedAxis );
1473 :
1474 0 : if( !mbIs3DChart )
1475 : {
1476 : // firstSliceAng
1477 0 : exportFirstSliceAng( );
1478 : }
1479 :
1480 0 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1481 : }
1482 :
1483 0 : void ChartExport::exportRadarChart( Reference< chart2::XChartType > xChartType)
1484 : {
1485 0 : FSHelperPtr pFS = GetFS();
1486 : pFS->startElement( FSNS( XML_c, XML_radarChart ),
1487 0 : FSEND );
1488 :
1489 : // radarStyle
1490 0 : sal_Int32 eChartType = getChartType( );
1491 0 : const char* radarStyle = NULL;
1492 0 : if( eChartType == chart::TYPEID_RADARAREA )
1493 0 : radarStyle = "filled";
1494 : else
1495 0 : radarStyle = "marker";
1496 : pFS->singleElement( FSNS( XML_c, XML_radarStyle ),
1497 : XML_val, radarStyle,
1498 0 : FSEND );
1499 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1500 0 : exportSeries( xChartType, nAttachedAxis );
1501 0 : exportAxesId( nAttachedAxis );
1502 :
1503 0 : pFS->endElement( FSNS( XML_c, XML_radarChart ) );
1504 0 : }
1505 :
1506 0 : void ChartExport::exportScatterChart( Reference< chart2::XChartType > xChartType )
1507 : {
1508 0 : FSHelperPtr pFS = GetFS();
1509 : pFS->startElement( FSNS( XML_c, XML_scatterChart ),
1510 0 : FSEND );
1511 : // TODO:scatterStyle
1512 0 : const char* scatterStyle = "lineMarker";
1513 : pFS->singleElement( FSNS( XML_c, XML_scatterStyle ),
1514 : XML_val, scatterStyle,
1515 0 : FSEND );
1516 :
1517 : pFS->singleElement( FSNS( XML_c, XML_varyColors ),
1518 : XML_val, "0",
1519 0 : FSEND );
1520 :
1521 : // FIXME: should export xVal and yVal
1522 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1523 0 : exportSeries( xChartType, nAttachedAxis );
1524 0 : exportAxesId( nAttachedAxis );
1525 :
1526 0 : pFS->endElement( FSNS( XML_c, XML_scatterChart ) );
1527 0 : }
1528 :
1529 0 : void ChartExport::exportStockChart( Reference< chart2::XChartType > xChartType )
1530 : {
1531 0 : FSHelperPtr pFS = GetFS();
1532 : pFS->startElement( FSNS( XML_c, XML_stockChart ),
1533 0 : FSEND );
1534 :
1535 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1536 0 : exportSeries( xChartType, nAttachedAxis );
1537 : // export stock properties
1538 0 : Reference< ::com::sun::star::chart::XStatisticDisplay > xStockPropProvider( mxDiagram, uno::UNO_QUERY );
1539 0 : if( xStockPropProvider.is())
1540 : {
1541 0 : exportHiLowLines();
1542 0 : exportUpDownBars(xChartType);
1543 : }
1544 :
1545 0 : exportAxesId( nAttachedAxis );
1546 :
1547 0 : pFS->endElement( FSNS( XML_c, XML_stockChart ) );
1548 0 : }
1549 :
1550 0 : void ChartExport::exportHiLowLines()
1551 : {
1552 0 : FSHelperPtr pFS = GetFS();
1553 : // export the chart property
1554 0 : Reference< ::com::sun::star::chart::XStatisticDisplay > xChartPropProvider( mxDiagram, uno::UNO_QUERY );
1555 :
1556 0 : if (!xChartPropProvider.is())
1557 0 : return;
1558 :
1559 0 : Reference< beans::XPropertySet > xStockPropSet = xChartPropProvider->getMinMaxLine();
1560 0 : if( xStockPropSet.is() )
1561 : {
1562 : pFS->startElement( FSNS( XML_c, XML_hiLowLines ),
1563 0 : FSEND );
1564 0 : exportShapeProps( xStockPropSet );
1565 0 : pFS->endElement( FSNS( XML_c, XML_hiLowLines ) );
1566 0 : }
1567 : }
1568 :
1569 0 : void ChartExport::exportUpDownBars( Reference< chart2::XChartType > xChartType)
1570 : {
1571 0 : FSHelperPtr pFS = GetFS();
1572 : // export the chart property
1573 0 : Reference< ::com::sun::star::chart::XStatisticDisplay > xChartPropProvider( mxDiagram, uno::UNO_QUERY );
1574 0 : if(xChartPropProvider.is())
1575 : {
1576 0 : Reference< beans::XPropertySet > xChartPropSet = xChartPropProvider->getMinMaxLine();
1577 : // updownbar
1578 : pFS->startElement( FSNS( XML_c, XML_upDownBars ),
1579 0 : FSEND );
1580 : // TODO: gapWidth
1581 0 : sal_Int32 nGapWidth = 150;
1582 : pFS->singleElement( FSNS( XML_c, XML_gapWidth ),
1583 : XML_val, I32S( nGapWidth ),
1584 0 : FSEND );
1585 :
1586 0 : xChartPropSet = xChartPropProvider->getUpBar();
1587 0 : if( xChartPropSet.is() )
1588 : {
1589 : pFS->startElement( FSNS( XML_c, XML_upBars ),
1590 0 : FSEND );
1591 : // For Linechart with UpDownBars, spPr is not getting imported
1592 : // so no need to call the exportShapeProps() for LineChart
1593 0 : if(xChartType->getChartType().equals("com.sun.star.chart2.CandleStickChartType"))
1594 : {
1595 0 : exportShapeProps(xChartPropSet);
1596 : }
1597 0 : pFS->endElement( FSNS( XML_c, XML_upBars ) );
1598 : }
1599 0 : xChartPropSet = xChartPropProvider->getDownBar();
1600 0 : if( xChartPropSet.is() )
1601 : {
1602 : pFS->startElement( FSNS( XML_c, XML_downBars ),
1603 0 : FSEND );
1604 0 : if(xChartType->getChartType().equals("com.sun.star.chart2.CandleStickChartType"))
1605 : {
1606 0 : exportShapeProps(xChartPropSet);
1607 : }
1608 0 : pFS->endElement( FSNS( XML_c, XML_downBars ) );
1609 : }
1610 0 : pFS->endElement( FSNS( XML_c, XML_upDownBars ) );
1611 0 : }
1612 0 : }
1613 :
1614 0 : void ChartExport::exportSuffaceChart( Reference< chart2::XChartType > xChartType )
1615 : {
1616 0 : FSHelperPtr pFS = GetFS();
1617 0 : sal_Int32 nTypeId = XML_surfaceChart;
1618 0 : if( mbIs3DChart )
1619 0 : nTypeId = XML_surface3DChart;
1620 : pFS->startElement( FSNS( XML_c, nTypeId ),
1621 0 : FSEND );
1622 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1623 0 : exportSeries( xChartType, nAttachedAxis );
1624 0 : exportAxesId( nAttachedAxis );
1625 :
1626 0 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1627 0 : }
1628 :
1629 0 : void ChartExport::exportSeries( Reference< chart2::XChartType > xChartType, sal_Int32& nAttachedAxis )
1630 : {
1631 :
1632 0 : OUString aLabelRole = xChartType->getRoleOfSequenceForSeriesLabel();
1633 0 : Reference< chart2::XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY );
1634 0 : if( ! xDSCnt.is())
1635 0 : return;
1636 :
1637 0 : OUString aChartType( xChartType->getChartType());
1638 0 : sal_Int32 eChartType = lcl_getChartType( aChartType );
1639 :
1640 : // special export for stock charts
1641 0 : if( eChartType == chart::TYPEID_STOCK )
1642 : {
1643 0 : sal_Bool bJapaneseCandleSticks = sal_False;
1644 0 : Reference< beans::XPropertySet > xCTProp( xChartType, uno::UNO_QUERY );
1645 0 : if( xCTProp.is())
1646 0 : xCTProp->getPropertyValue("Japanese") >>= bJapaneseCandleSticks;
1647 : exportCandleStickSeries(
1648 0 : xDSCnt->getDataSeries(), bJapaneseCandleSticks, nAttachedAxis );
1649 0 : return;
1650 : }
1651 :
1652 :
1653 : // export dataseries for current chart-type
1654 0 : Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries());
1655 0 : for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
1656 : {
1657 : // export series
1658 0 : Reference< chart2::data::XDataSource > xSource( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY );
1659 0 : if( xSource.is())
1660 : {
1661 0 : Reference< chart2::XDataSeries > xDataSeries( xSource, uno::UNO_QUERY );
1662 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
1663 0 : xSource->getDataSequences());
1664 : // search for main sequence and create a series element
1665 : {
1666 0 : sal_Int32 nMainSequenceIndex = -1;
1667 0 : sal_Int32 nSeriesLength = 0;
1668 0 : Reference< chart2::data::XDataSequence > xValuesSeq;
1669 0 : Reference< chart2::data::XDataSequence > xLabelSeq;
1670 0 : sal_Int32 nSeqIdx=0;
1671 0 : for( ; nSeqIdx<aSeqCnt.getLength(); ++nSeqIdx )
1672 : {
1673 0 : OUString aRole;
1674 0 : Reference< chart2::data::XDataSequence > xTempValueSeq( aSeqCnt[nSeqIdx]->getValues() );
1675 0 : if( nMainSequenceIndex==-1 )
1676 : {
1677 0 : Reference< beans::XPropertySet > xSeqProp( xTempValueSeq, uno::UNO_QUERY );
1678 0 : if( xSeqProp.is())
1679 0 : xSeqProp->getPropertyValue("Role") >>= aRole;
1680 : // "main" sequence
1681 0 : if( aRole.equals( aLabelRole ))
1682 : {
1683 0 : xValuesSeq.set( xTempValueSeq );
1684 0 : xLabelSeq.set( aSeqCnt[nSeqIdx]->getLabel());
1685 0 : nMainSequenceIndex = nSeqIdx;
1686 0 : }
1687 : }
1688 0 : sal_Int32 nSequenceLength = (xTempValueSeq.is()? xTempValueSeq->getData().getLength() : sal_Int32(0));
1689 0 : if( nSeriesLength < nSequenceLength )
1690 0 : nSeriesLength = nSequenceLength;
1691 0 : }
1692 :
1693 : // have found the main sequence, then xValuesSeq and
1694 : // xLabelSeq contain those. Otherwise both are empty
1695 : {
1696 0 : FSHelperPtr pFS = GetFS();
1697 : pFS->startElement( FSNS( XML_c, XML_ser ),
1698 0 : FSEND );
1699 :
1700 : // TODO: idx and order
1701 : pFS->singleElement( FSNS( XML_c, XML_idx ),
1702 : XML_val, I32S(mnSeriesCount),
1703 0 : FSEND );
1704 : pFS->singleElement( FSNS( XML_c, XML_order ),
1705 : XML_val, I32S(mnSeriesCount++),
1706 0 : FSEND );
1707 :
1708 : // export label
1709 0 : if( xLabelSeq.is() )
1710 0 : exportSeriesText( xLabelSeq );
1711 :
1712 : // export shape properties
1713 : Reference< XPropertySet > xPropSet = SchXMLSeriesHelper::createOldAPISeriesPropertySet(
1714 0 : aSeriesSeq[nSeriesIdx], getModel() );
1715 0 : if( xPropSet.is() )
1716 : {
1717 0 : if( GetProperty( xPropSet, "Axis") )
1718 : {
1719 0 : mAny >>= nAttachedAxis;
1720 0 : if( nAttachedAxis == ::com::sun::star::chart::ChartAxisAssign::SECONDARY_Y )
1721 0 : nAttachedAxis = AXIS_SECONDARY_Y;
1722 : else
1723 0 : nAttachedAxis = AXIS_PRIMARY_Y;
1724 : }
1725 0 : exportShapeProps( xPropSet );
1726 : }
1727 :
1728 0 : switch( eChartType )
1729 : {
1730 : case chart::TYPEID_LINE:
1731 : {
1732 0 : exportMarker(xDataSeries);
1733 0 : break;
1734 : }
1735 : case chart::TYPEID_PIE:
1736 : case chart::TYPEID_DOUGHNUT:
1737 : {
1738 0 : if( xPropSet.is() && GetProperty( xPropSet, "SegmentOffset") )
1739 : {
1740 0 : sal_Int32 nOffset = 0;
1741 0 : mAny >>= nOffset;
1742 : pFS->singleElement( FSNS( XML_c, XML_explosion ),
1743 : XML_val, I32S( nOffset ),
1744 0 : FSEND );
1745 : }
1746 0 : break;
1747 : }
1748 : case chart::TYPEID_SCATTER:
1749 : {
1750 0 : exportMarker(xDataSeries);
1751 0 : break;
1752 : }
1753 : case chart::TYPEID_RADARLINE:
1754 : {
1755 0 : exportMarker(xDataSeries);
1756 0 : break;
1757 : }
1758 : }
1759 :
1760 : // export data points
1761 0 : exportDataPoints( uno::Reference< beans::XPropertySet >( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY ), nSeriesLength );
1762 :
1763 : // export data labels
1764 : // Excel does not like our current data label export
1765 : // for scatter charts
1766 0 : if( eChartType != chart::TYPEID_SCATTER && eChartType != chart::TYPEID_BAR )
1767 0 : exportDataLabels( uno::Reference< beans::XPropertySet >( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY ), nSeriesLength );
1768 :
1769 0 : exportTrendlines( aSeriesSeq[nSeriesIdx] );
1770 :
1771 0 : if( eChartType != chart::TYPEID_PIE &&
1772 : eChartType != chart::TYPEID_RADARLINE )
1773 : {
1774 : //export error bars here
1775 0 : Reference< XPropertySet > xSeriesPropSet( xSource, uno::UNO_QUERY );
1776 0 : Reference< XPropertySet > xErrorBarYProps;
1777 0 : xSeriesPropSet->getPropertyValue("ErrorBarY") >>= xErrorBarYProps;
1778 0 : if(xErrorBarYProps.is())
1779 0 : exportErrorBar(xErrorBarYProps, true);
1780 0 : Reference< XPropertySet > xErrorBarXProps;
1781 0 : xSeriesPropSet->getPropertyValue("ErrorBarX") >>= xErrorBarXProps;
1782 0 : if(xErrorBarXProps.is())
1783 0 : exportErrorBar(xErrorBarXProps, false);
1784 : }
1785 :
1786 : // export categories
1787 0 : if( eChartType != chart::TYPEID_SCATTER && mxCategoriesValues.is() )
1788 0 : exportSeriesCategory( mxCategoriesValues );
1789 :
1790 0 : if( (eChartType == chart::TYPEID_SCATTER)
1791 0 : || (eChartType == chart::TYPEID_BUBBLE) )
1792 : {
1793 : // export xVal
1794 0 : Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString("values-x") ) );
1795 0 : if( xSequence.is() )
1796 : {
1797 0 : Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() );
1798 0 : if( xValues.is() )
1799 0 : exportSeriesValues( xValues, XML_xVal );
1800 0 : }
1801 : }
1802 :
1803 :
1804 0 : if( eChartType == chart::TYPEID_BUBBLE )
1805 : {
1806 : // export yVal
1807 0 : Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString("values-y") ) );
1808 0 : if( xSequence.is() )
1809 : {
1810 0 : Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() );
1811 0 : if( xValues.is() )
1812 0 : exportSeriesValues( xValues, XML_yVal );
1813 0 : }
1814 : }
1815 :
1816 : // export values
1817 0 : if( xValuesSeq.is() )
1818 : {
1819 0 : sal_Int32 nYValueType = XML_val;
1820 0 : if( eChartType == chart::TYPEID_SCATTER )
1821 0 : nYValueType = XML_yVal;
1822 0 : else if( eChartType == chart::TYPEID_BUBBLE )
1823 0 : nYValueType = XML_bubbleSize;
1824 0 : exportSeriesValues( xValuesSeq, nYValueType );
1825 : }
1826 :
1827 0 : if( eChartType == chart::TYPEID_SCATTER
1828 0 : || eChartType == chart::TYPEID_LINE )
1829 0 : exportSmooth();
1830 :
1831 0 : pFS->endElement( FSNS( XML_c, XML_ser ) );
1832 0 : }
1833 0 : }
1834 : }
1835 0 : }
1836 : }
1837 :
1838 0 : void ChartExport::exportCandleStickSeries(
1839 : const Sequence< Reference< chart2::XDataSeries > > & aSeriesSeq,
1840 : bool /*bJapaneseCandleSticks*/,
1841 : sal_Int32& nAttachedAxis )
1842 : {
1843 0 : for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
1844 : {
1845 0 : Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nSeriesIdx] );
1846 0 : nAttachedAxis = lcl_isSeriesAttachedToFirstAxis( xSeries ) ? AXIS_PRIMARY_Y : AXIS_SECONDARY_Y;
1847 :
1848 0 : Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
1849 0 : if( xSource.is())
1850 : {
1851 : // export series in correct order (as we don't store roles)
1852 : // with japanese candlesticks: open, low, high, close
1853 : // otherwise: low, high, close
1854 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
1855 0 : xSource->getDataSequences());
1856 :
1857 0 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
1858 0 : const char* sSeries[] = {"values-first","values-max","values-min","values-last",0};
1859 :
1860 0 : for( sal_Int32 idx = 0; sSeries[idx] != 0 ; idx++ )
1861 : {
1862 0 : Reference< chart2::data::XLabeledDataSequence > xLabeledSeq( lcl_getDataSequenceByRole( aSeqCnt, OUString::createFromAscii(sSeries[idx]) ) );
1863 0 : if( xLabeledSeq.is())
1864 : {
1865 0 : Reference< chart2::data::XDataSequence > xLabelSeq( xLabeledSeq->getLabel());
1866 0 : Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues());
1867 : {
1868 0 : FSHelperPtr pFS = GetFS();
1869 : pFS->startElement( FSNS( XML_c, XML_ser ),
1870 0 : FSEND );
1871 :
1872 : // TODO: idx and order
1873 : // idx attribute should start from 1 and not from 0.
1874 : pFS->singleElement( FSNS( XML_c, XML_idx ),
1875 : XML_val, I32S(idx+1),
1876 0 : FSEND );
1877 : pFS->singleElement( FSNS( XML_c, XML_order ),
1878 : XML_val, I32S(idx+1),
1879 0 : FSEND );
1880 :
1881 : // export label
1882 0 : if( xLabelSeq.is() )
1883 0 : exportSeriesText( xLabelSeq );
1884 :
1885 : // TODO:export shape properties
1886 :
1887 : // export categories
1888 0 : if( mxCategoriesValues.is() )
1889 0 : exportSeriesCategory( mxCategoriesValues );
1890 :
1891 : // export values
1892 0 : if( xValueSeq.is() )
1893 0 : exportSeriesValues( xValueSeq );
1894 :
1895 0 : pFS->endElement( FSNS( XML_c, XML_ser ) );
1896 0 : }
1897 : }
1898 0 : }
1899 : }
1900 0 : }
1901 0 : }
1902 :
1903 0 : void ChartExport::exportSeriesText( const Reference< chart2::data::XDataSequence > & xValueSeq )
1904 : {
1905 0 : FSHelperPtr pFS = GetFS();
1906 0 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
1907 : pFS->startElement( FSNS( XML_c, XML_tx ),
1908 0 : FSEND );
1909 :
1910 0 : OUString aCellRange = xValueSeq->getSourceRangeRepresentation();
1911 0 : aCellRange = parseFormula( aCellRange );
1912 : pFS->startElement( FSNS( XML_c, XML_strRef ),
1913 0 : FSEND );
1914 :
1915 : pFS->startElement( FSNS( XML_c, XML_f ),
1916 0 : FSEND );
1917 0 : pFS->writeEscaped( aCellRange );
1918 0 : pFS->endElement( FSNS( XML_c, XML_f ) );
1919 :
1920 0 : OUString aLabelString = lcl_getLabelString( xValueSeq );
1921 : pFS->startElement( FSNS( XML_c, XML_strCache ),
1922 0 : FSEND );
1923 : pFS->singleElement( FSNS( XML_c, XML_ptCount ),
1924 : XML_val, "1",
1925 0 : FSEND );
1926 : pFS->startElement( FSNS( XML_c, XML_pt ),
1927 : XML_idx, "0",
1928 0 : FSEND );
1929 : pFS->startElement( FSNS( XML_c, XML_v ),
1930 0 : FSEND );
1931 0 : pFS->writeEscaped( aLabelString );
1932 0 : pFS->endElement( FSNS( XML_c, XML_v ) );
1933 0 : pFS->endElement( FSNS( XML_c, XML_pt ) );
1934 0 : pFS->endElement( FSNS( XML_c, XML_strCache ) );
1935 0 : pFS->endElement( FSNS( XML_c, XML_strRef ) );
1936 0 : pFS->endElement( FSNS( XML_c, XML_tx ) );
1937 0 : }
1938 :
1939 0 : void ChartExport::exportSeriesCategory( const Reference< chart2::data::XDataSequence > & xValueSeq )
1940 : {
1941 0 : FSHelperPtr pFS = GetFS();
1942 0 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
1943 : pFS->startElement( FSNS( XML_c, XML_cat ),
1944 0 : FSEND );
1945 :
1946 0 : OUString aCellRange = xValueSeq->getSourceRangeRepresentation();
1947 0 : aCellRange = parseFormula( aCellRange );
1948 : // TODO: need to handle XML_multiLvlStrRef according to aCellRange
1949 : pFS->startElement( FSNS( XML_c, XML_strRef ),
1950 0 : FSEND );
1951 :
1952 : pFS->startElement( FSNS( XML_c, XML_f ),
1953 0 : FSEND );
1954 0 : pFS->writeEscaped( aCellRange );
1955 0 : pFS->endElement( FSNS( XML_c, XML_f ) );
1956 :
1957 0 : ::std::vector< OUString > aCategories;
1958 0 : lcl_fillCategoriesIntoStringVector( xValueSeq, aCategories );
1959 0 : sal_Int32 ptCount = aCategories.size();
1960 : pFS->startElement( FSNS( XML_c, XML_strCache ),
1961 0 : FSEND );
1962 : pFS->singleElement( FSNS( XML_c, XML_ptCount ),
1963 : XML_val, I32S( ptCount ),
1964 0 : FSEND );
1965 0 : for( sal_Int32 i = 0; i < ptCount; i++ )
1966 : {
1967 : pFS->startElement( FSNS( XML_c, XML_pt ),
1968 : XML_idx, I32S( i ),
1969 0 : FSEND );
1970 : pFS->startElement( FSNS( XML_c, XML_v ),
1971 0 : FSEND );
1972 0 : pFS->writeEscaped( aCategories[i] );
1973 0 : pFS->endElement( FSNS( XML_c, XML_v ) );
1974 0 : pFS->endElement( FSNS( XML_c, XML_pt ) );
1975 : }
1976 :
1977 0 : pFS->endElement( FSNS( XML_c, XML_strCache ) );
1978 0 : pFS->endElement( FSNS( XML_c, XML_strRef ) );
1979 0 : pFS->endElement( FSNS( XML_c, XML_cat ) );
1980 0 : }
1981 :
1982 0 : void ChartExport::exportSeriesValues( const Reference< chart2::data::XDataSequence > & xValueSeq, sal_Int32 nValueType )
1983 : {
1984 0 : FSHelperPtr pFS = GetFS();
1985 0 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
1986 : pFS->startElement( FSNS( XML_c, nValueType ),
1987 0 : FSEND );
1988 :
1989 0 : OUString aCellRange = xValueSeq->getSourceRangeRepresentation();
1990 0 : aCellRange = parseFormula( aCellRange );
1991 : // TODO: need to handle XML_multiLvlStrRef according to aCellRange
1992 : pFS->startElement( FSNS( XML_c, XML_numRef ),
1993 0 : FSEND );
1994 :
1995 : pFS->startElement( FSNS( XML_c, XML_f ),
1996 0 : FSEND );
1997 0 : pFS->writeEscaped( aCellRange );
1998 0 : pFS->endElement( FSNS( XML_c, XML_f ) );
1999 :
2000 0 : ::std::vector< double > aValues;
2001 0 : aValues = lcl_getAllValuesFromSequence( xValueSeq );
2002 0 : sal_Int32 ptCount = aValues.size();
2003 : pFS->startElement( FSNS( XML_c, XML_numCache ),
2004 0 : FSEND );
2005 : pFS->startElement( FSNS( XML_c, XML_formatCode ),
2006 0 : FSEND );
2007 : // TODO: what format code?
2008 0 : pFS->writeEscaped( "General" );
2009 0 : pFS->endElement( FSNS( XML_c, XML_formatCode ) );
2010 : pFS->singleElement( FSNS( XML_c, XML_ptCount ),
2011 : XML_val, I32S( ptCount ),
2012 0 : FSEND );
2013 0 : for( sal_Int32 i = 0; i < ptCount; i++ )
2014 : {
2015 : pFS->startElement( FSNS( XML_c, XML_pt ),
2016 : XML_idx, I32S( i ),
2017 0 : FSEND );
2018 : pFS->startElement( FSNS( XML_c, XML_v ),
2019 0 : FSEND );
2020 0 : if (!rtl::math::isNan(aValues[i]))
2021 0 : pFS->write( aValues[i] );
2022 0 : pFS->endElement( FSNS( XML_c, XML_v ) );
2023 0 : pFS->endElement( FSNS( XML_c, XML_pt ) );
2024 : }
2025 :
2026 0 : pFS->endElement( FSNS( XML_c, XML_numCache ) );
2027 0 : pFS->endElement( FSNS( XML_c, XML_numRef ) );
2028 0 : pFS->endElement( FSNS( XML_c, nValueType ) );
2029 0 : }
2030 :
2031 0 : void ChartExport::exportShapeProps( Reference< XPropertySet > xPropSet )
2032 : {
2033 0 : FSHelperPtr pFS = GetFS();
2034 : pFS->startElement( FSNS( XML_c, XML_spPr ),
2035 0 : FSEND );
2036 :
2037 0 : WriteFill( xPropSet );
2038 0 : WriteOutline( xPropSet );
2039 :
2040 0 : pFS->endElement( FSNS( XML_c, XML_spPr ) );
2041 0 : }
2042 :
2043 0 : void ChartExport::InitPlotArea( )
2044 : {
2045 0 : Reference< XPropertySet > xDiagramProperties (mxDiagram, uno::UNO_QUERY);
2046 :
2047 : // Check for supported services and then the properties provided by this service.
2048 0 : Reference<lang::XServiceInfo> xServiceInfo (mxDiagram, uno::UNO_QUERY);
2049 0 : if (xServiceInfo.is())
2050 : {
2051 0 : if (xServiceInfo->supportsService(
2052 0 : OUString("com.sun.star.chart.ChartAxisZSupplier")))
2053 : {
2054 0 : xDiagramProperties->getPropertyValue(
2055 0 : OUString("HasZAxis")) >>= mbHasZAxis;
2056 : }
2057 : }
2058 :
2059 0 : xDiagramProperties->getPropertyValue(
2060 0 : OUString ("Dim3D")) >>= mbIs3DChart;
2061 :
2062 0 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
2063 0 : if( mbHasCategoryLabels && mxNewDiagram.is())
2064 : {
2065 0 : Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( mxNewDiagram ) );
2066 0 : if( xCategories.is() )
2067 : {
2068 0 : mxCategoriesValues.set( xCategories->getValues() );
2069 0 : }
2070 0 : }
2071 0 : }
2072 :
2073 0 : void ChartExport::exportAxes( )
2074 : {
2075 0 : sal_Int32 nSize = maAxes.size();
2076 0 : for( sal_Int32 nIdx = 0; nIdx < nSize; nIdx++ )
2077 : {
2078 0 : exportAxis( maAxes[nIdx] );
2079 : }
2080 0 : }
2081 :
2082 0 : void ChartExport::exportAxis( AxisIdPair aAxisIdPair )
2083 : {
2084 : // get some properties from document first
2085 0 : sal_Bool bHasXAxisTitle = sal_False,
2086 0 : bHasYAxisTitle = sal_False,
2087 0 : bHasZAxisTitle = sal_False,
2088 0 : bHasSecondaryXAxisTitle = sal_False,
2089 0 : bHasSecondaryYAxisTitle = sal_False;
2090 0 : sal_Bool bHasXAxisMajorGrid = sal_False,
2091 0 : bHasXAxisMinorGrid = sal_False,
2092 0 : bHasYAxisMajorGrid = sal_False,
2093 0 : bHasYAxisMinorGrid = sal_False,
2094 0 : bHasZAxisMajorGrid = sal_False,
2095 0 : bHasZAxisMinorGrid = sal_False;
2096 :
2097 0 : Reference< XPropertySet > xDiagramProperties (mxDiagram, uno::UNO_QUERY);
2098 :
2099 0 : xDiagramProperties->getPropertyValue(
2100 0 : OUString ("HasXAxisTitle")) >>= bHasXAxisTitle;
2101 0 : xDiagramProperties->getPropertyValue(
2102 0 : OUString ("HasYAxisTitle")) >>= bHasYAxisTitle;
2103 0 : xDiagramProperties->getPropertyValue(
2104 0 : OUString ("HasZAxisTitle")) >>= bHasZAxisTitle;
2105 0 : xDiagramProperties->getPropertyValue(
2106 0 : OUString ("HasSecondaryXAxisTitle")) >>= bHasSecondaryXAxisTitle;
2107 0 : xDiagramProperties->getPropertyValue(
2108 0 : OUString ("HasSecondaryYAxisTitle")) >>= bHasSecondaryYAxisTitle;
2109 :
2110 0 : xDiagramProperties->getPropertyValue(
2111 0 : OUString ("HasXAxisGrid")) >>= bHasXAxisMajorGrid;
2112 0 : xDiagramProperties->getPropertyValue(
2113 0 : OUString ("HasYAxisGrid")) >>= bHasYAxisMajorGrid;
2114 0 : xDiagramProperties->getPropertyValue(
2115 0 : OUString ("HasZAxisGrid")) >>= bHasZAxisMajorGrid;
2116 :
2117 0 : xDiagramProperties->getPropertyValue(
2118 0 : OUString ("HasXAxisHelpGrid")) >>= bHasXAxisMinorGrid;
2119 0 : xDiagramProperties->getPropertyValue(
2120 0 : OUString ("HasYAxisHelpGrid")) >>= bHasYAxisMinorGrid;
2121 0 : xDiagramProperties->getPropertyValue(
2122 0 : OUString ("HasZAxisHelpGrid")) >>= bHasZAxisMinorGrid;
2123 :
2124 0 : Reference< XPropertySet > xAxisProp;
2125 0 : Reference< drawing::XShape > xAxisTitle;
2126 0 : Reference< beans::XPropertySet > xMajorGrid;
2127 0 : Reference< beans::XPropertySet > xMinorGrid;
2128 0 : sal_Int32 nAxisType = XML_catAx;
2129 0 : const char* sAxPos = NULL;
2130 :
2131 0 : switch( aAxisIdPair.nAxisType )
2132 : {
2133 : case AXIS_PRIMARY_X:
2134 : {
2135 0 : Reference< ::com::sun::star::chart::XAxisXSupplier > xAxisXSupp( mxDiagram, uno::UNO_QUERY );
2136 0 : if( xAxisXSupp.is())
2137 0 : xAxisProp = xAxisXSupp->getXAxis();
2138 0 : if( bHasXAxisTitle )
2139 0 : xAxisTitle.set( xAxisXSupp->getXAxisTitle(), uno::UNO_QUERY );
2140 0 : if( bHasXAxisMajorGrid )
2141 0 : xMajorGrid.set( xAxisXSupp->getXMainGrid(), uno::UNO_QUERY );
2142 0 : if( bHasXAxisMinorGrid )
2143 0 : xMinorGrid.set( xAxisXSupp->getXHelpGrid(), uno::UNO_QUERY );
2144 :
2145 0 : sal_Int32 eChartType = getChartType( );
2146 0 : if( (eChartType == chart::TYPEID_SCATTER)
2147 0 : || (eChartType == chart::TYPEID_BUBBLE) )
2148 0 : nAxisType = XML_valAx;
2149 0 : else if( eChartType == chart::TYPEID_STOCK )
2150 0 : nAxisType = XML_dateAx;
2151 : // FIXME: axPos, need to check axis direction
2152 0 : sAxPos = "b";
2153 0 : break;
2154 : }
2155 : case AXIS_PRIMARY_Y:
2156 : {
2157 0 : Reference< ::com::sun::star::chart::XAxisYSupplier > xAxisYSupp( mxDiagram, uno::UNO_QUERY );
2158 0 : if( xAxisYSupp.is())
2159 0 : xAxisProp = xAxisYSupp->getYAxis();
2160 0 : if( bHasYAxisTitle )
2161 0 : xAxisTitle.set( xAxisYSupp->getYAxisTitle(), uno::UNO_QUERY );
2162 0 : if( bHasYAxisMajorGrid )
2163 0 : xMajorGrid.set( xAxisYSupp->getYMainGrid(), uno::UNO_QUERY );
2164 0 : if( bHasYAxisMinorGrid )
2165 0 : xMinorGrid.set( xAxisYSupp->getYHelpGrid(), uno::UNO_QUERY );
2166 :
2167 0 : nAxisType = XML_valAx;
2168 : // FIXME: axPos, need to check axis direction
2169 0 : sAxPos = "l";
2170 0 : break;
2171 : }
2172 : case AXIS_PRIMARY_Z:
2173 : {
2174 0 : Reference< ::com::sun::star::chart::XAxisZSupplier > xAxisZSupp( mxDiagram, uno::UNO_QUERY );
2175 0 : if( xAxisZSupp.is())
2176 0 : xAxisProp = xAxisZSupp->getZAxis();
2177 0 : if( bHasZAxisTitle )
2178 0 : xAxisTitle.set( xAxisZSupp->getZAxisTitle(), uno::UNO_QUERY );
2179 0 : if( bHasZAxisMajorGrid )
2180 0 : xMajorGrid.set( xAxisZSupp->getZMainGrid(), uno::UNO_QUERY );
2181 0 : if( bHasZAxisMinorGrid )
2182 0 : xMinorGrid.set( xAxisZSupp->getZHelpGrid(), uno::UNO_QUERY );
2183 :
2184 0 : sal_Int32 eChartType = getChartType( );
2185 0 : if( (eChartType == chart::TYPEID_SCATTER)
2186 0 : || (eChartType == chart::TYPEID_BUBBLE) )
2187 0 : nAxisType = XML_valAx;
2188 0 : else if( eChartType == chart::TYPEID_STOCK )
2189 0 : nAxisType = XML_dateAx;
2190 : // FIXME: axPos, need to check axis direction
2191 0 : sAxPos = "b";
2192 0 : break;
2193 : }
2194 : case AXIS_SECONDARY_Y:
2195 : {
2196 0 : Reference< ::com::sun::star::chart::XTwoAxisYSupplier > xAxisTwoYSupp( mxDiagram, uno::UNO_QUERY );
2197 0 : if( xAxisTwoYSupp.is())
2198 0 : xAxisProp = xAxisTwoYSupp->getSecondaryYAxis();
2199 0 : if( bHasSecondaryYAxisTitle )
2200 : {
2201 0 : Reference< ::com::sun::star::chart::XSecondAxisTitleSupplier > xAxisSupp( mxDiagram, uno::UNO_QUERY );
2202 0 : xAxisTitle.set( xAxisSupp->getSecondYAxisTitle(), uno::UNO_QUERY );
2203 : }
2204 :
2205 0 : nAxisType = XML_valAx;
2206 : // FIXME: axPos, need to check axis direction
2207 0 : sAxPos = "l";
2208 0 : break;
2209 : }
2210 : }
2211 :
2212 :
2213 0 : _exportAxis( xAxisProp, xAxisTitle, xMajorGrid, xMinorGrid, nAxisType, sAxPos, aAxisIdPair );
2214 0 : }
2215 :
2216 0 : void ChartExport::_exportAxis(
2217 : const Reference< XPropertySet >& xAxisProp,
2218 : const Reference< drawing::XShape >& xAxisTitle,
2219 : const Reference< XPropertySet >& xMajorGrid,
2220 : const Reference< XPropertySet >& xMinorGrid,
2221 : sal_Int32 nAxisType,
2222 : const char* sAxisPos,
2223 : AxisIdPair aAxisIdPair )
2224 : {
2225 0 : FSHelperPtr pFS = GetFS();
2226 : pFS->startElement( FSNS( XML_c, nAxisType ),
2227 0 : FSEND );
2228 : pFS->singleElement( FSNS( XML_c, XML_axId ),
2229 : XML_val, I32S( aAxisIdPair.nAxisId ),
2230 0 : FSEND );
2231 :
2232 : pFS->startElement( FSNS( XML_c, XML_scaling ),
2233 0 : FSEND );
2234 : // logBase, min, max
2235 0 : if(GetProperty( xAxisProp, "Logarithmic" ) )
2236 : {
2237 0 : sal_Bool bLogarithmic = sal_False;
2238 0 : mAny >>= bLogarithmic;
2239 0 : if( bLogarithmic )
2240 : {
2241 : // default value is 10?
2242 0 : sal_Int32 nLogBase = 10;
2243 : pFS->singleElement( FSNS( XML_c, XML_logBase ),
2244 : XML_val, I32S( nLogBase ),
2245 0 : FSEND );
2246 : }
2247 : }
2248 :
2249 : // orientation: minMax, maxMin
2250 0 : sal_Bool bReverseDirection = sal_False;
2251 0 : if(GetProperty( xAxisProp, "ReverseDirection" ) )
2252 0 : mAny >>= bReverseDirection;
2253 :
2254 0 : const char* orientation = bReverseDirection ? "maxMin":"minMax";
2255 : pFS->singleElement( FSNS( XML_c, XML_orientation ),
2256 : XML_val, orientation,
2257 0 : FSEND );
2258 :
2259 0 : sal_Bool bAutoMax = sal_False;
2260 0 : if(GetProperty( xAxisProp, "AutoMax" ) )
2261 0 : mAny >>= bAutoMax;
2262 :
2263 0 : if( !bAutoMax && (GetProperty( xAxisProp, "Max" ) ) )
2264 : {
2265 0 : double dMax = 0;
2266 0 : mAny >>= dMax;
2267 : pFS->singleElement( FSNS( XML_c, XML_max ),
2268 : XML_val, IS( dMax ),
2269 0 : FSEND );
2270 : }
2271 :
2272 0 : sal_Bool bAutoMin = sal_False;
2273 0 : if(GetProperty( xAxisProp, "AutoMin" ) )
2274 0 : mAny >>= bAutoMin;
2275 :
2276 0 : if( !bAutoMin && (GetProperty( xAxisProp, "Min" ) ) )
2277 : {
2278 0 : double dMin = 0;
2279 0 : mAny >>= dMin;
2280 : pFS->singleElement( FSNS( XML_c, XML_min ),
2281 : XML_val, IS( dMin ),
2282 0 : FSEND );
2283 : }
2284 :
2285 0 : pFS->endElement( FSNS( XML_c, XML_scaling ) );
2286 :
2287 0 : sal_Bool bVisible = sal_True;
2288 0 : if( xAxisProp.is() )
2289 : {
2290 0 : xAxisProp->getPropertyValue(
2291 0 : OUString ("Visible")) >>= bVisible;
2292 : }
2293 :
2294 : pFS->singleElement( FSNS( XML_c, XML_delete ),
2295 : XML_val, bVisible ? "0" : "1",
2296 0 : FSEND );
2297 :
2298 : // FIXME: axPos, need to check the property "ReverseDirection"
2299 : pFS->singleElement( FSNS( XML_c, XML_axPos ),
2300 : XML_val, sAxisPos,
2301 0 : FSEND );
2302 : // major grid line
2303 0 : if( xMajorGrid.is())
2304 : {
2305 : pFS->startElement( FSNS( XML_c, XML_majorGridlines ),
2306 0 : FSEND );
2307 0 : exportShapeProps( xMajorGrid );
2308 0 : pFS->endElement( FSNS( XML_c, XML_majorGridlines ) );
2309 : }
2310 :
2311 : // minor grid line
2312 0 : if( xMinorGrid.is())
2313 : {
2314 : pFS->startElement( FSNS( XML_c, XML_minorGridlines ),
2315 0 : FSEND );
2316 0 : exportShapeProps( xMinorGrid );
2317 0 : pFS->endElement( FSNS( XML_c, XML_minorGridlines ) );
2318 : }
2319 :
2320 : // title
2321 0 : if( xAxisTitle.is() )
2322 0 : exportTitle( xAxisTitle );
2323 :
2324 : // majorTickMark
2325 0 : sal_Int32 nValue = 0;
2326 0 : if(GetProperty( xAxisProp, "Marks" ) )
2327 : {
2328 0 : mAny >>= nValue;
2329 0 : sal_Bool bInner = nValue & ::com::sun::star::chart::ChartAxisMarks::INNER;
2330 0 : sal_Bool bOuter = nValue & ::com::sun::star::chart::ChartAxisMarks::OUTER;
2331 0 : const char* majorTickMark = NULL;
2332 0 : if( bInner && bOuter )
2333 0 : majorTickMark = "cross";
2334 0 : else if( bInner )
2335 0 : majorTickMark = "in";
2336 0 : else if( bOuter )
2337 0 : majorTickMark = "out";
2338 : else
2339 0 : majorTickMark = "none";
2340 : pFS->singleElement( FSNS( XML_c, XML_majorTickMark ),
2341 : XML_val, majorTickMark,
2342 0 : FSEND );
2343 : }
2344 : // minorTickMark
2345 0 : if(GetProperty( xAxisProp, "HelpMarks" ) )
2346 : {
2347 0 : mAny >>= nValue;
2348 0 : sal_Bool bInner = nValue & ::com::sun::star::chart::ChartAxisMarks::INNER;
2349 0 : sal_Bool bOuter = nValue & ::com::sun::star::chart::ChartAxisMarks::OUTER;
2350 0 : const char* minorTickMark = NULL;
2351 0 : if( bInner && bOuter )
2352 0 : minorTickMark = "cross";
2353 0 : else if( bInner )
2354 0 : minorTickMark = "in";
2355 0 : else if( bOuter )
2356 0 : minorTickMark = "out";
2357 : else
2358 0 : minorTickMark = "none";
2359 : pFS->singleElement( FSNS( XML_c, XML_minorTickMark ),
2360 : XML_val, minorTickMark,
2361 0 : FSEND );
2362 : }
2363 : // tickLblPos
2364 0 : const char* sTickLblPos = NULL;
2365 0 : sal_Bool bDisplayLabel = sal_True;
2366 0 : if(GetProperty( xAxisProp, "DisplayLabels" ) )
2367 0 : mAny >>= bDisplayLabel;
2368 0 : if( bDisplayLabel && (GetProperty( xAxisProp, "LabelPosition" ) ) )
2369 : {
2370 0 : ::com::sun::star::chart::ChartAxisLabelPosition eLabelPosition = ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS;
2371 0 : mAny >>= eLabelPosition;
2372 0 : switch( eLabelPosition )
2373 : {
2374 : case ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS:
2375 : case ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS_OTHER_SIDE:
2376 0 : sTickLblPos = "nextTo";
2377 0 : break;
2378 : case ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START:
2379 0 : sTickLblPos = "low";
2380 0 : break;
2381 : case ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END:
2382 0 : sTickLblPos = "high";
2383 0 : break;
2384 : default:
2385 0 : sTickLblPos = "nextTo";
2386 0 : break;
2387 : }
2388 : }
2389 : else
2390 : {
2391 0 : sTickLblPos = "none";
2392 : }
2393 : pFS->singleElement( FSNS( XML_c, XML_tickLblPos ),
2394 : XML_val, sTickLblPos,
2395 0 : FSEND );
2396 :
2397 : // shape properties
2398 0 : exportShapeProps( xAxisProp );
2399 :
2400 : pFS->singleElement( FSNS( XML_c, XML_crossAx ),
2401 : XML_val, I32S( aAxisIdPair.nCrossAx ),
2402 0 : FSEND );
2403 :
2404 : // crosses & crossesAt
2405 0 : sal_Bool bCrossesValue = sal_False;
2406 0 : const char* sCrosses = NULL;
2407 0 : if(GetProperty( xAxisProp, "CrossoverPosition" ) )
2408 : {
2409 0 : ::com::sun::star::chart::ChartAxisPosition ePosition( ::com::sun::star::chart::ChartAxisPosition_ZERO );
2410 0 : mAny >>= ePosition;
2411 0 : switch( ePosition )
2412 : {
2413 : case ::com::sun::star::chart::ChartAxisPosition_START:
2414 0 : sCrosses = "min";
2415 0 : break;
2416 : case ::com::sun::star::chart::ChartAxisPosition_END:
2417 0 : sCrosses = "max";
2418 0 : break;
2419 : case ::com::sun::star::chart::ChartAxisPosition_ZERO:
2420 0 : sCrosses = "autoZero";
2421 0 : break;
2422 : default:
2423 0 : bCrossesValue = sal_True;
2424 0 : break;
2425 : }
2426 : }
2427 :
2428 0 : if( bCrossesValue && GetProperty( xAxisProp, "CrossoverValue" ) )
2429 : {
2430 0 : double dValue = 0;
2431 0 : mAny >>= dValue;
2432 : pFS->singleElement( FSNS( XML_c, XML_crossesAt ),
2433 : XML_val, IS( dValue ),
2434 0 : FSEND );
2435 : }
2436 : else
2437 : {
2438 : pFS->singleElement( FSNS( XML_c, XML_crosses ),
2439 : XML_val, sCrosses,
2440 0 : FSEND );
2441 : }
2442 :
2443 0 : if( ( nAxisType == XML_catAx )
2444 0 : || ( nAxisType == XML_dateAx ) )
2445 : {
2446 : // FIXME: seems not support? use default value,
2447 0 : const char* isAuto = "1";
2448 : pFS->singleElement( FSNS( XML_c, XML_auto ),
2449 : XML_val, isAuto,
2450 0 : FSEND );
2451 :
2452 0 : if( nAxisType == XML_catAx )
2453 : {
2454 : // FIXME: seems not support? lblAlgn
2455 0 : const char* sLblAlgn = "ctr";
2456 : pFS->singleElement( FSNS( XML_c, XML_lblAlgn ),
2457 : XML_val, sLblAlgn,
2458 0 : FSEND );
2459 : }
2460 :
2461 : // FIXME: seems not support? lblOffset
2462 0 : sal_Int32 nLblOffset = 100;
2463 : pFS->singleElement( FSNS( XML_c, XML_lblOffset ),
2464 : XML_val, I32S( nLblOffset ),
2465 0 : FSEND );
2466 : }
2467 :
2468 : // majorUnit
2469 0 : sal_Bool bAutoStepMain = sal_False;
2470 0 : if(GetProperty( xAxisProp, "AutoStepMain" ) )
2471 0 : mAny >>= bAutoStepMain;
2472 :
2473 0 : if( !bAutoStepMain && (GetProperty( xAxisProp, "StepMain" ) ) )
2474 : {
2475 0 : double dMajorUnit = 0;
2476 0 : mAny >>= dMajorUnit;
2477 : pFS->singleElement( FSNS( XML_c, XML_majorUnit ),
2478 : XML_val, IS( dMajorUnit ),
2479 0 : FSEND );
2480 : }
2481 : // minorUnit
2482 0 : sal_Bool bAutoStepHelp = sal_False;
2483 0 : if(GetProperty( xAxisProp, "AutoStepHelp" ) )
2484 0 : mAny >>= bAutoStepHelp;
2485 :
2486 0 : if( !bAutoStepHelp && (GetProperty( xAxisProp, "StepHelp" ) ) )
2487 : {
2488 0 : double dMinorUnit = 0;
2489 0 : mAny >>= dMinorUnit;
2490 : pFS->singleElement( FSNS( XML_c, XML_minorUnit ),
2491 : XML_val, IS( dMinorUnit ),
2492 0 : FSEND );
2493 : }
2494 :
2495 0 : sal_Bool bDisplayUnits = sal_False;
2496 0 : if( nAxisType == XML_valAx && GetProperty( xAxisProp, "DisplayUnits" ) )
2497 : {
2498 0 : mAny >>= bDisplayUnits;
2499 0 : if(bDisplayUnits)
2500 : {
2501 0 : OUString aVal;
2502 0 : if(GetProperty( xAxisProp, "BuiltInUnit" ))
2503 : {
2504 0 : mAny >>= aVal;
2505 0 : if(!aVal.isEmpty())
2506 : {
2507 : pFS->startElement( FSNS( XML_c, XML_dispUnits ),
2508 0 : FSEND );
2509 :
2510 0 : OString aBuiltInUnit = OUStringToOString(aVal, RTL_TEXTENCODING_UTF8);
2511 : pFS->singleElement( FSNS( XML_c, XML_builtInUnit ),
2512 : XML_val, aBuiltInUnit.getStr(),
2513 0 : FSEND );
2514 :
2515 0 : pFS->singleElement(FSNS( XML_c, XML_dispUnitsLbl ),FSEND);
2516 0 : pFS->endElement( FSNS( XML_c, XML_dispUnits ) );
2517 : }
2518 0 : }
2519 : }
2520 : }
2521 : // TODO: text properties
2522 :
2523 0 : pFS->endElement( FSNS( XML_c, nAxisType ) );
2524 0 : }
2525 :
2526 0 : void ChartExport::exportDataLabels(
2527 : const uno::Reference< beans::XPropertySet > & xSeriesProperties,
2528 : sal_Int32 nSeriesLength )
2529 : {
2530 : // TODO: export field separators, missing flag vs. showing series name or not
2531 0 : uno::Reference< chart2::XDataSeries > xSeries( xSeriesProperties, uno::UNO_QUERY );
2532 :
2533 0 : if( xSeriesProperties.is())
2534 : {
2535 0 : FSHelperPtr pFS = GetFS();
2536 : pFS->startElement( FSNS( XML_c, XML_dLbls ),
2537 0 : FSEND );
2538 :
2539 0 : bool showLegendSymbol = false;
2540 0 : bool showNumber = false;
2541 0 : bool showCategoryName = false;
2542 0 : bool showNumberInPercent = false;
2543 :
2544 0 : sal_Int32 nElem = 0;
2545 :
2546 :
2547 0 : uno::Reference< beans::XPropertySet > xPropSet;
2548 0 : if(nSeriesLength != 0)
2549 : {
2550 : try
2551 : {
2552 0 : xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
2553 0 : xSeries, nElem, getModel() );
2554 : }
2555 0 : catch( const uno::Exception & rEx )
2556 : {
2557 : SAL_WARN("oox", "Exception caught during Export of data label: " << rEx.Message );
2558 : }
2559 : }
2560 :
2561 : namespace cssc2 = ::com::sun::star::chart2;
2562 0 : cssc2::DataPointLabel aTempLabel;
2563 0 : if( xPropSet.is() )
2564 : {
2565 0 : if (GetProperty( xPropSet, "Label"))
2566 0 : mAny >>= aTempLabel;
2567 : }
2568 :
2569 :
2570 :
2571 0 : for( nElem = 1; nElem < nSeriesLength; ++nElem)
2572 : {
2573 : try
2574 : {
2575 0 : xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
2576 0 : xSeries, nElem, getModel() );
2577 : }
2578 0 : catch( const uno::Exception & rEx )
2579 : {
2580 : SAL_WARN("oox", "Exception caught during Export of data label: " << rEx.Message );
2581 : }
2582 :
2583 0 : if( xPropSet.is() )
2584 : {
2585 : namespace cssc2 = ::com::sun::star::chart2;
2586 0 : cssc2::DataPointLabel aLabel;
2587 0 : if (GetProperty( xPropSet, "Label"))
2588 : {
2589 0 : mAny >>= aLabel;
2590 :
2591 : namespace csscd = ::com::sun::star::chart::DataLabelPlacement;
2592 0 : sal_Int32 nPlacement(csscd::AVOID_OVERLAP);
2593 0 : const char *aPlacement = NULL;
2594 0 : OUString aSep;
2595 :
2596 0 : if (GetProperty( xPropSet, "LabelPlacement"))
2597 0 : mAny >>= nPlacement;
2598 :
2599 0 : switch( nPlacement )
2600 : {
2601 0 : case csscd::OUTSIDE: aPlacement = "outEnd"; break;
2602 0 : case csscd::INSIDE: aPlacement = "inEnd"; break;
2603 0 : case csscd::CENTER: aPlacement = "ctr"; break;
2604 0 : case csscd::NEAR_ORIGIN: aPlacement = "inBase"; break;
2605 0 : case csscd::TOP: aPlacement = "t"; break;
2606 0 : case csscd::BOTTOM: aPlacement = "b"; break;
2607 0 : case csscd::LEFT: aPlacement = "l"; break;
2608 0 : case csscd::RIGHT: aPlacement = "r"; break;
2609 0 : case csscd::AVOID_OVERLAP: aPlacement = "bestFit"; break;
2610 : }
2611 :
2612 0 : if (aLabel.ShowLegendSymbol)
2613 0 : showLegendSymbol = true;
2614 0 : if(aLabel.ShowNumber)
2615 0 : showNumber = true;
2616 0 : if(aLabel.ShowCategoryName)
2617 0 : showCategoryName = true;
2618 0 : if(aLabel.ShowNumberInPercent)
2619 0 : showNumberInPercent = true;
2620 :
2621 0 : if(aTempLabel.ShowLegendSymbol != aLabel.ShowLegendSymbol || aTempLabel.ShowNumber!= aLabel.ShowNumber ||
2622 0 : aTempLabel.ShowCategoryName != aLabel.ShowCategoryName || aTempLabel.ShowNumberInPercent != aLabel.ShowNumberInPercent)
2623 : {
2624 0 : pFS->startElement( FSNS( XML_c, XML_dLbl ), FSEND);
2625 0 : pFS->singleElement( FSNS( XML_c, XML_idx), XML_val, I32S(nElem), FSEND);
2626 0 : pFS->singleElement( FSNS( XML_c, XML_dLblPos), XML_val, aPlacement, FSEND);
2627 :
2628 0 : if(aTempLabel.ShowLegendSymbol != aLabel.ShowLegendSymbol)
2629 : {
2630 0 : pFS->singleElement( FSNS( XML_c, XML_showLegendKey), XML_val, aLabel.ShowLegendSymbol ? "1": "0", FSEND);
2631 : }
2632 :
2633 0 : if (aTempLabel.ShowNumber!= aLabel.ShowNumber)
2634 : {
2635 0 : pFS->singleElement( FSNS( XML_c, XML_showVal), XML_val,aLabel.ShowNumber ? "1": "0", FSEND);
2636 : }
2637 :
2638 :
2639 0 : if(aTempLabel.ShowCategoryName != aLabel.ShowCategoryName)
2640 : {
2641 0 : pFS->singleElement( FSNS( XML_c, XML_showCatName), XML_val, aLabel.ShowCategoryName ? "1": "0", FSEND);
2642 : }
2643 : // MSO somehow assumes series name to be on (=displayed) by default.
2644 : // Let's put false here and switch it off then, since we have no UI means
2645 : // in LibO to toggle it on anyway
2646 0 : pFS->singleElement( FSNS( XML_c, XML_showSerName), XML_val, "0", FSEND);
2647 :
2648 0 : if(aTempLabel.ShowNumberInPercent != aLabel.ShowNumberInPercent)
2649 : {
2650 0 : pFS->singleElement( FSNS( XML_c, XML_showPercent), XML_val,aLabel.ShowNumberInPercent ? "1": "0", FSEND);
2651 : }
2652 :
2653 0 : if (GetProperty( xPropSet, "LabelSeparator"))
2654 : {
2655 0 : mAny >>= aSep;
2656 0 : pFS->startElement( FSNS( XML_c, XML_separator), FSEND);
2657 0 : pFS->writeEscaped(aSep);
2658 0 : pFS->endElement( FSNS( XML_c, XML_separator) );
2659 : }
2660 0 : pFS->endElement( FSNS( XML_c, XML_dLbl ));
2661 0 : }
2662 : }
2663 : }
2664 : }
2665 :
2666 0 : pFS->singleElement( FSNS( XML_c, XML_showLegendKey), XML_val, showLegendSymbol ? "1": "0", FSEND);
2667 0 : pFS->singleElement( FSNS( XML_c, XML_showVal), XML_val, showNumber ? "1": "0", FSEND);
2668 0 : pFS->singleElement( FSNS( XML_c, XML_showCatName), XML_val, showCategoryName ? "1": "0", FSEND);
2669 :
2670 0 : pFS->singleElement( FSNS( XML_c, XML_showSerName), XML_val, "0", FSEND);
2671 :
2672 0 : pFS->singleElement( FSNS( XML_c, XML_showPercent), XML_val, showNumberInPercent ? "1": "0", FSEND);
2673 :
2674 0 : pFS->endElement( FSNS( XML_c, XML_dLbls ) );
2675 0 : }
2676 0 : }
2677 :
2678 0 : void ChartExport::exportDataPoints(
2679 : const uno::Reference< beans::XPropertySet > & xSeriesProperties,
2680 : sal_Int32 nSeriesLength )
2681 : {
2682 0 : uno::Reference< chart2::XDataSeries > xSeries( xSeriesProperties, uno::UNO_QUERY );
2683 0 : bool bVaryColorsByPoint = false;
2684 0 : Sequence< sal_Int32 > aDataPointSeq;
2685 0 : if( xSeriesProperties.is())
2686 : {
2687 0 : Any aAny = xSeriesProperties->getPropertyValue(
2688 0 : OUString( "AttributedDataPoints" ));
2689 0 : aAny >>= aDataPointSeq;
2690 0 : xSeriesProperties->getPropertyValue(
2691 0 : OUString( "VaryColorsByPoint" )) >>= bVaryColorsByPoint;
2692 : }
2693 :
2694 0 : const sal_Int32 * pPoints = aDataPointSeq.getConstArray();
2695 : sal_Int32 nElement;
2696 0 : Reference< chart2::XColorScheme > xColorScheme;
2697 0 : if( mxNewDiagram.is())
2698 0 : xColorScheme.set( mxNewDiagram->getDefaultColorScheme());
2699 :
2700 0 : if( bVaryColorsByPoint && xColorScheme.is() )
2701 : {
2702 0 : ::std::set< sal_Int32 > aAttrPointSet;
2703 0 : ::std::copy( pPoints, pPoints + aDataPointSeq.getLength(),
2704 0 : ::std::inserter( aAttrPointSet, aAttrPointSet.begin()));
2705 0 : const ::std::set< sal_Int32 >::const_iterator aEndIt( aAttrPointSet.end());
2706 0 : for( nElement = 0; nElement < nSeriesLength; ++nElement )
2707 : {
2708 0 : uno::Reference< beans::XPropertySet > xPropSet;
2709 0 : if( aAttrPointSet.find( nElement ) != aEndIt )
2710 : {
2711 : try
2712 : {
2713 0 : xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
2714 0 : xSeries, nElement, getModel() );
2715 : }
2716 0 : catch( const uno::Exception & rEx )
2717 : {
2718 : SAL_WARN( "oox", "Exception caught during Export of data point: " << rEx.Message );
2719 : }
2720 : }
2721 : else
2722 : {
2723 : // property set only containing the color
2724 0 : xPropSet.set( new ColorPropertySet( xColorScheme->getColorByIndex( nElement )));
2725 : }
2726 :
2727 0 : if( xPropSet.is() )
2728 : {
2729 : OSL_TRACE("ChartExport::exportDataPoints -- writer data points ");
2730 0 : FSHelperPtr pFS = GetFS();
2731 : pFS->startElement( FSNS( XML_c, XML_dPt ),
2732 0 : FSEND );
2733 : pFS->singleElement( FSNS( XML_c, XML_idx ),
2734 : XML_val, I32S(nElement),
2735 0 : FSEND );
2736 0 : exportShapeProps( xPropSet );
2737 :
2738 0 : pFS->endElement( FSNS( XML_c, XML_dPt ) );
2739 : }
2740 0 : }
2741 0 : }
2742 0 : }
2743 :
2744 0 : void ChartExport::exportAxesId( sal_Int32 nAttachedAxis )
2745 : {
2746 0 : sal_Int32 nAxisIdx = lcl_generateRandomValue();
2747 0 : sal_Int32 nAxisIdy = lcl_generateRandomValue();
2748 0 : maAxes.push_back( AxisIdPair( AXIS_PRIMARY_X, nAxisIdx, nAxisIdy ) );
2749 0 : maAxes.push_back( AxisIdPair( nAttachedAxis, nAxisIdy, nAxisIdx ) );
2750 0 : FSHelperPtr pFS = GetFS();
2751 : pFS->singleElement( FSNS( XML_c, XML_axId ),
2752 : XML_val, I32S( nAxisIdx ),
2753 0 : FSEND );
2754 : pFS->singleElement( FSNS( XML_c, XML_axId ),
2755 : XML_val, I32S( nAxisIdy ),
2756 0 : FSEND );
2757 0 : if( mbHasZAxis )
2758 : {
2759 0 : sal_Int32 nAxisIdz = 0;
2760 0 : if( isDeep3dChart() )
2761 : {
2762 0 : nAxisIdz = lcl_generateRandomValue();
2763 0 : maAxes.push_back( AxisIdPair( AXIS_PRIMARY_Z, nAxisIdz, nAxisIdy ) );
2764 : }
2765 : pFS->singleElement( FSNS( XML_c, XML_axId ),
2766 : XML_val, I32S( nAxisIdz ),
2767 0 : FSEND );
2768 0 : }
2769 0 : }
2770 :
2771 0 : void ChartExport::exportGrouping( bool isBar )
2772 : {
2773 0 : FSHelperPtr pFS = GetFS();
2774 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
2775 : // grouping
2776 0 : sal_Bool bStacked = sal_False;
2777 0 : if( GetProperty( xPropSet, "Stacked" ) )
2778 0 : mAny >>= bStacked;
2779 0 : sal_Bool bPercentage = sal_False;
2780 0 : if( GetProperty( xPropSet, "Percent" ) )
2781 0 : mAny >>= bPercentage;
2782 :
2783 0 : const char* grouping = NULL;
2784 0 : if( bStacked )
2785 0 : grouping = "stacked";
2786 0 : else if( bPercentage )
2787 0 : grouping = "percentStacked";
2788 : else
2789 : {
2790 0 : if( isBar && !isDeep3dChart() )
2791 0 : grouping = "clustered";
2792 : else
2793 0 : grouping = "standard";
2794 : }
2795 : pFS->singleElement( FSNS( XML_c, XML_grouping ),
2796 : XML_val, grouping,
2797 0 : FSEND );
2798 0 : }
2799 :
2800 0 : void ChartExport::exportTrendlines( Reference< chart2::XDataSeries > xSeries )
2801 : {
2802 0 : FSHelperPtr pFS = GetFS();
2803 0 : Reference< chart2::XRegressionCurveContainer > xRegressionCurveContainer( xSeries, UNO_QUERY );
2804 0 : if( xRegressionCurveContainer.is() )
2805 : {
2806 0 : Sequence< Reference< chart2::XRegressionCurve > > aRegCurveSeq = xRegressionCurveContainer->getRegressionCurves();
2807 0 : const Reference< chart2::XRegressionCurve >* pBeg = aRegCurveSeq.getConstArray();
2808 0 : const Reference< chart2::XRegressionCurve >* pEnd = pBeg + aRegCurveSeq.getLength();
2809 0 : for( const Reference< chart2::XRegressionCurve >* pIt = pBeg; pIt != pEnd; ++pIt )
2810 : {
2811 0 : Reference< chart2::XRegressionCurve > xRegCurve = *pIt;
2812 0 : if (!xRegCurve.is())
2813 0 : continue;
2814 :
2815 0 : Reference< XPropertySet > xProperties( xRegCurve , uno::UNO_QUERY );
2816 :
2817 0 : OUString aService;
2818 0 : Reference< lang::XServiceName > xServiceName( xProperties, UNO_QUERY );
2819 0 : if( !xServiceName.is() )
2820 0 : continue;
2821 :
2822 0 : aService = xServiceName->getServiceName();
2823 :
2824 0 : if(aService != "com.sun.star.chart2.LinearRegressionCurve" &&
2825 0 : aService != "com.sun.star.chart2.ExponentialRegressionCurve" &&
2826 0 : aService != "com.sun.star.chart2.LogarithmicRegressionCurve" &&
2827 0 : aService != "com.sun.star.chart2.PotentialRegressionCurve" &&
2828 0 : aService != "com.sun.star.chart2.PolynomialRegressionCurve" &&
2829 0 : aService != "com.sun.star.chart2.MovingAverageRegressionCurve")
2830 0 : continue;
2831 :
2832 0 : pFS->startElement( FSNS( XML_c, XML_trendline ), FSEND );
2833 :
2834 0 : OUString aName;
2835 0 : xProperties->getPropertyValue("CurveName") >>= aName;
2836 0 : if(!aName.isEmpty())
2837 : {
2838 0 : pFS->startElement( FSNS( XML_c, XML_name), FSEND);
2839 0 : pFS->writeEscaped(aName);
2840 0 : pFS->endElement( FSNS( XML_c, XML_name) );
2841 : }
2842 :
2843 0 : exportShapeProps( xProperties );
2844 :
2845 0 : if( aService == "com.sun.star.chart2.LinearRegressionCurve" )
2846 : {
2847 : pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
2848 : XML_val, "linear",
2849 0 : FSEND );
2850 : }
2851 0 : else if( aService == "com.sun.star.chart2.ExponentialRegressionCurve" )
2852 : {
2853 : pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
2854 : XML_val, "exp",
2855 0 : FSEND );
2856 : }
2857 0 : else if( aService == "com.sun.star.chart2.LogarithmicRegressionCurve" )
2858 : {
2859 : pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
2860 : XML_val, "log",
2861 0 : FSEND );
2862 : }
2863 0 : else if( aService == "com.sun.star.chart2.PotentialRegressionCurve" )
2864 : {
2865 : pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
2866 : XML_val, "power",
2867 0 : FSEND );
2868 : }
2869 0 : else if( aService == "com.sun.star.chart2.PolynomialRegressionCurve" )
2870 : {
2871 : pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
2872 : XML_val, "poly",
2873 0 : FSEND );
2874 :
2875 0 : sal_Int32 aDegree = 2;
2876 0 : xProperties->getPropertyValue( "PolynomialDegree") >>= aDegree;
2877 : pFS->singleElement( FSNS( XML_c, XML_order ),
2878 : XML_val, I32S(aDegree),
2879 0 : FSEND );
2880 : }
2881 0 : else if( aService == "com.sun.star.chart2.MovingAverageRegressionCurve" )
2882 : {
2883 : pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
2884 : XML_val, "movingAvg",
2885 0 : FSEND );
2886 :
2887 0 : sal_Int32 aPeriod = 2;
2888 0 : xProperties->getPropertyValue( "MovingAveragePeriod") >>= aPeriod;
2889 :
2890 : pFS->singleElement( FSNS( XML_c, XML_period ),
2891 : XML_val, I32S(aPeriod),
2892 0 : FSEND );
2893 : }
2894 : else
2895 : {
2896 : // should never happen
2897 : // This would produce invalid OOXML files so we check earlier for the type
2898 : assert(false);
2899 : }
2900 :
2901 0 : double aExtrapolateForward = 0.0;
2902 0 : double aExtrapolateBackward = 0.0;
2903 :
2904 0 : xProperties->getPropertyValue("ExtrapolateForward") >>= aExtrapolateForward;
2905 0 : xProperties->getPropertyValue("ExtrapolateBackward") >>= aExtrapolateBackward;
2906 :
2907 : pFS->singleElement( FSNS( XML_c, XML_forward ),
2908 : XML_val, OString::number(aExtrapolateForward).getStr(),
2909 0 : FSEND );
2910 :
2911 : pFS->singleElement( FSNS( XML_c, XML_backward ),
2912 : XML_val, OString::number(aExtrapolateBackward).getStr(),
2913 0 : FSEND );
2914 :
2915 0 : sal_Bool aForceIntercept = false;
2916 0 : xProperties->getPropertyValue("ForceIntercept") >>= aForceIntercept;
2917 :
2918 0 : if (aForceIntercept)
2919 : {
2920 0 : double aInterceptValue = 0.0;
2921 0 : xProperties->getPropertyValue("InterceptValue") >>= aInterceptValue;
2922 :
2923 : pFS->singleElement( FSNS( XML_c, XML_intercept ),
2924 : XML_val, OString::number(aInterceptValue).getStr(),
2925 0 : FSEND );
2926 : }
2927 :
2928 : // Equation properties
2929 0 : Reference< XPropertySet > xEquationProperties( xRegCurve->getEquationProperties() );
2930 :
2931 : // Show Equation
2932 0 : sal_Bool aShowEquation = false;
2933 0 : xEquationProperties->getPropertyValue("ShowEquation") >>= aShowEquation;
2934 :
2935 : // Show R^2
2936 0 : sal_Bool aShowCorrelationCoefficient = false;
2937 0 : xEquationProperties->getPropertyValue("ShowCorrelationCoefficient") >>= aShowCorrelationCoefficient;
2938 :
2939 : pFS->singleElement( FSNS( XML_c, XML_dispRSqr ),
2940 : XML_val, aShowCorrelationCoefficient ? "1" : "0",
2941 0 : FSEND );
2942 :
2943 : pFS->singleElement( FSNS( XML_c, XML_dispEq ),
2944 : XML_val, aShowEquation ? "1" : "0",
2945 0 : FSEND );
2946 :
2947 0 : pFS->endElement( FSNS( XML_c, XML_trendline ) );
2948 0 : }
2949 0 : }
2950 0 : }
2951 :
2952 0 : void ChartExport::exportMarker(Reference< chart2::XDataSeries > xSeries)
2953 : {
2954 0 : Reference< XPropertySet > xPropSet( xSeries, uno::UNO_QUERY );
2955 0 : chart2::Symbol aSymbol;
2956 0 : if( GetProperty( xPropSet, "Symbol" ) )
2957 0 : mAny >>= aSymbol;
2958 :
2959 0 : if(aSymbol.Style != chart2::SymbolStyle_STANDARD && aSymbol.Style != chart2::SymbolStyle_AUTO)
2960 0 : return;
2961 :
2962 0 : FSHelperPtr pFS = GetFS();
2963 : pFS->startElement( FSNS( XML_c, XML_marker ),
2964 0 : FSEND );
2965 :
2966 0 : sal_Int32 nSymbol = aSymbol.StandardSymbol;
2967 : // TODO: more properties support for marker
2968 0 : const char* pSymbolType = NULL;
2969 0 : switch( nSymbol )
2970 : {
2971 : case 0:
2972 0 : pSymbolType = "square";
2973 0 : break;
2974 : case 1:
2975 0 : pSymbolType = "diamond";
2976 0 : break;
2977 : case 2:
2978 : case 3:
2979 : case 4:
2980 : case 5:
2981 0 : pSymbolType = "triangle";
2982 0 : break;
2983 : case 8:
2984 0 : pSymbolType = "circle";
2985 0 : break;
2986 : case 9:
2987 0 : pSymbolType = "star";
2988 0 : break;
2989 : case 10:
2990 0 : pSymbolType = "X";
2991 0 : break;
2992 : case 11:
2993 0 : pSymbolType = "plus";
2994 0 : break;
2995 : case 13:
2996 0 : pSymbolType = "dash";
2997 0 : break;
2998 : default:
2999 0 : pSymbolType = "square";
3000 0 : break;
3001 : }
3002 :
3003 0 : if( aSymbol.Style == chart2::SymbolStyle_AUTO )
3004 0 : pSymbolType = "auto";
3005 :
3006 0 : if( pSymbolType )
3007 : {
3008 : pFS->singleElement( FSNS( XML_c, XML_symbol ),
3009 : XML_val, pSymbolType,
3010 0 : FSEND );
3011 : }
3012 :
3013 0 : awt::Size aSymbolSize = aSymbol.Size;
3014 0 : sal_Int32 nSize = std::max( aSymbolSize.Width, aSymbolSize.Height );
3015 :
3016 0 : nSize = nSize/250.0*7.0; // just guessed based on some test cases
3017 0 : nSize = std::min<sal_Int32>( 72, std::max<sal_Int32>( 2, nSize ) );
3018 : pFS->singleElement( FSNS( XML_c, XML_size),
3019 : XML_val, I32S(nSize),
3020 0 : FSEND );
3021 :
3022 : pFS->startElement( FSNS( XML_c, XML_spPr ),
3023 0 : FSEND );
3024 0 : WriteSolidFill(aSymbol.FillColor);
3025 0 : pFS->endElement( FSNS( XML_c, XML_spPr ) );
3026 :
3027 0 : pFS->endElement( FSNS( XML_c, XML_marker ) );
3028 : }
3029 :
3030 0 : void ChartExport::exportSmooth()
3031 : {
3032 0 : FSHelperPtr pFS = GetFS();
3033 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY );
3034 0 : sal_Int32 nSplineType = 0;
3035 0 : if( GetProperty( xPropSet, "SplineType" ) )
3036 0 : mAny >>= nSplineType;
3037 0 : const char* pVal = nSplineType != 0 ? "1" : "0";
3038 : pFS->singleElement( FSNS( XML_c, XML_smooth ),
3039 : XML_val, pVal,
3040 0 : FSEND );
3041 0 : }
3042 :
3043 0 : void ChartExport::exportFirstSliceAng( )
3044 : {
3045 0 : FSHelperPtr pFS = GetFS();
3046 0 : sal_Int32 nStartingAngle = 0;
3047 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
3048 0 : if( GetProperty( xPropSet, "StartingAngle" ) )
3049 0 : mAny >>= nStartingAngle;
3050 :
3051 : // convert to ooxml angle
3052 0 : nStartingAngle = (450 - nStartingAngle ) % 360;
3053 : pFS->singleElement( FSNS( XML_c, XML_firstSliceAng ),
3054 : XML_val, I32S( nStartingAngle ),
3055 0 : FSEND );
3056 0 : }
3057 :
3058 : namespace {
3059 :
3060 0 : const char* getErrorBarStyle(sal_Int32 nErrorBarStyle)
3061 : {
3062 0 : switch(nErrorBarStyle)
3063 : {
3064 : case cssc::ErrorBarStyle::NONE:
3065 : // I have no idea how to map it to OOXML
3066 : // this approach is as good as any else
3067 0 : return "fixedVal";
3068 : case cssc::ErrorBarStyle::VARIANCE:
3069 0 : break;
3070 : case cssc::ErrorBarStyle::STANDARD_DEVIATION:
3071 0 : return "stdDev";
3072 : case cssc::ErrorBarStyle::ABSOLUTE:
3073 0 : return "fixedVal";
3074 : case cssc::ErrorBarStyle::RELATIVE:
3075 0 : return "percentage";
3076 : case cssc::ErrorBarStyle::ERROR_MARGIN:
3077 0 : break;
3078 : case cssc::ErrorBarStyle::STANDARD_ERROR:
3079 0 : return "stdErr";
3080 : case cssc::ErrorBarStyle::FROM_DATA:
3081 0 : return "cust";
3082 : default:
3083 : assert(false); // can't happen
3084 : }
3085 0 : return NULL;
3086 : }
3087 :
3088 0 : Reference< chart2::data::XDataSequence> getLabeledSequence(
3089 : uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences,
3090 : bool bPositive )
3091 : {
3092 0 : const OUString aRolePrefix( "error-bars" );
3093 0 : OUString aDirection;
3094 0 : if(bPositive)
3095 0 : aDirection = "positive";
3096 : else
3097 0 : aDirection = "negative";
3098 :
3099 0 : for( sal_Int32 nI=0; nI< aSequences.getLength(); ++nI )
3100 : {
3101 0 : if( aSequences[nI].is())
3102 : {
3103 0 : uno::Reference< chart2::data::XDataSequence > xSequence( aSequences[nI]->getValues());
3104 0 : uno::Reference< beans::XPropertySet > xSeqProp( xSequence, uno::UNO_QUERY_THROW );
3105 0 : OUString aRole;
3106 0 : if( ( xSeqProp->getPropertyValue(
3107 0 : OUString( "Role" )) >>= aRole ) &&
3108 0 : aRole.match( aRolePrefix ) && aRole.indexOf(aDirection) >= 0 )
3109 : {
3110 0 : return xSequence;
3111 0 : }
3112 : }
3113 : }
3114 :
3115 0 : return Reference< chart2::data::XDataSequence > ();
3116 : }
3117 :
3118 : }
3119 :
3120 0 : void ChartExport::exportErrorBar(Reference< XPropertySet> xErrorBarProps, bool bYError)
3121 : {
3122 0 : sal_Int32 nErrorBarStyle = cssc::ErrorBarStyle::NONE;
3123 0 : xErrorBarProps->getPropertyValue("ErrorBarStyle") >>= nErrorBarStyle;
3124 0 : const char* pErrorBarStyle = getErrorBarStyle(nErrorBarStyle);
3125 0 : if(!pErrorBarStyle)
3126 0 : return;
3127 :
3128 0 : FSHelperPtr pFS = GetFS();
3129 : pFS->startElement( FSNS( XML_c, XML_errBars ),
3130 0 : FSEND );
3131 : pFS->singleElement( FSNS( XML_c, XML_errDir ),
3132 : XML_val, bYError ? "y" : "x",
3133 0 : FSEND );
3134 0 : bool bPositive = false, bNegative = false;
3135 0 : xErrorBarProps->getPropertyValue("ShowPositiveError") >>= bPositive;
3136 0 : xErrorBarProps->getPropertyValue("ShowNegativeError") >>= bNegative;
3137 : const char* pErrBarType;
3138 0 : if(bPositive && bNegative)
3139 0 : pErrBarType = "both";
3140 0 : else if(bPositive)
3141 0 : pErrBarType = "plus";
3142 0 : else if(bNegative)
3143 0 : pErrBarType = "minus";
3144 : else
3145 : {
3146 : // what the hell should we do now?
3147 : // at least this makes the file valid
3148 0 : pErrBarType = "both";
3149 : }
3150 : pFS->singleElement( FSNS( XML_c, XML_errBarType ),
3151 : XML_val, pErrBarType,
3152 0 : FSEND );
3153 : pFS->singleElement( FSNS( XML_c, XML_errValType ),
3154 : XML_val, pErrorBarStyle,
3155 0 : FSEND );
3156 : pFS->singleElement( FSNS( XML_c, XML_noEndCap ),
3157 : XML_val, "0",
3158 0 : FSEND );
3159 0 : if(nErrorBarStyle == cssc::ErrorBarStyle::FROM_DATA)
3160 : {
3161 0 : uno::Reference< chart2::data::XDataSource > xDataSource(xErrorBarProps, uno::UNO_QUERY);
3162 : Sequence< Reference < chart2::data::XLabeledDataSequence > > aSequences =
3163 0 : xDataSource->getDataSequences();
3164 :
3165 0 : if(bPositive)
3166 : {
3167 0 : exportSeriesValues(getLabeledSequence(aSequences, true), XML_plus);
3168 : }
3169 :
3170 0 : if(bNegative)
3171 : {
3172 0 : exportSeriesValues(getLabeledSequence(aSequences, false), XML_minus);
3173 0 : }
3174 : }
3175 : else
3176 : {
3177 0 : double nVal = 0.0;
3178 0 : if(nErrorBarStyle == cssc::ErrorBarStyle::STANDARD_DEVIATION)
3179 : {
3180 0 : xErrorBarProps->getPropertyValue("Weight") >>= nVal;
3181 : }
3182 : else
3183 : {
3184 0 : if(bPositive)
3185 0 : xErrorBarProps->getPropertyValue("PositiveError") >>= nVal;
3186 : else
3187 0 : xErrorBarProps->getPropertyValue("NegativeError") >>= nVal;
3188 : }
3189 :
3190 0 : OString aVal = OString::number(nVal);
3191 :
3192 : pFS->singleElement( FSNS( XML_c, XML_val ),
3193 : XML_val, aVal.getStr(),
3194 0 : FSEND );
3195 : }
3196 :
3197 0 : pFS->endElement( FSNS( XML_c, XML_errBars) );
3198 : }
3199 :
3200 0 : void ChartExport::exportView3D()
3201 : {
3202 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
3203 0 : if( !xPropSet.is() )
3204 0 : return;
3205 0 : FSHelperPtr pFS = GetFS();
3206 : pFS->startElement( FSNS( XML_c, XML_view3D ),
3207 0 : FSEND );
3208 0 : sal_Int32 eChartType = getChartType( );
3209 : // rotX
3210 0 : if( GetProperty( xPropSet, "RotationHorizontal" ) )
3211 : {
3212 0 : sal_Int32 nRotationX = 0;
3213 0 : mAny >>= nRotationX;
3214 0 : if( nRotationX < 0 )
3215 : {
3216 0 : if(eChartType == chart::TYPEID_PIE)
3217 : {
3218 : /* In OOXML we get value in 0..90 range for pie chart X rotation , whereas we expect it to be in -90..90 range,
3219 : so we conver that during import. It is modified in View3DConverter::convertFromModel()
3220 : here we convert it back to 0..90 as we received in import */
3221 0 : nRotationX += 90; // X rotation (map Chart2 [-179,180] to OOXML [0..90])
3222 : }
3223 : else
3224 0 : nRotationX += 360; // X rotation (map Chart2 [-179,180] to OOXML [-90..90])
3225 : }
3226 : pFS->singleElement( FSNS( XML_c, XML_rotX ),
3227 : XML_val, I32S( nRotationX ),
3228 0 : FSEND );
3229 : }
3230 : // rotY
3231 0 : if( GetProperty( xPropSet, "RotationVertical" ) )
3232 : {
3233 : // Y rotation (map Chart2 [-179,180] to OOXML [0..359])
3234 0 : if( eChartType == chart::TYPEID_PIE && GetProperty( xPropSet, "StartingAngle" ) )
3235 : {
3236 : // Y rotation used as 'first pie slice angle' in 3D pie charts
3237 0 : sal_Int32 nStartingAngle=0;
3238 0 : mAny >>= nStartingAngle;
3239 : // convert to ooxml angle
3240 0 : nStartingAngle = (450 - nStartingAngle ) % 360;
3241 : pFS->singleElement( FSNS( XML_c, XML_rotY ),
3242 : XML_val, I32S( nStartingAngle ),
3243 0 : FSEND );
3244 : }
3245 : else
3246 : {
3247 0 : sal_Int32 nRotationY = 0;
3248 0 : mAny >>= nRotationY;
3249 : // Y rotation (map Chart2 [-179,180] to OOXML [0..359])
3250 0 : if( nRotationY < 0 )
3251 0 : nRotationY += 360;
3252 : pFS->singleElement( FSNS( XML_c, XML_rotY ),
3253 : XML_val, I32S( nRotationY ),
3254 0 : FSEND );
3255 : }
3256 : }
3257 : // rAngAx
3258 0 : if( GetProperty( xPropSet, "RightAngledAxes" ) )
3259 : {
3260 0 : sal_Bool bRightAngled = sal_False;
3261 0 : mAny >>= bRightAngled;
3262 0 : const char* sRightAngled = bRightAngled ? "1":"0";
3263 : pFS->singleElement( FSNS( XML_c, XML_rAngAx ),
3264 : XML_val, sRightAngled,
3265 0 : FSEND );
3266 : }
3267 : // perspective
3268 0 : if( GetProperty( xPropSet, "Perspective" ) )
3269 : {
3270 0 : sal_Int32 nPerspective = 0;
3271 0 : mAny >>= nPerspective;
3272 : // map Chart2 [0,100] to OOXML [0..200]
3273 0 : nPerspective *= 2;
3274 : pFS->singleElement( FSNS( XML_c, XML_perspective ),
3275 : XML_val, I32S( nPerspective ),
3276 0 : FSEND );
3277 : }
3278 0 : pFS->endElement( FSNS( XML_c, XML_view3D ) );
3279 : }
3280 :
3281 0 : bool ChartExport::isDeep3dChart()
3282 : {
3283 0 : sal_Bool isDeep = sal_False;
3284 0 : if( mbIs3DChart )
3285 : {
3286 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
3287 0 : if( GetProperty( xPropSet, "Deep" ) )
3288 0 : mAny >>= isDeep;
3289 : }
3290 0 : return isDeep;
3291 : }
3292 :
3293 : }// drawingml
3294 0 : }// oox
3295 :
3296 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|