1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_svx.hxx" 30*cdf0e10cSrcweir #include "fmscriptingenv.hxx" 31*cdf0e10cSrcweir #include "svx/fmmodel.hxx" 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir /** === begin UNO includes === **/ 34*cdf0e10cSrcweir #include <com/sun/star/lang/IllegalArgumentException.hpp> 35*cdf0e10cSrcweir #include <com/sun/star/script/XScriptListener.hpp> 36*cdf0e10cSrcweir #include <com/sun/star/container/XHierarchicalNameAccess.hpp> 37*cdf0e10cSrcweir #include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp> 38*cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp> 39*cdf0e10cSrcweir /** === end UNO includes === **/ 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir #include <tools/diagnose_ex.h> 42*cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx> 43*cdf0e10cSrcweir #include <comphelper/implementationreference.hxx> 44*cdf0e10cSrcweir #include <comphelper/componentcontext.hxx> 45*cdf0e10cSrcweir #include <comphelper/processfactory.hxx> 46*cdf0e10cSrcweir #include <vcl/svapp.hxx> 47*cdf0e10cSrcweir #include <vos/mutex.hxx> 48*cdf0e10cSrcweir #include <sfx2/objsh.hxx> 49*cdf0e10cSrcweir #include <sfx2/app.hxx> 50*cdf0e10cSrcweir #include <basic/basmgr.hxx> 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir #include <boost/shared_ptr.hpp> 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir //........................................................................ 55*cdf0e10cSrcweir namespace svxform 56*cdf0e10cSrcweir { 57*cdf0e10cSrcweir //........................................................................ 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir /** === begin UNO using === **/ 60*cdf0e10cSrcweir using ::com::sun::star::uno::Reference; 61*cdf0e10cSrcweir using ::com::sun::star::script::XEventAttacherManager; 62*cdf0e10cSrcweir using ::com::sun::star::lang::IllegalArgumentException; 63*cdf0e10cSrcweir using ::com::sun::star::script::XScriptListener; 64*cdf0e10cSrcweir using ::com::sun::star::script::ScriptEvent; 65*cdf0e10cSrcweir using ::com::sun::star::uno::RuntimeException; 66*cdf0e10cSrcweir using ::com::sun::star::lang::EventObject; 67*cdf0e10cSrcweir using ::com::sun::star::reflection::InvocationTargetException; 68*cdf0e10cSrcweir using ::com::sun::star::uno::Any; 69*cdf0e10cSrcweir using ::com::sun::star::container::XHierarchicalNameAccess; 70*cdf0e10cSrcweir using ::com::sun::star::reflection::XInterfaceMethodTypeDescription; 71*cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY_THROW; 72*cdf0e10cSrcweir using ::com::sun::star::lang::DisposedException; 73*cdf0e10cSrcweir using ::com::sun::star::uno::RuntimeException; 74*cdf0e10cSrcweir using ::com::sun::star::uno::Exception; 75*cdf0e10cSrcweir using ::com::sun::star::uno::Sequence; 76*cdf0e10cSrcweir using ::com::sun::star::uno::XInterface; 77*cdf0e10cSrcweir /** === end UNO using === **/ 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir class FormScriptingEnvironment; 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir //==================================================================== 82*cdf0e10cSrcweir //= FormScriptListener 83*cdf0e10cSrcweir //==================================================================== 84*cdf0e10cSrcweir typedef ::cppu::WeakImplHelper1 < XScriptListener 85*cdf0e10cSrcweir > FormScriptListener_Base; 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir /** implements the XScriptListener interface, is used by FormScriptingEnvironment 88*cdf0e10cSrcweir */ 89*cdf0e10cSrcweir class FormScriptListener :public FormScriptListener_Base 90*cdf0e10cSrcweir { 91*cdf0e10cSrcweir private: 92*cdf0e10cSrcweir ::osl::Mutex m_aMutex; 93*cdf0e10cSrcweir ::rtl::Reference< FormScriptingEnvironment > m_pScriptExecutor; 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir public: 96*cdf0e10cSrcweir FormScriptListener( const ::rtl::Reference< FormScriptingEnvironment >& _pScriptExecutor ); 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir // XScriptListener 99*cdf0e10cSrcweir virtual void SAL_CALL firing( const ScriptEvent& aEvent ) throw (RuntimeException); 100*cdf0e10cSrcweir virtual Any SAL_CALL approveFiring( const ScriptEvent& aEvent ) throw (InvocationTargetException, RuntimeException); 101*cdf0e10cSrcweir // XEventListener 102*cdf0e10cSrcweir virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException); 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir // lifetime control 105*cdf0e10cSrcweir void SAL_CALL dispose(); 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir protected: 108*cdf0e10cSrcweir ~FormScriptListener(); 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir private: 111*cdf0e10cSrcweir /** determines whether calling a given method at a given listener interface can be done asynchronously 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir @param _rListenerType 114*cdf0e10cSrcweir the name of the UNO type whose method is to be checked 115*cdf0e10cSrcweir @param _rMethodName 116*cdf0e10cSrcweir the name of the method at the interface determined by _rListenerType 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir @return 119*cdf0e10cSrcweir <TRUE/> if and only if the method is declared <code>oneway</code>, i.e. can be called asynchronously 120*cdf0e10cSrcweir */ 121*cdf0e10cSrcweir bool impl_allowAsynchronousCall_nothrow( const ::rtl::OUString& _rListenerType, const ::rtl::OUString& _rMethodName ) const; 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir /** determines whether the instance is already disposed 124*cdf0e10cSrcweir */ 125*cdf0e10cSrcweir bool impl_isDisposed_nothrow() const { return !m_pScriptExecutor.is(); } 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir /** fires the given script event in a thread-safe manner 128*cdf0e10cSrcweir 129*cdf0e10cSrcweir This methods calls our script executor's doFireScriptEvent, with previously releasing the given mutex guard, 130*cdf0e10cSrcweir but ensuring that our script executor is not deleted between this release and the actual call. 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir @param _rGuard 133*cdf0e10cSrcweir a clearable guard to our mutex. Must be the only active guard to our mutex. 134*cdf0e10cSrcweir @param _rEvent 135*cdf0e10cSrcweir the event to fire 136*cdf0e10cSrcweir @param _pSyncronousResult 137*cdf0e10cSrcweir a place to take a possible result of the script call. 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir @precond 140*cdf0e10cSrcweir m_pScriptExecutor is not <NULL/>. 141*cdf0e10cSrcweir */ 142*cdf0e10cSrcweir void impl_doFireScriptEvent_nothrow( ::osl::ClearableMutexGuard& _rGuard, const ScriptEvent& _rEvent, Any* _pSyncronousResult ); 143*cdf0e10cSrcweir 144*cdf0e10cSrcweir private: 145*cdf0e10cSrcweir DECL_LINK( OnAsyncScriptEvent, ScriptEvent* ); 146*cdf0e10cSrcweir }; 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir //==================================================================== 149*cdf0e10cSrcweir //= FormScriptingEnvironment 150*cdf0e10cSrcweir //==================================================================== 151*cdf0e10cSrcweir class FormScriptingEnvironment : public IFormScriptingEnvironment 152*cdf0e10cSrcweir { 153*cdf0e10cSrcweir private: 154*cdf0e10cSrcweir typedef ::comphelper::ImplementationReference< FormScriptListener, XScriptListener > ListenerImplementation; 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir private: 157*cdf0e10cSrcweir ::osl::Mutex m_aMutex; 158*cdf0e10cSrcweir oslInterlockedCount m_refCount; 159*cdf0e10cSrcweir ListenerImplementation m_pScriptListener; 160*cdf0e10cSrcweir FmFormModel& m_rFormModel; 161*cdf0e10cSrcweir bool m_bDisposed; 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir public: 164*cdf0e10cSrcweir FormScriptingEnvironment( FmFormModel& _rModel ); 165*cdf0e10cSrcweir virtual ~FormScriptingEnvironment(); 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir // callback for FormScriptListener 168*cdf0e10cSrcweir void doFireScriptEvent( const ScriptEvent& _rEvent, Any* _pSyncronousResult ); 169*cdf0e10cSrcweir 170*cdf0e10cSrcweir // IFormScriptingEnvironment 171*cdf0e10cSrcweir virtual void registerEventAttacherManager( const Reference< XEventAttacherManager >& _rxManager ); 172*cdf0e10cSrcweir virtual void revokeEventAttacherManager( const Reference< XEventAttacherManager >& _rxManager ); 173*cdf0e10cSrcweir virtual void dispose(); 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir // IReference 176*cdf0e10cSrcweir virtual oslInterlockedCount SAL_CALL acquire(); 177*cdf0e10cSrcweir virtual oslInterlockedCount SAL_CALL release(); 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir private: 180*cdf0e10cSrcweir void impl_registerOrRevoke_throw( const Reference< XEventAttacherManager >& _rxManager, bool _bRegister ); 181*cdf0e10cSrcweir 182*cdf0e10cSrcweir private: 183*cdf0e10cSrcweir FormScriptingEnvironment(); // never implemented 184*cdf0e10cSrcweir FormScriptingEnvironment( const FormScriptingEnvironment& ); // never implemented 185*cdf0e10cSrcweir FormScriptingEnvironment& operator=( const FormScriptingEnvironment& ); // never implemented 186*cdf0e10cSrcweir }; 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir //==================================================================== 189*cdf0e10cSrcweir //= FormScriptListener 190*cdf0e10cSrcweir //==================================================================== 191*cdf0e10cSrcweir //-------------------------------------------------------------------- 192*cdf0e10cSrcweir FormScriptListener::FormScriptListener( const ::rtl::Reference< FormScriptingEnvironment >& _pScriptExecutor ) 193*cdf0e10cSrcweir :m_pScriptExecutor( _pScriptExecutor ) 194*cdf0e10cSrcweir { 195*cdf0e10cSrcweir } 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir //-------------------------------------------------------------------- 198*cdf0e10cSrcweir FormScriptListener::~FormScriptListener() 199*cdf0e10cSrcweir { 200*cdf0e10cSrcweir } 201*cdf0e10cSrcweir 202*cdf0e10cSrcweir //-------------------------------------------------------------------- 203*cdf0e10cSrcweir bool FormScriptListener::impl_allowAsynchronousCall_nothrow( const ::rtl::OUString& _rListenerType, const ::rtl::OUString& _rMethodName ) const 204*cdf0e10cSrcweir { 205*cdf0e10cSrcweir bool bAllowAsynchronousCall = false; 206*cdf0e10cSrcweir try 207*cdf0e10cSrcweir { 208*cdf0e10cSrcweir ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); 209*cdf0e10cSrcweir Reference< XHierarchicalNameAccess > xTypeDescriptions( aContext.getSingleton( "com.sun.star.reflection.theTypeDescriptionManager" ), UNO_QUERY_THROW ); 210*cdf0e10cSrcweir 211*cdf0e10cSrcweir ::rtl::OUString sMethodDescription( _rListenerType ); 212*cdf0e10cSrcweir sMethodDescription += ::rtl::OUString::createFromAscii( "::" ); 213*cdf0e10cSrcweir sMethodDescription += _rMethodName; 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir Reference< XInterfaceMethodTypeDescription > xMethod( xTypeDescriptions->getByHierarchicalName( sMethodDescription ), UNO_QUERY_THROW ); 216*cdf0e10cSrcweir bAllowAsynchronousCall = xMethod->isOneway(); 217*cdf0e10cSrcweir } 218*cdf0e10cSrcweir catch( const Exception& ) 219*cdf0e10cSrcweir { 220*cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 221*cdf0e10cSrcweir } 222*cdf0e10cSrcweir return bAllowAsynchronousCall; 223*cdf0e10cSrcweir } 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir //-------------------------------------------------------------------- 226*cdf0e10cSrcweir void FormScriptListener::impl_doFireScriptEvent_nothrow( ::osl::ClearableMutexGuard& _rGuard, const ScriptEvent& _rEvent, Any* _pSyncronousResult ) 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir OSL_PRECOND( m_pScriptExecutor.is(), "FormScriptListener::impl_doFireScriptEvent_nothrow: this will crash!" ); 229*cdf0e10cSrcweir 230*cdf0e10cSrcweir ::rtl::Reference< FormScriptingEnvironment > pExecutor( m_pScriptExecutor ); 231*cdf0e10cSrcweir _rGuard.clear(); 232*cdf0e10cSrcweir pExecutor->doFireScriptEvent( _rEvent, _pSyncronousResult ); 233*cdf0e10cSrcweir } 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir //-------------------------------------------------------------------- 236*cdf0e10cSrcweir void SAL_CALL FormScriptListener::firing( const ScriptEvent& _rEvent ) throw (RuntimeException) 237*cdf0e10cSrcweir { 238*cdf0e10cSrcweir ::osl::ClearableMutexGuard aGuard( m_aMutex ); 239*cdf0e10cSrcweir static const ::rtl::OUString vbaInterOp = 240*cdf0e10cSrcweir ::rtl::OUString::createFromAscii("VBAInterop"); 241*cdf0e10cSrcweir if ( _rEvent.ScriptType.equals(vbaInterOp) ) 242*cdf0e10cSrcweir return; // not handled here 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir if ( impl_isDisposed_nothrow() ) 245*cdf0e10cSrcweir return; 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir if ( !impl_allowAsynchronousCall_nothrow( _rEvent.ListenerType.getTypeName(), _rEvent.MethodName ) ) 248*cdf0e10cSrcweir { 249*cdf0e10cSrcweir impl_doFireScriptEvent_nothrow( aGuard, _rEvent, NULL ); 250*cdf0e10cSrcweir return; 251*cdf0e10cSrcweir } 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir acquire(); 254*cdf0e10cSrcweir Application::PostUserEvent( LINK( this, FormScriptListener, OnAsyncScriptEvent ), new ScriptEvent( _rEvent ) ); 255*cdf0e10cSrcweir } 256*cdf0e10cSrcweir 257*cdf0e10cSrcweir //-------------------------------------------------------------------- 258*cdf0e10cSrcweir Any SAL_CALL FormScriptListener::approveFiring( const ScriptEvent& _rEvent ) throw (InvocationTargetException, RuntimeException) 259*cdf0e10cSrcweir { 260*cdf0e10cSrcweir Any aResult; 261*cdf0e10cSrcweir 262*cdf0e10cSrcweir ::osl::ClearableMutexGuard aGuard( m_aMutex ); 263*cdf0e10cSrcweir if ( !impl_isDisposed_nothrow() ) 264*cdf0e10cSrcweir impl_doFireScriptEvent_nothrow( aGuard, _rEvent, &aResult ); 265*cdf0e10cSrcweir 266*cdf0e10cSrcweir return aResult; 267*cdf0e10cSrcweir } 268*cdf0e10cSrcweir 269*cdf0e10cSrcweir //-------------------------------------------------------------------- 270*cdf0e10cSrcweir void SAL_CALL FormScriptListener::disposing( const EventObject& /*Source*/ ) throw (RuntimeException) 271*cdf0e10cSrcweir { 272*cdf0e10cSrcweir // not interested in 273*cdf0e10cSrcweir } 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir //-------------------------------------------------------------------- 276*cdf0e10cSrcweir void SAL_CALL FormScriptListener::dispose() 277*cdf0e10cSrcweir { 278*cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 279*cdf0e10cSrcweir m_pScriptExecutor = NULL; 280*cdf0e10cSrcweir } 281*cdf0e10cSrcweir 282*cdf0e10cSrcweir //-------------------------------------------------------------------- 283*cdf0e10cSrcweir IMPL_LINK( FormScriptListener, OnAsyncScriptEvent, ScriptEvent*, _pEvent ) 284*cdf0e10cSrcweir { 285*cdf0e10cSrcweir OSL_PRECOND( _pEvent != NULL, "FormScriptListener::OnAsyncScriptEvent: invalid event!" ); 286*cdf0e10cSrcweir if ( !_pEvent ) 287*cdf0e10cSrcweir return 1L; 288*cdf0e10cSrcweir 289*cdf0e10cSrcweir { 290*cdf0e10cSrcweir ::osl::ClearableMutexGuard aGuard( m_aMutex ); 291*cdf0e10cSrcweir 292*cdf0e10cSrcweir if ( !impl_isDisposed_nothrow() ) 293*cdf0e10cSrcweir impl_doFireScriptEvent_nothrow( aGuard, *_pEvent, NULL ); 294*cdf0e10cSrcweir } 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir delete _pEvent; 297*cdf0e10cSrcweir // we acquired ourself immediately before posting the event 298*cdf0e10cSrcweir release(); 299*cdf0e10cSrcweir return 0L; 300*cdf0e10cSrcweir } 301*cdf0e10cSrcweir 302*cdf0e10cSrcweir //==================================================================== 303*cdf0e10cSrcweir //= FormScriptingEnvironment 304*cdf0e10cSrcweir //==================================================================== 305*cdf0e10cSrcweir //-------------------------------------------------------------------- 306*cdf0e10cSrcweir FormScriptingEnvironment::FormScriptingEnvironment( FmFormModel& _rModel ) 307*cdf0e10cSrcweir :m_refCount( 0 ) 308*cdf0e10cSrcweir ,m_pScriptListener( NULL ) 309*cdf0e10cSrcweir ,m_rFormModel( _rModel ) 310*cdf0e10cSrcweir ,m_bDisposed( false ) 311*cdf0e10cSrcweir { 312*cdf0e10cSrcweir m_pScriptListener = ListenerImplementation( new FormScriptListener( this ) ); 313*cdf0e10cSrcweir // note that this is a cyclic reference between the FormScriptListener and the FormScriptingEnvironment 314*cdf0e10cSrcweir // This cycle is broken up when our instance is disposed. 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir //-------------------------------------------------------------------- 318*cdf0e10cSrcweir FormScriptingEnvironment::~FormScriptingEnvironment() 319*cdf0e10cSrcweir { 320*cdf0e10cSrcweir } 321*cdf0e10cSrcweir 322*cdf0e10cSrcweir //-------------------------------------------------------------------- 323*cdf0e10cSrcweir void FormScriptingEnvironment::impl_registerOrRevoke_throw( const Reference< XEventAttacherManager >& _rxManager, bool _bRegister ) 324*cdf0e10cSrcweir { 325*cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 326*cdf0e10cSrcweir 327*cdf0e10cSrcweir if ( !_rxManager.is() ) 328*cdf0e10cSrcweir throw IllegalArgumentException(); 329*cdf0e10cSrcweir if ( m_bDisposed ) 330*cdf0e10cSrcweir throw DisposedException(); 331*cdf0e10cSrcweir 332*cdf0e10cSrcweir try 333*cdf0e10cSrcweir { 334*cdf0e10cSrcweir if ( _bRegister ) 335*cdf0e10cSrcweir _rxManager->addScriptListener( m_pScriptListener.getRef() ); 336*cdf0e10cSrcweir else 337*cdf0e10cSrcweir _rxManager->removeScriptListener( m_pScriptListener.getRef() ); 338*cdf0e10cSrcweir } 339*cdf0e10cSrcweir catch( const RuntimeException& ) { throw; } 340*cdf0e10cSrcweir catch( const Exception& ) 341*cdf0e10cSrcweir { 342*cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 343*cdf0e10cSrcweir } 344*cdf0e10cSrcweir } 345*cdf0e10cSrcweir 346*cdf0e10cSrcweir //-------------------------------------------------------------------- 347*cdf0e10cSrcweir void FormScriptingEnvironment::registerEventAttacherManager( const Reference< XEventAttacherManager >& _rxManager ) 348*cdf0e10cSrcweir { 349*cdf0e10cSrcweir impl_registerOrRevoke_throw( _rxManager, true ); 350*cdf0e10cSrcweir } 351*cdf0e10cSrcweir 352*cdf0e10cSrcweir //-------------------------------------------------------------------- 353*cdf0e10cSrcweir void FormScriptingEnvironment::revokeEventAttacherManager( const Reference< XEventAttacherManager >& _rxManager ) 354*cdf0e10cSrcweir { 355*cdf0e10cSrcweir impl_registerOrRevoke_throw( _rxManager, false ); 356*cdf0e10cSrcweir } 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir //-------------------------------------------------------------------- 359*cdf0e10cSrcweir oslInterlockedCount SAL_CALL FormScriptingEnvironment::acquire() 360*cdf0e10cSrcweir { 361*cdf0e10cSrcweir return osl_incrementInterlockedCount( &m_refCount ); 362*cdf0e10cSrcweir } 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir //-------------------------------------------------------------------- 365*cdf0e10cSrcweir oslInterlockedCount SAL_CALL FormScriptingEnvironment::release() 366*cdf0e10cSrcweir { 367*cdf0e10cSrcweir if ( 0 == osl_decrementInterlockedCount( &m_refCount ) ) 368*cdf0e10cSrcweir { 369*cdf0e10cSrcweir delete this; 370*cdf0e10cSrcweir return 0; 371*cdf0e10cSrcweir } 372*cdf0e10cSrcweir return m_refCount; 373*cdf0e10cSrcweir } 374*cdf0e10cSrcweir 375*cdf0e10cSrcweir //-------------------------------------------------------------------- 376*cdf0e10cSrcweir IFormScriptingEnvironment::~IFormScriptingEnvironment() 377*cdf0e10cSrcweir { 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir 380*cdf0e10cSrcweir //-------------------------------------------------------------------- 381*cdf0e10cSrcweir namespace 382*cdf0e10cSrcweir { 383*cdf0e10cSrcweir //................................................................ 384*cdf0e10cSrcweir //. NewStyleUNOScript 385*cdf0e10cSrcweir //................................................................ 386*cdf0e10cSrcweir class SAL_NO_VTABLE IScript 387*cdf0e10cSrcweir { 388*cdf0e10cSrcweir public: 389*cdf0e10cSrcweir virtual void invoke( const Sequence< Any >& _rArguments, Any& _rSynchronousResult ) = 0; 390*cdf0e10cSrcweir 391*cdf0e10cSrcweir virtual ~IScript() { } 392*cdf0e10cSrcweir }; 393*cdf0e10cSrcweir typedef ::boost::shared_ptr< IScript > PScript; 394*cdf0e10cSrcweir 395*cdf0e10cSrcweir //................................................................ 396*cdf0e10cSrcweir //. NewStyleUNOScript 397*cdf0e10cSrcweir //................................................................ 398*cdf0e10cSrcweir class NewStyleUNOScript : public IScript 399*cdf0e10cSrcweir { 400*cdf0e10cSrcweir SfxObjectShell& m_rObjectShell; 401*cdf0e10cSrcweir const ::rtl::OUString m_sScriptCode; 402*cdf0e10cSrcweir 403*cdf0e10cSrcweir public: 404*cdf0e10cSrcweir NewStyleUNOScript( SfxObjectShell& _rObjectShell, const ::rtl::OUString& _rScriptCode ) 405*cdf0e10cSrcweir :m_rObjectShell( _rObjectShell ) 406*cdf0e10cSrcweir ,m_sScriptCode( _rScriptCode ) 407*cdf0e10cSrcweir { 408*cdf0e10cSrcweir } 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir // IScript 411*cdf0e10cSrcweir virtual void invoke( const Sequence< Any >& _rArguments, Any& _rSynchronousResult ); 412*cdf0e10cSrcweir }; 413*cdf0e10cSrcweir 414*cdf0e10cSrcweir //................................................................ 415*cdf0e10cSrcweir void NewStyleUNOScript::invoke( const Sequence< Any >& _rArguments, Any& _rSynchronousResult ) 416*cdf0e10cSrcweir { 417*cdf0e10cSrcweir Sequence< sal_Int16 > aOutArgsIndex; 418*cdf0e10cSrcweir Sequence< Any > aOutArgs; 419*cdf0e10cSrcweir 420*cdf0e10cSrcweir m_rObjectShell.CallXScript( m_sScriptCode, _rArguments, _rSynchronousResult, aOutArgsIndex, aOutArgs ); 421*cdf0e10cSrcweir } 422*cdf0e10cSrcweir } 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir //-------------------------------------------------------------------- 425*cdf0e10cSrcweir void FormScriptingEnvironment::doFireScriptEvent( const ScriptEvent& _rEvent, Any* _pSyncronousResult ) 426*cdf0e10cSrcweir { 427*cdf0e10cSrcweir ::vos::OClearableGuard aSolarGuard( Application::GetSolarMutex() ); 428*cdf0e10cSrcweir ::osl::ClearableMutexGuard aGuard( m_aMutex ); 429*cdf0e10cSrcweir 430*cdf0e10cSrcweir if ( m_bDisposed ) 431*cdf0e10cSrcweir return; 432*cdf0e10cSrcweir 433*cdf0e10cSrcweir // SfxObjectShellRef is good here since the model controls the lifetime of the object 434*cdf0e10cSrcweir SfxObjectShellRef xObjectShell = m_rFormModel.GetObjectShell(); 435*cdf0e10cSrcweir if( !xObjectShell.Is() ) 436*cdf0e10cSrcweir return; 437*cdf0e10cSrcweir 438*cdf0e10cSrcweir // the script to execute 439*cdf0e10cSrcweir PScript pScript; 440*cdf0e10cSrcweir 441*cdf0e10cSrcweir if ( !_rEvent.ScriptType.equalsAscii( "StarBasic" ) ) 442*cdf0e10cSrcweir { 443*cdf0e10cSrcweir pScript.reset( new NewStyleUNOScript( *xObjectShell, _rEvent.ScriptCode ) ); 444*cdf0e10cSrcweir } 445*cdf0e10cSrcweir else 446*cdf0e10cSrcweir { 447*cdf0e10cSrcweir ::rtl::OUString sScriptCode = _rEvent.ScriptCode; 448*cdf0e10cSrcweir ::rtl::OUString sMacroLocation; 449*cdf0e10cSrcweir 450*cdf0e10cSrcweir // is there a location in the script name ("application" or "document")? 451*cdf0e10cSrcweir sal_Int32 nPrefixLen = sScriptCode.indexOf( ':' ); 452*cdf0e10cSrcweir DBG_ASSERT( 0 <= nPrefixLen, "FormScriptingEnvironment::doFireScriptEvent: Basic script name in old format encountered!" ); 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir if ( 0 <= nPrefixLen ) 455*cdf0e10cSrcweir { 456*cdf0e10cSrcweir // and it has such a prefix 457*cdf0e10cSrcweir sMacroLocation = sScriptCode.copy( 0, nPrefixLen ); 458*cdf0e10cSrcweir DBG_ASSERT( 0 == sMacroLocation.compareToAscii( "document" ) 459*cdf0e10cSrcweir || 0 == sMacroLocation.compareToAscii( "application" ), 460*cdf0e10cSrcweir "FormScriptingEnvironment::doFireScriptEvent: invalid (unknown) prefix!" ); 461*cdf0e10cSrcweir 462*cdf0e10cSrcweir // strip the prefix: the SfxObjectShell::CallScript knows nothing about such prefixes 463*cdf0e10cSrcweir sScriptCode = sScriptCode.copy( nPrefixLen + 1 ); 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir 466*cdf0e10cSrcweir if ( !sMacroLocation.getLength() ) 467*cdf0e10cSrcweir { 468*cdf0e10cSrcweir // legacy format: use the app-wide Basic, if it has a respective method, otherwise fall back to the doc's Basic 469*cdf0e10cSrcweir if ( SFX_APP()->GetBasicManager()->HasMacro( sScriptCode ) ) 470*cdf0e10cSrcweir sMacroLocation = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application" ) ); 471*cdf0e10cSrcweir else 472*cdf0e10cSrcweir sMacroLocation = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "document" ) ); 473*cdf0e10cSrcweir } 474*cdf0e10cSrcweir 475*cdf0e10cSrcweir ::rtl::OUStringBuffer aScriptURI; 476*cdf0e10cSrcweir aScriptURI.appendAscii( "vnd.sun.star.script:" ); 477*cdf0e10cSrcweir aScriptURI.append( sScriptCode ); 478*cdf0e10cSrcweir aScriptURI.appendAscii( "?language=Basic" ); 479*cdf0e10cSrcweir aScriptURI.appendAscii( "&location=" ); 480*cdf0e10cSrcweir aScriptURI.append( sMacroLocation ); 481*cdf0e10cSrcweir 482*cdf0e10cSrcweir const ::rtl::OUString sScriptURI( aScriptURI.makeStringAndClear() ); 483*cdf0e10cSrcweir pScript.reset( new NewStyleUNOScript( *xObjectShell, sScriptURI ) ); 484*cdf0e10cSrcweir } 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir OSL_ENSURE( pScript.get(), "FormScriptingEnvironment::doFireScriptEvent: no script to execute!" ); 487*cdf0e10cSrcweir if ( !pScript.get() ) 488*cdf0e10cSrcweir // this is an internal error in the above code 489*cdf0e10cSrcweir throw RuntimeException(); 490*cdf0e10cSrcweir 491*cdf0e10cSrcweir aGuard.clear(); 492*cdf0e10cSrcweir aSolarGuard.clear(); 493*cdf0e10cSrcweir 494*cdf0e10cSrcweir Any aIgnoreResult; 495*cdf0e10cSrcweir pScript->invoke( _rEvent.Arguments, _pSyncronousResult ? *_pSyncronousResult : aIgnoreResult ); 496*cdf0e10cSrcweir pScript.reset(); 497*cdf0e10cSrcweir 498*cdf0e10cSrcweir { 499*cdf0e10cSrcweir // object shells are not thread safe, so guard the destruction 500*cdf0e10cSrcweir ::vos::OGuard aSolarGuarsReset( Application::GetSolarMutex() ); 501*cdf0e10cSrcweir xObjectShell = NULL; 502*cdf0e10cSrcweir } 503*cdf0e10cSrcweir } 504*cdf0e10cSrcweir 505*cdf0e10cSrcweir //-------------------------------------------------------------------- 506*cdf0e10cSrcweir void FormScriptingEnvironment::dispose() 507*cdf0e10cSrcweir { 508*cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 509*cdf0e10cSrcweir m_bDisposed = true; 510*cdf0e10cSrcweir m_pScriptListener->dispose(); 511*cdf0e10cSrcweir } 512*cdf0e10cSrcweir 513*cdf0e10cSrcweir //-------------------------------------------------------------------- 514*cdf0e10cSrcweir PFormScriptingEnvironment createDefaultFormScriptingEnvironment( FmFormModel& _rModel ) 515*cdf0e10cSrcweir { 516*cdf0e10cSrcweir return new FormScriptingEnvironment( _rModel ); 517*cdf0e10cSrcweir } 518*cdf0e10cSrcweir 519*cdf0e10cSrcweir //........................................................................ 520*cdf0e10cSrcweir } // namespace svxform 521*cdf0e10cSrcweir //........................................................................ 522*cdf0e10cSrcweir 523