| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // 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 "ChartModelHelper.hxx" |
| #include "DataSeriesHelper.hxx" |
| #include "ControllerLockGuard.hxx" |
| #include "Chart2ModelContact.hxx" |
| #include <com/sun/star/beans/PropertyAttribute.hpp> |
| #include <com/sun/star/chart2/XTitled.hpp> |
| #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp> |
| #include <com/sun/star/chart2/data/XTextualDataSequence.hpp> |
| #include <com/sun/star/chart2/data/XDataSource.hpp> |
| #include <com/sun/star/chart2/XDataSeries.hpp> |
| #include <com/sun/star/chart2/XDataSeriesContainer.hpp> |
| #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> |
| #include <com/sun/star/chart2/XChartTypeContainer.hpp> |
| #include <com/sun/star/chart2/data/XDataReceiver.hpp> |
| #include <com/sun/star/chart/ChartDataRowSource.hpp> |
| #include <com/sun/star/chart/XChartDocument.hpp> |
| |
| #include "CharacterProperties.hxx" |
| #include "LineProperties.hxx" |
| #include "FillProperties.hxx" |
| |
| #include <map> |
| #include <algorithm> |
| #include <rtl/math.hxx> |
| |
| using namespace ::com::sun::star; |
| using ::com::sun::star::uno::Reference; |
| using ::com::sun::star::uno::Sequence; |
| using ::rtl::OUString; |
| using ::osl::MutexGuard; |
| using ::com::sun::star::chart2::XAnyDescriptionAccess; |
| using ::com::sun::star::chart::XComplexDescriptionAccess; |
| using ::com::sun::star::chart::XChartData; |
| using ::com::sun::star::chart::XChartDataArray; |
| using ::com::sun::star::chart::XDateCategories; |
| |
| namespace |
| { |
| static const ::rtl::OUString lcl_aServiceName( |
| RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.ChartData" )); |
| |
| 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 |
| { |
| |
| //-------------------------------------------------------------------------------------- |
| |
| struct lcl_Operator |
| { |
| lcl_Operator() |
| { |
| } |
| virtual ~lcl_Operator() |
| { |
| } |
| virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) = 0; |
| |
| virtual bool setsCategories( bool /*bDataInColumns*/ ) |
| { |
| return false; |
| } |
| }; |
| |
| //-------------------------------------------------------------------------- |
| |
| struct lcl_AllOperator : public lcl_Operator |
| { |
| lcl_AllOperator( const Reference< XChartData >& xDataToApply ) |
| : lcl_Operator() |
| , m_xDataToApply( xDataToApply ) |
| { |
| } |
| |
| virtual bool setsCategories( bool /*bDataInColumns*/ ) |
| { |
| return true; |
| } |
| |
| virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) |
| { |
| if( !xDataAccess.is() ) |
| return; |
| |
| Reference< XAnyDescriptionAccess > xNewAny( m_xDataToApply, uno::UNO_QUERY ); |
| Reference< XComplexDescriptionAccess > xNewComplex( m_xDataToApply, uno::UNO_QUERY ); |
| if( xNewAny.is() ) |
| { |
| xDataAccess->setData( xNewAny->getData() ); |
| xDataAccess->setComplexRowDescriptions( xNewAny->getComplexRowDescriptions() ); |
| xDataAccess->setComplexColumnDescriptions( xNewAny->getComplexColumnDescriptions() ); |
| } |
| else if( xNewComplex.is() ) |
| { |
| xDataAccess->setData( xNewComplex->getData() ); |
| xDataAccess->setComplexRowDescriptions( xNewComplex->getComplexRowDescriptions() ); |
| xDataAccess->setComplexColumnDescriptions( xNewComplex->getComplexColumnDescriptions() ); |
| } |
| else |
| { |
| Reference< XChartDataArray > xNew( m_xDataToApply, uno::UNO_QUERY ); |
| if( xNew.is() ) |
| { |
| xDataAccess->setData( xNew->getData() ); |
| xDataAccess->setRowDescriptions( xNew->getRowDescriptions() ); |
| xDataAccess->setColumnDescriptions( xNew->getColumnDescriptions() ); |
| } |
| } |
| } |
| |
| Reference< XChartData > m_xDataToApply; |
| }; |
| |
| //-------------------------------------------------------------------------- |
| |
| struct lcl_DataOperator : public lcl_Operator |
| { |
| lcl_DataOperator( const Sequence< Sequence< double > >& rData ) |
| : lcl_Operator() |
| , m_rData( rData ) |
| { |
| } |
| |
| virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) |
| { |
| if( xDataAccess.is() ) |
| xDataAccess->setData( lcl_getNANInsteadDBL_MIN( m_rData ) ); |
| } |
| |
| const Sequence< Sequence< double > >& m_rData; |
| }; |
| |
| //-------------------------------------------------------------------------- |
| |
| struct lcl_RowDescriptionsOperator : public lcl_Operator |
| { |
| lcl_RowDescriptionsOperator( const Sequence< OUString >& rRowDescriptions |
| , const Reference< chart2::XChartDocument >& xChartDoc ) |
| : lcl_Operator() |
| , m_rRowDescriptions( rRowDescriptions ) |
| , m_xChartDoc(xChartDoc) |
| , m_bDataInColumns(true) |
| { |
| } |
| |
| virtual bool setsCategories( bool bDataInColumns ) |
| { |
| m_bDataInColumns = bDataInColumns; |
| return bDataInColumns; |
| } |
| |
| virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) |
| { |
| if( xDataAccess.is() ) |
| { |
| xDataAccess->setRowDescriptions( m_rRowDescriptions ); |
| if( m_bDataInColumns ) |
| DiagramHelper::switchToTextCategories( m_xChartDoc ); |
| } |
| } |
| |
| const Sequence< OUString >& m_rRowDescriptions; |
| Reference< chart2::XChartDocument > m_xChartDoc; |
| bool m_bDataInColumns; |
| }; |
| |
| //-------------------------------------------------------------------------- |
| |
| struct lcl_ComplexRowDescriptionsOperator : public lcl_Operator |
| { |
| lcl_ComplexRowDescriptionsOperator( const Sequence< Sequence< OUString > >& rComplexRowDescriptions |
| , const Reference< chart2::XChartDocument >& xChartDoc ) |
| : lcl_Operator() |
| , m_rComplexRowDescriptions( rComplexRowDescriptions ) |
| , m_xChartDoc(xChartDoc) |
| , m_bDataInColumns(true) |
| { |
| } |
| |
| virtual bool setsCategories( bool bDataInColumns ) |
| { |
| m_bDataInColumns = bDataInColumns; |
| return bDataInColumns; |
| } |
| |
| virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) |
| { |
| if( xDataAccess.is() ) |
| { |
| xDataAccess->setComplexRowDescriptions( m_rComplexRowDescriptions ); |
| if( m_bDataInColumns ) |
| DiagramHelper::switchToTextCategories( m_xChartDoc ); |
| } |
| } |
| |
| const Sequence< Sequence< OUString > >& m_rComplexRowDescriptions; |
| Reference< chart2::XChartDocument > m_xChartDoc; |
| bool m_bDataInColumns; |
| }; |
| //-------------------------------------------------------------------------- |
| |
| struct lcl_AnyRowDescriptionsOperator : public lcl_Operator |
| { |
| lcl_AnyRowDescriptionsOperator( const Sequence< Sequence< uno::Any > >& rAnyRowDescriptions ) |
| : lcl_Operator() |
| , m_rAnyRowDescriptions( rAnyRowDescriptions ) |
| { |
| } |
| |
| virtual bool setsCategories( bool bDataInColumns ) |
| { |
| return bDataInColumns; |
| } |
| |
| virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) |
| { |
| if( xDataAccess.is() ) |
| xDataAccess->setAnyRowDescriptions( m_rAnyRowDescriptions ); |
| } |
| |
| const Sequence< Sequence< uno::Any > >& m_rAnyRowDescriptions; |
| }; |
| |
| //-------------------------------------------------------------------------- |
| |
| struct lcl_ColumnDescriptionsOperator : public lcl_Operator |
| { |
| lcl_ColumnDescriptionsOperator( const Sequence< OUString >& rColumnDescriptions |
| , const Reference< chart2::XChartDocument >& xChartDoc ) |
| : lcl_Operator() |
| , m_rColumnDescriptions( rColumnDescriptions ) |
| , m_xChartDoc(xChartDoc) |
| , m_bDataInColumns(true) |
| { |
| } |
| |
| virtual bool setsCategories( bool bDataInColumns ) |
| { |
| m_bDataInColumns = bDataInColumns; |
| return !bDataInColumns; |
| } |
| |
| virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) |
| { |
| if( xDataAccess.is() ) |
| { |
| xDataAccess->setColumnDescriptions( m_rColumnDescriptions ); |
| if( !m_bDataInColumns ) |
| DiagramHelper::switchToTextCategories( m_xChartDoc ); |
| } |
| } |
| |
| const Sequence< OUString >& m_rColumnDescriptions; |
| Reference< chart2::XChartDocument > m_xChartDoc; |
| bool m_bDataInColumns; |
| }; |
| |
| //-------------------------------------------------------------------------- |
| |
| struct lcl_ComplexColumnDescriptionsOperator : public lcl_Operator |
| { |
| lcl_ComplexColumnDescriptionsOperator( const Sequence< Sequence< OUString > >& rComplexColumnDescriptions |
| , const Reference< chart2::XChartDocument >& xChartDoc ) |
| : lcl_Operator() |
| , m_rComplexColumnDescriptions( rComplexColumnDescriptions ) |
| , m_xChartDoc(xChartDoc) |
| , m_bDataInColumns(true) |
| { |
| } |
| |
| virtual bool setsCategories( bool bDataInColumns ) |
| { |
| m_bDataInColumns = bDataInColumns; |
| return !bDataInColumns; |
| } |
| |
| virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) |
| { |
| if( xDataAccess.is() ) |
| { |
| xDataAccess->setComplexColumnDescriptions( m_rComplexColumnDescriptions ); |
| if( !m_bDataInColumns ) |
| DiagramHelper::switchToTextCategories( m_xChartDoc ); |
| } |
| } |
| |
| const Sequence< Sequence< OUString > >& m_rComplexColumnDescriptions; |
| Reference< chart2::XChartDocument > m_xChartDoc; |
| bool m_bDataInColumns; |
| }; |
| |
| //-------------------------------------------------------------------------- |
| |
| struct lcl_AnyColumnDescriptionsOperator : public lcl_Operator |
| { |
| lcl_AnyColumnDescriptionsOperator( const Sequence< Sequence< uno::Any > >& rAnyColumnDescriptions ) |
| : lcl_Operator() |
| , m_rAnyColumnDescriptions( rAnyColumnDescriptions ) |
| { |
| } |
| |
| virtual bool setsCategories( bool bDataInColumns ) |
| { |
| return bDataInColumns; |
| } |
| |
| virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) |
| { |
| if( xDataAccess.is() ) |
| xDataAccess->setAnyColumnDescriptions( m_rAnyColumnDescriptions ); |
| } |
| |
| const Sequence< Sequence< uno::Any > >& m_rAnyColumnDescriptions; |
| }; |
| |
| //-------------------------------------------------------------------------- |
| |
| struct lcl_DateCategoriesOperator : public lcl_Operator |
| { |
| lcl_DateCategoriesOperator( const Sequence< double >& rDates ) |
| : lcl_Operator() |
| , m_rDates( rDates ) |
| { |
| } |
| |
| virtual bool setsCategories( bool /*bDataInColumns*/ ) |
| { |
| return true; |
| } |
| |
| virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) |
| { |
| Reference< XDateCategories > xDateCategories( xDataAccess, uno::UNO_QUERY ); |
| if( xDateCategories.is() ) |
| xDateCategories->setDateCategories( m_rDates ); |
| } |
| |
| const Sequence< double >& m_rDates; |
| }; |
| |
| //-------------------------------------------------------------------------- |
| |
| ChartDataWrapper::ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact ) : |
| m_spChart2ModelContact( spChart2ModelContact ), |
| m_aEventListenerContainer( m_aMutex ) |
| { |
| osl_incrementInterlockedCount( &m_refCount ); |
| initDataAccess(); |
| osl_decrementInterlockedCount( &m_refCount ); |
| } |
| |
| ChartDataWrapper::ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact, |
| const Reference< XChartData >& xNewData ) : |
| m_spChart2ModelContact( spChart2ModelContact ), |
| m_aEventListenerContainer( m_aMutex ) |
| { |
| osl_incrementInterlockedCount( &m_refCount ); |
| lcl_AllOperator aOperator( xNewData ); |
| applyData( aOperator ); |
| osl_decrementInterlockedCount( &m_refCount ); |
| } |
| |
| 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 (read)____ |
| Sequence< Sequence< double > > SAL_CALL ChartDataWrapper::getData() |
| throw (uno::RuntimeException) |
| { |
| initDataAccess(); |
| if( m_xDataAccess.is() ) |
| return lcl_getDBL_MINInsteadNAN( m_xDataAccess->getData() ); |
| return Sequence< Sequence< double > >(); |
| } |
| Sequence< OUString > SAL_CALL ChartDataWrapper::getRowDescriptions() |
| throw (uno::RuntimeException) |
| { |
| initDataAccess(); |
| if( m_xDataAccess.is() ) |
| return m_xDataAccess->getRowDescriptions(); |
| return Sequence< OUString >(); |
| } |
| Sequence< OUString > SAL_CALL ChartDataWrapper::getColumnDescriptions() |
| throw (uno::RuntimeException) |
| { |
| initDataAccess(); |
| if( m_xDataAccess.is() ) |
| return m_xDataAccess->getColumnDescriptions(); |
| return Sequence< OUString > (); |
| } |
| |
| // ____ XComplexDescriptionAccess (read) ____ |
| Sequence< Sequence< OUString > > SAL_CALL ChartDataWrapper::getComplexRowDescriptions() throw (uno::RuntimeException) |
| { |
| initDataAccess(); |
| if( m_xDataAccess.is() ) |
| return m_xDataAccess->getComplexRowDescriptions(); |
| return Sequence< Sequence< OUString > >(); |
| } |
| Sequence< Sequence< OUString > > SAL_CALL ChartDataWrapper::getComplexColumnDescriptions() throw (uno::RuntimeException) |
| { |
| initDataAccess(); |
| if( m_xDataAccess.is() ) |
| return m_xDataAccess->getComplexColumnDescriptions(); |
| return Sequence< Sequence< OUString > >(); |
| } |
| |
| // ____ XAnyDescriptionAccess (read) ____ |
| Sequence< Sequence< uno::Any > > SAL_CALL ChartDataWrapper::getAnyRowDescriptions() throw (uno::RuntimeException) |
| { |
| initDataAccess(); |
| if( m_xDataAccess.is() ) |
| return m_xDataAccess->getAnyRowDescriptions(); |
| return Sequence< Sequence< uno::Any > >(); |
| } |
| Sequence< Sequence< uno::Any > > SAL_CALL ChartDataWrapper::getAnyColumnDescriptions() throw (uno::RuntimeException) |
| { |
| initDataAccess(); |
| if( m_xDataAccess.is() ) |
| return m_xDataAccess->getAnyColumnDescriptions(); |
| return Sequence< Sequence< uno::Any > >(); |
| } |
| |
| // ____ XDateCategories (read) ____ |
| Sequence< double > SAL_CALL ChartDataWrapper::getDateCategories() throw (uno::RuntimeException) |
| { |
| initDataAccess(); |
| Reference< XDateCategories > xDateCategories( m_xDataAccess, uno::UNO_QUERY ); |
| if( xDateCategories.is() ) |
| return xDateCategories->getDateCategories(); |
| return Sequence< double >(); |
| } |
| |
| // ____ XChartDataArray (write)____ |
| void SAL_CALL ChartDataWrapper::setData( const Sequence< Sequence< double > >& rData ) |
| throw (uno::RuntimeException) |
| { |
| lcl_DataOperator aOperator( rData ); |
| applyData( aOperator ); |
| } |
| void SAL_CALL ChartDataWrapper::setRowDescriptions( const Sequence< OUString >& rRowDescriptions ) |
| throw (uno::RuntimeException) |
| { |
| lcl_RowDescriptionsOperator aOperator( rRowDescriptions, m_spChart2ModelContact->getChart2Document() ); |
| applyData( aOperator ); |
| } |
| void SAL_CALL ChartDataWrapper::setColumnDescriptions( const Sequence< OUString >& rColumnDescriptions ) |
| throw (uno::RuntimeException) |
| { |
| lcl_ColumnDescriptionsOperator aOperator( rColumnDescriptions, m_spChart2ModelContact->getChart2Document() ); |
| applyData( aOperator ); |
| } |
| |
| // ____ XComplexDescriptionAccess (write) ____ |
| void SAL_CALL ChartDataWrapper::setComplexRowDescriptions( const Sequence< Sequence< ::rtl::OUString > >& rRowDescriptions ) throw (uno::RuntimeException) |
| { |
| lcl_ComplexRowDescriptionsOperator aOperator( rRowDescriptions, m_spChart2ModelContact->getChart2Document() ); |
| applyData( aOperator ); |
| } |
| void SAL_CALL ChartDataWrapper::setComplexColumnDescriptions( const Sequence< Sequence< ::rtl::OUString > >& rColumnDescriptions ) throw (uno::RuntimeException) |
| { |
| lcl_ComplexColumnDescriptionsOperator aOperator( rColumnDescriptions, m_spChart2ModelContact->getChart2Document() ); |
| applyData( aOperator ); |
| } |
| |
| // ____ XAnyDescriptionAccess (write) ____ |
| void SAL_CALL ChartDataWrapper::setAnyRowDescriptions( const Sequence< Sequence< uno::Any > >& rRowDescriptions ) throw (uno::RuntimeException) |
| { |
| lcl_AnyRowDescriptionsOperator aOperator( rRowDescriptions ); |
| applyData( aOperator ); |
| } |
| void SAL_CALL ChartDataWrapper::setAnyColumnDescriptions( const Sequence< Sequence< uno::Any > >& rColumnDescriptions ) throw (uno::RuntimeException) |
| { |
| lcl_AnyColumnDescriptionsOperator aOperator( rColumnDescriptions ); |
| applyData( aOperator ); |
| } |
| |
| // ____ XDateCategories (write) ____ |
| void SAL_CALL ChartDataWrapper::setDateCategories( const Sequence< double >& rDates ) throw (uno::RuntimeException) |
| { |
| Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() ); |
| ControllerLockGuard aCtrlLockGuard( uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY )); |
| lcl_DateCategoriesOperator aOperator( rDates ); |
| applyData( aOperator ); |
| DiagramHelper::switchToDateCategories( xChartDoc ); |
| } |
| |
| //-------------------------------------------------------------------------------------- |
| |
| // ____ 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 ))); |
| m_xDataAccess=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 ); |
| if( xListener.is() ) |
| xListener->chartDataChanged( aEvent ); |
| } |
| } |
| |
| // -------------------------------------------------------------------------------- |
| |
| void ChartDataWrapper::switchToInternalDataProvider() |
| { |
| //create an internal data provider that is connected to the model |
| Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() ); |
| if( xChartDoc.is() ) |
| xChartDoc->createInternalDataProvider( true /*bCloneExistingData*/ ); |
| initDataAccess(); |
| } |
| |
| void ChartDataWrapper::initDataAccess() |
| { |
| Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() ); |
| if( !xChartDoc.is() ) |
| return; |
| if( xChartDoc->hasInternalDataProvider() ) |
| m_xDataAccess = Reference< XAnyDescriptionAccess >( xChartDoc->getDataProvider(), uno::UNO_QUERY_THROW ); |
| else |
| { |
| //create a separate "internal data provider" that is not connected to the model |
| m_xDataAccess = Reference< XAnyDescriptionAccess >( ChartModelHelper::createInternalDataProvider( |
| xChartDoc, false /*bConnectToModel*/ ), uno::UNO_QUERY_THROW ); |
| } |
| } |
| |
| void ChartDataWrapper::applyData( lcl_Operator& rDataOperator ) |
| { |
| //bool bSetValues, bool bSetRowDescriptions, bool bSetColumnDescriptions |
| Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() ); |
| if( !xChartDoc.is() ) |
| return; |
| |
| // 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( !bHasCategories && rDataOperator.setsCategories( bUseColumns ) ) |
| bHasCategories = true; |
| |
| aRangeString = C2U("all"); |
| uno::Sequence< beans::PropertyValue > aArguments( DataSourceHelper::createArguments( |
| aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories ) ); |
| |
| |
| // /-- locked controllers |
| ControllerLockGuard aCtrlLockGuard( uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY )); |
| |
| // create and attach new data source |
| switchToInternalDataProvider(); |
| rDataOperator.apply(m_xDataAccess); |
| uno::Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() ); |
| OSL_ASSERT( xDataProvider.is() ); |
| if( !xDataProvider.is() ) |
| return; |
| uno::Reference< chart2::data::XDataSource > xSource( xDataProvider->createDataSource( aArguments ) ); |
| |
| uno::Reference< chart2::XDiagram > xDia( xChartDoc->getFirstDiagram() ); |
| if( xDia.is() ) |
| xDia->setDiagramData( 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; |
| DiagramHelper::setStackMode( xDia, eStackMode ); |
| } |
| |
| // 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 |