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