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