fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / chart2 / source / controller / main / ChartController.cxx
blobb53ebf66c8d278c853378db08f7f126e4c64c03a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "ChartController.hxx"
21 #include "servicenames.hxx"
22 #include "ResId.hxx"
23 #include "dlg_DataSource.hxx"
24 #include "ChartModelHelper.hxx"
25 #include "ControllerCommandDispatch.hxx"
26 #include "Strings.hrc"
27 #include "chartview/ExplicitValueProvider.hxx"
28 #include "ChartViewHelper.hxx"
30 #include "ChartWindow.hxx"
31 #include "chartview/DrawModelWrapper.hxx"
32 #include "DrawViewWrapper.hxx"
33 #include "ObjectIdentifier.hxx"
34 #include "DiagramHelper.hxx"
35 #include "ControllerLockGuard.hxx"
36 #include "UndoGuard.hxx"
37 #include "ChartDropTargetHelper.hxx"
39 #include "macros.hxx"
40 #include "dlg_CreationWizard.hxx"
41 #include "dlg_ChartType.hxx"
42 #include "AccessibleChartView.hxx"
43 #include "DrawCommandDispatch.hxx"
44 #include "ShapeController.hxx"
45 #include "UndoActions.hxx"
47 #include <comphelper/InlineContainer.hxx>
48 #include <cppuhelper/supportsservice.hxx>
50 #include <com/sun/star/awt/PosSize.hpp>
51 #include <com/sun/star/chart2/XChartDocument.hpp>
52 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
53 #include <com/sun/star/frame/XLoadable.hpp>
54 #include <com/sun/star/util/XCloneable.hpp>
55 #include <com/sun/star/embed/XEmbeddedClient.hpp>
56 #include <com/sun/star/util/XModeChangeBroadcaster.hpp>
57 #include <com/sun/star/util/XModifyBroadcaster.hpp>
58 #include <com/sun/star/frame/LayoutManagerEvents.hpp>
59 #include <com/sun/star/document/XUndoManagerSupplier.hpp>
60 #include <com/sun/star/document/XUndoAction.hpp>
62 #include <vcl/msgbox.hxx>
63 #include <toolkit/awt/vclxwindow.hxx>
64 #include <toolkit/helper/vclunohelper.hxx>
65 #include <vcl/svapp.hxx>
66 #include <osl/mutex.hxx>
68 #include <com/sun/star/frame/XLayoutManager.hpp>
69 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
71 // this is needed to properly destroy the unique_ptr to the AcceleratorExecute
72 // object in the DTOR
73 #include <svtools/acceleratorexecute.hxx>
74 #include <svx/ActionDescriptionProvider.hxx>
75 #include <tools/diagnose_ex.h>
77 // enable the following define to let the controller listen to model changes and
78 // react on this by rebuilding the view
79 #define TEST_ENABLE_MODIFY_LISTENER
81 namespace chart
84 using namespace ::com::sun::star;
85 using namespace ::com::sun::star::accessibility;
86 using namespace ::com::sun::star::chart2;
87 using ::com::sun::star::uno::Any;
88 using ::com::sun::star::uno::Reference;
89 using ::com::sun::star::uno::Sequence;
91 ChartController::ChartController(uno::Reference<uno::XComponentContext> const & xContext) :
92 m_aLifeTimeManager( NULL ),
93 m_bSuspended( false ),
94 m_bCanClose( true ),
95 m_xCC(xContext), //@todo is it allowed to hold this context??
96 m_xFrame( NULL ),
97 m_aModelMutex(),
98 m_aModel( NULL, m_aModelMutex ),
99 m_pChartWindow( NULL ),
100 m_xViewWindow(),
101 m_xChartView(),
102 m_pDrawModelWrapper(),
103 m_pDrawViewWrapper(NULL),
104 m_eDragMode(SDRDRAG_MOVE),
105 m_bWaitingForDoubleClick(false),
106 m_bWaitingForMouseUp(false),
107 m_bConnectingToView(false),
108 m_xUndoManager( 0 ),
109 m_aDispatchContainer( m_xCC, this ),
110 m_eDrawMode( CHARTDRAW_SELECT )
112 m_aDoubleClickTimer.SetTimeoutHdl( LINK( this, ChartController, DoubleClickWaitingHdl ) );
115 ChartController::~ChartController()
117 stopDoubleClickWaiting();
120 ChartController::RefCountable::RefCountable() : m_nRefCount(0)
124 ChartController::RefCountable::~RefCountable()
127 void ChartController::RefCountable::acquire()
129 m_nRefCount++;
131 void ChartController::RefCountable::release()
133 m_nRefCount--;
134 if(!m_nRefCount)
135 delete this;
138 ChartController::TheModel::TheModel( const uno::Reference< frame::XModel > & xModel ) :
139 m_xModel( xModel ),
140 m_xCloseable( NULL ),
141 m_bOwnership( true )
143 m_xCloseable =
144 uno::Reference< util::XCloseable >( xModel, uno::UNO_QUERY );
147 ChartController::TheModel::~TheModel()
151 void ChartController::TheModel::SetOwnership( bool bGetsOwnership )
153 m_bOwnership = bGetsOwnership;
156 void ChartController::TheModel::addListener( ChartController* pController )
158 if(m_xCloseable.is())
160 //if you need to be able to veto against the destruction of the model
161 // you must add as a close listener
163 //otherwise you 'can' add as closelistener or 'must' add as dispose event listener
165 m_xCloseable->addCloseListener(
166 static_cast<util::XCloseListener*>(pController) );
168 else if( m_xModel.is() )
170 //we need to add as dispose event listener
171 m_xModel->addEventListener(
172 static_cast<util::XCloseListener*>(pController) );
177 void ChartController::TheModel::removeListener( ChartController* pController )
179 if(m_xCloseable.is())
180 m_xCloseable->removeCloseListener(
181 static_cast<util::XCloseListener*>(pController) );
183 else if( m_xModel.is() )
184 m_xModel->removeEventListener(
185 static_cast<util::XCloseListener*>(pController) );
188 void ChartController::TheModel::tryTermination()
190 if(!m_bOwnership)
191 return;
195 if(m_xCloseable.is())
199 //@todo ? are we allowed to use sal_True here if we have the explicit ownership?
200 //I think yes, because there might be other closelistners later in the list which might be interested still
201 //but make sure that we do not throw the CloseVetoException here ourselfs
202 //so stop listening before trying to terminate or check the source of queryclosing event
203 m_xCloseable->close(sal_True);
205 m_bOwnership = false;
207 catch( const util::CloseVetoException& )
209 //since we have indicated to give up the ownership with parameter true in close call
210 //the one who has thrown the CloseVetoException is the new owner
212 #if OSL_DEBUG_LEVEL > 1
213 OSL_ENSURE( !m_bOwnership,
214 "INFO: a well known owner has caught a CloseVetoException after calling close(true)" );
215 #endif
217 m_bOwnership = false;
218 return;
222 else if( m_xModel.is() )
224 //@todo correct??
225 m_xModel->dispose();
226 return;
229 catch(const uno::Exception& ex)
231 (void)(ex); // no warning in non-debug builds
232 OSL_FAIL( OString( OString("Termination of model failed: ")
233 + OUStringToOString( ex.Message, RTL_TEXTENCODING_ASCII_US ) ).getStr() );
237 ChartController::TheModelRef::TheModelRef( TheModel* pTheModel, osl::Mutex& rMutex ) :
238 m_pTheModel(pTheModel),
239 m_rModelMutex(rMutex)
241 osl::Guard< osl::Mutex > aGuard( m_rModelMutex );
242 if(m_pTheModel)
243 m_pTheModel->acquire();
245 ChartController::TheModelRef::TheModelRef( const TheModelRef& rTheModel, ::osl::Mutex& rMutex ) :
246 m_rModelMutex(rMutex)
248 osl::Guard< osl::Mutex > aGuard( m_rModelMutex );
249 m_pTheModel=rTheModel.operator->();
250 if(m_pTheModel)
251 m_pTheModel->acquire();
253 ChartController::TheModelRef& ChartController::TheModelRef::operator=(TheModel* pTheModel)
255 osl::Guard< osl::Mutex > aGuard( m_rModelMutex );
256 if(m_pTheModel==pTheModel)
257 return *this;
258 if(m_pTheModel)
259 m_pTheModel->release();
260 m_pTheModel=pTheModel;
261 if(m_pTheModel)
262 m_pTheModel->acquire();
263 return *this;
265 ChartController::TheModelRef& ChartController::TheModelRef::operator=(const TheModelRef& rTheModel)
267 osl::Guard< osl::Mutex > aGuard( m_rModelMutex );
268 TheModel* pNew=rTheModel.operator->();
269 if(m_pTheModel==pNew)
270 return *this;
271 if(m_pTheModel)
272 m_pTheModel->release();
273 m_pTheModel=pNew;
274 if(m_pTheModel)
275 m_pTheModel->acquire();
276 return *this;
278 ChartController::TheModelRef::~TheModelRef()
280 osl::Guard< osl::Mutex > aGuard( m_rModelMutex );
281 if(m_pTheModel)
282 m_pTheModel->release();
284 bool ChartController::TheModelRef::is() const
286 return (m_pTheModel != 0);
289 // private methods
291 bool ChartController::impl_isDisposedOrSuspended() const
293 if( m_aLifeTimeManager.impl_isDisposed() )
294 return true;
296 if( m_bSuspended )
298 OSL_FAIL( "This Controller is suspended" );
299 return true;
301 return false;
304 // lang::XServiceInfo
306 OUString SAL_CALL ChartController::getImplementationName()
307 throw( css::uno::RuntimeException, std::exception )
309 return getImplementationName_Static();
312 OUString ChartController::getImplementationName_Static()
314 return OUString(CHART_CONTROLLER_SERVICE_IMPLEMENTATION_NAME);
317 sal_Bool SAL_CALL ChartController::supportsService( const OUString& rServiceName )
318 throw( css::uno::RuntimeException, std::exception )
320 return cppu::supportsService(this, rServiceName);
323 css::uno::Sequence< OUString > SAL_CALL ChartController::getSupportedServiceNames()
324 throw( css::uno::RuntimeException, std::exception )
326 return getSupportedServiceNames_Static();
329 uno::Sequence< OUString > ChartController::getSupportedServiceNames_Static()
331 uno::Sequence< OUString > aSNS( 2 );
332 aSNS.getArray()[ 0 ] = CHART_CONTROLLER_SERVICE_NAME;
333 aSNS.getArray()[ 1 ] = "com.sun.star.frame.Controller";
334 //// @todo : add additional services if you support any further
335 return aSNS;
338 // XController
340 void SAL_CALL ChartController::attachFrame(
341 const uno::Reference<frame::XFrame>& xFrame )
342 throw(uno::RuntimeException, std::exception)
344 SolarMutexGuard aGuard;
346 if( impl_isDisposedOrSuspended() ) //@todo? allow attaching the frame while suspended?
347 return; //behave passive if already disposed or suspended
349 if(m_xFrame.is()) //what happens, if we do have a Frame already??
351 //@todo? throw exception?
352 OSL_FAIL( "there is already a frame attached to the controller" );
353 return;
356 //--attach frame
357 m_xFrame = xFrame; //the frameloader is responsible to call xFrame->setComponent
359 //add as disposelistener to the frame (due to persistent reference) ??...:
361 //the frame is considered to be owner of this controller and will live longer than we do
362 //the frame or the disposer of the frame has the duty to call suspend and dispose on this object
363 //so we do not need to add as lang::XEventListener for DisposingEvents right?
365 //@todo nothing right???
367 //create view @todo is this the correct place here??
369 vcl::Window* pParent = NULL;
370 //get the window parent from the frame to use as parent for our new window
371 if(xFrame.is())
373 uno::Reference< awt::XWindow > xContainerWindow = xFrame->getContainerWindow();
374 VCLXWindow* pParentComponent = VCLXWindow::GetImplementation(xContainerWindow);
375 assert(pParentComponent);
376 if (pParentComponent)
377 pParentComponent->setVisible(sal_True);
379 pParent = VCLUnoHelper::GetWindow( xContainerWindow );
382 if(m_pChartWindow)
384 //@todo delete ...
385 m_pChartWindow->clear();
386 m_apDropTargetHelper.reset();
389 // calls to VCL
390 SolarMutexGuard aSolarGuard;
391 m_pChartWindow = VclPtr<ChartWindow>::Create(this,pParent,pParent?pParent->GetStyle():0);
392 m_pChartWindow->SetBackground();//no Background
393 m_xViewWindow = uno::Reference< awt::XWindow >( m_pChartWindow->GetComponentInterface(), uno::UNO_QUERY );
394 m_pChartWindow->Show();
395 m_apDropTargetHelper.reset(
396 new ChartDropTargetHelper( m_pChartWindow->GetDropTarget(),
397 uno::Reference< chart2::XChartDocument >( getModel(), uno::UNO_QUERY )));
399 impl_createDrawViewController();
402 //create the menu
404 uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY );
405 if( xPropSet.is() )
409 uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
410 xPropSet->getPropertyValue( "LayoutManager" ) >>= xLayoutManager;
411 if ( xLayoutManager.is() )
413 xLayoutManager->lock();
414 xLayoutManager->requestElement( "private:resource/menubar/menubar" );
415 //@todo: createElement should become unnecessary, remove when #i79198# is fixed
416 xLayoutManager->createElement( "private:resource/toolbar/standardbar" );
417 xLayoutManager->requestElement( "private:resource/toolbar/standardbar" );
418 //@todo: createElement should become unnecessary, remove when #i79198# is fixed
419 xLayoutManager->createElement( "private:resource/toolbar/toolbar" );
420 xLayoutManager->requestElement( "private:resource/toolbar/toolbar" );
422 // #i12587# support for shapes in chart
423 xLayoutManager->createElement( "private:resource/toolbar/drawbar" );
424 xLayoutManager->requestElement( "private:resource/toolbar/drawbar" );
426 xLayoutManager->requestElement( "private:resource/statusbar/statusbar" );
427 xLayoutManager->unlock();
429 // add as listener to get notified when
430 m_xLayoutManagerEventBroadcaster.set( xLayoutManager, uno::UNO_QUERY );
431 if( m_xLayoutManagerEventBroadcaster.is())
432 m_xLayoutManagerEventBroadcaster->addLayoutManagerEventListener( this );
435 catch( const uno::Exception & ex )
437 ASSERT_EXCEPTION( ex );
443 //XModeChangeListener
444 void SAL_CALL ChartController::modeChanged( const util::ModeChangeEvent& rEvent )
445 throw (uno::RuntimeException, std::exception)
447 //adjust controller to view status changes
449 if( rEvent.NewMode == "dirty" )
451 //the view has become dirty, we should repaint it if we have a window
452 SolarMutexGuard aGuard;
453 if( m_pChartWindow )
454 m_pChartWindow->ForceInvalidate();
456 else if( rEvent.NewMode == "invalid" )
458 //the view is about to become invalid so end all actions on it
459 impl_invalidateAccessible();
460 SolarMutexGuard aGuard;
461 if( m_pDrawViewWrapper && m_pDrawViewWrapper->IsTextEdit() )
462 this->EndTextEdit();
463 if( m_pDrawViewWrapper )
465 m_pDrawViewWrapper->UnmarkAll();
466 m_pDrawViewWrapper->HideSdrPage();
469 else
471 //the view was rebuild so we can start some actions on it again
472 if( !m_bConnectingToView )
474 if(m_pChartWindow && m_aModel.is() )
476 m_bConnectingToView = true;
478 GetDrawModelWrapper();
479 if(m_pDrawModelWrapper)
482 SolarMutexGuard aGuard;
483 if( m_pDrawViewWrapper )
484 m_pDrawViewWrapper->ReInit();
487 //reselect object
488 if( m_aSelection.hasSelection() )
489 this->impl_selectObjectAndNotiy();
490 else
491 ChartModelHelper::triggerRangeHighlighting( getModel() );
493 impl_initializeAccessible();
496 SolarMutexGuard aGuard;
497 if( m_pChartWindow )
498 m_pChartWindow->Invalidate();
502 m_bConnectingToView = false;
508 sal_Bool SAL_CALL ChartController::attachModel( const uno::Reference< frame::XModel > & xModel )
509 throw(uno::RuntimeException, std::exception)
511 impl_invalidateAccessible();
513 //is called to attach the controller to a new model.
514 //return true if attach was successfully, false otherwise (e.g. if you do not work with a model)
516 SolarMutexResettableGuard aGuard;
517 if( impl_isDisposedOrSuspended() ) //@todo? allow attaching a new model while suspended?
518 return sal_False; //behave passive if already disposed or suspended
519 aGuard.clear();
521 TheModelRef aNewModelRef( new TheModel( xModel), m_aModelMutex);
522 TheModelRef aOldModelRef(m_aModel,m_aModelMutex);
523 m_aModel = aNewModelRef;
525 //--handle relations to the old model if any
526 if( aOldModelRef.is() )
528 uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY );
529 if( xViewBroadcaster.is() )
530 xViewBroadcaster->removeModeChangeListener(this);
531 m_pDrawModelWrapper.reset();
533 aOldModelRef->removeListener( this );
534 #ifdef TEST_ENABLE_MODIFY_LISTENER
535 uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aOldModelRef->getModel(),uno::UNO_QUERY );
536 if( xMBroadcaster.is())
537 xMBroadcaster->removeModifyListener( this );
538 #endif
541 //--handle relations to the new model
542 aNewModelRef->addListener( this );
544 aGuard.reset(); // lock for m_aDispatchContainer access
545 // set new model at dispatchers
546 m_aDispatchContainer.setModel( aNewModelRef->getModel());
547 ControllerCommandDispatch * pDispatch = new ControllerCommandDispatch( m_xCC, this, &m_aDispatchContainer );
548 pDispatch->initialize();
550 // the dispatch container will return "this" for all commands returned by
551 // impl_getAvailableCommands(). That means, for those commands dispatch()
552 // is called here at the ChartController.
553 m_aDispatchContainer.setChartDispatch( pDispatch, impl_getAvailableCommands() );
555 DrawCommandDispatch* pDrawDispatch = new DrawCommandDispatch( m_xCC, this );
556 pDrawDispatch->initialize();
557 m_aDispatchContainer.setDrawCommandDispatch( pDrawDispatch );
559 ShapeController* pShapeController = new ShapeController( m_xCC, this );
560 pShapeController->initialize();
561 m_aDispatchContainer.setShapeController( pShapeController );
562 aGuard.clear();
564 #ifdef TEST_ENABLE_MODIFY_LISTENER
565 uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aNewModelRef->getModel(),uno::UNO_QUERY );
566 if( xMBroadcaster.is())
567 xMBroadcaster->addModifyListener( this );
568 #endif
570 // #i119999# Do not do this per default to allow the user to deselect the chart OLE with a single press to ESC
571 // select chart area per default:
572 // select( uno::makeAny( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ) );
574 uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY );
575 if( xFact.is())
577 m_xChartView = xFact->createInstance( CHART_VIEW_SERVICE_NAME );
578 GetDrawModelWrapper();
579 uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY );
580 if( xViewBroadcaster.is() )
581 xViewBroadcaster->addModeChangeListener(this);
584 //the frameloader is responsible to call xModel->connectController
586 SolarMutexGuard aGuard2;
587 if( m_pChartWindow )
588 m_pChartWindow->Invalidate();
591 uno::Reference< document::XUndoManagerSupplier > xSuppUndo( getModel(), uno::UNO_QUERY_THROW );
592 m_xUndoManager.set( xSuppUndo->getUndoManager(), uno::UNO_QUERY_THROW );
594 return sal_True;
597 uno::Reference< frame::XFrame > SAL_CALL ChartController::getFrame()
598 throw(uno::RuntimeException, std::exception)
600 //provides access to owner frame of this controller
601 //return the frame containing this controller
603 return m_xFrame;
606 uno::Reference< frame::XModel > SAL_CALL ChartController::getModel()
607 throw(uno::RuntimeException, std::exception)
609 //provides access to currently attached model
610 //returns the currently attached model
612 //return nothing, if you do not have a model
613 TheModelRef aModelRef( m_aModel, m_aModelMutex);
614 if(aModelRef.is())
615 return aModelRef->getModel();
617 return uno::Reference< frame::XModel > ();
620 uno::Any SAL_CALL ChartController::getViewData()
621 throw(uno::RuntimeException, std::exception)
623 //provides access to current view status
624 //set of data that can be used to restore the current view status at later time
625 // by using XController::restoreViewData()
627 SolarMutexGuard aGuard;
628 if( impl_isDisposedOrSuspended() )
629 return uno::Any(); //behave passive if already disposed or suspended //@todo? or throw an exception??
631 //-- collect current view state
632 uno::Any aRet;
633 //// @todo integrate specialized implementation
635 return aRet;
638 void SAL_CALL ChartController::restoreViewData(
639 const uno::Any& /* Value */ )
640 throw(uno::RuntimeException, std::exception)
642 //restores the view status using the data gotten from a previous call to XController::getViewData()
644 SolarMutexGuard aGuard;
645 if( impl_isDisposedOrSuspended() )
646 return; //behave passive if already disposed or suspended //@todo? or throw an exception??
648 //// @todo integrate specialized implementation
651 sal_Bool SAL_CALL ChartController::suspend( sal_Bool bSuspend )
652 throw(uno::RuntimeException, std::exception)
654 //is called to prepare the controller for closing the view
655 //bSuspend==true: force the controller to suspend his work
656 //bSuspend==false try to reactivate the controller
657 //returns true if request was accepted and of course successfully finished, false otherwise
659 //we may show dialogs here to ask the user for saving changes ... @todo?
661 SolarMutexGuard aGuard;
662 if( m_aLifeTimeManager.impl_isDisposed() )
663 return sal_False; //behave passive if already disposed, return false because request was not accepted //@todo? correct
665 if(bool(bSuspend) == m_bSuspended)
667 OSL_FAIL( "new suspend mode equals old suspend mode" );
668 return sal_True;
671 //change suspend mode
672 if(bSuspend)
674 m_bSuspended = bSuspend;
675 return sal_True;
677 else
679 m_bSuspended = bSuspend;
681 return sal_True;
684 void ChartController::impl_createDrawViewController()
686 SolarMutexGuard aGuard;
687 if(!m_pDrawViewWrapper)
689 if( m_pDrawModelWrapper )
691 m_pDrawViewWrapper = new DrawViewWrapper(&m_pDrawModelWrapper->getSdrModel(),m_pChartWindow,true);
692 m_pDrawViewWrapper->attachParentReferenceDevice( getModel() );
697 void ChartController::impl_deleteDrawViewController()
699 if( m_pDrawViewWrapper )
701 SolarMutexGuard aGuard;
702 if( m_pDrawViewWrapper->IsTextEdit() )
703 this->EndTextEdit();
704 DELETEZ( m_pDrawViewWrapper );
708 // XComponent (base of XController)
710 void SAL_CALL ChartController::dispose()
711 throw(uno::RuntimeException, std::exception)
715 //This object should release all resources and references in the
716 //easiest possible manner
717 //This object must notify all registered listeners using the method
718 //<member>XEventListener::disposing</member>
720 //hold no mutex
721 if( !m_aLifeTimeManager.dispose() )
722 return;
724 // OSL_ENSURE( m_bSuspended, "dispose was called but controller is not suspended" );
726 this->stopDoubleClickWaiting();
728 //end range highlighting
729 if( m_aModel.is())
731 uno::Reference< view::XSelectionChangeListener > xSelectionChangeListener;
732 uno::Reference< chart2::data::XDataReceiver > xDataReceiver( getModel(), uno::UNO_QUERY );
733 if( xDataReceiver.is() )
734 xSelectionChangeListener = uno::Reference< view::XSelectionChangeListener >( xDataReceiver->getRangeHighlighter(), uno::UNO_QUERY );
735 if( xSelectionChangeListener.is() )
737 uno::Reference< frame::XController > xController( this );
738 uno::Reference< lang::XComponent > xComp( xController, uno::UNO_QUERY );
739 lang::EventObject aEvent( xComp );
740 xSelectionChangeListener->disposing( aEvent );
744 //--release all resources and references
746 uno::Reference< chart2::X3DChartWindowProvider > x3DWindowProvider(getModel(), uno::UNO_QUERY_THROW);
747 x3DWindowProvider->setWindow(0);
749 uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY );
750 if( xViewBroadcaster.is() )
751 xViewBroadcaster->removeModeChangeListener(this);
753 impl_invalidateAccessible();
754 SolarMutexGuard aSolarGuard;
755 impl_deleteDrawViewController();
756 m_pDrawModelWrapper.reset();
758 m_apDropTargetHelper.reset();
760 //the accessible view is disposed within window destructor of m_pChartWindow
761 m_pChartWindow->clear();
762 m_pChartWindow = NULL;//m_pChartWindow is deleted via UNO due to dispose of m_xViewWindow (trigerred by Framework (Controller pretends to be XWindow also))
763 m_xViewWindow->dispose();
764 m_xChartView.clear();
767 // remove as listener to layout manager events
768 if( m_xLayoutManagerEventBroadcaster.is())
770 m_xLayoutManagerEventBroadcaster->removeLayoutManagerEventListener( this );
771 m_xLayoutManagerEventBroadcaster.set( 0 );
774 m_xFrame.clear();
775 m_xUndoManager.clear();
777 TheModelRef aModelRef( m_aModel, m_aModelMutex);
778 m_aModel = NULL;
780 if( aModelRef.is())
782 uno::Reference< frame::XModel > xModel( aModelRef->getModel() );
783 if(xModel.is())
784 xModel->disconnectController( uno::Reference< frame::XController >( this ));
786 aModelRef->removeListener( this );
787 #ifdef TEST_ENABLE_MODIFY_LISTENER
790 uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aModelRef->getModel(),uno::UNO_QUERY );
791 if( xMBroadcaster.is())
792 xMBroadcaster->removeModifyListener( this );
794 catch( const uno::Exception & ex )
796 ASSERT_EXCEPTION( ex );
798 #endif
799 aModelRef->tryTermination();
802 //// @todo integrate specialized implementation
803 //e.g. release further resources and references
805 SolarMutexGuard g;
806 m_aDispatchContainer.DisposeAndClear();
808 catch( const uno::Exception & ex )
810 ASSERT_EXCEPTION( ex );
814 void SAL_CALL ChartController::addEventListener(
815 const uno::Reference<lang::XEventListener>& xListener )
816 throw(uno::RuntimeException, std::exception)
818 SolarMutexGuard aGuard;
819 if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode?
820 return; //behave passive if already disposed or suspended
822 //--add listener
823 m_aLifeTimeManager.m_aListenerContainer.addInterface( cppu::UnoType<lang::XEventListener>::get(), xListener );
826 void SAL_CALL ChartController::removeEventListener(
827 const uno::Reference<lang::XEventListener>& xListener )
828 throw(uno::RuntimeException, std::exception)
830 SolarMutexGuard aGuard;
831 if( m_aLifeTimeManager.impl_isDisposed(false) )
832 return; //behave passive if already disposed or suspended
834 //--remove listener
835 m_aLifeTimeManager.m_aListenerContainer.removeInterface( cppu::UnoType<lang::XEventListener>::get(), xListener );
838 // util::XCloseListener
839 void SAL_CALL ChartController::queryClosing(
840 const lang::EventObject& rSource,
841 sal_Bool bGetsOwnership )
842 throw(util::CloseVetoException, uno::RuntimeException, std::exception)
844 //do not use the m_aControllerMutex here because this call is not allowed to block
846 TheModelRef aModelRef( m_aModel, m_aModelMutex);
848 if( !aModelRef.is() )
849 return;
851 if( !(aModelRef->getModel() == rSource.Source) )
853 OSL_FAIL( "queryClosing was called on a controller from an unknown source" );
854 return;
857 if( !m_bCanClose )//@todo tryaqcuire mutex
859 if( bGetsOwnership )
861 aModelRef->SetOwnership( bGetsOwnership );
864 throw util::CloseVetoException();
866 else
868 //@ todo prepare to closing model -> don't start any further hindering actions
872 void SAL_CALL ChartController::notifyClosing(
873 const lang::EventObject& rSource )
874 throw(uno::RuntimeException, std::exception)
876 //Listener should deregister himself and release all references to the closing object.
878 TheModelRef aModelRef( m_aModel, m_aModelMutex);
879 if( impl_releaseThisModel( rSource.Source ) )
881 //--stop listening to the closing model
882 aModelRef->removeListener( this );
884 // #i79087# If the model using this controller is closed, the frame is
885 // expected to be closed as well
886 Reference< util::XCloseable > xFrameCloseable( m_xFrame, uno::UNO_QUERY );
887 if( xFrameCloseable.is())
891 xFrameCloseable->close( sal_False /* DeliverOwnership */ );
892 m_xFrame.clear();
894 catch( const util::CloseVetoException & )
896 // closing was vetoed
902 bool ChartController::impl_releaseThisModel(
903 const uno::Reference< uno::XInterface > & xModel )
905 bool bReleaseModel = false;
907 ::osl::Guard< ::osl::Mutex > aGuard( m_aModelMutex );
908 if( m_aModel.is() && m_aModel->getModel() == xModel )
910 m_aModel = NULL;
911 m_xUndoManager.clear();
912 bReleaseModel = true;
915 if( bReleaseModel )
917 SolarMutexGuard g;
918 m_aDispatchContainer.setModel( 0 );
920 return bReleaseModel;
923 // util::XEventListener (base of XCloseListener)
924 void SAL_CALL ChartController::disposing(
925 const lang::EventObject& rSource )
926 throw(uno::RuntimeException, std::exception)
928 if( !impl_releaseThisModel( rSource.Source ))
930 if( rSource.Source == m_xLayoutManagerEventBroadcaster )
931 m_xLayoutManagerEventBroadcaster.set( 0 );
935 void SAL_CALL ChartController::layoutEvent(
936 const lang::EventObject& aSource,
937 sal_Int16 eLayoutEvent,
938 const uno::Any& /* aInfo */ )
939 throw (uno::RuntimeException, std::exception)
941 if( eLayoutEvent == frame::LayoutManagerEvents::MERGEDMENUBAR )
943 Reference< frame::XLayoutManager > xLM( aSource.Source, uno::UNO_QUERY );
944 if( xLM.is())
946 xLM->createElement( "private:resource/statusbar/statusbar" );
947 xLM->requestElement( "private:resource/statusbar/statusbar" );
952 // XDispatchProvider (required interface)
954 namespace
957 bool lcl_isFormatObjectCommand( const OString& aCommand )
959 if( aCommand == "MainTitle"
960 || aCommand == "SubTitle"
961 || aCommand == "XTitle"
962 || aCommand == "YTitle"
963 || aCommand == "ZTitle"
964 || aCommand == "SecondaryXTitle"
965 || aCommand == "SecondaryYTitle"
966 || aCommand == "AllTitles"
967 || aCommand == "DiagramAxisX"
968 || aCommand == "DiagramAxisY"
969 || aCommand == "DiagramAxisZ"
970 || aCommand == "DiagramAxisA"
971 || aCommand == "DiagramAxisB"
972 || aCommand == "DiagramAxisAll"
973 || aCommand == "DiagramGridXMain"
974 || aCommand == "DiagramGridYMain"
975 || aCommand == "DiagramGridZMain"
976 || aCommand == "DiagramGridXHelp"
977 || aCommand == "DiagramGridYHelp"
978 || aCommand == "DiagramGridZHelp"
979 || aCommand == "DiagramGridAll"
981 || aCommand == "DiagramWall"
982 || aCommand == "DiagramFloor"
983 || aCommand == "DiagramArea"
984 || aCommand == "Legend"
986 || aCommand == "FormatWall"
987 || aCommand == "FormatFloor"
988 || aCommand == "FormatChartArea"
989 || aCommand == "FormatLegend"
991 || aCommand == "FormatTitle"
992 || aCommand == "FormatAxis"
993 || aCommand == "FormatDataSeries"
994 || aCommand == "FormatDataPoint"
995 || aCommand == "FormatDataLabels"
996 || aCommand == "FormatDataLabel"
997 || aCommand == "FormatXErrorBars"
998 || aCommand == "FormatYErrorBars"
999 || aCommand == "FormatMeanValue"
1000 || aCommand == "FormatTrendline"
1001 || aCommand == "FormatTrendlineEquation"
1002 || aCommand == "FormatStockLoss"
1003 || aCommand == "FormatStockGain"
1004 || aCommand == "FormatMajorGrid"
1005 || aCommand == "FormatMinorGrid"
1007 return true;
1009 // else
1010 return false;
1013 } // anonymous namespace
1015 uno::Reference<frame::XDispatch> SAL_CALL
1016 ChartController::queryDispatch(
1017 const util::URL& rURL,
1018 const OUString& rTargetFrameName,
1019 sal_Int32 /* nSearchFlags */)
1020 throw(uno::RuntimeException, std::exception)
1022 SolarMutexGuard aGuard;
1024 if ( !m_aLifeTimeManager.impl_isDisposed() && getModel().is() )
1026 if( !rTargetFrameName.isEmpty() && rTargetFrameName == "_self" )
1027 return m_aDispatchContainer.getDispatchForURL( rURL );
1029 return uno::Reference< frame::XDispatch > ();
1032 uno::Sequence<uno::Reference<frame::XDispatch > >
1033 ChartController::queryDispatches(
1034 const uno::Sequence<frame::DispatchDescriptor>& xDescripts )
1035 throw(uno::RuntimeException, std::exception)
1037 SolarMutexGuard g;
1039 if ( !m_aLifeTimeManager.impl_isDisposed() )
1041 return m_aDispatchContainer.getDispatchesForURLs( xDescripts );
1043 return uno::Sequence<uno::Reference<frame::XDispatch > > ();
1046 // frame::XDispatch
1048 void SAL_CALL ChartController::dispatch(
1049 const util::URL& rURL,
1050 const uno::Sequence< beans::PropertyValue >& rArgs )
1051 throw (uno::RuntimeException, std::exception)
1053 //@todo avoid OString
1054 OString aCommand( OUStringToOString( rURL.Path, RTL_TEXTENCODING_ASCII_US ) );
1056 if(aCommand == "Paste")
1057 this->executeDispatch_Paste();
1058 else if(aCommand == "Copy" )
1059 this->executeDispatch_Copy();
1060 else if(aCommand == "Cut" )
1061 this->executeDispatch_Cut();
1062 else if(aCommand == "DataRanges" )
1063 this->executeDispatch_SourceData();
1064 else if(aCommand == "Update" ) //Update Chart
1066 ChartViewHelper::setViewToDirtyState( getModel() );
1067 SolarMutexGuard aGuard;
1068 if( m_pChartWindow )
1069 m_pChartWindow->Invalidate();
1071 else if(aCommand == "DiagramData" )
1072 this->executeDispatch_EditData();
1073 //insert objects
1074 else if( aCommand == "InsertTitles"
1075 || aCommand == "InsertMenuTitles")
1076 this->executeDispatch_InsertTitles();
1077 else if( aCommand == "InsertMenuLegend" )
1078 this->executeDispatch_OpenLegendDialog();
1079 else if( aCommand == "InsertLegend" )
1080 this->executeDispatch_InsertLegend();
1081 else if( aCommand == "DeleteLegend" )
1082 this->executeDispatch_DeleteLegend();
1083 else if( aCommand == "InsertMenuDataLabels" )
1084 this->executeDispatch_InsertMenu_DataLabels();
1085 else if( aCommand == "InsertMenuAxes"
1086 || aCommand == "InsertRemoveAxes" )
1087 this->executeDispatch_InsertAxes();
1088 else if( aCommand == "InsertMenuGrids" )
1089 this->executeDispatch_InsertGrid();
1090 else if( aCommand == "InsertMenuTrendlines" )
1091 this->executeDispatch_InsertMenu_Trendlines();
1092 else if( aCommand == "InsertMenuMeanValues" )
1093 this->executeDispatch_InsertMenu_MeanValues();
1094 else if( aCommand == "InsertMenuXErrorBars" )
1095 this->executeDispatch_InsertErrorBars(false);
1096 else if( aCommand == "InsertMenuYErrorBars" )
1097 this->executeDispatch_InsertErrorBars(true);
1098 else if( aCommand == "InsertSymbol" )
1099 this->executeDispatch_InsertSpecialCharacter();
1100 else if( aCommand == "InsertTrendline" )
1101 this->executeDispatch_InsertTrendline();
1102 else if( aCommand == "DeleteTrendline" )
1103 this->executeDispatch_DeleteTrendline();
1104 else if( aCommand == "InsertMeanValue" )
1105 this->executeDispatch_InsertMeanValue();
1106 else if( aCommand == "DeleteMeanValue" )
1107 this->executeDispatch_DeleteMeanValue();
1108 else if( aCommand == "InsertXErrorBars" )
1109 this->executeDispatch_InsertErrorBars(false);
1110 else if( aCommand == "InsertYErrorBars" )
1111 this->executeDispatch_InsertErrorBars(true);
1112 else if( aCommand == "DeleteXErrorBars" )
1113 this->executeDispatch_DeleteErrorBars(false);
1114 else if( aCommand == "DeleteYErrorBars" )
1115 this->executeDispatch_DeleteErrorBars(true);
1116 else if( aCommand == "InsertTrendlineEquation" )
1117 this->executeDispatch_InsertTrendlineEquation();
1118 else if( aCommand == "DeleteTrendlineEquation" )
1119 this->executeDispatch_DeleteTrendlineEquation();
1120 else if( aCommand == "InsertTrendlineEquationAndR2" )
1121 this->executeDispatch_InsertTrendlineEquation( true );
1122 else if( aCommand == "InsertR2Value" )
1123 this->executeDispatch_InsertR2Value();
1124 else if( aCommand == "DeleteR2Value")
1125 this->executeDispatch_DeleteR2Value();
1126 else if( aCommand == "InsertDataLabels" )
1127 this->executeDispatch_InsertDataLabels();
1128 else if( aCommand == "InsertDataLabel" )
1129 this->executeDispatch_InsertDataLabel();
1130 else if( aCommand == "DeleteDataLabels")
1131 this->executeDispatch_DeleteDataLabels();
1132 else if( aCommand == "DeleteDataLabel" )
1133 this->executeDispatch_DeleteDataLabel();
1134 else if( aCommand == "ResetAllDataPoints" )
1135 this->executeDispatch_ResetAllDataPoints();
1136 else if( aCommand == "ResetDataPoint" )
1137 this->executeDispatch_ResetDataPoint();
1138 else if( aCommand == "InsertAxis" )
1139 this->executeDispatch_InsertAxis();
1140 else if( aCommand == "InsertMajorGrid" )
1141 this->executeDispatch_InsertMajorGrid();
1142 else if( aCommand == "InsertMinorGrid" )
1143 this->executeDispatch_InsertMinorGrid();
1144 else if( aCommand == "InsertAxisTitle" )
1145 this->executeDispatch_InsertAxisTitle();
1146 else if( aCommand == "DeleteAxis" )
1147 this->executeDispatch_DeleteAxis();
1148 else if( aCommand == "DeleteMajorGrid")
1149 this->executeDispatch_DeleteMajorGrid();
1150 else if( aCommand == "DeleteMinorGrid" )
1151 this->executeDispatch_DeleteMinorGrid();
1152 //format objects
1153 else if( aCommand == "FormatSelection" )
1154 this->executeDispatch_ObjectProperties();
1155 else if( aCommand == "TransformDialog" )
1157 if ( isShapeContext() )
1159 this->impl_ShapeControllerDispatch( rURL, rArgs );
1161 else
1163 this->executeDispatch_PositionAndSize();
1166 else if( lcl_isFormatObjectCommand(aCommand) )
1167 this->executeDispatch_FormatObject(rURL.Path);
1168 //more format
1169 else if( aCommand == "DiagramType" )
1170 this->executeDispatch_ChartType();
1171 else if( aCommand == "View3D" )
1172 this->executeDispatch_View3D();
1173 else if ( aCommand == "Forward" )
1175 if ( isShapeContext() )
1177 this->impl_ShapeControllerDispatch( rURL, rArgs );
1179 else
1181 this->executeDispatch_MoveSeries( true );
1184 else if ( aCommand == "Backward" )
1186 if ( isShapeContext() )
1188 this->impl_ShapeControllerDispatch( rURL, rArgs );
1190 else
1192 this->executeDispatch_MoveSeries( false );
1195 else if( aCommand == "NewArrangement")
1196 this->executeDispatch_NewArrangement();
1197 else if( aCommand == "ToggleLegend" )
1198 this->executeDispatch_ToggleLegend();
1199 else if( aCommand == "ToggleGridHorizontal" )
1200 this->executeDispatch_ToggleGridHorizontal();
1201 else if( aCommand == "ToggleGridVertical" )
1202 this->executeDispatch_ToggleGridVertical();
1203 else if( aCommand == "ScaleText" )
1204 this->executeDispatch_ScaleText();
1205 else if( aCommand == "StatusBarVisible" )
1207 // workaround: this should not be necessary.
1208 uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY );
1209 if( xPropSet.is() )
1211 uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
1212 xPropSet->getPropertyValue( "LayoutManager" ) >>= xLayoutManager;
1213 if ( xLayoutManager.is() )
1215 bool bIsVisible( xLayoutManager->isElementVisible( "private:resource/statusbar/statusbar" ));
1216 if( bIsVisible )
1218 xLayoutManager->hideElement( "private:resource/statusbar/statusbar" );
1219 xLayoutManager->destroyElement( "private:resource/statusbar/statusbar" );
1221 else
1223 xLayoutManager->createElement( "private:resource/statusbar/statusbar" );
1224 xLayoutManager->showElement( "private:resource/statusbar/statusbar" );
1226 // @todo: update menu state (checkmark next to "Statusbar").
1232 void SAL_CALL ChartController::addStatusListener(
1233 const uno::Reference<frame::XStatusListener >& /* xControl */,
1234 const util::URL& /* aURL */ )
1235 throw (uno::RuntimeException, std::exception)
1237 //@todo
1240 void SAL_CALL ChartController::removeStatusListener(
1241 const uno::Reference<frame::XStatusListener >& /* xControl */,
1242 const util::URL& /* aURL */ )
1243 throw (uno::RuntimeException, std::exception)
1245 //@todo
1248 // XContextMenuInterception (optional interface)
1249 void SAL_CALL ChartController::registerContextMenuInterceptor(
1250 const uno::Reference< ui::XContextMenuInterceptor >& /* xInterceptor */)
1251 throw(uno::RuntimeException, std::exception)
1253 //@todo
1256 void SAL_CALL ChartController::releaseContextMenuInterceptor(
1257 const uno::Reference< ui::XContextMenuInterceptor > & /* xInterceptor */)
1258 throw(uno::RuntimeException, std::exception)
1260 //@todo
1263 // ____ XEmbeddedClient ____
1264 // implementation see: ChartController_EditData.cxx
1266 void ChartController::executeDispatch_ChartType()
1268 // using assignment for broken gcc 3.3
1269 UndoLiveUpdateGuard aUndoGuard = UndoLiveUpdateGuard(
1270 SCH_RESSTR( STR_ACTION_EDIT_CHARTTYPE ), m_xUndoManager );
1272 SolarMutexGuard aSolarGuard;
1273 //prepare and open dialog
1274 ScopedVclPtrInstance< ChartTypeDialog > aDlg( m_pChartWindow, getModel(), m_xCC );
1275 if( aDlg->Execute() == RET_OK )
1277 impl_adaptDataSeriesAutoResize();
1278 aUndoGuard.commit();
1282 void ChartController::executeDispatch_SourceData()
1284 //convert properties to ItemSet
1285 uno::Reference< XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
1286 OSL_ENSURE( xChartDoc.is(), "Invalid XChartDocument" );
1287 if( !xChartDoc.is())
1288 return;
1290 UndoLiveUpdateGuard aUndoGuard = UndoLiveUpdateGuard(
1291 SCH_RESSTR(STR_ACTION_EDIT_DATA_RANGES), m_xUndoManager );
1292 if( xChartDoc.is())
1294 SolarMutexGuard aSolarGuard;
1295 ScopedVclPtrInstance< ::chart::DataSourceDialog > aDlg( m_pChartWindow, xChartDoc, m_xCC );
1296 if( aDlg->Execute() == RET_OK )
1298 impl_adaptDataSeriesAutoResize();
1299 aUndoGuard.commit();
1304 void ChartController::executeDispatch_MoveSeries( bool bForward )
1306 ControllerLockGuardUNO aCLGuard( getModel() );
1308 //get selected series
1309 OUString aObjectCID(m_aSelection.getSelectedCID());
1310 uno::Reference< XDataSeries > xGivenDataSeries( ObjectIdentifier::getDataSeriesForCID( //yyy todo also legendentries and labels?
1311 aObjectCID, getModel() ) );
1313 UndoGuardWithSelection aUndoGuard(
1314 ActionDescriptionProvider::createDescription(
1315 (bForward ? ActionDescriptionProvider::MOVE_TOTOP : ActionDescriptionProvider::MOVE_TOBOTTOM),
1316 SCH_RESSTR(STR_OBJECT_DATASERIES)),
1317 m_xUndoManager );
1319 bool bChanged = DiagramHelper::moveSeries( ChartModelHelper::findDiagram( getModel() ), xGivenDataSeries, bForward );
1320 if( bChanged )
1322 m_aSelection.setSelection( ObjectIdentifier::getMovedSeriesCID( aObjectCID, bForward ) );
1323 aUndoGuard.commit();
1327 // ____ XMultiServiceFactory ____
1328 uno::Reference< uno::XInterface > SAL_CALL
1329 ChartController::createInstance( const OUString& aServiceSpecifier )
1330 throw (uno::Exception,
1331 uno::RuntimeException, std::exception)
1333 uno::Reference< uno::XInterface > xResult;
1335 if( aServiceSpecifier == CHART_ACCESSIBLE_TEXT_SERVICE_NAME )
1336 xResult.set( impl_createAccessibleTextContext());
1337 return xResult;
1340 uno::Reference< uno::XInterface > SAL_CALL
1341 ChartController::createInstanceWithArguments(
1342 const OUString& ServiceSpecifier,
1343 const uno::Sequence< uno::Any >& /* Arguments */ )
1344 throw (uno::Exception, uno::RuntimeException, std::exception)
1346 // ignore Arguments
1347 return createInstance( ServiceSpecifier );
1350 uno::Sequence< OUString > SAL_CALL
1351 ChartController::getAvailableServiceNames()
1352 throw (uno::RuntimeException, std::exception)
1354 uno::Sequence< OUString > aServiceNames(1);
1355 aServiceNames[0] = CHART_ACCESSIBLE_TEXT_SERVICE_NAME;
1356 return aServiceNames;
1359 // ____ XModifyListener ____
1360 void SAL_CALL ChartController::modified(
1361 const lang::EventObject& /* aEvent */ )
1362 throw (uno::RuntimeException, std::exception)
1364 // the source can also be a subobject of the ChartModel
1365 // @todo: change the source in ChartModel to always be the model itself ?
1366 //todo? update menu states ?
1369 IMPL_LINK( ChartController, NotifyUndoActionHdl, SdrUndoAction*, pUndoAction )
1371 ENSURE_OR_RETURN( pUndoAction, "invalid Undo action", 1L );
1373 OUString aObjectCID = m_aSelection.getSelectedCID();
1374 if ( aObjectCID.isEmpty() )
1378 const Reference< document::XUndoManagerSupplier > xSuppUndo( getModel(), uno::UNO_QUERY_THROW );
1379 const Reference< document::XUndoManager > xUndoManager( xSuppUndo->getUndoManager(), uno::UNO_QUERY_THROW );
1380 const Reference< document::XUndoAction > xAction( new impl::ShapeUndoElement( *pUndoAction ) );
1381 xUndoManager->addUndoAction( xAction );
1383 catch( const uno::Exception& )
1385 DBG_UNHANDLED_EXCEPTION();
1388 return 0L;
1391 DrawModelWrapper* ChartController::GetDrawModelWrapper()
1393 if( !m_pDrawModelWrapper.get() )
1395 ExplicitValueProvider* pProvider = ExplicitValueProvider::getExplicitValueProvider( m_xChartView );
1396 if( pProvider )
1397 m_pDrawModelWrapper = pProvider->getDrawModelWrapper();
1398 if ( m_pDrawModelWrapper.get() )
1400 m_pDrawModelWrapper->getSdrModel().SetNotifyUndoActionHdl( LINK( this, ChartController, NotifyUndoActionHdl ) );
1403 return m_pDrawModelWrapper.get();
1406 DrawViewWrapper* ChartController::GetDrawViewWrapper()
1408 if ( !m_pDrawViewWrapper )
1410 impl_createDrawViewController();
1412 return m_pDrawViewWrapper;
1415 uno::Reference< XAccessible > ChartController::CreateAccessible()
1417 uno::Reference< XAccessible > xResult = new AccessibleChartView( m_xCC, GetDrawViewWrapper() );
1418 impl_initializeAccessible( uno::Reference< lang::XInitialization >( xResult, uno::UNO_QUERY ) );
1419 return xResult;
1422 void ChartController::impl_invalidateAccessible()
1424 SolarMutexGuard aGuard;
1425 if( m_pChartWindow )
1427 Reference< lang::XInitialization > xInit( m_pChartWindow->GetAccessible(false), uno::UNO_QUERY );
1428 if(xInit.is())
1430 uno::Sequence< uno::Any > aArguments(3);//empty arguments -> invalid accessible
1431 xInit->initialize(aArguments);
1435 void ChartController::impl_initializeAccessible()
1437 SolarMutexGuard aGuard;
1438 if( m_pChartWindow )
1439 this->impl_initializeAccessible( Reference< lang::XInitialization >( m_pChartWindow->GetAccessible(false), uno::UNO_QUERY ) );
1441 void ChartController::impl_initializeAccessible( const uno::Reference< lang::XInitialization >& xInit )
1443 if(xInit.is())
1445 uno::Sequence< uno::Any > aArguments(5);
1446 uno::Reference<view::XSelectionSupplier> xSelectionSupplier(this);
1447 aArguments[0]=uno::makeAny(xSelectionSupplier);
1448 uno::Reference<frame::XModel> xModel(getModel());
1449 aArguments[1]=uno::makeAny(xModel);
1450 aArguments[2]=uno::makeAny(m_xChartView);
1451 uno::Reference< XAccessible > xParent;
1453 SolarMutexGuard aGuard;
1454 if( m_pChartWindow )
1456 vcl::Window* pParentWin( m_pChartWindow->GetAccessibleParentWindow());
1457 if( pParentWin )
1458 xParent.set( pParentWin->GetAccessible());
1461 aArguments[3]=uno::makeAny(xParent);
1462 aArguments[4]=uno::makeAny(m_xViewWindow);
1464 xInit->initialize(aArguments);
1468 ::std::set< OUString > ChartController::impl_getAvailableCommands()
1470 return ::comphelper::MakeSet< OUString >
1471 // commands for container forward
1472 ( "AddDirect" ) ( "NewDoc" ) ( "Open" )
1473 ( "Save" ) ( "SaveAs" ) ( "SendMail" )
1474 ( "EditDoc" ) ( "ExportDirectToPDF" ) ( "PrintDefault" )
1476 // own commands
1477 ( "Cut" ) ( "Copy" ) ( "Paste" )
1478 ( "DataRanges" ) ( "DiagramData" )
1479 // insert objects
1480 ( "InsertMenuTitles" ) ( "InsertTitles" )
1481 ( "InsertMenuLegend" ) ( "InsertLegend" ) ( "DeleteLegend" )
1482 ( "InsertMenuDataLabels" )
1483 ( "InsertMenuAxes" ) ( "InsertRemoveAxes" ) ( "InsertMenuGrids" )
1484 ( "InsertSymbol" )
1485 ( "InsertTrendlineEquation" ) ( "InsertTrendlineEquationAndR2" )
1486 ( "InsertR2Value" ) ( "DeleteR2Value" )
1487 ( "InsertMenuTrendlines" ) ( "InsertTrendline" )
1488 ( "InsertMenuMeanValues" ) ( "InsertMeanValue" )
1489 ( "InsertMenuXErrorBars" ) ( "InsertXErrorBars" )
1490 ( "InsertMenuYErrorBars" ) ( "InsertYErrorBars" )
1491 ( "InsertDataLabels" ) ( "InsertDataLabel" )
1492 ( "DeleteTrendline" ) ( "DeleteMeanValue" ) ( "DeleteTrendlineEquation" )
1493 ( "DeleteXErrorBars" ) ( "DeleteYErrorBars" )
1494 ( "DeleteDataLabels" ) ( "DeleteDataLabel" )
1495 //format objects
1496 ( "FormatSelection" ) ( "TransformDialog" )
1497 ( "DiagramType" ) ( "View3D" )
1498 ( "Forward" ) ( "Backward" )
1499 ( "MainTitle" ) ( "SubTitle" )
1500 ( "XTitle" ) ( "YTitle" ) ( "ZTitle" )
1501 ( "SecondaryXTitle" ) ( "SecondaryYTitle" )
1502 ( "AllTitles" ) ( "Legend" )
1503 ( "DiagramAxisX" ) ( "DiagramAxisY" ) ( "DiagramAxisZ" )
1504 ( "DiagramAxisA" ) ( "DiagramAxisB" ) ( "DiagramAxisAll" )
1505 ( "DiagramGridXMain" ) ( "DiagramGridYMain" ) ( "DiagramGridZMain" )
1506 ( "DiagramGridXHelp" ) ( "DiagramGridYHelp" ) ( "DiagramGridZHelp" )
1507 ( "DiagramGridAll" )
1508 ( "DiagramWall" ) ( "DiagramFloor" ) ( "DiagramArea" )
1510 //context menu - format objects entries
1511 ( "FormatWall" ) ( "FormatFloor" ) ( "FormatChartArea" )
1512 ( "FormatLegend" )
1514 ( "FormatAxis" ) ( "FormatTitle" )
1515 ( "FormatDataSeries" ) ( "FormatDataPoint" )
1516 ( "ResetAllDataPoints" ) ( "ResetDataPoint" )
1517 ( "FormatDataLabels" ) ( "FormatDataLabel" )
1518 ( "FormatMeanValue" ) ( "FormatTrendline" ) ( "FormatTrendlineEquation" )
1519 ( "FormatXErrorBars" ) ( "FormatYErrorBars" )
1520 ( "FormatStockLoss" ) ( "FormatStockGain" )
1522 ( "FormatMajorGrid" ) ( "InsertMajorGrid" ) ( "DeleteMajorGrid" )
1523 ( "FormatMinorGrid" ) ( "InsertMinorGrid" ) ( "DeleteMinorGrid" )
1524 ( "InsertAxis" ) ( "DeleteAxis" ) ( "InsertAxisTitle" )
1526 // toolbar commands
1527 ( "ToggleGridHorizontal" ) ( "ToggleGridVertical" ) ( "ToggleLegend" ) ( "ScaleText" )
1528 ( "NewArrangement" ) ( "Update" )
1529 ( "DefaultColors" ) ( "BarWidth" ) ( "NumberOfLines" )
1530 ( "ArrangeRow" )
1531 ( "StatusBarVisible" )
1532 ( "ChartElementSelector" )
1536 } //namespace chart
1538 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1539 com_sun_star_comp_chart2_ChartController_get_implementation(css::uno::XComponentContext *context,
1540 css::uno::Sequence<css::uno::Any> const &)
1542 return cppu::acquire(new chart::ChartController(context));
1545 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */