summaryrefslogtreecommitdiff
path: root/chart2/source/controller/main/ChartController.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'chart2/source/controller/main/ChartController.cxx')
-rw-r--r--chart2/source/controller/main/ChartController.cxx1603
1 files changed, 1603 insertions, 0 deletions
diff --git a/chart2/source/controller/main/ChartController.cxx b/chart2/source/controller/main/ChartController.cxx
new file mode 100644
index 000000000000..bf8afc65e78f
--- /dev/null
+++ b/chart2/source/controller/main/ChartController.cxx
@@ -0,0 +1,1603 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "ChartController.hxx"
+#include "servicenames.hxx"
+#include "ResId.hxx"
+#include "dlg_DataSource.hxx"
+#include "ChartModelHelper.hxx"
+#include "ControllerCommandDispatch.hxx"
+#include "Strings.hrc"
+#include "chartview/ExplicitValueProvider.hxx"
+#include "ChartViewHelper.hxx"
+
+#include "ChartWindow.hxx"
+#include "chartview/DrawModelWrapper.hxx"
+#include "DrawViewWrapper.hxx"
+#include "ObjectIdentifier.hxx"
+#include "DiagramHelper.hxx"
+#include "ControllerLockGuard.hxx"
+#include "UndoGuard.hxx"
+#include "ChartDropTargetHelper.hxx"
+
+#include "macros.hxx"
+#include "dlg_CreationWizard.hxx"
+#include "dlg_ChartType.hxx"
+//#include "svx/ActionDescriptionProvider.hxx"
+#include "AccessibleChartView.hxx"
+#include "DrawCommandDispatch.hxx"
+#include "ShapeController.hxx"
+#include "UndoManager.hxx"
+
+#include <comphelper/InlineContainer.hxx>
+
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/XUndoSupplier.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+#include <com/sun/star/frame/XLoadable.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+#include <com/sun/star/embed/XEmbeddedClient.hpp>
+#include <com/sun/star/util/XModeChangeBroadcaster.hpp>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+#include <com/sun/star/frame/LayoutManagerEvents.hpp>
+
+//-------
+// header for define RET_OK
+#include <vcl/msgbox.hxx>
+//-------
+
+//-------
+#include <toolkit/awt/vclxwindow.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/svapp.hxx>
+#include <vos/mutex.hxx>
+//-------
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+
+// this is needed to properly destroy the auto_ptr to the AcceleratorExecute
+// object in the DTOR
+#include <svtools/acceleratorexecute.hxx>
+#include <svx/ActionDescriptionProvider.hxx>
+
+// enable the following define to let the controller listen to model changes and
+// react on this by rebuilding the view
+#define TEST_ENABLE_MODIFY_LISTENER
+
+/*
+#include <vcl/svapp.hxx>
+*/
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::chart2;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+DBG_NAME(ChartController)
+//-----------------------------------------------------------------
+// ChartController Constructor and Destructor
+//-----------------------------------------------------------------
+
+ChartController::ChartController(uno::Reference<uno::XComponentContext> const & xContext)
+ : m_aLifeTimeManager( NULL )
+ , m_bSuspended( sal_False )
+ , m_bCanClose( sal_True )
+ , m_xCC(xContext) //@todo is it allowed to hold this context??
+ , m_xFrame( NULL )
+ , m_aModelMutex()
+ , m_aModel( NULL, m_aModelMutex )
+ , m_pChartWindow( NULL )
+ , m_xViewWindow()
+ , m_xChartView()
+ , m_pDrawModelWrapper()
+ , m_pDrawViewWrapper(NULL)
+ , m_eDragMode(SDRDRAG_MOVE)
+ , m_bWaitingForDoubleClick(false)
+ , m_bWaitingForMouseUp(false)
+ , m_bConnectingToView(false)
+ , m_xUndoManager( 0 )
+ , m_aDispatchContainer( m_xCC, this )
+ , m_eDrawMode( CHARTDRAW_SELECT )
+{
+ DBG_CTOR(ChartController,NULL);
+// m_aDispatchContainer.setUndoManager( m_xUndoManager );
+ m_aDoubleClickTimer.SetTimeoutHdl( LINK( this, ChartController, DoubleClickWaitingHdl ) );
+}
+
+ChartController::~ChartController()
+{
+ DBG_DTOR(ChartController,NULL);
+ stopDoubleClickWaiting();
+}
+
+//-----------------------------------------------------------------
+
+ChartController::RefCountable::RefCountable() : m_nRefCount(0)
+{
+}
+
+ChartController::RefCountable::~RefCountable()
+{
+}
+void ChartController::RefCountable::acquire()
+{
+ m_nRefCount++;
+}
+void ChartController::RefCountable::release()
+{
+ m_nRefCount--;
+ if(!m_nRefCount)
+ delete this;
+}
+
+//-----------------------------------------------------------------
+
+ChartController::TheModel::TheModel( const uno::Reference< frame::XModel > & xModel )
+ : m_xModel( xModel )
+ , m_xCloseable( NULL )
+ , m_bOwnership( sal_True )
+ , m_bOwnershipIsWellKnown( sal_False )
+{
+ m_xCloseable =
+ uno::Reference< util::XCloseable >( xModel, uno::UNO_QUERY );
+}
+
+ChartController::TheModel::~TheModel()
+{
+}
+
+void ChartController::TheModel::SetOwnerShip( sal_Bool bGetsOwnership )
+{
+ m_bOwnership = bGetsOwnership;
+ m_bOwnershipIsWellKnown = sal_True;
+}
+
+void ChartController::TheModel::addListener( ChartController* pController )
+{
+ if(m_xCloseable.is())
+ {
+ //if you need to be able to veto against the destruction of the model
+ // you must add as a close listener
+
+ //otherwise you 'can' add as closelistener or 'must' add as dispose event listener
+
+ m_xCloseable->addCloseListener(
+ static_cast<util::XCloseListener*>(pController) );
+ }
+ else if( m_xModel.is() )
+ {
+ //we need to add as dispose event listener
+ m_xModel->addEventListener(
+ static_cast<util::XCloseListener*>(pController) );
+ }
+
+}
+
+void ChartController::TheModel::removeListener( ChartController* pController )
+{
+ if(m_xCloseable.is())
+ m_xCloseable->removeCloseListener(
+ static_cast<util::XCloseListener*>(pController) );
+
+ else if( m_xModel.is() )
+ m_xModel->removeEventListener(
+ static_cast<util::XCloseListener*>(pController) );
+}
+
+void ChartController::TheModel::tryTermination()
+{
+ if(!m_bOwnership)
+ return;
+
+ try
+ {
+ if(m_xCloseable.is())
+ {
+ try
+ {
+ //@todo ? are we allowed to use sal_True here if we have the explicit ownership?
+ //I think yes, because there might be other closelistners later in the list which might be interested still
+ //but make sure that we do not throw the CloseVetoException here ourselfs
+ //so stop listening before trying to terminate or check the source of queryclosing event
+ m_xCloseable->close(sal_True);
+
+ m_bOwnership = false;
+ m_bOwnershipIsWellKnown = sal_True;
+ }
+ catch( util::CloseVetoException& )
+ {
+ //since we have indicated to give up the ownership with paramter true in close call
+ //the one who has thrown the CloseVetoException is the new owner
+
+#if OSL_DEBUG_LEVEL > 2
+ OSL_ENSURE( !m_bOwnership,
+ "INFO: a well known owner has catched a CloseVetoException after calling close(true)" );
+#endif
+
+ m_bOwnership = false;
+ m_bOwnershipIsWellKnown = sal_True;
+ return;
+ }
+
+ }
+ else if( m_xModel.is() )
+ {
+ //@todo correct??
+ m_xModel->dispose();
+ return;
+ }
+ }
+ catch( uno::Exception& ex)
+ {
+ (void)(ex); // no warning in non-debug builds
+ OSL_ENSURE( sal_False, ( rtl::OString("Termination of model failed: ")
+ + rtl::OUStringToOString( ex.Message, RTL_TEXTENCODING_ASCII_US ) ).getStr() );
+ }
+}
+
+//-----------------------------------------------------------------
+
+ChartController::TheModelRef::TheModelRef( TheModel* pTheModel, ::osl::Mutex& rMutex )
+ : m_pTheModel(pTheModel), m_rModelMutex(rMutex)
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( m_rModelMutex );
+ if(m_pTheModel)
+ m_pTheModel->acquire();
+}
+ChartController::TheModelRef::TheModelRef( const TheModelRef& rTheModel, ::osl::Mutex& rMutex )
+ : m_rModelMutex(rMutex)
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( m_rModelMutex );
+ m_pTheModel=rTheModel.operator->();
+ if(m_pTheModel)
+ m_pTheModel->acquire();
+}
+ChartController::TheModelRef& ChartController::TheModelRef::operator=(TheModel* pTheModel)
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( m_rModelMutex );
+ if(m_pTheModel==pTheModel)
+ return *this;
+ if(m_pTheModel)
+ m_pTheModel->release();
+ m_pTheModel=pTheModel;
+ if(m_pTheModel)
+ m_pTheModel->acquire();
+ return *this;
+}
+ChartController::TheModelRef& ChartController::TheModelRef::operator=(const TheModelRef& rTheModel)
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( m_rModelMutex );
+ TheModel* pNew=rTheModel.operator->();
+ if(m_pTheModel==pNew)
+ return *this;
+ if(m_pTheModel)
+ m_pTheModel->release();
+ m_pTheModel=pNew;
+ if(m_pTheModel)
+ m_pTheModel->acquire();
+ return *this;
+}
+ChartController::TheModelRef::~TheModelRef()
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( m_rModelMutex );
+ if(m_pTheModel)
+ m_pTheModel->release();
+}
+sal_Bool ChartController::TheModelRef::is() const
+{
+ return (m_pTheModel != 0);
+}
+
+
+//-----------------------------------------------------------------
+// private methods
+//-----------------------------------------------------------------
+
+ sal_Bool ChartController
+::impl_isDisposedOrSuspended() const
+{
+ if( m_aLifeTimeManager.impl_isDisposed() )
+ return sal_True;
+
+ if( m_bSuspended )
+ {
+ OSL_ENSURE( sal_False, "This Controller is suspended" );
+ return sal_True;
+ }
+ return sal_False;
+}
+
+//-----------------------------------------------------------------
+// lang::XServiceInfo
+//-----------------------------------------------------------------
+
+APPHELPER_XSERVICEINFO_IMPL(ChartController,CHART_CONTROLLER_SERVICE_IMPLEMENTATION_NAME)
+
+ uno::Sequence< rtl::OUString > ChartController
+::getSupportedServiceNames_Static()
+{
+ uno::Sequence< rtl::OUString > aSNS( 2 );
+ aSNS.getArray()[ 0 ] = CHART_CONTROLLER_SERVICE_NAME;
+ aSNS.getArray()[ 1 ] = ::rtl::OUString::createFromAscii("com.sun.star.frame.Controller");
+ //// @todo : add additional services if you support any further
+ return aSNS;
+}
+
+//-----------------------------------------------------------------
+// XController
+//-----------------------------------------------------------------
+
+ void SAL_CALL ChartController
+::attachFrame( const uno::Reference<frame::XFrame>& xFrame )
+ throw(uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex());
+
+ if( impl_isDisposedOrSuspended() ) //@todo? allow attaching the frame while suspended?
+ return; //behave passive if already disposed or suspended
+
+ if(m_xFrame.is()) //what happens, if we do have a Frame already??
+ {
+ //@todo? throw exception?
+ OSL_ENSURE( sal_False, "there is already a frame attached to the controller" );
+ return;
+ }
+
+ //--attach frame
+ m_xFrame = xFrame; //the frameloader is responsible to call xFrame->setComponent
+
+ //add as disposelistener to the frame (due to persistent reference) ??...:
+
+ //the frame is considered to be owner of this controller and will live longer than we do
+ //the frame or the disposer of the frame has the duty to call suspend and dispose on this object
+ //so we do not need to add as lang::XEventListener for DisposingEvents right?
+
+ //@todo nothing right???
+
+
+
+ //--------------------------------------------------
+ //create view @todo is this the correct place here??
+
+ Window* pParent = NULL;
+ //get the window parent from the frame to use as parent for our new window
+ if(xFrame.is())
+ {
+ uno::Reference< awt::XWindow > xContainerWindow = xFrame->getContainerWindow();
+ VCLXWindow* pParentComponent = VCLXWindow::GetImplementation(xContainerWindow);
+ pParentComponent->setVisible(sal_True);
+
+ pParent = VCLUnoHelper::GetWindow( xContainerWindow );
+ }
+
+ if(m_pChartWindow)
+ {
+ //@todo delete ...
+ m_pChartWindow->clear();
+ m_apDropTargetHelper.reset();
+ }
+ {
+ awt::Size aPageSize( ChartModelHelper::getPageSize(getModel()) );
+
+ // calls to VCL
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
+ m_pChartWindow = new ChartWindow(this,pParent,pParent?pParent->GetStyle():0);
+ m_pChartWindow->SetBackground();//no Background
+ m_xViewWindow = uno::Reference< awt::XWindow >( m_pChartWindow->GetComponentInterface(), uno::UNO_QUERY );
+ m_pChartWindow->Show();
+ m_apDropTargetHelper.reset(
+ new ChartDropTargetHelper( m_pChartWindow->GetDropTarget(),
+ uno::Reference< chart2::XChartDocument >( getModel(), uno::UNO_QUERY )));
+
+ impl_createDrawViewController();
+ }
+
+ //create the menu
+ {
+ uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY );
+ if( xPropSet.is() )
+ {
+ try
+ {
+ uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
+ xPropSet->getPropertyValue( C2U( "LayoutManager" ) ) >>= xLayoutManager;
+ if ( xLayoutManager.is() )
+ {
+ xLayoutManager->lock();
+ xLayoutManager->requestElement( C2U( "private:resource/menubar/menubar" ) );
+ //@todo: createElement should become unnecessary, remove when #i79198# is fixed
+ xLayoutManager->createElement( C2U( "private:resource/toolbar/standardbar" ) );
+ xLayoutManager->requestElement( C2U( "private:resource/toolbar/standardbar" ) );
+ //@todo: createElement should become unnecessary, remove when #i79198# is fixed
+ xLayoutManager->createElement( C2U( "private:resource/toolbar/toolbar" ) );
+ xLayoutManager->requestElement( C2U( "private:resource/toolbar/toolbar" ) );
+
+ // #i12587# support for shapes in chart
+ xLayoutManager->createElement( C2U( "private:resource/toolbar/drawbar" ) );
+ xLayoutManager->requestElement( C2U( "private:resource/toolbar/drawbar" ) );
+
+ xLayoutManager->requestElement( C2U( "private:resource/statusbar/statusbar" ) );
+ xLayoutManager->unlock();
+
+ // add as listener to get notified when
+ m_xLayoutManagerEventBroadcaster.set( xLayoutManager, uno::UNO_QUERY );
+ if( m_xLayoutManagerEventBroadcaster.is())
+ m_xLayoutManagerEventBroadcaster->addLayoutManagerEventListener( this );
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+ }
+}
+
+//XModeChangeListener
+void SAL_CALL ChartController::modeChanged( const util::ModeChangeEvent& rEvent )
+ throw ( uno::RuntimeException )
+{
+ //adjust controller to view status changes
+
+ if( rEvent.NewMode.equals(C2U("dirty")) )
+ {
+ //the view has become dirty, we should repaint it if we have a window
+ if( m_pChartWindow )
+ m_pChartWindow->ForceInvalidate();
+ }
+ else if( rEvent.NewMode.equals(C2U("invalid")) )
+ {
+ //the view is about to become invalid so end all actions on it
+ impl_invalidateAccessible();
+ ::vos::OGuard aGuard( Application::GetSolarMutex());
+ if( m_pDrawViewWrapper && m_pDrawViewWrapper->IsTextEdit() )
+ this->EndTextEdit();
+ if( m_pDrawViewWrapper )
+ {
+ m_pDrawViewWrapper->UnmarkAll();
+ //m_pDrawViewWrapper->hideMarkHandles(); todo??
+ m_pDrawViewWrapper->HideSdrPage();
+ }
+ }
+ else
+ {
+ //the view was rebuild so we can start some actions on it again
+ if( !m_bConnectingToView )
+ {
+ if(m_pChartWindow && m_aModel.is() )
+ {
+ m_bConnectingToView = true;
+
+ GetDrawModelWrapper();
+ if(m_pDrawModelWrapper)
+ {
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex());
+ if( m_pDrawViewWrapper )
+ m_pDrawViewWrapper->ReInit();
+ }
+
+ //reselect object
+ if( m_aSelection.hasSelection() )
+ this->impl_selectObjectAndNotiy();
+ else
+ ChartModelHelper::triggerRangeHighlighting( getModel() );
+
+ impl_initializeAccessible();
+
+ if( m_pChartWindow )
+ m_pChartWindow->Invalidate();
+ }
+
+ m_bConnectingToView = false;
+ }
+ }
+ }
+}
+
+ sal_Bool SAL_CALL ChartController
+::attachModel( const uno::Reference< frame::XModel > & xModel )
+ throw(uno::RuntimeException)
+{
+ impl_invalidateAccessible();
+
+ //is called to attach the controller to a new model.
+ //return true if attach was successfully, false otherwise (e.g. if you do not work with a model)
+
+ ::vos::OClearableGuard aGuard( Application::GetSolarMutex());
+ if( impl_isDisposedOrSuspended() ) //@todo? allow attaching a new model while suspended?
+ return sal_False; //behave passive if already disposed or suspended
+ aGuard.clear();
+
+
+ TheModelRef aNewModelRef( new TheModel( xModel), m_aModelMutex);
+ TheModelRef aOldModelRef(m_aModel,m_aModelMutex);
+ m_aModel = aNewModelRef;
+
+ //--handle relations to the old model if any
+ if( aOldModelRef.is() )
+ {
+ uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY );
+ if( xViewBroadcaster.is() )
+ xViewBroadcaster->removeModeChangeListener(this);
+ m_pDrawModelWrapper.reset();
+
+ aOldModelRef->removeListener( this );
+ //@todo?? termination correct?
+// aOldModelRef->tryTermination();
+#ifdef TEST_ENABLE_MODIFY_LISTENER
+ uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aOldModelRef->getModel(),uno::UNO_QUERY );
+ if( xMBroadcaster.is())
+ xMBroadcaster->removeModifyListener( this );
+#endif
+ }
+
+ //--handle relations to the new model
+ aNewModelRef->addListener( this );
+
+ // set new model at dispatchers
+ m_aDispatchContainer.setModel( aNewModelRef->getModel());
+ ControllerCommandDispatch * pDispatch = new ControllerCommandDispatch( m_xCC, this, &m_aDispatchContainer );
+ pDispatch->initialize();
+
+ // the dispatch container will return "this" for all commands returned by
+ // impl_getAvailableCommands(). That means, for those commands dispatch()
+ // is called here at the ChartController.
+ m_aDispatchContainer.setChartDispatch( pDispatch, impl_getAvailableCommands() );
+
+ DrawCommandDispatch* pDrawDispatch = new DrawCommandDispatch( m_xCC, this );
+ if ( pDrawDispatch )
+ {
+ pDrawDispatch->initialize();
+ m_aDispatchContainer.setDrawCommandDispatch( pDrawDispatch );
+ }
+
+ ShapeController* pShapeController = new ShapeController( m_xCC, this );
+ if ( pShapeController )
+ {
+ pShapeController->initialize();
+ m_aDispatchContainer.setShapeController( pShapeController );
+ }
+
+#ifdef TEST_ENABLE_MODIFY_LISTENER
+ uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aNewModelRef->getModel(),uno::UNO_QUERY );
+ if( xMBroadcaster.is())
+ xMBroadcaster->addModifyListener( this );
+#endif
+
+ //select chart area per default:
+ select( uno::makeAny( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, rtl::OUString() ) ) );
+
+ uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY );
+ if( xFact.is())
+ {
+ m_xChartView = xFact->createInstance( CHART_VIEW_SERVICE_NAME );
+ GetDrawModelWrapper();
+ uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY );
+ if( xViewBroadcaster.is() )
+ xViewBroadcaster->addModeChangeListener(this);
+ }
+
+ //the frameloader is responsible to call xModel->connectController
+ if( m_pChartWindow )
+ m_pChartWindow->Invalidate();
+
+ uno::Reference< chart2::XUndoSupplier > xUndoSupplier( getModel(), uno::UNO_QUERY );
+ if( xUndoSupplier.is())
+ m_xUndoManager.set( xUndoSupplier->getUndoManager());
+
+ return sal_True;
+}
+
+ uno::Reference< frame::XFrame > SAL_CALL ChartController
+::getFrame() throw(uno::RuntimeException)
+{
+ //provides access to owner frame of this controller
+ //return the frame containing this controller
+
+ return m_xFrame;
+}
+
+ uno::Reference< frame::XModel > SAL_CALL ChartController
+::getModel() throw(uno::RuntimeException)
+{
+ //provides access to currently attached model
+ //returns the currently attached model
+
+ //return nothing, if you do not have a model
+ TheModelRef aModelRef( m_aModel, m_aModelMutex);
+ if(aModelRef.is())
+ return aModelRef->getModel();
+
+ return uno::Reference< frame::XModel > ();
+}
+
+ uno::Any SAL_CALL ChartController
+::getViewData() throw(uno::RuntimeException)
+{
+ //provides access to current view status
+ //set of data that can be used to restore the current view status at later time
+ // by using XController::restoreViewData()
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex());
+ if( impl_isDisposedOrSuspended() )
+ return uno::Any(); //behave passive if already disposed or suspended //@todo? or throw an exception??
+
+ //-- collect current view state
+ uno::Any aRet;
+ //// @todo integrate specialized implementation
+
+ return aRet;
+}
+
+ void SAL_CALL ChartController
+::restoreViewData( const uno::Any& /* Value */ )
+ throw(uno::RuntimeException)
+{
+ //restores the view status using the data gotten from a previous call to XController::getViewData()
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex());
+ if( impl_isDisposedOrSuspended() )
+ return; //behave passive if already disposed or suspended //@todo? or throw an exception??
+
+ //// @todo integrate specialized implementation
+}
+
+ sal_Bool SAL_CALL ChartController
+::suspend( sal_Bool bSuspend )
+ throw(uno::RuntimeException)
+{
+ //is called to prepare the controller for closing the view
+ //bSuspend==true: force the controller to suspend his work
+ //bSuspend==false try to reactivate the controller
+ //returns true if request was accepted and of course successfully finished, false otherwise
+
+ //we may show dialogs here to ask the user for saving changes ... @todo?
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex());
+ if( m_aLifeTimeManager.impl_isDisposed() )
+ return sal_False; //behave passive if already disposed, return false because request was not accepted //@todo? correct
+
+ if(bSuspend==m_bSuspended)
+ {
+ OSL_ENSURE( sal_False, "new suspend mode equals old suspend mode" );
+ return sal_True;
+ }
+
+ //change suspend mode
+ if(bSuspend)
+ {
+ //aGuard.clear();
+ //@todo ??? try to stop all what may prevent me from becoming disposed
+ //aGuard.reset();
+
+ m_bSuspended = bSuspend;
+ return sal_True;
+ }
+ else
+ {
+ //aGuard.clear();
+ //@todo ??? redo what was made in section bSuspend==true
+ //aGuard.reset();
+
+ m_bSuspended = bSuspend;
+ }
+ return sal_True;
+
+
+ /*
+ if ( bSuspend )
+ getFrame()->removeFrameActionListener( pImp );
+ else
+ getFrame()->addFrameActionListener( pImp );
+ */
+}
+
+
+void ChartController::impl_createDrawViewController()
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex());
+ if(!m_pDrawViewWrapper)
+ {
+ if( m_pDrawModelWrapper )
+ {
+ m_pDrawViewWrapper = new DrawViewWrapper(&m_pDrawModelWrapper->getSdrModel(),m_pChartWindow,true);
+ m_pDrawViewWrapper->attachParentReferenceDevice( getModel() );
+ }
+ }
+}
+void ChartController::impl_deleteDrawViewController()
+{
+ if( m_pDrawViewWrapper )
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex());
+ if( m_pDrawViewWrapper->IsTextEdit() )
+ this->EndTextEdit();
+ DELETEZ( m_pDrawViewWrapper );
+ }
+}
+
+//-----------------------------------------------------------------
+// XComponent (base of XController)
+//-----------------------------------------------------------------
+
+ void SAL_CALL ChartController
+::dispose() throw(uno::RuntimeException)
+{
+ try
+ {
+ //This object should release all resources and references in the
+ //easiest possible manner
+ //This object must notify all registered listeners using the method
+ //<member>XEventListener::disposing</member>
+
+ //hold no mutex
+ if( !m_aLifeTimeManager.dispose() )
+ return;
+
+// OSL_ENSURE( m_bSuspended, "dispose was called but controller is not suspended" );
+
+ this->stopDoubleClickWaiting();
+
+ //end range highlighting
+ if( m_aModel.is())
+ {
+ uno::Reference< view::XSelectionChangeListener > xSelectionChangeListener;
+ uno::Reference< chart2::data::XDataReceiver > xDataReceiver( getModel(), uno::UNO_QUERY );
+ if( xDataReceiver.is() )
+ xSelectionChangeListener = uno::Reference< view::XSelectionChangeListener >( xDataReceiver->getRangeHighlighter(), uno::UNO_QUERY );
+ if( xSelectionChangeListener.is() )
+ {
+ uno::Reference< frame::XController > xController( this );
+ uno::Reference< lang::XComponent > xComp( xController, uno::UNO_QUERY );
+ //lang::EventObject aEvent( static_cast< lang::XComponent* >( this ) );
+ lang::EventObject aEvent( xComp );
+ xSelectionChangeListener->disposing( aEvent );
+ }
+ }
+
+ //--release all resources and references
+ {
+ uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY );
+ if( xViewBroadcaster.is() )
+ xViewBroadcaster->removeModeChangeListener(this);
+ // /--
+ impl_invalidateAccessible();
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
+ impl_deleteDrawViewController();
+ m_pDrawModelWrapper.reset();
+
+ m_apDropTargetHelper.reset();
+
+ //the accessible view is disposed within window destructor of m_pChartWindow
+ m_pChartWindow->clear();
+ m_pChartWindow = NULL;//m_pChartWindow is deleted via UNO due to dispose of m_xViewWindow (trigerred by Framework (Controller pretends to be XWindow also))
+ m_xViewWindow->dispose();
+ m_xChartView.clear();
+ // \--
+ }
+
+ // remove as listener to layout manager events
+ if( m_xLayoutManagerEventBroadcaster.is())
+ {
+ m_xLayoutManagerEventBroadcaster->removeLayoutManagerEventListener( this );
+ m_xLayoutManagerEventBroadcaster.set( 0 );
+ }
+
+ m_xFrame.clear();
+ m_xUndoManager.clear();
+
+ TheModelRef aModelRef( m_aModel, m_aModelMutex);
+ m_aModel = NULL;
+
+ if( aModelRef.is())
+ {
+ uno::Reference< frame::XModel > xModel( aModelRef->getModel() );
+ if(xModel.is())
+ xModel->disconnectController( uno::Reference< frame::XController >( this ));
+
+ aModelRef->removeListener( this );
+#ifdef TEST_ENABLE_MODIFY_LISTENER
+ try
+ {
+ uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aModelRef->getModel(),uno::UNO_QUERY );
+ if( xMBroadcaster.is())
+ xMBroadcaster->removeModifyListener( this );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+#endif
+ aModelRef->tryTermination();
+ }
+
+ //// @todo integrate specialized implementation
+ //e.g. release further resources and references
+
+ m_aDispatchContainer.DisposeAndClear();
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+
+ void SAL_CALL ChartController
+::addEventListener( const uno::Reference<lang::XEventListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex());
+ if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode?
+ return; //behave passive if already disposed or suspended
+
+ //--add listener
+ m_aLifeTimeManager.m_aListenerContainer.addInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0), xListener );
+}
+
+ void SAL_CALL ChartController
+::removeEventListener( const uno::Reference<
+ lang::XEventListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex());
+ if( m_aLifeTimeManager.impl_isDisposed(false) )
+ return; //behave passive if already disposed or suspended
+
+ //--remove listener
+ m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0), xListener );
+}
+
+
+//-----------------------------------------------------------------
+// util::XCloseListener
+//-----------------------------------------------------------------
+ void SAL_CALL ChartController
+::queryClosing( const lang::EventObject& rSource, sal_Bool bGetsOwnership )
+ throw(util::CloseVetoException, uno::RuntimeException)
+{
+ //do not use the m_aControllerMutex here because this call is not allowed to block
+
+ TheModelRef aModelRef( m_aModel, m_aModelMutex);
+
+ if( !aModelRef.is() )
+ return;
+
+ if( !(aModelRef->getModel() == rSource.Source) )
+ {
+ OSL_ENSURE( sal_False, "queryClosing was called on a controller from an unknown source" );
+ return;
+ }
+
+ if( !m_bCanClose )//@todo tryaqcuire mutex
+ {
+ if( bGetsOwnership )
+ {
+ aModelRef->SetOwnerShip( bGetsOwnership );
+ }
+
+ throw util::CloseVetoException();
+ }
+ else
+ {
+ //@ todo prepare to to closing model -> don't start any further hindering actions
+ }
+}
+
+ void SAL_CALL ChartController
+::notifyClosing( const lang::EventObject& rSource )
+ throw(uno::RuntimeException)
+{
+ //Listener should deregister himself and relaese all references to the closing object.
+
+ TheModelRef aModelRef( m_aModel, m_aModelMutex);
+ if( impl_releaseThisModel( rSource.Source ) )
+ {
+ //--stop listening to the closing model
+ aModelRef->removeListener( this );
+
+ // #i79087# If the model using this controller is closed, the frame is
+ // expected to be closed as well
+ Reference< util::XCloseable > xFrameCloseable( m_xFrame, uno::UNO_QUERY );
+ if( xFrameCloseable.is())
+ {
+ try
+ {
+ xFrameCloseable->close( sal_False /* DeliverOwnership */ );
+ m_xFrame.clear();
+ }
+ catch( util::CloseVetoException & )
+ {
+ // closing was vetoed
+ }
+ }
+ }
+}
+
+bool ChartController::impl_releaseThisModel( const uno::Reference< uno::XInterface > & xModel )
+{
+ bool bReleaseModel = sal_False;
+ {
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aModelMutex );
+ if( m_aModel.is() && m_aModel->getModel() == xModel )
+ {
+ m_aModel = NULL;
+ m_xUndoManager.clear();
+ bReleaseModel = true;
+ }
+ }
+ if( bReleaseModel )
+ m_aDispatchContainer.setModel( 0 );
+ return bReleaseModel;
+}
+
+//-----------------------------------------------------------------
+// util::XEventListener (base of XCloseListener)
+//-----------------------------------------------------------------
+ void SAL_CALL ChartController
+::disposing( const lang::EventObject& rSource )
+ throw(uno::RuntimeException)
+{
+ if( !impl_releaseThisModel( rSource.Source ))
+ {
+ if( rSource.Source == m_xLayoutManagerEventBroadcaster )
+ m_xLayoutManagerEventBroadcaster.set( 0 );
+ }
+}
+
+void SAL_CALL ChartController::layoutEvent( const lang::EventObject& aSource, ::sal_Int16 eLayoutEvent, const uno::Any& /* aInfo */ )
+ throw (uno::RuntimeException)
+{
+ if( eLayoutEvent == frame::LayoutManagerEvents::MERGEDMENUBAR )
+ {
+ Reference< frame::XLayoutManager > xLM( aSource.Source, uno::UNO_QUERY );
+ if( xLM.is())
+ {
+ xLM->createElement( C2U("private:resource/statusbar/statusbar"));
+ xLM->requestElement( C2U("private:resource/statusbar/statusbar"));
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------
+// XDispatchProvider (required interface)
+//-----------------------------------------------------------------
+
+namespace
+{
+bool lcl_isFormatObjectCommand( const rtl::OString& aCommand )
+{
+ if( aCommand.equals("MainTitle")
+ || aCommand.equals("SubTitle")
+ || aCommand.equals("XTitle")
+ || aCommand.equals("YTitle")
+ || aCommand.equals("ZTitle")
+ || aCommand.equals("SecondaryXTitle")
+ || aCommand.equals("SecondaryYTitle")
+ || aCommand.equals("AllTitles")
+ || aCommand.equals("DiagramAxisX")
+ || aCommand.equals("DiagramAxisY")
+ || aCommand.equals("DiagramAxisZ")
+ || aCommand.equals("DiagramAxisA")
+ || aCommand.equals("DiagramAxisB")
+ || aCommand.equals("DiagramAxisAll")
+ || aCommand.equals("DiagramGridXMain")
+ || aCommand.equals("DiagramGridYMain")
+ || aCommand.equals("DiagramGridZMain")
+ || aCommand.equals("DiagramGridXHelp")
+ || aCommand.equals("DiagramGridYHelp")
+ || aCommand.equals("DiagramGridZHelp")
+ || aCommand.equals("DiagramGridAll")
+
+ || aCommand.equals("DiagramWall")
+ || aCommand.equals("DiagramFloor")
+ || aCommand.equals("DiagramArea")
+ || aCommand.equals("Legend")
+
+ || aCommand.equals("FormatWall")
+ || aCommand.equals("FormatFloor")
+ || aCommand.equals("FormatChartArea")
+ || aCommand.equals("FormatLegend")
+
+ || aCommand.equals("FormatTitle")
+ || aCommand.equals("FormatAxis")
+ || aCommand.equals("FormatDataSeries")
+ || aCommand.equals("FormatDataPoint")
+ || aCommand.equals("FormatDataLabels")
+ || aCommand.equals("FormatDataLabel")
+ || aCommand.equals("FormatYErrorBars")
+ || aCommand.equals("FormatMeanValue")
+ || aCommand.equals("FormatTrendline")
+ || aCommand.equals("FormatTrendlineEquation")
+ || aCommand.equals("FormatStockLoss")
+ || aCommand.equals("FormatStockGain")
+ || aCommand.equals("FormatMajorGrid")
+ || aCommand.equals("FormatMinorGrid")
+ )
+ return true;
+
+ // else
+ return false;
+}
+} // anonymous namespace
+
+ uno::Reference<frame::XDispatch> SAL_CALL ChartController
+::queryDispatch( const util::URL& rURL
+ , const rtl::OUString& rTargetFrameName
+ , sal_Int32 /* nSearchFlags */)
+ throw(uno::RuntimeException)
+{
+ if ( !m_aLifeTimeManager.impl_isDisposed() && getModel().is() )
+ {
+ if( rTargetFrameName.getLength() &&
+ rTargetFrameName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("_self")))
+ return m_aDispatchContainer.getDispatchForURL( rURL );
+ }
+ return uno::Reference< frame::XDispatch > ();
+}
+
+ uno::Sequence<uno::Reference<frame::XDispatch > > ChartController
+::queryDispatches( const uno::Sequence<
+ frame::DispatchDescriptor>& xDescripts)
+ throw(uno::RuntimeException)
+{
+ if ( !m_aLifeTimeManager.impl_isDisposed() )
+ {
+ return m_aDispatchContainer.getDispatchesForURLs( xDescripts );
+ }
+ return uno::Sequence<uno::Reference<frame::XDispatch > > ();
+}
+
+//-----------------------------------------------------------------
+// frame::XDispatch
+//-----------------------------------------------------------------
+
+ void SAL_CALL ChartController
+::dispatch( const util::URL& rURL
+ , const uno::Sequence< beans::PropertyValue >& rArgs )
+ throw (uno::RuntimeException)
+{
+ //@todo avoid OString (see Mathias mail on bug #104387#)
+ rtl::OString aCommand( rtl::OUStringToOString( rURL.Path, RTL_TEXTENCODING_ASCII_US ) );
+
+ if(aCommand.equals("Paste"))
+ this->executeDispatch_Paste();
+ else if(aCommand.equals("Copy"))
+ this->executeDispatch_Copy();
+ else if(aCommand.equals("Cut"))
+ this->executeDispatch_Cut();
+ else if(aCommand.equals("DataRanges"))
+ this->executeDispatch_SourceData();
+ //----------------------------------
+ else if(aCommand.equals("Update")) //Update Chart
+ {
+ ChartViewHelper::setViewToDirtyState( getModel() );
+ if( m_pChartWindow )
+ m_pChartWindow->Invalidate();
+ }
+ else if(aCommand.equals("DiagramData"))
+ this->executeDispatch_EditData();
+ //insert objects
+ else if( aCommand.equals("InsertTitles")
+ || aCommand.equals("InsertMenuTitles") )
+ this->executeDispatch_InsertTitles();
+ else if( aCommand.equals("InsertMenuLegend") )
+ this->executeDispatch_OpenLegendDialog();
+ else if( aCommand.equals("InsertLegend") )
+ this->executeDispatch_InsertLegend();
+ else if( aCommand.equals("DeleteLegend") )
+ this->executeDispatch_DeleteLegend();
+ else if( aCommand.equals("InsertMenuDataLabels"))
+ this->executeDispatch_InsertMenu_DataLabels();
+ else if( aCommand.equals("InsertMenuAxes")
+ || aCommand.equals("InsertRemoveAxes") )
+ this->executeDispatch_InsertAxes();
+ else if( aCommand.equals("InsertMenuGrids"))
+ this->executeDispatch_InsertGrid();
+ else if( aCommand.equals("InsertMenuTrendlines"))
+ this->executeDispatch_InsertMenu_Trendlines();
+ else if( aCommand.equals("InsertMenuMeanValues"))
+ this->executeDispatch_InsertMenu_MeanValues();
+ else if( aCommand.equals("InsertMenuYErrorBars"))
+ this->executeDispatch_InsertMenu_YErrorBars();
+ else if( aCommand.equals("InsertSymbol"))
+ this->executeDispatch_InsertSpecialCharacter();
+ else if( aCommand.equals("InsertTrendline"))
+ this->executeDispatch_InsertTrendline();
+ else if( aCommand.equals("DeleteTrendline"))
+ this->executeDispatch_DeleteTrendline();
+ else if( aCommand.equals("InsertMeanValue"))
+ this->executeDispatch_InsertMeanValue();
+ else if( aCommand.equals("DeleteMeanValue"))
+ this->executeDispatch_DeleteMeanValue();
+ else if( aCommand.equals("InsertYErrorBars"))
+ this->executeDispatch_InsertYErrorBars();
+ else if( aCommand.equals("DeleteYErrorBars"))
+ this->executeDispatch_DeleteYErrorBars();
+ else if( aCommand.equals("InsertTrendlineEquation"))
+ this->executeDispatch_InsertTrendlineEquation();
+ else if( aCommand.equals("DeleteTrendlineEquation"))
+ this->executeDispatch_DeleteTrendlineEquation();
+ else if( aCommand.equals("InsertTrendlineEquationAndR2"))
+ this->executeDispatch_InsertTrendlineEquation( true );
+ else if( aCommand.equals("InsertR2Value"))
+ this->executeDispatch_InsertR2Value();
+ else if( aCommand.equals("DeleteR2Value"))
+ this->executeDispatch_DeleteR2Value();
+ else if( aCommand.equals("InsertDataLabels") )
+ this->executeDispatch_InsertDataLabels();
+ else if( aCommand.equals("InsertDataLabel") )
+ this->executeDispatch_InsertDataLabel();
+ else if( aCommand.equals("DeleteDataLabels") )
+ this->executeDispatch_DeleteDataLabels();
+ else if( aCommand.equals("DeleteDataLabel") )
+ this->executeDispatch_DeleteDataLabel();
+ else if( aCommand.equals("ResetAllDataPoints") )
+ this->executeDispatch_ResetAllDataPoints();
+ else if( aCommand.equals("ResetDataPoint") )
+ this->executeDispatch_ResetDataPoint();
+ else if( aCommand.equals("InsertAxis") )
+ this->executeDispatch_InsertAxis();
+ else if( aCommand.equals("InsertMajorGrid") )
+ this->executeDispatch_InsertMajorGrid();
+ else if( aCommand.equals("InsertMinorGrid") )
+ this->executeDispatch_InsertMinorGrid();
+ else if( aCommand.equals("InsertAxisTitle") )
+ this->executeDispatch_InsertAxisTitle();
+ else if( aCommand.equals("DeleteAxis") )
+ this->executeDispatch_DeleteAxis();
+ else if( aCommand.equals("DeleteMajorGrid") )
+ this->executeDispatch_DeleteMajorGrid();
+ else if( aCommand.equals("DeleteMinorGrid") )
+ this->executeDispatch_DeleteMinorGrid();
+ //format objects
+ else if( aCommand.equals("FormatSelection") )
+ this->executeDispatch_ObjectProperties();
+ else if( aCommand.equals("TransformDialog"))
+ {
+ if ( isShapeContext() )
+ {
+ this->impl_ShapeControllerDispatch( rURL, rArgs );
+ }
+ else
+ {
+ this->executeDispatch_PositionAndSize();
+ }
+ }
+ else if( lcl_isFormatObjectCommand(aCommand) )
+ this->executeDispatch_FormatObject(rURL.Path);
+ //more format
+//MENUCHANGE else if(aCommand.equals("SelectSourceRanges"))
+//MENUCHANGE this->executeDispatch_SourceData();
+ else if( aCommand.equals("DiagramType"))
+ this->executeDispatch_ChartType();
+ else if( aCommand.equals("View3D"))
+ this->executeDispatch_View3D();
+ else if ( aCommand.equals( "Forward" ) )
+ {
+ if ( isShapeContext() )
+ {
+ this->impl_ShapeControllerDispatch( rURL, rArgs );
+ }
+ else
+ {
+ this->executeDispatch_MoveSeries( sal_True );
+ }
+ }
+ else if ( aCommand.equals( "Backward" ) )
+ {
+ if ( isShapeContext() )
+ {
+ this->impl_ShapeControllerDispatch( rURL, rArgs );
+ }
+ else
+ {
+ this->executeDispatch_MoveSeries( sal_False );
+ }
+ }
+ else if( aCommand.equals("NewArrangement"))
+ this->executeDispatch_NewArrangement();
+ else if( aCommand.equals("ToggleLegend"))
+ this->executeDispatch_ToggleLegend();
+ else if( aCommand.equals("ToggleGridHorizontal"))
+ this->executeDispatch_ToggleGridHorizontal();
+ else if( aCommand.equals("ScaleText"))
+ this->executeDispatch_ScaleText();
+ else if( aCommand.equals("StatusBarVisible"))
+ {
+ // workaround: this should not be necessary.
+ uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY );
+ if( xPropSet.is() )
+ {
+ uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
+ xPropSet->getPropertyValue( C2U( "LayoutManager" ) ) >>= xLayoutManager;
+ if ( xLayoutManager.is() )
+ {
+ bool bIsVisible( xLayoutManager->isElementVisible( C2U("private:resource/statusbar/statusbar")));
+ if( bIsVisible )
+ {
+ xLayoutManager->hideElement( C2U( "private:resource/statusbar/statusbar"));
+ xLayoutManager->destroyElement( C2U( "private:resource/statusbar/statusbar"));
+ }
+ else
+ {
+ xLayoutManager->createElement( C2U( "private:resource/statusbar/statusbar"));
+ xLayoutManager->showElement( C2U( "private:resource/statusbar/statusbar"));
+ }
+ // @todo: update menu state (checkmark next to "Statusbar").
+ }
+ }
+ }
+
+ /*
+ case SID_TEXTEDIT:
+ this->executeDispatch_EditText();
+ */
+}
+
+ void SAL_CALL ChartController
+::addStatusListener( const uno::Reference<frame::XStatusListener >& /* xControl */
+ , const util::URL& /* aURL */ )
+ throw (uno::RuntimeException)
+{
+// // TODO: add listener by URL !
+// ::vos::OGuard aGuard( Application::GetSolarMutex());
+// if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode?
+// return; //behave passive if already disposed or suspended
+
+// //--add listener
+// m_aLifeTimeManager.m_aListenerContainer.addInterface( ::getCppuType( & xControl ), xControl );
+}
+
+ void SAL_CALL ChartController
+::removeStatusListener( const uno::Reference<frame::XStatusListener >& /* xControl */
+ , const util::URL& /* aURL */ )
+ throw (uno::RuntimeException)
+{
+// // TODO: remove listener by URL !
+// ::vos::OGuard aGuard( Application::GetSolarMutex());
+// if( m_aLifeTimeManager.impl_isDisposed() )
+// return; //behave passive if already disposed or suspended
+
+// //--remove listener
+// m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType( & xControl ), xControl );
+}
+
+//-----------------------------------------------------------------
+// XContextMenuInterception (optional interface)
+//-----------------------------------------------------------------
+ void SAL_CALL ChartController
+::registerContextMenuInterceptor( const uno::Reference<
+ ui::XContextMenuInterceptor > & /* xInterceptor */)
+ throw(uno::RuntimeException)
+{
+ //@todo
+}
+
+ void SAL_CALL ChartController
+::releaseContextMenuInterceptor( const uno::Reference<
+ ui::XContextMenuInterceptor > & /* xInterceptor */)
+ throw(uno::RuntimeException)
+{
+ //@todo
+}
+
+// ____ XEmbeddedClient ____
+// implementation see: ChartController_EditData.cxx
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+void SAL_CALL ChartController::executeDispatch_ChartType()
+{
+ // using assignment for broken gcc 3.3
+ UndoLiveUpdateGuard aUndoGuard = UndoLiveUpdateGuard(
+ ::rtl::OUString( String( SchResId( STR_ACTION_EDIT_CHARTTYPE ))), m_xUndoManager, getModel() );
+
+ // /--
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
+ //prepare and open dialog
+ ChartTypeDialog aDlg( m_pChartWindow, getModel(), m_xCC );
+ if( aDlg.Execute() == RET_OK )
+ {
+ impl_adaptDataSeriesAutoResize();
+ aUndoGuard.commitAction();
+ }
+ // \--
+}
+
+void SAL_CALL ChartController::executeDispatch_SourceData()
+{
+ //-------------------------------------------------------------
+ //convert properties to ItemSet
+ uno::Reference< XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
+ DBG_ASSERT( xChartDoc.is(), "Invalid XChartDocument" );
+ if( !xChartDoc.is())
+ return;
+
+ // using assignment for broken gcc 3.3
+ UndoLiveUpdateGuard aUndoGuard = UndoLiveUpdateGuard(
+ ::rtl::OUString( String( SchResId( STR_ACTION_EDIT_DATA_RANGES ))), m_xUndoManager, getModel() );
+ if( xChartDoc.is())
+ {
+ // /--
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
+ ::chart::DataSourceDialog aDlg( m_pChartWindow, xChartDoc, m_xCC );
+ if( aDlg.Execute() == RET_OK )
+ {
+ impl_adaptDataSeriesAutoResize();
+ aUndoGuard.commitAction();
+ }
+ // \--
+ }
+}
+
+void SAL_CALL ChartController::executeDispatch_MoveSeries( sal_Bool bForward )
+{
+ ControllerLockGuard aCLGuard( getModel() );
+
+ //get selected series
+ ::rtl::OUString aObjectCID(m_aSelection.getSelectedCID());
+ uno::Reference< XDataSeries > xGivenDataSeries( ObjectIdentifier::getDataSeriesForCID( //yyy todo also legendentries and labels?
+ aObjectCID, getModel() ) );
+
+ UndoGuardWithSelection aUndoGuard(
+ ActionDescriptionProvider::createDescription(
+ (bForward ? ActionDescriptionProvider::MOVE_TOTOP : ActionDescriptionProvider::MOVE_TOBOTTOM),
+ ::rtl::OUString( String( SchResId( STR_OBJECT_DATASERIES )))),
+ m_xUndoManager, getModel());
+
+ bool bChanged = DiagramHelper::moveSeries( ChartModelHelper::findDiagram( getModel() ), xGivenDataSeries, bForward );
+ if( bChanged )
+ {
+ m_aSelection.setSelection( ObjectIdentifier::getMovedSeriesCID( aObjectCID, bForward ) );
+ aUndoGuard.commitAction();
+ }
+}
+
+// ____ XMultiServiceFactory ____
+uno::Reference< uno::XInterface > SAL_CALL
+ ChartController::createInstance( const ::rtl::OUString& aServiceSpecifier )
+ throw (uno::Exception,
+ uno::RuntimeException)
+{
+ uno::Reference< uno::XInterface > xResult;
+
+ if( aServiceSpecifier.equals( CHART_ACCESSIBLE_TEXT_SERVICE_NAME ))
+ xResult.set( impl_createAccessibleTextContext());
+ return xResult;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL
+ ChartController::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier,
+ const uno::Sequence< uno::Any >& /* Arguments */ )
+ throw (uno::Exception,
+ uno::RuntimeException)
+{
+ // ignore Arguments
+ return createInstance( ServiceSpecifier );
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL
+ ChartController::getAvailableServiceNames()
+ throw (uno::RuntimeException)
+{
+ static uno::Sequence< ::rtl::OUString > aServiceNames;
+
+ if( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc(1);
+ aServiceNames[0] = CHART_ACCESSIBLE_TEXT_SERVICE_NAME;
+ }
+
+ return aServiceNames;
+}
+
+// ____ XModifyListener ____
+void SAL_CALL ChartController::modified( const lang::EventObject& /* aEvent */ )
+ throw (uno::RuntimeException)
+{
+ // the source can also be a subobject of the ChartModel
+ // @todo: change the source in ChartModel to always be the model itself ?
+// if( getModel() == aEvent.Source )
+
+
+ //todo? update menu states ?
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+IMPL_LINK( ChartController, NotifyUndoActionHdl, SdrUndoAction*, pUndoAction )
+{
+ ::rtl::OUString aObjectCID = m_aSelection.getSelectedCID();
+ if ( aObjectCID.getLength() == 0 )
+ {
+ UndoManager* pUndoManager = UndoManager::getImplementation( m_xUndoManager );
+ if ( pUndoManager )
+ {
+ pUndoManager->addShapeUndoAction( pUndoAction );
+ }
+ }
+ return 0L;
+}
+
+DrawModelWrapper* ChartController::GetDrawModelWrapper()
+{
+ if( !m_pDrawModelWrapper.get() )
+ {
+ ExplicitValueProvider* pProvider = ExplicitValueProvider::getExplicitValueProvider( m_xChartView );
+ if( pProvider )
+ m_pDrawModelWrapper = pProvider->getDrawModelWrapper();
+ if ( m_pDrawModelWrapper.get() )
+ {
+ m_pDrawModelWrapper->getSdrModel().SetNotifyUndoActionHdl( LINK( this, ChartController, NotifyUndoActionHdl ) );
+ }
+ }
+ return m_pDrawModelWrapper.get();
+}
+
+DrawViewWrapper* ChartController::GetDrawViewWrapper()
+{
+ if ( !m_pDrawViewWrapper )
+ {
+ impl_createDrawViewController();
+ }
+ return m_pDrawViewWrapper;
+}
+
+uno::Reference< XAccessible > ChartController::CreateAccessible()
+{
+ uno::Reference< XAccessible > xResult = new AccessibleChartView( m_xCC, GetDrawViewWrapper() );
+ impl_initializeAccessible( uno::Reference< lang::XInitialization >( xResult, uno::UNO_QUERY ) );
+ return xResult;
+}
+
+void ChartController::impl_invalidateAccessible()
+{
+ if( m_pChartWindow )
+ {
+ Reference< lang::XInitialization > xInit( m_pChartWindow->GetAccessible(false), uno::UNO_QUERY );
+ if(xInit.is())
+ {
+ uno::Sequence< uno::Any > aArguments(3);//empty arguments -> invalid accessible
+ xInit->initialize(aArguments);
+ }
+ }
+}
+void ChartController::impl_initializeAccessible()
+{
+ if( m_pChartWindow )
+ this->impl_initializeAccessible( Reference< lang::XInitialization >( m_pChartWindow->GetAccessible(false), uno::UNO_QUERY ) );
+}
+void ChartController::impl_initializeAccessible( const uno::Reference< lang::XInitialization >& xInit )
+{
+ if(xInit.is())
+ {
+ uno::Sequence< uno::Any > aArguments(5);
+ uno::Reference<view::XSelectionSupplier> xSelectionSupplier(this);
+ aArguments[0]=uno::makeAny(xSelectionSupplier);
+ uno::Reference<frame::XModel> xModel(getModel());
+ aArguments[1]=uno::makeAny(xModel);
+ aArguments[2]=uno::makeAny(m_xChartView);
+ uno::Reference< XAccessible > xParent;
+ if( m_pChartWindow )
+ {
+ Window* pParentWin( m_pChartWindow->GetAccessibleParentWindow());
+ if( pParentWin )
+ xParent.set( pParentWin->GetAccessible());
+ }
+ aArguments[3]=uno::makeAny(xParent);
+ aArguments[4]=uno::makeAny(m_xViewWindow);
+
+ xInit->initialize(aArguments);
+ }
+}
+
+::std::set< ::rtl::OUString > ChartController::impl_getAvailableCommands()
+{
+ return ::comphelper::MakeSet< ::rtl::OUString >
+ // commands for container forward
+ ( C2U("AddDirect")) ( C2U("NewDoc")) ( C2U("Open"))
+ ( C2U("Save")) ( C2U("SaveAs")) ( C2U("SendMail"))
+ ( C2U("EditDoc")) ( C2U("ExportDirectToPDF")) ( C2U("PrintDefault"))
+
+ // own commands
+ ( C2U("Cut") ) ( C2U("Copy") ) ( C2U("Paste") )
+ ( C2U("DataRanges") ) ( C2U("DiagramData") )
+ // insert objects
+ ( C2U("InsertMenuTitles") ) ( C2U("InsertTitles") )
+ ( C2U("InsertMenuLegend") ) ( C2U("InsertLegend") ) ( C2U("DeleteLegend") )
+ ( C2U("InsertMenuDataLabels") )
+ ( C2U("InsertMenuAxes") ) ( C2U("InsertRemoveAxes") ) ( C2U("InsertMenuGrids") )
+ ( C2U("InsertSymbol") )
+ ( C2U("InsertTrendlineEquation") ) ( C2U("InsertTrendlineEquationAndR2") )
+ ( C2U("InsertR2Value") ) ( C2U("DeleteR2Value") )
+ ( C2U("InsertMenuTrendlines") ) ( C2U("InsertTrendline") )
+ ( C2U("InsertMenuMeanValues") ) ( C2U("InsertMeanValue") )
+ ( C2U("InsertMenuYErrorBars") ) ( C2U("InsertYErrorBars") )
+ ( C2U("InsertDataLabels") ) ( C2U("InsertDataLabel") )
+ ( C2U("DeleteTrendline") ) ( C2U("DeleteMeanValue") ) ( C2U("DeleteTrendlineEquation") )
+ ( C2U("DeleteYErrorBars") )
+ ( C2U("DeleteDataLabels") ) ( C2U("DeleteDataLabel") )
+ //format objects
+//MENUCHANGE ( C2U("SelectSourceRanges") )
+ ( C2U("FormatSelection") ) ( C2U("TransformDialog") )
+ ( C2U("DiagramType") ) ( C2U("View3D") )
+ ( C2U("Forward") ) ( C2U("Backward") )
+ ( C2U("MainTitle") ) ( C2U("SubTitle") )
+ ( C2U("XTitle") ) ( C2U("YTitle") ) ( C2U("ZTitle") )
+ ( C2U("SecondaryXTitle") ) ( C2U("SecondaryYTitle") )
+ ( C2U("AllTitles") ) ( C2U("Legend") )
+ ( C2U("DiagramAxisX") ) ( C2U("DiagramAxisY") ) ( C2U("DiagramAxisZ") )
+ ( C2U("DiagramAxisA") ) ( C2U("DiagramAxisB") ) ( C2U("DiagramAxisAll") )
+ ( C2U("DiagramGridXMain") ) ( C2U("DiagramGridYMain") ) ( C2U("DiagramGridZMain") )
+ ( C2U("DiagramGridXHelp") ) ( C2U("DiagramGridYHelp") ) ( C2U("DiagramGridZHelp") )
+ ( C2U("DiagramGridAll") )
+ ( C2U("DiagramWall") ) ( C2U("DiagramFloor") ) ( C2U("DiagramArea") )
+
+ //context menu - format objects entries
+ ( C2U("FormatWall") ) ( C2U("FormatFloor") ) ( C2U("FormatChartArea") )
+ ( C2U("FormatLegend") )
+
+ ( C2U("FormatAxis") ) ( C2U("FormatTitle") )
+ ( C2U("FormatDataSeries") ) ( C2U("FormatDataPoint") )
+ ( C2U("ResetAllDataPoints") ) ( C2U("ResetDataPoint") )
+ ( C2U("FormatDataLabels") ) ( C2U("FormatDataLabel") )
+ ( C2U("FormatMeanValue") ) ( C2U("FormatTrendline") ) ( C2U("FormatTrendlineEquation") )
+ ( C2U("FormatYErrorBars") )
+ ( C2U("FormatStockLoss") ) ( C2U("FormatStockGain") )
+
+ ( C2U("FormatMajorGrid") ) ( C2U("InsertMajorGrid") ) ( C2U("DeleteMajorGrid") )
+ ( C2U("FormatMinorGrid") ) ( C2U("InsertMinorGrid") ) ( C2U("DeleteMinorGrid") )
+ ( C2U("InsertAxis") ) ( C2U("DeleteAxis") ) ( C2U("InsertAxisTitle") )
+
+ // toolbar commands
+ ( C2U("ToggleGridHorizontal"))( C2U("ToggleLegend") ) ( C2U("ScaleText") )
+ ( C2U("NewArrangement") ) ( C2U("Update") )
+ ( C2U("DefaultColors") ) ( C2U("BarWidth") ) ( C2U("NumberOfLines") )
+ ( C2U("ArrangeRow") )
+ ( C2U("StatusBarVisible") )
+ ( C2U("ChartElementSelector") )
+ ;
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................