Files
libreoffice/chart2/source/controller/main/ChartController.cxx

1146 lines
37 KiB
C++
Raw Normal View History

2003-10-06 08:58:36 +00:00
/*************************************************************************
*
* $RCSfile: ChartController.cxx,v $
*
* $Revision: 1.16 $
2003-10-06 08:58:36 +00:00
*
* last change: $Author: rt $ $Date: 2004-07-12 15:35:46 $
2003-10-06 08:58:36 +00:00
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library 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 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (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.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2003 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#include "ChartController.hxx"
#include "servicenames.hxx"
#include "SchItemPool.hxx"
2003-10-06 08:58:36 +00:00
#include "InlineContainer.hxx"
#include "Chart.hrc"
#include "ResId.hxx"
#include "SchSlotIds.hxx"
#include "chartview/ChartView.hxx"
#include "ChartWindow.hxx"
#include "DrawModelWrapper.hxx"
#include "DrawViewWrapper.hxx"
#include "DataSeriesTreeHelper.hxx"
2003-11-04 14:35:09 +00:00
#include "DiagramHelper.hxx"
2003-10-06 08:58:36 +00:00
#include "macros.hxx"
#include "chartview/NumberFormatterWrapper.hxx"
#include "dlg_ChartType.hxx"
//for SID_CHARMAP:
#ifndef _SVX_SVXIDS_HRC
#include <svx/svxids.hrc>
#endif
#ifndef _COM_SUN_STAR_CHART2_XCHARTDOCUMENT_HPP_
#include <com/sun/star/chart2/XChartDocument.hpp>
2003-10-06 08:58:36 +00:00
#endif
#ifndef _COM_SUN_STAR_CHART2_XSTACKABLESCALEGROUP_HPP_
#include <com/sun/star/chart2/XStackableScaleGroup.hpp>
2003-10-06 08:58:36 +00:00
#endif
#ifndef _COM_SUN_STAR_CHART2_XCHARTTYPETEMPLATE_HPP_
#include <com/sun/star/chart2/XChartTypeTemplate.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XLOADABLE_HPP_
#include <com/sun/star/frame/XLoadable.hpp>
#endif
2003-10-06 08:58:36 +00:00
//-------
// header for define RET_OK
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
//-------
//-------
#ifndef _TOOLKIT_AWT_VCLXWINDOW_HXX_
#include <toolkit/awt/vclxwindow.hxx>
#endif
#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/helper/vclunohelper.hxx>
#endif
#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
//-------
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_UTIL_XURLTRANSFORMER_HPP_
#include <com/sun/star/util/XURLTransformer.hpp>
#endif
//.............................................................................
namespace chart
{
//.............................................................................
using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;
2003-10-06 08:58:36 +00:00
//-----------------------------------------------------------------
// 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??
2003-10-06 08:58:36 +00:00
, m_xFrame( NULL )
, m_aModelMutex()
, m_aModel( NULL, m_aModelMutex )
, m_pChartWindow( NULL )
, m_xViewWindow( NULL )
, m_pChartView( NULL )
, m_pDrawModelWrapper( NULL )
, m_pDrawViewWrapper(NULL)
, m_bViewDirty( false )
, m_pNumberFormatterWrapper(NULL)
{
//@todo
m_pNumberFormatterWrapper = new NumberFormatterWrapper();
}
ChartController::~ChartController()
{
impl_deleteView();
//m_pChartWindow is deleted via UNO by Window hierarchy or Framework
DELETEZ( m_pNumberFormatterWrapper );
DELETEZ( m_pDrawViewWrapper );
DELETEZ( m_pDrawModelWrapper );
2003-10-06 08:58:36 +00:00
//@todo ?
}
//-----------------------------------------------------------------
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<lang::XEventListener*>(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<lang::XEventListener*>(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
OSL_ENSURE( !m_bOwnership,
"INFO: a well known owner has catched a CloseVetoException after calling close(true)" );
m_bOwnership = false;
m_bOwnershipIsWellKnown = sal_True;
return;
}
}
else if( m_xModel.is() )
{
//@todo correct??
m_xModel->dispose();
return;
}
}
catch( uno::Exception& ex)
{
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()
{
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)
{
osl::Guard< osl::Mutex > aGuard( m_aControllerMutex );
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 ...
}
{
// calls to VCL
::vos::OGuard aSolarGuard( Application::GetSolarMutex());
m_pChartWindow = new ChartWindow(this,pParent,pParent?pParent->GetStyle():0);
m_xViewWindow = uno::Reference< awt::XWindow >( m_pChartWindow->GetComponentInterface(), uno::UNO_QUERY );
m_pChartWindow->Show();
}
impl_tryInitializeView();
{//create the menu
util::URL aURL( SchResId(RID_MENU).getURL() );
uno::Reference< lang::XMultiServiceFactory > xMgr = comphelper::getProcessServiceFactory();
uno::Reference< util::XURLTransformer > xTrans(
xMgr->createInstance( ::rtl::OUString::createFromAscii(
"com.sun.star.util.URLTransformer") ), uno::UNO_QUERY );
if( xTrans.is() )
{
// Datei laden
xTrans->parseStrict( aURL );
uno::Reference< frame::XDispatchProvider > xProv( xFrame, uno::UNO_QUERY );
if ( xProv.is() )
{
uno::Reference< frame::XDispatch > aDisp =
xProv->queryDispatch( aURL,
::rtl::OUString::createFromAscii("_menubar"), 12 );
if ( aDisp.is() )
aDisp->dispatch( aURL, uno::Sequence<beans::PropertyValue>() );
}
}
}
}
void SAL_CALL ChartController
::impl_rebuildView()
throw(uno::RuntimeException)
{
m_bViewDirty = false;
impl_tryInitializeView();
if( m_aSelectedObjectCID.getLength() )
{
//@todo reselect object
m_aSelectedObjectCID = C2U("");
}
}
void SAL_CALL ChartController
::impl_deleteView()
throw(uno::RuntimeException)
{
2003-11-15 07:48:34 +00:00
if( m_pDrawViewWrapper && m_pDrawViewWrapper->IsTextEdit() )
this->EndTextEdit();
if( m_pDrawViewWrapper )
m_pDrawViewWrapper->SetMarkHdlHidden(TRUE);
DELETEZ( m_pDrawViewWrapper );
delete m_pChartView; m_pChartView = NULL;
2003-10-06 08:58:36 +00:00
}
sal_Bool SAL_CALL ChartController
::impl_tryInitializeView()
throw(uno::RuntimeException)
{
osl::ClearableGuard< osl::Mutex > aGuard( m_aControllerMutex );
if(!m_pChartWindow || !m_aModel.is() )
return sal_False;
if( !m_pDrawModelWrapper )
m_pDrawModelWrapper = new DrawModelWrapper(m_xCC
,wrapper::SchItemPool::CreateSchItemPool());
2003-10-06 08:58:36 +00:00
uno::Reference< frame::XModel > xDrawModel = m_pDrawModelWrapper->getUnoModel();
if( xDrawModel.is())
xDrawModel->lockControllers();
impl_deleteView();
2003-10-06 08:58:36 +00:00
m_pChartView = ChartView::createView( m_xCC, m_aModel->getModel()
, uno::Reference<drawing::XDrawPagesSupplier>::query( xDrawModel )
, m_pNumberFormatterWrapper );
//OutputDevice* pOutDev = m_pDrawViewWrapper->GetWin(0);
Size aPageSize = m_pChartWindow->GetOutputSize();
m_pChartView->create( awt::Size( aPageSize.Width(), aPageSize.Height() ) );
// m_pChartWindow->SetChartView(m_pChartView);//enable event flow from window to View (Window knows View)
//create draw view:
if(!m_pDrawViewWrapper)
m_pDrawViewWrapper = new DrawViewWrapper(&m_pDrawModelWrapper->getSdrModel(),m_pChartWindow);
else
m_pDrawViewWrapper->ReInit();//this does not work properly for unknown reasons (after some tiny resizes their seems to went something very wrong: mouse click to view -> crash )
2003-10-06 08:58:36 +00:00
//test:
//Rectangle aTest = m_pDrawViewWrapper->GetWorkArea();
//m_pDrawViewWrapper->SetWorkArea(pOutDev->PixelToLogic(Rectangle(rOfs, rSize)));
if( xDrawModel.is())
{
xDrawModel->unlockControllers();
m_pChartWindow->Invalidate();
}
return sal_True;
}
sal_Bool SAL_CALL ChartController
::attachModel( const uno::Reference< frame::XModel > & xModel )
throw(uno::RuntimeException)
{
//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)
osl::ClearableGuard< osl::Mutex > aGuard( m_aControllerMutex );
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() )
{
aOldModelRef->removeListener( this );
//@todo?? termination correct?
aOldModelRef->tryTermination();
}
//--handle relations to the new model
aNewModelRef->addListener( this );
//the frameloader is responsible to call xModel->connectController
{
// Indirect calls to VCL
::vos::OGuard aSolarGuard( Application::GetSolarMutex());
impl_tryInitializeView();
}
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()
osl::ResettableGuard< osl::Mutex > aGuard( m_aControllerMutex );
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()
osl::ResettableGuard< osl::Mutex > aGuard( m_aControllerMutex );
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?
osl::ResettableGuard< osl::Mutex > aGuard( m_aControllerMutex );
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" );
//@todo ??? or return true in this case?
return sal_False;
}
//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 );
*/
return sal_True;
}
//-----------------------------------------------------------------
// XComponent (base of XController)
//-----------------------------------------------------------------
void SAL_CALL ChartController
::dispose() throw(uno::RuntimeException)
{
//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" );
//--release all resources and references
impl_deleteView();
DELETEZ( m_pDrawViewWrapper );
DELETEZ( m_pDrawModelWrapper );
2003-10-06 08:58:36 +00:00
m_pChartWindow = NULL;//m_pChartWindow is deleted via UNO by Window hierarchy or Framework
m_xFrame = NULL;
TheModelRef aModelRef( m_aModel, m_aModelMutex);
m_aModel = NULL;
if(aModelRef.is())
{
aModelRef->removeListener( this );
aModelRef->tryTermination();
}
//// @todo integrate specialized implementation
//e.g. release further resources and references
}
void SAL_CALL ChartController
::addEventListener( const uno::Reference<lang::XEventListener>& xListener )
throw(uno::RuntimeException)
{
osl::Guard< osl::Mutex > aGuard( m_aControllerMutex );
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)
{
osl::Guard< osl::Mutex > aGuard( m_aControllerMutex );
if( impl_isDisposedOrSuspended() ) //@todo? allow removing of listeners in suspend mode?
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( 0, m_aModelMutex);
bool bReleaseModel = sal_False;
{
::osl::Guard< ::osl::Mutex > aGuard( m_aModelMutex );
aModelRef = m_aModel;
if( aModelRef.is() && aModelRef->getModel() == rSource.Source )
{
m_aModel = NULL;
bReleaseModel = sal_True;
}
}
//@todo ?? why remove the listener??? this could be handled by the closing object
if( bReleaseModel )
{
//--stop listening to the closing model
aModelRef->removeListener( this );
}
}
//-----------------------------------------------------------------
// util::XEventListener (base of XCloseListener)
//-----------------------------------------------------------------
void SAL_CALL ChartController
::disposing( const lang::EventObject& rSource )
throw(uno::RuntimeException)
{
notifyClosing(rSource);
}
//-----------------------------------------------------------------
// XDispatchProvider (required interface)
//-----------------------------------------------------------------
bool isFormatObjectSID( sal_Int32 nSlotID )
{
switch( nSlotID )
{
case SID_DIAGRAM_TITLE_MAIN:
case SID_DIAGRAM_TITLE_SUB:
case SID_DIAGRAM_TITLE_X:
case SID_DIAGRAM_TITLE_Y:
case SID_DIAGRAM_TITLE_Z:
case SID_DIAGRAM_TITLE_ALL:
case SID_LEGEND:
case SID_DIAGRAM_AXIS_X:
case SID_DIAGRAM_AXIS_Y:
case SID_DIAGRAM_AXIS_Z:
case SID_DIAGRAM_AXIS_A: // secondary x-axis
case SID_DIAGRAM_AXIS_B: // secondary y-axis
case SID_DIAGRAM_AXIS_ALL:
case SID_DIAGRAM_GRID_X_MAIN:
case SID_DIAGRAM_GRID_Y_MAIN:
case SID_DIAGRAM_GRID_Z_MAIN:
case SID_DIAGRAM_GRID_X_HELP:
case SID_DIAGRAM_GRID_Y_HELP:
case SID_DIAGRAM_GRID_Z_HELP:
case SID_DIAGRAM_GRID_ALL:
case SID_DIAGRAM_WALL:
case SID_DIAGRAM_FLOOR:
case SID_DIAGRAM_AREA:
return true;
}
2003-10-06 08:58:36 +00:00
return false;
}
uno::Reference<frame::XDispatch> SAL_CALL ChartController
::queryDispatch( const util::URL& rURL
, const rtl::OUString& rTargetFrameName
, sal_Int32 nSearchFlags)
throw(uno::RuntimeException)
{
//// @todo integrate specialized implementation
//decide which commands you can handle
if ( !m_aLifeTimeManager.impl_isDisposed() )
{
//@todo avoid OString (see Mathias mail on bug #104387#)
rtl::OString aCommand( rtl::OUStringToOString( rURL.Path, RTL_TEXTENCODING_ASCII_US ) );
if( aCommand.equals("Save")
|| aCommand.equals("SaveAs")
|| aCommand.equals("SaveAll")
|| aCommand.equals("Undo")
|| aCommand.equals("Cut")
|| aCommand.equals("Copy")
|| aCommand.equals("Paste")
|| aCommand.equals("SelectAll")
|| aCommand.equals("Close")
|| aCommand.equals("TESTTEST")
|| aCommand.equals("slot:23")
//|| aCommand.copy(0,4).EqualsAscii("Bib/")
//|| aURL.Complete.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("slot:5503"))
)
{
//@todo create a seperate dispatcher object or implement XDispatch interface by yourself
//to return it here
return static_cast< frame::XDispatch* >( this );
}
else if(rURL.Protocol.equalsIgnoreAsciiCase( C2U("slot:") ) )
{
sal_Int32 nSlotID = rURL.Path.toInt32();
if( SID_DIAGRAM_OBJECTS == nSlotID
|| SID_DIAGRAM_TYPE == nSlotID
|| SID_INSERT_TITLE == nSlotID
|| SID_INSERT_CHART_LEGEND == nSlotID
|| SID_INSERT_DESCRIPTION == nSlotID
|| SID_INSERT_AXIS == nSlotID
|| SID_INSERT_GRIDS == nSlotID
|| SID_INSERT_STATISTICS == nSlotID
|| SID_CHARMAP == nSlotID
|| SID_TEXTEDIT == nSlotID
2003-10-06 08:58:36 +00:00
|| isFormatObjectSID(nSlotID)
|| SID_3D_VIEW == nSlotID
|| SID_ATTR_TRANSFORM == nSlotID
|| SID_DIAGRAM_DATA == nSlotID
2003-10-06 08:58:36 +00:00
)
{
return static_cast< frame::XDispatch* >( this );
}
}
}
return uno::Reference< frame::XDispatch > ();
}
/*
typedef ::std::map< sal_Int32, ::rtl::OUString > tSlotIdCommandMap;
typedef ::comphelper::MakeMap< sal_Int32, ::rtl::OUString > tMakeSlotIdCommandMap;
tMakeSlotIdCommandMap m_aSlotIdCommandMap =
tMakeSlotIdCommandMap
( (sal_Int32)SID_DIAGRAM_TITLE_MAIN, C2U( "slot:" )+=rtl::OUString::valueOf( (sal_Int32)SID_DIAGRAM_TITLE_MAIN ) )
;
*/
uno::Sequence<uno::Reference<frame::XDispatch > > ChartController
::queryDispatches( const uno::Sequence<
frame::DispatchDescriptor>& xDescripts)
throw(uno::RuntimeException)
{
sal_Int32 nCount = xDescripts.getLength();
if( !nCount )
return uno::Sequence<uno::Reference<frame::XDispatch > > ();
uno::Sequence<uno::Reference<frame::XDispatch > > aRet( nCount );
for( sal_Int32 nPos = 0; nPos<nCount; ++nPos )
{
aRet[ nPos ] = queryDispatch(
xDescripts[nPos].FeatureURL
, xDescripts[nPos].FrameName
, xDescripts[nPos].SearchFlags );
}
return aRet;
}
//-----------------------------------------------------------------
// 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 ) );
//test only
if(aCommand.equals("TESTTEST")
|| aCommand.equals("Undo") )
{
Window* pWindow = m_pChartWindow;
Rectangle aRect( Point(0,0), pWindow->GetOutputSize() );
Region aRegion( aRect );
m_pDrawViewWrapper->CompleteRedraw(pWindow, aRegion );
2003-10-06 08:58:36 +00:00
/*
INVALIDATE_CHILDREN
INVALIDATE_NOCHILDREN
INVALIDATE_NOERASE
INVALIDATE_UPDATE
INVALIDATE_TRANSPARENT
INVALIDATE_NOTRANSPARENT
INVALIDATE_NOCLIPCHILDREN
*/
//Invalidate(INVALIDATE_UPDATE);
}
else if(aCommand.equals("Save"))
{
//only test:
impl_rebuildView();
}
else if(aCommand.equals("SaveAs"))
{
//only test:
this->executeDispatch_ObjectToDefault();
}
//----------------------------------
else if(rURL.Protocol.equalsIgnoreAsciiCase( C2U("slot:") ) )
{
sal_Int32 nSlotID = rURL.Path.toInt32();
switch( nSlotID )
2003-10-06 08:58:36 +00:00
{
case SID_DIAGRAM_OBJECTS:
this->executeDispatch_ObjectProperties();
break;
case SID_DIAGRAM_TYPE:
this->executeDispatch_ChartType();
break;
case SID_INSERT_TITLE:
this->executeDispatch_InsertTitle();
break;
case SID_INSERT_CHART_LEGEND:
this->executeDispatch_InsertLegend();
break;
case SID_INSERT_DESCRIPTION:
this->executeDispatch_InsertDataLabel();
break;
case SID_INSERT_AXIS:
this->executeDispatch_InsertAxis();
break;
case SID_INSERT_GRIDS:
this->executeDispatch_InsertGrid();
break;
case SID_INSERT_STATISTICS:
this->executeDispatch_InsertStatistic();
break;
case SID_CHARMAP:
this->executeDispatch_InsertSpecialCharacter();
break;
case SID_TEXTEDIT:
this->executeDispatch_EditText();
break;
case SID_3D_VIEW:
this->executeDispatch_RotateDiagram();
break;
case SID_ATTR_TRANSFORM:
this->executeDispatch_PositionAndSize( m_aSelectedObjectCID );
break;
case SID_DIAGRAM_DATA:
this->executeDispatch_EditData();
break;
default:
if( isFormatObjectSID(nSlotID) )
{
this->executeDispatch_FormatObject(nSlotID);
}
break;
}
2003-10-06 08:58:36 +00:00
}
else if(aCommand.equals("SaveAll"))
{
if( m_aModel.is())
{
// initialize doc with default data (file-data provider)
uno::Reference< frame::XLoadable > xLoadable(
2003-10-06 08:58:36 +00:00
m_aModel->getModel(), uno::UNO_QUERY );
OSL_ASSERT( xLoadable.is());
xLoadable->initNew();
// switch to internal calc-data
uno::Reference< XChartDocument > xChartDoc( xLoadable, uno::UNO_QUERY );
if( xChartDoc.is())
xChartDoc->createInternalDataProvider( sal_True );
2003-10-06 08:58:36 +00:00
impl_rebuildView();
}
}
}
void SAL_CALL ChartController
::addStatusListener( const uno::Reference<frame::XStatusListener >& xControl
, const util::URL& aURL )
throw (uno::RuntimeException)
{
}
void SAL_CALL ChartController
::removeStatusListener( const uno::Reference<frame::XStatusListener >& xControl
, const util::URL& aURL )
throw (uno::RuntimeException)
{
}
//-----------------------------------------------------------------
// 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
2003-10-06 08:58:36 +00:00
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void SAL_CALL ChartController::executeDispatch_ChartType()
{
bool bChanged = false;
//-------------------------------------------------------------
//convert properties to ItemSet
uno::Reference< XChartDocument > xChartDoc( m_aModel->getModel(), uno::UNO_QUERY );
DBG_ASSERT( xChartDoc.is(), "Invalid XChartDocument" );
if( !xChartDoc.is())
return;
uno::Reference< XDiagram > xDia( xChartDoc->getDiagram() );
DBG_ASSERT( xDia.is(), "No Diagram set!" );
uno::Reference< XChartTypeTemplate > xTemplate;
2003-10-06 08:58:36 +00:00
if( xChartDoc.is())
2003-10-06 08:58:36 +00:00
{
uno::Reference< lang::XMultiServiceFactory > xCTManager( xChartDoc->getChartTypeManager(), uno::UNO_QUERY );
2003-10-06 08:58:36 +00:00
//-------------------------------------------------------------
//prepare and open dialog
Window* pParent( NULL );
SchDiagramTypeDlg aDlg( pParent, xDia, xCTManager );
2003-11-04 12:28:39 +00:00
if( aDlg.Execute() == RET_OK &&
aDlg.HasChanged() )
2003-10-06 08:58:36 +00:00
{
xTemplate.set( aDlg.getTemplate());
bChanged = true;
2003-10-06 08:58:36 +00:00
}
}
try
{
//make sure that all objects using m_pDrawModelWrapper or m_pChartView are already deleted
if( bChanged &&
xTemplate.is() )
2003-10-06 08:58:36 +00:00
{
2003-11-04 14:35:09 +00:00
uno::Reference< XDiagram > xNewDia(
xTemplate->createDiagram(
2003-11-04 14:35:09 +00:00
helper::DataSeriesTreeHelper::getDataSeriesFromDiagram( xDia )));
helper::DiagramHelper::changeDiagram( xDia, xNewDia );
xChartDoc->setDiagram( xNewDia );
impl_rebuildView();
2003-10-06 08:58:36 +00:00
}
}
catch( uno::Exception& e)
2003-10-06 08:58:36 +00:00
{
ASSERT_EXCEPTION( e );
2003-10-06 08:58:36 +00:00
}
}
//.............................................................................
} //namespace chart
//.............................................................................