extensions/source/ole/unoconversionutilities.hxx | 22 ++++------ stoc/source/invocation/invocation.cxx | 48 +++++++++++++++-------- 2 files changed, 42 insertions(+), 28 deletions(-)
New commits: commit 7873bba6c1e5de580ef28d0ecf68d154dd57e726 Author: Tor Lillqvist <t...@collabora.com> Date: Wed Feb 14 22:17:57 2018 +0200 Hack to make properties work better from Automation clients There were a couple of problems apparent at this stage when using the ooovbaapi things from a test Automation client (written in VBScript, to be precise). Accessing for instance the ActiveDocument property of an ooo::vba::word::XGlobals instance worked fine. But properties of other objects, like instances of ooo::vba::word::XDocument, did not work. When attempting to access any property of an ooo::vba::word::XDocument, the code ended up calling the hasProperty() of SwVbaDocuemnt. That function is for checking a totally different kind of "properties", namely named form controls. Why form controls are con-fused with oovbaapi properties I don't know. Maybe it is intentional and as expected when using the oovbaapi from the built-in Basic interpreter in LibreOffice. Or then just an accident in history. Still, surely it can't be changed, that would break Basic scripts embedded in existing ODF documents. Anyway, from an OLE Automation client, for instance when asking for the Content property of an ooo::vba::word::XDocument object, we definitely don't want any form control that happens to have the name "Content". We want an object with two integer properties, Start and End. Make this work by always creating an invocation factory instead of using the object itself. Pass the invocation factory's createInstanceWithArguments() function an extra argument indicating this is the case of use from OLE Automation. In the Invocation_Impl class in the stoc module, when this extra argument is noticed, set a new mbFromOLE flag. Modify the behaviour slightly when that is true. I am not at all sure that this will work in all cases, but let's see, at least for simple tests so far it had the intended effect. Another issue was that looking up these properties was case sensitive. This is wrong at least from languages like VBScript. Use the mbFromOLE flag also to affect the case sensitivity behaviour. Maybe I should simply make sure that _xDirect is null in the Automation case? _Direct (a reference to an XInvocation) being non-null probably means that we are using the document interface's own implementation of XInvocation, which is probably always wrong in the OLE Automation case. (Just see the SwVbaDocument implementations of hasProperty() and invoke(), for instance.) Change-Id: I2fd174f69f430893aef538cc9bf2a99d1c86b567 Reviewed-on: https://gerrit.libreoffice.org/55023 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Tor Lillqvist <t...@collabora.com> diff --git a/extensions/source/ole/unoconversionutilities.hxx b/extensions/source/ole/unoconversionutilities.hxx index 9b88ce681d80..f0ef703bd845 100644 --- a/extensions/source/ole/unoconversionutilities.hxx +++ b/extensions/source/ole/unoconversionutilities.hxx @@ -1388,20 +1388,18 @@ void UnoConversionUtilities<T>::createUnoObjectWrapper(const Any & rObj, VARIANT } } // If we have no UNO wrapper nor the IDispatch yet then we have to create - // a wrapper. For that we need an XInvocation from the UNO object. + // a wrapper. For that we need an XInvocation. - // get an XInvocation or create one using the invocation service - Reference<XInvocation> xInv(xInt, UNO_QUERY); - if ( ! xInv.is()) + // create an XInvocation using the invocation service + Reference<XInvocation> xInv; + Reference<XSingleServiceFactory> xInvFactory= getInvocationFactory(rObj); + if (xInvFactory.is()) { - Reference<XSingleServiceFactory> xInvFactory= getInvocationFactory(rObj); - if (xInvFactory.is()) - { - Sequence<Any> params(1); - params.getArray()[0] = rObj; - Reference<XInterface> xInt2 = xInvFactory->createInstanceWithArguments(params); - xInv.set(xInt2, UNO_QUERY); - } + Sequence<Any> params(2); + params.getArray()[0] = rObj; + params.getArray()[1] = makeAny(OUString("FromOLE")); + Reference<XInterface> xInt2 = xInvFactory->createInstanceWithArguments(params); + xInv.set(xInt2, UNO_QUERY); } if (xInv.is()) diff --git a/stoc/source/invocation/invocation.cxx b/stoc/source/invocation/invocation.cxx index 1e4e54b297d5..830ad61e33a6 100644 --- a/stoc/source/invocation/invocation.cxx +++ b/stoc/source/invocation/invocation.cxx @@ -99,7 +99,8 @@ class Invocation_Impl public: Invocation_Impl( const Any & rAdapted, const Reference<XTypeConverter> &, const Reference<XIntrospection> &, - const Reference<XIdlReflection> & ); + const Reference<XIdlReflection> &, + bool bFromOLE ); // XInterface virtual Any SAL_CALL queryInterface( const Type & aType) override; @@ -213,6 +214,8 @@ private: Reference<XExactName> _xENDirect, _xENIntrospection; + + bool mbFromOLE; }; @@ -221,11 +224,13 @@ Invocation_Impl::Invocation_Impl const Any & rAdapted, const Reference<XTypeConverter> & rTC, const Reference<XIntrospection> & rI, - const Reference<XIdlReflection> & rCR + const Reference<XIdlReflection> & rCR, + bool bFromOLE ) : xTypeConverter( rTC ) , xIntrospection( rI ) , xCoreReflection( rCR ) + , mbFromOLE( bFromOLE ) { setMaterial( rAdapted ); } @@ -248,8 +253,9 @@ Any SAL_CALL Invocation_Impl::queryInterface( const Type & aType ) if( aType == cppu::UnoType<XExactName>::get()) { // Invocation does not support XExactName, if direct object supports - // XInvocation, but not XExactName. - if ((_xDirect.is() && _xENDirect.is()) || + // XInvocation, but not XExactName. Except when called from OLE Automation. + if (mbFromOLE || + (_xDirect.is() && _xENDirect.is()) || (!_xDirect.is() && _xENIntrospection.is())) { return makeAny( Reference< XExactName >( static_cast< XExactName* >(this) ) ); @@ -302,7 +308,8 @@ Any SAL_CALL Invocation_Impl::queryInterface( const Type & aType ) { // Invocation does not support XInvocation2, if direct object supports // XInvocation, but not XInvocation2. - if ( ( _xDirect.is() && _xDirect2.is()) || + if ( mbFromOLE || + ( _xDirect.is() && _xDirect2.is()) || (!_xDirect.is() && _xIntrospectionAccess.is() ) ) { return makeAny( Reference< XInvocation2 >( static_cast< XInvocation2* >(this) ) ); @@ -345,7 +352,7 @@ void Invocation_Impl::setMaterial( const Any& rMaterial ) // First do this outside the guard _xDirect.set( rMaterial, UNO_QUERY ); - if( _xDirect.is() ) + if( !mbFromOLE && _xDirect.is() ) { // Consult object directly _xElementAccess.set( _xDirect, UNO_QUERY ); @@ -441,7 +448,7 @@ Reference<XIntrospectionAccess> Invocation_Impl::getIntrospection() sal_Bool Invocation_Impl::hasMethod( const OUString& Name ) { - if (_xDirect.is()) + if (!mbFromOLE && _xDirect.is()) return _xDirect->hasMethod( Name ); if( _xIntrospectionAccess.is() ) return _xIntrospectionAccess->hasMethod( Name, MethodConcept::ALL ^ MethodConcept::DANGEROUS ); @@ -451,7 +458,7 @@ sal_Bool Invocation_Impl::hasMethod( const OUString& Name ) sal_Bool Invocation_Impl::hasProperty( const OUString& Name ) { - if (_xDirect.is()) + if (!mbFromOLE && _xDirect.is()) return _xDirect->hasProperty( Name ); // PropertySet if( _xIntrospectionAccess.is() @@ -466,7 +473,7 @@ sal_Bool Invocation_Impl::hasProperty( const OUString& Name ) Any Invocation_Impl::getValue( const OUString& PropertyName ) { - if (_xDirect.is()) + if (!mbFromOLE && _xDirect.is()) return _xDirect->getValue( PropertyName ); try { @@ -575,7 +582,7 @@ void Invocation_Impl::setValue( const OUString& PropertyName, const Any& Value ) Any Invocation_Impl::invoke( const OUString& FunctionName, const Sequence<Any>& InParams, Sequence<sal_Int16>& OutIndices, Sequence<Any>& OutParams ) { - if (_xDirect.is()) + if (!mbFromOLE && _xDirect.is()) return _xDirect->invoke( FunctionName, InParams, OutIndices, OutParams ); if (_xIntrospectionAccess.is()) @@ -1084,17 +1091,26 @@ Reference<XInterface> InvocationService::createInstance() Reference<XInterface> InvocationService::createInstanceWithArguments( const Sequence<Any>& rArguments ) { + if (rArguments.getLength() == 2) + { + OUString aArg1; + if ((rArguments[1] >>= aArg1) && + aArg1 == "FromOLE") + { + return Reference< XInterface > + ( *new Invocation_Impl( *rArguments.getConstArray(), + xTypeConverter, xIntrospection, xCoreReflection, true ) ); + } + } if (rArguments.getLength() == 1) { return Reference< XInterface > ( *new Invocation_Impl( *rArguments.getConstArray(), - xTypeConverter, xIntrospection, xCoreReflection ) ); - } - else - { - //TODO:throw( Exception("no default construction of invocation adapter possible!", *this) ); - return Reference<XInterface>(); + xTypeConverter, xIntrospection, xCoreReflection, false ) ); } + + //TODO:throw( Exception("no default construction of invocation adapter possible!", *this) ); + return Reference<XInterface>(); } /// @throws RuntimeException _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits