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