1*2c696243SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*2c696243SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*2c696243SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*2c696243SAndrew Rist * distributed with this work for additional information 6*2c696243SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*2c696243SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*2c696243SAndrew Rist * "License"); you may not use this file except in compliance 9*2c696243SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*2c696243SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*2c696243SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*2c696243SAndrew Rist * software distributed under the License is distributed on an 15*2c696243SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*2c696243SAndrew Rist * KIND, either express or implied. See the License for the 17*2c696243SAndrew Rist * specific language governing permissions and limitations 18*2c696243SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*2c696243SAndrew Rist *************************************************************/ 21*2c696243SAndrew Rist 22*2c696243SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_scripting.hxx" 26cdf0e10cSrcweir #include "basscript.hxx" 27cdf0e10cSrcweir #include <vos/mutex.hxx> 28cdf0e10cSrcweir #include <vcl/svapp.hxx> 29cdf0e10cSrcweir #include <basic/sbx.hxx> 30cdf0e10cSrcweir #include <basic/sbstar.hxx> 31cdf0e10cSrcweir #include <basic/sbmod.hxx> 32cdf0e10cSrcweir #include <basic/sbmeth.hxx> 33cdf0e10cSrcweir #include <basic/basmgr.hxx> 34cdf0e10cSrcweir #include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp> 35cdf0e10cSrcweir 36cdf0e10cSrcweir #include <map> 37cdf0e10cSrcweir 38cdf0e10cSrcweir 39cdf0e10cSrcweir using namespace ::com::sun::star; 40cdf0e10cSrcweir using namespace ::com::sun::star::lang; 41cdf0e10cSrcweir using namespace ::com::sun::star::uno; 42cdf0e10cSrcweir using namespace ::com::sun::star::script; 43cdf0e10cSrcweir using namespace ::com::sun::star::document; 44cdf0e10cSrcweir 45cdf0e10cSrcweir extern ::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar ); 46cdf0e10cSrcweir extern void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue ); 47cdf0e10cSrcweir 48cdf0e10cSrcweir 49cdf0e10cSrcweir //......................................................................... 50cdf0e10cSrcweir namespace basprov 51cdf0e10cSrcweir { 52cdf0e10cSrcweir //......................................................................... 53cdf0e10cSrcweir 54cdf0e10cSrcweir typedef ::std::map< sal_Int16, Any, ::std::less< sal_Int16 > > OutParamMap; 55cdf0e10cSrcweir 56cdf0e10cSrcweir // ============================================================================= 57cdf0e10cSrcweir // BasicScriptImpl 58cdf0e10cSrcweir // ============================================================================= 59cdf0e10cSrcweir 60cdf0e10cSrcweir // ----------------------------------------------------------------------------- 61cdf0e10cSrcweir BasicScriptImpl(const::rtl::OUString & funcName,SbMethodRef xMethod)62cdf0e10cSrcweir BasicScriptImpl::BasicScriptImpl( const ::rtl::OUString& funcName, SbMethodRef xMethod ) 63cdf0e10cSrcweir :m_xMethod( xMethod ) 64cdf0e10cSrcweir ,m_funcName( funcName ) 65cdf0e10cSrcweir ,m_documentBasicManager( NULL ) 66cdf0e10cSrcweir ,m_xDocumentScriptContext() 67cdf0e10cSrcweir { 68cdf0e10cSrcweir } 69cdf0e10cSrcweir 70cdf0e10cSrcweir // ----------------------------------------------------------------------------- 71cdf0e10cSrcweir BasicScriptImpl(const::rtl::OUString & funcName,SbMethodRef xMethod,BasicManager & documentBasicManager,const Reference<XScriptInvocationContext> & documentScriptContext)72cdf0e10cSrcweir BasicScriptImpl::BasicScriptImpl( const ::rtl::OUString& funcName, SbMethodRef xMethod, 73cdf0e10cSrcweir BasicManager& documentBasicManager, const Reference< XScriptInvocationContext >& documentScriptContext ) 74cdf0e10cSrcweir :m_xMethod( xMethod ) 75cdf0e10cSrcweir ,m_funcName( funcName ) 76cdf0e10cSrcweir ,m_documentBasicManager( &documentBasicManager ) 77cdf0e10cSrcweir ,m_xDocumentScriptContext( documentScriptContext ) 78cdf0e10cSrcweir { 79cdf0e10cSrcweir StartListening( *m_documentBasicManager ); 80cdf0e10cSrcweir } 81cdf0e10cSrcweir 82cdf0e10cSrcweir // ----------------------------------------------------------------------------- ~BasicScriptImpl()83cdf0e10cSrcweir BasicScriptImpl::~BasicScriptImpl() 84cdf0e10cSrcweir { 85cdf0e10cSrcweir if ( m_documentBasicManager ) 86cdf0e10cSrcweir EndListening( *m_documentBasicManager ); 87cdf0e10cSrcweir } 88cdf0e10cSrcweir 89cdf0e10cSrcweir // ----------------------------------------------------------------------------- 90cdf0e10cSrcweir // SfxListener 91cdf0e10cSrcweir // ----------------------------------------------------------------------------- Notify(SfxBroadcaster & rBC,const SfxHint & rHint)92cdf0e10cSrcweir void BasicScriptImpl::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) 93cdf0e10cSrcweir { 94cdf0e10cSrcweir if ( &rBC != m_documentBasicManager ) 95cdf0e10cSrcweir { 96cdf0e10cSrcweir OSL_ENSURE( false, "BasicScriptImpl::Notify: where does this come from?" ); 97cdf0e10cSrcweir // not interested in 98cdf0e10cSrcweir return; 99cdf0e10cSrcweir } 100cdf0e10cSrcweir const SfxSimpleHint* pSimpleHint = PTR_CAST( SfxSimpleHint, &rHint ); 101cdf0e10cSrcweir if ( pSimpleHint && ( pSimpleHint->GetId() == SFX_HINT_DYING ) ) 102cdf0e10cSrcweir { 103cdf0e10cSrcweir m_documentBasicManager = NULL; 104cdf0e10cSrcweir EndListening( rBC ); // prevent multiple notifications 105cdf0e10cSrcweir } 106cdf0e10cSrcweir } 107cdf0e10cSrcweir 108cdf0e10cSrcweir // ----------------------------------------------------------------------------- 109cdf0e10cSrcweir // XScript 110cdf0e10cSrcweir // ----------------------------------------------------------------------------- 111cdf0e10cSrcweir invoke(const Sequence<Any> & aParams,Sequence<sal_Int16> & aOutParamIndex,Sequence<Any> & aOutParam)112cdf0e10cSrcweir Any BasicScriptImpl::invoke( const Sequence< Any >& aParams, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) 113cdf0e10cSrcweir throw ( provider::ScriptFrameworkErrorException, reflection::InvocationTargetException, uno::RuntimeException) 114cdf0e10cSrcweir { 115cdf0e10cSrcweir // TODO: throw CannotConvertException 116cdf0e10cSrcweir // TODO: check length of aOutParamIndex, aOutParam 117cdf0e10cSrcweir 118cdf0e10cSrcweir ::vos::OGuard aGuard( Application::GetSolarMutex() ); 119cdf0e10cSrcweir 120cdf0e10cSrcweir Any aReturn; 121cdf0e10cSrcweir 122cdf0e10cSrcweir if ( m_xMethod ) 123cdf0e10cSrcweir { 124cdf0e10cSrcweir // check if compiled 125cdf0e10cSrcweir SbModule* pModule = static_cast< SbModule* >( m_xMethod->GetParent() ); 126cdf0e10cSrcweir if ( pModule && !pModule->IsCompiled() ) 127cdf0e10cSrcweir pModule->Compile(); 128cdf0e10cSrcweir 129cdf0e10cSrcweir // check number of parameters 130cdf0e10cSrcweir sal_Int32 nParamsCount = aParams.getLength(); 131cdf0e10cSrcweir SbxInfo* pInfo = m_xMethod->GetInfo(); 132cdf0e10cSrcweir if ( pInfo ) 133cdf0e10cSrcweir { 134cdf0e10cSrcweir sal_Int32 nSbxOptional = 0; 135cdf0e10cSrcweir sal_uInt16 n = 1; 136cdf0e10cSrcweir for ( const SbxParamInfo* pParamInfo = pInfo->GetParam( n ); pParamInfo; pParamInfo = pInfo->GetParam( ++n ) ) 137cdf0e10cSrcweir { 138cdf0e10cSrcweir if ( ( pParamInfo->nFlags & SBX_OPTIONAL ) != 0 ) 139cdf0e10cSrcweir ++nSbxOptional; 140cdf0e10cSrcweir else 141cdf0e10cSrcweir nSbxOptional = 0; 142cdf0e10cSrcweir } 143cdf0e10cSrcweir sal_Int32 nSbxCount = n - 1; 144cdf0e10cSrcweir if ( nParamsCount < nSbxCount - nSbxOptional ) 145cdf0e10cSrcweir { 146cdf0e10cSrcweir throw provider::ScriptFrameworkErrorException( 147cdf0e10cSrcweir ::rtl::OUString( 148cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 149cdf0e10cSrcweir "wrong number of parameters!" ) ), 150cdf0e10cSrcweir Reference< XInterface >(), 151cdf0e10cSrcweir m_funcName, 152cdf0e10cSrcweir ::rtl::OUString( 153cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( "Basic" ) ), 154cdf0e10cSrcweir provider::ScriptFrameworkErrorType::NO_SUCH_SCRIPT ); 155cdf0e10cSrcweir } 156cdf0e10cSrcweir } 157cdf0e10cSrcweir 158cdf0e10cSrcweir // set parameters 159cdf0e10cSrcweir SbxArrayRef xSbxParams; 160cdf0e10cSrcweir if ( nParamsCount > 0 ) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir xSbxParams = new SbxArray; 163cdf0e10cSrcweir const Any* pParams = aParams.getConstArray(); 164cdf0e10cSrcweir for ( sal_Int32 i = 0; i < nParamsCount; ++i ) 165cdf0e10cSrcweir { 166cdf0e10cSrcweir SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT ); 167cdf0e10cSrcweir unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), pParams[i] ); 168cdf0e10cSrcweir xSbxParams->Put( xSbxVar, static_cast< sal_uInt16 >( i ) + 1 ); 169cdf0e10cSrcweir 170cdf0e10cSrcweir // Enable passing by ref 171cdf0e10cSrcweir if ( xSbxVar->GetType() != SbxVARIANT ) 172cdf0e10cSrcweir xSbxVar->SetFlag( SBX_FIXED ); 173cdf0e10cSrcweir } 174cdf0e10cSrcweir } 175cdf0e10cSrcweir if ( xSbxParams.Is() ) 176cdf0e10cSrcweir m_xMethod->SetParameters( xSbxParams ); 177cdf0e10cSrcweir 178cdf0e10cSrcweir // call method 179cdf0e10cSrcweir SbxVariableRef xReturn = new SbxVariable; 180cdf0e10cSrcweir ErrCode nErr = SbxERR_OK; 181cdf0e10cSrcweir { 182cdf0e10cSrcweir // if it's a document-based script, temporarily reset ThisComponent to the script invocation context 183cdf0e10cSrcweir Any aOldThisComponent; 184cdf0e10cSrcweir if ( m_documentBasicManager && m_xDocumentScriptContext.is() ) 185cdf0e10cSrcweir aOldThisComponent = m_documentBasicManager->SetGlobalUNOConstant( "ThisComponent", makeAny( m_xDocumentScriptContext ) ); 186cdf0e10cSrcweir 187cdf0e10cSrcweir nErr = m_xMethod->Call( xReturn ); 188cdf0e10cSrcweir 189cdf0e10cSrcweir if ( m_documentBasicManager && m_xDocumentScriptContext.is() ) 190cdf0e10cSrcweir m_documentBasicManager->SetGlobalUNOConstant( "ThisComponent", aOldThisComponent ); 191cdf0e10cSrcweir } 192cdf0e10cSrcweir if ( nErr != SbxERR_OK ) 193cdf0e10cSrcweir { 194cdf0e10cSrcweir // TODO: throw InvocationTargetException ? 195cdf0e10cSrcweir } 196cdf0e10cSrcweir 197cdf0e10cSrcweir // get output parameters 198cdf0e10cSrcweir if ( xSbxParams.Is() ) 199cdf0e10cSrcweir { 200cdf0e10cSrcweir SbxInfo* pInfo_ = m_xMethod->GetInfo(); 201cdf0e10cSrcweir if ( pInfo_ ) 202cdf0e10cSrcweir { 203cdf0e10cSrcweir OutParamMap aOutParamMap; 204cdf0e10cSrcweir for ( sal_uInt16 n = 1, nCount = xSbxParams->Count(); n < nCount; ++n ) 205cdf0e10cSrcweir { 206cdf0e10cSrcweir const SbxParamInfo* pParamInfo = pInfo_->GetParam( n ); 207cdf0e10cSrcweir if ( pParamInfo && ( pParamInfo->eType & SbxBYREF ) != 0 ) 208cdf0e10cSrcweir { 209cdf0e10cSrcweir SbxVariable* pVar = xSbxParams->Get( n ); 210cdf0e10cSrcweir if ( pVar ) 211cdf0e10cSrcweir { 212cdf0e10cSrcweir SbxVariableRef xVar = pVar; 213cdf0e10cSrcweir aOutParamMap.insert( OutParamMap::value_type( n - 1, sbxToUnoValue( xVar ) ) ); 214cdf0e10cSrcweir } 215cdf0e10cSrcweir } 216cdf0e10cSrcweir } 217cdf0e10cSrcweir sal_Int32 nOutParamCount = aOutParamMap.size(); 218cdf0e10cSrcweir aOutParamIndex.realloc( nOutParamCount ); 219cdf0e10cSrcweir aOutParam.realloc( nOutParamCount ); 220cdf0e10cSrcweir sal_Int16* pOutParamIndex = aOutParamIndex.getArray(); 221cdf0e10cSrcweir Any* pOutParam = aOutParam.getArray(); 222cdf0e10cSrcweir for ( OutParamMap::iterator aIt = aOutParamMap.begin(); aIt != aOutParamMap.end(); ++aIt, ++pOutParamIndex, ++pOutParam ) 223cdf0e10cSrcweir { 224cdf0e10cSrcweir *pOutParamIndex = aIt->first; 225cdf0e10cSrcweir *pOutParam = aIt->second; 226cdf0e10cSrcweir } 227cdf0e10cSrcweir } 228cdf0e10cSrcweir } 229cdf0e10cSrcweir 230cdf0e10cSrcweir // get return value 231cdf0e10cSrcweir aReturn = sbxToUnoValue( xReturn ); 232cdf0e10cSrcweir 233cdf0e10cSrcweir // reset parameters 234cdf0e10cSrcweir m_xMethod->SetParameters( NULL ); 235cdf0e10cSrcweir } 236cdf0e10cSrcweir 237cdf0e10cSrcweir return aReturn; 238cdf0e10cSrcweir } 239cdf0e10cSrcweir 240cdf0e10cSrcweir // ----------------------------------------------------------------------------- 241cdf0e10cSrcweir 242cdf0e10cSrcweir //......................................................................... 243cdf0e10cSrcweir } // namespace basprov 244cdf0e10cSrcweir //......................................................................... 245