merge the formfield patch from ooo-build
[ooovba.git] / chart2 / source / controller / chartapiwrapper / ChartDataWrapper.cxx
blob482a22f58a38946574502e211b54ad0aeb317c87
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: ChartDataWrapper.cxx,v $
10 * $Revision: 1.8 $
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_chart2.hxx"
33 #include "ChartDataWrapper.hxx"
34 #include "macros.hxx"
35 #include "DiagramHelper.hxx"
36 #include "DataSourceHelper.hxx"
37 #include "servicenames_charttypes.hxx"
38 #include "ContainerHelper.hxx"
39 #include "CommonFunctors.hxx"
40 #include "ChartModelHelper.hxx"
41 #include "DataSeriesHelper.hxx"
42 #include "ControllerLockGuard.hxx"
43 #include "Chart2ModelContact.hxx"
44 #include <com/sun/star/beans/PropertyAttribute.hpp>
45 #include <com/sun/star/chart2/XTitled.hpp>
46 #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
47 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
48 #include <com/sun/star/chart2/data/XDataSource.hpp>
49 #include <com/sun/star/chart2/XDataSeries.hpp>
50 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
51 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
52 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
53 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
54 #include <com/sun/star/chart/ChartDataRowSource.hpp>
55 #include <com/sun/star/chart/XChartDocument.hpp>
57 #include "CharacterProperties.hxx"
58 #include "LineProperties.hxx"
59 #include "FillProperties.hxx"
61 #include <map>
62 #include <algorithm>
63 #include <rtl/math.hxx>
65 using namespace ::com::sun::star;
66 using ::com::sun::star::uno::Reference;
67 using ::osl::MutexGuard;
69 namespace
71 static const ::rtl::OUString lcl_aServiceName(
72 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.ChartData" ));
74 struct lcl_DataSequenceToDoubleSeq : public ::std::unary_function<
75 uno::Reference< chart2::data::XDataSequence >,
76 uno::Sequence< double > >
78 uno::Sequence< double > operator() ( const uno::Reference< chart2::data::XDataSequence > & xSeq )
80 uno::Reference< chart2::data::XNumericalDataSequence > xNumSeq( xSeq, uno::UNO_QUERY );
81 if( xNumSeq.is())
83 return xNumSeq->getNumericalData();
85 else if( xSeq.is())
87 uno::Sequence< uno::Any > aValues = xSeq->getData();
88 uno::Sequence< double > aResult( aValues.getLength());
89 const sal_Int32 nLength = aValues.getLength();
90 for( sal_Int32 i = 0; i < nLength; ++i )
92 if( ! ( aValues[ i ] >>= aResult[ i ]) )
94 aResult[ i ] = DBL_MIN;
96 double& rValue = aResult[ i ];
97 if( ::rtl::math::isNan( rValue ) )
98 rValue = DBL_MIN;
100 return aResult;
102 return uno::Sequence< double >();
106 void lcl_AddSequences( uno::Reference< chart2::data::XLabeledDataSequence > xLSeq,
107 ::std::vector< uno::Reference< chart2::data::XDataSequence > > & rOutSeqVector,
108 ::std::vector< ::rtl::OUString > & rOutLabelVector )
110 if( xLSeq.is() )
112 uno::Reference< chart2::data::XDataSequence > xSeq( xLSeq->getValues() );
113 rOutSeqVector.push_back( xSeq );
115 ::rtl::OUString aLabel( ::chart::DataSeriesHelper::getLabelForLabeledDataSequence( xLSeq ) );
116 rOutLabelVector.push_back( aLabel );
120 uno::Sequence< uno::Sequence< double > > lcl_getNANInsteadDBL_MIN( const uno::Sequence< uno::Sequence< double > >& rData )
122 uno::Sequence< uno::Sequence< double > > aRet;
123 const sal_Int32 nOuterSize = rData.getLength();
124 aRet.realloc( nOuterSize );
125 for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter )
127 sal_Int32 nInnerSize = rData[nOuter].getLength();
128 aRet[nOuter].realloc( nInnerSize );
129 for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner )
131 aRet[nOuter][nInner] = rData[nOuter][nInner];
132 double& rValue = aRet[nOuter][nInner];
133 if( rValue == DBL_MIN )
134 ::rtl::math::setNan( &rValue );
137 return aRet;
140 uno::Sequence< uno::Sequence< double > > lcl_getDBL_MINInsteadNAN( const uno::Sequence< uno::Sequence< double > >& rData )
142 uno::Sequence< uno::Sequence< double > > aRet;
143 const sal_Int32 nOuterSize = rData.getLength();
144 aRet.realloc( nOuterSize );
145 for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter )
147 sal_Int32 nInnerSize = rData[nOuter].getLength();
148 aRet[nOuter].realloc( nInnerSize );
149 for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner )
151 aRet[nOuter][nInner] = rData[nOuter][nInner];
152 double& rValue = aRet[nOuter][nInner];
153 if( ::rtl::math::isNan( rValue ) )
154 rValue = DBL_MIN;
157 return aRet;
160 } // anonymous namespace
162 // --------------------------------------------------------------------------------
164 namespace chart
166 namespace wrapper
169 ChartDataWrapper::ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact ) :
170 m_spChart2ModelContact( spChart2ModelContact ),
171 m_aEventListenerContainer( m_aMutex )
173 refreshData();
176 ChartDataWrapper::~ChartDataWrapper()
178 // @todo: implement XComponent and call this in dispose(). In the DTOR the
179 // ref-count is 0, thus creating a stack reference to this calls the DTOR at
180 // the end of the block recursively
181 // uno::Reference< uno::XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
182 // m_aEventListenerContainer.disposeAndClear( lang::EventObject( xSource ) );
185 // ____ XChartDataArray ____
186 uno::Sequence< uno::Sequence< double > > SAL_CALL ChartDataWrapper::getData()
187 throw (uno::RuntimeException)
189 // until we have a data change notification mechanism we always have to
190 // update the data here
191 refreshData();
192 // /--
193 MutexGuard aGuard( GetMutex());
194 return m_aData;
195 // \--
198 void SAL_CALL ChartDataWrapper::setData(
199 const uno::Sequence< uno::Sequence< double > >& aData )
200 throw (uno::RuntimeException)
202 refreshData();
204 // /--
205 MutexGuard aGuard( GetMutex());
206 m_aData = aData;
207 // \--
209 applyData( true, false, false );
212 uno::Sequence< ::rtl::OUString > SAL_CALL ChartDataWrapper::getRowDescriptions()
213 throw (uno::RuntimeException)
215 // until we have a data change notification mechanism we always have to
216 // update the data here
217 refreshData();
219 // /--
220 MutexGuard aGuard( GetMutex());
221 return m_aRowDescriptions;
222 // \--
225 void SAL_CALL ChartDataWrapper::setRowDescriptions(
226 const uno::Sequence< ::rtl::OUString >& aRowDescriptions )
227 throw (uno::RuntimeException)
229 refreshData();
231 // /--
232 MutexGuard aGuard( GetMutex());
233 m_aRowDescriptions = aRowDescriptions;
234 // \--
236 applyData( false, true, false );
239 uno::Sequence<
240 ::rtl::OUString > SAL_CALL ChartDataWrapper::getColumnDescriptions()
241 throw (uno::RuntimeException)
243 // until we have a data change notification mechanism we always have to
244 // update the data here
245 refreshData();
246 // /--
247 MutexGuard aGuard( GetMutex());
248 return m_aColumnDescriptions;
249 // \--
252 void SAL_CALL ChartDataWrapper::setColumnDescriptions(
253 const uno::Sequence< ::rtl::OUString >& aColumnDescriptions )
254 throw (uno::RuntimeException)
256 refreshData();
258 // /--
259 MutexGuard aGuard( GetMutex());
260 m_aColumnDescriptions = aColumnDescriptions;
261 // \--
263 applyData( false, false, true );
267 // ____ XChartData (base of XChartDataArray) ____
268 void SAL_CALL ChartDataWrapper::addChartDataChangeEventListener(
269 const uno::Reference<
270 ::com::sun::star::chart::XChartDataChangeEventListener >& aListener )
271 throw (uno::RuntimeException)
273 m_aEventListenerContainer.addInterface( aListener );
276 void SAL_CALL ChartDataWrapper::removeChartDataChangeEventListener(
277 const uno::Reference<
278 ::com::sun::star::chart::XChartDataChangeEventListener >& aListener )
279 throw (uno::RuntimeException)
281 m_aEventListenerContainer.removeInterface( aListener );
284 double SAL_CALL ChartDataWrapper::getNotANumber()
285 throw (uno::RuntimeException)
287 return DBL_MIN;
290 sal_Bool SAL_CALL ChartDataWrapper::isNotANumber( double nNumber )
291 throw (uno::RuntimeException)
293 return DBL_MIN == nNumber
294 || ::rtl::math::isNan( nNumber )
295 || ::rtl::math::isInf( nNumber );
298 // ____ XComponent ____
299 void SAL_CALL ChartDataWrapper::dispose()
300 throw (uno::RuntimeException)
302 m_aEventListenerContainer.disposeAndClear( lang::EventObject( static_cast< ::cppu::OWeakObject* >( this )));
304 // /--
305 MutexGuard aGuard( GetMutex());
306 m_aData.realloc( 0 );
307 m_aColumnDescriptions.realloc( 0 );
308 m_aRowDescriptions.realloc( 0 );
309 // \--
312 void SAL_CALL ChartDataWrapper::addEventListener(
313 const uno::Reference< lang::XEventListener > & xListener )
314 throw (uno::RuntimeException)
316 m_aEventListenerContainer.addInterface( xListener );
319 void SAL_CALL ChartDataWrapper::removeEventListener(
320 const uno::Reference< lang::XEventListener >& aListener )
321 throw (uno::RuntimeException)
323 m_aEventListenerContainer.removeInterface( aListener );
326 // ____ XEventListener ____
327 void SAL_CALL ChartDataWrapper::disposing( const lang::EventObject& /* Source */ )
328 throw (uno::RuntimeException)
332 // ::com::sun::star::chart::ChartDataChangeEvent aEvent;
333 // aEvent.Type = chart::ChartDataChangeType_ALL;
334 // aEvent.StartColumn = 0;
335 // aEvent.EndColumn = 0;
336 // aEvent.StartRow = 0;
337 // aEvent.EndRow = 0;
338 void ChartDataWrapper::fireChartDataChangeEvent(
339 ::com::sun::star::chart::ChartDataChangeEvent& aEvent )
341 if( ! m_aEventListenerContainer.getLength() )
342 return;
344 uno::Reference< uno::XInterface > xSrc( static_cast< cppu::OWeakObject* >( this ));
345 OSL_ASSERT( xSrc.is());
346 if( xSrc.is() )
347 aEvent.Source = xSrc;
349 ::cppu::OInterfaceIteratorHelper aIter( m_aEventListenerContainer );
351 while( aIter.hasMoreElements() )
353 uno::Reference<
354 ::com::sun::star::chart::XChartDataChangeEventListener > xListener(
355 aIter.next(), uno::UNO_QUERY );
356 xListener->chartDataChanged( aEvent );
360 void ChartDataWrapper::refreshData()
362 //todo mutex...
363 Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
364 if( !xChartDoc.is() )
365 return;
366 if( xChartDoc->hasInternalDataProvider())
368 try {
369 uno::Reference< ::com::sun::star::chart::XChartDataArray > xInternalData( xChartDoc->getDataProvider(), uno::UNO_QUERY_THROW );
370 m_aColumnDescriptions = xInternalData->getColumnDescriptions();
371 m_aRowDescriptions = xInternalData->getRowDescriptions();
372 m_aData = lcl_getDBL_MINInsteadNAN( xInternalData->getData() );
374 catch( const uno::Exception & ex ) {
375 ASSERT_EXCEPTION( ex );
378 else
380 uno::Reference< chart2::XDiagram > xDia(
381 xChartDoc->getFirstDiagram() );
382 if( ! xDia.is())
383 return;
385 // get information about the segmentation of the assumed "rectangular" data
386 // range
387 ::rtl::OUString aRangeString;
388 bool bUseColumns = true;
389 bool bFirstCellAsLabel = true;
390 bool bHasCategories = true;
391 uno::Sequence< sal_Int32 > aSequenceMapping;
393 DataSourceHelper::detectRangeSegmentation(
394 uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ),
395 aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories );
398 // get data values from data series
399 // --------------------------------
400 uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledSequences;
401 uno::Reference< chart2::data::XDataSource > xRectangularDataSource(
402 DataSourceHelper::pressUsedDataIntoRectangularFormat( xChartDoc, false /*bWithCategories*/ ) );
403 if( xRectangularDataSource.is() )
405 aLabeledSequences = xRectangularDataSource->getDataSequences();
408 ::std::vector< uno::Reference< chart2::data::XDataSequence > > aSequenceVector;
409 ::std::vector< ::rtl::OUString > aLabelVector;
410 for( sal_Int32 nN=0; nN<aLabeledSequences.getLength(); nN++ )
411 lcl_AddSequences( aLabeledSequences[nN], aSequenceVector, aLabelVector );
413 if( aSequenceMapping.getLength() )
415 //aSequenceVector and aLabelVector contain changed positions; resort them to the original position
416 ::std::vector< uno::Reference< chart2::data::XDataSequence > > aBackSortedSequences;
417 ::std::vector< ::rtl::OUString > aBackSortedLabels;
419 std::map< sal_Int32, sal_Int32 > aReverseMap;
421 sal_Int32 nNewIndex, nOldIndex;
422 for( sal_Int32 nS=0; nS <aSequenceMapping.getLength(); nS++ )
424 nOldIndex = aSequenceMapping[nS];
425 nNewIndex = nS;
426 if( bHasCategories )
427 nNewIndex--;
428 if( nOldIndex >= 0 && nNewIndex >= 0 )
429 aReverseMap[nOldIndex] = nNewIndex;
433 std::map< sal_Int32, sal_Int32 >::iterator aMapIt = aReverseMap.begin();
434 std::map< sal_Int32, sal_Int32 >::const_iterator aMapEnd = aReverseMap.end();
436 for( ; aMapIt != aMapEnd; ++aMapIt )
438 size_t nNewIndex = static_cast< size_t >( aMapIt->second );
439 if( nNewIndex < aSequenceVector.size() )
440 aBackSortedSequences.push_back( aSequenceVector[nNewIndex] );
441 if( nNewIndex < aLabelVector.size() )
442 aBackSortedLabels.push_back( aLabelVector[nNewIndex] );
445 // note: assign( beg, end ) doesn't work on solaris
446 aSequenceVector.clear();
447 aSequenceVector.insert(
448 aSequenceVector.begin(), aBackSortedSequences.begin(), aBackSortedSequences.end() );
449 aLabelVector.clear();
450 aLabelVector.insert(
451 aLabelVector.begin(), aBackSortedLabels.begin(), aBackSortedLabels.end() );
454 if( bUseColumns )
456 const sal_Int32 nInnerSize = aSequenceVector.size();
457 if( nInnerSize > 0 && aSequenceVector[0].is() )
459 // take the length of the first data series also as length for all
460 // other series
461 const sal_Int32 nOuterSize = aSequenceVector[0]->getData().getLength();
463 m_aData.realloc( nOuterSize );
464 for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter )
465 m_aData[nOuter].realloc( nInnerSize );
467 for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner )
469 uno::Sequence< double > aValues = uno::Sequence< double > (
470 lcl_DataSequenceToDoubleSeq() (aSequenceVector[nInner] ));
471 sal_Int32 nMax = ::std::min( nOuterSize, aValues.getLength());
472 for( sal_Int32 nOuter=0; nOuter<nMax; ++nOuter )
473 m_aData[nOuter][nInner] = aValues[nOuter];
477 else
479 m_aData.realloc( static_cast< sal_Int32 >( aSequenceVector.size()));
480 ::std::transform( aSequenceVector.begin(), aSequenceVector.end(),
481 m_aData.getArray(),
482 lcl_DataSequenceToDoubleSeq() );
485 // labels (values already filled during parsing of data values)
486 if( bUseColumns )
487 m_aColumnDescriptions = ::chart::ContainerHelper::ContainerToSequence( aLabelVector );
488 else
489 m_aRowDescriptions = ::chart::ContainerHelper::ContainerToSequence( aLabelVector );
491 // get row-/column descriptions
492 // ----------------------------
493 // categories
494 uno::Sequence< ::rtl::OUString > & rSequence =
495 bUseColumns ? m_aRowDescriptions : m_aColumnDescriptions;
496 rSequence = DiagramHelper::generateAutomaticCategories( xChartDoc );
500 void ChartDataWrapper::applyData( bool bSetValues, bool bSetRowDescriptions, bool bSetColumnDescriptions )
502 Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
503 if( !xChartDoc.is() )
504 return;
506 // /-- locked controllers
507 ControllerLockGuard aCtrlLockGuard( uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ));
508 // should do nothing if we already have an internal data provider
509 xChartDoc->createInternalDataProvider( sal_True /* bCloneExistingData */ );
511 uno::Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider());
512 uno::Reference< XChartDataArray > xDocDataArray( xDataProvider, uno::UNO_QUERY );
514 // remember some diagram properties to reset later
515 sal_Bool bStacked = sal_False;
516 sal_Bool bPercent = sal_False;
517 sal_Bool bDeep = sal_False;
518 uno::Reference< ::com::sun::star::chart::XChartDocument > xOldDoc( xChartDoc, uno::UNO_QUERY );
519 OSL_ASSERT( xOldDoc.is());
520 uno::Reference< beans::XPropertySet > xDiaProp( xOldDoc->getDiagram(), uno::UNO_QUERY );
521 if( xDiaProp.is())
523 xDiaProp->getPropertyValue( C2U("Stacked")) >>= bStacked;
524 xDiaProp->getPropertyValue( C2U("Percent")) >>= bPercent;
525 xDiaProp->getPropertyValue( C2U("Deep")) >>= bDeep;
528 //detect arguments for the new data source
529 ::rtl::OUString aRangeString;
530 bool bUseColumns = true;
531 bool bFirstCellAsLabel = true;
532 bool bHasCategories = true;
533 uno::Sequence< sal_Int32 > aSequenceMapping;
535 DataSourceHelper::detectRangeSegmentation(
536 uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ),
537 aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories );
539 if( !bFirstCellAsLabel )
541 if( bSetRowDescriptions && !bUseColumns )
542 bFirstCellAsLabel = true;
543 else if( bSetColumnDescriptions && bUseColumns )
544 bFirstCellAsLabel = true;
546 if( !bHasCategories )
548 if( bSetColumnDescriptions && bUseColumns )
549 bHasCategories = true;
550 else if( bSetRowDescriptions && !bUseColumns )
551 bHasCategories = true;
554 aRangeString = C2U("all");
555 uno::Sequence< beans::PropertyValue > aArguments( DataSourceHelper::createArguments(
556 aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories ) );
558 // create and attach new data source
559 uno::Reference< chart2::data::XDataSource > xSource;
560 if( xDocDataArray.is() )
562 // we have an internal data provider that supports the XChartDataArray
563 // interface
564 if( bSetValues )
565 xDocDataArray->setData( lcl_getNANInsteadDBL_MIN( m_aData ) );
566 if( bSetRowDescriptions )
567 xDocDataArray->setRowDescriptions( m_aRowDescriptions );
568 if( bSetColumnDescriptions )
569 xDocDataArray->setColumnDescriptions( m_aColumnDescriptions );
571 xSource.set( xDataProvider->createDataSource( aArguments ));
573 else
575 uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY );
576 OSL_ASSERT( xChartDoc.is());
577 OSL_ASSERT( xReceiver.is());
578 if( ! (xChartDoc.is() && xReceiver.is()))
579 return;
581 // create a data provider containing the new data
582 uno::Reference< chart2::data::XDataProvider > xTempDataProvider(
583 ChartModelHelper::createInternalDataProvider() );
584 if( ! xTempDataProvider.is())
585 throw uno::RuntimeException( C2U("Couldn't create temporary data provider"),
586 static_cast< ::cppu::OWeakObject * >( this ));
588 uno::Reference< ::com::sun::star::chart::XChartDataArray > xDataArray( xTempDataProvider, uno::UNO_QUERY );
589 OSL_ASSERT( xDataArray.is());
590 if( xDataArray.is())
592 if( bSetValues )
593 xDataArray->setData( lcl_getNANInsteadDBL_MIN( m_aData ) );
594 if( bSetRowDescriptions )
595 xDataArray->setRowDescriptions( m_aRowDescriptions );
596 if( bSetColumnDescriptions )
597 xDataArray->setColumnDescriptions( m_aColumnDescriptions );
599 // removes existing data provider and attaches the new one
600 xReceiver->attachDataProvider( xTempDataProvider );
601 xSource.set( xTempDataProvider->createDataSource( aArguments));
605 // determine a template
606 uno::Reference< lang::XMultiServiceFactory > xFact( xChartDoc->getChartTypeManager(), uno::UNO_QUERY );
607 uno::Reference< chart2::XDiagram > xDia( xChartDoc->getFirstDiagram());
608 DiagramHelper::tTemplateWithServiceName aTemplateAndService =
609 DiagramHelper::getTemplateForDiagram( xDia, xFact );
610 ::rtl::OUString aServiceName( aTemplateAndService.second );
611 uno::Reference< chart2::XChartTypeTemplate > xTemplate = aTemplateAndService.first;
613 // (fall-back)
614 if( ! xTemplate.is())
616 if( aServiceName.getLength() == 0 )
617 aServiceName = C2U("com.sun.star.chart2.template.Column");
618 xTemplate.set( xFact->createInstance( aServiceName ), uno::UNO_QUERY );
620 OSL_ASSERT( xTemplate.is());
622 if( xTemplate.is() && xSource.is())
624 // argument detection works with internal knowledge of the
625 // ArrayDataProvider
626 OSL_ASSERT( xDia.is());
627 xTemplate->changeDiagramData(
628 xDia, xSource, aArguments );
631 //correct stacking mode
632 if( bStacked || bPercent || bDeep )
634 StackMode eStackMode = StackMode_Y_STACKED;
635 if( bDeep )
636 eStackMode = StackMode_Z_STACKED;
637 else if( bPercent )
638 eStackMode = StackMode_Y_STACKED_PERCENT;
639 DiagramHelper::setStackMode( xDia, eStackMode );
642 // notify listeners
643 ::com::sun::star::chart::ChartDataChangeEvent aEvent(
644 static_cast< ::cppu::OWeakObject* >( this ),
645 ::com::sun::star::chart::ChartDataChangeType_ALL, 0, 0, 0, 0 );
646 fireChartDataChangeEvent( aEvent );
647 // \-- locked controllers
650 // --------------------------------------------------------------------------------
652 uno::Sequence< ::rtl::OUString > ChartDataWrapper::getSupportedServiceNames_Static()
654 uno::Sequence< ::rtl::OUString > aServices( 2 );
655 aServices[ 0 ] = C2U( "com.sun.star.chart.ChartDataArray" );
656 aServices[ 1 ] = C2U( "com.sun.star.chart.ChartData" );
658 return aServices;
661 // ================================================================================
663 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
664 APPHELPER_XSERVICEINFO_IMPL( ChartDataWrapper, lcl_aServiceName );
666 } // namespace wrapper
667 } // namespace chart