merge the formfield patch from ooo-build
[ooovba.git] / xmloff / source / chart / SchXMLExport.cxx
blob56daa7b05cbdc57e2907734da9ae32c9c0ae61ee
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: SchXMLExport.cxx,v $
10 * $Revision: 1.101 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
34 #include <xmloff/xmlprmap.hxx>
36 #include "SchXMLExport.hxx"
37 #include "XMLChartPropertySetMapper.hxx"
38 #include "SchXMLSeriesHelper.hxx"
39 #include "ColorPropertySet.hxx"
40 #include "SchXMLTools.hxx"
41 #include <tools/debug.hxx>
42 #include <rtl/logfile.hxx>
43 #include <comphelper/processfactory.hxx>
44 #include <tools/globname.hxx>
45 #include <sot/clsids.hxx>
47 #ifndef _SVTOOLS_NMSPMAP_HXX
48 #include <xmloff/nmspmap.hxx>
49 #endif
50 #include "xmlnmspe.hxx"
51 #include <xmloff/xmltoken.hxx>
52 #include <xmloff/families.hxx>
53 #include <xmloff/xmlaustp.hxx>
54 #include <xmloff/xmluconv.hxx>
55 #include <xmloff/xmlmetae.hxx>
56 #include "xexptran.hxx"
57 #include <rtl/math.hxx>
58 // header for any2enum
59 #include <comphelper/extract.hxx>
61 #include <list>
62 #include <typeinfo>
63 #include <algorithm>
65 #include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
66 #include <com/sun/star/lang/XServiceInfo.hpp>
67 #include <com/sun/star/lang/XServiceName.hpp>
68 #include <com/sun/star/beans/XPropertySet.hpp>
69 #include <com/sun/star/uno/XComponentContext.hpp>
70 #include <com/sun/star/util/XRefreshable.hpp>
72 #include <com/sun/star/chart/XChartDocument.hpp>
73 #include <com/sun/star/chart/ChartLegendPosition.hpp>
74 #include <com/sun/star/chart/XTwoAxisXSupplier.hpp>
75 #include <com/sun/star/chart/XTwoAxisYSupplier.hpp>
76 #include <com/sun/star/chart/XAxisZSupplier.hpp>
77 #include <com/sun/star/chart/XChartDataArray.hpp>
78 #include <com/sun/star/chart/ChartDataRowSource.hpp>
79 #include <com/sun/star/chart/ChartAxisAssign.hpp>
80 #include <com/sun/star/chart/ChartSeriesAddress.hpp>
81 #include <com/sun/star/chart/X3DDisplay.hpp>
82 #include <com/sun/star/chart/XStatisticDisplay.hpp>
83 #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
85 #include <com/sun/star/chart2/XChartDocument.hpp>
86 #include <com/sun/star/chart2/XDiagram.hpp>
87 #include <com/sun/star/chart2/RelativePosition.hpp>
88 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
89 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
90 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
91 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
92 #include <com/sun/star/chart2/data/XDataSource.hpp>
93 #include <com/sun/star/chart2/data/XDataSink.hpp>
94 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
95 #include <com/sun/star/chart2/data/XDataProvider.hpp>
96 #include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
97 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
98 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
99 #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
101 #include <com/sun/star/util/XStringMapping.hpp>
102 #include <com/sun/star/drawing/HomogenMatrix.hpp>
103 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
104 #include <com/sun/star/drawing/XShapes.hpp>
105 #include <com/sun/star/embed/Aspects.hpp>
106 #include <com/sun/star/embed/XVisualObject.hpp>
107 #include <com/sun/star/container/XChild.hpp>
110 #include "MultiPropertySetHandler.hxx"
111 #include "PropertyMap.hxx"
113 using namespace com::sun::star;
114 using namespace ::xmloff::token;
116 using ::rtl::OUString;
117 using ::rtl::OUStringBuffer;
118 using ::rtl::OUStringToOString;
119 using ::com::sun::star::uno::Sequence;
120 using ::com::sun::star::uno::Reference;
121 using ::com::sun::star::uno::Any;
123 namespace
125 Reference< uno::XComponentContext > lcl_getComponentContext()
127 Reference< uno::XComponentContext > xContext;
130 Reference< beans::XPropertySet > xFactProp( comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
131 if( xFactProp.is())
132 xFactProp->getPropertyValue(OUString::createFromAscii("DefaultContext")) >>= xContext;
134 catch( uno::Exception& )
137 return xContext;
140 class lcl_MatchesRole : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool >
142 public:
143 explicit lcl_MatchesRole( const OUString & aRole ) :
144 m_aRole( aRole )
147 bool operator () ( const Reference< chart2::data::XLabeledDataSequence > & xSeq ) const
149 if( !xSeq.is() )
150 return false;
151 Reference< beans::XPropertySet > xProp( xSeq->getValues(), uno::UNO_QUERY );
152 OUString aRole;
154 return ( xProp.is() &&
155 (xProp->getPropertyValue(
156 OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )) ) >>= aRole ) &&
157 m_aRole.equals( aRole ));
160 private:
161 OUString m_aRole;
164 template< typename T >
165 void lcl_SequenceToVectorAppend( const Sequence< T > & rSource, ::std::vector< T > & rDestination )
167 rDestination.reserve( rDestination.size() + rSource.getLength());
168 ::std::copy( rSource.getConstArray(), rSource.getConstArray() + rSource.getLength(),
169 ::std::back_inserter( rDestination ));
172 Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const Reference< chart2::XDiagram > & xDiagram )
174 Reference< chart2::data::XLabeledDataSequence > xResult;
177 Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
178 xDiagram, uno::UNO_QUERY_THROW );
179 Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
180 xCooSysCnt->getCoordinateSystems());
181 for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
183 Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[i] );
184 OSL_ASSERT( xCooSys.is());
185 for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
187 const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
188 for(sal_Int32 nI=0; nI<=nMaxAxisIndex; ++nI)
190 Reference< chart2::XAxis > xAxis = xCooSys->getAxisByDimension( nN, nI );
191 OSL_ASSERT( xAxis.is());
192 if( xAxis.is())
194 chart2::ScaleData aScaleData = xAxis->getScaleData();
195 if( aScaleData.Categories.is())
197 xResult.set( aScaleData.Categories );
198 break;
205 catch( uno::Exception & ex )
207 (void)ex; // avoid warning for pro build
208 OSL_ENSURE( false, OUStringToOString(
209 OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
210 OUString::createFromAscii( typeid( ex ).name()) +
211 OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
212 ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
216 //unused ranges are very problematic as they bear the risk to damage the rectangular structure completly
217 if(!xResult.is())
219 Sequence< Reference< chart2::data::XLabeledDataSequence > > aUnusedSequences( xDiagram->getUnusedData() );
221 lcl_MatchesRole aHasCategories( OUString::createFromAscii("categories" ) );
222 for( sal_Int32 nN=0; nN<aUnusedSequences.getLength(); nN++ )
224 if( aHasCategories( aUnusedSequences[nN] ) )
226 xResult.set( aUnusedSequences[nN] );
227 break;
233 return xResult;
236 Reference< chart2::data::XDataSource > lcl_createDataSource(
237 const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aData )
239 Reference< chart2::data::XDataSink > xSink;
240 Reference< uno::XComponentContext > xContext( lcl_getComponentContext());
241 if( xContext.is() )
242 xSink.set(
243 xContext->getServiceManager()->createInstanceWithContext(
244 OUString::createFromAscii("com.sun.star.chart2.data.DataSource"),
245 xContext ), uno::UNO_QUERY_THROW );
246 if( xSink.is())
247 xSink->setData( aData );
249 return Reference< chart2::data::XDataSource >( xSink, uno::UNO_QUERY );
252 Sequence< Reference< chart2::data::XLabeledDataSequence > > lcl_getAllSeriesSequences( const Reference< chart2::XChartDocument >& xChartDoc )
254 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aContainer;
255 if( xChartDoc.is() )
257 Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
258 ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( SchXMLSeriesHelper::getDataSeriesFromDiagram( xDiagram ));
259 for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aSeriesIt( aSeriesVector.begin() )
260 ; aSeriesIt != aSeriesVector.end(); ++aSeriesIt )
262 Reference< chart2::data::XDataSource > xDataSource( *aSeriesIt, uno::UNO_QUERY );
263 if( !xDataSource.is() )
264 continue;
265 uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > aDataSequences( xDataSource->getDataSequences() );
266 lcl_SequenceToVectorAppend( aDataSequences, aContainer );
270 Sequence< Reference< chart2::data::XLabeledDataSequence > > aRet( aContainer.size());
271 ::std::copy( aContainer.begin(), aContainer.end(), aRet.getArray());
273 return aRet;
276 Reference< chart2::data::XLabeledDataSequence >
277 lcl_getDataSequenceByRole(
278 const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aLabeledSeq,
279 const OUString & rRole )
281 Reference< chart2::data::XLabeledDataSequence > aNoResult;
283 const Reference< chart2::data::XLabeledDataSequence > * pBegin = aLabeledSeq.getConstArray();
284 const Reference< chart2::data::XLabeledDataSequence > * pEnd = pBegin + aLabeledSeq.getLength();
285 const Reference< chart2::data::XLabeledDataSequence > * pMatch =
286 ::std::find_if( pBegin, pEnd, lcl_MatchesRole( rRole ));
288 if( pMatch != pEnd )
289 return *pMatch;
291 return aNoResult;
294 Reference< chart2::data::XDataSource > lcl_pressUsedDataIntoRectangularFormat( const Reference< chart2::XChartDocument >& xChartDoc, sal_Bool& rOutSourceHasCategoryLabels )
296 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aLabeledSeqVector;
298 //categories are always the first sequence
299 Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
300 Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xDiagram ) );
301 if( xCategories.is() )
302 aLabeledSeqVector.push_back( xCategories );
303 rOutSourceHasCategoryLabels = sal_Bool(xCategories.is());
305 Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeriesSeqVector(
306 lcl_getAllSeriesSequences( xChartDoc ) );
308 //the first x-values is always the next sequence //todo ... other x-values get lost for old format
309 Reference< chart2::data::XLabeledDataSequence > xXValues(
310 lcl_getDataSequenceByRole( aSeriesSeqVector, OUString::createFromAscii("values-x" ) ) );
311 if( xXValues.is() )
312 aLabeledSeqVector.push_back( xXValues );
314 //add all other sequences now without x-values
315 lcl_MatchesRole aHasXValues( OUString::createFromAscii("values-x" ) );
316 for( sal_Int32 nN=0; nN<aSeriesSeqVector.getLength(); nN++ )
318 if( !aHasXValues( aSeriesSeqVector[nN] ) )
319 aLabeledSeqVector.push_back( aSeriesSeqVector[nN] );
322 Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( aLabeledSeqVector.size() );
323 ::std::copy( aLabeledSeqVector.begin(), aLabeledSeqVector.end(), aSeq.getArray() );
325 return lcl_createDataSource( aSeq );
328 bool lcl_isSeriesAttachedToFirstAxis(
329 const Reference< chart2::XDataSeries > & xDataSeries )
331 bool bResult=true;
335 sal_Int32 nAxisIndex = 0;
336 Reference< beans::XPropertySet > xProp( xDataSeries, uno::UNO_QUERY_THROW );
337 if( xProp.is() )
338 xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("AttachedAxisIndex") ) ) >>= nAxisIndex;
339 bResult = (0==nAxisIndex);
341 catch( uno::Exception & ex )
343 (void)ex; // avoid warning for pro build
344 OSL_ENSURE( false, OUStringToOString(
345 OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
346 OUString::createFromAscii( typeid( ex ).name()) +
347 OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
348 ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
351 return bResult;
354 OUString lcl_ConvertRange( const ::rtl::OUString & rRange, const Reference< chart2::XChartDocument > & xDoc )
356 OUString aResult = rRange;
357 if( !xDoc.is() )
358 return aResult;
359 Reference< chart2::data::XRangeXMLConversion > xConversion(
360 xDoc->getDataProvider(), uno::UNO_QUERY );
361 if( xConversion.is())
362 aResult = xConversion->convertRangeToXML( rRange );
363 return aResult;
366 typedef ::std::pair< OUString, OUString > tLabelAndValueRange;
368 tLabelAndValueRange lcl_getLabelAndValueRangeByRole(
369 const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aSeqCnt,
370 const OUString & rRole,
371 const Reference< chart2::XChartDocument > & xDoc,
372 SchXMLExportHelper::tDataSequenceCont & rOutSequencesToExport )
374 tLabelAndValueRange aResult;
376 Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
377 lcl_getDataSequenceByRole( aSeqCnt, rRole ));
378 if( xLabeledSeq.is())
380 Reference< chart2::data::XDataSequence > xLabelSeq( xLabeledSeq->getLabel());
381 if( xLabelSeq.is())
382 aResult.first = lcl_ConvertRange( xLabelSeq->getSourceRangeRepresentation(), xDoc );
384 Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues());
385 if( xValueSeq.is())
386 aResult.second = lcl_ConvertRange( xValueSeq->getSourceRangeRepresentation(), xDoc );
388 if( xLabelSeq.is() || xValueSeq.is())
389 rOutSequencesToExport.push_back( SchXMLExportHelper::tLabelValuesDataPair( xLabelSeq, xValueSeq ));
392 return aResult;
395 sal_Int32 lcl_getSequenceLengthByRole(
396 const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aSeqCnt,
397 const OUString & rRole )
399 Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
400 lcl_getDataSequenceByRole( aSeqCnt, rRole ));
401 if( xLabeledSeq.is())
403 Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getValues());
404 return xSeq->getData().getLength();
406 return 0;
409 bool lcl_hasChartType( const Reference< chart2::XDiagram > & xDiagram, const OUString & rChartType )
413 Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
414 Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
415 for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
417 Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
418 Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
419 for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
421 if( aChartTypes[nCTIdx]->getChartType().equals( rChartType ))
422 return true;
426 catch( uno::Exception & )
428 DBG_ERROR( "Exception while searching for chart type in diagram" );
430 return false;
433 OUString lcl_flattenStringSequence( const Sequence< OUString > & rSequence )
435 OUStringBuffer aResult;
436 bool bPrecedeWithSpace = false;
437 for( sal_Int32 nIndex=0; nIndex<rSequence.getLength(); ++nIndex )
439 if( rSequence[nIndex].getLength())
441 if( bPrecedeWithSpace )
442 aResult.append( static_cast< sal_Unicode >( ' ' ));
443 aResult.append( rSequence[nIndex] );
444 bPrecedeWithSpace = true;
447 return aResult.makeStringAndClear();
450 OUString lcl_getLabelString( const Reference< chart2::data::XDataSequence > & xLabelSeq )
452 Sequence< OUString > aLabels;
454 uno::Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xLabelSeq, uno::UNO_QUERY );
455 if( xTextualDataSequence.is())
457 aLabels = xTextualDataSequence->getTextualData();
459 else if( xLabelSeq.is())
461 Sequence< uno::Any > aAnies( xLabelSeq->getData());
462 aLabels.realloc( aAnies.getLength());
463 for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
464 aAnies[i] >>= aLabels[i];
467 return lcl_flattenStringSequence( aLabels );
470 sal_Int32 lcl_getMaxSequenceLength(
471 const SchXMLExportHelper::tDataSequenceCont & rContainer )
473 sal_Int32 nResult = 0;
474 for( SchXMLExportHelper::tDataSequenceCont::const_iterator aIt( rContainer.begin());
475 aIt != rContainer.end(); ++aIt )
477 if( aIt->first.is())
479 sal_Int32 nSeqLength = aIt->first->getData().getLength();
480 if( nSeqLength > nResult )
481 nResult = nSeqLength;
483 if( aIt->second.is())
485 sal_Int32 nSeqLength = aIt->second->getData().getLength();
486 if( nSeqLength > nResult )
487 nResult = nSeqLength;
490 return nResult;
493 void lcl_fillCategoriesIntoStringVector(
494 const Reference< chart2::data::XDataSequence > & xCategories,
495 ::std::vector< OUString > & rOutCategories )
497 OSL_ASSERT( xCategories.is());
498 if( !xCategories.is())
499 return;
500 Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xCategories, uno::UNO_QUERY );
501 if( xTextualDataSequence.is())
503 rOutCategories.clear();
504 Sequence< OUString > aTextData( xTextualDataSequence->getTextualData());
505 ::std::copy( aTextData.getConstArray(), aTextData.getConstArray() + aTextData.getLength(),
506 ::std::back_inserter( rOutCategories ));
508 else
510 Sequence< uno::Any > aAnies( xCategories->getData());
511 rOutCategories.resize( aAnies.getLength());
512 for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
513 aAnies[i] >>= rOutCategories[i];
517 double lcl_getValueFromSequence( const Reference< chart2::data::XDataSequence > & xSeq, sal_Int32 nIndex )
519 double fResult = 0.0;
520 ::rtl::math::setNan( &fResult );
521 Reference< chart2::data::XNumericalDataSequence > xNumSeq( xSeq, uno::UNO_QUERY );
522 if( xNumSeq.is())
524 Sequence< double > aValues( xNumSeq->getNumericalData());
525 if( nIndex < aValues.getLength() )
526 fResult = aValues[nIndex];
528 else
530 Sequence< uno::Any > aAnies( xSeq->getData());
531 if( nIndex < aAnies.getLength() )
532 aAnies[nIndex] >>= fResult;
534 return fResult;
537 ::std::vector< double > lcl_getAllValuesFromSequence( const Reference< chart2::data::XDataSequence > & xSeq )
539 double fNan = 0.0;
540 ::rtl::math::setNan( &fNan );
541 ::std::vector< double > aResult;
543 Reference< chart2::data::XNumericalDataSequence > xNumSeq( xSeq, uno::UNO_QUERY );
544 if( xNumSeq.is())
546 Sequence< double > aValues( xNumSeq->getNumericalData());
547 ::std::copy( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(),
548 ::std::back_inserter( aResult ));
550 else if( xSeq.is())
552 Sequence< uno::Any > aAnies( xSeq->getData());
553 aResult.resize( aAnies.getLength(), fNan );
554 for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
555 aAnies[i] >>= aResult[i];
557 return aResult;
560 bool lcl_SequenceHasUnhiddenData( const uno::Reference< chart2::data::XDataSequence >& xDataSequence )
562 if( !xDataSequence.is() )
563 return false;
564 uno::Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY );
565 if( xProp.is() )
567 uno::Sequence< sal_Int32 > aHiddenValues;
570 xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "HiddenValues" ) ) ) >>= aHiddenValues;
571 if( !aHiddenValues.getLength() )
572 return true;
574 catch( uno::Exception& e )
576 (void)e; // avoid warning
577 return true;
580 if( xDataSequence->getData().getLength() )
581 return true;
582 return false;
585 struct lcl_TableData
587 typedef ::std::vector< OUString > tStringContainer;
588 typedef ::std::vector< ::std::vector< double > > tTwoDimNumberContainer;
590 tTwoDimNumberContainer aDataInRows;
591 tStringContainer aDataRangeRepresentations;
592 tStringContainer aFirstRowStrings;
593 tStringContainer aFirstRowRangeRepresentations;
594 tStringContainer aFirstColumnStrings;
595 tStringContainer aFirstColumnRangeRepresentations;
597 ::std::vector< sal_Int32 > aHiddenColumns;
600 // ::std::bind2nd( ::std::mem_fun_ref( &T::resize ), nSize ) does not work
601 template< class T >
602 struct lcl_resize
604 lcl_resize( typename T::size_type nSize, typename T::value_type fDefaultValue ) : m_nSize( nSize ), m_fDefaultValue( fDefaultValue ) {}
605 void operator()( T & t )
606 { t.resize( m_nSize, m_fDefaultValue ); }
607 private:
608 typename T::size_type m_nSize;
609 typename T::value_type m_fDefaultValue;
613 typedef ::std::map< sal_Int32, SchXMLExportHelper::tLabelValuesDataPair >
614 lcl_DataSequenceMap;
616 struct lcl_SequenceToMapElement :
617 public ::std::unary_function< lcl_DataSequenceMap::mapped_type, lcl_DataSequenceMap::value_type >
619 lcl_SequenceToMapElement( sal_Int32 nOffset = 0 ) :
620 m_nOffset( nOffset )
622 result_type operator() ( const argument_type & rContent )
624 sal_Int32 nIndex = -1;
625 if( rContent.second.is())
627 OUString aRangeRep( rContent.second->getSourceRangeRepresentation());
628 if( aRangeRep.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("categories")))
630 OSL_ASSERT( m_nOffset > 0 );
631 nIndex = 0;
633 else
634 nIndex = aRangeRep.toInt32() + m_nOffset;
636 else if( rContent.first.is())
637 nIndex = rContent.first->getSourceRangeRepresentation().copy( sizeof("label ")).toInt32() + m_nOffset;
638 return result_type( nIndex, rContent );
640 private:
641 sal_Int32 m_nOffset;
644 void lcl_PrepareInternalSequencesForTableExport(
645 SchXMLExportHelper::tDataSequenceCont & rInOutSequences, bool bHasCategories )
647 lcl_DataSequenceMap aIndexSequenceMap;
648 const sal_Int32 nOffset = bHasCategories ? 1 : 0;
649 ::std::transform( rInOutSequences.begin(), rInOutSequences.end(),
650 ::std::inserter( aIndexSequenceMap, aIndexSequenceMap.begin()),
651 lcl_SequenceToMapElement( nOffset ));
653 rInOutSequences.clear();
654 sal_Int32 nIndex = 0;
655 for( lcl_DataSequenceMap::const_iterator aIt = aIndexSequenceMap.begin();
656 aIt != aIndexSequenceMap.end(); ++aIt, ++nIndex )
658 if( aIt->first < 0 )
659 continue;
660 // fill empty columns
661 for( ; nIndex < aIt->first; ++nIndex )
662 rInOutSequences.push_back(
663 SchXMLExportHelper::tDataSequenceCont::value_type( 0, 0 ));
664 OSL_ASSERT( nIndex == aIt->first );
665 rInOutSequences.push_back( aIt->second );
670 lcl_TableData lcl_getDataForLocalTable(
671 const SchXMLExportHelper::tDataSequenceCont & aPassedSequences, bool bHasCategoryLabels,
672 bool bSwap,
673 bool bHasOwnData,
674 const Reference< chart2::data::XRangeXMLConversion > & xRangeConversion )
676 lcl_TableData aResult;
678 SchXMLExportHelper::tDataSequenceCont aSequencesToExport( aPassedSequences );
679 if( bHasOwnData )
680 lcl_PrepareInternalSequencesForTableExport( aSequencesToExport, bHasCategoryLabels );
682 SchXMLExportHelper::tDataSequenceCont::size_type nNumSequences = aSequencesToExport.size();
683 SchXMLExportHelper::tDataSequenceCont::const_iterator aBegin( aSequencesToExport.begin());
684 SchXMLExportHelper::tDataSequenceCont::const_iterator aEnd( aSequencesToExport.end());
685 SchXMLExportHelper::tDataSequenceCont::const_iterator aIt( aBegin );
687 if( bHasCategoryLabels )
689 if( nNumSequences>=1 ) //#i83537#
690 --nNumSequences;
691 else
692 bHasCategoryLabels=false;
694 size_t nMaxSequenceLength( lcl_getMaxSequenceLength( aSequencesToExport ));
695 size_t nNumColumns( bSwap ? nMaxSequenceLength : nNumSequences );
696 size_t nNumRows( bSwap ? nNumSequences : nMaxSequenceLength );
698 // resize data
699 aResult.aDataInRows.resize( nNumRows );
700 double fNan = 0.0;
701 ::rtl::math::setNan( &fNan );
702 ::std::for_each( aResult.aDataInRows.begin(), aResult.aDataInRows.end(),
703 lcl_resize< lcl_TableData::tTwoDimNumberContainer::value_type >( nNumColumns, fNan ));
704 aResult.aFirstRowStrings.resize( nNumColumns );
705 aResult.aFirstColumnStrings.resize( nNumRows );
707 lcl_TableData::tStringContainer & rCategories =
708 (bSwap ? aResult.aFirstRowStrings : aResult.aFirstColumnStrings );
709 lcl_TableData::tStringContainer & rLabels =
710 (bSwap ? aResult.aFirstColumnStrings : aResult.aFirstRowStrings );
712 if( aIt != aEnd )
714 if( bHasCategoryLabels )
716 lcl_fillCategoriesIntoStringVector( aIt->second, rCategories );
717 if( aIt->second.is())
719 OUString aRange( aIt->second->getSourceRangeRepresentation());
720 if( xRangeConversion.is())
721 aRange = xRangeConversion->convertRangeToXML( aRange );
722 if( bSwap )
723 aResult.aFirstRowRangeRepresentations.push_back( aRange );
724 else
725 aResult.aFirstColumnRangeRepresentations.push_back( aRange );
727 ++aIt;
729 else
731 // autogenerated categories
732 rCategories.clear();
733 lcl_SequenceToVectorAppend( aIt->second->generateLabel( chart2::data::LabelOrigin_LONG_SIDE ), rCategories );
737 // iterate over all sequences
738 size_t nSeqIdx = 0;
739 for( ; aIt != aEnd; ++aIt, ++nSeqIdx )
741 OUString aRange;
742 if( aIt->first.is())
744 rLabels[nSeqIdx] = lcl_getLabelString( aIt->first );
745 aRange = aIt->first->getSourceRangeRepresentation();
746 if( xRangeConversion.is())
747 aRange = xRangeConversion->convertRangeToXML( aRange );
749 else if( aIt->second.is())
750 rLabels[nSeqIdx] = lcl_flattenStringSequence(
751 aIt->second->generateLabel( chart2::data::LabelOrigin_SHORT_SIDE ));
752 if( bSwap )
753 aResult.aFirstColumnRangeRepresentations.push_back( aRange );
754 else
755 aResult.aFirstRowRangeRepresentations.push_back( aRange );
757 ::std::vector< double > aNumbers( lcl_getAllValuesFromSequence( aIt->second ));
758 if( bSwap )
759 aResult.aDataInRows[nSeqIdx] = aNumbers;
760 else
762 const sal_Int32 nSize( static_cast< sal_Int32 >( aNumbers.size()));
763 for( sal_Int32 nIdx=0; nIdx<nSize; ++nIdx )
764 aResult.aDataInRows[nIdx][nSeqIdx] = aNumbers[nIdx];
767 if( aIt->second.is())
769 aRange = aIt->second->getSourceRangeRepresentation();
770 if( xRangeConversion.is())
771 aRange = xRangeConversion->convertRangeToXML( aRange );
773 aResult.aDataRangeRepresentations.push_back( aRange );
775 //is column hidden?
776 if( !lcl_SequenceHasUnhiddenData(aIt->first) && !lcl_SequenceHasUnhiddenData(aIt->second) )
777 aResult.aHiddenColumns.push_back(nSeqIdx);
780 return aResult;
783 void lcl_exportNumberFormat( const OUString& rPropertyName, const Reference< beans::XPropertySet >& xPropSet,
784 SvXMLExport& rExport )
786 if( xPropSet.is())
788 sal_Int32 nNumberFormat = 0;
789 Any aNumAny = xPropSet->getPropertyValue( rPropertyName );
790 if( (aNumAny >>= nNumberFormat) && (nNumberFormat != -1) )
791 rExport.addDataStyle( nNumberFormat );
795 ::std::vector< Reference< chart2::data::XDataSequence > >
796 lcl_getErrorBarSequences( const Reference< beans::XPropertySet > & xErrorBarProp )
798 ::std::vector< Reference< chart2::data::XDataSequence > > aResult;
799 Reference< chart2::data::XDataSource > xErrorBarDataSource( xErrorBarProp, uno::UNO_QUERY );
800 if( !xErrorBarDataSource.is())
801 return aResult;
803 const OUString aRolePrefix( RTL_CONSTASCII_USTRINGPARAM( "error-bars-" ));
804 // const OUString aXRolePrefix( aRolePrefix + OUString( RTL_CONSTASCII_USTRINGPARAM( "x-" )));
805 // const OUString aYRolePrefix( aRolePrefix + OUString( RTL_CONSTASCII_USTRINGPARAM( "y-" )));
806 // const OUString aPositivePostfix( RTL_CONSTASCII_USTRINGPARAM( "positive" ));
807 // const OUString aNegativePostfix( RTL_CONSTASCII_USTRINGPARAM( "negative" ));
809 Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences(
810 xErrorBarDataSource->getDataSequences());
811 for( sal_Int32 nI=0; nI< aSequences.getLength(); ++nI )
815 if( aSequences[nI].is())
817 Reference< chart2::data::XDataSequence > xSequence( aSequences[nI]->getValues());
818 Reference< beans::XPropertySet > xSeqProp( xSequence, uno::UNO_QUERY_THROW );
819 OUString aRole;
820 if( ( xSeqProp->getPropertyValue(
821 OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" ))) >>= aRole ) &&
822 aRole.match( aRolePrefix ))
824 aResult.push_back( xSequence );
828 catch( uno::Exception & rEx )
830 #ifdef DBG_UTIL
831 String aStr( rEx.Message );
832 ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US );
833 DBG_ERROR1( "chart:exporting error bar ranges: %s", aBStr.GetBuffer());
834 #else
835 (void)rEx; // avoid warning
836 #endif
840 return aResult;
843 bool lcl_exportDomainForThisSequence( const Reference< chart2::data::XDataSequence > xValues, rtl::OUString& rFirstRangeForThisDomainIndex, SvXMLExport& rExport )
845 bool bDomainExported = false;
846 if( xValues.is())
848 Reference< chart2::XChartDocument > xNewDoc( rExport.GetModel(), uno::UNO_QUERY );
849 OUString aRange( lcl_ConvertRange( xValues->getSourceRangeRepresentation(), xNewDoc ) );
851 //work around error in OOo 2.0 (problems with multiple series having a domain element)
852 if( !rFirstRangeForThisDomainIndex.getLength() || !aRange.equals(rFirstRangeForThisDomainIndex) )
854 rExport.AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, aRange);
855 SvXMLElementExport aDomain( rExport, XML_NAMESPACE_CHART, XML_DOMAIN, sal_True, sal_True );
856 bDomainExported = true;
859 if( !rFirstRangeForThisDomainIndex.getLength() )
860 rFirstRangeForThisDomainIndex = aRange;
862 return bDomainExported;
865 } // anonymous namespace
867 struct SchXMLDataPointStruct
869 OUString maStyleName;
870 sal_Int32 mnRepeat;
872 SchXMLDataPointStruct() : mnRepeat( 1 ) {}
875 // ========================================
876 // class SchXMLExportHelper
877 // ========================================
879 SchXMLExportHelper::SchXMLExportHelper(
880 SvXMLExport& rExport,
881 SvXMLAutoStylePoolP& rASPool ) :
882 mrExport( rExport ),
883 mrAutoStylePool( rASPool ),
884 mbHasSeriesLabels( sal_False ),
885 mbHasCategoryLabels( sal_False ),
886 mbRowSourceColumns( sal_True )
887 // #110680#
888 // this id depends on the ServiceManager used due to the binary filter stripping.
889 // ,msCLSID( rtl::OUString( SvGlobalName( SO3_SCH_CLASSID ).GetHexName()))
891 // #110680#
892 // changed initialisation for msCLSID. Compare the ServiceInfo name with
893 // the known name of the LegacyServiceManager.
894 Reference<lang::XServiceInfo> xServiceInfo( mrExport.getServiceFactory(), uno::UNO_QUERY );
895 DBG_ASSERT( xServiceInfo.is(), "XMultiServiceFactory without xServiceInfo (!)" );
896 OUString rdbURL = xServiceInfo->getImplementationName();
897 OUString implLegacyServiceManagerName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.office.LegacyServiceManager" ) );
899 if( rdbURL.equals( implLegacyServiceManagerName ))
901 msCLSID = OUString( SvGlobalName( BF_SO3_SCH_CLASSID ).GetHexName());
903 else
905 msCLSID = OUString( SvGlobalName( SO3_SCH_CLASSID ).GetHexName());
908 msTableName = OUString::createFromAscii( "local-table" );
910 // create factory
911 mxPropertyHandlerFactory = new XMLChartPropHdlFactory;
913 if( mxPropertyHandlerFactory.is() )
915 // create property set mapper
916 mxPropertySetMapper = new XMLChartPropertySetMapper;
919 mxExpPropMapper = new XMLChartExportPropertyMapper( mxPropertySetMapper, rExport );
921 // register chart auto-style family
922 mrAutoStylePool.AddFamily(
923 XML_STYLE_FAMILY_SCH_CHART_ID,
924 OUString::createFromAscii( XML_STYLE_FAMILY_SCH_CHART_NAME ),
925 mxExpPropMapper.get(),
926 OUString::createFromAscii( XML_STYLE_FAMILY_SCH_CHART_PREFIX ));
928 // register shape family
929 mrAutoStylePool.AddFamily(
930 XML_STYLE_FAMILY_SD_GRAPHICS_ID,
931 OUString::createFromAscii( XML_STYLE_FAMILY_SD_GRAPHICS_NAME ),
932 mxExpPropMapper.get(),
933 OUString::createFromAscii( XML_STYLE_FAMILY_SD_GRAPHICS_PREFIX ));
934 // register paragraph family also for shapes
935 mrAutoStylePool.AddFamily(
936 XML_STYLE_FAMILY_TEXT_PARAGRAPH,
937 GetXMLToken( XML_PARAGRAPH ),
938 mxExpPropMapper.get(),
939 String( 'P' ));
940 // register text family also for shapes
941 mrAutoStylePool.AddFamily(
942 XML_STYLE_FAMILY_TEXT_TEXT,
943 GetXMLToken( XML_TEXT ),
944 mxExpPropMapper.get(),
945 String( 'T' ));
948 SchXMLExportHelper::~SchXMLExportHelper() {}
950 const OUString& SchXMLExportHelper::getChartCLSID()
952 return msCLSID;
955 void SchXMLExportHelper::exportAutoStyles()
957 if( mxExpPropMapper.is())
959 //ToDo: when embedded in calc/writer this is not necessary because the
960 // numberformatter is shared between both documents
961 mrExport.exportAutoDataStyles();
963 // export chart auto styles
964 mrAutoStylePool.exportXML(
965 XML_STYLE_FAMILY_SCH_CHART_ID
966 , mrExport.GetDocHandler(),
967 mrExport.GetMM100UnitConverter(),
968 mrExport.GetNamespaceMap()
971 // export auto styles for additional shapes
972 mrExport.GetShapeExport()->exportAutoStyles();
973 // and for text in additional shapes
974 mrExport.GetTextParagraphExport()->exportTextAutoStyles();
978 void SchXMLExportHelper::collectAutoStyles( Reference< chart::XChartDocument > rChartDoc )
980 RTL_LOGFILE_CONTEXT_AUTHOR( aLogContext, "xmloff", "bm", "::SchXMLExportHelper::collectAutoStyles" );
982 parseDocument( rChartDoc, sal_False );
985 void SchXMLExportHelper::exportChart( Reference< chart::XChartDocument > rChartDoc,
986 sal_Bool bIncludeTable )
988 RTL_LOGFILE_CONTEXT_AUTHOR( aLogContext, "xmloff", "bm", "::SchXMLExportHelper::exportChart" );
990 parseDocument( rChartDoc, sal_True, bIncludeTable );
991 DBG_ASSERT( maAutoStyleNameQueue.empty(), "There are still remaining autostyle names in the queue" );
995 // private methods
996 // ---------------
998 ::rtl::OUString lcl_GetStringFromNumberSequence( const ::com::sun::star::uno::Sequence< sal_Int32 >& rSequenceMapping, bool bRemoveOneFromEachIndex /*should be true if having categories*/ )
1000 const sal_Int32* pArray = rSequenceMapping.getConstArray();
1001 const sal_Int32 nSize = rSequenceMapping.getLength();
1002 sal_Int32 i = 0;
1003 OUStringBuffer aBuf;
1004 bool bHasPredecessor = false;
1005 for( i = 0; i < nSize; ++i )
1007 sal_Int32 nIndex = pArray[ i ];
1008 if( bRemoveOneFromEachIndex )
1009 --nIndex;
1010 if(nIndex>=0)
1012 if(bHasPredecessor)
1013 aBuf.append( static_cast< sal_Unicode >( ' ' ));
1014 aBuf.append( nIndex, 10 );
1015 bHasPredecessor = true;
1018 return aBuf.makeStringAndClear();
1021 /// if bExportContent is false the auto-styles are collected
1022 void SchXMLExportHelper::parseDocument( Reference< chart::XChartDocument >& rChartDoc,
1023 sal_Bool bExportContent,
1024 sal_Bool bIncludeTable )
1026 Reference< chart2::XChartDocument > xNewDoc( rChartDoc, uno::UNO_QUERY );
1027 if( !rChartDoc.is() || !xNewDoc.is() )
1029 DBG_ERROR( "No XChartDocument was given for export." );
1030 return;
1033 awt::Size aPageSize( getPageSize( xNewDoc ));
1034 if( bExportContent )
1035 addSize( aPageSize );
1036 Reference< chart::XDiagram > xDiagram = rChartDoc->getDiagram();
1037 Reference< chart2::XDiagram > xNewDiagram;
1038 if( xNewDoc.is())
1039 xNewDiagram.set( xNewDoc->getFirstDiagram());
1041 //todo remove if model changes are notified and view is updated automatically
1042 if( bExportContent )
1044 Reference< util::XRefreshable > xRefreshable( xNewDoc, uno::UNO_QUERY );
1045 if( xRefreshable.is() )
1046 xRefreshable->refresh();
1049 // get Properties of ChartDocument
1050 sal_Bool bHasMainTitle = sal_False;
1051 sal_Bool bHasSubTitle = sal_False;
1052 sal_Bool bHasLegend = sal_False;
1053 util::DateTime aNullDate(0,0,0,0,30,12,1899);
1055 std::vector< XMLPropertyState > aPropertyStates;
1057 Reference< beans::XPropertySet > xDocPropSet( rChartDoc, uno::UNO_QUERY );
1058 if( xDocPropSet.is())
1062 Any aAny( xDocPropSet->getPropertyValue(
1063 OUString( RTL_CONSTASCII_USTRINGPARAM( "HasMainTitle" ))));
1064 aAny >>= bHasMainTitle;
1065 aAny = xDocPropSet->getPropertyValue(
1066 OUString( RTL_CONSTASCII_USTRINGPARAM( "HasSubTitle" )));
1067 aAny >>= bHasSubTitle;
1068 aAny = xDocPropSet->getPropertyValue(
1069 OUString( RTL_CONSTASCII_USTRINGPARAM( "HasLegend" )));
1070 aAny >>= bHasLegend;
1071 if ( bIncludeTable )
1073 OUString sNullDate( RTL_CONSTASCII_USTRINGPARAM( "NullDate" ));
1074 aAny = xDocPropSet->getPropertyValue(sNullDate);
1075 if ( !aAny.hasValue() )
1077 Reference<container::XChild> xChild(rChartDoc, uno::UNO_QUERY );
1078 if ( xChild.is() )
1080 Reference< beans::XPropertySet > xParentDoc( xChild->getParent(),uno::UNO_QUERY);
1081 if ( xParentDoc.is() && xParentDoc->getPropertySetInfo()->hasPropertyByName(sNullDate) )
1082 aAny = xParentDoc->getPropertyValue(sNullDate);
1086 aAny >>= aNullDate;
1089 catch( beans::UnknownPropertyException & )
1091 DBG_WARNING( "Required property not found in ChartDocument" );
1093 } // if( xDocPropSet.is())
1095 if ( bIncludeTable && (aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899 ) )
1097 SvXMLElementExport aSet( mrExport, XML_NAMESPACE_TABLE, XML_CALCULATION_SETTINGS, sal_True, sal_True );
1099 ::rtl::OUStringBuffer sBuffer;
1100 SvXMLUnitConverter::convertDateTime(sBuffer,aNullDate);
1101 mrExport.AddAttribute( XML_NAMESPACE_TABLE,XML_DATE_VALUE,sBuffer.makeStringAndClear());
1102 SvXMLElementExport aNull( mrExport, XML_NAMESPACE_TABLE, XML_NULL_DATE, sal_True, sal_True );
1106 // chart element
1107 // -------------
1109 SvXMLElementExport* pElChart = 0;
1110 // get property states for autostyles
1111 if( mxExpPropMapper.is())
1113 Reference< beans::XPropertySet > xPropSet( rChartDoc->getArea(), uno::UNO_QUERY );
1114 if( xPropSet.is())
1115 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1118 if( bExportContent )
1120 //export data provider in xlink:href attribute
1121 const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
1122 if( nCurrentODFVersion >= SvtSaveOptions::ODFVER_012 )
1124 OUString aDataProviderURL( RTL_CONSTASCII_USTRINGPARAM( ".." ) );
1125 if( xNewDoc->hasInternalDataProvider() )
1126 aDataProviderURL = OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) );
1127 else //special handling for data base data provider necessary
1129 Reference< chart2::data::XDatabaseDataProvider > xDBDataProvider( xNewDoc->getDataProvider(), uno::UNO_QUERY );
1130 if( xDBDataProvider.is() )
1131 aDataProviderURL = OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) );
1133 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, aDataProviderURL );
1136 OUString sChartType( xDiagram->getDiagramType() );
1138 // attributes
1139 // determine class
1140 if( sChartType.getLength())
1142 enum XMLTokenEnum eXMLChartType = SchXMLTools::getTokenByChartType( sChartType, true /* bUseOldNames */ );
1144 DBG_ASSERT( eXMLChartType != XML_TOKEN_INVALID, "invalid chart class" );
1145 if( eXMLChartType == XML_TOKEN_INVALID )
1146 eXMLChartType = XML_BAR;
1148 if( eXMLChartType == XML_ADD_IN )
1150 // sChartType is the servie-name of the add-in
1151 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS,
1152 mrExport.GetNamespaceMap().GetQNameByKey(
1153 XML_NAMESPACE_OOO, sChartType) );
1155 else if( eXMLChartType != XML_TOKEN_INVALID )
1157 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS,
1158 mrExport.GetNamespaceMap().GetQNameByKey(
1159 XML_NAMESPACE_CHART, GetXMLToken(eXMLChartType )) );
1162 //column-mapping or row-mapping
1163 if( maSequenceMapping.getLength() )
1165 enum XMLTokenEnum eTransToken = ::xmloff::token::XML_ROW_MAPPING;
1166 if( mbRowSourceColumns )
1167 eTransToken = ::xmloff::token::XML_COLUMN_MAPPING;
1168 ::rtl::OUString aSequenceMappingStr( lcl_GetStringFromNumberSequence(
1169 maSequenceMapping, mbHasCategoryLabels && !xNewDoc->hasInternalDataProvider() ) );
1171 mrExport.AddAttribute( XML_NAMESPACE_CHART,
1172 ::xmloff::token::GetXMLToken( eTransToken ),
1173 aSequenceMappingStr );
1176 // write style name
1177 AddAutoStyleAttribute( aPropertyStates );
1179 //element
1180 pElChart = new SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_CHART, sal_True, sal_True );
1182 else // autostyles
1184 CollectAutoStyle( aPropertyStates );
1186 // remove property states for autostyles
1187 aPropertyStates.clear();
1189 // title element
1190 // -------------
1192 if( bHasMainTitle )
1194 // get property states for autostyles
1195 if( mxExpPropMapper.is())
1197 Reference< beans::XPropertySet > xPropSet( rChartDoc->getTitle(), uno::UNO_QUERY );
1198 if( xPropSet.is())
1199 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1201 if( bExportContent )
1203 Reference< drawing::XShape > xShape = rChartDoc->getTitle();
1204 if( xShape.is()) // && "hasTitleBeenMoved"
1205 addPosition( xShape );
1207 // write style name
1208 AddAutoStyleAttribute( aPropertyStates );
1210 // element
1211 SvXMLElementExport aElTitle( mrExport, XML_NAMESPACE_CHART, XML_TITLE, sal_True, sal_True );
1213 // content (text:p)
1214 Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
1215 if( xPropSet.is())
1217 Any aAny( xPropSet->getPropertyValue(
1218 OUString( RTL_CONSTASCII_USTRINGPARAM( "String" ))));
1219 OUString aText;
1220 aAny >>= aText;
1221 exportText( aText );
1224 else // autostyles
1226 CollectAutoStyle( aPropertyStates );
1228 // remove property states for autostyles
1229 aPropertyStates.clear();
1232 // subtitle element
1233 // ----------------
1235 if( bHasSubTitle )
1237 // get property states for autostyles
1238 if( mxExpPropMapper.is())
1240 Reference< beans::XPropertySet > xPropSet( rChartDoc->getSubTitle(), uno::UNO_QUERY );
1241 if( xPropSet.is())
1242 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1245 if( bExportContent )
1247 Reference< drawing::XShape > xShape = rChartDoc->getSubTitle();
1248 if( xShape.is())
1249 addPosition( xShape );
1251 // write style name
1252 AddAutoStyleAttribute( aPropertyStates );
1254 // element (has no subelements)
1255 SvXMLElementExport aElSubTitle( mrExport, XML_NAMESPACE_CHART, XML_SUBTITLE, sal_True, sal_True );
1257 // content (text:p)
1258 Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
1259 if( xPropSet.is())
1261 Any aAny( xPropSet->getPropertyValue(
1262 OUString( RTL_CONSTASCII_USTRINGPARAM( "String" ))));
1263 OUString aText;
1264 aAny >>= aText;
1265 exportText( aText );
1268 else // autostyles
1270 CollectAutoStyle( aPropertyStates );
1272 // remove property states for autostyles
1273 aPropertyStates.clear();
1276 // legend element
1277 // --------------
1278 if( bHasLegend )
1280 // get property states for autostyles
1281 if( mxExpPropMapper.is())
1283 Reference< beans::XPropertySet > xPropSet( rChartDoc->getLegend(), uno::UNO_QUERY );
1284 if( xPropSet.is())
1285 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1288 if( bExportContent )
1290 Reference< beans::XPropertySet > xProp( rChartDoc->getLegend(), uno::UNO_QUERY );
1291 if( xProp.is())
1293 chart::ChartLegendPosition aLegendPos = chart::ChartLegendPosition_NONE;
1296 Any aAny( xProp->getPropertyValue(
1297 OUString( RTL_CONSTASCII_USTRINGPARAM( "Alignment" ))));
1298 aAny >>= aLegendPos;
1300 catch( beans::UnknownPropertyException & )
1302 DBG_WARNING( "Property Align not found in ChartLegend" );
1305 switch( aLegendPos )
1307 case chart::ChartLegendPosition_LEFT:
1308 // msString = GetXMLToken(XML_LEFT);
1309 // #i35421# change left->start (not clear why this was done)
1310 msString = GetXMLToken(XML_START);
1311 break;
1312 case chart::ChartLegendPosition_RIGHT:
1313 // msString = GetXMLToken(XML_RIGHT);
1314 // #i35421# change right->end (not clear why this was done)
1315 msString = GetXMLToken(XML_END);
1316 break;
1317 case chart::ChartLegendPosition_TOP:
1318 msString = GetXMLToken(XML_TOP);
1319 break;
1320 case chart::ChartLegendPosition_BOTTOM:
1321 msString = GetXMLToken(XML_BOTTOM);
1322 break;
1323 case chart::ChartLegendPosition_NONE:
1324 case chart::ChartLegendPosition_MAKE_FIXED_SIZE:
1325 // nothing
1326 break;
1329 // export anchor position
1330 if( msString.getLength())
1331 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_LEGEND_POSITION, msString );
1333 // export absolute position
1334 msString = OUString();
1335 Reference< drawing::XShape > xShape( xProp, uno::UNO_QUERY );
1336 if( xShape.is())
1337 addPosition( xShape );
1340 // write style name
1341 AddAutoStyleAttribute( aPropertyStates );
1343 // element
1344 SvXMLElementExport aLegend( mrExport, XML_NAMESPACE_CHART, XML_LEGEND, sal_True, sal_True );
1346 else // autostyles
1348 CollectAutoStyle( aPropertyStates );
1350 // remove property states for autostyles
1351 aPropertyStates.clear();
1354 // plot-area element
1355 // -----------------
1356 if( xDiagram.is())
1357 exportPlotArea( xDiagram, xNewDiagram, aPageSize, bExportContent, bIncludeTable );
1359 // export additional shapes
1360 // ------------------------
1361 if( xDocPropSet.is() )
1363 if( bExportContent )
1365 if( mxAdditionalShapes.is())
1367 // can't call exportShapes with all shapes because the
1368 // initialisation happend with the complete draw page and not
1369 // the XShapes object used here. Thus the shapes have to be
1370 // exported one by one
1371 UniReference< XMLShapeExport > rShapeExport = mrExport.GetShapeExport();
1372 Reference< drawing::XShape > xShape;
1373 const sal_Int32 nShapeCount( mxAdditionalShapes->getCount());
1374 for( sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++ )
1376 mxAdditionalShapes->getByIndex( nShapeId ) >>= xShape;
1377 DBG_ASSERT( xShape.is(), "Shape without an XShape?" );
1378 if( ! xShape.is())
1379 continue;
1381 rShapeExport->exportShape( xShape );
1383 // this would be the easier way if it worked:
1384 //mrExport.GetShapeExport()->exportShapes( mxAdditionalShapes );
1387 else
1389 // get a sequence of non-chart shapes (inserted via clipboard)
1392 Any aShapesAny = xDocPropSet->getPropertyValue( OUString::createFromAscii( "AdditionalShapes" ));
1393 aShapesAny >>= mxAdditionalShapes;
1395 catch( uno::Exception & rEx )
1397 (void)rEx; // avoid warning for pro build
1398 OSL_TRACE(
1399 OUStringToOString(
1400 OUString( RTL_CONSTASCII_USTRINGPARAM(
1401 "AdditionalShapes not found: " )) +
1402 rEx.Message,
1403 RTL_TEXTENCODING_ASCII_US ).getStr());
1406 if( mxAdditionalShapes.is())
1408 // seek shapes has to be called for the whole page because in
1409 // the shape export the vector of shapes is accessed via the
1410 // ZOrder which might be (actually is) larger than the number of
1411 // shapes in mxAdditionalShapes
1412 Reference< drawing::XDrawPageSupplier > xSupplier( rChartDoc, uno::UNO_QUERY );
1413 DBG_ASSERT( xSupplier.is(), "Cannot retrieve draw page to initialize shape export" );
1414 if( xSupplier.is() )
1416 Reference< drawing::XShapes > xDrawPage( xSupplier->getDrawPage(), uno::UNO_QUERY );
1417 DBG_ASSERT( xDrawPage.is(), "Invalid draw page for initializing shape export" );
1418 if( xDrawPage.is())
1419 mrExport.GetShapeExport()->seekShapes( xDrawPage );
1422 // can't call collectShapesAutoStyles with all shapes because
1423 // the initialisation happend with the complete draw page and
1424 // not the XShapes object used here. Thus the shapes have to be
1425 // exported one by one
1426 UniReference< XMLShapeExport > rShapeExport = mrExport.GetShapeExport();
1427 Reference< drawing::XShape > xShape;
1428 const sal_Int32 nShapeCount( mxAdditionalShapes->getCount());
1429 for( sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++ )
1431 mxAdditionalShapes->getByIndex( nShapeId ) >>= xShape;
1432 DBG_ASSERT( xShape.is(), "Shape without an XShape?" );
1433 if( ! xShape.is())
1434 continue;
1436 rShapeExport->collectShapeAutoStyles( xShape );
1438 // this would be the easier way if it worked:
1439 // mrExport.GetShapeExport()->collectShapesAutoStyles( mxAdditionalShapes );
1444 // table element
1445 // (is included as subelement of chart)
1446 // ------------------------------------
1447 if( bExportContent )
1449 // #85929# always export table, otherwise clipboard may loose data
1450 exportTable();
1453 // close <chart:chart> element
1454 if( pElChart )
1455 delete pElChart;
1458 void SchXMLExportHelper::exportTable()
1460 // table element
1461 // -------------
1462 mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, msTableName );
1463 SvXMLElementExport aTable( mrExport, XML_NAMESPACE_TABLE, XML_TABLE, sal_True, sal_True );
1465 bool bHasOwnData = false;
1466 Reference< chart2::XChartDocument > xNewDoc( mrExport.GetModel(), uno::UNO_QUERY );
1467 Reference< chart2::data::XRangeXMLConversion > xRangeConversion;
1468 if( xNewDoc.is())
1470 bHasOwnData = xNewDoc->hasInternalDataProvider();
1471 xRangeConversion.set( xNewDoc->getDataProvider(), uno::UNO_QUERY );
1474 lcl_TableData aData( lcl_getDataForLocalTable(
1475 m_aDataSequencesToExport, mbHasCategoryLabels, !mbRowSourceColumns, bHasOwnData, xRangeConversion ));
1477 lcl_TableData::tStringContainer::const_iterator aDataRangeIter( aData.aDataRangeRepresentations.begin());
1478 const lcl_TableData::tStringContainer::const_iterator aDataRangeEndIter( aData.aDataRangeRepresentations.end());
1479 lcl_TableData::tStringContainer::const_iterator aFirstColumnRangeIter( aData.aFirstColumnRangeRepresentations.begin());
1480 const lcl_TableData::tStringContainer::const_iterator aFirstColumnRangeEndIter( aData.aFirstColumnRangeRepresentations.end());
1482 // declare columns
1484 SvXMLElementExport aHeaderColumns( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, sal_True, sal_True );
1485 SvXMLElementExport aHeaderColumn( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True );
1488 SvXMLElementExport aColumns( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMNS, sal_True, sal_True );
1490 sal_Int32 nNextIndex = 0;
1491 for( size_t nN=0; nN< aData.aHiddenColumns.size(); nN++ )
1493 //i91578 display of hidden values (copy paste scenario; export hidden flag thus it can be used during migration to locale table upon paste )
1494 sal_Int32 nHiddenIndex = aData.aHiddenColumns[nN];
1495 if( nHiddenIndex > nNextIndex )
1497 sal_Int64 nRepeat = static_cast< sal_Int64 >( nHiddenIndex - nNextIndex );
1498 if(nRepeat>1)
1499 mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED,
1500 OUString::valueOf( nRepeat ));
1501 SvXMLElementExport aColumn( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True );
1503 mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_VISIBILITY, GetXMLToken( XML_COLLAPSE ) );
1504 SvXMLElementExport aColumn( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True );
1505 nNextIndex = nHiddenIndex+1;
1508 sal_Int32 nEndIndex = aData.aFirstRowStrings.size()-1;
1509 if( nEndIndex >= nNextIndex )
1511 sal_Int64 nRepeat = static_cast< sal_Int64 >( nEndIndex - nNextIndex + 1 );
1512 if(nRepeat>1)
1513 mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED,
1514 OUString::valueOf( nRepeat ));
1515 SvXMLElementExport aColumn( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True );
1519 // export rows with content
1521 SvXMLElementExport aHeaderRows( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, sal_True, sal_True );
1522 SvXMLElementExport aRow( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True );
1524 SvXMLElementExport aEmptyCell( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True );
1525 SvXMLElementExport aEmptyParagraph( mrExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_True );
1528 lcl_TableData::tStringContainer::const_iterator aFirstRowRangeIter( aData.aFirstRowRangeRepresentations.begin());
1529 const lcl_TableData::tStringContainer::const_iterator aFirstRowRangeEndIter( aData.aFirstRowRangeRepresentations.end());
1530 for( lcl_TableData::tStringContainer::const_iterator aIt( aData.aFirstRowStrings.begin());
1531 aIt != aData.aFirstRowStrings.end(); ++aIt )
1533 mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING );
1534 SvXMLElementExport aCell( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True );
1535 // write the original range name as id into the local table
1536 // to allow a correct re-association when copying via clipboard
1537 if( !bHasOwnData && aFirstRowRangeIter != aFirstRowRangeEndIter )
1539 if( (*aFirstRowRangeIter).getLength())
1540 mrExport.AddAttribute( XML_NAMESPACE_TEXT, XML_ID, *aFirstRowRangeIter );
1541 ++aFirstRowRangeIter;
1543 exportText( *aIt );
1545 OSL_ASSERT( bHasOwnData || aFirstRowRangeIter == aFirstRowRangeEndIter );
1546 } // closing row and header-rows elements
1548 // value rows
1550 SvXMLElementExport aRows( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_ROWS, sal_True, sal_True );
1551 lcl_TableData::tStringContainer::const_iterator aFirstColIt( aData.aFirstColumnStrings.begin());
1552 for( lcl_TableData::tTwoDimNumberContainer::const_iterator aColIt( aData.aDataInRows.begin());
1553 aColIt != aData.aDataInRows.end(); ++aColIt )
1555 SvXMLElementExport aRow( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True );
1557 mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING );
1558 SvXMLElementExport aCell( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True );
1559 if( aFirstColIt != aData.aFirstColumnStrings.end())
1561 // write the original range name as id into the local table
1562 // to allow a correct re-association when copying via clipboard
1563 if( !bHasOwnData && aFirstColumnRangeIter != aFirstColumnRangeEndIter )
1564 mrExport.AddAttribute( XML_NAMESPACE_TEXT, XML_ID, *aFirstColumnRangeIter++ );
1565 exportText( *aFirstColIt );
1566 ++aFirstColIt;
1569 for( lcl_TableData::tTwoDimNumberContainer::value_type::const_iterator aInnerIt( aColIt->begin());
1570 aInnerIt != aColIt->end(); ++aInnerIt )
1572 SvXMLUnitConverter::convertDouble( msStringBuffer, *aInnerIt );
1573 msString = msStringBuffer.makeStringAndClear();
1574 mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT );
1575 mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_VALUE, msString );
1576 SvXMLElementExport aCell( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True );
1577 // write the original range name as id into the local table to
1578 // allow a correct re-association when copying via clipboard
1579 if( ( !bHasOwnData && aDataRangeIter != aDataRangeEndIter ) &&
1580 ( mbRowSourceColumns || (aInnerIt == aColIt->begin())) )
1582 if( (*aDataRangeIter).getLength())
1583 mrExport.AddAttribute( XML_NAMESPACE_TEXT, XML_ID, *aDataRangeIter );
1584 ++aDataRangeIter;
1586 exportText( msString, false ); // do not convert tabs and lfs
1591 // if range iterator was used it should have reached its end
1592 OSL_ASSERT( bHasOwnData || (aDataRangeIter == aDataRangeEndIter) );
1593 OSL_ASSERT( bHasOwnData || (aFirstColumnRangeIter == aFirstColumnRangeEndIter) );
1596 void SchXMLExportHelper::exportPlotArea(
1597 Reference< chart::XDiagram > xDiagram,
1598 Reference< chart2::XDiagram > xNewDiagram,
1599 const awt::Size & rPageSize,
1600 sal_Bool bExportContent,
1601 sal_Bool bIncludeTable )
1603 DBG_ASSERT( xDiagram.is(), "Invalid XDiagram as parameter" );
1604 if( ! xDiagram.is())
1605 return;
1607 // variables for autostyles
1608 Reference< beans::XPropertySet > xPropSet;
1609 std::vector< XMLPropertyState > aPropertyStates;
1611 OUString aASName;
1612 sal_Bool bHasTwoYAxes = sal_False;
1613 sal_Bool bIs3DChart = sal_False;
1614 drawing::HomogenMatrix aTransMatrix;
1616 msStringBuffer.setLength( 0 );
1618 // plot-area element
1619 // -----------------
1621 SvXMLElementExport* pElPlotArea = 0;
1622 // get property states for autostyles
1623 xPropSet = Reference< beans::XPropertySet >( xDiagram, uno::UNO_QUERY );
1624 if( xPropSet.is())
1626 if( mxExpPropMapper.is())
1627 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
1629 if( bExportContent )
1631 UniReference< XMLShapeExport > rShapeExport;
1633 // write style name
1634 AddAutoStyleAttribute( aPropertyStates );
1636 if( msChartAddress.getLength() )
1638 if( !bIncludeTable )
1639 mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, msChartAddress );
1641 Reference< chart::XChartDocument > xDoc( mrExport.GetModel(), uno::UNO_QUERY );
1642 if( xDoc.is() )
1644 Reference< beans::XPropertySet > xDocProp( xDoc, uno::UNO_QUERY );
1645 if( xDocProp.is())
1647 Any aAny;
1648 sal_Bool bFirstCol = false, bFirstRow = false;
1652 aAny = xDocProp->getPropertyValue(
1653 OUString( RTL_CONSTASCII_USTRINGPARAM( "DataSourceLabelsInFirstColumn" )));
1654 aAny >>= bFirstCol;
1655 aAny = xDocProp->getPropertyValue(
1656 OUString( RTL_CONSTASCII_USTRINGPARAM( "DataSourceLabelsInFirstRow" )));
1657 aAny >>= bFirstRow;
1659 if( bFirstCol || bFirstRow )
1661 mrExport.AddAttribute( XML_NAMESPACE_CHART,
1662 ::xmloff::token::GetXMLToken( ::xmloff::token::XML_DATA_SOURCE_HAS_LABELS ),
1663 ( bFirstCol
1664 ? ( bFirstRow
1665 ? ::xmloff::token::GetXMLToken( ::xmloff::token::XML_BOTH )
1666 : ::xmloff::token::GetXMLToken( ::xmloff::token::XML_COLUMN ))
1667 : ::xmloff::token::GetXMLToken( ::xmloff::token::XML_ROW )));
1670 catch( beans::UnknownPropertyException & )
1672 DBG_ERRORFILE( "Properties missing" );
1678 // #i72973#, #144135# only export table-number-list in OOo format (also for binary)
1679 Reference< beans::XPropertySet > xExportInfo( mrExport.getExportInfo());
1680 if( msTableNumberList.getLength() &&
1681 xExportInfo.is())
1685 OUString sExportTableNumListPropName( RTL_CONSTASCII_USTRINGPARAM("ExportTableNumberList"));
1686 Reference< beans::XPropertySetInfo > xInfo( xExportInfo->getPropertySetInfo());
1687 bool bExportTableNumberList = false;
1688 if( xInfo.is() && xInfo->hasPropertyByName( sExportTableNumListPropName ) &&
1689 (xExportInfo->getPropertyValue( sExportTableNumListPropName ) >>= bExportTableNumberList) &&
1690 bExportTableNumberList )
1692 // this attribute is for charts embedded in calc documents only.
1693 // With this you are able to store a file again in 5.0 binary format
1694 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_TABLE_NUMBER_LIST, msTableNumberList );
1697 catch( uno::Exception & rEx )
1699 #ifdef DBG_UTIL
1700 String aStr( rEx.Message );
1701 ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US );
1702 DBG_ERROR1( "chart:TableNumberList property caught: %s", aBStr.GetBuffer());
1703 #else
1704 (void)rEx; // avoid warning
1705 #endif
1709 // attributes
1710 Reference< drawing::XShape > xShape ( xDiagram, uno::UNO_QUERY );
1711 if( xShape.is())
1713 addPosition( xShape );
1714 addSize( xShape );
1717 if( xPropSet.is())
1719 Any aAny;
1722 aAny = xPropSet->getPropertyValue(
1723 OUString( RTL_CONSTASCII_USTRINGPARAM( "HasSecondaryYAxis" )));
1724 aAny >>= bHasTwoYAxes;
1726 catch( beans::UnknownPropertyException & )
1728 DBG_ERROR( "Property HasSecondaryYAxis not found in Diagram" );
1731 // 3d attributes
1734 aAny = xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Dim3D" )));
1735 aAny >>= bIs3DChart;
1737 if( bIs3DChart )
1739 rShapeExport = mrExport.GetShapeExport();
1740 if( rShapeExport.is())
1741 rShapeExport->export3DSceneAttributes( xPropSet );
1744 catch( uno::Exception & rEx )
1746 #ifdef DBG_UTIL
1747 String aStr( rEx.Message );
1748 ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US );
1749 DBG_ERROR1( "chart:exportPlotAreaException caught: %s", aBStr.GetBuffer());
1750 #else
1751 (void)rEx; // avoid warning
1752 #endif
1756 // element
1757 pElPlotArea = new SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_PLOT_AREA, sal_True, sal_True );
1759 // light sources (inside plot area element)
1760 if( bIs3DChart &&
1761 rShapeExport.is())
1762 rShapeExport->export3DLamps( xPropSet );
1764 else // autostyles
1766 CollectAutoStyle( aPropertyStates );
1768 // remove property states for autostyles
1769 aPropertyStates.clear();
1771 // axis elements
1772 // -------------
1773 exportAxes( xDiagram, xNewDiagram, bExportContent );
1775 // series elements
1776 // ---------------
1777 exportSeries( xNewDiagram, rPageSize, bExportContent, bHasTwoYAxes );
1779 // stock-chart elements
1780 OUString sChartType ( xDiagram->getDiagramType());
1781 if( 0 == sChartType.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.StockDiagram" )))
1783 Reference< chart::XStatisticDisplay > xStockPropProvider( xDiagram, uno::UNO_QUERY );
1784 if( xStockPropProvider.is())
1786 // stock-gain-marker
1787 Reference< beans::XPropertySet > xStockPropSet = xStockPropProvider->getUpBar();
1788 if( xStockPropSet.is())
1790 aPropertyStates.clear();
1791 aPropertyStates = mxExpPropMapper->Filter( xStockPropSet );
1793 if( !aPropertyStates.empty() )
1795 if( bExportContent )
1797 AddAutoStyleAttribute( aPropertyStates );
1799 SvXMLElementExport aGain( mrExport, XML_NAMESPACE_CHART, XML_STOCK_GAIN_MARKER, sal_True, sal_True );
1801 else
1803 CollectAutoStyle( aPropertyStates );
1808 // stock-loss-marker
1809 xStockPropSet = xStockPropProvider->getDownBar();
1810 if( xStockPropSet.is())
1812 aPropertyStates.clear();
1813 aPropertyStates = mxExpPropMapper->Filter( xStockPropSet );
1815 if( !aPropertyStates.empty() )
1817 if( bExportContent )
1819 AddAutoStyleAttribute( aPropertyStates );
1821 SvXMLElementExport aGain( mrExport, XML_NAMESPACE_CHART, XML_STOCK_LOSS_MARKER, sal_True, sal_True );
1823 else
1825 CollectAutoStyle( aPropertyStates );
1830 // stock-range-line
1831 xStockPropSet = xStockPropProvider->getMinMaxLine();
1832 if( xStockPropSet.is())
1834 aPropertyStates.clear();
1835 aPropertyStates = mxExpPropMapper->Filter( xStockPropSet );
1837 if( !aPropertyStates.empty() )
1839 if( bExportContent )
1841 AddAutoStyleAttribute( aPropertyStates );
1843 SvXMLElementExport aGain( mrExport, XML_NAMESPACE_CHART, XML_STOCK_RANGE_LINE, sal_True, sal_True );
1845 else
1847 CollectAutoStyle( aPropertyStates );
1854 // wall and floor element
1855 // ----------------------
1857 Reference< chart::X3DDisplay > xWallFloorSupplier( xDiagram, uno::UNO_QUERY );
1858 if( mxExpPropMapper.is() &&
1859 xWallFloorSupplier.is())
1861 // remove property states for autostyles
1862 aPropertyStates.clear();
1864 Reference< beans::XPropertySet > xWallPropSet( xWallFloorSupplier->getWall(), uno::UNO_QUERY );
1865 if( xWallPropSet.is())
1867 aPropertyStates = mxExpPropMapper->Filter( xWallPropSet );
1869 if( !aPropertyStates.empty() )
1871 // write element
1872 if( bExportContent )
1874 // add style name attribute
1875 AddAutoStyleAttribute( aPropertyStates );
1877 SvXMLElementExport aWall( mrExport, XML_NAMESPACE_CHART, XML_WALL, sal_True, sal_True );
1879 else // autostyles
1881 CollectAutoStyle( aPropertyStates );
1886 // floor element
1887 // -------------
1889 // remove property states for autostyles
1890 aPropertyStates.clear();
1892 Reference< beans::XPropertySet > xFloorPropSet( xWallFloorSupplier->getFloor(), uno::UNO_QUERY );
1893 if( xFloorPropSet.is())
1895 aPropertyStates = mxExpPropMapper->Filter( xFloorPropSet );
1897 if( !aPropertyStates.empty() )
1899 // write element
1900 if( bExportContent )
1902 // add style name attribute
1903 AddAutoStyleAttribute( aPropertyStates );
1905 SvXMLElementExport aFloor( mrExport, XML_NAMESPACE_CHART, XML_FLOOR, sal_True, sal_True );
1907 else // autostyles
1909 CollectAutoStyle( aPropertyStates );
1915 if( pElPlotArea )
1916 delete pElPlotArea;
1919 void SchXMLExportHelper::exportAxes(
1920 const Reference< chart::XDiagram > & xDiagram,
1921 const Reference< chart2::XDiagram > & xNewDiagram,
1922 sal_Bool bExportContent )
1924 DBG_ASSERT( xDiagram.is(), "Invalid XDiagram as parameter" );
1925 if( ! xDiagram.is())
1926 return;
1928 // variables for autostyles
1929 const OUString sNumFormat( OUString::createFromAscii( "NumberFormat" ));
1930 Reference< beans::XPropertySet > xPropSet;
1931 std::vector< XMLPropertyState > aPropertyStates;
1933 OUString aASName;
1935 // get some properties from document first
1936 sal_Bool bHasXAxis = sal_False,
1937 bHasYAxis = sal_False,
1938 bHasZAxis = sal_False,
1939 bHasSecondaryXAxis = sal_False,
1940 bHasSecondaryYAxis = sal_False;
1941 sal_Bool bHasXAxisTitle = sal_False,
1942 bHasYAxisTitle = sal_False,
1943 bHasZAxisTitle = sal_False,
1944 bHasSecondaryXAxisTitle = sal_False,
1945 bHasSecondaryYAxisTitle = sal_False;
1946 sal_Bool bHasXAxisMajorGrid = sal_False,
1947 bHasXAxisMinorGrid = sal_False,
1948 bHasYAxisMajorGrid = sal_False,
1949 bHasYAxisMinorGrid = sal_False,
1950 bHasZAxisMajorGrid = sal_False,
1951 bHasZAxisMinorGrid = sal_False;
1952 sal_Bool bIs3DChart = sal_False;
1954 // get multiple properties using XMultiPropertySet
1955 MultiPropertySetHandler aDiagramProperties (xDiagram);
1957 // Check for supported services and then the properties provided by this service.
1958 Reference<lang::XServiceInfo> xServiceInfo (xDiagram, uno::UNO_QUERY);
1959 if (xServiceInfo.is())
1961 if (xServiceInfo->supportsService(
1962 OUString::createFromAscii ("com.sun.star.chart.ChartAxisXSupplier")))
1964 aDiagramProperties.Add (
1965 OUString(RTL_CONSTASCII_USTRINGPARAM("HasXAxis")), bHasXAxis);
1967 if (xServiceInfo->supportsService(
1968 OUString::createFromAscii ("com.sun.star.chart.ChartAxisYSupplier")))
1970 aDiagramProperties.Add (
1971 OUString(RTL_CONSTASCII_USTRINGPARAM("HasYAxis")), bHasYAxis);
1973 if (xServiceInfo->supportsService(
1974 OUString::createFromAscii ("com.sun.star.chart.ChartAxisZSupplier")))
1976 aDiagramProperties.Add (
1977 OUString(RTL_CONSTASCII_USTRINGPARAM("HasZAxis")), bHasZAxis);
1979 if (xServiceInfo->supportsService(
1980 OUString::createFromAscii ("com.sun.star.chart.ChartTwoAxisXSupplier")))
1982 aDiagramProperties.Add (
1983 OUString(RTL_CONSTASCII_USTRINGPARAM("HasSecondaryXAxis")), bHasSecondaryXAxis);
1985 if (xServiceInfo->supportsService(
1986 OUString::createFromAscii ("com.sun.star.chart.ChartTwoAxisYSupplier")))
1988 aDiagramProperties.Add (
1989 OUString(RTL_CONSTASCII_USTRINGPARAM("HasSecondaryYAxis")), bHasSecondaryYAxis);
1993 aDiagramProperties.Add (
1994 OUString (RTL_CONSTASCII_USTRINGPARAM ("HasXAxisTitle")), bHasXAxisTitle);
1995 aDiagramProperties.Add (
1996 OUString (RTL_CONSTASCII_USTRINGPARAM ("HasYAxisTitle")), bHasYAxisTitle);
1997 aDiagramProperties.Add (
1998 OUString (RTL_CONSTASCII_USTRINGPARAM ("HasZAxisTitle")), bHasZAxisTitle);
1999 aDiagramProperties.Add (
2000 OUString (RTL_CONSTASCII_USTRINGPARAM ("HasSecondaryXAxisTitle")), bHasSecondaryXAxisTitle);
2001 aDiagramProperties.Add (
2002 OUString (RTL_CONSTASCII_USTRINGPARAM ("HasSecondaryYAxisTitle")), bHasSecondaryYAxisTitle);
2004 aDiagramProperties.Add (
2005 OUString (RTL_CONSTASCII_USTRINGPARAM ("HasXAxisGrid")), bHasXAxisMajorGrid);
2006 aDiagramProperties.Add (
2007 OUString (RTL_CONSTASCII_USTRINGPARAM ("HasYAxisGrid")), bHasYAxisMajorGrid);
2008 aDiagramProperties.Add (
2009 OUString (RTL_CONSTASCII_USTRINGPARAM ("HasZAxisGrid")), bHasZAxisMajorGrid);
2011 aDiagramProperties.Add (
2012 OUString (RTL_CONSTASCII_USTRINGPARAM ("HasXAxisHelpGrid")), bHasXAxisMinorGrid);
2013 aDiagramProperties.Add (
2014 OUString (RTL_CONSTASCII_USTRINGPARAM ("HasYAxisHelpGrid")), bHasYAxisMinorGrid);
2015 aDiagramProperties.Add (
2016 OUString (RTL_CONSTASCII_USTRINGPARAM ("HasZAxisHelpGrid")), bHasZAxisMinorGrid);
2018 aDiagramProperties.Add(
2019 OUString (RTL_CONSTASCII_USTRINGPARAM ("Dim3D")), bIs3DChart);
2021 if ( ! aDiagramProperties.GetProperties ())
2023 DBG_WARNING ("Required properties not found in Chart diagram");
2026 SvXMLElementExport* pAxis = NULL;
2028 // x axis
2029 // -------
2031 // write axis element also if the axis itself is not visible, but a grid or
2032 // title
2033 Reference< chart::XAxisXSupplier > xAxisXSupp( xDiagram, uno::UNO_QUERY );
2034 if( xAxisXSupp.is())
2036 bool bHasAxisProperties = false;
2037 // get property states for autostyles
2038 if( mxExpPropMapper.is())
2040 xPropSet = xAxisXSupp->getXAxis();
2041 if( xPropSet.is())
2043 bHasAxisProperties = true;
2044 lcl_exportNumberFormat( sNumFormat, xPropSet, mrExport );
2045 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
2049 if( bHasXAxis ||
2050 bHasXAxisTitle || bHasXAxisMajorGrid || bHasXAxisMinorGrid ||
2051 mbHasCategoryLabels || bHasAxisProperties )
2053 if( bExportContent )
2055 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_DIMENSION, XML_X );
2056 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_NAME, XML_PRIMARY_X );
2058 // write style name
2059 AddAutoStyleAttribute( aPropertyStates );
2061 // element
2062 pAxis = new SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_AXIS, sal_True, sal_True );
2064 else // autostyles
2066 CollectAutoStyle( aPropertyStates );
2068 aPropertyStates.clear();
2070 // axis-title
2071 if( bHasXAxisTitle )
2073 Reference< beans::XPropertySet > xTitleProp( xAxisXSupp->getXAxisTitle(), uno::UNO_QUERY );
2074 if( xTitleProp.is())
2076 aPropertyStates = mxExpPropMapper->Filter( xTitleProp );
2077 if( bExportContent )
2079 OUString aText;
2080 Any aAny( xTitleProp->getPropertyValue(
2081 OUString( RTL_CONSTASCII_USTRINGPARAM( "String" ))));
2082 aAny >>= aText;
2084 Reference< drawing::XShape > xShape( xTitleProp, uno::UNO_QUERY );
2085 if( xShape.is())
2086 addPosition( xShape );
2088 AddAutoStyleAttribute( aPropertyStates );
2089 SvXMLElementExport aTitle( mrExport, XML_NAMESPACE_CHART, XML_TITLE, sal_True, sal_True );
2091 // paragraph containing title
2092 exportText( aText );
2094 else
2096 CollectAutoStyle( aPropertyStates );
2098 aPropertyStates.clear();
2102 // categories if we have a categories chart
2103 if( bExportContent &&
2104 mbHasCategoryLabels )
2106 OUString aCategoriesRange;
2107 // fill msString with cell-range-address of categories
2108 // export own table references
2109 if( xNewDiagram.is())
2111 Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xNewDiagram ) );
2112 if( xCategories.is() )
2114 Reference< chart2::data::XDataSequence > xValues( xCategories->getValues() );
2115 if( xValues.is())
2117 Reference< chart2::XChartDocument > xNewDoc( mrExport.GetModel(), uno::UNO_QUERY );
2118 aCategoriesRange = lcl_ConvertRange( xValues->getSourceRangeRepresentation(), xNewDoc );
2119 m_aDataSequencesToExport.push_back( tLabelValuesDataPair( 0, xValues ));
2124 if( aCategoriesRange.getLength())
2125 mrExport.AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, aCategoriesRange );
2126 SvXMLElementExport aCategories( mrExport, XML_NAMESPACE_CHART, XML_CATEGORIES, sal_True, sal_True );
2129 // grid
2130 Reference< beans::XPropertySet > xMajorGrid( xAxisXSupp->getXMainGrid(), uno::UNO_QUERY );
2131 if( bHasXAxisMajorGrid && xMajorGrid.is())
2133 aPropertyStates = mxExpPropMapper->Filter( xMajorGrid );
2134 if( bExportContent )
2136 AddAutoStyleAttribute( aPropertyStates );
2137 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS, XML_MAJOR );
2138 SvXMLElementExport aGrid( mrExport, XML_NAMESPACE_CHART, XML_GRID, sal_True, sal_True );
2140 else
2142 CollectAutoStyle( aPropertyStates );
2144 aPropertyStates.clear();
2146 Reference< beans::XPropertySet > xMinorGrid( xAxisXSupp->getXHelpGrid(), uno::UNO_QUERY );
2147 if( bHasXAxisMinorGrid && xMinorGrid.is())
2149 aPropertyStates = mxExpPropMapper->Filter( xMinorGrid );
2150 if( bExportContent )
2152 AddAutoStyleAttribute( aPropertyStates );
2153 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS, XML_MINOR );
2154 SvXMLElementExport aGrid( mrExport, XML_NAMESPACE_CHART, XML_GRID, sal_True, sal_True );
2156 else
2158 CollectAutoStyle( aPropertyStates );
2160 aPropertyStates.clear();
2162 if( pAxis )
2164 delete pAxis;
2165 pAxis = NULL;
2170 // secondary x axis
2171 if( bHasSecondaryXAxis || bHasSecondaryXAxisTitle )
2173 Reference< chart::XTwoAxisXSupplier > xAxisTwoXSupp( xDiagram, uno::UNO_QUERY );
2174 if( xAxisTwoXSupp.is())
2176 // get property states for autostyles
2177 if( mxExpPropMapper.is())
2179 xPropSet = xAxisTwoXSupp->getSecondaryXAxis();
2180 lcl_exportNumberFormat( sNumFormat, xPropSet, mrExport );
2181 if( xPropSet.is())
2182 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
2184 if( bExportContent )
2186 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_DIMENSION, XML_X );
2187 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_NAME, XML_SECONDARY_X );
2188 AddAutoStyleAttribute( aPropertyStates );
2189 pAxis = new SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_AXIS, sal_True, sal_True );
2191 else // autostyles
2193 CollectAutoStyle( aPropertyStates );
2195 aPropertyStates.clear();
2197 if( bHasSecondaryXAxisTitle )
2199 Reference< chart::XSecondAxisTitleSupplier > xAxisSupp( xDiagram, uno::UNO_QUERY );
2200 Reference< beans::XPropertySet > xTitleProp( xAxisSupp->getSecondXAxisTitle(), uno::UNO_QUERY );
2201 if( xTitleProp.is())
2203 aPropertyStates = mxExpPropMapper->Filter( xTitleProp );
2204 if( bExportContent )
2206 OUString aText;
2207 Any aAny( xTitleProp->getPropertyValue(
2208 OUString( RTL_CONSTASCII_USTRINGPARAM( "String" ))));
2209 aAny >>= aText;
2211 Reference< drawing::XShape > xShape( xTitleProp, uno::UNO_QUERY );
2212 if( xShape.is())
2213 addPosition( xShape );
2215 AddAutoStyleAttribute( aPropertyStates );
2216 SvXMLElementExport aTitle( mrExport, XML_NAMESPACE_CHART, XML_TITLE, sal_True, sal_True );
2218 exportText( aText );
2220 else
2222 CollectAutoStyle( aPropertyStates );
2224 aPropertyStates.clear();
2228 if( pAxis )
2230 delete pAxis;
2231 pAxis = NULL;
2236 // y axis
2237 // -------
2239 // write axis element also if the axis itself is not visible, but a grid or
2240 // title
2241 Reference< chart::XAxisYSupplier > xAxisYSupp( xDiagram, uno::UNO_QUERY );
2242 if( xAxisYSupp.is())
2244 bool bHasAxisProperties = false;
2245 // get property states for autostyles
2246 if( mxExpPropMapper.is())
2248 xPropSet = xAxisYSupp->getYAxis();
2249 if( xPropSet.is())
2251 bHasAxisProperties = true;
2252 lcl_exportNumberFormat( sNumFormat, xPropSet, mrExport );
2253 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
2257 if( bHasYAxis ||
2258 bHasYAxisTitle || bHasYAxisMajorGrid || bHasYAxisMinorGrid || bHasAxisProperties )
2260 if( bExportContent )
2262 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_DIMENSION, XML_Y );
2263 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_NAME, XML_PRIMARY_Y );
2264 AddAutoStyleAttribute( aPropertyStates );
2265 pAxis = new SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_AXIS, sal_True, sal_True );
2267 else
2269 CollectAutoStyle( aPropertyStates );
2271 aPropertyStates.clear();
2273 // axis-title
2274 if( bHasYAxisTitle )
2276 Reference< beans::XPropertySet > xTitleProp( xAxisYSupp->getYAxisTitle(), uno::UNO_QUERY );
2277 if( xTitleProp.is())
2279 aPropertyStates = mxExpPropMapper->Filter( xTitleProp );
2280 if( bExportContent )
2282 OUString aText;
2283 Any aAny( xTitleProp->getPropertyValue(
2284 OUString( RTL_CONSTASCII_USTRINGPARAM( "String" ))));
2285 aAny >>= aText;
2287 Reference< drawing::XShape > xShape( xTitleProp, uno::UNO_QUERY );
2288 if( xShape.is())
2289 addPosition( xShape );
2291 AddAutoStyleAttribute( aPropertyStates );
2292 SvXMLElementExport aTitle( mrExport, XML_NAMESPACE_CHART, XML_TITLE, sal_True, sal_True );
2294 // paragraph containing title
2295 exportText( aText );
2297 else
2299 CollectAutoStyle( aPropertyStates );
2301 aPropertyStates.clear();
2305 // grid
2306 Reference< beans::XPropertySet > xMajorGrid( xAxisYSupp->getYMainGrid(), uno::UNO_QUERY );
2307 if( bHasYAxisMajorGrid && xMajorGrid.is())
2309 aPropertyStates = mxExpPropMapper->Filter( xMajorGrid );
2311 if( bExportContent )
2313 AddAutoStyleAttribute( aPropertyStates );
2314 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS, XML_MAJOR );
2315 SvXMLElementExport aGrid( mrExport, XML_NAMESPACE_CHART, XML_GRID, sal_True, sal_True );
2317 else
2319 CollectAutoStyle( aPropertyStates );
2321 aPropertyStates.clear();
2323 // minor grid
2324 Reference< beans::XPropertySet > xMinorGrid( xAxisYSupp->getYHelpGrid(), uno::UNO_QUERY );
2325 if( bHasYAxisMinorGrid && xMinorGrid.is())
2327 aPropertyStates = mxExpPropMapper->Filter( xMinorGrid );
2329 if( bExportContent )
2331 AddAutoStyleAttribute( aPropertyStates );
2332 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS, XML_MINOR );
2333 SvXMLElementExport aGrid( mrExport, XML_NAMESPACE_CHART, XML_GRID, sal_True, sal_True );
2335 else
2337 CollectAutoStyle( aPropertyStates );
2339 aPropertyStates.clear();
2341 if( pAxis )
2343 delete pAxis;
2344 pAxis = NULL;
2349 if( bHasSecondaryYAxis || bHasSecondaryYAxisTitle )
2351 Reference< chart::XTwoAxisYSupplier > xAxisTwoYSupp( xDiagram, uno::UNO_QUERY );
2352 if( xAxisTwoYSupp.is())
2354 // get property states for autostyles
2355 if( mxExpPropMapper.is())
2357 xPropSet = xAxisTwoYSupp->getSecondaryYAxis();
2358 lcl_exportNumberFormat( sNumFormat, xPropSet, mrExport );
2359 if( xPropSet.is())
2360 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
2362 if( bExportContent )
2364 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_DIMENSION, XML_Y );
2365 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_NAME, XML_SECONDARY_Y );
2366 AddAutoStyleAttribute( aPropertyStates );
2367 pAxis = new SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_AXIS, sal_True, sal_True );
2369 else // autostyles
2371 CollectAutoStyle( aPropertyStates );
2373 aPropertyStates.clear();
2374 if( bHasSecondaryYAxisTitle )
2376 Reference< chart::XSecondAxisTitleSupplier > xAxisSupp( xDiagram, uno::UNO_QUERY );
2377 Reference< beans::XPropertySet > xTitleProp( xAxisSupp->getSecondYAxisTitle(), uno::UNO_QUERY );
2378 if( xTitleProp.is())
2380 aPropertyStates = mxExpPropMapper->Filter( xTitleProp );
2381 if( bExportContent )
2383 OUString aText;
2384 Any aAny( xTitleProp->getPropertyValue(
2385 OUString( RTL_CONSTASCII_USTRINGPARAM( "String" ))));
2386 aAny >>= aText;
2388 Reference< drawing::XShape > xShape( xTitleProp, uno::UNO_QUERY );
2389 if( xShape.is())
2390 addPosition( xShape );
2392 AddAutoStyleAttribute( aPropertyStates );
2393 SvXMLElementExport aTitle( mrExport, XML_NAMESPACE_CHART, XML_TITLE, sal_True, sal_True );
2395 exportText( aText );
2397 else
2399 CollectAutoStyle( aPropertyStates );
2401 aPropertyStates.clear();
2405 if( pAxis )
2407 delete pAxis;
2408 pAxis = NULL;
2413 // z axis
2414 // -------
2416 if( bHasZAxis &&
2417 bIs3DChart )
2419 Reference< chart::XAxisZSupplier > xAxisZSupp( xDiagram, uno::UNO_QUERY );
2420 if( xAxisZSupp.is())
2422 // get property states for autostyles
2423 if( mxExpPropMapper.is())
2425 xPropSet = xAxisZSupp->getZAxis();
2426 lcl_exportNumberFormat( sNumFormat, xPropSet, mrExport );
2427 if( xPropSet.is())
2428 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
2430 if( bExportContent )
2432 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_DIMENSION, XML_Z );
2433 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_NAME, XML_PRIMARY_Z );
2435 AddAutoStyleAttribute( aPropertyStates );
2436 pAxis = new SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_AXIS, sal_True, sal_True );
2438 else
2440 CollectAutoStyle( aPropertyStates );
2442 aPropertyStates.clear();
2444 // axis-title
2445 if( bHasZAxisTitle )
2447 Reference< beans::XPropertySet > xTitleProp( xAxisZSupp->getZAxisTitle(), uno::UNO_QUERY );
2448 if( xTitleProp.is())
2450 aPropertyStates = mxExpPropMapper->Filter( xTitleProp );
2451 if( bExportContent )
2453 OUString aText;
2454 Any aAny( xTitleProp->getPropertyValue(
2455 OUString( RTL_CONSTASCII_USTRINGPARAM( "String" ))));
2456 aAny >>= aText;
2458 Reference< drawing::XShape > xShape( xTitleProp, uno::UNO_QUERY );
2459 if( xShape.is())
2460 addPosition( xShape );
2462 AddAutoStyleAttribute( aPropertyStates );
2463 SvXMLElementExport aTitle( mrExport, XML_NAMESPACE_CHART, XML_TITLE, sal_True, sal_True );
2465 // paragraph containing title
2466 exportText( aText );
2468 else
2470 CollectAutoStyle( aPropertyStates );
2472 aPropertyStates.clear();
2476 // grid
2477 Reference< beans::XPropertySet > xMajorGrid( xAxisZSupp->getZMainGrid(), uno::UNO_QUERY );
2478 if( bHasZAxisMajorGrid && xMajorGrid.is())
2480 aPropertyStates = mxExpPropMapper->Filter( xMajorGrid );
2482 if( bExportContent )
2484 AddAutoStyleAttribute( aPropertyStates );
2485 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS, XML_MAJOR );
2486 SvXMLElementExport aGrid( mrExport, XML_NAMESPACE_CHART, XML_GRID, sal_True, sal_True );
2488 else
2490 CollectAutoStyle( aPropertyStates );
2492 aPropertyStates.clear();
2494 // minor grid
2495 Reference< beans::XPropertySet > xMinorGrid( xAxisZSupp->getZHelpGrid(), uno::UNO_QUERY );
2496 if( bHasZAxisMinorGrid && xMinorGrid.is())
2498 aPropertyStates = mxExpPropMapper->Filter( xMinorGrid );
2500 if( bExportContent )
2502 AddAutoStyleAttribute( aPropertyStates );
2503 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS, XML_MINOR );
2504 SvXMLElementExport aGrid( mrExport, XML_NAMESPACE_CHART, XML_GRID, sal_True, sal_True );
2506 else
2508 CollectAutoStyle( aPropertyStates );
2510 aPropertyStates.clear();
2513 if( pAxis )
2515 delete pAxis;
2516 pAxis = NULL;
2521 void SchXMLExportHelper::exportSeries(
2522 const Reference< chart2::XDiagram > & xNewDiagram,
2523 const awt::Size & rPageSize,
2524 sal_Bool bExportContent,
2525 sal_Bool bHasTwoYAxes )
2527 Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( xNewDiagram, uno::UNO_QUERY );
2528 if( ! xBCooSysCnt.is())
2529 return;
2530 Reference< chart2::XChartDocument > xNewDoc( mrExport.GetModel(), uno::UNO_QUERY );
2532 OUString aFirstXDomainRange;
2533 OUString aFirstYDomainRange;
2535 std::vector< XMLPropertyState > aPropertyStates;
2537 const OUString sNumFormat( OUString::createFromAscii( "NumberFormat" ));
2538 const OUString sPercentageNumFormat( OUString::createFromAscii( "PercentageNumberFormat" ));
2540 Sequence< Reference< chart2::XCoordinateSystem > >
2541 aCooSysSeq( xBCooSysCnt->getCoordinateSystems());
2542 for( sal_Int32 nCSIdx=0; nCSIdx<aCooSysSeq.getLength(); ++nCSIdx )
2544 Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCSIdx], uno::UNO_QUERY );
2545 if( ! xCTCnt.is())
2546 continue;
2547 Sequence< Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes());
2548 for( sal_Int32 nCTIdx=0; nCTIdx<aCTSeq.getLength(); ++nCTIdx )
2550 Reference< chart2::XDataSeriesContainer > xDSCnt( aCTSeq[nCTIdx], uno::UNO_QUERY );
2551 if( ! xDSCnt.is())
2552 continue;
2553 // note: if xDSCnt.is() then also aCTSeq[nCTIdx]
2554 OUString aChartType( aCTSeq[nCTIdx]->getChartType());
2555 OUString aLabelRole = aCTSeq[nCTIdx]->getRoleOfSequenceForSeriesLabel();
2557 // special export for stock charts
2558 if( aChartType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.CandleStickChartType")))
2560 sal_Bool bJapaneseCandleSticks = sal_False;
2561 Reference< beans::XPropertySet > xCTProp( aCTSeq[nCTIdx], uno::UNO_QUERY );
2562 if( xCTProp.is())
2563 xCTProp->getPropertyValue( OUString::createFromAscii("Japanese")) >>= bJapaneseCandleSticks;
2564 exportCandleStickSeries(
2565 xDSCnt->getDataSeries(), xNewDiagram, bJapaneseCandleSticks, bExportContent );
2566 continue;
2569 // export dataseries for current chart-type
2570 Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries());
2571 for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
2573 // export series
2574 Reference< chart2::data::XDataSource > xSource( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY );
2575 if( xSource.is())
2577 SvXMLElementExport* pSeries = NULL;
2578 Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
2579 xSource->getDataSequences());
2580 sal_Int32 nMainSequenceIndex = -1;
2581 sal_Int32 nSeriesLength = 0;
2582 sal_Int32 nAttachedAxis = chart::ChartAxisAssign::PRIMARY_Y;
2583 sal_Bool bHasMeanValueLine = false;
2584 chart::ChartRegressionCurveType eRegressionType( chart::ChartRegressionCurveType_NONE );
2585 chart::ChartErrorIndicatorType eErrorType( chart::ChartErrorIndicatorType_NONE );
2586 sal_Int32 nErrorBarStyle( chart::ErrorBarStyle::NONE );
2587 Reference< beans::XPropertySet > xPropSet;
2588 tLabelValuesDataPair aSeriesLabelValuesPair;
2590 // search for main sequence and create a series element
2592 Reference< chart2::data::XDataSequence > xValuesSeq;
2593 Reference< chart2::data::XDataSequence > xLabelSeq;
2594 sal_Int32 nSeqIdx=0;
2595 for( ; nSeqIdx<aSeqCnt.getLength(); ++nSeqIdx )
2597 OUString aRole;
2598 Reference< chart2::data::XDataSequence > xTempValueSeq( aSeqCnt[nSeqIdx]->getValues() );
2599 if( nMainSequenceIndex==-1 )
2601 Reference< beans::XPropertySet > xSeqProp( xTempValueSeq, uno::UNO_QUERY );
2602 if( xSeqProp.is())
2603 xSeqProp->getPropertyValue(OUString::createFromAscii("Role")) >>= aRole;
2604 // "main" sequence
2605 if( aRole.equals( aLabelRole ))
2607 xValuesSeq.set( xTempValueSeq );
2608 xLabelSeq.set( aSeqCnt[nSeqIdx]->getLabel());
2609 nMainSequenceIndex = nSeqIdx;
2612 sal_Int32 nSequenceLength = (xTempValueSeq.is()? xTempValueSeq->getData().getLength() : sal_Int32(0));
2613 if( nSeriesLength < nSequenceLength )
2614 nSeriesLength = nSequenceLength;
2617 // have found the main sequence, then xValuesSeq and
2618 // xLabelSeq contain those. Otherwise both are empty
2620 // get property states for autostyles
2623 xPropSet = SchXMLSeriesHelper::createOldAPISeriesPropertySet(
2624 aSeriesSeq[nSeriesIdx], mrExport.GetModel() );
2626 catch( uno::Exception & rEx )
2628 (void)rEx; // avoid warning for pro build
2629 OSL_TRACE(
2630 OUStringToOString(
2631 OUString( RTL_CONSTASCII_USTRINGPARAM(
2632 "Series not found or no XPropertySet: " )) +
2633 rEx.Message,
2634 RTL_TEXTENCODING_ASCII_US ).getStr());
2635 continue;
2637 if( xPropSet.is())
2639 // determine attached axis
2642 Any aAny( xPropSet->getPropertyValue(
2643 OUString( RTL_CONSTASCII_USTRINGPARAM( "Axis" ))));
2644 aAny >>= nAttachedAxis;
2646 aAny = xPropSet->getPropertyValue(
2647 OUString( RTL_CONSTASCII_USTRINGPARAM ( "MeanValue" )));
2648 aAny >>= bHasMeanValueLine;
2650 aAny = xPropSet->getPropertyValue(
2651 OUString( RTL_CONSTASCII_USTRINGPARAM( "RegressionCurves" )));
2652 aAny >>= eRegressionType;
2654 aAny = xPropSet->getPropertyValue(
2655 OUString( RTL_CONSTASCII_USTRINGPARAM( "ErrorIndicator" )));
2656 aAny >>= eErrorType;
2658 aAny = xPropSet->getPropertyValue(
2659 OUString( RTL_CONSTASCII_USTRINGPARAM( "ErrorBarStyle" )));
2660 aAny >>= nErrorBarStyle;
2662 catch( beans::UnknownPropertyException & rEx )
2664 (void)rEx; // avoid warning for pro build
2665 OSL_TRACE(
2666 OUStringToOString(
2667 OUString( RTL_CONSTASCII_USTRINGPARAM(
2668 "Required property not found in DataRowProperties: " )) +
2669 rEx.Message,
2670 RTL_TEXTENCODING_ASCII_US ).getStr());
2673 const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
2674 if( nCurrentODFVersion >= SvtSaveOptions::ODFVER_012 )
2676 lcl_exportNumberFormat( sNumFormat, xPropSet, mrExport );
2677 lcl_exportNumberFormat( sPercentageNumFormat, xPropSet, mrExport );
2680 if( mxExpPropMapper.is())
2681 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
2684 if( bExportContent )
2686 if( bHasTwoYAxes )
2688 if( nAttachedAxis == chart::ChartAxisAssign::SECONDARY_Y )
2689 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_SECONDARY_Y );
2690 else
2691 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_PRIMARY_Y );
2694 // write style name
2695 AddAutoStyleAttribute( aPropertyStates );
2697 if( xValuesSeq.is())
2698 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_VALUES_CELL_RANGE_ADDRESS,
2699 lcl_ConvertRange(
2700 xValuesSeq->getSourceRangeRepresentation(),
2701 xNewDoc ));
2702 else
2703 // #i75297# allow empty series, export empty range to have all ranges on import
2704 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_VALUES_CELL_RANGE_ADDRESS, OUString());
2706 if( xLabelSeq.is())
2707 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_LABEL_CELL_ADDRESS,
2708 lcl_ConvertRange(
2709 xLabelSeq->getSourceRangeRepresentation(),
2710 xNewDoc ));
2711 if( xLabelSeq.is() || xValuesSeq.is() )
2712 aSeriesLabelValuesPair = tLabelValuesDataPair( xLabelSeq, xValuesSeq );
2714 // chart-type for mixed types
2715 enum XMLTokenEnum eCTToken(
2716 SchXMLTools::getTokenByChartType( aChartType, false /* bUseOldNames */ ));
2717 //@todo: get token for current charttype
2718 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS,
2719 mrExport.GetNamespaceMap().GetQNameByKey(
2720 XML_NAMESPACE_CHART, GetXMLToken( eCTToken )));
2722 // open series element until end of for loop
2723 pSeries = new SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_SERIES, sal_True, sal_True );
2725 else // autostyles
2727 CollectAutoStyle( aPropertyStates );
2729 // remove property states for autostyles
2730 aPropertyStates.clear();
2734 // export domain elements if we have a series parent element
2735 if( pSeries )
2737 // domain elements
2738 if( bExportContent )
2740 bool bIsScatterChart = aChartType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.ScatterChartType"));
2741 bool bIsBubbleChart = aChartType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.BubbleChartType"));
2742 Reference< chart2::data::XDataSequence > xYValuesForBubbleChart;
2743 if( bIsBubbleChart )
2745 Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString::createFromAscii("values-y" ) ) );
2746 if( xSequence.is() )
2748 xYValuesForBubbleChart = xSequence->getValues();
2749 if( !lcl_exportDomainForThisSequence( xYValuesForBubbleChart, aFirstYDomainRange, mrExport ) )
2750 xYValuesForBubbleChart = 0;
2753 if( bIsScatterChart || bIsBubbleChart )
2755 Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString::createFromAscii("values-x" ) ) );
2756 if( xSequence.is() )
2758 Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() );
2759 if( lcl_exportDomainForThisSequence( xValues, aFirstXDomainRange, mrExport ) )
2760 m_aDataSequencesToExport.push_back( tLabelValuesDataPair( 0, xValues ));
2763 if( xYValuesForBubbleChart.is() )
2764 m_aDataSequencesToExport.push_back( tLabelValuesDataPair( 0, xYValuesForBubbleChart ));
2768 // add sequences for main sequence after domain sequences,
2769 // so that the export of the local table has the correct order
2770 if( bExportContent &&
2771 (aSeriesLabelValuesPair.first.is() || aSeriesLabelValuesPair.second.is()))
2772 m_aDataSequencesToExport.push_back( aSeriesLabelValuesPair );
2774 // statistical objects:
2775 // regression curves and mean value lines
2776 if( bHasMeanValueLine &&
2777 xPropSet.is() &&
2778 mxExpPropMapper.is() )
2780 Reference< beans::XPropertySet > xStatProp;
2783 Any aPropAny( xPropSet->getPropertyValue(
2784 OUString( RTL_CONSTASCII_USTRINGPARAM( "DataMeanValueProperties" ))));
2785 aPropAny >>= xStatProp;
2787 catch( uno::Exception & rEx )
2789 (void)rEx; // avoid warning for pro build
2790 DBG_ERROR1( "Exception caught during Export of series - optional DataMeanValueProperties not available: %s",
2791 OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
2794 if( xStatProp.is() )
2796 aPropertyStates = mxExpPropMapper->Filter( xStatProp );
2798 if( !aPropertyStates.empty() )
2800 // write element
2801 if( bExportContent )
2803 // add style name attribute
2804 AddAutoStyleAttribute( aPropertyStates );
2806 SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_MEAN_VALUE, sal_True, sal_True );
2808 else // autostyles
2810 CollectAutoStyle( aPropertyStates );
2816 if( eRegressionType != chart::ChartRegressionCurveType_NONE &&
2817 xPropSet.is() &&
2818 mxExpPropMapper.is() )
2820 exportRegressionCurve( aSeriesSeq[nSeriesIdx], xPropSet, rPageSize, bExportContent );
2823 if( nErrorBarStyle != chart::ErrorBarStyle::NONE &&
2824 eErrorType != chart::ChartErrorIndicatorType_NONE &&
2825 xPropSet.is() &&
2826 mxExpPropMapper.is() )
2828 Reference< beans::XPropertySet > xStatProp;
2831 Any aPropAny( xPropSet->getPropertyValue(
2832 OUString( RTL_CONSTASCII_USTRINGPARAM( "DataErrorProperties" ))));
2833 aPropAny >>= xStatProp;
2835 catch( uno::Exception & rEx )
2837 (void)rEx; // avoid warning for pro build
2838 DBG_ERROR1( "Exception caught during Export of series - optional DataErrorProperties not available: %s",
2839 OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
2842 if( xStatProp.is() )
2844 if( bExportContent &&
2845 nErrorBarStyle == chart::ErrorBarStyle::FROM_DATA )
2847 // register data ranges for error bars for export in local table
2848 ::std::vector< Reference< chart2::data::XDataSequence > > aErrorBarSequences(
2849 lcl_getErrorBarSequences( xStatProp ));
2850 for( ::std::vector< Reference< chart2::data::XDataSequence > >::const_iterator aIt(
2851 aErrorBarSequences.begin()); aIt != aErrorBarSequences.end(); ++aIt )
2853 m_aDataSequencesToExport.push_back( tLabelValuesDataPair( 0, *aIt ));
2857 aPropertyStates = mxExpPropMapper->Filter( xStatProp );
2859 if( !aPropertyStates.empty() )
2861 // write element
2862 if( bExportContent )
2864 // add style name attribute
2865 AddAutoStyleAttribute( aPropertyStates );
2866 SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_ERROR_INDICATOR, sal_True, sal_True );
2868 else // autostyles
2870 CollectAutoStyle( aPropertyStates );
2876 exportDataPoints(
2877 uno::Reference< beans::XPropertySet >( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY ),
2878 nSeriesLength, xNewDiagram, bExportContent );
2880 // close series element
2881 if( pSeries )
2882 delete pSeries;
2885 aPropertyStates.clear();
2890 void SchXMLExportHelper::exportRegressionCurve(
2891 const Reference< chart2::XDataSeries > & xSeries,
2892 const Reference< beans::XPropertySet > & xSeriesProp,
2893 const awt::Size & rPageSize,
2894 sal_Bool bExportContent )
2896 OSL_ASSERT( mxExpPropMapper.is());
2898 std::vector< XMLPropertyState > aPropertyStates;
2899 std::vector< XMLPropertyState > aEquationPropertyStates;
2900 Reference< beans::XPropertySet > xStatProp;
2903 Any aPropAny( xSeriesProp->getPropertyValue(
2904 OUString( RTL_CONSTASCII_USTRINGPARAM( "DataRegressionProperties" ))));
2905 aPropAny >>= xStatProp;
2907 catch( uno::Exception & rEx )
2909 (void)rEx; // avoid warning for pro build
2910 DBG_ERROR1( "Exception caught during Export of series - optional DataRegressionProperties not available: %s",
2911 OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
2914 if( xStatProp.is() )
2916 Reference< chart2::XRegressionCurve > xRegCurve( SchXMLTools::getRegressionCurve( xSeries ));
2917 Reference< beans::XPropertySet > xEquationProperties;
2918 if( xRegCurve.is())
2919 xEquationProperties.set( xRegCurve->getEquationProperties());
2921 bool bShowEquation = false;
2922 bool bShowRSquared = false;
2923 bool bExportEquation = false;
2924 aPropertyStates = mxExpPropMapper->Filter( xStatProp );
2925 if( xEquationProperties.is())
2927 xEquationProperties->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "ShowEquation" )))
2928 >>= bShowEquation;
2929 xEquationProperties->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "ShowCorrelationCoefficient" )))
2930 >>= bShowRSquared;
2931 bExportEquation = ( bShowEquation || bShowRSquared );
2932 const SvtSaveOptions::ODFDefaultVersion nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
2933 if( nCurrentVersion < SvtSaveOptions::ODFVER_012 )
2934 bExportEquation=false;
2935 if( bExportEquation )
2937 // number format
2938 sal_Int32 nNumberFormat = 0;
2939 if( ( xEquationProperties->getPropertyValue(
2940 OUString( RTL_CONSTASCII_USTRINGPARAM( "NumberFormat" ))) >>= nNumberFormat ) &&
2941 nNumberFormat != -1 )
2943 mrExport.addDataStyle( nNumberFormat );
2945 aEquationPropertyStates = mxExpPropMapper->Filter( xEquationProperties );
2949 if( !aPropertyStates.empty() || bExportEquation )
2951 // write element
2952 if( bExportContent )
2954 // add style name attribute
2955 if( !aPropertyStates.empty())
2956 AddAutoStyleAttribute( aPropertyStates );
2957 SvXMLElementExport aRegressionExport( mrExport, XML_NAMESPACE_CHART, XML_REGRESSION_CURVE, sal_True, sal_True );
2958 if( bExportEquation )
2960 // default is true
2961 if( !bShowEquation )
2962 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_DISPLAY_EQUATION, XML_FALSE );
2963 // default is false
2964 if( bShowRSquared )
2965 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_DISPLAY_R_SQUARE, XML_TRUE );
2967 // export position
2968 chart2::RelativePosition aRelativePosition;
2969 if( xEquationProperties->getPropertyValue(
2970 OUString( RTL_CONSTASCII_USTRINGPARAM("RelativePosition"))) >>= aRelativePosition )
2972 double fX = aRelativePosition.Primary * rPageSize.Width;
2973 double fY = aRelativePosition.Secondary * rPageSize.Height;
2974 awt::Point aPos;
2975 aPos.X = static_cast< sal_Int32 >( ::rtl::math::round( fX ));
2976 aPos.Y = static_cast< sal_Int32 >( ::rtl::math::round( fY ));
2977 addPosition( aPos );
2980 if( !aEquationPropertyStates.empty())
2981 AddAutoStyleAttribute( aEquationPropertyStates );
2983 SvXMLElementExport( mrExport, XML_NAMESPACE_CHART, XML_EQUATION, sal_True, sal_True );
2986 else // autostyles
2988 if( !aPropertyStates.empty())
2989 CollectAutoStyle( aPropertyStates );
2990 if( bExportEquation && !aEquationPropertyStates.empty())
2991 CollectAutoStyle( aEquationPropertyStates );
2997 void SchXMLExportHelper::exportCandleStickSeries(
2998 const Sequence< Reference< chart2::XDataSeries > > & aSeriesSeq,
2999 const Reference< chart2::XDiagram > & xDiagram,
3000 sal_Bool bJapaneseCandleSticks,
3001 sal_Bool bExportContent )
3003 // std::vector< XMLPropertyState > aPropertyStates;
3005 for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
3007 Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nSeriesIdx] );
3008 sal_Int32 nAttachedAxis = lcl_isSeriesAttachedToFirstAxis( xSeries )
3009 ? chart::ChartAxisAssign::PRIMARY_Y
3010 : chart::ChartAxisAssign::SECONDARY_Y;
3012 Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
3013 if( xSource.is())
3015 // export series in correct order (as we don't store roles)
3016 // with japanese candlesticks: open, low, high, close
3017 // otherwise: low, high, close
3018 Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
3019 xSource->getDataSequences());
3021 sal_Int32 nSeriesLength =
3022 lcl_getSequenceLengthByRole( aSeqCnt, OUString::createFromAscii("values-last"));
3024 if( bExportContent )
3026 Reference< chart2::XChartDocument > xNewDoc( mrExport.GetModel(), uno::UNO_QUERY );
3027 //@todo: export data points
3029 // open
3030 if( bJapaneseCandleSticks )
3032 tLabelAndValueRange aRanges( lcl_getLabelAndValueRangeByRole(
3033 aSeqCnt, OUString::createFromAscii("values-first"), xNewDoc, m_aDataSequencesToExport ));
3034 if( aRanges.second.getLength())
3035 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_VALUES_CELL_RANGE_ADDRESS, aRanges.second );
3036 if( aRanges.first.getLength())
3037 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_LABEL_CELL_ADDRESS, aRanges.first );
3038 if( nAttachedAxis == chart::ChartAxisAssign::SECONDARY_Y )
3039 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_SECONDARY_Y );
3040 else
3041 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_PRIMARY_Y );
3042 SvXMLElementExport aOpenSeries( mrExport, XML_NAMESPACE_CHART, XML_SERIES, sal_True, sal_True );
3043 // export empty data points
3044 exportDataPoints( 0, nSeriesLength, xDiagram, bExportContent );
3047 // low
3049 tLabelAndValueRange aRanges( lcl_getLabelAndValueRangeByRole(
3050 aSeqCnt, OUString::createFromAscii("values-min"), xNewDoc, m_aDataSequencesToExport ));
3051 if( aRanges.second.getLength())
3052 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_VALUES_CELL_RANGE_ADDRESS, aRanges.second );
3053 if( aRanges.first.getLength())
3054 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_LABEL_CELL_ADDRESS, aRanges.first );
3055 if( nAttachedAxis == chart::ChartAxisAssign::SECONDARY_Y )
3056 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_SECONDARY_Y );
3057 else
3058 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_PRIMARY_Y );
3059 SvXMLElementExport aLowSeries( mrExport, XML_NAMESPACE_CHART, XML_SERIES, sal_True, sal_True );
3060 // export empty data points
3061 exportDataPoints( 0, nSeriesLength, xDiagram, bExportContent );
3064 // high
3066 tLabelAndValueRange aRanges( lcl_getLabelAndValueRangeByRole(
3067 aSeqCnt, OUString::createFromAscii("values-max"), xNewDoc, m_aDataSequencesToExport ));
3068 if( aRanges.second.getLength())
3069 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_VALUES_CELL_RANGE_ADDRESS, aRanges.second );
3070 if( aRanges.first.getLength())
3071 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_LABEL_CELL_ADDRESS, aRanges.first );
3072 if( nAttachedAxis == chart::ChartAxisAssign::SECONDARY_Y )
3073 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_SECONDARY_Y );
3074 else
3075 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_PRIMARY_Y );
3076 SvXMLElementExport aHighSeries( mrExport, XML_NAMESPACE_CHART, XML_SERIES, sal_True, sal_True );
3077 // export empty data points
3078 exportDataPoints( 0, nSeriesLength, xDiagram, bExportContent );
3081 // close
3083 tLabelAndValueRange aRanges( lcl_getLabelAndValueRangeByRole(
3084 aSeqCnt, OUString::createFromAscii("values-last"), xNewDoc, m_aDataSequencesToExport ));
3085 if( aRanges.second.getLength())
3086 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_VALUES_CELL_RANGE_ADDRESS, aRanges.second );
3087 if( aRanges.first.getLength())
3088 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_LABEL_CELL_ADDRESS, aRanges.first );
3089 if( nAttachedAxis == chart::ChartAxisAssign::SECONDARY_Y )
3090 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_SECONDARY_Y );
3091 else
3092 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_ATTACHED_AXIS, XML_PRIMARY_Y );
3093 // write style name
3094 // AddAutoStyleAttribute( aPropertyStates );
3095 // chart type
3096 // mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_CLASS,
3097 // mrExport.GetNamespaceMap().GetQNameByKey(
3098 // XML_NAMESPACE_CHART, GetXMLToken( XML_STOCK )));
3099 SvXMLElementExport aCloseSeries( mrExport, XML_NAMESPACE_CHART, XML_SERIES, sal_True, sal_True );
3100 // export empty data points
3101 exportDataPoints( 0, nSeriesLength, xDiagram, bExportContent );
3104 else // autostyles
3106 // for close series
3107 // CollectAutoStyle( aPropertyStates );
3109 // remove property states for autostyles
3110 // aPropertyStates.clear();
3115 void SchXMLExportHelper::exportDataPoints(
3116 const uno::Reference< beans::XPropertySet > & xSeriesProperties,
3117 sal_Int32 nSeriesLength,
3118 const uno::Reference< chart2::XDiagram > & xDiagram,
3119 sal_Bool bExportContent )
3121 // data-points
3122 // -----------
3123 // write data-points only if they contain autostyles
3124 // objects with equal autostyles are grouped using the attribute
3125 // repeat="number"
3127 // Note: if only the nth data-point has autostyles there is an element
3128 // without style and repeat="n-1" attribute written in advance.
3130 // the sequence aDataPointSeq contains indices of data-points that
3131 // do have own attributes. This increases the performance substantially.
3133 // more performant version for #93600#
3134 if( mxExpPropMapper.is())
3136 uno::Reference< chart2::XDataSeries > xSeries( xSeriesProperties, uno::UNO_QUERY );
3138 std::vector< XMLPropertyState > aPropertyStates;
3140 const OUString sNumFormat( OUString::createFromAscii( "NumberFormat" ));
3141 const OUString sPercentageNumFormat( OUString::createFromAscii( "PercentageNumberFormat" ));
3143 bool bVaryColorsByPoint = false;
3144 Sequence< sal_Int32 > aDataPointSeq;
3145 if( xSeriesProperties.is())
3147 Any aAny = xSeriesProperties->getPropertyValue(
3148 OUString( RTL_CONSTASCII_USTRINGPARAM( "AttributedDataPoints" )));
3149 aAny >>= aDataPointSeq;
3150 xSeriesProperties->getPropertyValue(
3151 OUString( RTL_CONSTASCII_USTRINGPARAM( "VaryColorsByPoint" ))) >>= bVaryColorsByPoint;
3155 sal_Int32 nSize = aDataPointSeq.getLength();
3156 DBG_ASSERT( nSize <= nSeriesLength, "Too many point attributes" );
3158 const sal_Int32 * pPoints = aDataPointSeq.getConstArray();
3159 sal_Int32 nElement;
3160 sal_Int32 nRepeat;
3161 Reference< chart2::XColorScheme > xColorScheme;
3162 if( xDiagram.is())
3163 xColorScheme.set( xDiagram->getDefaultColorScheme());
3165 ::std::list< SchXMLDataPointStruct > aDataPointList;
3167 sal_Int32 nLastIndex = -1;
3168 sal_Int32 nCurrIndex = 0;
3170 // collect elements
3171 if( bVaryColorsByPoint && xColorScheme.is() )
3173 ::std::set< sal_Int32 > aAttrPointSet;
3174 ::std::copy( pPoints, pPoints + aDataPointSeq.getLength(),
3175 ::std::inserter( aAttrPointSet, aAttrPointSet.begin()));
3176 const ::std::set< sal_Int32 >::const_iterator aEndIt( aAttrPointSet.end());
3177 for( nElement = 0; nElement < nSeriesLength; ++nElement )
3179 aPropertyStates.clear();
3180 uno::Reference< beans::XPropertySet > xPropSet;
3181 bool bExportNumFmt = false;
3182 if( aAttrPointSet.find( nElement ) != aEndIt )
3186 xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
3187 xSeries, nElement, mrExport.GetModel() );
3188 bExportNumFmt = true;
3190 catch( uno::Exception & rEx )
3192 (void)rEx; // avoid warning for pro build
3193 DBG_ERROR1( "Exception caught during Export of data point: %s",
3194 OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
3197 else
3199 // property set only containing the color
3200 xPropSet.set( new ::xmloff::chart::ColorPropertySet(
3201 xColorScheme->getColorByIndex( nElement )));
3203 DBG_ASSERT( xPropSet.is(), "Pie Segments should have properties" );
3204 if( xPropSet.is())
3206 const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
3207 if( nCurrentODFVersion >= SvtSaveOptions::ODFVER_012 && bExportNumFmt )
3209 lcl_exportNumberFormat( sNumFormat, xPropSet, mrExport );
3210 lcl_exportNumberFormat( sPercentageNumFormat, xPropSet, mrExport );
3213 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
3214 if( !aPropertyStates.empty() )
3216 if( bExportContent )
3218 // write data-point with style
3219 DBG_ASSERT( ! maAutoStyleNameQueue.empty(), "Autostyle queue empty!" );
3221 SchXMLDataPointStruct aPoint;
3222 aPoint.maStyleName = maAutoStyleNameQueue.front();
3223 maAutoStyleNameQueue.pop();
3224 aDataPointList.push_back( aPoint );
3226 else
3228 CollectAutoStyle( aPropertyStates );
3233 DBG_ASSERT( !bExportContent || (static_cast<sal_Int32>(aDataPointList.size()) == nSeriesLength),
3234 "not enough data points on content export" );
3236 else
3238 for( nElement = 0; nElement < nSize; ++nElement )
3240 aPropertyStates.clear();
3241 nCurrIndex = pPoints[ nElement ];
3242 //assuming sorted indices in pPoints
3244 if( nCurrIndex<0 || nCurrIndex>=nSeriesLength )
3245 break;
3247 // write leading empty data points
3248 if( nCurrIndex - nLastIndex > 1 )
3250 SchXMLDataPointStruct aPoint;
3251 aPoint.mnRepeat = nCurrIndex - nLastIndex - 1;
3252 aDataPointList.push_back( aPoint );
3255 uno::Reference< beans::XPropertySet > xPropSet;
3256 // get property states
3259 xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
3260 xSeries, nCurrIndex, mrExport.GetModel() );
3262 catch( uno::Exception & rEx )
3264 (void)rEx; // avoid warning for pro build
3265 DBG_ERROR1( "Exception caught during Export of data point: %s",
3266 OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
3268 if( xPropSet.is())
3270 const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
3271 if( nCurrentODFVersion >= SvtSaveOptions::ODFVER_012 )
3273 lcl_exportNumberFormat( sNumFormat, xPropSet, mrExport );
3274 lcl_exportNumberFormat( sPercentageNumFormat, xPropSet, mrExport );
3277 aPropertyStates = mxExpPropMapper->Filter( xPropSet );
3278 if( !aPropertyStates.empty() )
3280 if( bExportContent )
3282 // write data-point with style
3283 DBG_ASSERT( ! maAutoStyleNameQueue.empty(), "Autostyle queue empty!" );
3284 SchXMLDataPointStruct aPoint;
3285 aPoint.maStyleName = maAutoStyleNameQueue.front();
3286 maAutoStyleNameQueue.pop();
3288 aDataPointList.push_back( aPoint );
3289 nLastIndex = nCurrIndex;
3291 else
3293 CollectAutoStyle( aPropertyStates );
3295 continue;
3299 // if we get here the property states are empty
3300 SchXMLDataPointStruct aPoint;
3301 aDataPointList.push_back( aPoint );
3303 nLastIndex = nCurrIndex;
3305 // final empty elements
3306 nRepeat = nSeriesLength - nLastIndex - 1;
3307 if( nRepeat > 0 )
3309 SchXMLDataPointStruct aPoint;
3310 aPoint.mnRepeat = nRepeat;
3311 aDataPointList.push_back( aPoint );
3315 if( bExportContent )
3317 // write elements (merge equal ones)
3318 ::std::list< SchXMLDataPointStruct >::iterator aIter = aDataPointList.begin();
3319 SchXMLDataPointStruct aPoint;
3320 SchXMLDataPointStruct aLastPoint;
3322 // initialize so that it doesn't matter if
3323 // the element is counted in the first iteration
3324 aLastPoint.mnRepeat = 0;
3326 for( ; aIter != aDataPointList.end(); ++aIter )
3328 aPoint = (*aIter);
3330 if( aPoint.maStyleName == aLastPoint.maStyleName )
3331 aPoint.mnRepeat += aLastPoint.mnRepeat;
3332 else if( aLastPoint.mnRepeat > 0 )
3334 // write last element
3335 if( aLastPoint.maStyleName.getLength() )
3336 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_STYLE_NAME, aLastPoint.maStyleName );
3338 if( aLastPoint.mnRepeat > 1 )
3339 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_REPEATED,
3340 OUString::valueOf( (sal_Int64)( aLastPoint.mnRepeat ) ));
3342 SvXMLElementExport aPointElem( mrExport, XML_NAMESPACE_CHART, XML_DATA_POINT, sal_True, sal_True );
3344 aLastPoint = aPoint;
3346 // write last element if it hasn't been written in last iteration
3347 if( aPoint.maStyleName == aLastPoint.maStyleName )
3349 if( aLastPoint.maStyleName.getLength() )
3350 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_STYLE_NAME, aLastPoint.maStyleName );
3352 if( aLastPoint.mnRepeat > 1 )
3353 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_REPEATED,
3354 OUString::valueOf( (sal_Int64)( aLastPoint.mnRepeat ) ));
3356 SvXMLElementExport aPointElem( mrExport, XML_NAMESPACE_CHART, XML_DATA_POINT, sal_True, sal_True );
3363 void SchXMLExportHelper::getCellAddress( sal_Int32 nCol, sal_Int32 nRow )
3365 msStringBuffer.append( (sal_Unicode)'.' );
3366 if( nCol < 26 )
3367 msStringBuffer.append( (sal_Unicode)('A' + nCol) );
3368 else if( nCol < 702 )
3370 msStringBuffer.append( (sal_Unicode)('A' + nCol / 26 - 1 ));
3371 msStringBuffer.append( (sal_Unicode)('A' + nCol % 26) );
3373 else
3375 msStringBuffer.append( (sal_Unicode)('A' + nCol / 702 - 1 ));
3376 msStringBuffer.append( (sal_Unicode)('A' + (nCol % 702) / 26 ));
3377 msStringBuffer.append( (sal_Unicode)('A' + nCol % 26) );
3380 msStringBuffer.append( nRow + (sal_Int32)1 );
3383 void SchXMLExportHelper::addPosition( const awt::Point & rPosition )
3385 mrExport.GetMM100UnitConverter().convertMeasure( msStringBuffer, rPosition.X );
3386 msString = msStringBuffer.makeStringAndClear();
3387 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X, msString );
3389 mrExport.GetMM100UnitConverter().convertMeasure( msStringBuffer, rPosition.Y );
3390 msString = msStringBuffer.makeStringAndClear();
3391 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y, msString );
3394 void SchXMLExportHelper::addPosition( Reference< drawing::XShape > xShape )
3396 if( xShape.is())
3397 addPosition( xShape->getPosition());
3400 void SchXMLExportHelper::addSize( const awt::Size & rSize )
3402 mrExport.GetMM100UnitConverter().convertMeasure( msStringBuffer, rSize.Width );
3403 msString = msStringBuffer.makeStringAndClear();
3404 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH, msString );
3406 mrExport.GetMM100UnitConverter().convertMeasure( msStringBuffer, rSize.Height );
3407 msString = msStringBuffer.makeStringAndClear();
3408 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_HEIGHT, msString );
3411 void SchXMLExportHelper::addSize( Reference< drawing::XShape > xShape )
3413 if( xShape.is())
3414 addSize( xShape->getSize() );
3417 awt::Size SchXMLExportHelper::getPageSize( const Reference< chart2::XChartDocument > & xChartDoc ) const
3419 awt::Size aSize( 8000, 7000 );
3420 uno::Reference< embed::XVisualObject > xVisualObject( xChartDoc, uno::UNO_QUERY );
3421 DBG_ASSERT( xVisualObject.is(),"need XVisualObject for page size" );
3422 if( xVisualObject.is() )
3423 aSize = xVisualObject->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
3425 return aSize;
3428 void SchXMLExportHelper::swapDataArray( Sequence< Sequence< double > >& rSequence )
3430 sal_Int32 nOuterSize = rSequence.getLength();
3431 sal_Int32 nInnerSize = rSequence[0].getLength(); // assume that all subsequences have same length
3432 sal_Int32 i, o;
3434 Sequence< Sequence< double > > aResult( nInnerSize );
3435 Sequence< double >* pArray = aResult.getArray();
3436 for( i = 0; i < nInnerSize; i++ )
3438 pArray[ i ].realloc( nOuterSize );
3439 for( o = 0 ; o < nOuterSize ; o++ )
3440 aResult[ i ][ o ] = rSequence[ o ][ i ];
3443 rSequence = aResult;
3446 void SchXMLExportHelper::CollectAutoStyle( const std::vector< XMLPropertyState >& aStates )
3448 if( !aStates.empty() )
3449 maAutoStyleNameQueue.push( GetAutoStylePoolP().Add( XML_STYLE_FAMILY_SCH_CHART_ID, aStates ));
3452 void SchXMLExportHelper::AddAutoStyleAttribute( const std::vector< XMLPropertyState >& aStates )
3454 if( !aStates.empty() )
3456 DBG_ASSERT( ! maAutoStyleNameQueue.empty(), "Autostyle queue empty!" );
3458 mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_STYLE_NAME, maAutoStyleNameQueue.front() );
3459 maAutoStyleNameQueue.pop();
3463 void SchXMLExportHelper::exportText( const OUString& rText, bool bConvertTabsLFs )
3465 SchXMLTools::exportText( mrExport, rText, bConvertTabsLFs );
3468 // ========================================
3469 // class SchXMLExport
3470 // ========================================
3472 // #110680#
3473 SchXMLExport::SchXMLExport(
3474 const Reference< lang::XMultiServiceFactory >& xServiceFactory,
3475 sal_uInt16 nExportFlags )
3476 : SvXMLExport( xServiceFactory, MAP_CM, ::xmloff::token::XML_CHART, nExportFlags ),
3477 maAutoStylePool( *this ),
3478 maExportHelper( *this, maAutoStylePool )
3483 SchXMLExport::~SchXMLExport()
3485 // stop progress view
3486 if( mxStatusIndicator.is())
3488 mxStatusIndicator->end();
3489 mxStatusIndicator->reset();
3493 sal_uInt32 SchXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum eClass )
3495 Reference< chart2::XChartDocument > xChartDoc( GetModel(), uno::UNO_QUERY );
3496 maExportHelper.InitRangeSegmentationProperties( xChartDoc );
3497 return SvXMLExport::exportDoc( eClass );
3500 void SchXMLExport::_ExportStyles( sal_Bool bUsed )
3502 SvXMLExport::_ExportStyles( bUsed );
3505 void SchXMLExport::_ExportMasterStyles()
3507 // not available in chart
3508 DBG_WARNING( "Master Style Export requested. Not available for Chart" );
3511 void SchXMLExport::_ExportAutoStyles()
3513 // there are no styles that require their own autostyles
3514 if( getExportFlags() & EXPORT_CONTENT )
3516 Reference< chart::XChartDocument > xChartDoc( GetModel(), uno::UNO_QUERY );
3517 if( xChartDoc.is())
3519 maExportHelper.collectAutoStyles( xChartDoc );
3520 maExportHelper.exportAutoStyles();
3522 else
3524 DBG_ERROR( "Couldn't export chart due to wrong XModel (must be XChartDocument)" );
3529 void SchXMLExport::_ExportContent()
3531 Reference< chart::XChartDocument > xChartDoc( GetModel(), uno::UNO_QUERY );
3532 if( xChartDoc.is())
3534 // determine if data comes from the outside
3535 sal_Bool bIncludeTable = sal_True;
3537 Reference< chart2::XChartDocument > xNewDoc( xChartDoc, uno::UNO_QUERY );
3538 if( xNewDoc.is())
3540 // check if we have own data. If so we must not export the complete
3541 // range string, as this is our only indicator for having own or
3542 // external data. @todo: fix this in the file format!
3543 Reference< lang::XServiceInfo > xDPServiceInfo( xNewDoc->getDataProvider(), uno::UNO_QUERY );
3544 if( ! (xDPServiceInfo.is() &&
3545 xDPServiceInfo->getImplementationName().equalsAsciiL(
3546 RTL_CONSTASCII_STRINGPARAM( "com.sun.star.comp.chart.InternalDataProvider" ))))
3548 bIncludeTable = sal_False;
3551 else
3553 Reference< lang::XServiceInfo > xServ( xChartDoc, uno::UNO_QUERY );
3554 if( xServ.is())
3556 if( xServ->supportsService(
3557 OUString::createFromAscii( "com.sun.star.chart.ChartTableAddressSupplier" )))
3559 Reference< beans::XPropertySet > xProp( xServ, uno::UNO_QUERY );
3560 if( xProp.is())
3562 Any aAny;
3565 OUString sChartAddress;
3566 aAny = xProp->getPropertyValue(
3567 OUString::createFromAscii( "ChartRangeAddress" ));
3568 aAny >>= sChartAddress;
3569 maExportHelper.SetChartRangeAddress( sChartAddress );
3571 OUString sTableNumberList;
3572 aAny = xProp->getPropertyValue(
3573 OUString::createFromAscii( "TableNumberList" ));
3574 aAny >>= sTableNumberList;
3575 maExportHelper.SetTableNumberList( sTableNumberList );
3577 // do not include own table if there are external addresses
3578 bIncludeTable = (sChartAddress.getLength() == 0);
3580 catch( beans::UnknownPropertyException & )
3582 DBG_ERROR( "Property ChartRangeAddress not supported by ChartDocument" );
3588 maExportHelper.exportChart( xChartDoc, bIncludeTable );
3590 else
3592 DBG_ERROR( "Couldn't export chart due to wrong XModel" );
3596 void SchXMLExport::SetProgress( sal_Int32 nPercentage )
3598 // set progress view
3599 if( mxStatusIndicator.is())
3600 mxStatusIndicator->setValue( nPercentage );
3603 void SchXMLExportHelper::InitRangeSegmentationProperties( const Reference< chart2::XChartDocument > & xChartDoc )
3605 if( xChartDoc.is())
3608 Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
3609 OSL_ENSURE( xDataProvider.is(), "No DataProvider" );
3610 if( xDataProvider.is())
3612 Reference< chart2::data::XDataSource > xDataSource( lcl_pressUsedDataIntoRectangularFormat( xChartDoc, mbHasCategoryLabels ));
3613 Sequence< beans::PropertyValue > aArgs( xDataProvider->detectArguments( xDataSource ));
3614 ::rtl::OUString sCellRange, sBrokenRange;
3615 bool bBrokenRangeAvailable = false;
3616 for( sal_Int32 i=0; i<aArgs.getLength(); ++i )
3618 if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CellRangeRepresentation")))
3619 aArgs[i].Value >>= sCellRange;
3620 else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("BrokenCellRangeForExport")))
3622 if( aArgs[i].Value >>= sBrokenRange )
3623 bBrokenRangeAvailable = true;
3625 else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DataRowSource")))
3627 chart::ChartDataRowSource eRowSource;
3628 aArgs[i].Value >>= eRowSource;
3629 mbRowSourceColumns = ( eRowSource == chart::ChartDataRowSource_COLUMNS );
3631 else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("FirstCellAsLabel")))
3632 aArgs[i].Value >>= mbHasSeriesLabels;
3633 else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("SequenceMapping")))
3634 aArgs[i].Value >>= maSequenceMapping;
3635 else if( aArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("TableNumberList")))
3636 aArgs[i].Value >>= msTableNumberList;
3639 // #i79009# For Writer we have to export a broken version of the
3640 // range, where every row number is noe too large, so that older
3641 // version can correctly read those files.
3642 msChartAddress = (bBrokenRangeAvailable ? sBrokenRange : sCellRange);
3643 if( msChartAddress.getLength() > 0 )
3645 // convert format to XML-conform one
3646 Reference< chart2::data::XRangeXMLConversion > xConversion( xDataProvider, uno::UNO_QUERY );
3647 if( xConversion.is())
3648 msChartAddress = xConversion->convertRangeToXML( msChartAddress );
3652 catch( uno::Exception & ex )
3654 (void)ex; // avoid warning for pro build
3655 OSL_ENSURE( false, OUStringToOString(
3656 OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
3657 OUString::createFromAscii( typeid( ex ).name()) +
3658 OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
3659 ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
3663 // export components ========================================
3665 // first version: everything goes in one storage
3667 Sequence< OUString > SAL_CALL SchXMLExport_getSupportedServiceNames() throw()
3669 const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLExporter" ) );
3670 const Sequence< OUString > aSeq( &aServiceName, 1 );
3671 return aSeq;
3674 OUString SAL_CALL SchXMLExport_getImplementationName() throw()
3676 return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Compact" ) );
3679 Reference< uno::XInterface > SAL_CALL SchXMLExport_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
3681 // #110680#
3682 // #103997# removed some flags from EXPORT_ALL
3683 // return (cppu::OWeakObject*)new SchXMLExport( EXPORT_ALL ^ ( EXPORT_SETTINGS | EXPORT_MASTERSTYLES | EXPORT_SCRIPTS ));
3684 return (cppu::OWeakObject*)new SchXMLExport( rSMgr, EXPORT_ALL ^ ( EXPORT_SETTINGS | EXPORT_MASTERSTYLES | EXPORT_SCRIPTS ));
3687 // Oasis format
3688 Sequence< OUString > SAL_CALL SchXMLExport_Oasis_getSupportedServiceNames() throw()
3690 const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisExporter" ) );
3691 const Sequence< OUString > aSeq( &aServiceName, 1 );
3692 return aSeq;
3695 OUString SAL_CALL SchXMLExport_Oasis_getImplementationName() throw()
3697 return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Oasis.Compact" ) );
3700 Reference< uno::XInterface > SAL_CALL SchXMLExport_Oasis_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
3702 // #103997# removed some flags from EXPORT_ALL
3703 return (cppu::OWeakObject*)new SchXMLExport( rSMgr,
3704 (EXPORT_ALL ^ ( EXPORT_SETTINGS | EXPORT_MASTERSTYLES | EXPORT_SCRIPTS )) | EXPORT_OASIS );
3707 // ============================================================
3709 // multiple storage version: one for content / styles / meta
3711 Sequence< OUString > SAL_CALL SchXMLExport_Styles_getSupportedServiceNames() throw()
3713 const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLStylesExporter" ));
3714 const Sequence< OUString > aSeq( &aServiceName, 1 );
3715 return aSeq;
3718 OUString SAL_CALL SchXMLExport_Styles_getImplementationName() throw()
3720 return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Styles" ));
3723 Reference< uno::XInterface > SAL_CALL SchXMLExport_Styles_createInstance(const Reference< lang::XMultiServiceFactory >& rSMgr) throw( uno::Exception )
3725 // #110680#
3726 // return (cppu::OWeakObject*)new SchXMLExport( EXPORT_STYLES );
3727 return (cppu::OWeakObject*)new SchXMLExport( rSMgr, EXPORT_STYLES );
3730 // Oasis format
3731 Sequence< OUString > SAL_CALL SchXMLExport_Oasis_Styles_getSupportedServiceNames() throw()
3733 const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisStylesExporter" ));
3734 const Sequence< OUString > aSeq( &aServiceName, 1 );
3735 return aSeq;
3738 OUString SAL_CALL SchXMLExport_Oasis_Styles_getImplementationName() throw()
3740 return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Oasis.Styles" ));
3743 Reference< uno::XInterface > SAL_CALL SchXMLExport_Oasis_Styles_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
3745 return (cppu::OWeakObject*)new SchXMLExport( rSMgr, EXPORT_STYLES | EXPORT_OASIS );
3748 // ------------------------------------------------------------
3750 Sequence< OUString > SAL_CALL SchXMLExport_Content_getSupportedServiceNames() throw()
3752 const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLContentExporter" ));
3753 const Sequence< OUString > aSeq( &aServiceName, 1 );
3754 return aSeq;
3757 OUString SAL_CALL SchXMLExport_Content_getImplementationName() throw()
3759 return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Content" ));
3762 Reference< uno::XInterface > SAL_CALL SchXMLExport_Content_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
3764 // #110680#
3765 // return (cppu::OWeakObject*)new SchXMLExport( EXPORT_AUTOSTYLES | EXPORT_CONTENT | EXPORT_FONTDECLS );
3766 return (cppu::OWeakObject*)new SchXMLExport( rSMgr, EXPORT_AUTOSTYLES | EXPORT_CONTENT | EXPORT_FONTDECLS );
3769 // Oasis format
3770 Sequence< OUString > SAL_CALL SchXMLExport_Oasis_Content_getSupportedServiceNames() throw()
3772 const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisContentExporter" ));
3773 const Sequence< OUString > aSeq( &aServiceName, 1 );
3774 return aSeq;
3777 OUString SAL_CALL SchXMLExport_Oasis_Content_getImplementationName() throw()
3779 return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Oasis.Content" ));
3782 Reference< uno::XInterface > SAL_CALL SchXMLExport_Oasis_Content_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
3784 return (cppu::OWeakObject*)new SchXMLExport( rSMgr, EXPORT_AUTOSTYLES | EXPORT_CONTENT | EXPORT_FONTDECLS | EXPORT_OASIS );
3787 // ------------------------------------------------------------
3789 // Sequence< OUString > SAL_CALL SchXMLExport_Meta_getSupportedServiceNames() throw()
3790 // {
3791 // const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLMetaExporter" ));
3792 // const Sequence< OUString > aSeq( &aServiceName, 1 );
3793 // return aSeq;
3794 // }
3796 // OUString SAL_CALL SchXMLExport_Meta_getImplementationName() throw()
3797 // {
3798 // return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Meta" ));
3799 // }
3801 // Reference< uno::XInterface > SAL_CALL SchXMLExport_Meta_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
3802 // {
3803 // return (cppu::OWeakObject*)new SchXMLExport( EXPORT_META );
3804 // }
3806 // Oasis format
3807 Sequence< OUString > SAL_CALL SchXMLExport_Oasis_Meta_getSupportedServiceNames() throw()
3809 const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisMetaExporter" ));
3810 const Sequence< OUString > aSeq( &aServiceName, 1 );
3811 return aSeq;
3814 OUString SAL_CALL SchXMLExport_Oasis_Meta_getImplementationName() throw()
3816 return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLExport.Oasis.Meta" ));
3819 Reference< uno::XInterface > SAL_CALL SchXMLExport_Oasis_Meta_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
3821 return (cppu::OWeakObject*)new SchXMLExport( rSMgr, EXPORT_META | EXPORT_OASIS );
3825 // XServiceInfo
3826 OUString SAL_CALL SchXMLExport::getImplementationName() throw( uno::RuntimeException )
3828 switch( getExportFlags())
3830 case EXPORT_ALL:
3831 return SchXMLExport_getImplementationName();
3832 case EXPORT_STYLES:
3833 return SchXMLExport_Styles_getImplementationName();
3834 case ( EXPORT_AUTOSTYLES | EXPORT_CONTENT | EXPORT_FONTDECLS ):
3835 return SchXMLExport_Content_getImplementationName();
3836 // case EXPORT_META:
3837 // return SchXMLExport_Meta_getImplementationName();
3839 // Oasis format
3840 case ( EXPORT_ALL | EXPORT_OASIS ):
3841 return SchXMLExport_Oasis_getImplementationName();
3842 case ( EXPORT_STYLES | EXPORT_OASIS ):
3843 return SchXMLExport_Oasis_Styles_getImplementationName();
3844 case ( EXPORT_AUTOSTYLES | EXPORT_CONTENT | EXPORT_FONTDECLS | EXPORT_OASIS ):
3845 return SchXMLExport_Oasis_Content_getImplementationName();
3846 case ( EXPORT_META | EXPORT_OASIS ):
3847 return SchXMLExport_Oasis_Meta_getImplementationName();
3849 case EXPORT_SETTINGS:
3850 // there is no settings component in chart
3851 default:
3852 return OUString::createFromAscii( "SchXMLExport" );