xref: /trunk/main/chart2/source/model/main/ChartModel.cxx (revision 74cbd1f1) !
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_chart2.hxx"
26 #include "ChartModel.hxx"
27 #include "servicenames.hxx"
28 #include "MediaDescriptorHelper.hxx"
29 #include "macros.hxx"
30 #include "servicenames.hxx"
31 #include "NoWarningThisInCTOR.hxx"
32 #include "DataSourceHelper.hxx"
33 #include "ChartModelHelper.hxx"
34 #include "DiagramHelper.hxx"
35 #include "DisposeHelper.hxx"
36 #include "ControllerLockGuard.hxx"
37 #include "ObjectIdentifier.hxx"
38 #include "PageBackground.hxx"
39 #include "CloneHelper.hxx"
40 #include "NameContainer.hxx"
41 #include "UndoManager.hxx"
42 
43 #include <com/sun/star/chart/ChartDataRowSource.hpp>
44 
45 #include <comphelper/InlineContainer.hxx>
46 #include <comphelper/processfactory.hxx>
47 
48 // header for class SvNumberFormatsSupplierObj
49 #include <svl/numuno.hxx>
50 #include <com/sun/star/lang/DisposedException.hpp>
51 #include <com/sun/star/lang/XInitialization.hpp>
52 #include <com/sun/star/view/XSelectionSupplier.hpp>
53 #include <com/sun/star/embed/XEmbedObjectCreator.hpp>
54 #include <com/sun/star/embed/XEmbedPersist.hpp>
55 #include <com/sun/star/embed/EmbedStates.hpp>
56 #include <com/sun/star/embed/XComponentSupplier.hpp>
57 #include <com/sun/star/embed/XStorage.hpp>
58 #include <com/sun/star/embed/EmbedMapUnits.hpp>
59 #include <com/sun/star/embed/Aspects.hpp>
60 #include <com/sun/star/awt/Gradient.hpp>
61 #include <com/sun/star/awt/XWindow.hpp>
62 #include <com/sun/star/awt/PosSize.hpp>
63 #include <com/sun/star/datatransfer/XTransferable.hpp>
64 #include <com/sun/star/drawing/Hatch.hpp>
65 #include <com/sun/star/drawing/LineDash.hpp>
66 #include <com/sun/star/drawing/XShapes.hpp>
67 
68 // header for class SvNumberFormatter
69 #include <svl/zforlist.hxx>
70 
71 using ::com::sun::star::uno::Sequence;
72 using ::com::sun::star::uno::Reference;
73 using ::com::sun::star::uno::RuntimeException;
74 using ::com::sun::star::uno::Any;
75 using ::rtl::OUString;
76 using ::osl::MutexGuard;
77 
78 using namespace ::com::sun::star;
79 using namespace ::apphelper;
80 using namespace ::chart::CloneHelper;
81 
82 namespace
83 {
84 const OUString lcl_aGDIMetaFileMIMEType(
85     RTL_CONSTASCII_USTRINGPARAM("application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\""));
86 const OUString lcl_aGDIMetaFileMIMETypeHighContrast(
87     RTL_CONSTASCII_USTRINGPARAM("application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\""));
88 
89 } // anonymous namespace
90 
91 //-----------------------------------------------------------------
92 // ChartModel Constructor and Destructor
93 //-----------------------------------------------------------------
94 
95 namespace chart
96 {
97 
ChartModel(uno::Reference<uno::XComponentContext> const & xContext)98 ChartModel::ChartModel(uno::Reference<uno::XComponentContext > const & xContext)
99 	: m_aLifeTimeManager( this, this )
100 	, m_bReadOnly( sal_False )
101 	, m_bModified( sal_False )
102     , m_nInLoad(0)
103     , m_bUpdateNotificationsPending(false)
104     , m_pUndoManager( NULL )
105     , m_aControllers( m_aModelMutex )
106 	, m_nControllerLockCount(0)
107     , m_xContext( xContext )
108     , m_aVisualAreaSize( ChartModelHelper::getDefaultPageSize() )
109     , m_xDataProvider( 0 )
110     , m_xInternalDataProvider( 0 )
111     , m_xPageBackground( new PageBackground( m_xContext ) )
112     , m_xXMLNamespaceMap( createNameContainer( ::getCppuType( (const OUString*) 0 ),
113                 C2U( "com.sun.star.xml.NamespaceMap" ), C2U( "com.sun.star.comp.chart.XMLNameSpaceMap" ) ), uno::UNO_QUERY)
114 {
115     OSL_TRACE( "ChartModel: CTOR called" );
116 
117     osl_incrementInterlockedCount(&m_refCount);
118     {
119         m_xOldModelAgg.set(
120             m_xContext->getServiceManager()->createInstanceWithContext(
121             CHART_CHARTAPIWRAPPER_SERVICE_NAME,
122             m_xContext ), uno::UNO_QUERY_THROW );
123         m_xOldModelAgg->setDelegator( *this );
124     }
125 
126     {
127         ModifyListenerHelper::addListener( m_xPageBackground, this );
128         m_xChartTypeManager.set( xContext->getServiceManager()->createInstanceWithContext(
129                 C2U( "com.sun.star.chart2.ChartTypeManager" ), m_xContext ), uno::UNO_QUERY );
130     }
131     osl_decrementInterlockedCount(&m_refCount);
132 }
133 
ChartModel(const ChartModel & rOther)134 ChartModel::ChartModel( const ChartModel & rOther )
135 	: impl::ChartModel_Base()
136     , m_aLifeTimeManager( this, this )
137 	, m_bReadOnly( rOther.m_bReadOnly )
138 	, m_bModified( rOther.m_bModified )
139     , m_nInLoad(0)
140     , m_bUpdateNotificationsPending(false)
141 	, m_aResource( rOther.m_aResource )
142     , m_aMediaDescriptor( rOther.m_aMediaDescriptor )
143 	, m_aControllers( m_aModelMutex )
144 	, m_nControllerLockCount(0)
145     , m_xContext( rOther.m_xContext )
146     // @note: the old model aggregate must not be shared with other models if it
147     // is, you get mutex deadlocks
148     , m_xOldModelAgg( 0 ) //rOther.m_xOldModelAgg )
149     , m_xStorage( 0 ) //rOther.m_xStorage )
150     , m_aVisualAreaSize( rOther.m_aVisualAreaSize )
151     , m_aGraphicObjectVector( rOther.m_aGraphicObjectVector )
152     , m_xDataProvider( rOther.m_xDataProvider )
153     , m_xInternalDataProvider( rOther.m_xInternalDataProvider )
154 {
155     OSL_TRACE( "ChartModel: Copy-CTOR called" );
156 
157     osl_incrementInterlockedCount(&m_refCount);
158     {
159         m_xOldModelAgg.set(
160             m_xContext->getServiceManager()->createInstanceWithContext(
161             CHART_CHARTAPIWRAPPER_SERVICE_NAME,
162             m_xContext ), uno::UNO_QUERY_THROW );
163         m_xOldModelAgg->setDelegator( *this );
164 
165         Reference< util::XModifyListener > xListener;
166         Reference< chart2::XTitle > xNewTitle = CreateRefClone< Reference< chart2::XTitle > >()( rOther.m_xTitle );
167         Reference< chart2::XDiagram > xNewDiagram = CreateRefClone< Reference< chart2::XDiagram > >()( rOther.m_xDiagram );
168         Reference< beans::XPropertySet > xNewPageBackground = CreateRefClone< Reference< beans::XPropertySet > >()( rOther.m_xPageBackground );
169         Reference< chart2::XChartTypeManager > xChartTypeManager = CreateRefClone< Reference< chart2::XChartTypeManager > >()( rOther.m_xChartTypeManager );
170         Reference< container::XNameAccess > xXMLNamespaceMap = CreateRefClone< Reference< container::XNameAccess > >()( rOther.m_xXMLNamespaceMap );
171 
172         {
173             MutexGuard aGuard( m_aModelMutex );
174             xListener = this;
175             m_xTitle = xNewTitle;
176             m_xDiagram = xNewDiagram;
177             m_xPageBackground = xNewPageBackground;
178             m_xChartTypeManager = xChartTypeManager;
179             m_xXMLNamespaceMap = xXMLNamespaceMap;
180         }
181 
182         ModifyListenerHelper::addListener( xNewTitle, xListener );
183         ModifyListenerHelper::addListener( xNewDiagram, xListener );
184         ModifyListenerHelper::addListener( xNewPageBackground, xListener );
185         xListener.clear();
186     }
187     osl_decrementInterlockedCount(&m_refCount);
188 }
189 
~ChartModel()190 ChartModel::~ChartModel()
191 {
192     OSL_TRACE( "ChartModel: DTOR called" );
193     if( m_xOldModelAgg.is())
194         m_xOldModelAgg->setDelegator( NULL );
195 }
196 
initialize(const Sequence<Any> &)197 void SAL_CALL ChartModel::initialize( const Sequence< Any >& /*rArguments*/ )
198                 throw (uno::Exception, uno::RuntimeException)
199 {
200     //#i113722# avoid duplicate creation
201 
202     //maybe additional todo?:
203     //support argument "EmbeddedObject"?
204     //support argument "EmbeddedScriptSupport"?
205     //support argument "DocumentRecoverySupport"?
206 }
207 
208 //-----------------------------------------------------------------
209 // private methods
210 //-----------------------------------------------------------------
211 
impl_g_getLocation()212 ::rtl::OUString ChartModel::impl_g_getLocation()
213 {
214 
215 	LifeTimeGuard aGuard(m_aLifeTimeManager);
216 	if(!aGuard.startApiCall())
217 		return ::rtl::OUString(); //behave passive if already disposed or closed or throw exception @todo?
218 	//mutex is acquired
219 	return m_aResource;
220 }
221 
impl_isControllerConnected(const uno::Reference<frame::XController> & xController)222 sal_Bool ChartModel::impl_isControllerConnected( const uno::Reference< frame::XController >& xController )
223 {
224 	try
225 	{
226 		uno::Sequence< uno::Reference<uno::XInterface> > aSeq = m_aControllers.getElements();
227 		for( sal_Int32 nN = aSeq.getLength(); nN--; )
228 		{
229 			if( aSeq[nN] == xController )
230 				return sal_True;
231 		}
232 	}
233 	catch( uno::Exception )
234 	{
235 	}
236 	return sal_False;
237 }
238 
impl_getCurrentController()239 uno::Reference< frame::XController > ChartModel::impl_getCurrentController() throw(uno::RuntimeException)
240 {
241 		//@todo? hold only weak references to controllers
242 
243 	// get the last active controller of this model
244 	if( m_xCurrentController.is() )
245 		return m_xCurrentController;
246 
247 	// get the first controller of this model
248 	if( m_aControllers.getLength() )
249 	{
250 		uno::Reference<uno::XInterface> xI = m_aControllers.getElements()[0];
251 		return uno::Reference<frame::XController>( xI, uno::UNO_QUERY );
252 	}
253 
254 	//return nothing if no controllers are connected at all
255 	return uno::Reference< frame::XController > ();
256 }
257 
impl_notifyCloseListeners()258 void SAL_CALL ChartModel::impl_notifyCloseListeners()
259 		throw( uno::RuntimeException)
260 {
261 	::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
262 		.getContainer( ::getCppuType((const uno::Reference< util::XCloseListener >*)0) );
263 	if( pIC )
264 	{
265 		lang::EventObject aEvent( static_cast< lang::XComponent*>(this) );
266 		::cppu::OInterfaceIteratorHelper aIt( *pIC );
267 		while( aIt.hasMoreElements() )
268         {
269             uno::Reference< util::XCloseListener > xListener( aIt.next(), uno::UNO_QUERY );
270             if( xListener.is() )
271                 xListener->notifyClosing( aEvent );
272         }
273 	}
274 }
275 
impl_adjustAdditionalShapesPositionAndSize(const awt::Size & aVisualAreaSize)276 void ChartModel::impl_adjustAdditionalShapesPositionAndSize( const awt::Size& aVisualAreaSize )
277 {
278     uno::Reference< beans::XPropertySet > xProperties( static_cast< ::cppu::OWeakObject* >( this ), uno::UNO_QUERY );
279     if ( xProperties.is() )
280     {
281         uno::Reference< drawing::XShapes > xShapes;
282         xProperties->getPropertyValue( C2U( "AdditionalShapes" ) ) >>= xShapes;
283         if ( xShapes.is() )
284         {
285             sal_Int32 nCount = xShapes->getCount();
286             for ( sal_Int32 i = 0; i < nCount; ++i )
287             {
288                 Reference< drawing::XShape > xShape;
289                 if ( xShapes->getByIndex( i ) >>= xShape )
290                 {
291                     if ( xShape.is() )
292                     {
293                         awt::Point aPos( xShape->getPosition() );
294                         awt::Size aSize( xShape->getSize() );
295 
296                         double fWidth = static_cast< double >( aVisualAreaSize.Width ) / m_aVisualAreaSize.Width;
297                         double fHeight = static_cast< double >( aVisualAreaSize.Height ) / m_aVisualAreaSize.Height;
298 
299                         aPos.X = static_cast< long >( aPos.X * fWidth );
300                         aPos.Y = static_cast< long >( aPos.Y * fHeight );
301                         aSize.Width = static_cast< long >( aSize.Width * fWidth );
302                         aSize.Height = static_cast< long >( aSize.Height * fHeight );
303 
304                         xShape->setPosition( aPos );
305                         xShape->setSize( aSize );
306                     }
307                 }
308             }
309         }
310     }
311 }
312 
313 //-----------------------------------------------------------------
314 // lang::XServiceInfo
315 //-----------------------------------------------------------------
316 
APPHELPER_XSERVICEINFO_IMPL(ChartModel,CHART_MODEL_SERVICE_IMPLEMENTATION_NAME)317 APPHELPER_XSERVICEINFO_IMPL(ChartModel,CHART_MODEL_SERVICE_IMPLEMENTATION_NAME)
318 
319 uno::Sequence< rtl::OUString > ChartModel::getSupportedServiceNames_Static()
320 {
321 	uno::Sequence< rtl::OUString > aSNS( 3 );
322 	aSNS[0] = CHART_MODEL_SERVICE_NAME;
323 	aSNS[1] = C2U( "com.sun.star.document.OfficeDocument" );
324     aSNS[2] = C2U( "com.sun.star.chart.ChartDocument" );
325 	//// @todo : add additional services if you support any further
326 	return aSNS;
327 }
328 
329 //-----------------------------------------------------------------
330 // frame::XModel (required interface)
331 //-----------------------------------------------------------------
332 
attachResource(const::rtl::OUString & rURL,const uno::Sequence<beans::PropertyValue> & rMediaDescriptor)333 sal_Bool SAL_CALL ChartModel::attachResource( const ::rtl::OUString& rURL
334 		, const uno::Sequence< beans::PropertyValue >& rMediaDescriptor )
335 		throw(uno::RuntimeException)
336 {
337     /*
338     The method attachResource() is used by the frame loader implementations
339     to inform the model about its URL and MediaDescriptor.
340     */
341 
342 	LifeTimeGuard aGuard(m_aLifeTimeManager);
343 	if(!aGuard.startApiCall())
344 		return sal_False; //behave passive if already disposed or closed or throw exception @todo?
345 	//mutex is acquired
346 
347 	if(!m_aResource.isEmpty())//we have a resource already //@todo? or is setting a new resource allowed?
348 		return sal_False;
349 	m_aResource = rURL;
350 	m_aMediaDescriptor = rMediaDescriptor;
351 
352 	//@todo ? check rURL ??
353 	//@todo ? evaluate m_aMediaDescriptor;
354 	//@todo ? ... ??? --> nothing, this method is only for setting informations
355 
356 	return sal_True;
357 }
358 
getURL()359 ::rtl::OUString SAL_CALL ChartModel::getURL() throw(uno::RuntimeException)
360 {
361 	return impl_g_getLocation();
362 }
363 
getArgs()364 uno::Sequence< beans::PropertyValue > SAL_CALL ChartModel::getArgs() throw(uno::RuntimeException)
365 {
366     /*
367     The method getArgs() returns a sequence of property values
368     that report the resource description according to com.sun.star.document.MediaDescriptor,
369     specified on loading or saving with storeAsURL.
370     */
371 
372 	LifeTimeGuard aGuard(m_aLifeTimeManager);
373 	if(!aGuard.startApiCall())
374 		return uno::Sequence< beans::PropertyValue >(); //behave passive if already disposed or closed or throw exception @todo?
375 	//mutex is acquired
376 
377 	return m_aMediaDescriptor;
378 }
379 
connectController(const uno::Reference<frame::XController> & xController)380 void SAL_CALL ChartModel::connectController( const uno::Reference< frame::XController >& xController )
381 		throw(uno::RuntimeException)
382 {
383 	//@todo? this method is declared as oneway -> ...?
384 
385 	LifeTimeGuard aGuard(m_aLifeTimeManager);
386 	if(!aGuard.startApiCall())
387 		return ; //behave passive if already disposed or closed
388 	//mutex is acquired
389 
390 	//--add controller
391 	m_aControllers.addInterface(xController);
392 }
393 
disconnectController(const uno::Reference<frame::XController> & xController)394 void SAL_CALL ChartModel::disconnectController( const uno::Reference< frame::XController >& xController )
395 		throw(uno::RuntimeException)
396 {
397 	//@todo? this method is declared as oneway -> ...?
398 
399 	LifeTimeGuard aGuard(m_aLifeTimeManager);
400 	if(!aGuard.startApiCall())
401 		return; //behave passive if already disposed or closed
402 
403 	//--remove controller
404 	m_aControllers.removeInterface(xController);
405 
406 	//case: current controller is disconnected:
407 	if( m_xCurrentController == xController )
408 		m_xCurrentController.clear();
409 
410     DisposeHelper::DisposeAndClear( m_xRangeHighlighter );
411 }
412 
lockControllers()413 void SAL_CALL ChartModel::lockControllers()	throw(uno::RuntimeException)
414 {
415     /*
416     suspends some notifications to the controllers which are used for display updates.
417 
418     The calls to lockControllers() and unlockControllers() may be nested
419     and even overlapping, but they must be in pairs. While there is at least one lock
420     remaining, some notifications for display updates are not broadcasted.
421     */
422 
423 	//@todo? this method is declared as oneway -> ...?
424 
425 	LifeTimeGuard aGuard(m_aLifeTimeManager);
426 	if(!aGuard.startApiCall())
427 		return; //behave passive if already disposed or closed or throw exception @todo?
428 	++m_nControllerLockCount;
429 }
430 
unlockControllers()431 void SAL_CALL ChartModel::unlockControllers() throw(uno::RuntimeException)
432 {
433     /*
434     resumes the notifications which were suspended by lockControllers() .
435 
436     The calls to lockControllers() and unlockControllers() may be nested
437     and even overlapping, but they must be in pairs. While there is at least one lock
438     remaining, some notifications for display updates are not broadcasted.
439     */
440 
441 	//@todo? this method is declared as oneway -> ...?
442 
443 	LifeTimeGuard aGuard(m_aLifeTimeManager);
444 	if(!aGuard.startApiCall())
445 		return; //behave passive if already disposed or closed or throw exception @todo?
446     if( m_nControllerLockCount == 0 )
447     {
448         OSL_TRACE( "ChartModel: unlockControllers called with m_nControllerLockCount == 0" );
449         return;
450     }
451 	--m_nControllerLockCount;
452     if( m_nControllerLockCount == 0 && m_bUpdateNotificationsPending  )
453     {
454         aGuard.clear();
455         impl_notifyModifiedListeners();
456     }
457 }
458 
hasControllersLocked()459 sal_Bool SAL_CALL ChartModel::hasControllersLocked() throw(uno::RuntimeException)
460 {
461 	LifeTimeGuard aGuard(m_aLifeTimeManager);
462 	if(!aGuard.startApiCall())
463 		return sal_False; //behave passive if already disposed or closed or throw exception @todo?
464 	return ( m_nControllerLockCount != 0 ) ;
465 }
466 
getCurrentController()467 uno::Reference< frame::XController > SAL_CALL ChartModel::getCurrentController() throw(uno::RuntimeException)
468 {
469 	LifeTimeGuard aGuard(m_aLifeTimeManager);
470 	if(!aGuard.startApiCall())
471 		throw lang::DisposedException(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
472 				"getCurrentController was called on an already disposed or closed model" ) )
473 				, static_cast< ::cppu::OWeakObject* >(this));
474 
475 	return impl_getCurrentController();
476 }
477 
setCurrentController(const uno::Reference<frame::XController> & xController)478 void SAL_CALL ChartModel::setCurrentController( const uno::Reference< frame::XController >& xController )
479 		throw(container::NoSuchElementException, uno::RuntimeException)
480 {
481 	LifeTimeGuard aGuard(m_aLifeTimeManager);
482 	if(!aGuard.startApiCall())
483 		throw lang::DisposedException(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
484 				"setCurrentController was called on an already disposed or closed model" ) )
485 				, static_cast< ::cppu::OWeakObject* >(this));
486 
487 	//OSL_ENSURE( impl_isControllerConnected(xController), "setCurrentController is called with a Controller which is not connected" );
488 	if(!impl_isControllerConnected(xController))
489 		throw container::NoSuchElementException(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
490 				"setCurrentController is called with a Controller which is not connected" ) )
491 				, static_cast< ::cppu::OWeakObject* >(this));
492 
493 	m_xCurrentController = xController;
494 
495     DisposeHelper::DisposeAndClear( m_xRangeHighlighter );
496 }
497 
getCurrentSelection()498 uno::Reference< uno::XInterface > SAL_CALL ChartModel::getCurrentSelection() throw(uno::RuntimeException)
499 {
500 	LifeTimeGuard aGuard(m_aLifeTimeManager);
501 	if(!aGuard.startApiCall())
502 		throw lang::DisposedException(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
503 				"getCurrentSelection was called on an already disposed or closed model" ) )
504 				, static_cast< ::cppu::OWeakObject* >(this));
505 
506 
507 	uno::Reference< uno::XInterface > xReturn;
508 	uno::Reference< frame::XController > xController = impl_getCurrentController();
509 
510 	aGuard.clear();
511 	if( xController.is() )
512 	{
513 		uno::Reference< view::XSelectionSupplier >  xSelectionSupl( xController, uno::UNO_QUERY );
514 		if ( xSelectionSupl.is() )
515 		{
516 			uno::Any aSel = xSelectionSupl->getSelection();
517             rtl::OUString aObjectCID;
518             if( aSel >>= aObjectCID )
519             {
520 			    xReturn.set( ObjectIdentifier::getObjectPropertySet( aObjectCID, Reference< XChartDocument >(this)));
521             }
522 		}
523 	}
524 	return xReturn;
525 }
526 
527 
528 //-----------------------------------------------------------------
529 // lang::XComponent (base of XModel)
530 //-----------------------------------------------------------------
dispose()531 void SAL_CALL ChartModel::dispose() throw(uno::RuntimeException)
532 {
533     Reference< XInterface > xKeepAlive( *this );
534 
535 	//This object should release all resources and references in the
536     //easiest possible manner
537 	//This object must notify all registered listeners using the method
538     //<member>XEventListener::disposing</member>
539 
540     //hold no mutex
541 	if( !m_aLifeTimeManager.dispose() )
542 		return;
543 
544 	//--release all resources and references
545 	//// @todo
546 
547     if ( m_xDiagram.is() )
548         ModifyListenerHelper::removeListener( m_xDiagram, this );
549 
550     m_xDataProvider.clear();
551     m_xInternalDataProvider.clear();
552     m_xNumberFormatsSupplier.clear();
553     DisposeHelper::DisposeAndClear( m_xOwnNumberFormatsSupplier );
554     DisposeHelper::DisposeAndClear( m_xChartTypeManager );
555     DisposeHelper::DisposeAndClear( m_xDiagram );
556     DisposeHelper::DisposeAndClear( m_xTitle );
557     DisposeHelper::DisposeAndClear( m_xPageBackground );
558     DisposeHelper::DisposeAndClear( m_xXMLNamespaceMap );
559 
560     m_xStorage.clear();
561         // just clear, don't dispose - we're not the owner
562 
563     if ( m_pUndoManager.is() )
564         m_pUndoManager->disposing();
565     m_pUndoManager.clear();
566         // that's important, since the UndoManager implementation delegates its ref counting to ourself.
567 
568     if( m_xOldModelAgg.is())  // #i120828#, to release cyclic reference to ChartModel object
569         m_xOldModelAgg->setDelegator( 0 );
570 
571     m_aControllers.disposeAndClear( lang::EventObject( static_cast< cppu::OWeakObject * >( this )));
572     m_xCurrentController.clear();
573 
574     DisposeHelper::DisposeAndClear( m_xRangeHighlighter );
575     OSL_TRACE( "ChartModel: dispose() called" );
576 }
577 
addEventListener(const uno::Reference<lang::XEventListener> & xListener)578 void SAL_CALL ChartModel::addEventListener( const uno::Reference< lang::XEventListener > & xListener )
579 		throw(uno::RuntimeException)
580 {
581 	if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
582 		return; //behave passive if already disposed or closed
583 
584 	m_aLifeTimeManager.m_aListenerContainer.addInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0), xListener );
585 }
586 
removeEventListener(const uno::Reference<lang::XEventListener> & xListener)587 void SAL_CALL ChartModel::removeEventListener( const uno::Reference< lang::XEventListener > & xListener )
588 		throw(uno::RuntimeException)
589 {
590 	if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) )
591 		return; //behave passive if already disposed or closed
592 
593 	m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0), xListener );
594 	return;
595 }
596 
597 //-----------------------------------------------------------------
598 // util::XCloseBroadcaster (base of XCloseable)
599 //-----------------------------------------------------------------
addCloseListener(const uno::Reference<util::XCloseListener> & xListener)600 void SAL_CALL ChartModel::addCloseListener( const uno::Reference<	util::XCloseListener > & xListener )
601 		throw(uno::RuntimeException)
602 {
603 	m_aLifeTimeManager.g_addCloseListener( xListener );
604 }
605 
removeCloseListener(const uno::Reference<util::XCloseListener> & xListener)606 void SAL_CALL ChartModel::removeCloseListener( const uno::Reference< util::XCloseListener > & xListener )
607 		throw(uno::RuntimeException)
608 {
609 	if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) )
610 		return; //behave passive if already disposed or closed
611 
612 	m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< util::XCloseListener >*)0), xListener );
613 	return;
614 }
615 
616 //-----------------------------------------------------------------
617 // util::XCloseable
618 //-----------------------------------------------------------------
close(sal_Bool bDeliverOwnership)619 void SAL_CALL ChartModel::close( sal_Bool bDeliverOwnership )
620             throw( util::CloseVetoException,
621                    uno::RuntimeException )
622 {
623 	//hold no mutex
624 
625 	if( !m_aLifeTimeManager.g_close_startTryClose( bDeliverOwnership ) )
626 		return;
627 	//no mutex is acquired
628 
629 	// At the end of this method may we must dispose ourself ...
630     // and may nobody from outside hold a reference to us ...
631     // then it's a good idea to do that by ourself.
632     uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) );
633 
634 	//the listeners have had no veto
635 	//check whether we self can close
636 	{
637 		util::CloseVetoException aVetoException = util::CloseVetoException(
638 						::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
639 						"the model itself could not be closed" ) )
640 						, static_cast< ::cppu::OWeakObject* >(this));
641 
642 		if( m_aLifeTimeManager.g_close_isNeedToCancelLongLastingCalls( bDeliverOwnership, aVetoException ) )
643 		{
644 			////you can empty this block, if you never start longlasting calls or
645 			////if your longlasting calls are per default not cancelable (check how you have constructed your LifeTimeManager)
646 
647 			sal_Bool bLongLastingCallsAreCanceled = sal_False;
648 			try
649 			{
650 				//try to cancel running longlasting calls
651 				//// @todo
652 			}
653 			catch( uno::Exception )
654 			{
655 				//// @todo
656 				//do not throw anything here!! (without endTryClose)
657 			}
658 			//if not successful canceled
659 			if(!bLongLastingCallsAreCanceled)
660 			{
661 				m_aLifeTimeManager.g_close_endTryClose( bDeliverOwnership, sal_True );
662                 throw aVetoException;
663 			}
664 		}
665 
666 	}
667 	m_aLifeTimeManager.g_close_endTryClose_doClose();
668 
669     // BM @todo: is it ok to call the listeners here?
670     impl_notifyCloseListeners();
671 }
672 
673 //-----------------------------------------------------------------
674 // lang::XTypeProvider
675 //-----------------------------------------------------------------
getTypes()676 uno::Sequence< uno::Type > SAL_CALL ChartModel::getTypes()
677         throw (uno::RuntimeException)
678 {
679     uno::Reference< lang::XTypeProvider > xAggTypeProvider;
680     if( (m_xOldModelAgg->queryAggregation( ::getCppuType( & xAggTypeProvider )) >>= xAggTypeProvider)
681         && xAggTypeProvider.is())
682     {
683         uno::Sequence< uno::Type > aOwnTypes( impl::ChartModel_Base::getTypes());
684         uno::Sequence< uno::Type > aAggTypes( xAggTypeProvider->getTypes());
685         uno::Sequence< uno::Type > aResult( aOwnTypes.getLength() + aAggTypes.getLength());
686         sal_Int32 i=0;
687         for( ;i<aOwnTypes.getLength(); ++i )
688             aResult[i] = aOwnTypes[i];
689         for( sal_Int32 j=0; i<aResult.getLength(); ++j, ++i)
690             aResult[i] = aAggTypes[j];
691         return aResult;
692     }
693 
694     return impl::ChartModel_Base::getTypes();
695 }
696 
697 //-----------------------------------------------------------------
698 // document::XDocumentPropertiesSupplier
699 //-----------------------------------------------------------------
700 uno::Reference< document::XDocumentProperties > SAL_CALL
getDocumentProperties()701         ChartModel::getDocumentProperties() throw (uno::RuntimeException)
702 {
703     ::osl::MutexGuard aGuard( m_aModelMutex );
704     if ( !m_xDocumentProperties.is() )
705     {
706         uno::Reference< document::XDocumentProperties > xDocProps(
707             ::comphelper::getProcessServiceFactory()->createInstance(
708                 C2U("com.sun.star.document.DocumentProperties") ), uno::UNO_QUERY );
709         m_xDocumentProperties.set(xDocProps);
710     }
711     return m_xDocumentProperties;
712 }
713 
714 //-----------------------------------------------------------------
715 // document::XDocumentPropertiesSupplier
716 //-----------------------------------------------------------------
getUndoManager()717 Reference< document::XUndoManager > SAL_CALL ChartModel::getUndoManager(  ) throw (RuntimeException)
718 {
719     ::osl::MutexGuard aGuard( m_aModelMutex );
720     if ( !m_pUndoManager.is() )
721         m_pUndoManager.set( new UndoManager( *this, m_aModelMutex ) );
722     return m_pUndoManager.get();
723 }
724 
725 //-----------------------------------------------------------------
726 // chart2::XChartDocument
727 //-----------------------------------------------------------------
728 
getFirstDiagram()729 uno::Reference< chart2::XDiagram > SAL_CALL ChartModel::getFirstDiagram()
730             throw (uno::RuntimeException)
731 {
732     MutexGuard aGuard( m_aModelMutex );
733     return m_xDiagram;
734 }
735 
setFirstDiagram(const uno::Reference<chart2::XDiagram> & xDiagram)736 void SAL_CALL ChartModel::setFirstDiagram( const uno::Reference< chart2::XDiagram >& xDiagram )
737             throw (uno::RuntimeException)
738 {
739     Reference< chart2::XDiagram > xOldDiagram;
740     Reference< util::XModifyListener > xListener;
741     {
742         MutexGuard aGuard( m_aModelMutex );
743         if( xDiagram == m_xDiagram )
744             return;
745         xOldDiagram = m_xDiagram;
746         m_xDiagram = xDiagram;
747         xListener = this;
748     }
749     //don't keep the mutex locked while calling out
750     ModifyListenerHelper::removeListener( xOldDiagram, xListener );
751     ModifyListenerHelper::addListener( xDiagram, xListener );
752     setModified( sal_True );
753 }
754 
impl_createDefaultData()755 Reference< chart2::data::XDataSource > ChartModel::impl_createDefaultData()
756 {
757     Reference< chart2::data::XDataSource > xDataSource;
758     if( hasInternalDataProvider() )
759     {
760         uno::Reference< lang::XInitialization > xIni(m_xInternalDataProvider,uno::UNO_QUERY);
761         if( xIni.is() )
762         {
763             //init internal dataprovider
764             {
765                 uno::Sequence< uno::Any > aArgs(1);
766                 beans::NamedValue aParam(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreateDefaultData")),uno::makeAny(sal_True));
767                 aArgs[0] <<= aParam;
768                 xIni->initialize(aArgs);
769             }
770             //create data
771             uno::Sequence< beans::PropertyValue > aArgs( 4 );
772             aArgs[0] = beans::PropertyValue(
773                 ::rtl::OUString::createFromAscii("CellRangeRepresentation"), -1,
774                 uno::makeAny( C2U("all") ), beans::PropertyState_DIRECT_VALUE );
775             aArgs[1] = beans::PropertyValue(
776                 ::rtl::OUString::createFromAscii("HasCategories"), -1,
777                 uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE );
778             aArgs[2] = beans::PropertyValue(
779                 ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1,
780                 uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE );
781             aArgs[3] = beans::PropertyValue(
782                 ::rtl::OUString::createFromAscii("DataRowSource"), -1,
783                 uno::makeAny( ::com::sun::star::chart::ChartDataRowSource_COLUMNS ), beans::PropertyState_DIRECT_VALUE );
784             xDataSource = m_xInternalDataProvider->createDataSource( aArgs );
785         }
786     }
787     return xDataSource;
788 }
789 
createInternalDataProvider(sal_Bool bCloneExistingData)790 void SAL_CALL ChartModel::createInternalDataProvider( sal_Bool bCloneExistingData )
791             throw (util::CloseVetoException, uno::RuntimeException)
792 {
793     // don't lock the mutex, because this call calls out to code that tries to
794     // lock the solar mutex. On the other hand, a paint locks the solar mutex
795     // and calls to the model lock the model's mutex => deadlock
796     // @todo: lock a separate mutex in the InternalData class
797     if( !hasInternalDataProvider() )
798     {
799         if( bCloneExistingData )
800             m_xInternalDataProvider = ChartModelHelper::createInternalDataProvider( this, true );
801         else
802             m_xInternalDataProvider = ChartModelHelper::createInternalDataProvider( Reference<XChartDocument>(), true );
803         m_xDataProvider.set( m_xInternalDataProvider );
804     }
805     setModified( sal_True );
806 }
807 
hasInternalDataProvider()808 sal_Bool SAL_CALL ChartModel::hasInternalDataProvider()
809     throw (uno::RuntimeException)
810 {
811     return m_xDataProvider.is() && m_xInternalDataProvider.is();
812 }
813 
getDataProvider()814 uno::Reference< chart2::data::XDataProvider > SAL_CALL ChartModel::getDataProvider()
815             throw (uno::RuntimeException)
816 {
817     // /--
818     MutexGuard aGuard( m_aModelMutex );
819     return m_xDataProvider;
820     // \--
821 }
822 
823 // ____ XDataReceiver ____
824 
attachDataProvider(const uno::Reference<chart2::data::XDataProvider> & xDataProvider)825 void SAL_CALL ChartModel::attachDataProvider( const uno::Reference< chart2::data::XDataProvider >& xDataProvider )
826             throw (uno::RuntimeException)
827 {
828     {
829         // /--
830         MutexGuard aGuard( m_aModelMutex );
831         uno::Reference< beans::XPropertySet > xProp( xDataProvider, uno::UNO_QUERY );
832         if( xProp.is() )
833         {
834             try
835             {
836                 sal_Bool bIncludeHiddenCells = ChartModelHelper::isIncludeHiddenCells( Reference< frame::XModel >(this) );
837                 xProp->setPropertyValue(C2U("IncludeHiddenCells"), uno::makeAny(bIncludeHiddenCells));
838             }
839             catch( const beans::UnknownPropertyException& )
840             {
841             }
842         }
843 
844         m_xDataProvider.set( xDataProvider );
845         m_xInternalDataProvider.clear();
846 
847         //the numberformatter is kept independent of the data provider!
848         // \--
849     }
850     setModified( sal_True );
851 }
852 
attachNumberFormatsSupplier(const uno::Reference<util::XNumberFormatsSupplier> & xNewSupplier)853 void SAL_CALL ChartModel::attachNumberFormatsSupplier( const uno::Reference< util::XNumberFormatsSupplier >& xNewSupplier )
854             throw (uno::RuntimeException)
855 {
856     {
857         // /--
858         MutexGuard aGuard( m_aModelMutex );
859         if( xNewSupplier==m_xNumberFormatsSupplier )
860             return;
861         if( xNewSupplier==m_xOwnNumberFormatsSupplier )
862             return;
863         if( m_xOwnNumberFormatsSupplier.is() && xNewSupplier.is() )
864         {
865             //@todo
866             //merge missing numberformats from own to new formatter
867         }
868         else if( !xNewSupplier.is() )
869         {
870             if( m_xNumberFormatsSupplier.is() )
871             {
872                 //@todo
873                 //merge missing numberformats from old numberformatter to own numberformatter
874                 //create own numberformatter if necessary
875             }
876         }
877 
878         m_xNumberFormatsSupplier.set( xNewSupplier );
879         m_xOwnNumberFormatsSupplier.clear();
880         // \--
881     }
882     setModified( sal_True );
883 }
884 
setArguments(const Sequence<beans::PropertyValue> & aArguments)885 void SAL_CALL ChartModel::setArguments( const Sequence< beans::PropertyValue >& aArguments )
886             throw (lang::IllegalArgumentException,
887                    uno::RuntimeException)
888 {
889     {
890         // /--
891         MutexGuard aGuard( m_aModelMutex );
892         if( !m_xDataProvider.is() )
893             return;
894         lockControllers();
895 
896         try
897         {
898             Reference< chart2::data::XDataSource > xDataSource( m_xDataProvider->createDataSource( aArguments ) );
899             if( xDataSource.is() )
900             {
901                 Reference< chart2::XDiagram > xDia( getFirstDiagram() );
902                 if( !xDia.is() )
903                 {
904                     Reference< chart2::XChartTypeTemplate > xTemplate( impl_createDefaultChartTypeTemplate() );
905                     if( xTemplate.is())
906                         setFirstDiagram( xTemplate->createDiagramByDataSource( xDataSource, aArguments ) );
907                 }
908                 else
909                     xDia->setDiagramData( xDataSource, aArguments );
910             }
911         }
912         catch( lang::IllegalArgumentException & )
913         {
914             throw;
915         }
916         catch( uno::Exception & ex )
917         {
918             ASSERT_EXCEPTION( ex );
919         }
920         unlockControllers();
921         // \--
922     }
923     setModified( sal_True );
924 }
925 
getUsedRangeRepresentations()926 Sequence< OUString > SAL_CALL ChartModel::getUsedRangeRepresentations()
927             throw (uno::RuntimeException)
928 {
929     return DataSourceHelper::getUsedDataRanges( Reference< frame::XModel >(this));
930 }
931 
getUsedData()932 Reference< chart2::data::XDataSource > SAL_CALL ChartModel::getUsedData()
933             throw (uno::RuntimeException)
934 {
935     return DataSourceHelper::getUsedData( Reference< chart2::XChartDocument >(this));
936 }
937 
getRangeHighlighter()938 Reference< chart2::data::XRangeHighlighter > SAL_CALL ChartModel::getRangeHighlighter()
939             throw (uno::RuntimeException)
940 {
941     if( ! m_xRangeHighlighter.is())
942     {
943         uno::Reference< view::XSelectionSupplier > xSelSupp( this->getCurrentController(), uno::UNO_QUERY );
944         if( xSelSupp.is() )
945             m_xRangeHighlighter.set( ChartModelHelper::createRangeHighlighter( xSelSupp ));
946     }
947     return m_xRangeHighlighter;
948 }
949 
impl_createDefaultChartTypeTemplate()950 Reference< chart2::XChartTypeTemplate > ChartModel::impl_createDefaultChartTypeTemplate()
951 {
952     Reference< chart2::XChartTypeTemplate > xTemplate;
953     Reference< lang::XMultiServiceFactory > xFact( m_xChartTypeManager, uno::UNO_QUERY );
954     if( xFact.is() )
955         xTemplate.set( xFact->createInstance( C2U( "com.sun.star.chart2.template.Column" ) ), uno::UNO_QUERY );
956     return xTemplate;
957 }
958 
setChartTypeManager(const uno::Reference<chart2::XChartTypeManager> & xNewManager)959 void SAL_CALL ChartModel::setChartTypeManager( const uno::Reference< chart2::XChartTypeManager >& xNewManager )
960             throw (uno::RuntimeException)
961 {
962     {
963         // /--
964         MutexGuard aGuard( m_aModelMutex );
965         m_xChartTypeManager = xNewManager;
966         // \--
967     }
968     setModified( sal_True );
969 }
970 
getChartTypeManager()971 uno::Reference< chart2::XChartTypeManager > SAL_CALL ChartModel::getChartTypeManager()
972             throw (uno::RuntimeException)
973 {
974     // /--
975     MutexGuard aGuard( m_aModelMutex );
976     return m_xChartTypeManager;
977     // \--
978 }
979 
getPageBackground()980 uno::Reference< beans::XPropertySet > SAL_CALL ChartModel::getPageBackground()
981     throw (uno::RuntimeException)
982 {
983     // /--
984     MutexGuard aGuard( m_aModelMutex );
985     return m_xPageBackground;
986     // \--
987 }
988 
989 // ____ XTitled ____
getTitleObject()990 uno::Reference< chart2::XTitle > SAL_CALL ChartModel::getTitleObject()
991     throw (uno::RuntimeException)
992 {
993     // /--
994     MutexGuard aGuard( m_aModelMutex );
995     return m_xTitle;
996     // \--
997 }
998 
setTitleObject(const uno::Reference<chart2::XTitle> & xTitle)999 void SAL_CALL ChartModel::setTitleObject( const uno::Reference< chart2::XTitle >& xTitle )
1000     throw (uno::RuntimeException)
1001 {
1002     {
1003         // /--
1004         MutexGuard aGuard( m_aModelMutex );
1005         if( m_xTitle.is() )
1006             ModifyListenerHelper::removeListener( m_xTitle, this );
1007         m_xTitle = xTitle;
1008         ModifyListenerHelper::addListener( m_xTitle, this );
1009         // \--
1010     }
1011     setModified( sal_True );
1012 }
1013 
1014 // ____ XInterface (for old API wrapper) ____
queryInterface(const uno::Type & aType)1015 uno::Any SAL_CALL ChartModel::queryInterface( const uno::Type& aType )
1016     throw (uno::RuntimeException)
1017 {
1018     uno::Any aResult( impl::ChartModel_Base::queryInterface( aType ));
1019 
1020     if( ! aResult.hasValue())
1021     {
1022         // try old API wrapper
1023         try
1024         {
1025             if( m_xOldModelAgg.is())
1026                 aResult = m_xOldModelAgg->queryAggregation( aType );
1027         }
1028         catch( uno::Exception & ex )
1029         {
1030             ASSERT_EXCEPTION( ex );
1031         }
1032     }
1033 
1034     return aResult;
1035 }
1036 
1037 // ____ XCloneable ____
createClone()1038 Reference< util::XCloneable > SAL_CALL ChartModel::createClone()
1039     throw (uno::RuntimeException)
1040 {
1041     return Reference< util::XCloneable >( new ChartModel( *this ));
1042 }
1043 
1044 // ____ XVisualObject ____
setVisualAreaSize(::sal_Int64 nAspect,const awt::Size & aSize)1045 void SAL_CALL ChartModel::setVisualAreaSize( ::sal_Int64 nAspect, const awt::Size& aSize )
1046     throw (lang::IllegalArgumentException,
1047            embed::WrongStateException,
1048            uno::Exception,
1049            uno::RuntimeException)
1050 {
1051     if( nAspect == embed::Aspects::MSOLE_CONTENT )
1052     {
1053         ControllerLockGuard aLockGuard( this );
1054         bool bChanged =
1055             (m_aVisualAreaSize.Width != aSize.Width ||
1056              m_aVisualAreaSize.Height != aSize.Height);
1057 
1058         // #i12587# support for shapes in chart
1059         if ( bChanged )
1060         {
1061             impl_adjustAdditionalShapesPositionAndSize( aSize );
1062         }
1063 
1064         m_aVisualAreaSize = aSize;
1065         if( bChanged )
1066             setModified( sal_True );
1067     }
1068     else
1069     {
1070         OSL_ENSURE( false, "setVisualAreaSize: Aspect not implemented yet.");
1071     }
1072 }
1073 
getVisualAreaSize(::sal_Int64 nAspect)1074 awt::Size SAL_CALL ChartModel::getVisualAreaSize( ::sal_Int64 nAspect )
1075     throw (lang::IllegalArgumentException,
1076            embed::WrongStateException,
1077            uno::Exception,
1078            uno::RuntimeException)
1079 {
1080     OSL_ENSURE( nAspect == embed::Aspects::MSOLE_CONTENT,
1081                 "No aspects other than content are supported" );
1082     (void)(nAspect); // avoid warning in non-debug builds
1083     // other possible aspects are MSOLE_THUMBNAIL, MSOLE_ICON and MSOLE_DOCPRINT
1084 
1085     return m_aVisualAreaSize;
1086 }
1087 
getPreferredVisualRepresentation(::sal_Int64 nAspect)1088 embed::VisualRepresentation SAL_CALL ChartModel::getPreferredVisualRepresentation( ::sal_Int64 nAspect )
1089     throw (lang::IllegalArgumentException,
1090            embed::WrongStateException,
1091            uno::Exception,
1092            uno::RuntimeException)
1093 {
1094     OSL_ENSURE( nAspect == embed::Aspects::MSOLE_CONTENT,
1095                 "No aspects other than content are supported" );
1096     (void)(nAspect); // avoid warning in non-debug builds
1097 
1098     embed::VisualRepresentation aResult;
1099 
1100     try
1101     {
1102         Sequence< sal_Int8 > aMetafile;
1103 
1104         //get view from old api wrapper
1105         Reference< datatransfer::XTransferable > xTransferable(
1106             this->createInstance( CHART_VIEW_SERVICE_NAME ), uno::UNO_QUERY );
1107         if( xTransferable.is() )
1108         {
1109             datatransfer::DataFlavor aDataFlavor( lcl_aGDIMetaFileMIMEType,
1110                     C2U( "GDIMetaFile" ),
1111 		            ::getCppuType( (const uno::Sequence< sal_Int8 >*) 0 ) );
1112 
1113             uno::Any aData( xTransferable->getTransferData( aDataFlavor ) );
1114             aData >>= aMetafile;
1115         }
1116 
1117         aResult.Flavor.MimeType = lcl_aGDIMetaFileMIMEType;
1118         aResult.Flavor.DataType = getCppuType( &aMetafile );
1119 
1120         aResult.Data <<= aMetafile;
1121     }
1122     catch( uno::Exception & ex )
1123     {
1124         ASSERT_EXCEPTION( ex );
1125     }
1126 
1127     return aResult;
1128 }
1129 
getMapUnit(::sal_Int64 nAspect)1130 ::sal_Int32 SAL_CALL ChartModel::getMapUnit( ::sal_Int64 nAspect )
1131     throw (uno::Exception,
1132            uno::RuntimeException)
1133 {
1134     OSL_ENSURE( nAspect == embed::Aspects::MSOLE_CONTENT,
1135                 "No aspects other than content are supported" );
1136     (void)(nAspect); // avoid warning in non-debug builds
1137     return embed::EmbedMapUnits::ONE_100TH_MM;
1138 }
1139 
1140 // ____ datatransfer::XTransferable ____
getTransferData(const datatransfer::DataFlavor & aFlavor)1141 uno::Any SAL_CALL ChartModel::getTransferData( const datatransfer::DataFlavor& aFlavor )
1142     throw (datatransfer::UnsupportedFlavorException,
1143            io::IOException,
1144            uno::RuntimeException)
1145 {
1146     uno::Any aResult;
1147     if( this->isDataFlavorSupported( aFlavor ))
1148     {
1149         try
1150         {
1151             //get view from old api wrapper
1152             Reference< datatransfer::XTransferable > xTransferable(
1153                 this->createInstance( CHART_VIEW_SERVICE_NAME ), uno::UNO_QUERY );
1154             if( xTransferable.is() &&
1155                 xTransferable->isDataFlavorSupported( aFlavor ))
1156             {
1157                 aResult = xTransferable->getTransferData( aFlavor );
1158             }
1159         }
1160         catch( uno::Exception & ex )
1161         {
1162             ASSERT_EXCEPTION( ex );
1163         }
1164     }
1165     else
1166     {
1167         throw datatransfer::UnsupportedFlavorException(
1168             aFlavor.MimeType, static_cast< ::cppu::OWeakObject* >( this ));
1169     }
1170 
1171     return aResult;
1172 }
1173 
getTransferDataFlavors()1174 Sequence< datatransfer::DataFlavor > SAL_CALL ChartModel::getTransferDataFlavors()
1175     throw (uno::RuntimeException)
1176 {
1177     uno::Sequence< datatransfer::DataFlavor > aRet(1);
1178 
1179 //     aRet[0] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMEType,
1180 //         C2U( "GDIMetaFile" ),
1181 // 		::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) );
1182     aRet[0] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMETypeHighContrast,
1183         C2U( "GDIMetaFile" ),
1184 		::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) );
1185 
1186 	return aRet;
1187 }
1188 
isDataFlavorSupported(const datatransfer::DataFlavor & aFlavor)1189 ::sal_Bool SAL_CALL ChartModel::isDataFlavorSupported( const datatransfer::DataFlavor& aFlavor )
1190     throw (uno::RuntimeException)
1191 {
1192 //     return ( aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMEType) ||
1193 //              aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMETypeHighContrast) );
1194     return aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMETypeHighContrast);
1195 }
1196 
1197 
1198 
1199 namespace
1200 {
1201 enum eServiceType
1202 {
1203     SERVICE_DASH_TABLE,
1204     SERVICE_GARDIENT_TABLE,
1205     SERVICE_HATCH_TABLE,
1206     SERVICE_BITMAP_TABLE,
1207     SERVICE_TRANSP_GRADIENT_TABLE,
1208     SERVICE_MARKER_TABLE,
1209     SERVICE_NAMESPACE_MAP
1210 };
1211 
1212 typedef ::std::map< ::rtl::OUString, enum eServiceType > tServiceNameMap;
1213 typedef ::comphelper::MakeMap< ::rtl::OUString, enum eServiceType > tMakeServiceNameMap;
1214 
lcl_getStaticServiceNameMap()1215 tServiceNameMap & lcl_getStaticServiceNameMap()
1216 {
1217     static tServiceNameMap aServiceNameMap(
1218         tMakeServiceNameMap
1219         ( C2U( "com.sun.star.drawing.DashTable" ),                    SERVICE_DASH_TABLE )
1220         ( C2U( "com.sun.star.drawing.GradientTable" ),                SERVICE_GARDIENT_TABLE )
1221         ( C2U( "com.sun.star.drawing.HatchTable" ),                   SERVICE_HATCH_TABLE )
1222         ( C2U( "com.sun.star.drawing.BitmapTable" ),                  SERVICE_BITMAP_TABLE )
1223         ( C2U( "com.sun.star.drawing.TransparencyGradientTable" ),    SERVICE_TRANSP_GRADIENT_TABLE )
1224         ( C2U( "com.sun.star.drawing.MarkerTable" ),                  SERVICE_MARKER_TABLE )
1225         ( C2U( "com.sun.star.xml.NamespaceMap" ),                     SERVICE_NAMESPACE_MAP )
1226         );
1227     return aServiceNameMap;
1228 }
1229 }
1230 // ____ XMultiServiceFactory ____
createInstance(const OUString & rServiceSpecifier)1231 Reference< uno::XInterface > SAL_CALL ChartModel::createInstance( const OUString& rServiceSpecifier )
1232             throw( uno::Exception, uno::RuntimeException )
1233 {
1234     uno::Reference< uno::XInterface > xResult;
1235     tServiceNameMap & rMap = lcl_getStaticServiceNameMap();
1236 
1237     tServiceNameMap::const_iterator aIt( rMap.find( rServiceSpecifier ));
1238     if( aIt != rMap.end())
1239     {
1240         switch( (*aIt).second )
1241         {
1242             case SERVICE_DASH_TABLE:
1243             case SERVICE_GARDIENT_TABLE:
1244             case SERVICE_HATCH_TABLE:
1245             case SERVICE_BITMAP_TABLE:
1246             case SERVICE_TRANSP_GRADIENT_TABLE:
1247             case SERVICE_MARKER_TABLE:
1248                 {
1249                     uno::Reference< lang::XMultiServiceFactory > xFact(
1250                         this->createInstance( CHART_VIEW_SERVICE_NAME ), uno::UNO_QUERY );
1251                     if ( xFact.is() )
1252                     {
1253                         return xFact->createInstance( rServiceSpecifier );
1254                     }
1255                 }
1256                 break;
1257             case SERVICE_NAMESPACE_MAP:
1258                 return Reference< uno::XInterface >( m_xXMLNamespaceMap );
1259         }
1260     }
1261     else
1262     {
1263         if( m_xOldModelAgg.is() )
1264         {
1265             Any aAny = m_xOldModelAgg->queryAggregation( ::getCppuType((const uno::Reference< lang::XMultiServiceFactory >*)0) );
1266             uno::Reference< lang::XMultiServiceFactory > xOldModelFactory;
1267             if( (aAny >>= xOldModelFactory) && xOldModelFactory.is() )
1268             {
1269                 return xOldModelFactory->createInstance( rServiceSpecifier );
1270             }
1271         }
1272     }
1273     return 0;
1274 }
1275 
createInstanceWithArguments(const OUString & rServiceSpecifier,const Sequence<Any> & Arguments)1276 Reference< uno::XInterface > SAL_CALL ChartModel::createInstanceWithArguments(
1277             const OUString& rServiceSpecifier , const Sequence< Any >& Arguments )
1278             throw( uno::Exception, uno::RuntimeException )
1279 {
1280     OSL_ENSURE( Arguments.getLength(), "createInstanceWithArguments: Warning: Arguments are ignored" );
1281     (void)(Arguments); // avoid warning in non-debug builds
1282     return createInstance( rServiceSpecifier );
1283 }
1284 
getAvailableServiceNames()1285 Sequence< OUString > SAL_CALL ChartModel::getAvailableServiceNames()
1286             throw( uno::RuntimeException )
1287 {
1288     uno::Sequence< ::rtl::OUString > aResult;
1289 
1290     if( m_xOldModelAgg.is())
1291     {
1292         Any aAny = m_xOldModelAgg->queryAggregation( ::getCppuType((const uno::Reference< lang::XMultiServiceFactory >*)0) );
1293         uno::Reference< lang::XMultiServiceFactory > xOldModelFactory;
1294         if( (aAny >>= xOldModelFactory) && xOldModelFactory.is() )
1295         {
1296             return xOldModelFactory->getAvailableServiceNames();
1297         }
1298     }
1299     return aResult;
1300 }
1301 
impl_getNumberFormatsSupplier()1302 Reference< util::XNumberFormatsSupplier > ChartModel::impl_getNumberFormatsSupplier()
1303 {
1304     if( !m_xNumberFormatsSupplier.is() )
1305     {
1306         if( !m_xOwnNumberFormatsSupplier.is() )
1307         {
1308             Reference< lang::XMultiServiceFactory > xFactory( m_xContext->getServiceManager(), uno::UNO_QUERY );
1309             m_apSvNumberFormatter.reset( new SvNumberFormatter( xFactory, LANGUAGE_SYSTEM ) );
1310             m_xOwnNumberFormatsSupplier = new SvNumberFormatsSupplierObj( m_apSvNumberFormatter.get() );
1311             //pOwnNumberFormatter->ChangeStandardPrec( 15 ); todo?
1312         }
1313         m_xNumberFormatsSupplier = m_xOwnNumberFormatsSupplier;
1314     }
1315     return m_xNumberFormatsSupplier;
1316 }
1317 
1318 // ____ XUnoTunnel ___
getSomething(const Sequence<::sal_Int8> & aIdentifier)1319 ::sal_Int64 SAL_CALL ChartModel::getSomething( const Sequence< ::sal_Int8 >& aIdentifier )
1320         throw( uno::RuntimeException)
1321 {
1322     if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( SvNumberFormatsSupplierObj::getUnoTunnelId().getConstArray(),
1323 														 aIdentifier.getConstArray(), 16 ) )
1324 	{
1325         Reference< lang::XUnoTunnel > xTunnel( impl_getNumberFormatsSupplier(), uno::UNO_QUERY );
1326         if( xTunnel.is() )
1327             return xTunnel->getSomething( aIdentifier );
1328 	}
1329 	return 0;
1330 }
1331 
1332 // ____ XNumberFormatsSupplier ____
getNumberFormatSettings()1333 uno::Reference< beans::XPropertySet > SAL_CALL ChartModel::getNumberFormatSettings()
1334     throw (uno::RuntimeException)
1335 {
1336     Reference< util::XNumberFormatsSupplier > xSupplier( impl_getNumberFormatsSupplier() );
1337     if( xSupplier.is() )
1338         return xSupplier->getNumberFormatSettings();
1339     return uno::Reference< beans::XPropertySet >();
1340 }
1341 
getNumberFormats()1342 uno::Reference< util::XNumberFormats > SAL_CALL ChartModel::getNumberFormats()
1343     throw (uno::RuntimeException)
1344 {
1345     Reference< util::XNumberFormatsSupplier > xSupplier( impl_getNumberFormatsSupplier() );
1346     if( xSupplier.is() )
1347         return xSupplier->getNumberFormats();
1348     return uno::Reference< util::XNumberFormats >();
1349 }
1350 
1351 // ____ XChild ____
getParent()1352 Reference< uno::XInterface > SAL_CALL ChartModel::getParent()
1353     throw (uno::RuntimeException)
1354 {
1355     return Reference< uno::XInterface >(m_xParent,uno::UNO_QUERY);
1356 }
1357 
setParent(const Reference<uno::XInterface> & Parent)1358 void SAL_CALL ChartModel::setParent( const Reference< uno::XInterface >& Parent )
1359     throw (lang::NoSupportException,
1360            uno::RuntimeException)
1361 {
1362     if( Parent != m_xParent )
1363         m_xParent.set( Parent, uno::UNO_QUERY );
1364 }
1365 
1366 // ____ XDataSource ____
getDataSequences()1367 uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > SAL_CALL ChartModel::getDataSequences()
1368     throw (uno::RuntimeException)
1369 {
1370     Reference< chart2::data::XDataSource > xSource(
1371         DataSourceHelper::getUsedData( uno::Reference< frame::XModel >(this) ) );
1372     if( xSource.is())
1373         return xSource->getDataSequences();
1374 
1375     return uno::Sequence< Reference< chart2::data::XLabeledDataSequence > >();
1376 }
1377 
1378 }  // namespace chart
1379