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