merge the formfield patch from ooo-build
[ooovba.git] / chart2 / source / model / main / ChartModel.cxx
blob1289f925c8f95e4820a08d4fbfd353c198d21d48
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ChartModel.cxx,v $
10 * $Revision: 1.17.8.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
33 #include "ChartModel.hxx"
34 #include "ImplChartModel.hxx"
35 #include "servicenames.hxx"
36 #include "MediaDescriptorHelper.hxx"
37 #include "macros.hxx"
38 #include "InternalData.hxx"
39 #include "servicenames.hxx"
40 #include "DataSourceHelper.hxx"
41 #include "NoWarningThisInCTOR.hxx"
42 #include "ChartModelHelper.hxx"
43 #include "DisposeHelper.hxx"
44 #include "ControllerLockGuard.hxx"
45 #include "ObjectIdentifier.hxx"
46 #include "ChartModelHelper.hxx"
48 #include <comphelper/InlineContainer.hxx>
49 #include <comphelper/processfactory.hxx>
51 // header for class SvNumberFormatsSupplierObj
52 #include <svtools/numuno.hxx>
53 #include <com/sun/star/lang/DisposedException.hpp>
54 #include <com/sun/star/lang/XInitialization.hpp>
55 #include <com/sun/star/view/XSelectionSupplier.hpp>
56 #include <com/sun/star/embed/XEmbedObjectCreator.hpp>
57 #include <com/sun/star/embed/XEmbedPersist.hpp>
58 #include <com/sun/star/embed/EmbedStates.hpp>
59 #include <com/sun/star/embed/XComponentSupplier.hpp>
60 #include <com/sun/star/embed/XStorage.hpp>
61 #include <com/sun/star/embed/EmbedMapUnits.hpp>
62 #include <com/sun/star/embed/Aspects.hpp>
63 #include <com/sun/star/awt/XWindow.hpp>
64 #include <com/sun/star/awt/PosSize.hpp>
65 #include <com/sun/star/datatransfer/XTransferable.hpp>
67 #include <map>
68 #include <algorithm>
70 using ::com::sun::star::uno::Sequence;
71 using ::com::sun::star::uno::Reference;
72 using ::com::sun::star::uno::Any;
73 using ::rtl::OUString;
74 using ::osl::MutexGuard;
76 using namespace ::com::sun::star;
77 using namespace ::apphelper;
79 namespace
81 const OUString lcl_aGDIMetaFileMIMEType(
82 RTL_CONSTASCII_USTRINGPARAM("application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\""));
83 const OUString lcl_aGDIMetaFileMIMETypeHighContrast(
84 RTL_CONSTASCII_USTRINGPARAM("application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\""));
86 } // anonymous namespace
88 //-----------------------------------------------------------------
89 // ChartModel Constructor and Destructor
90 //-----------------------------------------------------------------
92 namespace chart
95 ChartModel::ChartModel(uno::Reference<uno::XComponentContext > const & xContext)
96 : m_aLifeTimeManager( this, this )
97 , m_bReadOnly( sal_False )
98 , m_bModified( sal_False )
99 , m_nInLoad(0)
100 , m_bUpdateNotificationsPending(false)
101 , m_aControllers( m_aModelMutex )
102 , m_nControllerLockCount(0)
103 , m_xContext( xContext )
104 // default visual area is 8 x 7 cm
105 , m_aVisualAreaSize( 8000, 7000 )
107 OSL_TRACE( "ChartModel: CTOR called" );
109 // attention: passing this as reference to ImplChartModel
110 m_pImplChartModel.reset( new impl::ImplChartModel( xContext, this ));
113 ChartModel::ChartModel( const ChartModel & rOther )
114 : impl::ChartModel_Base()
115 , m_aLifeTimeManager( this, this )
116 , m_bReadOnly( rOther.m_bReadOnly )
117 , m_bModified( rOther.m_bModified )
118 , m_nInLoad(0)
119 , m_bUpdateNotificationsPending(false)
120 , m_aResource( rOther.m_aResource )
121 , m_aMediaDescriptor( rOther.m_aMediaDescriptor )
122 , m_aControllers( m_aModelMutex )
123 , m_nControllerLockCount(0)
124 , m_xContext( rOther.m_xContext )
125 // @note: the old model aggregate must not be shared with other models if it
126 // is, you get mutex deadlocks
127 , m_xOldModelAgg( 0 ) //rOther.m_xOldModelAgg )
128 , m_xStorage( 0 ) //rOther.m_xStorage )
129 , m_aVisualAreaSize( rOther.m_aVisualAreaSize )
130 , m_aGraphicObjectVector( rOther.m_aGraphicObjectVector )
132 OSL_TRACE( "ChartModel: Copy-CTOR called" );
134 // attention: passing this as reference to ImplChartModel
135 if( rOther.m_pImplChartModel.get())
136 m_pImplChartModel.reset( new impl::ImplChartModel( * rOther.m_pImplChartModel.get(), this ));
137 else
138 m_pImplChartModel.reset( new impl::ImplChartModel( m_xContext, this ));
141 ChartModel::~ChartModel()
143 OSL_TRACE( "ChartModel: DTOR called" );
144 if( m_xOldModelAgg.is())
145 m_xOldModelAgg->setDelegator( 0 );
149 //-----------------------------------------------------------------
150 // private methods
151 //-----------------------------------------------------------------
153 ::rtl::OUString ChartModel
154 ::impl_g_getLocation()
157 LifeTimeGuard aGuard(m_aLifeTimeManager);
158 if(!aGuard.startApiCall())
159 return ::rtl::OUString(); //behave passive if already disposed or closed or throw exception @todo?
160 //mutex is acquired
161 return m_aResource;
164 sal_Bool ChartModel
165 ::impl_isControllerConnected( const uno::Reference< frame::XController >& xController )
169 uno::Sequence< uno::Reference<uno::XInterface> > aSeq = m_aControllers.getElements();
170 for( sal_Int32 nN = aSeq.getLength(); nN--; )
172 if( aSeq[nN] == xController )
173 return sal_True;
176 catch( uno::Exception )
179 return sal_False;
182 uno::Reference< frame::XController > ChartModel
183 ::impl_getCurrentController() throw(uno::RuntimeException)
185 //@todo? hold only weak references to controllers
187 // get the last active controller of this model
188 if( m_xCurrentController.is() )
189 return m_xCurrentController;
191 // get the first controller of this model
192 if( m_aControllers.getLength() )
194 uno::Reference<uno::XInterface> xI = m_aControllers.getElements()[0];
195 return uno::Reference<frame::XController>( xI, uno::UNO_QUERY );
198 //return nothing if no controllers are connected at all
199 return uno::Reference< frame::XController > ();
202 void SAL_CALL ChartModel
203 ::impl_notifyCloseListeners()
204 throw( uno::RuntimeException)
206 ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
207 .getContainer( ::getCppuType((const uno::Reference< util::XCloseListener >*)0) );
208 if( pIC )
210 lang::EventObject aEvent( static_cast< lang::XComponent*>(this) );
211 ::cppu::OInterfaceIteratorHelper aIt( *pIC );
212 while( aIt.hasMoreElements() )
213 (static_cast< util::XCloseListener*>(aIt.next()))->notifyClosing( aEvent );
217 //-----------------------------------------------------------------
218 // lang::XServiceInfo
219 //-----------------------------------------------------------------
221 APPHELPER_XSERVICEINFO_IMPL(ChartModel,CHART_MODEL_SERVICE_IMPLEMENTATION_NAME)
223 uno::Sequence< rtl::OUString > ChartModel
224 ::getSupportedServiceNames_Static()
226 uno::Sequence< rtl::OUString > aSNS( 3 );
227 aSNS[0] = CHART_MODEL_SERVICE_NAME;
228 aSNS[1] = C2U( "com.sun.star.document.OfficeDocument" );
229 aSNS[2] = C2U( "com.sun.star.chart.ChartDocument" );
230 //// @todo : add additional services if you support any further
231 return aSNS;
234 //-----------------------------------------------------------------
235 // frame::XModel (required interface)
236 //-----------------------------------------------------------------
238 sal_Bool SAL_CALL ChartModel
239 ::attachResource( const ::rtl::OUString& rURL
240 , const uno::Sequence< beans::PropertyValue >& rMediaDescriptor )
241 throw(uno::RuntimeException)
244 The method attachResource() is used by the frame loader implementations
245 to inform the model about its URL and MediaDescriptor.
248 LifeTimeGuard aGuard(m_aLifeTimeManager);
249 if(!aGuard.startApiCall())
250 return sal_False; //behave passive if already disposed or closed or throw exception @todo?
251 //mutex is acquired
253 if(m_aResource.getLength()!=0)//we have a resource already //@todo? or is setting a new resource allowed?
254 return sal_False;
255 m_aResource = rURL;
256 m_aMediaDescriptor = rMediaDescriptor;
258 //@todo ? check rURL ??
259 //@todo ? evaluate m_aMediaDescriptor;
260 //@todo ? ... ??? --> nothing, this method is only for setting informations
262 return sal_True;
265 ::rtl::OUString SAL_CALL ChartModel
266 ::getURL() throw(uno::RuntimeException)
268 return impl_g_getLocation();
271 uno::Sequence< beans::PropertyValue > SAL_CALL ChartModel
272 ::getArgs() throw(uno::RuntimeException)
275 The method getArgs() returns a sequence of property values
276 that report the resource description according to com.sun.star.document.MediaDescriptor,
277 specified on loading or saving with storeAsURL.
280 LifeTimeGuard aGuard(m_aLifeTimeManager);
281 if(!aGuard.startApiCall())
282 return uno::Sequence< beans::PropertyValue >(); //behave passive if already disposed or closed or throw exception @todo?
283 //mutex is acquired
285 return m_aMediaDescriptor;
288 void SAL_CALL ChartModel
289 ::connectController( const uno::Reference< frame::XController >& xController )
290 throw(uno::RuntimeException)
292 //@todo? this method is declared as oneway -> ...?
294 LifeTimeGuard aGuard(m_aLifeTimeManager);
295 if(!aGuard.startApiCall())
296 return ; //behave passive if already disposed or closed
297 //mutex is acquired
299 //--add controller
300 m_aControllers.addInterface(xController);
303 void SAL_CALL ChartModel
304 ::disconnectController( const uno::Reference< frame::XController >& xController )
305 throw(uno::RuntimeException)
307 //@todo? this method is declared as oneway -> ...?
309 LifeTimeGuard aGuard(m_aLifeTimeManager);
310 if(!aGuard.startApiCall())
311 return; //behave passive if already disposed or closed
313 //--remove controller
314 m_aControllers.removeInterface(xController);
316 //case: current controller is disconnected:
317 if( m_xCurrentController == xController )
318 m_xCurrentController.clear();
320 DisposeHelper::DisposeAndClear( m_xRangeHighlighter );
323 void SAL_CALL ChartModel
324 ::lockControllers() throw(uno::RuntimeException)
327 suspends some notifications to the controllers which are used for display updates.
329 The calls to lockControllers() and unlockControllers() may be nested
330 and even overlapping, but they must be in pairs. While there is at least one lock
331 remaining, some notifications for display updates are not broadcasted.
334 //@todo? this method is declared as oneway -> ...?
336 LifeTimeGuard aGuard(m_aLifeTimeManager);
337 if(!aGuard.startApiCall())
338 return; //behave passive if already disposed or closed or throw exception @todo?
339 ++m_nControllerLockCount;
342 void SAL_CALL ChartModel
343 ::unlockControllers() throw(uno::RuntimeException)
346 resumes the notifications which were suspended by lockControllers() .
348 The calls to lockControllers() and unlockControllers() may be nested
349 and even overlapping, but they must be in pairs. While there is at least one lock
350 remaining, some notifications for display updates are not broadcasted.
353 //@todo? this method is declared as oneway -> ...?
355 LifeTimeGuard aGuard(m_aLifeTimeManager);
356 if(!aGuard.startApiCall())
357 return; //behave passive if already disposed or closed or throw exception @todo?
358 if( m_nControllerLockCount == 0 )
360 OSL_TRACE( "ChartModel: unlockControllers called with m_nControllerLockCount == 0" );
361 return;
363 --m_nControllerLockCount;
364 if( m_nControllerLockCount == 0 && m_bUpdateNotificationsPending )
366 aGuard.clear();
367 impl_notifyModifiedListeners();
371 sal_Bool SAL_CALL ChartModel
372 ::hasControllersLocked() throw(uno::RuntimeException)
374 LifeTimeGuard aGuard(m_aLifeTimeManager);
375 if(!aGuard.startApiCall())
376 return sal_False; //behave passive if already disposed or closed or throw exception @todo?
377 return ( m_nControllerLockCount != 0 ) ;
380 uno::Reference< frame::XController > SAL_CALL ChartModel
381 ::getCurrentController() throw(uno::RuntimeException)
383 LifeTimeGuard aGuard(m_aLifeTimeManager);
384 if(!aGuard.startApiCall())
385 throw lang::DisposedException(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
386 "getCurrentController was called on an already disposed or closed model" ) )
387 , static_cast< ::cppu::OWeakObject* >(this));
389 return impl_getCurrentController();
392 void SAL_CALL ChartModel
393 ::setCurrentController( const uno::Reference< frame::XController >& xController )
394 throw(container::NoSuchElementException, uno::RuntimeException)
396 LifeTimeGuard aGuard(m_aLifeTimeManager);
397 if(!aGuard.startApiCall())
398 throw lang::DisposedException(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
399 "setCurrentController was called on an already disposed or closed model" ) )
400 , static_cast< ::cppu::OWeakObject* >(this));
402 //OSL_ENSURE( impl_isControllerConnected(xController), "setCurrentController is called with a Controller which is not connected" );
403 if(!impl_isControllerConnected(xController))
404 throw container::NoSuchElementException(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
405 "setCurrentController is called with a Controller which is not connected" ) )
406 , static_cast< ::cppu::OWeakObject* >(this));
408 m_xCurrentController = xController;
410 DisposeHelper::DisposeAndClear( m_xRangeHighlighter );
413 uno::Reference< uno::XInterface > SAL_CALL ChartModel
414 ::getCurrentSelection() throw(uno::RuntimeException)
416 LifeTimeGuard aGuard(m_aLifeTimeManager);
417 if(!aGuard.startApiCall())
418 throw lang::DisposedException(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
419 "getCurrentSelection was called on an already disposed or closed model" ) )
420 , static_cast< ::cppu::OWeakObject* >(this));
423 uno::Reference< uno::XInterface > xReturn;
424 uno::Reference< frame::XController > xController = impl_getCurrentController();
426 aGuard.clear();
427 if( xController.is() )
429 uno::Reference< view::XSelectionSupplier > xSelectionSupl( xController, uno::UNO_QUERY );
430 if ( xSelectionSupl.is() )
432 uno::Any aSel = xSelectionSupl->getSelection();
433 rtl::OUString aObjectCID;
434 if( aSel >>= aObjectCID )
436 xReturn.set( ObjectIdentifier::getObjectPropertySet( aObjectCID, Reference< XChartDocument >(this)));
440 return xReturn;
444 //-----------------------------------------------------------------
445 // lang::XComponent (base of XModel)
446 //-----------------------------------------------------------------
447 void SAL_CALL ChartModel
448 ::dispose() throw(uno::RuntimeException)
450 //This object should release all resources and references in the
451 //easiest possible manner
452 //This object must notify all registered listeners using the method
453 //<member>XEventListener::disposing</member>
455 //hold no mutex
456 if( !m_aLifeTimeManager.dispose() )
457 return;
459 //--release all resources and references
460 //// @todo
461 if( m_pImplChartModel.get())
462 m_pImplChartModel->dispose();
464 // not owner of storage
465 // if( m_xStorage.is())
466 // {
467 // Reference< lang::XComponent > xComp( m_xStorage, uno::UNO_QUERY );
468 // if( xComp.is())
469 // xComp->dispose();
470 // }
471 m_xStorage.clear();
473 if( m_xOldModelAgg.is())
475 m_xOldModelAgg->setDelegator( 0 );
476 m_xOldModelAgg.clear();
479 m_aControllers.disposeAndClear( lang::EventObject( static_cast< cppu::OWeakObject * >( this )));
480 m_xCurrentController.clear();
482 m_xStorage.clear();
483 m_xParent.clear();
484 DisposeHelper::DisposeAndClear( m_xRangeHighlighter );
485 OSL_TRACE( "ChartModel: dispose() called" );
488 void SAL_CALL ChartModel
489 ::addEventListener( const uno::Reference< lang::XEventListener > & xListener )
490 throw(uno::RuntimeException)
492 if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
493 return; //behave passive if already disposed or closed
495 m_aLifeTimeManager.m_aListenerContainer.addInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0), xListener );
498 void SAL_CALL ChartModel
499 ::removeEventListener( const uno::Reference< lang::XEventListener > & xListener )
500 throw(uno::RuntimeException)
502 if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
503 return; //behave passive if already disposed or closed
505 m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0), xListener );
506 return;
509 //-----------------------------------------------------------------
510 // util::XCloseBroadcaster (base of XCloseable)
511 //-----------------------------------------------------------------
512 void SAL_CALL ChartModel
513 ::addCloseListener( const uno::Reference< util::XCloseListener > & xListener )
514 throw(uno::RuntimeException)
516 m_aLifeTimeManager.g_addCloseListener( xListener );
519 void SAL_CALL ChartModel
520 ::removeCloseListener( const uno::Reference< util::XCloseListener > & xListener )
521 throw(uno::RuntimeException)
523 if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
524 return; //behave passive if already disposed or closed
526 m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< util::XCloseListener >*)0), xListener );
527 return;
530 //-----------------------------------------------------------------
531 // util::XCloseable
532 //-----------------------------------------------------------------
533 void SAL_CALL ChartModel
534 ::close( sal_Bool bDeliverOwnership )
535 throw( util::CloseVetoException,
536 uno::RuntimeException )
538 //hold no mutex
540 if( !m_aLifeTimeManager.g_close_startTryClose( bDeliverOwnership ) )
541 return;
542 //no mutex is acquired
544 // At the end of this method may we must dispose ourself ...
545 // and may nobody from outside hold a reference to us ...
546 // then it's a good idea to do that by ourself.
547 uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) );
549 //the listeners have had no veto
550 //check wether we self can close
552 util::CloseVetoException aVetoException = util::CloseVetoException(
553 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
554 "the model itself could not be closed" ) )
555 , static_cast< ::cppu::OWeakObject* >(this));
557 if( m_aLifeTimeManager.g_close_isNeedToCancelLongLastingCalls( bDeliverOwnership, aVetoException ) )
559 ////you can empty this block, if you never start longlasting calls or
560 ////if your longlasting calls are per default not cancelable (check how you have constructed your LifeTimeManager)
562 sal_Bool bLongLastingCallsAreCanceled = sal_False;
565 //try to cancel running longlasting calls
566 //// @todo
568 catch( uno::Exception )
570 //// @todo
571 //do not throw anything here!! (without endTryClose)
573 //if not successful canceled
574 if(!bLongLastingCallsAreCanceled)
576 m_aLifeTimeManager.g_close_endTryClose( bDeliverOwnership, sal_True );
577 throw aVetoException;
582 m_aLifeTimeManager.g_close_endTryClose_doClose();
584 // BM @todo: is it ok to call the listeners here?
585 impl_notifyCloseListeners();
588 //-----------------------------------------------------------------
589 // lang::XTypeProvider
590 //-----------------------------------------------------------------
591 uno::Sequence< uno::Type > SAL_CALL ChartModel
592 ::getTypes()
593 throw (uno::RuntimeException)
595 uno::Reference< lang::XTypeProvider > xAggTypeProvider;
596 if( (m_xOldModelAgg->queryAggregation( ::getCppuType( & xAggTypeProvider )) >>= xAggTypeProvider)
597 && xAggTypeProvider.is())
599 uno::Sequence< uno::Type > aOwnTypes( impl::ChartModel_Base::getTypes());
600 uno::Sequence< uno::Type > aAggTypes( xAggTypeProvider->getTypes());
601 uno::Sequence< uno::Type > aResult( aOwnTypes.getLength() + aAggTypes.getLength());
602 sal_Int32 i=0;
603 for( ;i<aOwnTypes.getLength(); ++i )
604 aResult[i] = aOwnTypes[i];
605 for( sal_Int32 j=0; i<aResult.getLength(); ++j, ++i)
606 aResult[i] = aAggTypes[j];
607 return aResult;
610 return impl::ChartModel_Base::getTypes();
613 //-----------------------------------------------------------------
614 // document::XDocumentPropertiesSupplier
615 //-----------------------------------------------------------------
616 uno::Reference< document::XDocumentProperties > SAL_CALL
617 ChartModel::getDocumentProperties() throw (uno::RuntimeException)
619 if ( !m_xDocumentProperties.is() )
621 uno::Reference< document::XDocumentProperties > xDocProps(
622 ::comphelper::getProcessServiceFactory()->createInstance(
623 C2U("com.sun.star.document.DocumentProperties") ), uno::UNO_QUERY );
624 m_xDocumentProperties.set(xDocProps);
626 return m_xDocumentProperties;
629 //-----------------------------------------------------------------
630 // chart2::XChartDocument
631 //-----------------------------------------------------------------
633 uno::Reference< chart2::XDiagram > SAL_CALL ChartModel
634 ::getFirstDiagram()
635 throw (uno::RuntimeException)
637 OSL_ASSERT( m_pImplChartModel.get() != 0 );
638 // /--
639 MutexGuard aGuard( m_aModelMutex );
642 return m_pImplChartModel->GetDiagram( 0 );
644 catch( container::NoSuchElementException )
648 return uno::Reference< chart2::XDiagram >();
649 // \--
652 void SAL_CALL ChartModel
653 ::setFirstDiagram( const uno::Reference< chart2::XDiagram >& xDiagram )
654 throw (uno::RuntimeException)
656 OSL_ASSERT( m_pImplChartModel.get() != 0 );
658 // /--
659 MutexGuard aGuard( m_aModelMutex );
660 m_pImplChartModel->RemoveAllDiagrams();
661 m_pImplChartModel->AppendDiagram( xDiagram );
662 // \--
664 setModified( sal_True );
667 void SAL_CALL ChartModel
668 ::createInternalDataProvider( sal_Bool bCloneExistingData )
669 throw (util::CloseVetoException,
670 uno::RuntimeException)
672 OSL_ASSERT( m_pImplChartModel.get() != 0 );
673 // don't lock the mutex, because this call calls out to code that tries to
674 // lock the solar mutex. On the other hand, a paint locks the solar mutex
675 // and calls to the model lock the model's mutex => deadlock
676 // @todo: lock a separate mutex in the InternalData class
677 m_pImplChartModel->CreateInternalDataProvider( bCloneExistingData, this );
678 setModified( sal_True );
681 sal_Bool SAL_CALL ChartModel::hasInternalDataProvider()
682 throw (uno::RuntimeException)
684 return m_pImplChartModel->HasInternalDataProvider();
687 uno::Reference< chart2::data::XDataProvider > SAL_CALL ChartModel
688 ::getDataProvider()
689 throw (uno::RuntimeException)
691 OSL_ASSERT( m_pImplChartModel.get() != 0 );
692 // /--
693 MutexGuard aGuard( m_aModelMutex );
694 return m_pImplChartModel->GetDataProvider();
695 // \--
698 // ____ XDataReceiver ____
700 void SAL_CALL ChartModel
701 ::attachDataProvider( const uno::Reference< chart2::data::XDataProvider >& xProvider )
702 throw (uno::RuntimeException)
704 OSL_ASSERT( m_pImplChartModel.get() != 0 );
706 // /--
707 MutexGuard aGuard( m_aModelMutex );
708 uno::Reference< beans::XPropertySet > xProp( xProvider, uno::UNO_QUERY );
709 if( xProp.is() )
713 sal_Bool bIncludeHiddenCells = ChartModelHelper::isIncludeHiddenCells( Reference< frame::XModel >(this) );
714 xProp->setPropertyValue(C2U("IncludeHiddenCells"), uno::makeAny(bIncludeHiddenCells));
716 catch( const beans::UnknownPropertyException& )
721 m_pImplChartModel->SetDataProvider( xProvider );
722 // \--
724 setModified( sal_True );
727 void SAL_CALL ChartModel
728 ::attachNumberFormatsSupplier( const uno::Reference< util::XNumberFormatsSupplier >& xSupplier )
729 throw (uno::RuntimeException)
731 OSL_ASSERT( m_pImplChartModel.get() != 0 );
733 // /--
734 MutexGuard aGuard( m_aModelMutex );
735 m_pImplChartModel->SetNumberFormatsSupplier( xSupplier );
736 // \--
738 setModified( sal_True );
741 void SAL_CALL ChartModel
742 ::setArguments( const Sequence< beans::PropertyValue >& aArguments )
743 throw (lang::IllegalArgumentException,
744 uno::RuntimeException)
746 OSL_ASSERT( m_pImplChartModel.get() != 0 );
748 // /--
749 MutexGuard aGuard( m_aModelMutex );
750 lockControllers();
753 m_pImplChartModel->SetArguments( aArguments, true /* bSetData */ );
755 catch( const uno::Exception & ex )
757 ASSERT_EXCEPTION( ex );
759 unlockControllers();
760 // \--
762 setModified( sal_True );
765 Sequence< OUString > SAL_CALL ChartModel
766 ::getUsedRangeRepresentations()
767 throw (uno::RuntimeException)
769 return DataSourceHelper::getUsedDataRanges( Reference< frame::XModel >(this));
772 Reference< chart2::data::XDataSource > SAL_CALL ChartModel
773 ::getUsedData()
774 throw (uno::RuntimeException)
776 return DataSourceHelper::getUsedData( Reference< chart2::XChartDocument >(this));
779 Reference< chart2::data::XRangeHighlighter > SAL_CALL ChartModel
780 ::getRangeHighlighter()
781 throw (uno::RuntimeException)
783 if( ! m_xRangeHighlighter.is())
785 uno::Reference< view::XSelectionSupplier > xSelSupp( this->getCurrentController(), uno::UNO_QUERY );
786 if( xSelSupp.is() )
787 m_xRangeHighlighter.set( ChartModelHelper::createRangeHighlighter( xSelSupp ));
789 return m_xRangeHighlighter;
793 void SAL_CALL ChartModel
794 ::setChartTypeManager( const uno::Reference< chart2::XChartTypeManager >& xNewManager )
795 throw (uno::RuntimeException)
797 OSL_ASSERT( m_pImplChartModel.get() != 0 );
799 // /--
800 MutexGuard aGuard( m_aModelMutex );
801 m_pImplChartModel->SetChartTypeManager( xNewManager );
802 // \--
804 setModified( sal_True );
807 uno::Reference< chart2::XChartTypeManager > SAL_CALL ChartModel
808 ::getChartTypeManager()
809 throw (uno::RuntimeException)
811 OSL_ASSERT( m_pImplChartModel.get() != 0 );
812 // /--
813 MutexGuard aGuard( m_aModelMutex );
814 return m_pImplChartModel->GetChartTypeManager();
815 // \--
818 uno::Reference< beans::XPropertySet > SAL_CALL ChartModel
819 ::getPageBackground()
820 throw (uno::RuntimeException)
822 OSL_ASSERT( m_pImplChartModel.get() != 0 );
823 // /--
824 MutexGuard aGuard( m_aModelMutex );
825 return m_pImplChartModel->GetPageBackground();
826 // \--
829 // ____ XTitled ____
830 uno::Reference< chart2::XTitle > SAL_CALL ChartModel::getTitleObject()
831 throw (uno::RuntimeException)
833 OSL_ASSERT( m_pImplChartModel.get() != 0 );
834 // /--
835 MutexGuard aGuard( m_aModelMutex );
836 return m_pImplChartModel->GetTitle();
837 // \--
840 void SAL_CALL ChartModel::setTitleObject(
841 const uno::Reference<
842 chart2::XTitle >& Title )
843 throw (uno::RuntimeException)
845 OSL_ASSERT( m_pImplChartModel.get() != 0 );
847 // /--
848 MutexGuard aGuard( m_aModelMutex );
849 m_pImplChartModel->SetTitle( Title );
850 // \--
852 setModified( sal_True );
855 void ChartModel::impl_createOldModelAgg()
857 if( ! m_xOldModelAgg.is())
859 m_xOldModelAgg.set(
860 m_xContext->getServiceManager()->createInstanceWithContext(
861 CHART_CHARTAPIWRAPPER_SERVICE_NAME,
862 m_xContext ), uno::UNO_QUERY_THROW );
863 m_xOldModelAgg->setDelegator( static_cast< ::cppu::OWeakObject* >( this ));
867 // ____ XInterface (for old API wrapper) ____
868 uno::Any SAL_CALL ChartModel::queryInterface( const uno::Type& aType )
869 throw (uno::RuntimeException)
871 uno::Any aResult( impl::ChartModel_Base::queryInterface( aType ));
873 if( ! aResult.hasValue())
875 // try old API wrapper
878 impl_createOldModelAgg();
879 if( m_xOldModelAgg.is())
880 aResult = m_xOldModelAgg->queryAggregation( aType );
882 catch( uno::Exception & ex )
884 ASSERT_EXCEPTION( ex );
888 return aResult;
891 // ____ XCloneable ____
892 Reference< util::XCloneable > SAL_CALL ChartModel::createClone()
893 throw (uno::RuntimeException)
895 return Reference< util::XCloneable >( new ChartModel( *this ));
898 // ____ XVisualObject ____
899 void SAL_CALL ChartModel::setVisualAreaSize( ::sal_Int64 nAspect, const awt::Size& aSize )
900 throw (lang::IllegalArgumentException,
901 embed::WrongStateException,
902 uno::Exception,
903 uno::RuntimeException)
905 if( nAspect == embed::Aspects::MSOLE_CONTENT )
907 bool bChanged =
908 (m_aVisualAreaSize.Width != aSize.Width ||
909 m_aVisualAreaSize.Height != aSize.Height);
910 m_aVisualAreaSize = aSize;
911 if( bChanged )
912 setModified( sal_True );
914 else
916 OSL_ENSURE( false, "setVisualAreaSize: Aspect not implemented yet.");
920 awt::Size SAL_CALL ChartModel::getVisualAreaSize( ::sal_Int64 nAspect )
921 throw (lang::IllegalArgumentException,
922 embed::WrongStateException,
923 uno::Exception,
924 uno::RuntimeException)
926 OSL_ENSURE( nAspect == embed::Aspects::MSOLE_CONTENT,
927 "No aspects other than content are supported" );
928 (void)(nAspect); // avoid warning in non-debug builds
929 // other possible aspects are MSOLE_THUMBNAIL, MSOLE_ICON and MSOLE_DOCPRINT
931 return m_aVisualAreaSize;
934 embed::VisualRepresentation SAL_CALL ChartModel::getPreferredVisualRepresentation( ::sal_Int64 nAspect )
935 throw (lang::IllegalArgumentException,
936 embed::WrongStateException,
937 uno::Exception,
938 uno::RuntimeException)
940 OSL_ENSURE( nAspect == embed::Aspects::MSOLE_CONTENT,
941 "No aspects other than content are supported" );
942 (void)(nAspect); // avoid warning in non-debug builds
944 embed::VisualRepresentation aResult;
948 Sequence< sal_Int8 > aMetafile;
950 //get view from old api wrapper
951 Reference< datatransfer::XTransferable > xTransferable(
952 this->createInstance( CHART_VIEW_SERVICE_NAME ), uno::UNO_QUERY );
953 if( xTransferable.is() )
955 datatransfer::DataFlavor aDataFlavor( lcl_aGDIMetaFileMIMEType,
956 C2U( "GDIMetaFile" ),
957 ::getCppuType( (const uno::Sequence< sal_Int8 >*) 0 ) );
959 uno::Any aData( xTransferable->getTransferData( aDataFlavor ) );
960 aData >>= aMetafile;
963 aResult.Flavor.MimeType = lcl_aGDIMetaFileMIMEType;
964 aResult.Flavor.DataType = getCppuType( &aMetafile );
966 aResult.Data <<= aMetafile;
968 catch( uno::Exception & ex )
970 ASSERT_EXCEPTION( ex );
973 return aResult;
976 ::sal_Int32 SAL_CALL ChartModel::getMapUnit( ::sal_Int64 nAspect )
977 throw (uno::Exception,
978 uno::RuntimeException)
980 OSL_ENSURE( nAspect == embed::Aspects::MSOLE_CONTENT,
981 "No aspects other than content are supported" );
982 (void)(nAspect); // avoid warning in non-debug builds
983 return embed::EmbedMapUnits::ONE_100TH_MM;
986 // ____ datatransfer::XTransferable ____
987 uno::Any SAL_CALL ChartModel::getTransferData( const datatransfer::DataFlavor& aFlavor )
988 throw (datatransfer::UnsupportedFlavorException,
989 io::IOException,
990 uno::RuntimeException)
992 uno::Any aResult;
993 if( this->isDataFlavorSupported( aFlavor ))
997 //get view from old api wrapper
998 Reference< datatransfer::XTransferable > xTransferable(
999 this->createInstance( CHART_VIEW_SERVICE_NAME ), uno::UNO_QUERY );
1000 if( xTransferable.is() &&
1001 xTransferable->isDataFlavorSupported( aFlavor ))
1003 aResult = xTransferable->getTransferData( aFlavor );
1006 catch( uno::Exception & ex )
1008 ASSERT_EXCEPTION( ex );
1011 else
1013 throw datatransfer::UnsupportedFlavorException(
1014 aFlavor.MimeType, static_cast< ::cppu::OWeakObject* >( this ));
1017 return aResult;
1020 Sequence< datatransfer::DataFlavor > SAL_CALL ChartModel::getTransferDataFlavors()
1021 throw (uno::RuntimeException)
1023 uno::Sequence< datatransfer::DataFlavor > aRet(1);
1025 // aRet[0] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMEType,
1026 // C2U( "GDIMetaFile" ),
1027 // ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) );
1028 aRet[0] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMETypeHighContrast,
1029 C2U( "GDIMetaFile" ),
1030 ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) );
1032 return aRet;
1035 ::sal_Bool SAL_CALL ChartModel::isDataFlavorSupported( const datatransfer::DataFlavor& aFlavor )
1036 throw (uno::RuntimeException)
1038 // return ( aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMEType) ||
1039 // aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMETypeHighContrast) );
1040 return aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMETypeHighContrast);
1045 namespace
1047 enum eServiceType
1049 SERVICE_DASH_TABLE,
1050 SERVICE_GARDIENT_TABLE,
1051 SERVICE_HATCH_TABLE,
1052 SERVICE_BITMAP_TABLE,
1053 SERVICE_TRANSP_GRADIENT_TABLE,
1054 SERVICE_MARKER_TABLE,
1055 SERVICE_NAMESPACE_MAP
1058 typedef ::std::map< ::rtl::OUString, enum eServiceType > tServiceNameMap;
1059 typedef ::comphelper::MakeMap< ::rtl::OUString, enum eServiceType > tMakeServiceNameMap;
1061 tServiceNameMap & lcl_getStaticServiceNameMap()
1063 static tServiceNameMap aServiceNameMap(
1064 tMakeServiceNameMap
1065 ( C2U( "com.sun.star.drawing.DashTable" ), SERVICE_DASH_TABLE )
1066 ( C2U( "com.sun.star.drawing.GradientTable" ), SERVICE_GARDIENT_TABLE )
1067 ( C2U( "com.sun.star.drawing.HatchTable" ), SERVICE_HATCH_TABLE )
1068 ( C2U( "com.sun.star.drawing.BitmapTable" ), SERVICE_BITMAP_TABLE )
1069 ( C2U( "com.sun.star.drawing.TransparencyGradientTable" ), SERVICE_TRANSP_GRADIENT_TABLE )
1070 ( C2U( "com.sun.star.drawing.MarkerTable" ), SERVICE_MARKER_TABLE )
1071 ( C2U( "com.sun.star.xml.NamespaceMap" ), SERVICE_NAMESPACE_MAP )
1073 return aServiceNameMap;
1076 // ____ XMultiServiceFactory ____
1077 Reference< uno::XInterface > SAL_CALL ChartModel::createInstance( const OUString& rServiceSpecifier )
1078 throw( uno::Exception, uno::RuntimeException )
1080 if( ! m_pImplChartModel.get() )
1081 return 0;
1083 uno::Reference< uno::XInterface > xResult;
1084 tServiceNameMap & rMap = lcl_getStaticServiceNameMap();
1086 tServiceNameMap::const_iterator aIt( rMap.find( rServiceSpecifier ));
1087 if( aIt != rMap.end())
1089 switch( (*aIt).second )
1091 case SERVICE_DASH_TABLE:
1092 return m_pImplChartModel->GetDashTable();
1093 case SERVICE_GARDIENT_TABLE:
1094 return m_pImplChartModel->GetGradientTable();
1095 case SERVICE_HATCH_TABLE:
1096 return m_pImplChartModel->GetHatchTable();
1097 case SERVICE_BITMAP_TABLE:
1098 return m_pImplChartModel->GetBitmapTable();
1099 case SERVICE_TRANSP_GRADIENT_TABLE:
1100 return m_pImplChartModel->GetTransparencyGradientTable();
1101 case SERVICE_MARKER_TABLE:
1102 // not supported
1103 return 0;
1104 case SERVICE_NAMESPACE_MAP:
1105 // not yet supported, @todo
1106 // return 0;
1107 return m_pImplChartModel->GetXMLNameSpaceMap();
1110 else
1112 impl_createOldModelAgg();
1113 if( m_xOldModelAgg.is() )
1115 Any aAny = m_xOldModelAgg->queryAggregation( ::getCppuType((const uno::Reference< lang::XMultiServiceFactory >*)0) );
1116 uno::Reference< lang::XMultiServiceFactory > xOldModelFactory;
1117 if( (aAny >>= xOldModelFactory) && xOldModelFactory.is() )
1119 return xOldModelFactory->createInstance( rServiceSpecifier );
1123 return 0;
1126 Reference< uno::XInterface > SAL_CALL ChartModel::createInstanceWithArguments(
1127 const OUString& rServiceSpecifier , const Sequence< Any >& Arguments )
1128 throw( uno::Exception, uno::RuntimeException )
1130 OSL_ENSURE( Arguments.getLength(), "createInstanceWithArguments: Warning: Arguments are ignored" );
1131 (void)(Arguments); // avoid warning in non-debug builds
1132 return createInstance( rServiceSpecifier );
1135 Sequence< OUString > SAL_CALL ChartModel::getAvailableServiceNames()
1136 throw( uno::RuntimeException )
1138 uno::Sequence< ::rtl::OUString > aResult;
1140 impl_createOldModelAgg();
1141 if( m_xOldModelAgg.is())
1143 Any aAny = m_xOldModelAgg->queryAggregation( ::getCppuType((const uno::Reference< lang::XMultiServiceFactory >*)0) );
1144 uno::Reference< lang::XMultiServiceFactory > xOldModelFactory;
1145 if( (aAny >>= xOldModelFactory) && xOldModelFactory.is() )
1147 return xOldModelFactory->getAvailableServiceNames();
1150 return aResult;
1153 // ____ XUnoTunnel ___
1154 ::sal_Int64 SAL_CALL ChartModel::getSomething( const Sequence< ::sal_Int8 >& aIdentifier )
1155 throw( uno::RuntimeException)
1157 if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( SvNumberFormatsSupplierObj::getUnoTunnelId().getConstArray(),
1158 aIdentifier.getConstArray(), 16 ) )
1160 OSL_ENSURE( m_pImplChartModel.get(), "need a model implementation to provide a numberformatter" );
1161 if( m_pImplChartModel.get() )
1163 Reference< lang::XUnoTunnel > xTunnel( m_pImplChartModel->GetNumberFormatsSupplier(), uno::UNO_QUERY );
1164 if( xTunnel.is() )
1165 return xTunnel->getSomething( aIdentifier );
1167 return 0;
1169 return 0;
1172 // ____ XNumberFormatsSupplier ____
1173 uno::Reference< beans::XPropertySet > SAL_CALL ChartModel::getNumberFormatSettings()
1174 throw (uno::RuntimeException)
1176 OSL_ENSURE( m_pImplChartModel.get(), "need a model implementation to provide a numberformatter" );
1177 if( m_pImplChartModel.get() )
1179 Reference< util::XNumberFormatsSupplier > xSupplier( m_pImplChartModel->GetNumberFormatsSupplier() );
1180 if( xSupplier.is() )
1181 return xSupplier->getNumberFormatSettings();
1183 return uno::Reference< beans::XPropertySet >();
1186 uno::Reference< util::XNumberFormats > SAL_CALL ChartModel::getNumberFormats()
1187 throw (uno::RuntimeException)
1189 OSL_ENSURE( m_pImplChartModel.get(), "need a model implementation to provide a numberformatter" );
1190 if( m_pImplChartModel.get() )
1192 Reference< util::XNumberFormatsSupplier > xSupplier( m_pImplChartModel->GetNumberFormatsSupplier() );
1193 if( xSupplier.is() )
1194 return xSupplier->getNumberFormats();
1196 return uno::Reference< util::XNumberFormats >();
1199 // ____ XChild ____
1200 Reference< uno::XInterface > SAL_CALL ChartModel::getParent()
1201 throw (uno::RuntimeException)
1203 return Reference< uno::XInterface >(m_xParent,uno::UNO_QUERY);
1206 void SAL_CALL ChartModel::setParent( const Reference< uno::XInterface >& Parent )
1207 throw (lang::NoSupportException,
1208 uno::RuntimeException)
1210 if( Parent != m_xParent )
1211 m_xParent.set( Parent, uno::UNO_QUERY );
1214 // ____ XUndoManager ____
1215 Reference< chart2::XUndoManager > SAL_CALL ChartModel::getUndoManager()
1216 throw (uno::RuntimeException)
1218 return m_pImplChartModel->GetUndoManager();
1221 // ____ XDataSource ____
1222 uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > SAL_CALL ChartModel::getDataSequences()
1223 throw (uno::RuntimeException)
1225 Reference< chart2::data::XDataSource > xSource(
1226 DataSourceHelper::getUsedData( uno::Reference< frame::XModel >(this) ) );
1227 if( xSource.is())
1228 return xSource->getDataSequences();
1230 return uno::Sequence< Reference< chart2::data::XLabeledDataSequence > >();
1233 } // namespace chart