[Libreoffice-commits] core.git: extensions/source stoc/source

Tor Lillqvist tml at collabora.com
Wed May 30 06:27:13 UTC 2018


 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 <tml at 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 <ci at libreoffice.org>
    Reviewed-by: Tor Lillqvist <tml at 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


More information about the Libreoffice-commits mailing list