Files
libreoffice/chart2/source/controller/chartapiwrapper/ChartDataWrapper.cxx
Rüdiger Timm 14e57f1329 INTEGRATION: CWS chart07 (1.5.12); FILE MERGED
2007/07/02 21:34:07 bm 1.5.12.2: #i78873# fire event listeners when data changes
2007/06/26 09:57:04 bm 1.5.12.1: #i78785# fix for (broken) gcc 3.3 for Mac OS/X Panther applied
2007-07-25 07:26:21 +00:00

703 lines
25 KiB
C++

/*************************************************************************
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: ChartDataWrapper.cxx,v $
*
* $Revision: 1.6 $
*
* last change: $Author: rt $ $Date: 2007-07-25 08:26:21 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2005 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"
#include "ChartDataWrapper.hxx"
#include "macros.hxx"
#include "DiagramHelper.hxx"
#include "DataSourceHelper.hxx"
#include "servicenames_charttypes.hxx"
#include "ContainerHelper.hxx"
#include "CommonFunctors.hxx"
#include "InternalDataProvider.hxx"
#include "DataSeriesHelper.hxx"
#include "ControllerLockGuard.hxx"
#include "Chart2ModelContact.hxx"
#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
#include <com/sun/star/beans/PropertyAttribute.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XTITLED_HPP_
#include <com/sun/star/chart2/XTitled.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_DATA_XNUMERICALDATASEQUENCE_HPP_
#include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_DATA_XTEXTUALDATASEQUENCE_HPP_
#include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_DATA_XDATASOURCE_HPP_
#include <com/sun/star/chart2/data/XDataSource.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XDATASERIES_HPP_
#include <com/sun/star/chart2/XDataSeries.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XDATASERIESCONTAINER_HPP_
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XCOORDINATESYSTEMCONTAINER_HPP_
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XCHARTTYPECONTAINER_HPP_
#include <com/sun/star/chart2/XChartTypeContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_DATA_XDATARECEIVER_HPP_
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART_CHARTDATAROWSOURCE_HPP_
#include <com/sun/star/chart/ChartDataRowSource.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART_XCHARTDOCUMENT_HPP_
#include <com/sun/star/chart/XChartDocument.hpp>
#endif
#include "CharacterProperties.hxx"
#include "LineProperties.hxx"
#include "FillProperties.hxx"
#include <map>
#include <algorithm>
#ifndef INCLUDED_RTL_MATH_HXX
#include <rtl/math.hxx>
#endif
using namespace ::com::sun::star;
using ::com::sun::star::uno::Reference;
using ::osl::MutexGuard;
namespace
{
static const ::rtl::OUString lcl_aServiceName(
RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.ChartData" ));
struct lcl_DataSequenceToDoubleSeq : public ::std::unary_function<
uno::Reference< chart2::data::XDataSequence >,
uno::Sequence< double > >
{
uno::Sequence< double > operator() ( const uno::Reference< chart2::data::XDataSequence > & xSeq )
{
uno::Reference< chart2::data::XNumericalDataSequence > xNumSeq( xSeq, uno::UNO_QUERY );
if( xNumSeq.is())
{
return xNumSeq->getNumericalData();
}
else if( xSeq.is())
{
uno::Sequence< uno::Any > aValues = xSeq->getData();
uno::Sequence< double > aResult( aValues.getLength());
const sal_Int32 nLength = aValues.getLength();
for( sal_Int32 i = 0; i < nLength; ++i )
{
if( ! ( aValues[ i ] >>= aResult[ i ]) )
{
aResult[ i ] = DBL_MIN;
}
double& rValue = aResult[ i ];
if( ::rtl::math::isNan( rValue ) )
rValue = DBL_MIN;
}
return aResult;
}
return uno::Sequence< double >();
}
};
void lcl_AddSequences( uno::Reference< chart2::data::XLabeledDataSequence > xLSeq,
::std::vector< uno::Reference< chart2::data::XDataSequence > > & rOutSeqVector,
::std::vector< ::rtl::OUString > & rOutLabelVector )
{
if( xLSeq.is() )
{
uno::Reference< chart2::data::XDataSequence > xSeq( xLSeq->getValues() );
rOutSeqVector.push_back( xSeq );
::rtl::OUString aLabel( ::chart::DataSeriesHelper::getLabelForLabeledDataSequence( xLSeq ) );
rOutLabelVector.push_back( aLabel );
}
}
uno::Sequence< uno::Sequence< double > > lcl_getNANInsteadDBL_MIN( const uno::Sequence< uno::Sequence< double > >& rData )
{
uno::Sequence< uno::Sequence< double > > aRet;
const sal_Int32 nOuterSize = rData.getLength();
aRet.realloc( nOuterSize );
for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter )
{
sal_Int32 nInnerSize = rData[nOuter].getLength();
aRet[nOuter].realloc( nInnerSize );
for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner )
{
aRet[nOuter][nInner] = rData[nOuter][nInner];
double& rValue = aRet[nOuter][nInner];
if( rValue == DBL_MIN )
::rtl::math::setNan( &rValue );
}
}
return aRet;
}
uno::Sequence< uno::Sequence< double > > lcl_getDBL_MINInsteadNAN( const uno::Sequence< uno::Sequence< double > >& rData )
{
uno::Sequence< uno::Sequence< double > > aRet;
const sal_Int32 nOuterSize = rData.getLength();
aRet.realloc( nOuterSize );
for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter )
{
sal_Int32 nInnerSize = rData[nOuter].getLength();
aRet[nOuter].realloc( nInnerSize );
for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner )
{
aRet[nOuter][nInner] = rData[nOuter][nInner];
double& rValue = aRet[nOuter][nInner];
if( ::rtl::math::isNan( rValue ) )
rValue = DBL_MIN;
}
}
return aRet;
}
} // anonymous namespace
// --------------------------------------------------------------------------------
namespace chart
{
namespace wrapper
{
ChartDataWrapper::ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact ) :
m_spChart2ModelContact( spChart2ModelContact ),
m_aEventListenerContainer( m_aMutex )
{
refreshData();
}
ChartDataWrapper::~ChartDataWrapper()
{
// @todo: implement XComponent and call this in dispose(). In the DTOR the
// ref-count is 0, thus creating a stack reference to this calls the DTOR at
// the end of the block recursively
// uno::Reference< uno::XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
// m_aEventListenerContainer.disposeAndClear( lang::EventObject( xSource ) );
}
// ____ XChartDataArray ____
uno::Sequence< uno::Sequence< double > > SAL_CALL ChartDataWrapper::getData()
throw (uno::RuntimeException)
{
// until we have a data change notification mechanism we always have to
// update the data here
refreshData();
// /--
MutexGuard aGuard( GetMutex());
return m_aData;
// \--
}
void SAL_CALL ChartDataWrapper::setData(
const uno::Sequence< uno::Sequence< double > >& aData )
throw (uno::RuntimeException)
{
refreshData();
{
// /--
MutexGuard aGuard( GetMutex());
m_aData = aData;
// \--
}
applyData( true, false, false );
}
uno::Sequence< ::rtl::OUString > SAL_CALL ChartDataWrapper::getRowDescriptions()
throw (uno::RuntimeException)
{
// until we have a data change notification mechanism we always have to
// update the data here
refreshData();
// /--
MutexGuard aGuard( GetMutex());
return m_aRowDescriptions;
// \--
}
void SAL_CALL ChartDataWrapper::setRowDescriptions(
const uno::Sequence< ::rtl::OUString >& aRowDescriptions )
throw (uno::RuntimeException)
{
refreshData();
{
// /--
MutexGuard aGuard( GetMutex());
m_aRowDescriptions = aRowDescriptions;
// \--
}
applyData( false, true, false );
}
uno::Sequence<
::rtl::OUString > SAL_CALL ChartDataWrapper::getColumnDescriptions()
throw (uno::RuntimeException)
{
// until we have a data change notification mechanism we always have to
// update the data here
refreshData();
// /--
MutexGuard aGuard( GetMutex());
return m_aColumnDescriptions;
// \--
}
void SAL_CALL ChartDataWrapper::setColumnDescriptions(
const uno::Sequence< ::rtl::OUString >& aColumnDescriptions )
throw (uno::RuntimeException)
{
refreshData();
{
// /--
MutexGuard aGuard( GetMutex());
m_aColumnDescriptions = aColumnDescriptions;
// \--
}
applyData( false, false, true );
}
// ____ XChartData (base of XChartDataArray) ____
void SAL_CALL ChartDataWrapper::addChartDataChangeEventListener(
const uno::Reference<
::com::sun::star::chart::XChartDataChangeEventListener >& aListener )
throw (uno::RuntimeException)
{
m_aEventListenerContainer.addInterface( aListener );
}
void SAL_CALL ChartDataWrapper::removeChartDataChangeEventListener(
const uno::Reference<
::com::sun::star::chart::XChartDataChangeEventListener >& aListener )
throw (uno::RuntimeException)
{
m_aEventListenerContainer.removeInterface( aListener );
}
double SAL_CALL ChartDataWrapper::getNotANumber()
throw (uno::RuntimeException)
{
return DBL_MIN;
}
sal_Bool SAL_CALL ChartDataWrapper::isNotANumber( double nNumber )
throw (uno::RuntimeException)
{
return DBL_MIN == nNumber
|| ::rtl::math::isNan( nNumber )
|| ::rtl::math::isInf( nNumber );
}
// ____ XComponent ____
void SAL_CALL ChartDataWrapper::dispose()
throw (uno::RuntimeException)
{
m_aEventListenerContainer.disposeAndClear( lang::EventObject( static_cast< ::cppu::OWeakObject* >( this )));
// /--
MutexGuard aGuard( GetMutex());
m_aData.realloc( 0 );
m_aColumnDescriptions.realloc( 0 );
m_aRowDescriptions.realloc( 0 );
// \--
}
void SAL_CALL ChartDataWrapper::addEventListener(
const uno::Reference< lang::XEventListener > & xListener )
throw (uno::RuntimeException)
{
m_aEventListenerContainer.addInterface( xListener );
}
void SAL_CALL ChartDataWrapper::removeEventListener(
const uno::Reference< lang::XEventListener >& aListener )
throw (uno::RuntimeException)
{
m_aEventListenerContainer.removeInterface( aListener );
}
// ____ XEventListener ____
void SAL_CALL ChartDataWrapper::disposing( const lang::EventObject& /* Source */ )
throw (uno::RuntimeException)
{
}
// ::com::sun::star::chart::ChartDataChangeEvent aEvent;
// aEvent.Type = chart::ChartDataChangeType_ALL;
// aEvent.StartColumn = 0;
// aEvent.EndColumn = 0;
// aEvent.StartRow = 0;
// aEvent.EndRow = 0;
void ChartDataWrapper::fireChartDataChangeEvent(
::com::sun::star::chart::ChartDataChangeEvent& aEvent )
{
if( ! m_aEventListenerContainer.getLength() )
return;
uno::Reference< uno::XInterface > xSrc( static_cast< cppu::OWeakObject* >( this ));
OSL_ASSERT( xSrc.is());
if( xSrc.is() )
aEvent.Source = xSrc;
::cppu::OInterfaceIteratorHelper aIter( m_aEventListenerContainer );
while( aIter.hasMoreElements() )
{
uno::Reference<
::com::sun::star::chart::XChartDataChangeEventListener > xListener(
aIter.next(), uno::UNO_QUERY );
xListener->chartDataChanged( aEvent );
}
}
void ChartDataWrapper::refreshData()
{
//todo mutex...
Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
if( !xChartDoc.is() )
return;
if( xChartDoc->hasInternalDataProvider())
{
try {
uno::Reference< ::com::sun::star::chart::XChartDataArray > xInternalData( xChartDoc->getDataProvider(), uno::UNO_QUERY_THROW );
m_aColumnDescriptions = xInternalData->getColumnDescriptions();
m_aRowDescriptions = xInternalData->getRowDescriptions();
m_aData = lcl_getDBL_MINInsteadNAN( xInternalData->getData() );
}
catch( const uno::Exception & ex ) {
ASSERT_EXCEPTION( ex );
}
}
else
{
uno::Reference< chart2::XDiagram > xDia(
xChartDoc->getFirstDiagram() );
if( ! xDia.is())
return;
// get information about the segmentation of the assumed "rectangular" data
// range
::rtl::OUString aRangeString;
bool bUseColumns = true;
bool bFirstCellAsLabel = true;
bool bHasCategories = true;
uno::Sequence< sal_Int32 > aSequenceMapping;
DataSourceHelper::detectRangeSegmentation(
uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ),
aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories );
// get data values from data series
// --------------------------------
uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledSequences;
uno::Reference< chart2::data::XDataSource > xRectangularDataSource(
DataSourceHelper::pressUsedDataIntoRectangularFormat( xChartDoc, false /*bWithCategories*/ ) );
if( xRectangularDataSource.is() )
{
aLabeledSequences = xRectangularDataSource->getDataSequences();
}
::std::vector< uno::Reference< chart2::data::XDataSequence > > aSequenceVector;
::std::vector< ::rtl::OUString > aLabelVector;
for( sal_Int32 nN=0; nN<aLabeledSequences.getLength(); nN++ )
lcl_AddSequences( aLabeledSequences[nN], aSequenceVector, aLabelVector );
if( aSequenceMapping.getLength() )
{
//aSequenceVector and aLabelVector contain changed positions; resort them to the original position
::std::vector< uno::Reference< chart2::data::XDataSequence > > aBackSortedSequences;
::std::vector< ::rtl::OUString > aBackSortedLabels;
std::map< sal_Int32, sal_Int32 > aReverseMap;
{
sal_Int32 nNewIndex, nOldIndex;
for( sal_Int32 nS=0; nS <aSequenceMapping.getLength(); nS++ )
{
nOldIndex = aSequenceMapping[nS];
nNewIndex = nS;
if( bHasCategories )
nNewIndex--;
if( nOldIndex >= 0 && nNewIndex >= 0 )
aReverseMap[nOldIndex] = nNewIndex;
}
}
std::map< sal_Int32, sal_Int32 >::iterator aMapIt = aReverseMap.begin();
std::map< sal_Int32, sal_Int32 >::const_iterator aMapEnd = aReverseMap.end();
for( ; aMapIt != aMapEnd; ++aMapIt )
{
size_t nNewIndex = static_cast< size_t >( aMapIt->second );
if( nNewIndex < aSequenceVector.size() )
aBackSortedSequences.push_back( aSequenceVector[nNewIndex] );
if( nNewIndex < aLabelVector.size() )
aBackSortedLabels.push_back( aLabelVector[nNewIndex] );
}
// note: assign( beg, end ) doesn't work on solaris
aSequenceVector.clear();
aSequenceVector.insert(
aSequenceVector.begin(), aBackSortedSequences.begin(), aBackSortedSequences.end() );
aLabelVector.clear();
aLabelVector.insert(
aLabelVector.begin(), aBackSortedLabels.begin(), aBackSortedLabels.end() );
}
if( bUseColumns )
{
const sal_Int32 nInnerSize = aSequenceVector.size();
if( nInnerSize > 0 && aSequenceVector[0].is() )
{
// take the length of the first data series also as length for all
// other series
const sal_Int32 nOuterSize = aSequenceVector[0]->getData().getLength();
m_aData.realloc( nOuterSize );
for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter )
m_aData[nOuter].realloc( nInnerSize );
for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner )
{
uno::Sequence< double > aValues = uno::Sequence< double > (
lcl_DataSequenceToDoubleSeq() (aSequenceVector[nInner] ));
sal_Int32 nMax = ::std::min( nOuterSize, aValues.getLength());
for( sal_Int32 nOuter=0; nOuter<nMax; ++nOuter )
m_aData[nOuter][nInner] = aValues[nOuter];
}
}
}
else
{
m_aData.realloc( static_cast< sal_Int32 >( aSequenceVector.size()));
::std::transform( aSequenceVector.begin(), aSequenceVector.end(),
m_aData.getArray(),
lcl_DataSequenceToDoubleSeq() );
}
// labels (values already filled during parsing of data values)
if( bUseColumns )
m_aColumnDescriptions = ::chart::ContainerHelper::ContainerToSequence( aLabelVector );
else
m_aRowDescriptions = ::chart::ContainerHelper::ContainerToSequence( aLabelVector );
// get row-/column descriptions
// ----------------------------
// categories
uno::Sequence< ::rtl::OUString > & rSequence =
bUseColumns ? m_aRowDescriptions : m_aColumnDescriptions;
rSequence = DiagramHelper::generateAutomaticCategories( xChartDoc );
}
}
void ChartDataWrapper::applyData( bool bSetValues, bool bSetRowDescriptions, bool bSetColumnDescriptions )
{
Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
if( !xChartDoc.is() )
return;
// /-- locked controllers
ControllerLockGuard aCtrlLockGuard( uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ));
// should do nothing if we already have an internal data provider
xChartDoc->createInternalDataProvider( sal_True /* bCloneExistingData */ );
uno::Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider());
uno::Reference< XChartDataArray > xDocDataArray( xDataProvider, uno::UNO_QUERY );
// remember some diagram properties to reset later
sal_Bool bStacked = sal_False;
sal_Bool bPercent = sal_False;
sal_Bool bDeep = sal_False;
uno::Reference< ::com::sun::star::chart::XChartDocument > xOldDoc( xChartDoc, uno::UNO_QUERY );
OSL_ASSERT( xOldDoc.is());
uno::Reference< beans::XPropertySet > xDiaProp( xOldDoc->getDiagram(), uno::UNO_QUERY );
if( xDiaProp.is())
{
xDiaProp->getPropertyValue( C2U("Stacked")) >>= bStacked;
xDiaProp->getPropertyValue( C2U("Percent")) >>= bPercent;
xDiaProp->getPropertyValue( C2U("Deep")) >>= bDeep;
}
//detect arguments for the new data source
::rtl::OUString aRangeString;
bool bUseColumns = true;
bool bFirstCellAsLabel = true;
bool bHasCategories = true;
uno::Sequence< sal_Int32 > aSequenceMapping;
DataSourceHelper::detectRangeSegmentation(
uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ),
aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories );
if( !bFirstCellAsLabel )
{
if( bSetRowDescriptions && !bUseColumns )
bFirstCellAsLabel = true;
else if( bSetColumnDescriptions && bUseColumns )
bFirstCellAsLabel = true;
}
if( !bHasCategories )
{
if( bSetColumnDescriptions && bUseColumns )
bHasCategories = true;
else if( bSetRowDescriptions && !bUseColumns )
bHasCategories = true;
}
aRangeString = C2U("all");
uno::Sequence< beans::PropertyValue > aArguments( DataSourceHelper::createArguments(
aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories ) );
// create and attach new data source
uno::Reference< chart2::data::XDataSource > xSource;
if( xDocDataArray.is() )
{
// we have an internal data provider that supports the XChartDataArray
// interface
if( bSetValues )
xDocDataArray->setData( lcl_getNANInsteadDBL_MIN( m_aData ) );
if( bSetRowDescriptions )
xDocDataArray->setRowDescriptions( m_aRowDescriptions );
if( bSetColumnDescriptions )
xDocDataArray->setColumnDescriptions( m_aColumnDescriptions );
xSource.set( xDataProvider->createDataSource( aArguments ));
}
else
{
uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY );
OSL_ASSERT( xChartDoc.is());
OSL_ASSERT( xReceiver.is());
if( ! (xChartDoc.is() && xReceiver.is()))
return;
// create a data provider containing the new data
uno::Reference< chart2::data::XDataProvider > xTempDataProvider(
new InternalDataProvider());
if( ! xTempDataProvider.is())
throw uno::RuntimeException( C2U("Couldn't create temporary data provider"),
static_cast< ::cppu::OWeakObject * >( this ));
uno::Reference< ::com::sun::star::chart::XChartDataArray > xDataArray( xTempDataProvider, uno::UNO_QUERY );
OSL_ASSERT( xDataArray.is());
if( xDataArray.is())
{
if( bSetValues )
xDataArray->setData( lcl_getNANInsteadDBL_MIN( m_aData ) );
if( bSetRowDescriptions )
xDataArray->setRowDescriptions( m_aRowDescriptions );
if( bSetColumnDescriptions )
xDataArray->setColumnDescriptions( m_aColumnDescriptions );
// removes existing data provider and attaches the new one
xReceiver->attachDataProvider( xTempDataProvider );
xSource.set( xTempDataProvider->createDataSource( aArguments));
}
}
// determine a template
uno::Reference< lang::XMultiServiceFactory > xFact( xChartDoc->getChartTypeManager(), uno::UNO_QUERY );
uno::Reference< chart2::XDiagram > xDia( xChartDoc->getFirstDiagram());
DiagramHelper::tTemplateWithServiceName aTemplateAndService =
DiagramHelper::getTemplateForDiagram( xDia, xFact );
::rtl::OUString aServiceName( aTemplateAndService.second );
uno::Reference< chart2::XChartTypeTemplate > xTemplate = aTemplateAndService.first;
// (fall-back)
if( ! xTemplate.is())
{
if( aServiceName.getLength() == 0 )
aServiceName = C2U("com.sun.star.chart2.template.Column");
xTemplate.set( xFact->createInstance( aServiceName ), uno::UNO_QUERY );
}
OSL_ASSERT( xTemplate.is());
if( xTemplate.is() && xSource.is())
{
// argument detection works with internal knowledge of the
// ArrayDataProvider
OSL_ASSERT( xDia.is());
xTemplate->changeDiagramData(
xDia, xSource, aArguments );
}
//correct stacking mode
if( bStacked || bPercent || bDeep )
{
StackMode eStackMode = StackMode_Y_STACKED;
if( bDeep )
eStackMode = StackMode_Z_STACKED;
else if( bPercent )
eStackMode = StackMode_Y_STACKED_PERCENT;
bool bOnlyAtFirstChartType = false;
DiagramHelper::setStackMode( xDia, eStackMode, bOnlyAtFirstChartType );
}
// notify listeners
::com::sun::star::chart::ChartDataChangeEvent aEvent(
static_cast< ::cppu::OWeakObject* >( this ),
::com::sun::star::chart::ChartDataChangeType_ALL, 0, 0, 0, 0 );
fireChartDataChangeEvent( aEvent );
// \-- locked controllers
}
// --------------------------------------------------------------------------------
uno::Sequence< ::rtl::OUString > ChartDataWrapper::getSupportedServiceNames_Static()
{
uno::Sequence< ::rtl::OUString > aServices( 2 );
aServices[ 0 ] = C2U( "com.sun.star.chart.ChartDataArray" );
aServices[ 1 ] = C2U( "com.sun.star.chart.ChartData" );
return aServices;
}
// ================================================================================
// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
APPHELPER_XSERVICEINFO_IMPL( ChartDataWrapper, lcl_aServiceName );
} // namespace wrapper
} // namespace chart