| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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 "AccessibleChartView.hxx" |
| #include "DrawCommandDispatch.hxx" |
| #include "ShapeController.hxx" |
| #include "UndoActions.hxx" |
| |
| #include <comphelper/InlineContainer.hxx> |
| |
| #include <com/sun/star/awt/PosSize.hpp> |
| #include <com/sun/star/chart2/XChartDocument.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> |
| #include <com/sun/star/document/XUndoManagerSupplier.hpp> |
| #include <com/sun/star/document/XUndoAction.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> |
| #include <tools/diagnose_ex.h> |
| |
| // 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_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 |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| 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(); |
| |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| 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 aClearableGuard( Application::GetSolarMutex()); |
| if( impl_isDisposedOrSuspended() ) //@todo? allow attaching a new model while suspended? |
| return sal_False; //behave passive if already disposed or suspended |
| aClearableGuard.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 |
| |
| // #119999# Do not do this per default to allow the user to deselect the chart OLE with a single press to ESC |
| // 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 |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| if( m_pChartWindow ) |
| m_pChartWindow->Invalidate(); |
| } |
| |
| uno::Reference< document::XUndoManagerSupplier > xSuppUndo( getModel(), uno::UNO_QUERY_THROW ); |
| m_xUndoManager.set( xSuppUndo->getUndoManager(), uno::UNO_QUERY_THROW ); |
| |
| 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.isEmpty() && |
| 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() ); |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| 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( |
| String( SchResId( STR_ACTION_EDIT_CHARTTYPE )), m_xUndoManager ); |
| |
| // /-- |
| ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); |
| //prepare and open dialog |
| ChartTypeDialog aDlg( m_pChartWindow, getModel(), m_xCC ); |
| if( aDlg.Execute() == RET_OK ) |
| { |
| impl_adaptDataSeriesAutoResize(); |
| aUndoGuard.commit(); |
| } |
| // \-- |
| } |
| |
| 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( |
| String( SchResId( STR_ACTION_EDIT_DATA_RANGES )), m_xUndoManager ); |
| if( xChartDoc.is()) |
| { |
| // /-- |
| ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); |
| ::chart::DataSourceDialog aDlg( m_pChartWindow, xChartDoc, m_xCC ); |
| if( aDlg.Execute() == RET_OK ) |
| { |
| impl_adaptDataSeriesAutoResize(); |
| aUndoGuard.commit(); |
| } |
| // \-- |
| } |
| } |
| |
| 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), |
| String( SchResId( STR_OBJECT_DATASERIES ))), |
| m_xUndoManager ); |
| |
| bool bChanged = DiagramHelper::moveSeries( ChartModelHelper::findDiagram( getModel() ), xGivenDataSeries, bForward ); |
| if( bChanged ) |
| { |
| m_aSelection.setSelection( ObjectIdentifier::getMovedSeriesCID( aObjectCID, bForward ) ); |
| aUndoGuard.commit(); |
| } |
| } |
| |
| // ____ 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 ) |
| { |
| ENSURE_OR_RETURN( pUndoAction, "invalid Undo action", 1L ); |
| |
| ::rtl::OUString aObjectCID = m_aSelection.getSelectedCID(); |
| if ( aObjectCID.isEmpty() ) |
| { |
| try |
| { |
| const Reference< document::XUndoManagerSupplier > xSuppUndo( getModel(), uno::UNO_QUERY_THROW ); |
| const Reference< document::XUndoManager > xUndoManager( xSuppUndo->getUndoManager(), uno::UNO_QUERY_THROW ); |
| const Reference< document::XUndoAction > xAction( new impl::ShapeUndoElement( *pUndoAction ) ); |
| xUndoManager->addUndoAction( xAction ); |
| } |
| catch( const uno::Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| 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() |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| 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() |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| 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; |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| 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 |
| //............................................................................. |