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/chart/XChartDocument.hpp>
29 : #include <com/sun/star/chart/ChartLegendPosition.hpp>
30 : #include <com/sun/star/chart/XTwoAxisXSupplier.hpp>
31 : #include <com/sun/star/chart/XTwoAxisYSupplier.hpp>
32 : #include <com/sun/star/chart/XAxisZSupplier.hpp>
33 : #include <com/sun/star/chart/XChartDataArray.hpp>
34 : #include <com/sun/star/chart/ChartDataRowSource.hpp>
35 : #include <com/sun/star/chart/ChartAxisAssign.hpp>
36 : #include <com/sun/star/chart/ChartSeriesAddress.hpp>
37 : #include <com/sun/star/chart/X3DDisplay.hpp>
38 : #include <com/sun/star/chart/XStatisticDisplay.hpp>
39 : #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
40 : #include <com/sun/star/chart/ChartSymbolType.hpp>
41 : #include <com/sun/star/chart/ChartAxisMarks.hpp>
42 : #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
43 : #include <com/sun/star/chart/ChartAxisPosition.hpp>
44 : #include <com/sun/star/chart/ChartSolidType.hpp>
45 :
46 : #include <com/sun/star/chart2/XChartDocument.hpp>
47 : #include <com/sun/star/chart2/XDiagram.hpp>
48 : #include <com/sun/star/chart2/RelativePosition.hpp>
49 : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
50 : #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
51 : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
52 : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
53 : #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
54 : #include <com/sun/star/chart2/data/XDataSource.hpp>
55 : #include <com/sun/star/chart2/data/XDataSink.hpp>
56 : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
57 : #include <com/sun/star/chart2/data/XDataProvider.hpp>
58 : #include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
59 : #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
60 : #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
61 : #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
62 :
63 : #include <com/sun/star/beans/XPropertySet.hpp>
64 : #include <com/sun/star/beans/XPropertyState.hpp>
65 : #include <com/sun/star/container/XEnumerationAccess.hpp>
66 : #include <com/sun/star/drawing/XShape.hpp>
67 : #include <com/sun/star/drawing/FillStyle.hpp>
68 : #include <com/sun/star/drawing/BitmapMode.hpp>
69 :
70 : #include <com/sun/star/table/CellAddress.hpp>
71 : #include <com/sun/star/sheet/XFormulaParser.hpp>
72 : #include <com/sun/star/sheet/XFormulaTokens.hpp>
73 : #include <com/sun/star/sheet/FormulaToken.hpp>
74 : #include <com/sun/star/sheet/AddressConvention.hpp>
75 :
76 : #include <com/sun/star/text/WritingMode.hpp>
77 : #include <com/sun/star/container/XNamed.hpp>
78 :
79 : #include <comphelper/processfactory.hxx>
80 : #include "SchXMLSeriesHelper.hxx"
81 : #include "ColorPropertySet.hxx"
82 : #include <set>
83 : #include <time.h>
84 :
85 : using namespace ::com::sun::star;
86 : using namespace ::com::sun::star::uno;
87 : using namespace ::com::sun::star::drawing;
88 : using namespace ::oox::core;
89 : using ::com::sun::star::beans::PropertyState;
90 : using ::com::sun::star::beans::PropertyValue;
91 : using ::com::sun::star::beans::XPropertySet;
92 : using ::com::sun::star::beans::XPropertyState;
93 : using ::com::sun::star::container::XEnumeration;
94 : using ::com::sun::star::container::XEnumerationAccess;
95 : using ::com::sun::star::container::XIndexAccess;
96 : using ::com::sun::star::container::XNamed;
97 : using ::com::sun::star::io::XOutputStream;
98 : using ::com::sun::star::table::CellAddress;
99 : using ::com::sun::star::sheet::XFormulaParser;
100 : using ::com::sun::star::sheet::XFormulaTokens;
101 : using ::oox::core::XmlFilterBase;
102 : using ::sax_fastparser::FSHelperPtr;
103 :
104 : DBG(extern void dump_pset(Reference< XPropertySet > rXPropSet));
105 :
106 : #define IDS(x) (OString(#x " ") + OString::valueOf( mnShapeIdMax++ )).getStr()
107 :
108 : namespace oox { namespace drawingml {
109 :
110 : #define GETA(propName) \
111 : GetProperty( rXPropSet, String( #propName ) )
112 :
113 : #define GETAD(propName) \
114 : ( GetPropertyAndState( rXPropSet, rXPropState, String( #propName ), eState ) && eState == beans::PropertyState_DIRECT_VALUE )
115 :
116 : #define GET(variable, propName) \
117 : if ( GETA(propName) ) \
118 : mAny >>= variable;
119 :
120 0 : class lcl_MatchesRole : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool >
121 : {
122 : public:
123 0 : explicit lcl_MatchesRole( const OUString & aRole ) :
124 0 : m_aRole( aRole )
125 0 : {}
126 :
127 0 : bool operator () ( const Reference< chart2::data::XLabeledDataSequence > & xSeq ) const
128 : {
129 0 : if( !xSeq.is() )
130 0 : return false;
131 0 : Reference< beans::XPropertySet > xProp( xSeq->getValues(), uno::UNO_QUERY );
132 0 : OUString aRole;
133 :
134 0 : return ( xProp.is() &&
135 0 : (xProp->getPropertyValue(
136 0 : OUString( "Role" ) ) >>= aRole ) &&
137 0 : m_aRole.equals( aRole ));
138 : }
139 :
140 : private:
141 : OUString m_aRole;
142 : };
143 :
144 : template< typename T >
145 0 : void lcl_SequenceToVectorAppend( const Sequence< T > & rSource, ::std::vector< T > & rDestination )
146 : {
147 0 : rDestination.reserve( rDestination.size() + rSource.getLength());
148 0 : ::std::copy( rSource.getConstArray(), rSource.getConstArray() + rSource.getLength(),
149 : ::std::back_inserter( rDestination ));
150 0 : }
151 :
152 0 : Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const Reference< chart2::XDiagram > & xDiagram )
153 : {
154 0 : Reference< chart2::data::XLabeledDataSequence > xResult;
155 : try
156 : {
157 : Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
158 0 : xDiagram, uno::UNO_QUERY_THROW );
159 : Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
160 0 : xCooSysCnt->getCoordinateSystems());
161 0 : for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
162 : {
163 0 : Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[i] );
164 : OSL_ASSERT( xCooSys.is());
165 0 : for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
166 : {
167 0 : const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
168 0 : for(sal_Int32 nI=0; nI<=nMaxAxisIndex; ++nI)
169 : {
170 0 : Reference< chart2::XAxis > xAxis = xCooSys->getAxisByDimension( nN, nI );
171 : OSL_ASSERT( xAxis.is());
172 0 : if( xAxis.is())
173 : {
174 0 : chart2::ScaleData aScaleData = xAxis->getScaleData();
175 0 : if( aScaleData.Categories.is())
176 : {
177 0 : xResult.set( aScaleData.Categories );
178 : break;
179 0 : }
180 : }
181 0 : }
182 : }
183 0 : }
184 : }
185 0 : catch( const uno::Exception & ex )
186 : {
187 : (void)ex; // avoid warning for pro build
188 : OSL_FAIL( OUStringToOString(
189 : OUString( "Exception caught. Type: " ) +
190 : OUString::createFromAscii( typeid( ex ).name()) +
191 : OUString( ", Message: " ) +
192 : ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
193 : }
194 :
195 0 : return xResult;
196 : }
197 :
198 0 : Reference< chart2::data::XDataSource > lcl_createDataSource(
199 : const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aData )
200 : {
201 : Reference< uno::XComponentContext > xContext(
202 0 : comphelper::getProcessComponentContext() );
203 : Reference< chart2::data::XDataSink > xSink(
204 0 : xContext->getServiceManager()->createInstanceWithContext(
205 0 : "com.sun.star.chart2.data.DataSource", xContext ),
206 0 : uno::UNO_QUERY_THROW );
207 0 : if( xSink.is())
208 0 : xSink->setData( aData );
209 :
210 0 : return Reference< chart2::data::XDataSource >( xSink, uno::UNO_QUERY );
211 : }
212 :
213 0 : Sequence< Reference< chart2::data::XLabeledDataSequence > > lcl_getAllSeriesSequences( const Reference< chart2::XChartDocument >& xChartDoc )
214 : {
215 0 : ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aContainer;
216 0 : if( xChartDoc.is() )
217 : {
218 0 : Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
219 0 : ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( SchXMLSeriesHelper::getDataSeriesFromDiagram( xDiagram ));
220 0 : for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aSeriesIt( aSeriesVector.begin() )
221 0 : ; aSeriesIt != aSeriesVector.end(); ++aSeriesIt )
222 : {
223 0 : Reference< chart2::data::XDataSource > xDataSource( *aSeriesIt, uno::UNO_QUERY );
224 0 : if( !xDataSource.is() )
225 0 : continue;
226 0 : uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > aDataSequences( xDataSource->getDataSequences() );
227 0 : lcl_SequenceToVectorAppend( aDataSequences, aContainer );
228 0 : }
229 : }
230 :
231 0 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aRet( aContainer.size());
232 0 : ::std::copy( aContainer.begin(), aContainer.end(), aRet.getArray());
233 :
234 0 : return aRet;
235 : }
236 :
237 : Reference< chart2::data::XLabeledDataSequence >
238 0 : lcl_getDataSequenceByRole(
239 : const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aLabeledSeq,
240 : const OUString & rRole )
241 : {
242 0 : Reference< chart2::data::XLabeledDataSequence > aNoResult;
243 :
244 0 : const Reference< chart2::data::XLabeledDataSequence > * pBegin = aLabeledSeq.getConstArray();
245 0 : const Reference< chart2::data::XLabeledDataSequence > * pEnd = pBegin + aLabeledSeq.getLength();
246 : const Reference< chart2::data::XLabeledDataSequence > * pMatch =
247 0 : ::std::find_if( pBegin, pEnd, lcl_MatchesRole( rRole ));
248 :
249 0 : if( pMatch != pEnd )
250 0 : return *pMatch;
251 :
252 0 : return aNoResult;
253 : }
254 :
255 0 : Reference< chart2::data::XDataSource > lcl_pressUsedDataIntoRectangularFormat( const Reference< chart2::XChartDocument >& xChartDoc, sal_Bool& rOutSourceHasCategoryLabels )
256 : {
257 0 : ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aLabeledSeqVector;
258 :
259 : //categories are always the first sequence
260 0 : Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
261 0 : Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xDiagram ) );
262 0 : if( xCategories.is() )
263 0 : aLabeledSeqVector.push_back( xCategories );
264 0 : rOutSourceHasCategoryLabels = sal_Bool(xCategories.is());
265 :
266 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeriesSeqVector(
267 0 : lcl_getAllSeriesSequences( xChartDoc ) );
268 :
269 : //the first x-values is always the next sequence //todo ... other x-values get lost for old format
270 : Reference< chart2::data::XLabeledDataSequence > xXValues(
271 0 : lcl_getDataSequenceByRole( aSeriesSeqVector, OUString("values-x") ) );
272 0 : if( xXValues.is() )
273 0 : aLabeledSeqVector.push_back( xXValues );
274 :
275 : //add all other sequences now without x-values
276 0 : lcl_MatchesRole aHasXValues( OUString("values-x") );
277 0 : for( sal_Int32 nN=0; nN<aSeriesSeqVector.getLength(); nN++ )
278 : {
279 0 : if( !aHasXValues( aSeriesSeqVector[nN] ) )
280 0 : aLabeledSeqVector.push_back( aSeriesSeqVector[nN] );
281 : }
282 :
283 0 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( aLabeledSeqVector.size() );
284 0 : ::std::copy( aLabeledSeqVector.begin(), aLabeledSeqVector.end(), aSeq.getArray() );
285 :
286 0 : return lcl_createDataSource( aSeq );
287 : }
288 :
289 0 : bool lcl_isSeriesAttachedToFirstAxis(
290 : const Reference< chart2::XDataSeries > & xDataSeries )
291 : {
292 0 : bool bResult=true;
293 :
294 : try
295 : {
296 0 : sal_Int32 nAxisIndex = 0;
297 0 : Reference< beans::XPropertySet > xProp( xDataSeries, uno::UNO_QUERY_THROW );
298 0 : if( xProp.is() )
299 0 : xProp->getPropertyValue( OUString( "AttachedAxisIndex" ) ) >>= nAxisIndex;
300 0 : bResult = (0==nAxisIndex);
301 : }
302 0 : catch( const uno::Exception & ex )
303 : {
304 : (void)ex; // avoid warning for pro build
305 : OSL_FAIL( OUStringToOString(
306 : OUString( "Exception caught. Type: " ) +
307 : OUString::createFromAscii( typeid( ex ).name()) +
308 : OUString( ", Message: " ) +
309 : ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
310 : }
311 :
312 0 : return bResult;
313 : }
314 :
315 0 : OUString lcl_flattenStringSequence( const Sequence< OUString > & rSequence )
316 : {
317 0 : OUStringBuffer aResult;
318 0 : bool bPrecedeWithSpace = false;
319 0 : for( sal_Int32 nIndex=0; nIndex<rSequence.getLength(); ++nIndex )
320 : {
321 0 : if( !rSequence[nIndex].isEmpty())
322 : {
323 0 : if( bPrecedeWithSpace )
324 0 : aResult.append( static_cast< sal_Unicode >( ' ' ));
325 0 : aResult.append( rSequence[nIndex] );
326 0 : bPrecedeWithSpace = true;
327 : }
328 : }
329 0 : return aResult.makeStringAndClear();
330 : }
331 :
332 0 : OUString lcl_getLabelString( const Reference< chart2::data::XDataSequence > & xLabelSeq )
333 : {
334 0 : Sequence< OUString > aLabels;
335 :
336 0 : uno::Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xLabelSeq, uno::UNO_QUERY );
337 0 : if( xTextualDataSequence.is())
338 : {
339 0 : aLabels = xTextualDataSequence->getTextualData();
340 : }
341 0 : else if( xLabelSeq.is())
342 : {
343 0 : Sequence< uno::Any > aAnies( xLabelSeq->getData());
344 0 : aLabels.realloc( aAnies.getLength());
345 0 : for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
346 0 : aAnies[i] >>= aLabels[i];
347 : }
348 :
349 0 : return lcl_flattenStringSequence( aLabels );
350 : }
351 :
352 0 : void lcl_fillCategoriesIntoStringVector(
353 : const Reference< chart2::data::XDataSequence > & xCategories,
354 : ::std::vector< OUString > & rOutCategories )
355 : {
356 : OSL_ASSERT( xCategories.is());
357 0 : if( !xCategories.is())
358 0 : return;
359 0 : Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xCategories, uno::UNO_QUERY );
360 0 : if( xTextualDataSequence.is())
361 : {
362 0 : rOutCategories.clear();
363 0 : Sequence< OUString > aTextData( xTextualDataSequence->getTextualData());
364 0 : ::std::copy( aTextData.getConstArray(), aTextData.getConstArray() + aTextData.getLength(),
365 0 : ::std::back_inserter( rOutCategories ));
366 : }
367 : else
368 : {
369 0 : Sequence< uno::Any > aAnies( xCategories->getData());
370 0 : rOutCategories.resize( aAnies.getLength());
371 0 : for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
372 0 : aAnies[i] >>= rOutCategories[i];
373 0 : }
374 : }
375 :
376 0 : ::std::vector< double > lcl_getAllValuesFromSequence( const Reference< chart2::data::XDataSequence > & xSeq )
377 : {
378 0 : double fNan = 0.0;
379 0 : ::rtl::math::setNan( &fNan );
380 0 : ::std::vector< double > aResult;
381 :
382 0 : Reference< chart2::data::XNumericalDataSequence > xNumSeq( xSeq, uno::UNO_QUERY );
383 0 : if( xNumSeq.is())
384 : {
385 0 : Sequence< double > aValues( xNumSeq->getNumericalData());
386 0 : ::std::copy( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(),
387 0 : ::std::back_inserter( aResult ));
388 : }
389 0 : else if( xSeq.is())
390 : {
391 0 : Sequence< uno::Any > aAnies( xSeq->getData());
392 0 : aResult.resize( aAnies.getLength(), fNan );
393 0 : for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
394 0 : aAnies[i] >>= aResult[i];
395 : }
396 0 : return aResult;
397 : }
398 :
399 0 : sal_Int32 lcl_getChartType( const OUString& sChartType )
400 : {
401 0 : chart::TypeId eChartTypeId = chart::TYPEID_UNKNOWN;
402 0 : if(( 0 == sChartType.reverseCompareTo( "com.sun.star.chart.BarDiagram" ))
403 0 : || ( 0 == sChartType.reverseCompareTo( "com.sun.star.chart2.ColumnChartType" )))
404 0 : eChartTypeId = chart::TYPEID_BAR;
405 0 : else if(( 0 == sChartType.reverseCompareTo( "com.sun.star.chart.AreaDiagram" ))
406 0 : || ( 0 == sChartType.reverseCompareTo( "com.sun.star.chart2.AreaChartType" ) ) )
407 0 : eChartTypeId = chart::TYPEID_AREA;
408 0 : else if(( 0 == sChartType.reverseCompareTo( "com.sun.star.chart.LineDiagram" ))
409 0 : || ( 0 == sChartType.reverseCompareTo( "com.sun.star.chart2.LineChartType" ) ) )
410 0 : eChartTypeId = chart::TYPEID_LINE;
411 0 : else if(( 0 == sChartType.reverseCompareTo( "com.sun.star.chart.PieDiagram" ))
412 0 : || ( 0 == sChartType.reverseCompareTo( "com.sun.star.chart2.PieChartType") ) )
413 0 : eChartTypeId = chart::TYPEID_PIE;
414 0 : else if(( 0 == sChartType.reverseCompareTo( "com.sun.star.chart.DonutDiagram"))
415 0 : || ( 0 == sChartType.reverseCompareTo( "com.sun.star.chart2.DonutChartType") ) )
416 0 : eChartTypeId = chart::TYPEID_DOUGHNUT;
417 0 : else if(( 0 == sChartType.reverseCompareTo( "com.sun.star.chart.XYDiagram"))
418 0 : || ( 0 == sChartType.reverseCompareTo( "com.sun.star.chart2.ScatterChartType") ) )
419 0 : eChartTypeId = chart::TYPEID_SCATTER;
420 0 : else if(( 0 == sChartType.reverseCompareTo( "com.sun.star.chart.NetDiagram"))
421 0 : || ( 0 == sChartType.reverseCompareTo( "com.sun.star.chart2.NetChartType") ) )
422 0 : eChartTypeId = chart::TYPEID_RADARLINE;
423 0 : else if(( 0 == sChartType.reverseCompareTo( "com.sun.star.chart.FilledNetDiagram"))
424 0 : || ( 0 == sChartType.reverseCompareTo( "com.sun.star.chart2.FilledNetChartType") ) )
425 0 : eChartTypeId = chart::TYPEID_RADARAREA;
426 0 : else if(( 0 == sChartType.reverseCompareTo( "com.sun.star.chart.StockDiagram"))
427 0 : || ( 0 == sChartType.reverseCompareTo( "com.sun.star.chart2.CandleStickChartType") ) )
428 0 : eChartTypeId = chart::TYPEID_STOCK;
429 0 : else if(( 0 == sChartType.reverseCompareTo( "com.sun.star.chart.BubbleDiagram"))
430 0 : || ( 0 == sChartType.reverseCompareTo( "com.sun.star.chart2.BubbleChartType") ) )
431 0 : eChartTypeId = chart::TYPEID_BUBBLE;
432 :
433 0 : return eChartTypeId;
434 : }
435 :
436 0 : sal_Int32 lcl_generateRandomValue()
437 : {
438 : static sal_Int32 MAX_NUMBER = 100000000;
439 : //srand( unsigned( time( NULL ) ));
440 0 : return sal_Int32( rand() % MAX_NUMBER );
441 : }
442 :
443 0 : ChartExport::ChartExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, Reference< frame::XModel >& xModel, XmlFilterBase* pFB, DocumentType eDocumentType )
444 : : DrawingML( pFS, pFB, eDocumentType )
445 : , mnXmlNamespace( nXmlNamespace )
446 : , maFraction( 1, 576 )
447 : , mxChartModel( xModel )
448 : , mbHasSeriesLabels( sal_False )
449 : , mbHasCategoryLabels( sal_False )
450 : , mbRowSourceColumns( sal_True )
451 : , mbHasXAxis( sal_False )
452 : , mbHasYAxis( sal_False )
453 : , mbHasZAxis( sal_False )
454 : , mbHasSecondaryXAxis( sal_False )
455 : , mbHasSecondaryYAxis( sal_False )
456 0 : , mbIs3DChart( sal_False )
457 : {
458 0 : }
459 :
460 0 : sal_Int32 ChartExport::GetChartID( )
461 : {
462 0 : sal_Int32 nID = GetFB()->GetUniqueId();
463 0 : return nID;
464 : }
465 :
466 0 : sal_Int32 ChartExport::getChartType( )
467 : {
468 0 : OUString sChartType = mxDiagram->getDiagramType();
469 0 : return lcl_getChartType( sChartType );
470 : }
471 :
472 0 : OUString ChartExport::parseFormula( const OUString& rRange )
473 : {
474 0 : OUString aResult;
475 0 : Reference< XFormulaParser > xParser;
476 0 : uno::Reference< lang::XMultiServiceFactory > xSF( GetFB()->getModelFactory(), uno::UNO_QUERY );
477 0 : if( xSF.is() )
478 : {
479 : try
480 : {
481 0 : xParser.set( xSF->createInstance( OUString("com.sun.star.sheet.FormulaParser") ), UNO_QUERY );
482 : }
483 0 : catch( Exception& )
484 : {
485 : }
486 : }
487 0 : if( xParser.is() )
488 : {
489 : OSL_TRACE("ChartExport::parseFormula, parser is valid");
490 0 : Reference< XPropertySet > xParserProps( xParser, uno::UNO_QUERY );
491 0 : if( xParserProps.is() )
492 : {
493 0 : xParserProps->setPropertyValue( OUString("FormulaConvention"), uno::makeAny(::com::sun::star::sheet::AddressConvention::OOO) );
494 : }
495 0 : uno::Sequence<sheet::FormulaToken> aTokens = xParser->parseFormula( rRange, CellAddress( 0, 0, 0 ) );
496 0 : if( xParserProps.is() )
497 : {
498 0 : xParserProps->setPropertyValue( OUString("FormulaConvention"), uno::makeAny(::com::sun::star::sheet::AddressConvention::XL_OOX) );
499 : }
500 0 : aResult = xParser->printFormula( aTokens, CellAddress( 0, 0, 0 ) );
501 : }
502 : else
503 : {
504 : OSL_TRACE("ChartExport::parseFormula, parser is invalid");
505 : //FIXME: currently just using simple converter, e.g $Sheet1.$A$1:$C$1 -> Sheet1!$A$1:$C$1
506 0 : OUString aRange( rRange );
507 0 : if( aRange.indexOf("$") == 0 )
508 0 : aRange = aRange.copy(1);
509 0 : aRange = aRange.replaceAll(".$", "!$" );
510 0 : aResult = aRange;
511 : }
512 :
513 : 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());
514 0 : return aResult;
515 : }
516 :
517 0 : ChartExport& ChartExport::WriteChartObj( const Reference< XShape >& xShape, sal_Int32 nChartCount )
518 : {
519 : OSL_TRACE("ChartExport::WriteChartObj -- writer chart object");
520 0 : FSHelperPtr pFS = GetFS();
521 :
522 0 : pFS->startElementNS( mnXmlNamespace, XML_graphicFrame, FSEND );
523 :
524 0 : pFS->startElementNS( mnXmlNamespace, XML_nvGraphicFramePr, FSEND );
525 :
526 : // TODO: get the correct chart name chart id
527 0 : OUString sName = S("Object 1");
528 0 : Reference< XNamed > xNamed( xShape, UNO_QUERY );
529 0 : if (xNamed.is())
530 0 : sName = xNamed->getName();
531 :
532 0 : sal_Int32 nID = GetChartID();
533 :
534 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
535 : XML_id, I32S( nID ),
536 : XML_name, USS( sName ),
537 0 : FSEND );
538 :
539 : pFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr,
540 0 : FSEND );
541 :
542 0 : if( GetDocumentType() == DOCUMENT_PPTX )
543 : pFS->singleElementNS( mnXmlNamespace, XML_nvPr,
544 0 : FSEND );
545 0 : pFS->endElementNS( mnXmlNamespace, XML_nvGraphicFramePr );
546 :
547 : // visual chart properties
548 0 : WriteShapeTransformation( xShape, mnXmlNamespace );
549 :
550 : // writer chart object
551 0 : pFS->startElement( FSNS( XML_a, XML_graphic ), FSEND );
552 : pFS->startElement( FSNS( XML_a, XML_graphicData ),
553 : XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/chart",
554 0 : FSEND );
555 0 : OUString sId;
556 0 : const char* sFullPath = NULL;
557 0 : const char* sRelativePath = NULL;
558 0 : switch( GetDocumentType() )
559 : {
560 : case DOCUMENT_DOCX:
561 : {
562 0 : sFullPath = "word/charts/chart";
563 0 : sRelativePath = "charts/chart";
564 0 : break;
565 : }
566 : case DOCUMENT_PPTX:
567 : {
568 0 : sFullPath = "ppt/charts/chart";
569 0 : sRelativePath = "../charts/chart";
570 0 : break;
571 : }
572 : case DOCUMENT_XLSX:
573 : {
574 0 : sFullPath = "xl/charts/chart";
575 0 : sRelativePath = "../charts/chart";
576 0 : break;
577 : }
578 : default:
579 : {
580 0 : sFullPath = "charts/chart";
581 0 : sRelativePath = "charts/chart";
582 0 : break;
583 : }
584 : }
585 : OUString sFullStream = OUStringBuffer()
586 0 : .appendAscii(sFullPath)
587 0 : .append(nChartCount)
588 0 : .appendAscii( ".xml" )
589 0 : .makeStringAndClear();
590 : OUString sRelativeStream = OUStringBuffer()
591 0 : .appendAscii(sRelativePath)
592 0 : .append(nChartCount)
593 0 : .appendAscii( ".xml" )
594 0 : .makeStringAndClear();
595 : FSHelperPtr pChart = CreateOutputStream(
596 : sFullStream,
597 : sRelativeStream,
598 : pFS->getOutputStream(),
599 : "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
600 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
601 0 : &sId );
602 :
603 : pFS->singleElement( FSNS( XML_c, XML_chart ),
604 : FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
605 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
606 : FSNS( XML_r, XML_id ), USS( sId ),
607 0 : FSEND );
608 :
609 0 : pFS->endElement( FSNS( XML_a, XML_graphicData ) );
610 0 : pFS->endElement( FSNS( XML_a, XML_graphic ) );
611 0 : pFS->endElementNS( mnXmlNamespace, XML_graphicFrame );
612 :
613 0 : SetFS( pChart );
614 0 : ExportContent();
615 :
616 0 : return *this;
617 : }
618 :
619 0 : void ChartExport::InitRangeSegmentationProperties( const Reference< chart2::XChartDocument > & xChartDoc )
620 : {
621 0 : if( xChartDoc.is())
622 : try
623 : {
624 0 : Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
625 : OSL_ENSURE( xDataProvider.is(), "No DataProvider" );
626 0 : if( xDataProvider.is())
627 : {
628 0 : Reference< chart2::data::XDataSource > xDataSource( lcl_pressUsedDataIntoRectangularFormat( xChartDoc, mbHasCategoryLabels ));
629 0 : Sequence< beans::PropertyValue > aArgs( xDataProvider->detectArguments( xDataSource ));
630 0 : OUString sCellRange, sBrokenRange;
631 0 : bool bBrokenRangeAvailable = false;
632 0 : for( sal_Int32 i=0; i<aArgs.getLength(); ++i )
633 : {
634 0 : if ( aArgs[i].Name == "CellRangeRepresentation" )
635 0 : aArgs[i].Value >>= sCellRange;
636 0 : else if ( aArgs[i].Name == "BrokenCellRangeForExport" )
637 : {
638 0 : if( aArgs[i].Value >>= sBrokenRange )
639 0 : bBrokenRangeAvailable = true;
640 : }
641 0 : else if ( aArgs[i].Name == "DataRowSource" )
642 : {
643 : ::com::sun::star::chart::ChartDataRowSource eRowSource;
644 0 : aArgs[i].Value >>= eRowSource;
645 0 : mbRowSourceColumns = ( eRowSource == ::com::sun::star::chart::ChartDataRowSource_COLUMNS );
646 : }
647 0 : else if ( aArgs[i].Name == "FirstCellAsLabel" )
648 0 : aArgs[i].Value >>= mbHasSeriesLabels;
649 0 : else if ( aArgs[i].Name == "SequenceMapping" )
650 0 : aArgs[i].Value >>= maSequenceMapping;
651 0 : else if ( aArgs[i].Name == "TableNumberList" )
652 0 : aArgs[i].Value >>= msTableNumberList;
653 : }
654 :
655 : // #i79009# For Writer we have to export a broken version of the
656 : // range, where every row number is noe too large, so that older
657 : // version can correctly read those files.
658 0 : msChartAddress = (bBrokenRangeAvailable ? sBrokenRange : sCellRange);
659 0 : if( !msChartAddress.isEmpty() )
660 : {
661 : // convert format to XML-conform one
662 0 : Reference< chart2::data::XRangeXMLConversion > xConversion( xDataProvider, uno::UNO_QUERY );
663 0 : if( xConversion.is())
664 0 : msChartAddress = xConversion->convertRangeToXML( msChartAddress );
665 0 : }
666 0 : }
667 : }
668 0 : catch( const uno::Exception & ex )
669 : {
670 : (void)ex; // avoid warning for pro build
671 : OSL_FAIL( OUStringToOString(
672 : OUString( "Exception caught. Type: " ) +
673 : OUString::createFromAscii( typeid( ex ).name()) +
674 : OUString( ", Message: " ) +
675 : ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
676 : }
677 0 : }
678 :
679 0 : void ChartExport::ExportContent()
680 : {
681 0 : Reference< chart2::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
682 : OSL_ASSERT( xChartDoc.is() );
683 0 : if( !xChartDoc.is() )
684 0 : return;
685 0 : InitRangeSegmentationProperties( xChartDoc );
686 : // TODO: export chart
687 0 : _ExportContent( );
688 : }
689 :
690 0 : void ChartExport::_ExportContent()
691 : {
692 0 : Reference< ::com::sun::star::chart::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
693 0 : if( xChartDoc.is())
694 : {
695 : // determine if data comes from the outside
696 0 : sal_Bool bIncludeTable = sal_True;
697 :
698 0 : Reference< chart2::XChartDocument > xNewDoc( xChartDoc, uno::UNO_QUERY );
699 0 : if( xNewDoc.is())
700 : {
701 : // check if we have own data. If so we must not export the complete
702 : // range string, as this is our only indicator for having own or
703 : // external data. @todo: fix this in the file format!
704 0 : Reference< lang::XServiceInfo > xDPServiceInfo( xNewDoc->getDataProvider(), uno::UNO_QUERY );
705 0 : if( ! (xDPServiceInfo.is() && xDPServiceInfo->getImplementationName() == "com.sun.star.comp.chart.InternalDataProvider" ))
706 : {
707 0 : bIncludeTable = sal_False;
708 0 : }
709 : }
710 : else
711 : {
712 0 : Reference< lang::XServiceInfo > xServ( xChartDoc, uno::UNO_QUERY );
713 0 : if( xServ.is())
714 : {
715 0 : if( xServ->supportsService(
716 0 : OUString("com.sun.star.chart.ChartTableAddressSupplier")))
717 : {
718 0 : Reference< beans::XPropertySet > xProp( xServ, uno::UNO_QUERY );
719 0 : if( xProp.is())
720 : {
721 0 : Any aAny;
722 : try
723 : {
724 0 : OUString sChartAddress;
725 0 : aAny = xProp->getPropertyValue(
726 0 : OUString("ChartRangeAddress"));
727 0 : aAny >>= msChartAddress;
728 : //maExportHelper.SetChartRangeAddress( sChartAddress );
729 :
730 : // OUString sTableNumberList;
731 0 : aAny = xProp->getPropertyValue(
732 0 : OUString("TableNumberList"));
733 0 : aAny >>= msTableNumberList;
734 : //maExportHelper.SetTableNumberList( sTableNumberList );
735 :
736 : // do not include own table if there are external addresses
737 0 : bIncludeTable = sChartAddress.isEmpty();
738 : }
739 0 : catch( beans::UnknownPropertyException & )
740 : {
741 : OSL_FAIL( "Property ChartRangeAddress not supported by ChartDocument" );
742 0 : }
743 0 : }
744 : }
745 0 : }
746 : }
747 0 : exportChartSpace( xChartDoc, bIncludeTable );
748 : }
749 : else
750 : {
751 : OSL_FAIL( "Couldn't export chart due to wrong XModel" );
752 0 : }
753 0 : }
754 :
755 0 : void ChartExport::exportChartSpace( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc,
756 : sal_Bool bIncludeTable )
757 : {
758 0 : FSHelperPtr pFS = GetFS();
759 : pFS->startElement( FSNS( XML_c, XML_chartSpace ),
760 : FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
761 : FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
762 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
763 0 : FSEND );
764 : // TODO: get the correct editing lanauge
765 : pFS->singleElement( FSNS( XML_c, XML_lang ),
766 : XML_val, "en-US",
767 0 : FSEND );
768 :
769 : if( !bIncludeTable )
770 : {
771 : // TODO:external data
772 : }
773 : //XML_chart
774 0 : exportChart(rChartDoc);
775 :
776 : // TODO: printSettings
777 : // TODO: style
778 : // TODO: text properties
779 : // TODO: shape properties
780 0 : Reference< XPropertySet > xPropSet( rChartDoc->getArea(), uno::UNO_QUERY );
781 0 : if( xPropSet.is() )
782 0 : exportShapeProps( xPropSet );
783 0 : pFS->endElement( FSNS( XML_c, XML_chartSpace ) );
784 0 : }
785 :
786 0 : void ChartExport::exportChart( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc )
787 : {
788 0 : Reference< chart2::XChartDocument > xNewDoc( rChartDoc, uno::UNO_QUERY );
789 0 : mxDiagram.set( rChartDoc->getDiagram() );
790 0 : if( xNewDoc.is())
791 0 : mxNewDiagram.set( xNewDoc->getFirstDiagram());
792 :
793 : // get Properties of ChartDocument
794 0 : sal_Bool bHasMainTitle = sal_False;
795 0 : sal_Bool bHasSubTitle = sal_False;
796 0 : sal_Bool bHasLegend = sal_False;
797 0 : Reference< beans::XPropertySet > xDocPropSet( rChartDoc, uno::UNO_QUERY );
798 0 : if( xDocPropSet.is())
799 : {
800 : try
801 : {
802 0 : Any aAny( xDocPropSet->getPropertyValue(
803 0 : OUString( "HasMainTitle" )));
804 0 : aAny >>= bHasMainTitle;
805 0 : aAny = xDocPropSet->getPropertyValue(
806 0 : OUString( "HasSubTitle" ));
807 0 : aAny >>= bHasSubTitle;
808 0 : aAny = xDocPropSet->getPropertyValue(
809 0 : OUString( "HasLegend" ));
810 0 : aAny >>= bHasLegend;
811 : }
812 0 : catch( beans::UnknownPropertyException & )
813 : {
814 : DBG_WARNING( "Required property not found in ChartDocument" );
815 : }
816 : } // if( xDocPropSet.is())
817 :
818 : // chart element
819 : // -------------
820 0 : FSHelperPtr pFS = GetFS();
821 : pFS->startElement( FSNS( XML_c, XML_chart ),
822 0 : FSEND );
823 :
824 : // title
825 0 : if( bHasMainTitle )
826 : {
827 0 : Reference< drawing::XShape > xShape = rChartDoc->getTitle();
828 0 : if( xShape.is() )
829 0 : exportTitle( xShape );
830 : }
831 0 : InitPlotArea( );
832 0 : if( mbIs3DChart )
833 : {
834 0 : exportView3D();
835 :
836 : // sideWall
837 :
838 : // backWall
839 0 : Reference< beans::XPropertySet > xBackWall( mxNewDiagram->getWall(), uno::UNO_QUERY );
840 0 : if( xBackWall.is() )
841 : {
842 : pFS->startElement( FSNS( XML_c, XML_backWall ),
843 0 : FSEND );
844 0 : exportShapeProps( xBackWall );
845 0 : pFS->endElement( FSNS( XML_c, XML_backWall ) );
846 : }
847 :
848 : // floor
849 0 : Reference< beans::XPropertySet > xFloor( mxNewDiagram->getFloor(), uno::UNO_QUERY );
850 0 : if( xFloor.is() )
851 : {
852 : pFS->startElement( FSNS( XML_c, XML_floor ),
853 0 : FSEND );
854 0 : exportShapeProps( xFloor );
855 0 : pFS->endElement( FSNS( XML_c, XML_floor ) );
856 0 : }
857 :
858 : }
859 : // plot area
860 0 : exportPlotArea( );
861 : // legend
862 0 : if( bHasLegend )
863 0 : exportLegend( rChartDoc );
864 : // only visible cells should be plotted on the chart
865 : pFS->singleElement( FSNS( XML_c, XML_plotVisOnly ),
866 : XML_val, "1",
867 0 : FSEND );
868 :
869 0 : pFS->endElement( FSNS( XML_c, XML_chart ) );
870 0 : }
871 :
872 0 : void ChartExport::exportLegend( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc )
873 : {
874 0 : FSHelperPtr pFS = GetFS();
875 : pFS->startElement( FSNS( XML_c, XML_legend ),
876 0 : FSEND );
877 :
878 0 : Reference< beans::XPropertySet > xProp( rChartDoc->getLegend(), uno::UNO_QUERY );
879 0 : if( xProp.is() )
880 : {
881 : // position
882 0 : ::com::sun::star::chart::ChartLegendPosition aLegendPos = ::com::sun::star::chart::ChartLegendPosition_NONE;
883 : try
884 : {
885 0 : Any aAny( xProp->getPropertyValue(
886 0 : OUString( "Alignment" )));
887 0 : aAny >>= aLegendPos;
888 : }
889 0 : catch( beans::UnknownPropertyException & )
890 : {
891 : DBG_WARNING( "Property Align not found in ChartLegend" );
892 : }
893 :
894 0 : const char* strPos = NULL;
895 0 : switch( aLegendPos )
896 : {
897 : case ::com::sun::star::chart::ChartLegendPosition_LEFT:
898 0 : strPos = "l";
899 0 : break;
900 : case ::com::sun::star::chart::ChartLegendPosition_RIGHT:
901 0 : strPos = "r";
902 0 : break;
903 : case ::com::sun::star::chart::ChartLegendPosition_TOP:
904 0 : strPos = "t";
905 0 : break;
906 : case ::com::sun::star::chart::ChartLegendPosition_BOTTOM:
907 0 : strPos = "b";
908 0 : break;
909 : case ::com::sun::star::chart::ChartLegendPosition_NONE:
910 : case ::com::sun::star::chart::ChartLegendPosition_MAKE_FIXED_SIZE:
911 : // nothing
912 0 : break;
913 : }
914 :
915 0 : if( strPos != NULL )
916 : {
917 : pFS->singleElement( FSNS( XML_c, XML_legendPos ),
918 : XML_val, strPos,
919 0 : FSEND );
920 : }
921 :
922 : // shape properties
923 0 : exportShapeProps( xProp );
924 : }
925 :
926 : // legendEntry
927 :
928 0 : pFS->endElement( FSNS( XML_c, XML_legend ) );
929 0 : }
930 :
931 0 : void ChartExport::exportTitle( Reference< XShape > xShape )
932 : {
933 0 : OUString sText;
934 0 : Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
935 0 : if( xPropSet.is())
936 : {
937 0 : xPropSet->getPropertyValue( OUString( "String" )) >>= sText;
938 : }
939 0 : if( sText.isEmpty() )
940 0 : return;
941 :
942 0 : FSHelperPtr pFS = GetFS();
943 : pFS->startElement( FSNS( XML_c, XML_title ),
944 0 : FSEND );
945 : // TODO:customize layout
946 : pFS->singleElement( FSNS( XML_c, XML_layout ),
947 0 : FSEND );
948 :
949 : pFS->startElement( FSNS( XML_c, XML_tx ),
950 0 : FSEND );
951 : pFS->startElement( FSNS( XML_c, XML_rich ),
952 0 : FSEND );
953 :
954 : // TODO: bodyPr
955 0 : const char* sWritingMode = NULL;
956 0 : sal_Bool bVertical = sal_False;
957 0 : xPropSet->getPropertyValue( OUString( "StackedText" )) >>= bVertical;
958 0 : if( bVertical )
959 0 : sWritingMode = "wordArtVert";
960 :
961 : pFS->singleElement( FSNS( XML_a, XML_bodyPr ),
962 : XML_vert, sWritingMode,
963 0 : FSEND );
964 : // TODO: lstStyle
965 : pFS->singleElement( FSNS( XML_a, XML_lstStyle ),
966 0 : FSEND );
967 : // FIXME: handle multipul paragraphs to parse aText
968 : pFS->startElement( FSNS( XML_a, XML_p ),
969 0 : FSEND );
970 :
971 : pFS->startElement( FSNS( XML_a, XML_pPr ),
972 0 : FSEND );
973 : pFS->singleElement( FSNS( XML_a, XML_defRPr ),
974 0 : FSEND );
975 0 : pFS->endElement( FSNS( XML_a, XML_pPr ) );
976 :
977 : pFS->startElement( FSNS( XML_a, XML_r ),
978 0 : FSEND );
979 0 : WriteRunProperties( xPropSet, sal_False );
980 : pFS->startElement( FSNS( XML_a, XML_t ),
981 0 : FSEND );
982 0 : pFS->writeEscaped( sText );
983 0 : pFS->endElement( FSNS( XML_a, XML_t ) );
984 0 : pFS->endElement( FSNS( XML_a, XML_r ) );
985 :
986 0 : pFS->endElement( FSNS( XML_a, XML_p ) );
987 :
988 0 : pFS->endElement( FSNS( XML_c, XML_rich ) );
989 0 : pFS->endElement( FSNS( XML_c, XML_tx ) );
990 0 : pFS->endElement( FSNS( XML_c, XML_title ) );
991 : }
992 :
993 0 : void ChartExport::exportPlotArea( )
994 : {
995 0 : Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( mxNewDiagram, uno::UNO_QUERY );
996 0 : if( ! xBCooSysCnt.is())
997 : return;
998 :
999 : // plot-area element
1000 : // -----------------
1001 0 : FSHelperPtr pFS = GetFS();
1002 : pFS->startElement( FSNS( XML_c, XML_plotArea ),
1003 0 : FSEND );
1004 : // layout
1005 : pFS->singleElement( FSNS( XML_c, XML_layout ),
1006 0 : FSEND );
1007 :
1008 : // chart type
1009 : Sequence< Reference< chart2::XCoordinateSystem > >
1010 0 : aCooSysSeq( xBCooSysCnt->getCoordinateSystems());
1011 0 : for( sal_Int32 nCSIdx=0; nCSIdx<aCooSysSeq.getLength(); ++nCSIdx )
1012 : {
1013 0 : Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCSIdx], uno::UNO_QUERY );
1014 0 : if( ! xCTCnt.is())
1015 0 : continue;
1016 0 : Sequence< Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes());
1017 0 : for( sal_Int32 nCTIdx=0; nCTIdx<aCTSeq.getLength(); ++nCTIdx )
1018 : {
1019 0 : Reference< chart2::XDataSeriesContainer > xDSCnt( aCTSeq[nCTIdx], uno::UNO_QUERY );
1020 0 : if( ! xDSCnt.is())
1021 : return;
1022 0 : Reference< chart2::XChartType > xChartType( aCTSeq[nCTIdx], uno::UNO_QUERY );
1023 0 : if( ! xChartType.is())
1024 0 : continue;
1025 : // note: if xDSCnt.is() then also aCTSeq[nCTIdx]
1026 0 : OUString aChartType( xChartType->getChartType());
1027 0 : sal_Int32 eChartType = lcl_getChartType( aChartType );
1028 0 : switch( eChartType )
1029 : {
1030 : case chart::TYPEID_BAR:
1031 : {
1032 0 : exportBarChart( xChartType );
1033 0 : break;
1034 : }
1035 : case chart::TYPEID_AREA:
1036 : {
1037 0 : exportAreaChart( xChartType );
1038 0 : break;
1039 : }
1040 : case chart::TYPEID_LINE:
1041 : {
1042 0 : exportLineChart( xChartType );
1043 0 : break;
1044 : }
1045 : case chart::TYPEID_BUBBLE:
1046 : {
1047 0 : exportBubbleChart( xChartType );
1048 0 : break;
1049 : }
1050 : case chart::TYPEID_DOUGHNUT:
1051 : {
1052 0 : exportDoughnutChart( xChartType );
1053 0 : break;
1054 : }
1055 : case chart::TYPEID_OFPIE:
1056 : {
1057 0 : exportOfPieChart( xChartType );
1058 0 : break;
1059 : }
1060 : case chart::TYPEID_PIE:
1061 : {
1062 0 : exportPieChart( xChartType );
1063 0 : break;
1064 : }
1065 : case chart::TYPEID_RADARLINE:
1066 : case chart::TYPEID_RADARAREA:
1067 : {
1068 0 : exportRadarChart( xChartType );
1069 0 : break;
1070 : }
1071 : case chart::TYPEID_SCATTER:
1072 : {
1073 0 : exportScatterChart( xChartType );
1074 0 : break;
1075 : }
1076 : case chart::TYPEID_STOCK:
1077 : {
1078 0 : exportStockChart( xChartType );
1079 0 : break;
1080 : }
1081 : case chart::TYPEID_SURFACE:
1082 : {
1083 0 : exportSuffaceChart( xChartType );
1084 0 : break;
1085 : }
1086 : default:
1087 : {
1088 : OSL_TRACE("ChartExport::exportPlotArea -- not support chart type");
1089 0 : break;
1090 : }
1091 : }
1092 :
1093 0 : }
1094 0 : }
1095 : //Axis Data
1096 0 : exportAxes( );
1097 :
1098 : // shape properties
1099 0 : Reference< ::com::sun::star::chart::X3DDisplay > xWallFloorSupplier( mxDiagram, uno::UNO_QUERY );
1100 0 : if( xWallFloorSupplier.is() )
1101 : {
1102 0 : Reference< beans::XPropertySet > xWallPropSet( xWallFloorSupplier->getWall(), uno::UNO_QUERY );
1103 0 : if( xWallPropSet.is() )
1104 : {
1105 0 : exportShapeProps( xWallPropSet );
1106 0 : }
1107 : }
1108 :
1109 0 : pFS->endElement( FSNS( XML_c, XML_plotArea ) );
1110 :
1111 : }
1112 :
1113 0 : void ChartExport::exportAreaChart( Reference< chart2::XChartType > xChartType )
1114 : {
1115 0 : FSHelperPtr pFS = GetFS();
1116 0 : sal_Int32 nTypeId = XML_areaChart;
1117 0 : if( mbIs3DChart )
1118 0 : nTypeId = XML_area3DChart;
1119 : pFS->startElement( FSNS( XML_c, nTypeId ),
1120 0 : FSEND );
1121 :
1122 0 : exportGrouping( );
1123 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1124 0 : exportSeries( xChartType, nAttachedAxis );
1125 0 : exportAxesId( nAttachedAxis );
1126 :
1127 0 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1128 0 : }
1129 :
1130 0 : void ChartExport::exportBarChart( Reference< chart2::XChartType > xChartType )
1131 : {
1132 0 : sal_Int32 nTypeId = XML_barChart;
1133 0 : if( mbIs3DChart )
1134 0 : nTypeId = XML_bar3DChart;
1135 0 : FSHelperPtr pFS = GetFS();
1136 : pFS->startElement( FSNS( XML_c, nTypeId ),
1137 0 : FSEND );
1138 : // bar direction
1139 0 : sal_Bool bVertical = sal_False;
1140 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
1141 0 : if( GetProperty( xPropSet, S( "Vertical" ) ) )
1142 0 : mAny >>= bVertical;
1143 :
1144 0 : const char* bardir = bVertical? "bar":"col";
1145 : pFS->singleElement( FSNS( XML_c, XML_barDir ),
1146 : XML_val, bardir,
1147 0 : FSEND );
1148 :
1149 0 : exportGrouping( sal_True );
1150 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1151 0 : exportSeries( xChartType, nAttachedAxis );
1152 :
1153 0 : Reference< XPropertySet > xTypeProp( xChartType, uno::UNO_QUERY );
1154 0 : if( mbIs3DChart )
1155 : {
1156 : // Shape
1157 : namespace cssc = ::com::sun::star::chart;
1158 0 : sal_Int32 nGeom3d = cssc::ChartSolidType::RECTANGULAR_SOLID;
1159 0 : if( xPropSet.is() && GetProperty( xPropSet, S("SolidType") ) )
1160 0 : mAny >>= nGeom3d;
1161 0 : const char* sShapeType = NULL;
1162 0 : switch( nGeom3d )
1163 : {
1164 : case cssc::ChartSolidType::RECTANGULAR_SOLID:
1165 0 : sShapeType = "box";
1166 0 : break;
1167 : case cssc::ChartSolidType::CONE:
1168 0 : sShapeType = "cone";
1169 0 : break;
1170 : case cssc::ChartSolidType::CYLINDER:
1171 0 : sShapeType = "cylinder";
1172 0 : break;
1173 : case cssc::ChartSolidType::PYRAMID:
1174 0 : sShapeType = "pyramid";
1175 0 : break;
1176 : }
1177 : pFS->singleElement( FSNS( XML_c, XML_shape ),
1178 : XML_val, sShapeType,
1179 0 : FSEND );
1180 : }
1181 :
1182 : //overlap
1183 0 : if( xTypeProp.is() && GetProperty( xTypeProp, S("OverlapSequence") ) )
1184 : {
1185 0 : uno::Sequence< sal_Int32 > aBarPositionSequence;
1186 0 : mAny >>= aBarPositionSequence;
1187 0 : if( aBarPositionSequence.getLength() )
1188 : {
1189 0 : sal_Int32 nOverlap = aBarPositionSequence[0];
1190 0 : if( nOverlap > 0 )
1191 : pFS->singleElement( FSNS( XML_c, XML_overlap ),
1192 : XML_val, I32S( nOverlap ),
1193 0 : FSEND );
1194 0 : }
1195 : }
1196 0 : if( xTypeProp.is() && GetProperty( xTypeProp, S("GapwidthSequence") ) )
1197 : {
1198 0 : uno::Sequence< sal_Int32 > aBarPositionSequence;
1199 0 : mAny >>= aBarPositionSequence;
1200 0 : if( aBarPositionSequence.getLength() )
1201 : {
1202 0 : sal_Int32 nGapWidth = aBarPositionSequence[0];
1203 : pFS->singleElement( FSNS( XML_c, XML_gapWidth ),
1204 : XML_val, I32S( nGapWidth ),
1205 0 : FSEND );
1206 0 : }
1207 : }
1208 :
1209 0 : exportAxesId( nAttachedAxis );
1210 :
1211 0 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1212 0 : }
1213 :
1214 0 : void ChartExport::exportBubbleChart( Reference< chart2::XChartType > xChartType )
1215 : {
1216 0 : FSHelperPtr pFS = GetFS();
1217 : pFS->startElement( FSNS( XML_c, XML_bubbleChart ),
1218 0 : FSEND );
1219 :
1220 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1221 0 : exportSeries( xChartType, nAttachedAxis );
1222 0 : exportAxesId( nAttachedAxis );
1223 :
1224 0 : pFS->endElement( FSNS( XML_c, XML_bubbleChart ) );
1225 0 : }
1226 :
1227 0 : void ChartExport::exportDoughnutChart( Reference< chart2::XChartType > xChartType )
1228 : {
1229 0 : FSHelperPtr pFS = GetFS();
1230 : pFS->startElement( FSNS( XML_c, XML_doughnutChart ),
1231 0 : FSEND );
1232 :
1233 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1234 0 : exportSeries( xChartType, nAttachedAxis );
1235 : // firstSliceAng
1236 0 : exportFirstSliceAng( );
1237 : //FIXME: holeSize
1238 0 : sal_Int32 nHoleSize = 50;
1239 : pFS->singleElement( FSNS( XML_c, XML_holeSize ),
1240 : XML_val, I32S( nHoleSize ),
1241 0 : FSEND );
1242 :
1243 0 : exportAxesId( nAttachedAxis );
1244 :
1245 0 : pFS->endElement( FSNS( XML_c, XML_doughnutChart ) );
1246 0 : }
1247 :
1248 0 : void ChartExport::exportLineChart( Reference< chart2::XChartType > xChartType )
1249 : {
1250 0 : FSHelperPtr pFS = GetFS();
1251 0 : sal_Int32 nTypeId = XML_lineChart;
1252 0 : if( mbIs3DChart )
1253 0 : nTypeId = XML_line3DChart;
1254 : pFS->startElement( FSNS( XML_c, nTypeId ),
1255 0 : FSEND );
1256 :
1257 0 : exportGrouping( );
1258 : // TODO: show marker symbol in series?
1259 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1260 0 : exportSeries( xChartType, nAttachedAxis );
1261 :
1262 : // show marker?
1263 0 : sal_Int32 nSymbolType = ::com::sun::star::chart::ChartSymbolType::NONE;
1264 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
1265 0 : if( GetProperty( xPropSet, S( "SymbolType" ) ) )
1266 0 : mAny >>= nSymbolType;
1267 :
1268 0 : const char* marker = nSymbolType == ::com::sun::star::chart::ChartSymbolType::NONE? "0":"1";
1269 : pFS->singleElement( FSNS( XML_c, XML_marker ),
1270 : XML_val, marker,
1271 0 : FSEND );
1272 :
1273 0 : exportAxesId( nAttachedAxis );
1274 :
1275 0 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1276 0 : }
1277 :
1278 0 : void ChartExport::exportOfPieChart( Reference< chart2::XChartType > /*xChartType*/ )
1279 : {
1280 : // TODO:
1281 0 : }
1282 :
1283 0 : void ChartExport::exportPieChart( Reference< chart2::XChartType > xChartType )
1284 : {
1285 0 : FSHelperPtr pFS = GetFS();
1286 0 : sal_Int32 nTypeId = XML_pieChart;
1287 0 : if( mbIs3DChart )
1288 0 : nTypeId = XML_pie3DChart;
1289 : pFS->startElement( FSNS( XML_c, nTypeId ),
1290 0 : FSEND );
1291 : // TODO: varyColors
1292 0 : const char* varyColors = "1";
1293 : pFS->singleElement( FSNS( XML_c, XML_varyColors ),
1294 : XML_val, varyColors,
1295 0 : FSEND );
1296 :
1297 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1298 0 : exportSeries( xChartType, nAttachedAxis );
1299 :
1300 : // firstSliceAng
1301 0 : exportFirstSliceAng( );
1302 :
1303 0 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1304 0 : }
1305 :
1306 0 : void ChartExport::exportRadarChart( Reference< chart2::XChartType > xChartType)
1307 : {
1308 0 : FSHelperPtr pFS = GetFS();
1309 : pFS->startElement( FSNS( XML_c, XML_radarChart ),
1310 0 : FSEND );
1311 :
1312 : // radarStyle
1313 0 : sal_Int32 eChartType = getChartType( );
1314 0 : const char* radarStyle = NULL;
1315 0 : if( eChartType == chart::TYPEID_RADARAREA )
1316 0 : radarStyle = "filled";
1317 : else
1318 0 : radarStyle = "marker";
1319 : pFS->singleElement( FSNS( XML_c, XML_radarStyle ),
1320 : XML_val, radarStyle,
1321 0 : FSEND );
1322 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1323 0 : exportSeries( xChartType, nAttachedAxis );
1324 0 : exportAxesId( nAttachedAxis );
1325 :
1326 0 : pFS->endElement( FSNS( XML_c, XML_radarChart ) );
1327 0 : }
1328 :
1329 0 : void ChartExport::exportScatterChart( Reference< chart2::XChartType > xChartType )
1330 : {
1331 0 : FSHelperPtr pFS = GetFS();
1332 : pFS->startElement( FSNS( XML_c, XML_scatterChart ),
1333 0 : FSEND );
1334 : // TODO:scatterStyle
1335 0 : const char* scatterStyle = "lineMarker";
1336 : pFS->singleElement( FSNS( XML_c, XML_scatterStyle ),
1337 : XML_val, scatterStyle,
1338 0 : FSEND );
1339 :
1340 : // FIXME: should export xVal and yVal
1341 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1342 0 : exportSeries( xChartType, nAttachedAxis );
1343 0 : exportAxesId( nAttachedAxis );
1344 :
1345 0 : pFS->endElement( FSNS( XML_c, XML_scatterChart ) );
1346 0 : }
1347 :
1348 0 : void ChartExport::exportStockChart( Reference< chart2::XChartType > xChartType )
1349 : {
1350 0 : FSHelperPtr pFS = GetFS();
1351 : pFS->startElement( FSNS( XML_c, XML_stockChart ),
1352 0 : FSEND );
1353 :
1354 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1355 0 : exportSeries( xChartType, nAttachedAxis );
1356 : // export stock properties
1357 0 : Reference< ::com::sun::star::chart::XStatisticDisplay > xStockPropProvider( mxDiagram, uno::UNO_QUERY );
1358 0 : if( xStockPropProvider.is())
1359 : {
1360 : // stock-range-line
1361 0 : Reference< beans::XPropertySet > xStockPropSet = xStockPropProvider->getMinMaxLine();
1362 0 : if( xStockPropSet.is() )
1363 : {
1364 : pFS->startElement( FSNS( XML_c, XML_hiLowLines ),
1365 0 : FSEND );
1366 0 : exportShapeProps( xStockPropSet );
1367 0 : pFS->endElement( FSNS( XML_c, XML_hiLowLines ) );
1368 : }
1369 : // stock updownbar
1370 : pFS->startElement( FSNS( XML_c, XML_upDownBars ),
1371 0 : FSEND );
1372 : // TODO: gapWidth
1373 0 : sal_Int32 nGapWidth = 150;
1374 : pFS->singleElement( FSNS( XML_c, XML_gapWidth ),
1375 : XML_val, I32S( nGapWidth ),
1376 0 : FSEND );
1377 :
1378 0 : xStockPropSet = xStockPropProvider->getUpBar();
1379 0 : if( xStockPropSet.is() )
1380 : {
1381 : pFS->startElement( FSNS( XML_c, XML_upBars ),
1382 0 : FSEND );
1383 0 : exportShapeProps( xStockPropSet );
1384 0 : pFS->endElement( FSNS( XML_c, XML_upBars ) );
1385 : }
1386 :
1387 0 : xStockPropSet = xStockPropProvider->getDownBar();
1388 0 : if( xStockPropSet.is() )
1389 : {
1390 : pFS->startElement( FSNS( XML_c, XML_downBars ),
1391 0 : FSEND );
1392 0 : exportShapeProps( xStockPropSet );
1393 0 : pFS->endElement( FSNS( XML_c, XML_downBars ) );
1394 : }
1395 0 : pFS->endElement( FSNS( XML_c, XML_upDownBars ) );
1396 : }
1397 :
1398 0 : exportAxesId( nAttachedAxis );
1399 :
1400 0 : pFS->endElement( FSNS( XML_c, XML_stockChart ) );
1401 0 : }
1402 :
1403 0 : void ChartExport::exportSuffaceChart( Reference< chart2::XChartType > xChartType )
1404 : {
1405 0 : FSHelperPtr pFS = GetFS();
1406 0 : sal_Int32 nTypeId = XML_surfaceChart;
1407 0 : if( mbIs3DChart )
1408 0 : nTypeId = XML_surface3DChart;
1409 : pFS->startElement( FSNS( XML_c, nTypeId ),
1410 0 : FSEND );
1411 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1412 0 : exportSeries( xChartType, nAttachedAxis );
1413 0 : exportAxesId( nAttachedAxis );
1414 :
1415 0 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1416 0 : }
1417 :
1418 0 : void ChartExport::exportSeries( Reference< chart2::XChartType > xChartType, sal_Int32& nAttachedAxis )
1419 : {
1420 :
1421 0 : OUString aLabelRole = xChartType->getRoleOfSequenceForSeriesLabel();
1422 0 : Reference< chart2::XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY );
1423 0 : if( ! xDSCnt.is())
1424 : return;
1425 :
1426 0 : OUString aChartType( xChartType->getChartType());
1427 0 : sal_Int32 eChartType = lcl_getChartType( aChartType );
1428 :
1429 : // special export for stock charts
1430 0 : if( eChartType == chart::TYPEID_STOCK )
1431 : {
1432 0 : sal_Bool bJapaneseCandleSticks = sal_False;
1433 0 : Reference< beans::XPropertySet > xCTProp( xChartType, uno::UNO_QUERY );
1434 0 : if( xCTProp.is())
1435 0 : xCTProp->getPropertyValue( OUString("Japanese")) >>= bJapaneseCandleSticks;
1436 : exportCandleStickSeries(
1437 0 : xDSCnt->getDataSeries(), bJapaneseCandleSticks, nAttachedAxis );
1438 0 : return;
1439 : }
1440 :
1441 :
1442 : // export dataseries for current chart-type
1443 0 : Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries());
1444 0 : for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
1445 : {
1446 : // export series
1447 0 : Reference< chart2::data::XDataSource > xSource( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY );
1448 0 : if( xSource.is())
1449 : {
1450 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
1451 0 : xSource->getDataSequences());
1452 : // search for main sequence and create a series element
1453 : {
1454 0 : sal_Int32 nMainSequenceIndex = -1;
1455 0 : sal_Int32 nSeriesLength = 0;
1456 0 : Reference< chart2::data::XDataSequence > xValuesSeq;
1457 0 : Reference< chart2::data::XDataSequence > xLabelSeq;
1458 0 : sal_Int32 nSeqIdx=0;
1459 0 : for( ; nSeqIdx<aSeqCnt.getLength(); ++nSeqIdx )
1460 : {
1461 0 : OUString aRole;
1462 0 : Reference< chart2::data::XDataSequence > xTempValueSeq( aSeqCnt[nSeqIdx]->getValues() );
1463 0 : if( nMainSequenceIndex==-1 )
1464 : {
1465 0 : Reference< beans::XPropertySet > xSeqProp( xTempValueSeq, uno::UNO_QUERY );
1466 0 : if( xSeqProp.is())
1467 0 : xSeqProp->getPropertyValue(OUString("Role")) >>= aRole;
1468 : // "main" sequence
1469 0 : if( aRole.equals( aLabelRole ))
1470 : {
1471 0 : xValuesSeq.set( xTempValueSeq );
1472 0 : xLabelSeq.set( aSeqCnt[nSeqIdx]->getLabel());
1473 0 : nMainSequenceIndex = nSeqIdx;
1474 0 : }
1475 : }
1476 0 : sal_Int32 nSequenceLength = (xTempValueSeq.is()? xTempValueSeq->getData().getLength() : sal_Int32(0));
1477 0 : if( nSeriesLength < nSequenceLength )
1478 0 : nSeriesLength = nSequenceLength;
1479 0 : }
1480 :
1481 : // have found the main sequence, then xValuesSeq and
1482 : // xLabelSeq contain those. Otherwise both are empty
1483 : {
1484 0 : FSHelperPtr pFS = GetFS();
1485 : pFS->startElement( FSNS( XML_c, XML_ser ),
1486 0 : FSEND );
1487 :
1488 : // TODO: idx and order
1489 : pFS->singleElement( FSNS( XML_c, XML_idx ),
1490 : XML_val, I32S(nSeriesIdx),
1491 0 : FSEND );
1492 : pFS->singleElement( FSNS( XML_c, XML_order ),
1493 : XML_val, I32S(nSeriesIdx),
1494 0 : FSEND );
1495 :
1496 : // export label
1497 0 : if( xLabelSeq.is() )
1498 0 : exportSeriesText( xLabelSeq );
1499 :
1500 : // export shape properties
1501 : Reference< XPropertySet > xPropSet = SchXMLSeriesHelper::createOldAPISeriesPropertySet(
1502 0 : aSeriesSeq[nSeriesIdx], getModel() );
1503 0 : if( xPropSet.is() )
1504 : {
1505 0 : if( GetProperty( xPropSet, S("Axis") ) )
1506 : {
1507 0 : mAny >>= nAttachedAxis;
1508 0 : if( nAttachedAxis == ::com::sun::star::chart::ChartAxisAssign::SECONDARY_Y )
1509 0 : nAttachedAxis = AXIS_SECONDARY_Y;
1510 : else
1511 0 : nAttachedAxis = AXIS_PRIMARY_Y;
1512 : }
1513 0 : exportShapeProps( xPropSet );
1514 : }
1515 :
1516 0 : switch( eChartType )
1517 : {
1518 : case chart::TYPEID_LINE:
1519 : {
1520 0 : exportMarker( );
1521 0 : break;
1522 : }
1523 : case chart::TYPEID_PIE:
1524 : case chart::TYPEID_DOUGHNUT:
1525 : {
1526 0 : if( xPropSet.is() && GetProperty( xPropSet, S("SegmentOffset") ) )
1527 : {
1528 0 : sal_Int32 nOffset = 0;
1529 0 : mAny >>= nOffset;
1530 : pFS->singleElement( FSNS( XML_c, XML_explosion ),
1531 : XML_val, I32S( nOffset ),
1532 0 : FSEND );
1533 : }
1534 0 : break;
1535 : }
1536 : case chart::TYPEID_SCATTER:
1537 : {
1538 0 : exportMarker( );
1539 0 : exportSmooth( );
1540 0 : break;
1541 : }
1542 : case chart::TYPEID_RADARLINE:
1543 : {
1544 0 : exportMarker( );
1545 0 : break;
1546 : }
1547 : }
1548 :
1549 : // TODO: Data Labels: show data lables
1550 :
1551 : // export data points
1552 0 : exportDataPoints( uno::Reference< beans::XPropertySet >( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY ), nSeriesLength );
1553 :
1554 : // export categories
1555 0 : if( mxCategoriesValues.is() )
1556 0 : exportSeriesCategory( mxCategoriesValues );
1557 :
1558 0 : if( (eChartType == chart::TYPEID_SCATTER)
1559 : || (eChartType == chart::TYPEID_BUBBLE) )
1560 : {
1561 : // export xVal
1562 0 : Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString("values-x") ) );
1563 0 : if( xSequence.is() )
1564 : {
1565 0 : Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() );
1566 0 : if( xValues.is() )
1567 0 : exportSeriesValues( xValues, XML_xVal );
1568 0 : }
1569 : }
1570 :
1571 :
1572 0 : if( eChartType == chart::TYPEID_BUBBLE )
1573 : {
1574 : // export yVal
1575 0 : Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString("values-y") ) );
1576 0 : if( xSequence.is() )
1577 : {
1578 0 : Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() );
1579 0 : if( xValues.is() )
1580 0 : exportSeriesValues( xValues, XML_yVal );
1581 0 : }
1582 : }
1583 :
1584 : // export values
1585 0 : if( xValuesSeq.is() )
1586 : {
1587 0 : sal_Int32 nYValueType = XML_val;
1588 0 : if( eChartType == chart::TYPEID_SCATTER )
1589 0 : nYValueType = XML_yVal;
1590 0 : else if( eChartType == chart::TYPEID_BUBBLE )
1591 0 : nYValueType = XML_bubbleSize;
1592 0 : exportSeriesValues( xValuesSeq, nYValueType );
1593 : }
1594 :
1595 0 : pFS->endElement( FSNS( XML_c, XML_ser ) );
1596 0 : }
1597 0 : }
1598 : }
1599 0 : }
1600 : }
1601 :
1602 0 : void ChartExport::exportCandleStickSeries(
1603 : const Sequence< Reference< chart2::XDataSeries > > & aSeriesSeq,
1604 : sal_Bool /*bJapaneseCandleSticks*/,
1605 : sal_Int32& nAttachedAxis )
1606 : {
1607 0 : for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
1608 : {
1609 0 : Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nSeriesIdx] );
1610 0 : nAttachedAxis = lcl_isSeriesAttachedToFirstAxis( xSeries ) ? AXIS_PRIMARY_Y : AXIS_SECONDARY_Y;
1611 :
1612 0 : Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
1613 0 : if( xSource.is())
1614 : {
1615 : // export series in correct order (as we don't store roles)
1616 : // with japanese candlesticks: open, low, high, close
1617 : // otherwise: low, high, close
1618 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
1619 0 : xSource->getDataSequences());
1620 :
1621 0 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
1622 0 : const char* sSeries[] = {"values-first","values-max","values-min","values-last",0};
1623 0 : for( sal_Int32 idx = 0; sSeries[idx] != 0 ; idx++ )
1624 : {
1625 0 : Reference< chart2::data::XLabeledDataSequence > xLabeledSeq( lcl_getDataSequenceByRole( aSeqCnt, OUString::createFromAscii(sSeries[idx]) ) );
1626 0 : if( xLabeledSeq.is())
1627 : {
1628 0 : Reference< chart2::data::XDataSequence > xLabelSeq( xLabeledSeq->getLabel());
1629 0 : Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues());
1630 : {
1631 0 : FSHelperPtr pFS = GetFS();
1632 : pFS->startElement( FSNS( XML_c, XML_ser ),
1633 0 : FSEND );
1634 :
1635 : // TODO: idx and order
1636 : pFS->singleElement( FSNS( XML_c, XML_idx ),
1637 : XML_val, I32S(idx),
1638 0 : FSEND );
1639 : pFS->singleElement( FSNS( XML_c, XML_order ),
1640 : XML_val, I32S(idx),
1641 0 : FSEND );
1642 :
1643 : // export label
1644 0 : if( xLabelSeq.is() )
1645 0 : exportSeriesText( xLabelSeq );
1646 :
1647 : // TODO:export shape properties
1648 :
1649 : // export categories
1650 0 : if( mxCategoriesValues.is() )
1651 0 : exportSeriesCategory( mxCategoriesValues );
1652 :
1653 : // export values
1654 0 : if( xValueSeq.is() )
1655 0 : exportSeriesValues( xValueSeq );
1656 :
1657 0 : pFS->endElement( FSNS( XML_c, XML_ser ) );
1658 0 : }
1659 : }
1660 0 : }
1661 : }
1662 0 : }
1663 0 : }
1664 :
1665 :
1666 :
1667 0 : void ChartExport::exportSeriesText( const Reference< chart2::data::XDataSequence > & xValueSeq )
1668 : {
1669 0 : FSHelperPtr pFS = GetFS();
1670 0 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
1671 : pFS->startElement( FSNS( XML_c, XML_tx ),
1672 0 : FSEND );
1673 :
1674 0 : OUString aCellRange = xValueSeq->getSourceRangeRepresentation();
1675 0 : aCellRange = parseFormula( aCellRange );
1676 : pFS->startElement( FSNS( XML_c, XML_strRef ),
1677 0 : FSEND );
1678 :
1679 : pFS->startElement( FSNS( XML_c, XML_f ),
1680 0 : FSEND );
1681 0 : pFS->writeEscaped( aCellRange );
1682 0 : pFS->endElement( FSNS( XML_c, XML_f ) );
1683 :
1684 0 : OUString aLabelString = lcl_getLabelString( xValueSeq );
1685 : pFS->startElement( FSNS( XML_c, XML_strCache ),
1686 0 : FSEND );
1687 : pFS->singleElement( FSNS( XML_c, XML_ptCount ),
1688 : XML_val, "1",
1689 0 : FSEND );
1690 : pFS->startElement( FSNS( XML_c, XML_pt ),
1691 : XML_idx, "0",
1692 0 : FSEND );
1693 : pFS->startElement( FSNS( XML_c, XML_v ),
1694 0 : FSEND );
1695 0 : pFS->writeEscaped( aLabelString );
1696 0 : pFS->endElement( FSNS( XML_c, XML_v ) );
1697 0 : pFS->endElement( FSNS( XML_c, XML_pt ) );
1698 0 : pFS->endElement( FSNS( XML_c, XML_strCache ) );
1699 0 : pFS->endElement( FSNS( XML_c, XML_strRef ) );
1700 0 : pFS->endElement( FSNS( XML_c, XML_tx ) );
1701 0 : }
1702 :
1703 0 : void ChartExport::exportSeriesCategory( const Reference< chart2::data::XDataSequence > & xValueSeq )
1704 : {
1705 0 : FSHelperPtr pFS = GetFS();
1706 0 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
1707 : pFS->startElement( FSNS( XML_c, XML_cat ),
1708 0 : FSEND );
1709 :
1710 0 : OUString aCellRange = xValueSeq->getSourceRangeRepresentation();
1711 0 : aCellRange = parseFormula( aCellRange );
1712 : // TODO: need to handle XML_multiLvlStrRef according to aCellRange
1713 : pFS->startElement( FSNS( XML_c, XML_strRef ),
1714 0 : FSEND );
1715 :
1716 : pFS->startElement( FSNS( XML_c, XML_f ),
1717 0 : FSEND );
1718 0 : pFS->writeEscaped( aCellRange );
1719 0 : pFS->endElement( FSNS( XML_c, XML_f ) );
1720 :
1721 0 : ::std::vector< OUString > aCategories;
1722 0 : lcl_fillCategoriesIntoStringVector( xValueSeq, aCategories );
1723 0 : sal_Int32 ptCount = aCategories.size();
1724 : pFS->startElement( FSNS( XML_c, XML_strCache ),
1725 0 : FSEND );
1726 : pFS->singleElement( FSNS( XML_c, XML_ptCount ),
1727 : XML_val, I32S( ptCount ),
1728 0 : FSEND );
1729 0 : for( sal_Int32 i = 0; i < ptCount; i++ )
1730 : {
1731 : pFS->startElement( FSNS( XML_c, XML_pt ),
1732 : XML_idx, I32S( i ),
1733 0 : FSEND );
1734 : pFS->startElement( FSNS( XML_c, XML_v ),
1735 0 : FSEND );
1736 0 : pFS->writeEscaped( aCategories[i] );
1737 0 : pFS->endElement( FSNS( XML_c, XML_v ) );
1738 0 : pFS->endElement( FSNS( XML_c, XML_pt ) );
1739 : }
1740 :
1741 0 : pFS->endElement( FSNS( XML_c, XML_strCache ) );
1742 0 : pFS->endElement( FSNS( XML_c, XML_strRef ) );
1743 0 : pFS->endElement( FSNS( XML_c, XML_cat ) );
1744 0 : }
1745 :
1746 0 : void ChartExport::exportSeriesValues( const Reference< chart2::data::XDataSequence > & xValueSeq, sal_Int32 nValueType )
1747 : {
1748 0 : FSHelperPtr pFS = GetFS();
1749 0 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
1750 : pFS->startElement( FSNS( XML_c, nValueType ),
1751 0 : FSEND );
1752 :
1753 0 : OUString aCellRange = xValueSeq->getSourceRangeRepresentation();
1754 0 : aCellRange = parseFormula( aCellRange );
1755 : // TODO: need to handle XML_multiLvlStrRef according to aCellRange
1756 : pFS->startElement( FSNS( XML_c, XML_numRef ),
1757 0 : FSEND );
1758 :
1759 : pFS->startElement( FSNS( XML_c, XML_f ),
1760 0 : FSEND );
1761 0 : pFS->writeEscaped( aCellRange );
1762 0 : pFS->endElement( FSNS( XML_c, XML_f ) );
1763 :
1764 0 : ::std::vector< double > aValues;
1765 0 : aValues = lcl_getAllValuesFromSequence( xValueSeq );
1766 0 : sal_Int32 ptCount = aValues.size();
1767 : pFS->startElement( FSNS( XML_c, XML_numCache ),
1768 0 : FSEND );
1769 : pFS->startElement( FSNS( XML_c, XML_formatCode ),
1770 0 : FSEND );
1771 : // TODO: what format code?
1772 0 : pFS->writeEscaped( "General" );
1773 0 : pFS->endElement( FSNS( XML_c, XML_formatCode ) );
1774 : pFS->singleElement( FSNS( XML_c, XML_ptCount ),
1775 : XML_val, I32S( ptCount ),
1776 0 : FSEND );
1777 0 : for( sal_Int32 i = 0; i < ptCount; i++ )
1778 : {
1779 : pFS->startElement( FSNS( XML_c, XML_pt ),
1780 : XML_idx, I32S( i ),
1781 0 : FSEND );
1782 : pFS->startElement( FSNS( XML_c, XML_v ),
1783 0 : FSEND );
1784 0 : if (aValues[i] == aValues[i])
1785 0 : pFS->write( aValues[i] );
1786 0 : pFS->endElement( FSNS( XML_c, XML_v ) );
1787 0 : pFS->endElement( FSNS( XML_c, XML_pt ) );
1788 : }
1789 :
1790 0 : pFS->endElement( FSNS( XML_c, XML_numCache ) );
1791 0 : pFS->endElement( FSNS( XML_c, XML_numRef ) );
1792 0 : pFS->endElement( FSNS( XML_c, nValueType ) );
1793 0 : }
1794 :
1795 0 : void ChartExport::exportShapeProps( Reference< XPropertySet > xPropSet )
1796 : {
1797 0 : FSHelperPtr pFS = GetFS();
1798 : pFS->startElement( FSNS( XML_c, XML_spPr ),
1799 0 : FSEND );
1800 :
1801 0 : WriteFill( xPropSet );
1802 0 : WriteOutline( xPropSet );
1803 0 : pFS->endElement( FSNS( XML_c, XML_spPr ) );
1804 0 : }
1805 :
1806 0 : void ChartExport::InitPlotArea( )
1807 : {
1808 0 : Reference< XPropertySet > xDiagramProperties (mxDiagram, uno::UNO_QUERY);
1809 :
1810 : // Check for supported services and then the properties provided by this service.
1811 0 : Reference<lang::XServiceInfo> xServiceInfo (mxDiagram, uno::UNO_QUERY);
1812 0 : if (xServiceInfo.is())
1813 : {
1814 0 : if (xServiceInfo->supportsService(
1815 0 : OUString("com.sun.star.chart.ChartAxisXSupplier")))
1816 : {
1817 0 : xDiagramProperties->getPropertyValue(
1818 0 : OUString("HasXAxis")) >>= mbHasXAxis;
1819 : }
1820 0 : if (xServiceInfo->supportsService(
1821 0 : OUString("com.sun.star.chart.ChartAxisYSupplier")))
1822 : {
1823 0 : xDiagramProperties->getPropertyValue(
1824 0 : OUString("HasYAxis")) >>= mbHasYAxis;
1825 : }
1826 0 : if (xServiceInfo->supportsService(
1827 0 : OUString("com.sun.star.chart.ChartAxisZSupplier")))
1828 : {
1829 0 : xDiagramProperties->getPropertyValue(
1830 0 : OUString("HasZAxis")) >>= mbHasZAxis;
1831 : }
1832 0 : if (xServiceInfo->supportsService(
1833 0 : OUString("com.sun.star.chart.ChartTwoAxisXSupplier")))
1834 : {
1835 0 : xDiagramProperties->getPropertyValue(
1836 0 : OUString("HasSecondaryXAxis")) >>= mbHasSecondaryXAxis;
1837 : }
1838 0 : if (xServiceInfo->supportsService(
1839 0 : OUString("com.sun.star.chart.ChartTwoAxisYSupplier")))
1840 : {
1841 0 : xDiagramProperties->getPropertyValue(
1842 0 : OUString("HasSecondaryYAxis")) >>= mbHasSecondaryYAxis;
1843 : }
1844 : }
1845 :
1846 0 : xDiagramProperties->getPropertyValue(
1847 0 : OUString ("Dim3D")) >>= mbIs3DChart;
1848 :
1849 0 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
1850 0 : if( mbHasCategoryLabels && mxNewDiagram.is())
1851 : {
1852 0 : Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( mxNewDiagram ) );
1853 0 : if( xCategories.is() )
1854 : {
1855 0 : mxCategoriesValues.set( xCategories->getValues() );
1856 0 : }
1857 0 : }
1858 0 : }
1859 :
1860 0 : void ChartExport::exportAxes( )
1861 : {
1862 0 : sal_Int32 nSize = maAxes.size();
1863 0 : for( sal_Int32 nIdx = 0; nIdx < nSize; nIdx++ )
1864 : {
1865 0 : exportAxis( maAxes[nIdx] );
1866 : }
1867 0 : }
1868 :
1869 0 : void ChartExport::exportAxis( AxisIdPair aAxisIdPair )
1870 : {
1871 : // get some properties from document first
1872 0 : sal_Bool bHasXAxisTitle = sal_False,
1873 0 : bHasYAxisTitle = sal_False,
1874 0 : bHasZAxisTitle = sal_False,
1875 0 : bHasSecondaryXAxisTitle = sal_False,
1876 0 : bHasSecondaryYAxisTitle = sal_False;
1877 0 : sal_Bool bHasXAxisMajorGrid = sal_False,
1878 0 : bHasXAxisMinorGrid = sal_False,
1879 0 : bHasYAxisMajorGrid = sal_False,
1880 0 : bHasYAxisMinorGrid = sal_False,
1881 0 : bHasZAxisMajorGrid = sal_False,
1882 0 : bHasZAxisMinorGrid = sal_False;
1883 :
1884 0 : Reference< XPropertySet > xDiagramProperties (mxDiagram, uno::UNO_QUERY);
1885 :
1886 0 : xDiagramProperties->getPropertyValue(
1887 0 : OUString ("HasXAxisTitle")) >>= bHasXAxisTitle;
1888 0 : xDiagramProperties->getPropertyValue(
1889 0 : OUString ("HasYAxisTitle")) >>= bHasYAxisTitle;
1890 0 : xDiagramProperties->getPropertyValue(
1891 0 : OUString ("HasZAxisTitle")) >>= bHasZAxisTitle;
1892 0 : xDiagramProperties->getPropertyValue(
1893 0 : OUString ("HasSecondaryXAxisTitle")) >>= bHasSecondaryXAxisTitle;
1894 0 : xDiagramProperties->getPropertyValue(
1895 0 : OUString ("HasSecondaryYAxisTitle")) >>= bHasSecondaryYAxisTitle;
1896 :
1897 0 : xDiagramProperties->getPropertyValue(
1898 0 : OUString ("HasXAxisGrid")) >>= bHasXAxisMajorGrid;
1899 0 : xDiagramProperties->getPropertyValue(
1900 0 : OUString ("HasYAxisGrid")) >>= bHasYAxisMajorGrid;
1901 0 : xDiagramProperties->getPropertyValue(
1902 0 : OUString ("HasZAxisGrid")) >>= bHasZAxisMajorGrid;
1903 :
1904 0 : xDiagramProperties->getPropertyValue(
1905 0 : OUString ("HasXAxisHelpGrid")) >>= bHasXAxisMinorGrid;
1906 0 : xDiagramProperties->getPropertyValue(
1907 0 : OUString ("HasYAxisHelpGrid")) >>= bHasYAxisMinorGrid;
1908 0 : xDiagramProperties->getPropertyValue(
1909 0 : OUString ("HasZAxisHelpGrid")) >>= bHasZAxisMinorGrid;
1910 :
1911 0 : Reference< XPropertySet > xAxisProp;
1912 0 : Reference< drawing::XShape > xAxisTitle;
1913 0 : Reference< beans::XPropertySet > xMajorGrid;
1914 0 : Reference< beans::XPropertySet > xMinorGrid;
1915 0 : sal_Int32 nAxisType = XML_catAx;
1916 0 : const char* sAxPos = NULL;
1917 :
1918 0 : switch( aAxisIdPair.nAxisType )
1919 : {
1920 : case AXIS_PRIMARY_X:
1921 : {
1922 0 : Reference< ::com::sun::star::chart::XAxisXSupplier > xAxisXSupp( mxDiagram, uno::UNO_QUERY );
1923 0 : if( xAxisXSupp.is())
1924 0 : xAxisProp = xAxisXSupp->getXAxis();
1925 0 : if( bHasXAxisTitle )
1926 0 : xAxisTitle.set( xAxisXSupp->getXAxisTitle(), uno::UNO_QUERY );
1927 0 : if( bHasXAxisMajorGrid )
1928 0 : xMajorGrid.set( xAxisXSupp->getXMainGrid(), uno::UNO_QUERY );
1929 0 : if( bHasXAxisMinorGrid )
1930 0 : xMinorGrid.set( xAxisXSupp->getXHelpGrid(), uno::UNO_QUERY );
1931 :
1932 0 : sal_Int32 eChartType = getChartType( );
1933 0 : if( (eChartType == chart::TYPEID_SCATTER)
1934 : || (eChartType == chart::TYPEID_BUBBLE) )
1935 0 : nAxisType = XML_valAx;
1936 0 : else if( eChartType == chart::TYPEID_STOCK )
1937 0 : nAxisType = XML_dateAx;
1938 : // FIXME: axPos, need to check axis direction
1939 0 : sAxPos = "b";
1940 0 : break;
1941 : }
1942 : case AXIS_PRIMARY_Y:
1943 : {
1944 0 : Reference< ::com::sun::star::chart::XAxisYSupplier > xAxisYSupp( mxDiagram, uno::UNO_QUERY );
1945 0 : if( xAxisYSupp.is())
1946 0 : xAxisProp = xAxisYSupp->getYAxis();
1947 0 : if( bHasYAxisTitle )
1948 0 : xAxisTitle.set( xAxisYSupp->getYAxisTitle(), uno::UNO_QUERY );
1949 0 : if( bHasYAxisMajorGrid )
1950 0 : xMajorGrid.set( xAxisYSupp->getYMainGrid(), uno::UNO_QUERY );
1951 0 : if( bHasYAxisMinorGrid )
1952 0 : xMinorGrid.set( xAxisYSupp->getYHelpGrid(), uno::UNO_QUERY );
1953 :
1954 0 : nAxisType = XML_valAx;
1955 : // FIXME: axPos, need to check axis direction
1956 0 : sAxPos = "l";
1957 0 : break;
1958 : }
1959 : case AXIS_PRIMARY_Z:
1960 : {
1961 0 : Reference< ::com::sun::star::chart::XAxisZSupplier > xAxisZSupp( mxDiagram, uno::UNO_QUERY );
1962 0 : if( xAxisZSupp.is())
1963 0 : xAxisProp = xAxisZSupp->getZAxis();
1964 0 : if( bHasZAxisTitle )
1965 0 : xAxisTitle.set( xAxisZSupp->getZAxisTitle(), uno::UNO_QUERY );
1966 0 : if( bHasZAxisMajorGrid )
1967 0 : xMajorGrid.set( xAxisZSupp->getZMainGrid(), uno::UNO_QUERY );
1968 0 : if( bHasZAxisMinorGrid )
1969 0 : xMinorGrid.set( xAxisZSupp->getZHelpGrid(), uno::UNO_QUERY );
1970 :
1971 0 : sal_Int32 eChartType = getChartType( );
1972 0 : if( (eChartType == chart::TYPEID_SCATTER)
1973 : || (eChartType == chart::TYPEID_BUBBLE) )
1974 0 : nAxisType = XML_valAx;
1975 0 : else if( eChartType == chart::TYPEID_STOCK )
1976 0 : nAxisType = XML_dateAx;
1977 : // FIXME: axPos, need to check axis direction
1978 0 : sAxPos = "b";
1979 0 : break;
1980 : }
1981 : case AXIS_SECONDARY_Y:
1982 : {
1983 0 : Reference< ::com::sun::star::chart::XTwoAxisYSupplier > xAxisTwoYSupp( mxDiagram, uno::UNO_QUERY );
1984 0 : if( xAxisTwoYSupp.is())
1985 0 : xAxisProp = xAxisTwoYSupp->getSecondaryYAxis();
1986 0 : if( bHasSecondaryYAxisTitle )
1987 : {
1988 0 : Reference< ::com::sun::star::chart::XSecondAxisTitleSupplier > xAxisSupp( mxDiagram, uno::UNO_QUERY );
1989 0 : xAxisTitle.set( xAxisSupp->getSecondYAxisTitle(), uno::UNO_QUERY );
1990 : }
1991 :
1992 0 : nAxisType = XML_valAx;
1993 : // FIXME: axPos, need to check axis direction
1994 0 : sAxPos = "l";
1995 0 : break;
1996 : }
1997 : }
1998 :
1999 :
2000 0 : _exportAxis( xAxisProp, xAxisTitle, xMajorGrid, xMinorGrid, nAxisType, sAxPos, aAxisIdPair );
2001 0 : }
2002 :
2003 0 : void ChartExport::_exportAxis(
2004 : const Reference< XPropertySet >& xAxisProp,
2005 : const Reference< drawing::XShape >& xAxisTitle,
2006 : const Reference< XPropertySet >& xMajorGrid,
2007 : const Reference< XPropertySet >& xMinorGrid,
2008 : sal_Int32 nAxisType,
2009 : const char* sAxisPos,
2010 : AxisIdPair aAxisIdPair )
2011 : {
2012 0 : FSHelperPtr pFS = GetFS();
2013 : pFS->startElement( FSNS( XML_c, nAxisType ),
2014 0 : FSEND );
2015 : pFS->singleElement( FSNS( XML_c, XML_axId ),
2016 : XML_val, I32S( aAxisIdPair.nAxisId ),
2017 0 : FSEND );
2018 :
2019 : pFS->startElement( FSNS( XML_c, XML_scaling ),
2020 0 : FSEND );
2021 : // orientation: minMax, maxMin
2022 0 : sal_Bool bReverseDirection = sal_False;
2023 0 : if(GetProperty( xAxisProp, S( "ReverseDirection" ) ) )
2024 0 : mAny >>= bReverseDirection;
2025 :
2026 0 : const char* orientation = bReverseDirection ? "maxMin":"minMax";
2027 : pFS->singleElement( FSNS( XML_c, XML_orientation ),
2028 : XML_val, orientation,
2029 0 : FSEND );
2030 : // logBase, min, max
2031 0 : if(GetProperty( xAxisProp, S( "Logarithmic" ) ) )
2032 : {
2033 0 : sal_Bool bLogarithmic = sal_False;
2034 0 : mAny >>= bLogarithmic;
2035 0 : if( bLogarithmic )
2036 : {
2037 : // default value is 10?
2038 0 : sal_Int32 nLogBase = 10;
2039 : pFS->singleElement( FSNS( XML_c, XML_logBase ),
2040 : XML_val, I32S( nLogBase ),
2041 0 : FSEND );
2042 : }
2043 : }
2044 0 : sal_Bool bAutoMax = sal_False;
2045 0 : if(GetProperty( xAxisProp, S( "AutoMax" ) ) )
2046 0 : mAny >>= bAutoMax;
2047 :
2048 0 : if( !bAutoMax && (GetProperty( xAxisProp, S( "Max" ) ) ))
2049 : {
2050 0 : double dMax = 0;
2051 0 : mAny >>= dMax;
2052 : pFS->singleElement( FSNS( XML_c, XML_max ),
2053 : XML_val, IS( dMax ),
2054 0 : FSEND );
2055 : }
2056 :
2057 0 : sal_Bool bAutoMin = sal_False;
2058 0 : if(GetProperty( xAxisProp, S( "AutoMin" ) ) )
2059 0 : mAny >>= bAutoMin;
2060 :
2061 0 : if( !bAutoMin && (GetProperty( xAxisProp, S( "Min" ) ) ))
2062 : {
2063 0 : double dMin = 0;
2064 0 : mAny >>= dMin;
2065 : pFS->singleElement( FSNS( XML_c, XML_min ),
2066 : XML_val, IS( dMin ),
2067 0 : FSEND );
2068 : }
2069 :
2070 0 : pFS->endElement( FSNS( XML_c, XML_scaling ) );
2071 :
2072 : // title
2073 0 : if( xAxisTitle.is() )
2074 0 : exportTitle( xAxisTitle );
2075 :
2076 0 : sal_Bool bVisible = sal_True;
2077 0 : if( xAxisProp.is() )
2078 : {
2079 0 : xAxisProp->getPropertyValue(
2080 0 : OUString ("Visible")) >>= bVisible;
2081 : }
2082 :
2083 0 : if( !bVisible )
2084 : {
2085 : // other value?
2086 : pFS->singleElement( FSNS( XML_c, XML_delete ),
2087 : XML_val, "1",
2088 0 : FSEND );
2089 : }
2090 :
2091 : // FIXME: axPos, need to check the property "ReverseDirection"
2092 : pFS->singleElement( FSNS( XML_c, XML_axPos ),
2093 : XML_val, sAxisPos,
2094 0 : FSEND );
2095 : // major grid line
2096 0 : if( xMajorGrid.is())
2097 : {
2098 : pFS->startElement( FSNS( XML_c, XML_majorGridlines ),
2099 0 : FSEND );
2100 0 : exportShapeProps( xMajorGrid );
2101 0 : pFS->endElement( FSNS( XML_c, XML_majorGridlines ) );
2102 : }
2103 :
2104 : // minor grid line
2105 0 : if( xMinorGrid.is())
2106 : {
2107 : pFS->startElement( FSNS( XML_c, XML_minorGridlines ),
2108 0 : FSEND );
2109 0 : exportShapeProps( xMajorGrid );
2110 0 : pFS->endElement( FSNS( XML_c, XML_minorGridlines ) );
2111 : }
2112 :
2113 : // majorTickMark
2114 0 : sal_Int32 nValue = 0;
2115 0 : if(GetProperty( xAxisProp, S( "Marks" ) ) )
2116 : {
2117 0 : mAny >>= nValue;
2118 0 : sal_Bool bInner = nValue & ::com::sun::star::chart::ChartAxisMarks::INNER;
2119 0 : sal_Bool bOuter = nValue & ::com::sun::star::chart::ChartAxisMarks::OUTER;
2120 0 : const char* majorTickMark = NULL;
2121 0 : if( bInner && bOuter )
2122 0 : majorTickMark = "cross";
2123 0 : else if( bInner )
2124 0 : majorTickMark = "in";
2125 0 : else if( bOuter )
2126 0 : majorTickMark = "out";
2127 : else
2128 0 : majorTickMark = "none";
2129 : pFS->singleElement( FSNS( XML_c, XML_majorTickMark ),
2130 : XML_val, majorTickMark,
2131 0 : FSEND );
2132 : }
2133 : // minorTickMark
2134 0 : if(GetProperty( xAxisProp, S( "HelpMarks" ) ) )
2135 : {
2136 0 : mAny >>= nValue;
2137 0 : sal_Bool bInner = nValue & ::com::sun::star::chart::ChartAxisMarks::INNER;
2138 0 : sal_Bool bOuter = nValue & ::com::sun::star::chart::ChartAxisMarks::OUTER;
2139 0 : const char* minorTickMark = NULL;
2140 0 : if( bInner && bOuter )
2141 0 : minorTickMark = "cross";
2142 0 : else if( bInner )
2143 0 : minorTickMark = "in";
2144 0 : else if( bOuter )
2145 0 : minorTickMark = "out";
2146 : else
2147 0 : minorTickMark = "none";
2148 : pFS->singleElement( FSNS( XML_c, XML_minorTickMark ),
2149 : XML_val, minorTickMark,
2150 0 : FSEND );
2151 : }
2152 : // tickLblPos
2153 0 : const char* sTickLblPos = NULL;
2154 0 : sal_Bool bDisplayLabel = sal_True;
2155 0 : if(GetProperty( xAxisProp, S( "DisplayLabels" ) ) )
2156 0 : mAny >>= bDisplayLabel;
2157 0 : if( bDisplayLabel && (GetProperty( xAxisProp, S( "LabelPosition" ) ) ))
2158 : {
2159 0 : ::com::sun::star::chart::ChartAxisLabelPosition eLabelPosition = ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS;
2160 0 : mAny >>= eLabelPosition;
2161 0 : switch( eLabelPosition )
2162 : {
2163 : case ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS:
2164 : case ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS_OTHER_SIDE:
2165 0 : sTickLblPos = "nextTo";
2166 0 : break;
2167 : case ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START:
2168 0 : sTickLblPos = "low";
2169 0 : break;
2170 : case ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END:
2171 0 : sTickLblPos = "high";
2172 0 : break;
2173 : default:
2174 0 : sTickLblPos = "nextTo";
2175 0 : break;
2176 : }
2177 : }
2178 : else
2179 : {
2180 0 : sTickLblPos = "none";
2181 : }
2182 : pFS->singleElement( FSNS( XML_c, XML_tickLblPos ),
2183 : XML_val, sTickLblPos,
2184 0 : FSEND );
2185 :
2186 : pFS->singleElement( FSNS( XML_c, XML_crossAx ),
2187 : XML_val, I32S( aAxisIdPair.nCrossAx ),
2188 0 : FSEND );
2189 :
2190 : // crosses & crossesAt
2191 0 : sal_Bool bCrossesValue = sal_False;
2192 0 : const char* sCrosses = NULL;
2193 0 : if(GetProperty( xAxisProp, S( "CrossoverPosition" ) ) )
2194 : {
2195 0 : ::com::sun::star::chart::ChartAxisPosition ePosition( ::com::sun::star::chart::ChartAxisPosition_ZERO );
2196 0 : mAny >>= ePosition;
2197 0 : switch( ePosition )
2198 : {
2199 : case ::com::sun::star::chart::ChartAxisPosition_START:
2200 0 : sCrosses = "min";
2201 0 : break;
2202 : case ::com::sun::star::chart::ChartAxisPosition_END:
2203 0 : sCrosses = "max";
2204 0 : break;
2205 : case ::com::sun::star::chart::ChartAxisPosition_ZERO:
2206 0 : sCrosses = "autoZero";
2207 0 : break;
2208 : default:
2209 0 : bCrossesValue = sal_True;
2210 0 : break;
2211 : }
2212 : }
2213 :
2214 0 : if( bCrossesValue && GetProperty( xAxisProp, S("CrossoverValue" ) ) )
2215 : {
2216 0 : double dValue = 0;
2217 0 : mAny >>= dValue;
2218 : pFS->singleElement( FSNS( XML_c, XML_crossesAt ),
2219 : XML_val, IS( dValue ),
2220 0 : FSEND );
2221 : }
2222 : else
2223 : {
2224 : pFS->singleElement( FSNS( XML_c, XML_crosses ),
2225 : XML_val, sCrosses,
2226 0 : FSEND );
2227 : }
2228 :
2229 0 : if( nAxisType == XML_catAx )
2230 : {
2231 : // FIXME: seems not support? lblAlgn
2232 0 : const char* sLblAlgn = "ctr";
2233 : pFS->singleElement( FSNS( XML_c, XML_lblAlgn ),
2234 : XML_val, sLblAlgn,
2235 0 : FSEND );
2236 : }
2237 0 : if( ( nAxisType == XML_catAx )
2238 : || ( nAxisType == XML_dateAx ) )
2239 : {
2240 : // FIXME: seems not support? use default value,
2241 0 : const char* isAuto = "1";
2242 : pFS->singleElement( FSNS( XML_c, XML_auto ),
2243 : XML_val, isAuto,
2244 0 : FSEND );
2245 :
2246 : // FIXME: seems not support? lblOffset
2247 0 : sal_Int32 nLblOffset = 100;
2248 : pFS->singleElement( FSNS( XML_c, XML_lblOffset ),
2249 : XML_val, I32S( nLblOffset ),
2250 0 : FSEND );
2251 : }
2252 :
2253 : // majorUnit
2254 0 : sal_Bool bAutoStepMain = sal_False;
2255 0 : if(GetProperty( xAxisProp, S( "AutoStepMain" ) ) )
2256 0 : mAny >>= bAutoStepMain;
2257 :
2258 0 : if( !bAutoStepMain && (GetProperty( xAxisProp, S( "StepMain" ) ) ))
2259 : {
2260 0 : double dMajorUnit = 0;
2261 0 : mAny >>= dMajorUnit;
2262 : pFS->singleElement( FSNS( XML_c, XML_majorUnit ),
2263 : XML_val, IS( dMajorUnit ),
2264 0 : FSEND );
2265 : }
2266 : // minorUnit
2267 0 : sal_Bool bAutoStepHelp = sal_False;
2268 0 : if(GetProperty( xAxisProp, S( "AutoStepHelp" ) ) )
2269 0 : mAny >>= bAutoStepHelp;
2270 :
2271 0 : if( !bAutoStepHelp && (GetProperty( xAxisProp, S( "StepHelp" ) ) ))
2272 : {
2273 0 : double dMinorUnit = 0;
2274 0 : mAny >>= dMinorUnit;
2275 : pFS->singleElement( FSNS( XML_c, XML_minorUnit ),
2276 : XML_val, IS( dMinorUnit ),
2277 0 : FSEND );
2278 : }
2279 :
2280 : // shape properties
2281 0 : exportShapeProps( xAxisProp );
2282 : // TODO: text properties
2283 :
2284 0 : pFS->endElement( FSNS( XML_c, nAxisType ) );
2285 0 : }
2286 :
2287 0 : void ChartExport::exportDataPoints(
2288 : const uno::Reference< beans::XPropertySet > & xSeriesProperties,
2289 : sal_Int32 nSeriesLength )
2290 : {
2291 0 : uno::Reference< chart2::XDataSeries > xSeries( xSeriesProperties, uno::UNO_QUERY );
2292 0 : bool bVaryColorsByPoint = false;
2293 0 : Sequence< sal_Int32 > aDataPointSeq;
2294 0 : if( xSeriesProperties.is())
2295 : {
2296 0 : Any aAny = xSeriesProperties->getPropertyValue(
2297 0 : OUString( "AttributedDataPoints" ));
2298 0 : aAny >>= aDataPointSeq;
2299 0 : xSeriesProperties->getPropertyValue(
2300 0 : OUString( "VaryColorsByPoint" )) >>= bVaryColorsByPoint;
2301 : }
2302 :
2303 0 : const sal_Int32 * pPoints = aDataPointSeq.getConstArray();
2304 : sal_Int32 nElement;
2305 0 : Reference< chart2::XColorScheme > xColorScheme;
2306 0 : if( mxNewDiagram.is())
2307 0 : xColorScheme.set( mxNewDiagram->getDefaultColorScheme());
2308 :
2309 0 : if( bVaryColorsByPoint && xColorScheme.is() )
2310 : {
2311 0 : ::std::set< sal_Int32 > aAttrPointSet;
2312 0 : ::std::copy( pPoints, pPoints + aDataPointSeq.getLength(),
2313 0 : ::std::inserter( aAttrPointSet, aAttrPointSet.begin()));
2314 0 : const ::std::set< sal_Int32 >::const_iterator aEndIt( aAttrPointSet.end());
2315 0 : for( nElement = 0; nElement < nSeriesLength; ++nElement )
2316 : {
2317 0 : uno::Reference< beans::XPropertySet > xPropSet;
2318 0 : if( aAttrPointSet.find( nElement ) != aEndIt )
2319 : {
2320 : try
2321 : {
2322 : xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
2323 0 : xSeries, nElement, getModel() );
2324 : }
2325 0 : catch( const uno::Exception & rEx )
2326 : {
2327 : (void)rEx; // avoid warning for pro build
2328 : OSL_TRACE( "Exception caught during Export of data point: %s",
2329 : OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
2330 : }
2331 : }
2332 : else
2333 : {
2334 : // property set only containing the color
2335 0 : xPropSet.set( new ColorPropertySet( xColorScheme->getColorByIndex( nElement )));
2336 : }
2337 :
2338 0 : if( xPropSet.is() )
2339 : {
2340 : OSL_TRACE("ChartExport::exportDataPoints -- writer data points ");
2341 0 : FSHelperPtr pFS = GetFS();
2342 : pFS->startElement( FSNS( XML_c, XML_dPt ),
2343 0 : FSEND );
2344 : pFS->singleElement( FSNS( XML_c, XML_idx ),
2345 : XML_val, I32S(nElement),
2346 0 : FSEND );
2347 0 : exportShapeProps( xPropSet );
2348 :
2349 0 : pFS->endElement( FSNS( XML_c, XML_dPt ) );
2350 : }
2351 0 : }
2352 0 : }
2353 0 : }
2354 :
2355 0 : void ChartExport::exportAxesId( sal_Int32 nAttachedAxis )
2356 : {
2357 0 : sal_Int32 nAxisIdx = lcl_generateRandomValue();
2358 0 : sal_Int32 nAxisIdy = lcl_generateRandomValue();
2359 0 : maAxes.push_back( AxisIdPair( AXIS_PRIMARY_X, nAxisIdx, nAxisIdy ) );
2360 0 : maAxes.push_back( AxisIdPair( nAttachedAxis, nAxisIdy, nAxisIdx ) );
2361 0 : FSHelperPtr pFS = GetFS();
2362 : pFS->singleElement( FSNS( XML_c, XML_axId ),
2363 : XML_val, I32S( nAxisIdx ),
2364 0 : FSEND );
2365 : pFS->singleElement( FSNS( XML_c, XML_axId ),
2366 : XML_val, I32S( nAxisIdy ),
2367 0 : FSEND );
2368 0 : if( mbHasZAxis )
2369 : {
2370 0 : sal_Int32 nAxisIdz = 0;
2371 0 : if( isDeep3dChart() )
2372 : {
2373 0 : nAxisIdz = lcl_generateRandomValue();
2374 0 : maAxes.push_back( AxisIdPair( AXIS_PRIMARY_Z, nAxisIdz, nAxisIdy ) );
2375 : }
2376 : pFS->singleElement( FSNS( XML_c, XML_axId ),
2377 : XML_val, I32S( nAxisIdz ),
2378 0 : FSEND );
2379 0 : }
2380 0 : }
2381 :
2382 0 : void ChartExport::exportGrouping( sal_Bool isBar )
2383 : {
2384 0 : FSHelperPtr pFS = GetFS();
2385 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
2386 : // grouping
2387 0 : sal_Bool bStacked = sal_False;
2388 0 : if( GetProperty( xPropSet, S( "Stacked" ) ) )
2389 0 : mAny >>= bStacked;
2390 0 : sal_Bool bPercentage = sal_False;
2391 0 : if( GetProperty( xPropSet, S( "Percent" ) ) )
2392 0 : mAny >>= bPercentage;
2393 :
2394 0 : const char* grouping = NULL;
2395 0 : if( bStacked )
2396 0 : grouping = "stacked";
2397 0 : else if( bPercentage )
2398 0 : grouping = "percentStacked";
2399 : else
2400 : {
2401 0 : if( isBar && !isDeep3dChart() )
2402 0 : grouping = "clustered";
2403 : else
2404 0 : grouping = "standard";
2405 : }
2406 : pFS->singleElement( FSNS( XML_c, XML_grouping ),
2407 : XML_val, grouping,
2408 0 : FSEND );
2409 0 : }
2410 :
2411 0 : void ChartExport::exportMarker()
2412 : {
2413 0 : FSHelperPtr pFS = GetFS();
2414 : pFS->startElement( FSNS( XML_c, XML_marker ),
2415 0 : FSEND );
2416 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY );
2417 0 : sal_Int32 nSymbolType = ::com::sun::star::chart::ChartSymbolType::NONE;
2418 0 : if( GetProperty( xPropSet, S( "SymbolType" ) ) )
2419 0 : mAny >>= nSymbolType;
2420 : // TODO: more properties support for marker
2421 0 : if( nSymbolType == ::com::sun::star::chart::ChartSymbolType::NONE )
2422 : {
2423 : pFS->singleElement( FSNS( XML_c, XML_symbol ),
2424 : XML_val, "none",
2425 0 : FSEND );
2426 : }
2427 0 : pFS->endElement( FSNS( XML_c, XML_marker ) );
2428 0 : }
2429 :
2430 0 : void ChartExport::exportSmooth()
2431 : {
2432 0 : FSHelperPtr pFS = GetFS();
2433 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY );
2434 0 : sal_Int32 nSplineType = 0;
2435 0 : if( GetProperty( xPropSet, S( "SplineType" ) ) )
2436 0 : mAny >>= nSplineType;
2437 0 : if( nSplineType != 0 )
2438 : {
2439 : pFS->singleElement( FSNS( XML_c, XML_smooth ),
2440 : XML_val, "1",
2441 0 : FSEND );
2442 0 : }
2443 0 : }
2444 :
2445 0 : void ChartExport::exportFirstSliceAng( )
2446 : {
2447 0 : FSHelperPtr pFS = GetFS();
2448 0 : sal_Int32 nStartingAngle = 0;
2449 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
2450 0 : if( GetProperty( xPropSet, S( "StartingAngle" ) ) )
2451 0 : mAny >>= nStartingAngle;
2452 :
2453 : // convert to ooxml angle
2454 0 : nStartingAngle = (450 - nStartingAngle ) % 360;
2455 : pFS->singleElement( FSNS( XML_c, XML_firstSliceAng ),
2456 : XML_val, I32S( nStartingAngle ),
2457 0 : FSEND );
2458 0 : }
2459 :
2460 0 : void ChartExport::exportView3D()
2461 : {
2462 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
2463 0 : if( !xPropSet.is() )
2464 0 : return;
2465 0 : FSHelperPtr pFS = GetFS();
2466 : pFS->startElement( FSNS( XML_c, XML_view3D ),
2467 0 : FSEND );
2468 : // rotX
2469 0 : if( GetProperty( xPropSet, S( "RotationHorizontal" ) ) )
2470 : {
2471 0 : sal_Int32 nRotationX = 0;
2472 0 : mAny >>= nRotationX;
2473 : // X rotation (map Chart2 [-179,180] to OOXML [0..359])
2474 0 : if( nRotationX < 0 )
2475 0 : nRotationX += 360;
2476 : pFS->singleElement( FSNS( XML_c, XML_rotX ),
2477 : XML_val, I32S( nRotationX ),
2478 0 : FSEND );
2479 : }
2480 : // rotY
2481 0 : if( GetProperty( xPropSet, S( "RotationVertical" ) ) )
2482 : {
2483 0 : sal_Int32 nRotationY = 0;
2484 0 : mAny >>= nRotationY;
2485 : // Y rotation (map Chart2 [-179,180] to OOXML [0..359])
2486 0 : if( nRotationY < 0 )
2487 0 : nRotationY += 360;
2488 : pFS->singleElement( FSNS( XML_c, XML_rotY ),
2489 : XML_val, I32S( nRotationY ),
2490 0 : FSEND );
2491 : }
2492 : // perspective
2493 0 : if( GetProperty( xPropSet, S( "Perspective" ) ) )
2494 : {
2495 0 : sal_Int32 nPerspective = 0;
2496 0 : mAny >>= nPerspective;
2497 : // map Chart2 [0,100] to OOXML [0..200]
2498 0 : nPerspective *= 2;
2499 : pFS->singleElement( FSNS( XML_c, XML_perspective ),
2500 : XML_val, I32S( nPerspective ),
2501 0 : FSEND );
2502 : }
2503 : // rAngAx
2504 0 : if( GetProperty( xPropSet, S( "RightAngledAxes" ) ) )
2505 : {
2506 0 : sal_Bool bRightAngled = sal_False;
2507 0 : mAny >>= bRightAngled;
2508 0 : const char* sRightAngled = bRightAngled ? "1":"0";
2509 : pFS->singleElement( FSNS( XML_c, XML_rAngAx ),
2510 : XML_val, sRightAngled,
2511 0 : FSEND );
2512 : }
2513 0 : pFS->endElement( FSNS( XML_c, XML_view3D ) );
2514 : }
2515 :
2516 0 : sal_Bool ChartExport::isDeep3dChart()
2517 : {
2518 0 : sal_Bool isDeep = sal_False;
2519 0 : if( mbIs3DChart )
2520 : {
2521 0 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
2522 0 : if( GetProperty( xPropSet, S( "Deep" ) ) )
2523 0 : mAny >>= isDeep;
2524 : }
2525 0 : return isDeep;
2526 : }
2527 :
2528 : }// drawingml
2529 51 : }// oox
2530 :
2531 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|