diff options
Diffstat (limited to 'chart2/source/model/main/ChartModel.cxx')
-rwxr-xr-x | chart2/source/model/main/ChartModel.cxx | 1390 |
1 files changed, 1390 insertions, 0 deletions
diff --git a/chart2/source/model/main/ChartModel.cxx b/chart2/source/model/main/ChartModel.cxx new file mode 100755 index 000000000000..95bc1315ad51 --- /dev/null +++ b/chart2/source/model/main/ChartModel.cxx @@ -0,0 +1,1390 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_chart2.hxx" +#include "ChartModel.hxx" +#include "servicenames.hxx" +#include "MediaDescriptorHelper.hxx" +#include "macros.hxx" +#include "servicenames.hxx" +#include "NoWarningThisInCTOR.hxx" +#include "DataSourceHelper.hxx" +#include "ChartModelHelper.hxx" +#include "DiagramHelper.hxx" +#include "DisposeHelper.hxx" +#include "ControllerLockGuard.hxx" +#include "ObjectIdentifier.hxx" +#include "PageBackground.hxx" +#include "CloneHelper.hxx" +#include "NameContainer.hxx" + +#include <com/sun/star/chart/ChartDataRowSource.hpp> + +#include <comphelper/InlineContainer.hxx> +#include <comphelper/processfactory.hxx> + +// header for class SvNumberFormatsSupplierObj +#include <svl/numuno.hxx> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include <com/sun/star/embed/XEmbedObjectCreator.hpp> +#include <com/sun/star/embed/XEmbedPersist.hpp> +#include <com/sun/star/embed/EmbedStates.hpp> +#include <com/sun/star/embed/XComponentSupplier.hpp> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/embed/EmbedMapUnits.hpp> +#include <com/sun/star/embed/Aspects.hpp> +#include <com/sun/star/awt/Gradient.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <com/sun/star/drawing/Hatch.hpp> +#include <com/sun/star/drawing/LineDash.hpp> +#include <com/sun/star/drawing/XShapes.hpp> + +// header for class SvNumberFormatter +#include <svl/zforlist.hxx> + +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Any; +using ::rtl::OUString; +using ::osl::MutexGuard; + +using namespace ::com::sun::star; +using namespace ::apphelper; +using namespace ::chart::CloneHelper; + +namespace +{ +const OUString lcl_aGDIMetaFileMIMEType( + RTL_CONSTASCII_USTRINGPARAM("application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"")); +const OUString lcl_aGDIMetaFileMIMETypeHighContrast( + RTL_CONSTASCII_USTRINGPARAM("application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"")); + +} // anonymous namespace + +//----------------------------------------------------------------- +// ChartModel Constructor and Destructor +//----------------------------------------------------------------- + +namespace chart +{ + +ChartModel::ChartModel(uno::Reference<uno::XComponentContext > const & xContext) + : m_aLifeTimeManager( this, this ) + , m_bReadOnly( sal_False ) + , m_bModified( sal_False ) + , m_nInLoad(0) + , m_bUpdateNotificationsPending(false) + , m_aControllers( m_aModelMutex ) + , m_nControllerLockCount(0) + , m_xContext( xContext ) + , m_aVisualAreaSize( ChartModelHelper::getDefaultPageSize() ) + , m_xDataProvider( 0 ) + , m_xInternalDataProvider( 0 ) + , m_xPageBackground( new PageBackground( m_xContext ) ) + , m_xXMLNamespaceMap( createNameContainer( ::getCppuType( (const OUString*) 0 ), + C2U( "com.sun.star.xml.NamespaceMap" ), C2U( "com.sun.star.comp.chart.XMLNameSpaceMap" ) ), uno::UNO_QUERY) +{ + OSL_TRACE( "ChartModel: CTOR called" ); + osl_incrementInterlockedCount(&m_refCount); + + ModifyListenerHelper::addListener( m_xPageBackground, this ); + m_xChartTypeManager.set( xContext->getServiceManager()->createInstanceWithContext( + C2U( "com.sun.star.chart2.ChartTypeManager" ), m_xContext ), uno::UNO_QUERY ); + m_xUndoManager = Reference< chart2::XUndoManager >( + this->createInstance( CHART_UNDOMANAGER_SERVICE_NAME ), uno::UNO_QUERY ); + + osl_decrementInterlockedCount(&m_refCount); +} + +ChartModel::ChartModel( const ChartModel & rOther ) + : impl::ChartModel_Base() + , m_aLifeTimeManager( this, this ) + , m_bReadOnly( rOther.m_bReadOnly ) + , m_bModified( rOther.m_bModified ) + , m_nInLoad(0) + , m_bUpdateNotificationsPending(false) + , m_aResource( rOther.m_aResource ) + , m_aMediaDescriptor( rOther.m_aMediaDescriptor ) + , m_aControllers( m_aModelMutex ) + , m_nControllerLockCount(0) + , m_xContext( rOther.m_xContext ) + // @note: the old model aggregate must not be shared with other models if it + // is, you get mutex deadlocks + , m_xOldModelAgg( 0 ) //rOther.m_xOldModelAgg ) + , m_xStorage( 0 ) //rOther.m_xStorage ) + , m_aVisualAreaSize( rOther.m_aVisualAreaSize ) + , m_aGraphicObjectVector( rOther.m_aGraphicObjectVector ) + , m_xDataProvider( rOther.m_xDataProvider ) + , m_xInternalDataProvider( rOther.m_xInternalDataProvider ) + , m_xUndoManager( rOther.m_xUndoManager ) +{ + OSL_TRACE( "ChartModel: Copy-CTOR called" ); + osl_incrementInterlockedCount(&m_refCount); + + Reference< util::XModifyListener > xListener; + Reference< chart2::XTitle > xNewTitle = CreateRefClone< Reference< chart2::XTitle > >()( rOther.m_xTitle ); + Reference< chart2::XDiagram > xNewDiagram = CreateRefClone< Reference< chart2::XDiagram > >()( rOther.m_xDiagram ); + Reference< beans::XPropertySet > xNewPageBackground = CreateRefClone< Reference< beans::XPropertySet > >()( rOther.m_xPageBackground ); + Reference< chart2::XChartTypeManager > xChartTypeManager = CreateRefClone< Reference< chart2::XChartTypeManager > >()( rOther.m_xChartTypeManager ); + Reference< container::XNameAccess > xXMLNamespaceMap = CreateRefClone< Reference< container::XNameAccess > >()( rOther.m_xXMLNamespaceMap ); + + { + MutexGuard aGuard( m_aModelMutex ); + xListener = this; + m_xTitle = xNewTitle; + m_xDiagram = xNewDiagram; + m_xPageBackground = xNewPageBackground; + m_xChartTypeManager = xChartTypeManager; + m_xXMLNamespaceMap = xXMLNamespaceMap; + } + + ModifyListenerHelper::addListener( xNewTitle, xListener ); + ModifyListenerHelper::addListener( xNewDiagram, xListener ); + ModifyListenerHelper::addListener( xNewPageBackground, xListener ); + xListener.clear(); + + osl_decrementInterlockedCount(&m_refCount); +} + +ChartModel::~ChartModel() +{ + OSL_TRACE( "ChartModel: DTOR called" ); + if( m_xOldModelAgg.is()) + m_xOldModelAgg->setDelegator( 0 ); +} + +void SAL_CALL ChartModel::initialize( const Sequence< Any >& /*rArguments*/ ) + throw (uno::Exception, uno::RuntimeException) +{ + //#i113722# avoid duplicate creation + + //maybe additional todo?: + //support argument "EmbeddedObject"? + //support argument "EmbeddedScriptSupport"? + //support argument "DocumentRecoverySupport"? +} + +//----------------------------------------------------------------- +// private methods +//----------------------------------------------------------------- + +::rtl::OUString ChartModel::impl_g_getLocation() +{ + + LifeTimeGuard aGuard(m_aLifeTimeManager); + if(!aGuard.startApiCall()) + return ::rtl::OUString(); //behave passive if already disposed or closed or throw exception @todo? + //mutex is acquired + return m_aResource; +} + +sal_Bool ChartModel::impl_isControllerConnected( const uno::Reference< frame::XController >& xController ) +{ + try + { + uno::Sequence< uno::Reference<uno::XInterface> > aSeq = m_aControllers.getElements(); + for( sal_Int32 nN = aSeq.getLength(); nN--; ) + { + if( aSeq[nN] == xController ) + return sal_True; + } + } + catch( uno::Exception ) + { + } + return sal_False; +} + +uno::Reference< frame::XController > ChartModel::impl_getCurrentController() throw(uno::RuntimeException) +{ + //@todo? hold only weak references to controllers + + // get the last active controller of this model + if( m_xCurrentController.is() ) + return m_xCurrentController; + + // get the first controller of this model + if( m_aControllers.getLength() ) + { + uno::Reference<uno::XInterface> xI = m_aControllers.getElements()[0]; + return uno::Reference<frame::XController>( xI, uno::UNO_QUERY ); + } + + //return nothing if no controllers are connected at all + return uno::Reference< frame::XController > (); +} + +void SAL_CALL ChartModel::impl_notifyCloseListeners() + throw( uno::RuntimeException) +{ + ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer + .getContainer( ::getCppuType((const uno::Reference< util::XCloseListener >*)0) ); + if( pIC ) + { + lang::EventObject aEvent( static_cast< lang::XComponent*>(this) ); + ::cppu::OInterfaceIteratorHelper aIt( *pIC ); + while( aIt.hasMoreElements() ) + { + uno::Reference< util::XCloseListener > xListener( aIt.next(), uno::UNO_QUERY ); + if( xListener.is() ) + xListener->notifyClosing( aEvent ); + } + } +} + +void ChartModel::impl_adjustAdditionalShapesPositionAndSize( const awt::Size& aVisualAreaSize ) +{ + uno::Reference< beans::XPropertySet > xProperties( static_cast< ::cppu::OWeakObject* >( this ), uno::UNO_QUERY ); + if ( xProperties.is() ) + { + uno::Reference< drawing::XShapes > xShapes; + xProperties->getPropertyValue( C2U( "AdditionalShapes" ) ) >>= xShapes; + if ( xShapes.is() ) + { + sal_Int32 nCount = xShapes->getCount(); + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + Reference< drawing::XShape > xShape; + if ( xShapes->getByIndex( i ) >>= xShape ) + { + if ( xShape.is() ) + { + awt::Point aPos( xShape->getPosition() ); + awt::Size aSize( xShape->getSize() ); + + double fWidth = static_cast< double >( aVisualAreaSize.Width ) / m_aVisualAreaSize.Width; + double fHeight = static_cast< double >( aVisualAreaSize.Height ) / m_aVisualAreaSize.Height; + + aPos.X = static_cast< long >( aPos.X * fWidth ); + aPos.Y = static_cast< long >( aPos.Y * fHeight ); + aSize.Width = static_cast< long >( aSize.Width * fWidth ); + aSize.Height = static_cast< long >( aSize.Height * fHeight ); + + xShape->setPosition( aPos ); + xShape->setSize( aSize ); + } + } + } + } + } +} + +//----------------------------------------------------------------- +// lang::XServiceInfo +//----------------------------------------------------------------- + +APPHELPER_XSERVICEINFO_IMPL(ChartModel,CHART_MODEL_SERVICE_IMPLEMENTATION_NAME) + +uno::Sequence< rtl::OUString > ChartModel::getSupportedServiceNames_Static() +{ + uno::Sequence< rtl::OUString > aSNS( 3 ); + aSNS[0] = CHART_MODEL_SERVICE_NAME; + aSNS[1] = C2U( "com.sun.star.document.OfficeDocument" ); + aSNS[2] = C2U( "com.sun.star.chart.ChartDocument" ); + //// @todo : add additional services if you support any further + return aSNS; +} + +//----------------------------------------------------------------- +// frame::XModel (required interface) +//----------------------------------------------------------------- + +sal_Bool SAL_CALL ChartModel::attachResource( const ::rtl::OUString& rURL + , const uno::Sequence< beans::PropertyValue >& rMediaDescriptor ) + throw(uno::RuntimeException) +{ + /* + The method attachResource() is used by the frame loader implementations + to inform the model about its URL and MediaDescriptor. + */ + + LifeTimeGuard aGuard(m_aLifeTimeManager); + if(!aGuard.startApiCall()) + return sal_False; //behave passive if already disposed or closed or throw exception @todo? + //mutex is acquired + + if(m_aResource.getLength()!=0)//we have a resource already //@todo? or is setting a new resource allowed? + return sal_False; + m_aResource = rURL; + m_aMediaDescriptor = rMediaDescriptor; + + //@todo ? check rURL ?? + //@todo ? evaluate m_aMediaDescriptor; + //@todo ? ... ??? --> nothing, this method is only for setting informations + + return sal_True; +} + +::rtl::OUString SAL_CALL ChartModel::getURL() throw(uno::RuntimeException) +{ + return impl_g_getLocation(); +} + +uno::Sequence< beans::PropertyValue > SAL_CALL ChartModel::getArgs() throw(uno::RuntimeException) +{ + /* + The method getArgs() returns a sequence of property values + that report the resource description according to com.sun.star.document.MediaDescriptor, + specified on loading or saving with storeAsURL. + */ + + LifeTimeGuard aGuard(m_aLifeTimeManager); + if(!aGuard.startApiCall()) + return uno::Sequence< beans::PropertyValue >(); //behave passive if already disposed or closed or throw exception @todo? + //mutex is acquired + + return m_aMediaDescriptor; +} + +void SAL_CALL ChartModel::connectController( const uno::Reference< frame::XController >& xController ) + throw(uno::RuntimeException) +{ + //@todo? this method is declared as oneway -> ...? + + LifeTimeGuard aGuard(m_aLifeTimeManager); + if(!aGuard.startApiCall()) + return ; //behave passive if already disposed or closed + //mutex is acquired + + //--add controller + m_aControllers.addInterface(xController); +} + +void SAL_CALL ChartModel::disconnectController( const uno::Reference< frame::XController >& xController ) + throw(uno::RuntimeException) +{ + //@todo? this method is declared as oneway -> ...? + + LifeTimeGuard aGuard(m_aLifeTimeManager); + if(!aGuard.startApiCall()) + return; //behave passive if already disposed or closed + + //--remove controller + m_aControllers.removeInterface(xController); + + //case: current controller is disconnected: + if( m_xCurrentController == xController ) + m_xCurrentController.clear(); + + DisposeHelper::DisposeAndClear( m_xRangeHighlighter ); +} + +void SAL_CALL ChartModel::lockControllers() throw(uno::RuntimeException) +{ + /* + suspends some notifications to the controllers which are used for display updates. + + The calls to lockControllers() and unlockControllers() may be nested + and even overlapping, but they must be in pairs. While there is at least one lock + remaining, some notifications for display updates are not broadcasted. + */ + + //@todo? this method is declared as oneway -> ...? + + LifeTimeGuard aGuard(m_aLifeTimeManager); + if(!aGuard.startApiCall()) + return; //behave passive if already disposed or closed or throw exception @todo? + ++m_nControllerLockCount; +} + +void SAL_CALL ChartModel::unlockControllers() throw(uno::RuntimeException) +{ + /* + resumes the notifications which were suspended by lockControllers() . + + The calls to lockControllers() and unlockControllers() may be nested + and even overlapping, but they must be in pairs. While there is at least one lock + remaining, some notifications for display updates are not broadcasted. + */ + + //@todo? this method is declared as oneway -> ...? + + LifeTimeGuard aGuard(m_aLifeTimeManager); + if(!aGuard.startApiCall()) + return; //behave passive if already disposed or closed or throw exception @todo? + if( m_nControllerLockCount == 0 ) + { + OSL_TRACE( "ChartModel: unlockControllers called with m_nControllerLockCount == 0" ); + return; + } + --m_nControllerLockCount; + if( m_nControllerLockCount == 0 && m_bUpdateNotificationsPending ) + { + aGuard.clear(); + impl_notifyModifiedListeners(); + } +} + +sal_Bool SAL_CALL ChartModel::hasControllersLocked() throw(uno::RuntimeException) +{ + LifeTimeGuard aGuard(m_aLifeTimeManager); + if(!aGuard.startApiCall()) + return sal_False; //behave passive if already disposed or closed or throw exception @todo? + return ( m_nControllerLockCount != 0 ) ; +} + +uno::Reference< frame::XController > SAL_CALL ChartModel::getCurrentController() throw(uno::RuntimeException) +{ + LifeTimeGuard aGuard(m_aLifeTimeManager); + if(!aGuard.startApiCall()) + throw lang::DisposedException(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "getCurrentController was called on an already disposed or closed model" ) ) + , static_cast< ::cppu::OWeakObject* >(this)); + + return impl_getCurrentController(); +} + +void SAL_CALL ChartModel::setCurrentController( const uno::Reference< frame::XController >& xController ) + throw(container::NoSuchElementException, uno::RuntimeException) +{ + LifeTimeGuard aGuard(m_aLifeTimeManager); + if(!aGuard.startApiCall()) + throw lang::DisposedException(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "setCurrentController was called on an already disposed or closed model" ) ) + , static_cast< ::cppu::OWeakObject* >(this)); + + //OSL_ENSURE( impl_isControllerConnected(xController), "setCurrentController is called with a Controller which is not connected" ); + if(!impl_isControllerConnected(xController)) + throw container::NoSuchElementException(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "setCurrentController is called with a Controller which is not connected" ) ) + , static_cast< ::cppu::OWeakObject* >(this)); + + m_xCurrentController = xController; + + DisposeHelper::DisposeAndClear( m_xRangeHighlighter ); +} + +uno::Reference< uno::XInterface > SAL_CALL ChartModel::getCurrentSelection() throw(uno::RuntimeException) +{ + LifeTimeGuard aGuard(m_aLifeTimeManager); + if(!aGuard.startApiCall()) + throw lang::DisposedException(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "getCurrentSelection was called on an already disposed or closed model" ) ) + , static_cast< ::cppu::OWeakObject* >(this)); + + + uno::Reference< uno::XInterface > xReturn; + uno::Reference< frame::XController > xController = impl_getCurrentController(); + + aGuard.clear(); + if( xController.is() ) + { + uno::Reference< view::XSelectionSupplier > xSelectionSupl( xController, uno::UNO_QUERY ); + if ( xSelectionSupl.is() ) + { + uno::Any aSel = xSelectionSupl->getSelection(); + rtl::OUString aObjectCID; + if( aSel >>= aObjectCID ) + { + xReturn.set( ObjectIdentifier::getObjectPropertySet( aObjectCID, Reference< XChartDocument >(this))); + } + } + } + return xReturn; +} + + +//----------------------------------------------------------------- +// lang::XComponent (base of XModel) +//----------------------------------------------------------------- +void SAL_CALL ChartModel::dispose() throw(uno::RuntimeException) +{ + //This object should release all resources and references in the + //easiest possible manner + //This object must notify all registered listeners using the method + //<member>XEventListener::disposing</member> + + //hold no mutex + if( !m_aLifeTimeManager.dispose() ) + return; + + //--release all resources and references + //// @todo + + m_xDataProvider.clear(); + m_xInternalDataProvider.clear(); + m_xNumberFormatsSupplier.clear(); + DisposeHelper::DisposeAndClear( m_xOwnNumberFormatsSupplier ); + DisposeHelper::DisposeAndClear( m_xChartTypeManager ); + DisposeHelper::DisposeAndClear( m_xDiagram ); + DisposeHelper::DisposeAndClear( m_xTitle ); + DisposeHelper::DisposeAndClear( m_xPageBackground ); + DisposeHelper::DisposeAndClear( m_xXMLNamespaceMap ); + + // not owner of storage +// if( m_xStorage.is()) +// { +// Reference< lang::XComponent > xComp( m_xStorage, uno::UNO_QUERY ); +// if( xComp.is()) +// xComp->dispose(); +// } + m_xStorage.clear(); + + if( m_xOldModelAgg.is()) + { + m_xOldModelAgg->setDelegator( 0 ); + m_xOldModelAgg.clear(); + } + + m_aControllers.disposeAndClear( lang::EventObject( static_cast< cppu::OWeakObject * >( this ))); + m_xCurrentController.clear(); + + m_xStorage.clear(); + m_xParent.clear(); + DisposeHelper::DisposeAndClear( m_xRangeHighlighter ); + OSL_TRACE( "ChartModel: dispose() called" ); +} + +void SAL_CALL ChartModel::addEventListener( const uno::Reference< lang::XEventListener > & xListener ) + throw(uno::RuntimeException) +{ + if( m_aLifeTimeManager.impl_isDisposedOrClosed() ) + return; //behave passive if already disposed or closed + + m_aLifeTimeManager.m_aListenerContainer.addInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0), xListener ); +} + +void SAL_CALL ChartModel::removeEventListener( const uno::Reference< lang::XEventListener > & xListener ) + throw(uno::RuntimeException) +{ + if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) ) + return; //behave passive if already disposed or closed + + m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0), xListener ); + return; +} + +//----------------------------------------------------------------- +// util::XCloseBroadcaster (base of XCloseable) +//----------------------------------------------------------------- +void SAL_CALL ChartModel::addCloseListener( const uno::Reference< util::XCloseListener > & xListener ) + throw(uno::RuntimeException) +{ + m_aLifeTimeManager.g_addCloseListener( xListener ); +} + +void SAL_CALL ChartModel::removeCloseListener( const uno::Reference< util::XCloseListener > & xListener ) + throw(uno::RuntimeException) +{ + if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) ) + return; //behave passive if already disposed or closed + + m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< util::XCloseListener >*)0), xListener ); + return; +} + +//----------------------------------------------------------------- +// util::XCloseable +//----------------------------------------------------------------- +void SAL_CALL ChartModel::close( sal_Bool bDeliverOwnership ) + throw( util::CloseVetoException, + uno::RuntimeException ) +{ + //hold no mutex + + if( !m_aLifeTimeManager.g_close_startTryClose( bDeliverOwnership ) ) + return; + //no mutex is acquired + + // At the end of this method may we must dispose ourself ... + // and may nobody from outside hold a reference to us ... + // then it's a good idea to do that by ourself. + uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) ); + + //the listeners have had no veto + //check wether we self can close + { + util::CloseVetoException aVetoException = util::CloseVetoException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "the model itself could not be closed" ) ) + , static_cast< ::cppu::OWeakObject* >(this)); + + if( m_aLifeTimeManager.g_close_isNeedToCancelLongLastingCalls( bDeliverOwnership, aVetoException ) ) + { + ////you can empty this block, if you never start longlasting calls or + ////if your longlasting calls are per default not cancelable (check how you have constructed your LifeTimeManager) + + sal_Bool bLongLastingCallsAreCanceled = sal_False; + try + { + //try to cancel running longlasting calls + //// @todo + } + catch( uno::Exception ) + { + //// @todo + //do not throw anything here!! (without endTryClose) + } + //if not successful canceled + if(!bLongLastingCallsAreCanceled) + { + m_aLifeTimeManager.g_close_endTryClose( bDeliverOwnership, sal_True ); + throw aVetoException; + } + } + + } + m_aLifeTimeManager.g_close_endTryClose_doClose(); + + // BM @todo: is it ok to call the listeners here? + impl_notifyCloseListeners(); +} + +//----------------------------------------------------------------- +// lang::XTypeProvider +//----------------------------------------------------------------- +uno::Sequence< uno::Type > SAL_CALL ChartModel::getTypes() + throw (uno::RuntimeException) +{ + uno::Reference< lang::XTypeProvider > xAggTypeProvider; + if( (m_xOldModelAgg->queryAggregation( ::getCppuType( & xAggTypeProvider )) >>= xAggTypeProvider) + && xAggTypeProvider.is()) + { + uno::Sequence< uno::Type > aOwnTypes( impl::ChartModel_Base::getTypes()); + uno::Sequence< uno::Type > aAggTypes( xAggTypeProvider->getTypes()); + uno::Sequence< uno::Type > aResult( aOwnTypes.getLength() + aAggTypes.getLength()); + sal_Int32 i=0; + for( ;i<aOwnTypes.getLength(); ++i ) + aResult[i] = aOwnTypes[i]; + for( sal_Int32 j=0; i<aResult.getLength(); ++j, ++i) + aResult[i] = aAggTypes[j]; + return aResult; + } + + return impl::ChartModel_Base::getTypes(); +} + +//----------------------------------------------------------------- +// document::XDocumentPropertiesSupplier +//----------------------------------------------------------------- +uno::Reference< document::XDocumentProperties > SAL_CALL + ChartModel::getDocumentProperties() throw (uno::RuntimeException) +{ + if ( !m_xDocumentProperties.is() ) + { + uno::Reference< document::XDocumentProperties > xDocProps( + ::comphelper::getProcessServiceFactory()->createInstance( + C2U("com.sun.star.document.DocumentProperties") ), uno::UNO_QUERY ); + m_xDocumentProperties.set(xDocProps); + } + return m_xDocumentProperties; +} + +//----------------------------------------------------------------- +// chart2::XChartDocument +//----------------------------------------------------------------- + +uno::Reference< chart2::XDiagram > SAL_CALL ChartModel::getFirstDiagram() + throw (uno::RuntimeException) +{ + MutexGuard aGuard( m_aModelMutex ); + return m_xDiagram; +} + +void SAL_CALL ChartModel::setFirstDiagram( const uno::Reference< chart2::XDiagram >& xDiagram ) + throw (uno::RuntimeException) +{ + Reference< chart2::XDiagram > xOldDiagram; + Reference< util::XModifyListener > xListener; + { + MutexGuard aGuard( m_aModelMutex ); + if( xDiagram == m_xDiagram ) + return; + xOldDiagram = m_xDiagram; + m_xDiagram = xDiagram; + xListener = this; + } + //don't keep the mutex locked while calling out + ModifyListenerHelper::removeListener( xOldDiagram, xListener ); + ModifyListenerHelper::addListener( xDiagram, xListener ); + setModified( sal_True ); +} + +Reference< chart2::data::XDataSource > ChartModel::impl_createDefaultData() +{ + Reference< chart2::data::XDataSource > xDataSource; + if( hasInternalDataProvider() ) + { + uno::Reference< lang::XInitialization > xIni(m_xInternalDataProvider,uno::UNO_QUERY); + if( xIni.is() ) + { + //init internal dataprovider + { + uno::Sequence< uno::Any > aArgs(1); + beans::NamedValue aParam(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreateDefaultData")),uno::makeAny(sal_True)); + aArgs[0] <<= aParam; + xIni->initialize(aArgs); + } + //create data + uno::Sequence< beans::PropertyValue > aArgs( 4 ); + aArgs[0] = beans::PropertyValue( + ::rtl::OUString::createFromAscii("CellRangeRepresentation"), -1, + uno::makeAny( C2U("all") ), beans::PropertyState_DIRECT_VALUE ); + aArgs[1] = beans::PropertyValue( + ::rtl::OUString::createFromAscii("HasCategories"), -1, + uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE ); + aArgs[2] = beans::PropertyValue( + ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1, + uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE ); + aArgs[3] = beans::PropertyValue( + ::rtl::OUString::createFromAscii("DataRowSource"), -1, + uno::makeAny( ::com::sun::star::chart::ChartDataRowSource_COLUMNS ), beans::PropertyState_DIRECT_VALUE ); + xDataSource = m_xInternalDataProvider->createDataSource( aArgs ); + } + } + return xDataSource; +} + +void SAL_CALL ChartModel::createInternalDataProvider( sal_Bool bCloneExistingData ) + throw (util::CloseVetoException, uno::RuntimeException) +{ + // don't lock the mutex, because this call calls out to code that tries to + // lock the solar mutex. On the other hand, a paint locks the solar mutex + // and calls to the model lock the model's mutex => deadlock + // @todo: lock a separate mutex in the InternalData class + if( !hasInternalDataProvider() ) + { + if( bCloneExistingData ) + m_xInternalDataProvider = ChartModelHelper::createInternalDataProvider( this, true ); + else + m_xInternalDataProvider = ChartModelHelper::createInternalDataProvider( Reference<XChartDocument>(), true ); + m_xDataProvider.set( m_xInternalDataProvider ); + } + setModified( sal_True ); +} + +sal_Bool SAL_CALL ChartModel::hasInternalDataProvider() + throw (uno::RuntimeException) +{ + return m_xDataProvider.is() && m_xInternalDataProvider.is(); +} + +uno::Reference< chart2::data::XDataProvider > SAL_CALL ChartModel::getDataProvider() + throw (uno::RuntimeException) +{ + // /-- + MutexGuard aGuard( m_aModelMutex ); + return m_xDataProvider; + // \-- +} + +// ____ XDataReceiver ____ + +void SAL_CALL ChartModel::attachDataProvider( const uno::Reference< chart2::data::XDataProvider >& xDataProvider ) + throw (uno::RuntimeException) +{ + { + // /-- + MutexGuard aGuard( m_aModelMutex ); + uno::Reference< beans::XPropertySet > xProp( xDataProvider, uno::UNO_QUERY ); + if( xProp.is() ) + { + try + { + sal_Bool bIncludeHiddenCells = ChartModelHelper::isIncludeHiddenCells( Reference< frame::XModel >(this) ); + xProp->setPropertyValue(C2U("IncludeHiddenCells"), uno::makeAny(bIncludeHiddenCells)); + } + catch( const beans::UnknownPropertyException& ) + { + } + } + + m_xDataProvider.set( xDataProvider ); + m_xInternalDataProvider.clear(); + + //the numberformatter is kept independent of the data provider! + // \-- + } + setModified( sal_True ); +} + +void SAL_CALL ChartModel::attachNumberFormatsSupplier( const uno::Reference< util::XNumberFormatsSupplier >& xNewSupplier ) + throw (uno::RuntimeException) +{ + { + // /-- + MutexGuard aGuard( m_aModelMutex ); + if( xNewSupplier==m_xNumberFormatsSupplier ) + return; + if( xNewSupplier==m_xOwnNumberFormatsSupplier ) + return; + if( m_xOwnNumberFormatsSupplier.is() && xNewSupplier.is() ) + { + //@todo + //merge missing numberformats from own to new formatter + } + else if( !xNewSupplier.is() ) + { + if( m_xNumberFormatsSupplier.is() ) + { + //@todo + //merge missing numberformats from old numberformatter to own numberformatter + //create own numberformatter if necessary + } + } + + m_xNumberFormatsSupplier.set( xNewSupplier ); + m_xOwnNumberFormatsSupplier.clear(); + // \-- + } + setModified( sal_True ); +} + +void SAL_CALL ChartModel::setArguments( const Sequence< beans::PropertyValue >& aArguments ) + throw (lang::IllegalArgumentException, + uno::RuntimeException) +{ + { + // /-- + MutexGuard aGuard( m_aModelMutex ); + if( !m_xDataProvider.is() ) + return; + lockControllers(); + + try + { + Reference< chart2::data::XDataSource > xDataSource( m_xDataProvider->createDataSource( aArguments ) ); + if( xDataSource.is() ) + { + // set new data + Reference< chart2::XChartTypeTemplate > xTemplate; + Reference< chart2::XDiagram > xDia( getFirstDiagram() ); + if( xDia.is()) + { + // apply new data + DiagramHelper::tTemplateWithServiceName aTemplateAndService = + DiagramHelper::getTemplateForDiagram( + xDia, Reference< lang::XMultiServiceFactory >( m_xChartTypeManager, uno::UNO_QUERY )); + xTemplate.set( aTemplateAndService.first ); + } + + if( !xTemplate.is()) + xTemplate.set( impl_createDefaultChartTypeTemplate() ); + + if( xTemplate.is()) + { + if( xDia.is()) + xTemplate->changeDiagramData( xDia, xDataSource, aArguments ); + else + setFirstDiagram( xTemplate->createDiagramByDataSource( xDataSource, aArguments ) ); + } + } + } + catch( lang::IllegalArgumentException & ) + { + throw; + } + catch( uno::Exception & ex ) + { + ASSERT_EXCEPTION( ex ); + } + unlockControllers(); + // \-- + } + setModified( sal_True ); +} + +Sequence< OUString > SAL_CALL ChartModel::getUsedRangeRepresentations() + throw (uno::RuntimeException) +{ + return DataSourceHelper::getUsedDataRanges( Reference< frame::XModel >(this)); +} + +Reference< chart2::data::XDataSource > SAL_CALL ChartModel::getUsedData() + throw (uno::RuntimeException) +{ + return DataSourceHelper::getUsedData( Reference< chart2::XChartDocument >(this)); +} + +Reference< chart2::data::XRangeHighlighter > SAL_CALL ChartModel::getRangeHighlighter() + throw (uno::RuntimeException) +{ + if( ! m_xRangeHighlighter.is()) + { + uno::Reference< view::XSelectionSupplier > xSelSupp( this->getCurrentController(), uno::UNO_QUERY ); + if( xSelSupp.is() ) + m_xRangeHighlighter.set( ChartModelHelper::createRangeHighlighter( xSelSupp )); + } + return m_xRangeHighlighter; +} + +Reference< chart2::XChartTypeTemplate > ChartModel::impl_createDefaultChartTypeTemplate() +{ + Reference< chart2::XChartTypeTemplate > xTemplate; + Reference< lang::XMultiServiceFactory > xFact( m_xChartTypeManager, uno::UNO_QUERY ); + if( xFact.is() ) + xTemplate.set( xFact->createInstance( C2U( "com.sun.star.chart2.template.Column" ) ), uno::UNO_QUERY ); + return xTemplate; +} + +void SAL_CALL ChartModel::setChartTypeManager( const uno::Reference< chart2::XChartTypeManager >& xNewManager ) + throw (uno::RuntimeException) +{ + { + // /-- + MutexGuard aGuard( m_aModelMutex ); + m_xChartTypeManager = xNewManager; + // \-- + } + setModified( sal_True ); +} + +uno::Reference< chart2::XChartTypeManager > SAL_CALL ChartModel::getChartTypeManager() + throw (uno::RuntimeException) +{ + // /-- + MutexGuard aGuard( m_aModelMutex ); + return m_xChartTypeManager; + // \-- +} + +uno::Reference< beans::XPropertySet > SAL_CALL ChartModel::getPageBackground() + throw (uno::RuntimeException) +{ + // /-- + MutexGuard aGuard( m_aModelMutex ); + return m_xPageBackground; + // \-- +} + +// ____ XTitled ____ +uno::Reference< chart2::XTitle > SAL_CALL ChartModel::getTitleObject() + throw (uno::RuntimeException) +{ + // /-- + MutexGuard aGuard( m_aModelMutex ); + return m_xTitle; + // \-- +} + +void SAL_CALL ChartModel::setTitleObject( const uno::Reference< chart2::XTitle >& xTitle ) + throw (uno::RuntimeException) +{ + { + // /-- + MutexGuard aGuard( m_aModelMutex ); + if( m_xTitle.is() ) + ModifyListenerHelper::removeListener( m_xTitle, this ); + m_xTitle = xTitle; + ModifyListenerHelper::addListener( m_xTitle, this ); + // \-- + } + setModified( sal_True ); +} + +void ChartModel::impl_createOldModelAgg() +{ + if( ! m_xOldModelAgg.is()) + { + m_xOldModelAgg.set( + m_xContext->getServiceManager()->createInstanceWithContext( + CHART_CHARTAPIWRAPPER_SERVICE_NAME, + m_xContext ), uno::UNO_QUERY_THROW ); + m_xOldModelAgg->setDelegator( static_cast< ::cppu::OWeakObject* >( this )); + } +} + +// ____ XInterface (for old API wrapper) ____ +uno::Any SAL_CALL ChartModel::queryInterface( const uno::Type& aType ) + throw (uno::RuntimeException) +{ + uno::Any aResult( impl::ChartModel_Base::queryInterface( aType )); + + if( ! aResult.hasValue()) + { + // try old API wrapper + try + { + impl_createOldModelAgg(); + if( m_xOldModelAgg.is()) + aResult = m_xOldModelAgg->queryAggregation( aType ); + } + catch( uno::Exception & ex ) + { + ASSERT_EXCEPTION( ex ); + } + } + + return aResult; +} + +// ____ XCloneable ____ +Reference< util::XCloneable > SAL_CALL ChartModel::createClone() + throw (uno::RuntimeException) +{ + return Reference< util::XCloneable >( new ChartModel( *this )); +} + +// ____ XVisualObject ____ +void SAL_CALL ChartModel::setVisualAreaSize( ::sal_Int64 nAspect, const awt::Size& aSize ) + throw (lang::IllegalArgumentException, + embed::WrongStateException, + uno::Exception, + uno::RuntimeException) +{ + if( nAspect == embed::Aspects::MSOLE_CONTENT ) + { + ControllerLockGuard aLockGuard( this ); + bool bChanged = + (m_aVisualAreaSize.Width != aSize.Width || + m_aVisualAreaSize.Height != aSize.Height); + + // #i12587# support for shapes in chart + if ( bChanged ) + { + impl_adjustAdditionalShapesPositionAndSize( aSize ); + } + + m_aVisualAreaSize = aSize; + if( bChanged ) + setModified( sal_True ); + } + else + { + OSL_ENSURE( false, "setVisualAreaSize: Aspect not implemented yet."); + } +} + +awt::Size SAL_CALL ChartModel::getVisualAreaSize( ::sal_Int64 nAspect ) + throw (lang::IllegalArgumentException, + embed::WrongStateException, + uno::Exception, + uno::RuntimeException) +{ + OSL_ENSURE( nAspect == embed::Aspects::MSOLE_CONTENT, + "No aspects other than content are supported" ); + (void)(nAspect); // avoid warning in non-debug builds + // other possible aspects are MSOLE_THUMBNAIL, MSOLE_ICON and MSOLE_DOCPRINT + + return m_aVisualAreaSize; +} + +embed::VisualRepresentation SAL_CALL ChartModel::getPreferredVisualRepresentation( ::sal_Int64 nAspect ) + throw (lang::IllegalArgumentException, + embed::WrongStateException, + uno::Exception, + uno::RuntimeException) +{ + OSL_ENSURE( nAspect == embed::Aspects::MSOLE_CONTENT, + "No aspects other than content are supported" ); + (void)(nAspect); // avoid warning in non-debug builds + + embed::VisualRepresentation aResult; + + try + { + Sequence< sal_Int8 > aMetafile; + + //get view from old api wrapper + Reference< datatransfer::XTransferable > xTransferable( + this->createInstance( CHART_VIEW_SERVICE_NAME ), uno::UNO_QUERY ); + if( xTransferable.is() ) + { + datatransfer::DataFlavor aDataFlavor( lcl_aGDIMetaFileMIMEType, + C2U( "GDIMetaFile" ), + ::getCppuType( (const uno::Sequence< sal_Int8 >*) 0 ) ); + + uno::Any aData( xTransferable->getTransferData( aDataFlavor ) ); + aData >>= aMetafile; + } + + aResult.Flavor.MimeType = lcl_aGDIMetaFileMIMEType; + aResult.Flavor.DataType = getCppuType( &aMetafile ); + + aResult.Data <<= aMetafile; + } + catch( uno::Exception & ex ) + { + ASSERT_EXCEPTION( ex ); + } + + return aResult; +} + +::sal_Int32 SAL_CALL ChartModel::getMapUnit( ::sal_Int64 nAspect ) + throw (uno::Exception, + uno::RuntimeException) +{ + OSL_ENSURE( nAspect == embed::Aspects::MSOLE_CONTENT, + "No aspects other than content are supported" ); + (void)(nAspect); // avoid warning in non-debug builds + return embed::EmbedMapUnits::ONE_100TH_MM; +} + +// ____ datatransfer::XTransferable ____ +uno::Any SAL_CALL ChartModel::getTransferData( const datatransfer::DataFlavor& aFlavor ) + throw (datatransfer::UnsupportedFlavorException, + io::IOException, + uno::RuntimeException) +{ + uno::Any aResult; + if( this->isDataFlavorSupported( aFlavor )) + { + try + { + //get view from old api wrapper + Reference< datatransfer::XTransferable > xTransferable( + this->createInstance( CHART_VIEW_SERVICE_NAME ), uno::UNO_QUERY ); + if( xTransferable.is() && + xTransferable->isDataFlavorSupported( aFlavor )) + { + aResult = xTransferable->getTransferData( aFlavor ); + } + } + catch( uno::Exception & ex ) + { + ASSERT_EXCEPTION( ex ); + } + } + else + { + throw datatransfer::UnsupportedFlavorException( + aFlavor.MimeType, static_cast< ::cppu::OWeakObject* >( this )); + } + + return aResult; +} + +Sequence< datatransfer::DataFlavor > SAL_CALL ChartModel::getTransferDataFlavors() + throw (uno::RuntimeException) +{ + uno::Sequence< datatransfer::DataFlavor > aRet(1); + +// aRet[0] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMEType, +// C2U( "GDIMetaFile" ), +// ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) ); + aRet[0] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMETypeHighContrast, + C2U( "GDIMetaFile" ), + ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) ); + + return aRet; +} + +::sal_Bool SAL_CALL ChartModel::isDataFlavorSupported( const datatransfer::DataFlavor& aFlavor ) + throw (uno::RuntimeException) +{ +// return ( aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMEType) || +// aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMETypeHighContrast) ); + return aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMETypeHighContrast); +} + + + +namespace +{ +enum eServiceType +{ + SERVICE_DASH_TABLE, + SERVICE_GARDIENT_TABLE, + SERVICE_HATCH_TABLE, + SERVICE_BITMAP_TABLE, + SERVICE_TRANSP_GRADIENT_TABLE, + SERVICE_MARKER_TABLE, + SERVICE_NAMESPACE_MAP +}; + +typedef ::std::map< ::rtl::OUString, enum eServiceType > tServiceNameMap; +typedef ::comphelper::MakeMap< ::rtl::OUString, enum eServiceType > tMakeServiceNameMap; + +tServiceNameMap & lcl_getStaticServiceNameMap() +{ + static tServiceNameMap aServiceNameMap( + tMakeServiceNameMap + ( C2U( "com.sun.star.drawing.DashTable" ), SERVICE_DASH_TABLE ) + ( C2U( "com.sun.star.drawing.GradientTable" ), SERVICE_GARDIENT_TABLE ) + ( C2U( "com.sun.star.drawing.HatchTable" ), SERVICE_HATCH_TABLE ) + ( C2U( "com.sun.star.drawing.BitmapTable" ), SERVICE_BITMAP_TABLE ) + ( C2U( "com.sun.star.drawing.TransparencyGradientTable" ), SERVICE_TRANSP_GRADIENT_TABLE ) + ( C2U( "com.sun.star.drawing.MarkerTable" ), SERVICE_MARKER_TABLE ) + ( C2U( "com.sun.star.xml.NamespaceMap" ), SERVICE_NAMESPACE_MAP ) + ); + return aServiceNameMap; +} +} +// ____ XMultiServiceFactory ____ +Reference< uno::XInterface > SAL_CALL ChartModel::createInstance( const OUString& rServiceSpecifier ) + throw( uno::Exception, uno::RuntimeException ) +{ + uno::Reference< uno::XInterface > xResult; + tServiceNameMap & rMap = lcl_getStaticServiceNameMap(); + + tServiceNameMap::const_iterator aIt( rMap.find( rServiceSpecifier )); + if( aIt != rMap.end()) + { + switch( (*aIt).second ) + { + case SERVICE_DASH_TABLE: + case SERVICE_GARDIENT_TABLE: + case SERVICE_HATCH_TABLE: + case SERVICE_BITMAP_TABLE: + case SERVICE_TRANSP_GRADIENT_TABLE: + case SERVICE_MARKER_TABLE: + { + uno::Reference< lang::XMultiServiceFactory > xFact( + this->createInstance( CHART_VIEW_SERVICE_NAME ), uno::UNO_QUERY ); + if ( xFact.is() ) + { + return xFact->createInstance( rServiceSpecifier ); + } + } + break; + case SERVICE_NAMESPACE_MAP: + return Reference< uno::XInterface >( m_xXMLNamespaceMap ); + } + } + else + { + impl_createOldModelAgg(); + if( m_xOldModelAgg.is() ) + { + Any aAny = m_xOldModelAgg->queryAggregation( ::getCppuType((const uno::Reference< lang::XMultiServiceFactory >*)0) ); + uno::Reference< lang::XMultiServiceFactory > xOldModelFactory; + if( (aAny >>= xOldModelFactory) && xOldModelFactory.is() ) + { + return xOldModelFactory->createInstance( rServiceSpecifier ); + } + } + } + return 0; +} + +Reference< uno::XInterface > SAL_CALL ChartModel::createInstanceWithArguments( + const OUString& rServiceSpecifier , const Sequence< Any >& Arguments ) + throw( uno::Exception, uno::RuntimeException ) +{ + OSL_ENSURE( Arguments.getLength(), "createInstanceWithArguments: Warning: Arguments are ignored" ); + (void)(Arguments); // avoid warning in non-debug builds + return createInstance( rServiceSpecifier ); +} + +Sequence< OUString > SAL_CALL ChartModel::getAvailableServiceNames() + throw( uno::RuntimeException ) +{ + uno::Sequence< ::rtl::OUString > aResult; + + impl_createOldModelAgg(); + if( m_xOldModelAgg.is()) + { + Any aAny = m_xOldModelAgg->queryAggregation( ::getCppuType((const uno::Reference< lang::XMultiServiceFactory >*)0) ); + uno::Reference< lang::XMultiServiceFactory > xOldModelFactory; + if( (aAny >>= xOldModelFactory) && xOldModelFactory.is() ) + { + return xOldModelFactory->getAvailableServiceNames(); + } + } + return aResult; +} + +Reference< util::XNumberFormatsSupplier > ChartModel::impl_getNumberFormatsSupplier() +{ + if( !m_xNumberFormatsSupplier.is() ) + { + if( !m_xOwnNumberFormatsSupplier.is() ) + { + Reference< lang::XMultiServiceFactory > xFactory( m_xContext->getServiceManager(), uno::UNO_QUERY ); + m_apSvNumberFormatter.reset( new SvNumberFormatter( xFactory, LANGUAGE_SYSTEM ) ); + m_xOwnNumberFormatsSupplier = new SvNumberFormatsSupplierObj( m_apSvNumberFormatter.get() ); + //pOwnNumberFormatter->ChangeStandardPrec( 15 ); todo? + } + m_xNumberFormatsSupplier = m_xOwnNumberFormatsSupplier; + } + return m_xNumberFormatsSupplier; +} + +// ____ XUnoTunnel ___ +::sal_Int64 SAL_CALL ChartModel::getSomething( const Sequence< ::sal_Int8 >& aIdentifier ) + throw( uno::RuntimeException) +{ + if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( SvNumberFormatsSupplierObj::getUnoTunnelId().getConstArray(), + aIdentifier.getConstArray(), 16 ) ) + { + Reference< lang::XUnoTunnel > xTunnel( impl_getNumberFormatsSupplier(), uno::UNO_QUERY ); + if( xTunnel.is() ) + return xTunnel->getSomething( aIdentifier ); + } + return 0; +} + +// ____ XNumberFormatsSupplier ____ +uno::Reference< beans::XPropertySet > SAL_CALL ChartModel::getNumberFormatSettings() + throw (uno::RuntimeException) +{ + Reference< util::XNumberFormatsSupplier > xSupplier( impl_getNumberFormatsSupplier() ); + if( xSupplier.is() ) + return xSupplier->getNumberFormatSettings(); + return uno::Reference< beans::XPropertySet >(); +} + +uno::Reference< util::XNumberFormats > SAL_CALL ChartModel::getNumberFormats() + throw (uno::RuntimeException) +{ + Reference< util::XNumberFormatsSupplier > xSupplier( impl_getNumberFormatsSupplier() ); + if( xSupplier.is() ) + return xSupplier->getNumberFormats(); + return uno::Reference< util::XNumberFormats >(); +} + +// ____ XChild ____ +Reference< uno::XInterface > SAL_CALL ChartModel::getParent() + throw (uno::RuntimeException) +{ + return Reference< uno::XInterface >(m_xParent,uno::UNO_QUERY); +} + +void SAL_CALL ChartModel::setParent( const Reference< uno::XInterface >& Parent ) + throw (lang::NoSupportException, + uno::RuntimeException) +{ + if( Parent != m_xParent ) + m_xParent.set( Parent, uno::UNO_QUERY ); +} + +// ____ XUndoManager ____ +Reference< chart2::XUndoManager > SAL_CALL ChartModel::getUndoManager() + throw (uno::RuntimeException) +{ + return m_xUndoManager; +} + +// ____ XDataSource ____ +uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > SAL_CALL ChartModel::getDataSequences() + throw (uno::RuntimeException) +{ + Reference< chart2::data::XDataSource > xSource( + DataSourceHelper::getUsedData( uno::Reference< frame::XModel >(this) ) ); + if( xSource.is()) + return xSource->getDataSequences(); + + return uno::Sequence< Reference< chart2::data::XLabeledDataSequence > >(); +} + +} // namespace chart |