2010-10-14 08:30:07 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-06-28 21:09:53 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*
|
|
|
|
* This file incorporates work covered by the following license notice:
|
|
|
|
*
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
|
|
* with this work for additional information regarding copyright
|
|
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
|
|
* License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
|
|
|
|
*/
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
#include <osl/mutex.hxx>
|
|
|
|
#include <cppuhelper/queryinterface.hxx>
|
2018-05-24 15:47:30 +02:00
|
|
|
#include <cppuhelper/exc_hlp.hxx>
|
2000-09-18 14:29:57 +00:00
|
|
|
#include <cppuhelper/weak.hxx>
|
|
|
|
#include <cppuhelper/factory.hxx>
|
2001-06-22 15:21:02 +00:00
|
|
|
#include <cppuhelper/implementationentry.hxx>
|
2013-10-21 19:04:05 -02:00
|
|
|
#include <cppuhelper/supportsservice.hxx>
|
2000-09-18 14:29:57 +00:00
|
|
|
#include <cppuhelper/typeprovider.hxx>
|
2015-09-04 20:40:13 +09:00
|
|
|
#include <cppuhelper/implbase.hxx>
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2017-02-06 17:08:38 +01:00
|
|
|
#include <com/sun/star/script/CannotConvertException.hpp>
|
2000-09-18 14:29:57 +00:00
|
|
|
#include <com/sun/star/script/XTypeConverter.hpp>
|
|
|
|
#include <com/sun/star/script/XInvocation.hpp>
|
|
|
|
#include <com/sun/star/script/XInvocation2.hpp>
|
|
|
|
#include <com/sun/star/reflection/XIdlReflection.hpp>
|
2014-02-07 12:03:03 +01:00
|
|
|
#include <com/sun/star/reflection/theCoreReflection.hpp>
|
2000-09-18 14:29:57 +00:00
|
|
|
#include <com/sun/star/container/XNameContainer.hpp>
|
|
|
|
#include <com/sun/star/container/XIndexContainer.hpp>
|
|
|
|
#include <com/sun/star/container/XEnumerationAccess.hpp>
|
|
|
|
#include <com/sun/star/beans/XExactName.hpp>
|
|
|
|
#include <com/sun/star/beans/XMaterialHolder.hpp>
|
2014-03-07 10:31:07 +01:00
|
|
|
#include <com/sun/star/beans/theIntrospection.hpp>
|
2000-09-18 14:29:57 +00:00
|
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
|
|
#include <com/sun/star/beans/PropertyAttribute.hpp>
|
|
|
|
#include <com/sun/star/beans/MethodConcept.hpp>
|
|
|
|
#include <com/sun/star/beans/PropertyConcept.hpp>
|
|
|
|
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
|
|
|
|
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
|
|
|
|
#include <com/sun/star/lang/XServiceInfo.hpp>
|
|
|
|
#include <com/sun/star/lang/XTypeProvider.hpp>
|
|
|
|
#include <com/sun/star/registry/XRegistryKey.hpp>
|
|
|
|
|
2015-06-15 17:58:15 +09:00
|
|
|
#include <memory>
|
2000-09-18 14:29:57 +00:00
|
|
|
#include <rtl/ustrbuf.hxx>
|
|
|
|
#include <rtl/strbuf.hxx>
|
|
|
|
|
2001-06-22 15:21:02 +00:00
|
|
|
#define SERVICENAME "com.sun.star.script.Invocation"
|
|
|
|
#define IMPLNAME "com.sun.star.comp.stoc.Invocation"
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2014-05-22 08:45:37 +02:00
|
|
|
using namespace css::uno;
|
|
|
|
using namespace css::lang;
|
|
|
|
using namespace css::script;
|
|
|
|
using namespace css::reflection;
|
|
|
|
using namespace css::beans;
|
|
|
|
using namespace css::registry;
|
|
|
|
using namespace css::container;
|
2000-09-18 14:29:57 +00:00
|
|
|
using namespace cppu;
|
|
|
|
using namespace osl;
|
|
|
|
|
|
|
|
namespace stoc_inv
|
|
|
|
{
|
2001-06-22 15:21:02 +00:00
|
|
|
static Sequence< OUString > inv_getSupportedServiceNames()
|
|
|
|
{
|
2015-11-15 08:43:35 +02:00
|
|
|
Sequence< OUString > seqNames { SERVICENAME };
|
2011-06-01 15:34:41 +01:00
|
|
|
return seqNames;
|
2001-06-22 15:21:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static OUString inv_getImplementationName()
|
|
|
|
{
|
2013-05-06 16:32:22 +02:00
|
|
|
return OUString(IMPLNAME);
|
2001-06-22 15:21:02 +00:00
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2015-07-16 13:37:15 +08:00
|
|
|
// TODO: Implement centrally
|
2000-09-18 14:29:57 +00:00
|
|
|
inline Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XIdlReflection > & xRefl )
|
|
|
|
{
|
|
|
|
return xRefl->forName( rType.getTypeName() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class Invocation_Impl
|
|
|
|
: public OWeakObject
|
|
|
|
, public XInvocation2
|
|
|
|
, public XNameContainer
|
|
|
|
, public XIndexContainer
|
|
|
|
, public XEnumerationAccess
|
|
|
|
, public XExactName
|
|
|
|
, public XMaterialHolder
|
|
|
|
, public XTypeProvider
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Invocation_Impl( const Any & rAdapted, const Reference<XTypeConverter> &,
|
|
|
|
const Reference<XIntrospection> &,
|
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@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
2018-02-14 22:17:57 +02:00
|
|
|
const Reference<XIdlReflection> &,
|
|
|
|
bool bFromOLE );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
// XInterface
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual Any SAL_CALL queryInterface( const Type & aType) override;
|
2015-10-12 16:04:04 +02:00
|
|
|
virtual void SAL_CALL acquire() throw() override { OWeakObject::acquire(); }
|
|
|
|
virtual void SAL_CALL release() throw() override { OWeakObject::release(); }
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
// XTypeProvider
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual Sequence< css::uno::Type > SAL_CALL getTypes( ) override;
|
|
|
|
virtual Sequence< sal_Int8 > SAL_CALL getImplementationId( ) override;
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2015-07-16 13:37:15 +08:00
|
|
|
// XMaterialHolder
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual Any SAL_CALL getMaterial() override;
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
// XInvocation
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual Reference<XIntrospectionAccess> SAL_CALL getIntrospection() override;
|
|
|
|
virtual Any SAL_CALL invoke(const OUString& FunctionName, const Sequence< Any >& Params, Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam) override;
|
|
|
|
virtual void SAL_CALL setValue(const OUString& PropertyName, const Any& Value) override;
|
|
|
|
virtual Any SAL_CALL getValue(const OUString& PropertyName) override;
|
|
|
|
virtual sal_Bool SAL_CALL hasMethod(const OUString& Name) override;
|
|
|
|
virtual sal_Bool SAL_CALL hasProperty(const OUString& Name) override;
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
// XInvocation2
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual Sequence< OUString > SAL_CALL getMemberNames( ) override;
|
|
|
|
virtual Sequence< InvocationInfo > SAL_CALL getInfo( ) override;
|
|
|
|
virtual InvocationInfo SAL_CALL getInfoForName( const OUString& aName, sal_Bool bExact ) override;
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2015-07-16 13:37:15 +08:00
|
|
|
// All Access and Container methods are not thread safe
|
2000-09-18 14:29:57 +00:00
|
|
|
// XElementAccess
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual Type SAL_CALL getElementType() override
|
2000-09-18 14:29:57 +00:00
|
|
|
{ return _xElementAccess->getElementType(); }
|
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual sal_Bool SAL_CALL hasElements() override
|
2000-09-18 14:29:57 +00:00
|
|
|
{ return _xElementAccess->hasElements(); }
|
|
|
|
|
|
|
|
// XNameContainer
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual void SAL_CALL insertByName( const OUString& Name, const Any& Element ) override
|
2000-09-18 14:29:57 +00:00
|
|
|
{ _xNameContainer->insertByName( Name, Element ); }
|
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual void SAL_CALL removeByName( const OUString& Name ) override
|
2000-09-18 14:29:57 +00:00
|
|
|
{ _xNameContainer->removeByName( Name ); }
|
|
|
|
|
2015-07-23 11:36:38 +08:00
|
|
|
// XNameReplace
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual void SAL_CALL replaceByName( const OUString& Name, const Any& Element ) override
|
2015-07-23 11:36:38 +08:00
|
|
|
{ _xNameReplace->replaceByName( Name, Element ); }
|
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
// XNameAccess
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual Any SAL_CALL getByName( const OUString& Name ) override
|
2000-09-18 14:29:57 +00:00
|
|
|
{ return _xNameAccess->getByName( Name ); }
|
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual Sequence<OUString> SAL_CALL getElementNames() override
|
2000-09-18 14:29:57 +00:00
|
|
|
{ return _xNameAccess->getElementNames(); }
|
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual sal_Bool SAL_CALL hasByName( const OUString& Name ) override
|
2000-09-18 14:29:57 +00:00
|
|
|
{ return _xNameAccess->hasByName( Name ); }
|
|
|
|
|
|
|
|
// XIndexContainer
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual void SAL_CALL insertByIndex( sal_Int32 Index, const Any& Element ) override
|
2000-09-18 14:29:57 +00:00
|
|
|
{ _xIndexContainer->insertByIndex( Index, Element ); }
|
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual void SAL_CALL removeByIndex( sal_Int32 Index ) override
|
2000-09-18 14:29:57 +00:00
|
|
|
{ _xIndexContainer->removeByIndex( Index ); }
|
|
|
|
|
2015-07-23 11:36:38 +08:00
|
|
|
// XIndexReplace
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const Any& Element ) override
|
2015-07-23 11:36:38 +08:00
|
|
|
{ _xIndexReplace->replaceByIndex( Index, Element ); }
|
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
// XIndexAccess
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual sal_Int32 SAL_CALL getCount() override
|
2000-09-18 14:29:57 +00:00
|
|
|
{ return _xIndexAccess->getCount(); }
|
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual Any SAL_CALL getByIndex( sal_Int32 Index ) override
|
2000-09-18 14:29:57 +00:00
|
|
|
{ return _xIndexAccess->getByIndex( Index ); }
|
|
|
|
|
|
|
|
// XEnumerationAccess
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual Reference<XEnumeration> SAL_CALL createEnumeration() override
|
2000-09-18 14:29:57 +00:00
|
|
|
{ return _xEnumerationAccess->createEnumeration(); }
|
|
|
|
|
|
|
|
// XExactName
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual OUString SAL_CALL getExactName( const OUString& rApproximateName ) override;
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
private:
|
2014-03-12 13:23:31 +01:00
|
|
|
void setMaterial( const Any& rMaterial );
|
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
void getInfoSequenceImpl( Sequence< OUString >* pStringSeq, Sequence< InvocationInfo >* pInfoSeq );
|
|
|
|
void fillInfoForNameAccess( InvocationInfo& rInfo, const OUString& aName );
|
2015-04-01 14:24:26 +02:00
|
|
|
static void fillInfoForProperty( InvocationInfo& rInfo, const Property& rProp );
|
2016-04-12 12:08:00 +02:00
|
|
|
static void fillInfoForMethod( InvocationInfo& rInfo, const Reference< XIdlMethod >& xMethod );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
Reference<XTypeConverter> xTypeConverter;
|
|
|
|
Reference<XIntrospection> xIntrospection;
|
|
|
|
Reference<XIdlReflection> xCoreReflection;
|
|
|
|
|
|
|
|
Any _aMaterial;
|
|
|
|
// _xDirect and (_xIntrospectionAccess, xPropertySet) are exclusive
|
|
|
|
Reference<XInvocation> _xDirect;
|
|
|
|
Reference<XInvocation2> _xDirect2;
|
|
|
|
Reference<XPropertySet> _xPropertySet;
|
|
|
|
Reference<XIntrospectionAccess> _xIntrospectionAccess;
|
|
|
|
|
|
|
|
// supplied Interfaces
|
|
|
|
Reference<XNameContainer> _xNameContainer;
|
2015-07-23 11:36:38 +08:00
|
|
|
Reference<XNameReplace> _xNameReplace;
|
2000-09-18 14:29:57 +00:00
|
|
|
Reference<XNameAccess> _xNameAccess;
|
|
|
|
Reference<XIndexContainer> _xIndexContainer;
|
2015-07-23 11:36:38 +08:00
|
|
|
Reference<XIndexReplace> _xIndexReplace;
|
2000-09-18 14:29:57 +00:00
|
|
|
Reference<XIndexAccess> _xIndexAccess;
|
|
|
|
Reference<XEnumerationAccess> _xEnumerationAccess;
|
|
|
|
Reference<XElementAccess> _xElementAccess;
|
|
|
|
|
2014-02-25 20:42:12 +01:00
|
|
|
|
2015-07-13 09:28:52 +08:00
|
|
|
Reference<XExactName> _xENDirect, _xENIntrospection;
|
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@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
2018-02-14 22:17:57 +02:00
|
|
|
|
|
|
|
bool mbFromOLE;
|
2000-09-18 14:29:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Invocation_Impl::Invocation_Impl
|
|
|
|
(
|
|
|
|
const Any & rAdapted,
|
|
|
|
const Reference<XTypeConverter> & rTC,
|
|
|
|
const Reference<XIntrospection> & rI,
|
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@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
2018-02-14 22:17:57 +02:00
|
|
|
const Reference<XIdlReflection> & rCR,
|
|
|
|
bool bFromOLE
|
2000-09-18 14:29:57 +00:00
|
|
|
)
|
2006-06-19 23:02:34 +00:00
|
|
|
: xTypeConverter( rTC )
|
|
|
|
, xIntrospection( rI )
|
2000-09-18 14:29:57 +00:00
|
|
|
, xCoreReflection( rCR )
|
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@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
2018-02-14 22:17:57 +02:00
|
|
|
, mbFromOLE( bFromOLE )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
setMaterial( rAdapted );
|
|
|
|
}
|
|
|
|
|
|
|
|
//### INTERFACE IMPLEMENTATIONS ####################################################################
|
2014-02-25 20:42:12 +01:00
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
Any SAL_CALL Invocation_Impl::queryInterface( const Type & aType )
|
|
|
|
{
|
2015-07-16 13:37:15 +08:00
|
|
|
// PropertySet implementation
|
2000-09-18 14:29:57 +00:00
|
|
|
Any a = ::cppu::queryInterface( aType,
|
2017-09-04 08:53:38 +02:00
|
|
|
static_cast< XInvocation* >(this),
|
|
|
|
static_cast< XMaterialHolder* >(this),
|
|
|
|
static_cast< XTypeProvider * >(this) );
|
2000-09-18 14:29:57 +00:00
|
|
|
if( a.hasValue() )
|
|
|
|
{
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2014-05-23 22:11:27 +02:00
|
|
|
if( aType == cppu::UnoType<XExactName>::get())
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2017-03-18 20:07:23 +01:00
|
|
|
// Invocation does not support XExactName, if direct object supports
|
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@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
2018-02-14 22:17:57 +02:00
|
|
|
// XInvocation, but not XExactName. Except when called from OLE Automation.
|
|
|
|
if (mbFromOLE ||
|
|
|
|
(_xDirect.is() && _xENDirect.is()) ||
|
2015-07-13 09:28:52 +08:00
|
|
|
(!_xDirect.is() && _xENIntrospection.is()))
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2017-09-04 08:53:38 +02:00
|
|
|
return makeAny( Reference< XExactName >( static_cast< XExactName* >(this) ) );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
}
|
2014-05-23 22:11:27 +02:00
|
|
|
else if ( aType == cppu::UnoType<XNameContainer>::get())
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
if( _xNameContainer.is() )
|
2017-09-04 08:53:38 +02:00
|
|
|
return makeAny( Reference< XNameContainer >( static_cast< XNameContainer* >(this) ) );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2015-07-23 11:36:38 +08:00
|
|
|
else if ( aType == cppu::UnoType<XNameReplace>::get())
|
|
|
|
{
|
|
|
|
if( _xNameReplace.is() )
|
2017-09-04 08:53:38 +02:00
|
|
|
return makeAny( Reference< XNameReplace >( static_cast< XNameReplace* >(this) ) );
|
2015-07-23 11:36:38 +08:00
|
|
|
}
|
2014-05-23 22:11:27 +02:00
|
|
|
else if ( aType == cppu::UnoType<XNameAccess>::get())
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
if( _xNameAccess.is() )
|
2017-09-04 08:53:38 +02:00
|
|
|
return makeAny( Reference< XNameAccess >( static_cast< XNameAccess* >(this) ) );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2014-05-23 22:11:27 +02:00
|
|
|
else if ( aType == cppu::UnoType<XIndexContainer>::get())
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
if (_xIndexContainer.is())
|
2017-09-04 08:53:38 +02:00
|
|
|
return makeAny( Reference< XIndexContainer >( static_cast< XIndexContainer* >(this) ) );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2015-07-23 11:36:38 +08:00
|
|
|
else if ( aType == cppu::UnoType<XIndexReplace>::get())
|
|
|
|
{
|
|
|
|
if (_xIndexReplace.is())
|
2017-09-04 08:53:38 +02:00
|
|
|
return makeAny( Reference< XIndexReplace >( static_cast< XIndexReplace* >(this) ) );
|
2015-07-23 11:36:38 +08:00
|
|
|
}
|
2014-05-23 22:11:27 +02:00
|
|
|
else if ( aType == cppu::UnoType<XIndexAccess>::get())
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
if (_xIndexAccess.is())
|
2017-09-04 08:53:38 +02:00
|
|
|
return makeAny( Reference< XIndexAccess >( static_cast< XIndexAccess* >(this) ) );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2014-05-23 22:11:27 +02:00
|
|
|
else if ( aType == cppu::UnoType<XEnumerationAccess>::get())
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
if (_xEnumerationAccess.is())
|
2017-09-04 08:53:38 +02:00
|
|
|
return makeAny( Reference< XEnumerationAccess >( static_cast< XEnumerationAccess* >(this) ) );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2014-05-23 22:11:27 +02:00
|
|
|
else if ( aType == cppu::UnoType<XElementAccess>::get())
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
if (_xElementAccess.is())
|
|
|
|
{
|
2001-06-29 14:00:31 +00:00
|
|
|
return makeAny( Reference< XElementAccess >(
|
2017-09-04 08:53:38 +02:00
|
|
|
static_cast< XElementAccess* >(static_cast< XNameContainer* >(this)) ) );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
}
|
2014-05-23 22:11:27 +02:00
|
|
|
else if ( aType == cppu::UnoType<XInvocation2>::get())
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
// Invocation does not support XInvocation2, if direct object supports
|
|
|
|
// XInvocation, but not XInvocation2.
|
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@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
2018-02-14 22:17:57 +02:00
|
|
|
if ( mbFromOLE ||
|
|
|
|
( _xDirect.is() && _xDirect2.is()) ||
|
2000-09-18 14:29:57 +00:00
|
|
|
(!_xDirect.is() && _xIntrospectionAccess.is() ) )
|
|
|
|
{
|
2017-09-04 08:53:38 +02:00
|
|
|
return makeAny( Reference< XInvocation2 >( static_cast< XInvocation2* >(this) ) );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return OWeakObject::queryInterface( aType );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
Any Invocation_Impl::getMaterial()
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2015-07-16 13:37:15 +08:00
|
|
|
// AB, 12.2.1999 Make sure that the material is taken when possible
|
|
|
|
// from the direct Invocation of the Introspection, otherwise structs
|
|
|
|
// are not handled correctly
|
2000-09-18 14:29:57 +00:00
|
|
|
Reference<XMaterialHolder> xMaterialHolder;
|
|
|
|
if( _xDirect.is() )
|
|
|
|
{
|
2015-11-05 09:30:03 +02:00
|
|
|
xMaterialHolder.set( _xDirect, UNO_QUERY );
|
2000-09-18 14:29:57 +00:00
|
|
|
//_xDirect->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder );
|
|
|
|
}
|
|
|
|
else if( _xIntrospectionAccess.is() )
|
|
|
|
{
|
2015-11-05 09:30:03 +02:00
|
|
|
xMaterialHolder.set( _xIntrospectionAccess, UNO_QUERY );
|
2000-09-18 14:29:57 +00:00
|
|
|
//_xIntrospectionAccess->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder );
|
|
|
|
}
|
|
|
|
if( xMaterialHolder.is() )
|
|
|
|
{
|
|
|
|
return xMaterialHolder->getMaterial();
|
|
|
|
}
|
|
|
|
return _aMaterial;
|
|
|
|
}
|
|
|
|
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
void Invocation_Impl::setMaterial( const Any& rMaterial )
|
|
|
|
{
|
|
|
|
// set the material first and only once
|
|
|
|
_aMaterial = rMaterial;
|
|
|
|
|
2015-07-16 13:37:15 +08:00
|
|
|
// First do this outside the guard
|
2016-06-21 14:05:17 +02:00
|
|
|
_xDirect.set( rMaterial, UNO_QUERY );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
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@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
2018-02-14 22:17:57 +02:00
|
|
|
if( !mbFromOLE && _xDirect.is() )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2015-07-16 13:37:15 +08:00
|
|
|
// Consult object directly
|
2015-11-05 09:30:03 +02:00
|
|
|
_xElementAccess.set( _xDirect, UNO_QUERY );
|
|
|
|
_xEnumerationAccess.set( _xDirect, UNO_QUERY );
|
|
|
|
_xIndexAccess.set( _xDirect, UNO_QUERY );
|
|
|
|
_xIndexReplace.set( _xDirect, UNO_QUERY );
|
|
|
|
_xIndexContainer.set( _xDirect, UNO_QUERY );
|
|
|
|
_xNameAccess.set( _xDirect, UNO_QUERY );
|
|
|
|
_xNameReplace.set( _xDirect, UNO_QUERY );
|
|
|
|
_xNameContainer.set( _xDirect, UNO_QUERY );
|
|
|
|
_xENDirect.set( _xDirect, UNO_QUERY );
|
|
|
|
_xDirect2.set( _xDirect, UNO_QUERY );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-07-16 13:37:15 +08:00
|
|
|
// Make Invocation on the Introspection
|
2000-09-18 14:29:57 +00:00
|
|
|
if (xIntrospection.is())
|
|
|
|
{
|
|
|
|
_xIntrospectionAccess = xIntrospection->inspect( _aMaterial );
|
|
|
|
if( _xIntrospectionAccess.is() )
|
|
|
|
{
|
2015-11-05 09:30:03 +02:00
|
|
|
_xElementAccess.set(
|
2000-09-18 14:29:57 +00:00
|
|
|
_xIntrospectionAccess->queryAdapter(
|
2015-11-05 09:30:03 +02:00
|
|
|
cppu::UnoType<XElementAccess>::get()), UNO_QUERY );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2015-07-13 09:28:52 +08:00
|
|
|
if( _xElementAccess.is() )
|
|
|
|
{
|
2015-11-05 09:30:03 +02:00
|
|
|
_xEnumerationAccess.set(
|
2015-07-13 09:28:52 +08:00
|
|
|
_xIntrospectionAccess->queryAdapter(
|
2015-11-05 09:30:03 +02:00
|
|
|
cppu::UnoType<XEnumerationAccess>::get()), UNO_QUERY );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2015-11-05 09:30:03 +02:00
|
|
|
_xIndexAccess.set(
|
2015-07-13 09:28:52 +08:00
|
|
|
_xIntrospectionAccess->queryAdapter(
|
2015-11-05 09:30:03 +02:00
|
|
|
cppu::UnoType<XIndexAccess>::get()), UNO_QUERY );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2015-07-13 09:28:52 +08:00
|
|
|
if( _xIndexAccess.is() )
|
|
|
|
{
|
2015-11-05 09:30:03 +02:00
|
|
|
_xIndexReplace.set(
|
2015-07-23 11:36:38 +08:00
|
|
|
_xIntrospectionAccess->queryAdapter(
|
2015-11-05 09:30:03 +02:00
|
|
|
cppu::UnoType<XIndexReplace>::get()), UNO_QUERY );
|
2015-07-23 11:36:38 +08:00
|
|
|
|
2015-11-05 09:30:03 +02:00
|
|
|
_xIndexContainer.set(
|
2015-07-13 09:28:52 +08:00
|
|
|
_xIntrospectionAccess->queryAdapter(
|
2015-11-05 09:30:03 +02:00
|
|
|
cppu::UnoType<XIndexContainer>::get()), UNO_QUERY );
|
2015-07-13 09:28:52 +08:00
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2015-11-05 09:30:03 +02:00
|
|
|
_xNameAccess.set(
|
2015-07-13 09:28:52 +08:00
|
|
|
_xIntrospectionAccess->queryAdapter(
|
2015-11-05 09:30:03 +02:00
|
|
|
cppu::UnoType<XNameAccess>::get()), UNO_QUERY );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2015-07-13 09:28:52 +08:00
|
|
|
if( _xNameAccess.is() )
|
|
|
|
{
|
2015-11-05 09:30:03 +02:00
|
|
|
_xNameReplace.set(
|
2015-07-23 11:36:38 +08:00
|
|
|
_xIntrospectionAccess->queryAdapter(
|
2015-11-05 09:30:03 +02:00
|
|
|
cppu::UnoType<XNameReplace>::get()), UNO_QUERY );
|
2015-07-23 11:36:38 +08:00
|
|
|
|
2015-11-05 09:30:03 +02:00
|
|
|
_xNameContainer.set(
|
2015-07-13 09:28:52 +08:00
|
|
|
_xIntrospectionAccess->queryAdapter(
|
2015-11-05 09:30:03 +02:00
|
|
|
cppu::UnoType<XNameContainer>::get()), UNO_QUERY );
|
2015-07-13 09:28:52 +08:00
|
|
|
}
|
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2015-11-05 09:30:03 +02:00
|
|
|
_xPropertySet.set( _xIntrospectionAccess->queryAdapter( cppu::UnoType<XPropertySet>::get()),
|
|
|
|
UNO_QUERY );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2015-11-05 09:30:03 +02:00
|
|
|
_xENIntrospection.set( _xIntrospectionAccess, UNO_QUERY );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
OUString Invocation_Impl::getExactName( const OUString& rApproximateName )
|
|
|
|
{
|
|
|
|
if (_xENDirect.is())
|
|
|
|
return _xENDirect->getExactName( rApproximateName );
|
|
|
|
|
|
|
|
OUString aRet;
|
|
|
|
if (_xENIntrospection.is())
|
|
|
|
aRet = _xENIntrospection->getExactName( rApproximateName );
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2015-04-14 12:44:47 +02:00
|
|
|
Reference<XIntrospectionAccess> Invocation_Impl::getIntrospection()
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
if( _xDirect.is() )
|
|
|
|
return _xDirect->getIntrospection();
|
|
|
|
else
|
|
|
|
return _xIntrospectionAccess;
|
|
|
|
}
|
|
|
|
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
sal_Bool Invocation_Impl::hasMethod( const OUString& Name )
|
|
|
|
{
|
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@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
2018-02-14 22:17:57 +02:00
|
|
|
if (!mbFromOLE && _xDirect.is())
|
2000-09-18 14:29:57 +00:00
|
|
|
return _xDirect->hasMethod( Name );
|
|
|
|
if( _xIntrospectionAccess.is() )
|
|
|
|
return _xIntrospectionAccess->hasMethod( Name, MethodConcept::ALL ^ MethodConcept::DANGEROUS );
|
2016-04-20 17:19:52 +02:00
|
|
|
return false;
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
sal_Bool Invocation_Impl::hasProperty( const OUString& Name )
|
|
|
|
{
|
2018-02-22 00:47:30 +02:00
|
|
|
if (_xDirect.is())
|
|
|
|
{
|
|
|
|
bool bRet = _xDirect->hasProperty( Name );
|
|
|
|
if (bRet || !mbFromOLE)
|
|
|
|
return bRet;
|
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
// PropertySet
|
|
|
|
if( _xIntrospectionAccess.is()
|
|
|
|
&& _xIntrospectionAccess->hasProperty( Name, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
|
2016-04-20 17:19:52 +02:00
|
|
|
return true;
|
2000-09-18 14:29:57 +00:00
|
|
|
// NameAccess
|
|
|
|
if( _xNameAccess.is() )
|
|
|
|
return _xNameAccess->hasByName( Name );
|
2016-04-20 17:19:52 +02:00
|
|
|
return false;
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
Any Invocation_Impl::getValue( const OUString& PropertyName )
|
|
|
|
{
|
2018-02-22 00:47:30 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
if (_xDirect.is())
|
|
|
|
return _xDirect->getValue( PropertyName );
|
|
|
|
}
|
|
|
|
catch (RuntimeException &)
|
|
|
|
{
|
|
|
|
if (!mbFromOLE)
|
|
|
|
throw;
|
|
|
|
}
|
2003-03-27 11:01:26 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
// PropertySet
|
|
|
|
if( _xIntrospectionAccess.is() && _xPropertySet.is()
|
|
|
|
&& _xIntrospectionAccess->hasProperty
|
|
|
|
( PropertyName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
|
|
|
|
{
|
|
|
|
return _xPropertySet->getPropertyValue( PropertyName );
|
|
|
|
}
|
|
|
|
// NameAccess
|
|
|
|
if( _xNameAccess.is() && _xNameAccess->hasByName( PropertyName ) )
|
|
|
|
return _xNameAccess->getByName( PropertyName );
|
|
|
|
}
|
|
|
|
catch (UnknownPropertyException &)
|
|
|
|
{
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
catch (RuntimeException &)
|
|
|
|
{
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
catch (Exception &)
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-12-16 17:30:34 +01:00
|
|
|
throw UnknownPropertyException( "cannot get value " + PropertyName );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
void Invocation_Impl::setValue( const OUString& PropertyName, const Any& Value )
|
|
|
|
{
|
|
|
|
if (_xDirect.is())
|
|
|
|
_xDirect->setValue( PropertyName, Value );
|
|
|
|
else
|
|
|
|
{
|
2003-03-27 11:01:26 +00:00
|
|
|
try
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2003-03-27 11:01:26 +00:00
|
|
|
// Properties
|
|
|
|
if( _xIntrospectionAccess.is() && _xPropertySet.is()
|
|
|
|
&& _xIntrospectionAccess->hasProperty(
|
|
|
|
PropertyName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
|
|
|
|
{
|
|
|
|
Property aProp = _xIntrospectionAccess->getProperty(
|
|
|
|
PropertyName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS );
|
|
|
|
Reference < XIdlClass > r = TypeToIdlClass( aProp.Type, xCoreReflection );
|
|
|
|
if( r->isAssignableFrom( TypeToIdlClass( Value.getValueType(), xCoreReflection ) ) )
|
|
|
|
_xPropertySet->setPropertyValue( PropertyName, Value );
|
|
|
|
else if( xTypeConverter.is() )
|
|
|
|
_xPropertySet->setPropertyValue(
|
|
|
|
PropertyName, xTypeConverter->convertTo( Value, aProp.Type ) );
|
|
|
|
else
|
2014-05-23 12:03:21 +02:00
|
|
|
throw RuntimeException( "no type converter service!" );
|
2003-03-27 11:01:26 +00:00
|
|
|
}
|
|
|
|
// NameContainer
|
|
|
|
else if( _xNameContainer.is() )
|
|
|
|
{
|
2015-07-23 11:36:38 +08:00
|
|
|
// Note: This misfeature deliberately not adapted to apply to objects which
|
|
|
|
// have XNameReplace but not XNameContainer
|
2003-03-27 11:01:26 +00:00
|
|
|
Any aConv;
|
|
|
|
Reference < XIdlClass > r =
|
|
|
|
TypeToIdlClass( _xNameContainer->getElementType(), xCoreReflection );
|
|
|
|
if( r->isAssignableFrom(TypeToIdlClass( Value.getValueType(), xCoreReflection ) ) )
|
|
|
|
aConv = Value;
|
|
|
|
else if( xTypeConverter.is() )
|
|
|
|
aConv = xTypeConverter->convertTo( Value, _xNameContainer->getElementType() );
|
|
|
|
else
|
2014-05-23 12:03:21 +02:00
|
|
|
throw RuntimeException( "no type converter service!" );
|
2003-03-27 11:01:26 +00:00
|
|
|
|
2015-07-16 13:37:15 +08:00
|
|
|
// Replace if present, otherwise insert
|
2003-03-27 11:01:26 +00:00
|
|
|
if (_xNameContainer->hasByName( PropertyName ))
|
|
|
|
_xNameContainer->replaceByName( PropertyName, aConv );
|
|
|
|
else
|
|
|
|
_xNameContainer->insertByName( PropertyName, aConv );
|
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
else
|
2014-05-23 12:03:21 +02:00
|
|
|
throw UnknownPropertyException( "no introspection nor name container!" );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2003-03-27 11:01:26 +00:00
|
|
|
catch (UnknownPropertyException &)
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2003-03-27 11:01:26 +00:00
|
|
|
throw;
|
|
|
|
}
|
|
|
|
catch (CannotConvertException &)
|
|
|
|
{
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
catch (InvocationTargetException &)
|
|
|
|
{
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
catch (RuntimeException &)
|
|
|
|
{
|
|
|
|
throw;
|
|
|
|
}
|
2011-12-27 00:12:38 +09:00
|
|
|
catch (const Exception & exc)
|
2003-03-27 11:01:26 +00:00
|
|
|
{
|
2018-05-24 15:47:30 +02:00
|
|
|
css::uno::Any anyEx = cppu::getCaughtException();
|
2003-03-27 11:01:26 +00:00
|
|
|
throw InvocationTargetException(
|
2014-12-18 13:33:01 +01:00
|
|
|
"exception occurred in setValue(): " + exc.Message,
|
2018-05-24 15:47:30 +02:00
|
|
|
Reference< XInterface >(), anyEx );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
Any Invocation_Impl::invoke( const OUString& FunctionName, const Sequence<Any>& InParams,
|
2013-10-02 21:56:10 +03:00
|
|
|
Sequence<sal_Int16>& OutIndices, Sequence<Any>& OutParams )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
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@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
2018-02-14 22:17:57 +02:00
|
|
|
if (!mbFromOLE && _xDirect.is())
|
2013-10-02 21:56:10 +03:00
|
|
|
return _xDirect->invoke( FunctionName, InParams, OutIndices, OutParams );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
if (_xIntrospectionAccess.is())
|
|
|
|
{
|
|
|
|
// throw NoSuchMethodException if not exist
|
2000-10-06 13:25:14 +00:00
|
|
|
Reference<XIdlMethod> xMethod = _xIntrospectionAccess->getMethod(
|
|
|
|
FunctionName, MethodConcept::ALL ^ MethodConcept::DANGEROUS );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
// ParameterInfos
|
|
|
|
Sequence<ParamInfo> aFParams = xMethod->getParameterInfos();
|
|
|
|
const ParamInfo* pFParams = aFParams.getConstArray();
|
2006-06-19 23:02:34 +00:00
|
|
|
sal_Int32 nFParamsLen = aFParams.getLength();
|
2003-03-27 11:01:26 +00:00
|
|
|
if (nFParamsLen != InParams.getLength())
|
|
|
|
{
|
|
|
|
throw IllegalArgumentException(
|
2017-01-30 11:22:54 +02:00
|
|
|
"incorrect number of parameters passed invoking function " + FunctionName +
|
2018-02-08 21:36:07 +02:00
|
|
|
": expected " + OUString::number(nFParamsLen) + ", got " + OUString::number(InParams.getLength()),
|
2018-01-12 20:15:18 +01:00
|
|
|
static_cast<OWeakObject *>(this), sal_Int16(1) );
|
2003-03-27 11:01:26 +00:00
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
// IN Parameter
|
|
|
|
const Any* pInParams = InParams.getConstArray();
|
|
|
|
|
|
|
|
// Introspection Invoke Parameter
|
|
|
|
Sequence<Any> aInvokeParams( nFParamsLen );
|
|
|
|
Any* pInvokeParams = aInvokeParams.getArray();
|
|
|
|
|
2013-10-02 21:56:10 +03:00
|
|
|
// OUT Indices
|
|
|
|
OutIndices.realloc( nFParamsLen );
|
|
|
|
sal_Int16* pOutIndices = OutIndices.getArray();
|
2000-09-18 14:29:57 +00:00
|
|
|
sal_uInt32 nOutIndex = 0;
|
|
|
|
|
2006-09-25 11:51:42 +00:00
|
|
|
for ( sal_Int32 nPos = 0; nPos < nFParamsLen; ++nPos )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2006-09-25 11:51:42 +00:00
|
|
|
try
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
const ParamInfo& rFParam = pFParams[nPos];
|
|
|
|
const Reference<XIdlClass>& rDestType = rFParam.aType;
|
|
|
|
|
|
|
|
// is IN/INOUT parameter?
|
|
|
|
if (rFParam.aMode != ParamMode_OUT)
|
|
|
|
{
|
2000-10-06 13:25:14 +00:00
|
|
|
if (rDestType->isAssignableFrom( TypeToIdlClass( pInParams[nPos].getValueType(), xCoreReflection ) ))
|
|
|
|
{
|
|
|
|
pInvokeParams[nPos] = pInParams[nPos];
|
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
else if (xTypeConverter.is())
|
|
|
|
{
|
|
|
|
Type aDestType( rDestType->getTypeClass(), rDestType->getName() );
|
2000-10-06 13:25:14 +00:00
|
|
|
pInvokeParams[nPos] = xTypeConverter->convertTo( pInParams[nPos], aDestType );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
else
|
2000-10-06 13:25:14 +00:00
|
|
|
{
|
|
|
|
CannotConvertException aExc;
|
|
|
|
aExc.Context = *this;
|
2013-10-31 17:49:01 +02:00
|
|
|
aExc.Message = "invocation type mismatch!";
|
2000-10-06 13:25:14 +00:00
|
|
|
throw aExc;
|
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// is OUT/INOUT parameter?
|
|
|
|
if (rFParam.aMode != ParamMode_IN)
|
|
|
|
{
|
2018-01-12 20:15:18 +01:00
|
|
|
pOutIndices[nOutIndex] = static_cast<sal_Int16>(nPos);
|
2000-09-18 14:29:57 +00:00
|
|
|
if (rFParam.aMode == ParamMode_OUT)
|
|
|
|
rDestType->createObject( pInvokeParams[nPos] ); // default init
|
|
|
|
++nOutIndex;
|
|
|
|
}
|
|
|
|
}
|
2006-09-25 11:51:42 +00:00
|
|
|
catch( CannotConvertException& rExc )
|
2000-10-06 13:25:14 +00:00
|
|
|
{
|
2015-07-16 13:37:15 +08:00
|
|
|
rExc.ArgumentIndex = nPos; // Add optional parameter index
|
2011-08-10 23:04:54 +02:00
|
|
|
throw;
|
2000-10-06 13:25:14 +00:00
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2006-09-25 11:51:42 +00:00
|
|
|
|
|
|
|
// execute Method
|
|
|
|
Any aRet = xMethod->invoke( _aMaterial, aInvokeParams );
|
|
|
|
|
|
|
|
// OUT Params
|
2013-10-02 21:56:10 +03:00
|
|
|
OutIndices.realloc( nOutIndex );
|
|
|
|
pOutIndices = OutIndices.getArray();
|
2006-09-25 11:51:42 +00:00
|
|
|
OutParams.realloc( nOutIndex );
|
|
|
|
Any* pOutParams = OutParams.getArray();
|
|
|
|
|
|
|
|
while (nOutIndex--)
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2013-10-02 21:56:10 +03:00
|
|
|
pOutParams[nOutIndex] = pInvokeParams[ pOutIndices[nOutIndex] ];
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2006-09-25 11:51:42 +00:00
|
|
|
|
|
|
|
return aRet;
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2000-10-06 13:25:14 +00:00
|
|
|
|
|
|
|
RuntimeException aExc;
|
|
|
|
aExc.Context = *this;
|
2013-10-31 17:49:01 +02:00
|
|
|
aExc.Message = "invocation lacking of introspection access!";
|
2000-10-06 13:25:14 +00:00
|
|
|
throw aExc;
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
// Struct to optimize sorting
|
|
|
|
struct MemberItem
|
|
|
|
{
|
|
|
|
OUString aName;
|
|
|
|
|
|
|
|
// Defines where the member comes from
|
2005-04-04 06:54:13 +00:00
|
|
|
enum Mode { NAMEACCESS, PROPERTYSET, METHOD } eMode;
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
// Index to respective sequence
|
|
|
|
// (Index to NameAccess sequence for eMode==NAMEACCESS etc.)
|
|
|
|
sal_Int32 nIndex;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Implementation of getting name or info
|
|
|
|
// String sequence will be filled when pStringSeq != NULL
|
|
|
|
// Info sequence will be filled when pInfoSeq != NULL
|
|
|
|
void Invocation_Impl::getInfoSequenceImpl
|
|
|
|
(
|
|
|
|
Sequence< OUString >* pStringSeq,
|
|
|
|
Sequence< InvocationInfo >* pInfoSeq
|
|
|
|
)
|
|
|
|
{
|
|
|
|
//Sequence< OUString > aStrSeq;
|
|
|
|
//if( !pStringSeq )
|
|
|
|
//pStringSeq = &aStrSeq;
|
|
|
|
|
|
|
|
|
|
|
|
// Get all needed sequences
|
|
|
|
Sequence<OUString> aNameAccessNames;
|
|
|
|
Sequence<Property> aPropertySeq;
|
|
|
|
Sequence< Reference< XIdlMethod > > aMethodSeq;
|
|
|
|
|
|
|
|
if( _xNameAccess.is() )
|
|
|
|
{
|
|
|
|
aNameAccessNames = _xNameAccess->getElementNames();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( _xIntrospectionAccess.is() )
|
|
|
|
{
|
|
|
|
aPropertySeq = _xIntrospectionAccess->getProperties
|
|
|
|
( PropertyConcept::ALL - PropertyConcept::DANGEROUS );
|
|
|
|
|
|
|
|
aMethodSeq = _xIntrospectionAccess->getMethods
|
|
|
|
( MethodConcept::ALL - MethodConcept::DANGEROUS );
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int32 nNameAccessCount = aNameAccessNames.getLength();
|
|
|
|
sal_Int32 nPropertyCount = aPropertySeq.getLength();
|
|
|
|
sal_Int32 nMethodCount = aMethodSeq.getLength();
|
|
|
|
sal_Int32 nTotalCount = nNameAccessCount + nPropertyCount + nMethodCount;
|
|
|
|
|
|
|
|
// Create and fill array of MemberItems
|
2015-06-15 17:58:15 +09:00
|
|
|
std::unique_ptr< MemberItem []> pItems( new MemberItem[ nTotalCount ] );
|
2000-09-18 14:29:57 +00:00
|
|
|
const OUString* pStrings = aNameAccessNames.getConstArray();
|
|
|
|
const Property* pProps = aPropertySeq.getConstArray();
|
|
|
|
const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray();
|
|
|
|
|
|
|
|
// Fill array of MemberItems
|
|
|
|
sal_Int32 i, iTotal = 0;
|
|
|
|
|
|
|
|
// Name Access
|
|
|
|
for( i = 0 ; i < nNameAccessCount ; i++, iTotal++ )
|
|
|
|
{
|
|
|
|
MemberItem& rItem = pItems[ iTotal ];
|
|
|
|
rItem.aName = pStrings[ i ];
|
|
|
|
rItem.eMode = MemberItem::NAMEACCESS;
|
|
|
|
rItem.nIndex = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Property set
|
|
|
|
for( i = 0 ; i < nPropertyCount ; i++, iTotal++ )
|
|
|
|
{
|
|
|
|
MemberItem& rItem = pItems[ iTotal ];
|
|
|
|
rItem.aName = pProps[ i ].Name;
|
|
|
|
rItem.eMode = MemberItem::PROPERTYSET;
|
|
|
|
rItem.nIndex = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Methods
|
|
|
|
for( i = 0 ; i < nMethodCount ; i++, iTotal++ )
|
|
|
|
{
|
|
|
|
MemberItem& rItem = pItems[ iTotal ];
|
|
|
|
Reference< XIdlMethod > xMethod = pMethods[ i ];
|
|
|
|
rItem.aName = xMethod->getName();
|
|
|
|
rItem.eMode = MemberItem::METHOD;
|
|
|
|
rItem.nIndex = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setting up result sequences
|
2015-11-10 10:24:34 +01:00
|
|
|
OUString* pRetStrings = nullptr;
|
2000-09-18 14:29:57 +00:00
|
|
|
if( pStringSeq )
|
|
|
|
{
|
|
|
|
pStringSeq->realloc( nTotalCount );
|
|
|
|
pRetStrings = pStringSeq->getArray();
|
|
|
|
}
|
|
|
|
|
2015-11-10 10:24:34 +01:00
|
|
|
InvocationInfo* pRetInfos = nullptr;
|
2000-09-18 14:29:57 +00:00
|
|
|
if( pInfoSeq )
|
|
|
|
{
|
|
|
|
pInfoSeq->realloc( nTotalCount );
|
|
|
|
pRetInfos = pInfoSeq->getArray();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fill result sequences in the correct order of members
|
|
|
|
for( iTotal = 0 ; iTotal < nTotalCount ; iTotal++ )
|
|
|
|
{
|
|
|
|
MemberItem& rItem = pItems[ iTotal ];
|
|
|
|
if( pRetStrings )
|
|
|
|
{
|
|
|
|
pRetStrings[ iTotal ] = rItem.aName;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( pRetInfos )
|
|
|
|
{
|
|
|
|
if( rItem.eMode == MemberItem::NAMEACCESS )
|
|
|
|
{
|
|
|
|
fillInfoForNameAccess( pRetInfos[ iTotal ], rItem.aName );
|
|
|
|
}
|
|
|
|
else if( rItem.eMode == MemberItem::PROPERTYSET )
|
|
|
|
{
|
|
|
|
fillInfoForProperty( pRetInfos[ iTotal ], pProps[ rItem.nIndex ] );
|
|
|
|
}
|
|
|
|
else if( rItem.eMode == MemberItem::METHOD )
|
|
|
|
{
|
|
|
|
fillInfoForMethod( pRetInfos[ iTotal ], pMethods[ rItem.nIndex ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// XInvocation2
|
|
|
|
Sequence< OUString > SAL_CALL Invocation_Impl::getMemberNames( )
|
|
|
|
{
|
|
|
|
if( _xDirect2.is() )
|
|
|
|
{
|
|
|
|
return _xDirect2->getMemberNames();
|
|
|
|
}
|
|
|
|
Sequence< OUString > aRetSeq;
|
2015-11-10 10:24:34 +01:00
|
|
|
getInfoSequenceImpl( &aRetSeq, nullptr );
|
2000-09-18 14:29:57 +00:00
|
|
|
return aRetSeq;
|
|
|
|
}
|
|
|
|
|
|
|
|
Sequence< InvocationInfo > SAL_CALL Invocation_Impl::getInfo( )
|
|
|
|
{
|
|
|
|
if( _xDirect2.is() )
|
|
|
|
{
|
|
|
|
return _xDirect2->getInfo();
|
|
|
|
}
|
|
|
|
Sequence< InvocationInfo > aRetSeq;
|
2015-11-10 10:24:34 +01:00
|
|
|
getInfoSequenceImpl( nullptr, &aRetSeq );
|
2000-09-18 14:29:57 +00:00
|
|
|
return aRetSeq;
|
|
|
|
}
|
|
|
|
|
|
|
|
InvocationInfo SAL_CALL Invocation_Impl::getInfoForName( const OUString& aName, sal_Bool bExact )
|
|
|
|
{
|
|
|
|
if( _xDirect2.is() )
|
|
|
|
{
|
|
|
|
return _xDirect2->getInfoForName( aName, bExact );
|
|
|
|
}
|
|
|
|
|
2013-08-22 12:05:18 +09:00
|
|
|
bool bFound = false;
|
2000-09-18 14:29:57 +00:00
|
|
|
OUString aExactName = aName;
|
|
|
|
InvocationInfo aRetInfo;
|
|
|
|
|
|
|
|
if( bExact )
|
|
|
|
aExactName = getExactName( aName );
|
2012-01-12 17:01:19 -02:00
|
|
|
if( !aExactName.isEmpty() )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
if( _xIntrospectionAccess->hasMethod( aExactName, MethodConcept::ALL ^ MethodConcept::DANGEROUS ) )
|
|
|
|
{
|
|
|
|
Reference<XIdlMethod> xMethod = _xIntrospectionAccess->getMethod
|
|
|
|
( aExactName, MethodConcept::ALL ^ MethodConcept::DANGEROUS );
|
|
|
|
fillInfoForMethod( aRetInfo, xMethod );
|
2013-08-22 12:05:18 +09:00
|
|
|
bFound = true;
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( _xIntrospectionAccess.is() && _xIntrospectionAccess->hasProperty
|
|
|
|
( aExactName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
|
|
|
|
{
|
|
|
|
Property aProp = _xIntrospectionAccess->getProperty
|
|
|
|
( aExactName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS );
|
|
|
|
fillInfoForProperty( aRetInfo, aProp );
|
2013-08-22 12:05:18 +09:00
|
|
|
bFound = true;
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
// NameAccess
|
|
|
|
else if( _xNameAccess.is() && _xNameAccess->hasByName( aExactName ) )
|
|
|
|
{
|
|
|
|
fillInfoForNameAccess( aRetInfo, aExactName );
|
2013-08-22 12:05:18 +09:00
|
|
|
bFound = true;
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( !bFound )
|
|
|
|
{
|
|
|
|
throw IllegalArgumentException(
|
2017-01-30 11:22:54 +02:00
|
|
|
"getExactName(), Unknown name " + aName,
|
2015-06-08 16:28:10 +02:00
|
|
|
static_cast<XWeak *>(static_cast<OWeakObject *>(this)), 0 );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
return aRetInfo;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Helper functions to fill InvocationInfo for XNameAccess
|
|
|
|
void Invocation_Impl::fillInfoForNameAccess
|
|
|
|
(
|
|
|
|
InvocationInfo& rInfo,
|
|
|
|
const OUString& aName
|
|
|
|
)
|
|
|
|
{
|
|
|
|
rInfo.aName = aName;
|
|
|
|
rInfo.eMemberType = MemberType_PROPERTY;
|
|
|
|
rInfo.PropertyAttribute = 0;
|
|
|
|
if( !_xNameContainer.is() )
|
|
|
|
{
|
|
|
|
rInfo.PropertyAttribute = PropertyAttribute::READONLY;
|
|
|
|
}
|
|
|
|
rInfo.aType = _xNameAccess->getElementType();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Invocation_Impl::fillInfoForProperty
|
|
|
|
(
|
|
|
|
InvocationInfo& rInfo,
|
|
|
|
const Property& rProp
|
|
|
|
)
|
|
|
|
{
|
|
|
|
rInfo.aName = rProp.Name;
|
|
|
|
rInfo.eMemberType = MemberType_PROPERTY;
|
|
|
|
rInfo.PropertyAttribute = rProp.Attributes;
|
|
|
|
rInfo.aType = rProp.Type;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Invocation_Impl::fillInfoForMethod
|
|
|
|
(
|
|
|
|
InvocationInfo& rInfo,
|
2016-04-12 12:08:00 +02:00
|
|
|
const Reference< XIdlMethod >& xMethod
|
2000-09-18 14:29:57 +00:00
|
|
|
)
|
|
|
|
{
|
|
|
|
rInfo.aName = xMethod->getName();
|
|
|
|
rInfo.eMemberType = MemberType_METHOD;
|
|
|
|
Reference< XIdlClass > xReturnClass = xMethod->getReturnType();
|
|
|
|
Type aReturnType( xReturnClass->getTypeClass(), xReturnClass->getName() );
|
|
|
|
rInfo.aType = aReturnType;
|
|
|
|
Sequence<ParamInfo> aParamInfos = xMethod->getParameterInfos();
|
|
|
|
sal_Int32 nParamCount = aParamInfos.getLength();
|
|
|
|
if( nParamCount > 0 )
|
|
|
|
{
|
2016-02-11 22:07:09 +00:00
|
|
|
const ParamInfo* pInfo = aParamInfos.getConstArray();
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
rInfo.aParamTypes.realloc( nParamCount );
|
|
|
|
Type* pParamTypes = rInfo.aParamTypes.getArray();
|
|
|
|
rInfo.aParamModes.realloc( nParamCount );
|
|
|
|
ParamMode* pParamModes = rInfo.aParamModes.getArray();
|
|
|
|
|
|
|
|
for( sal_Int32 i = 0 ; i < nParamCount ; i++ )
|
|
|
|
{
|
2016-02-11 22:07:09 +00:00
|
|
|
Reference< XIdlClass > xParamClass = pInfo[i].aType;
|
2000-09-18 14:29:57 +00:00
|
|
|
Type aParamType( xParamClass->getTypeClass(), xParamClass->getName() );
|
|
|
|
pParamTypes[ i ] = aParamType;
|
2016-02-11 22:07:09 +00:00
|
|
|
pParamModes[ i ] = pInfo[i].aMode;
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// XTypeProvider
|
2017-01-26 12:28:58 +01:00
|
|
|
Sequence< Type > SAL_CALL Invocation_Impl::getTypes()
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2015-11-10 10:24:34 +01:00
|
|
|
static Sequence< Type > const * s_pTypes = nullptr;
|
2001-06-29 14:00:31 +00:00
|
|
|
if (! s_pTypes)
|
|
|
|
{
|
2016-07-18 15:19:32 +02:00
|
|
|
Sequence< Type > types( 4 + 10 );
|
2001-06-29 14:00:31 +00:00
|
|
|
Type * pTypes = types.getArray();
|
|
|
|
sal_Int32 n = 0;
|
|
|
|
|
2014-05-23 22:11:27 +02:00
|
|
|
pTypes[ n++ ] = cppu::UnoType<XTypeProvider>::get();
|
|
|
|
pTypes[ n++ ] = cppu::UnoType<XWeak>::get();
|
|
|
|
pTypes[ n++ ] = cppu::UnoType<XInvocation>::get();
|
|
|
|
pTypes[ n++ ] = cppu::UnoType<XMaterialHolder>::get();
|
2001-06-29 14:00:31 +00:00
|
|
|
|
2015-07-16 13:37:15 +08:00
|
|
|
// Invocation does not support XExactName if direct object supports
|
2001-06-29 14:00:31 +00:00
|
|
|
// XInvocation, but not XExactName.
|
|
|
|
if ((_xDirect.is() && _xENDirect.is()) ||
|
2015-07-13 09:28:52 +08:00
|
|
|
(!_xDirect.is() && _xENIntrospection.is()))
|
2001-06-29 14:00:31 +00:00
|
|
|
{
|
2014-05-23 22:11:27 +02:00
|
|
|
pTypes[ n++ ] = cppu::UnoType<XExactName>::get();
|
2001-06-29 14:00:31 +00:00
|
|
|
}
|
|
|
|
if( _xNameContainer.is() )
|
|
|
|
{
|
2014-05-23 22:11:27 +02:00
|
|
|
pTypes[ n++ ] = cppu::UnoType<XNameContainer>::get();
|
2001-06-29 14:00:31 +00:00
|
|
|
}
|
2015-07-23 11:36:38 +08:00
|
|
|
if( _xNameReplace.is() )
|
|
|
|
{
|
|
|
|
pTypes[ n++ ] = cppu::UnoType<XNameReplace>::get();
|
|
|
|
}
|
2001-06-29 14:00:31 +00:00
|
|
|
if( _xNameAccess.is() )
|
|
|
|
{
|
2014-05-23 22:11:27 +02:00
|
|
|
pTypes[ n++ ] = cppu::UnoType<XNameAccess>::get();
|
2001-06-29 14:00:31 +00:00
|
|
|
}
|
|
|
|
if (_xIndexContainer.is())
|
|
|
|
{
|
2014-05-23 22:11:27 +02:00
|
|
|
pTypes[ n++ ] = cppu::UnoType<XIndexContainer>::get();
|
2001-06-29 14:00:31 +00:00
|
|
|
}
|
2015-07-23 11:36:38 +08:00
|
|
|
if (_xIndexReplace.is())
|
|
|
|
{
|
|
|
|
pTypes[ n++ ] = cppu::UnoType<XIndexReplace>::get();
|
|
|
|
}
|
2001-06-29 14:00:31 +00:00
|
|
|
if (_xIndexAccess.is())
|
|
|
|
{
|
2014-05-23 22:11:27 +02:00
|
|
|
pTypes[ n++ ] = cppu::UnoType<XIndexAccess>::get();
|
2001-06-29 14:00:31 +00:00
|
|
|
}
|
|
|
|
if (_xEnumerationAccess.is())
|
|
|
|
{
|
2014-05-23 22:11:27 +02:00
|
|
|
pTypes[ n++ ] = cppu::UnoType<XEnumerationAccess>::get();
|
2001-06-29 14:00:31 +00:00
|
|
|
}
|
|
|
|
if (_xElementAccess.is())
|
|
|
|
{
|
2014-05-23 22:11:27 +02:00
|
|
|
pTypes[ n++ ] = cppu::UnoType<XElementAccess>::get();
|
2001-06-29 14:00:31 +00:00
|
|
|
}
|
|
|
|
// Invocation does not support XInvocation2, if direct object supports
|
|
|
|
// XInvocation, but not XInvocation2.
|
|
|
|
if ( ( _xDirect.is() && _xDirect2.is()) ||
|
|
|
|
(!_xDirect.is() && _xIntrospectionAccess.is() ) )
|
|
|
|
{
|
2014-05-23 22:11:27 +02:00
|
|
|
pTypes[ n++ ] = cppu::UnoType<XInvocation2>::get();
|
2001-06-29 14:00:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
types.realloc( n );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2001-06-29 14:00:31 +00:00
|
|
|
// store types
|
|
|
|
MutexGuard guard( Mutex::getGlobalMutex() );
|
|
|
|
if (! s_pTypes)
|
|
|
|
{
|
|
|
|
static Sequence< Type > s_types( types );
|
|
|
|
s_pTypes = &s_types;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return *s_pTypes;
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
Sequence< sal_Int8 > SAL_CALL Invocation_Impl::getImplementationId( )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2014-03-10 15:59:35 +01:00
|
|
|
return css::uno::Sequence<sal_Int8>();
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
2014-02-25 20:42:12 +01:00
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
class InvocationService
|
2015-09-04 20:40:13 +09:00
|
|
|
: public WeakImplHelper< XSingleServiceFactory, XServiceInfo >
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
public:
|
2015-07-15 20:26:40 +01:00
|
|
|
explicit InvocationService( const Reference<XComponentContext> & xCtx );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
// XServiceInfo
|
2017-01-26 12:28:58 +01:00
|
|
|
OUString SAL_CALL getImplementationName() override;
|
|
|
|
sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
|
|
|
|
Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
// XSingleServiceFactory
|
2017-01-26 12:28:58 +01:00
|
|
|
Reference<XInterface> SAL_CALL createInstance() override;
|
2000-09-18 14:29:57 +00:00
|
|
|
Reference<XInterface> SAL_CALL createInstanceWithArguments(
|
2017-01-26 12:28:58 +01:00
|
|
|
const Sequence<Any>& rArguments ) override;
|
2000-09-18 14:29:57 +00:00
|
|
|
private:
|
2001-06-22 15:21:02 +00:00
|
|
|
Reference<XComponentContext> mxCtx;
|
|
|
|
Reference<XMultiComponentFactory> mxSMgr;
|
2000-09-18 14:29:57 +00:00
|
|
|
Reference<XTypeConverter> xTypeConverter;
|
|
|
|
Reference<XIntrospection> xIntrospection;
|
|
|
|
Reference<XIdlReflection> xCoreReflection;
|
|
|
|
};
|
|
|
|
|
2001-06-22 15:21:02 +00:00
|
|
|
InvocationService::InvocationService( const Reference<XComponentContext> & xCtx )
|
2006-06-19 23:02:34 +00:00
|
|
|
: mxCtx( xCtx )
|
|
|
|
, mxSMgr( xCtx->getServiceManager() )
|
2014-02-07 12:03:03 +01:00
|
|
|
, xCoreReflection( css::reflection::theCoreReflection::get(mxCtx) )
|
2001-06-22 15:21:02 +00:00
|
|
|
{
|
2015-11-05 09:30:03 +02:00
|
|
|
xTypeConverter.set(
|
2015-10-30 08:40:11 +02:00
|
|
|
mxSMgr->createInstanceWithContext( "com.sun.star.script.Converter", xCtx ),
|
2001-06-22 15:21:02 +00:00
|
|
|
UNO_QUERY );
|
2014-03-07 10:31:07 +01:00
|
|
|
xIntrospection = theIntrospection::get(xCtx);
|
2001-06-22 15:21:02 +00:00
|
|
|
}
|
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
// XServiceInfo
|
2017-01-26 12:28:58 +01:00
|
|
|
OUString InvocationService::getImplementationName()
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2001-06-22 15:21:02 +00:00
|
|
|
return inv_getImplementationName();
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// XServiceInfo
|
2017-01-26 12:28:58 +01:00
|
|
|
sal_Bool InvocationService::supportsService(const OUString& ServiceName)
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2013-10-21 19:04:05 -02:00
|
|
|
return cppu::supportsService(this, ServiceName);
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// XServiceInfo
|
2017-01-26 12:28:58 +01:00
|
|
|
Sequence< OUString > InvocationService::getSupportedServiceNames()
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2001-06-22 15:21:02 +00:00
|
|
|
return inv_getSupportedServiceNames();
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
Reference<XInterface> InvocationService::createInstance()
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2013-06-29 21:24:12 +02:00
|
|
|
//TODO:throw( Exception("no default construction of invocation adapter possible!", *this) );
|
2000-09-18 14:29:57 +00:00
|
|
|
return Reference<XInterface>(); // dummy
|
|
|
|
}
|
|
|
|
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
Reference<XInterface> InvocationService::createInstanceWithArguments(
|
2017-01-26 12:28:58 +01:00
|
|
|
const Sequence<Any>& rArguments )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
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@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
2018-02-14 22:17:57 +02:00
|
|
|
if (rArguments.getLength() == 2)
|
|
|
|
{
|
|
|
|
OUString aArg1;
|
|
|
|
if ((rArguments[1] >>= aArg1) &&
|
|
|
|
aArg1 == "FromOLE")
|
|
|
|
{
|
|
|
|
return Reference< XInterface >
|
|
|
|
( *new Invocation_Impl( *rArguments.getConstArray(),
|
|
|
|
xTypeConverter, xIntrospection, xCoreReflection, true ) );
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
if (rArguments.getLength() == 1)
|
|
|
|
{
|
|
|
|
return Reference< XInterface >
|
|
|
|
( *new Invocation_Impl( *rArguments.getConstArray(),
|
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@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
2018-02-14 22:17:57 +02:00
|
|
|
xTypeConverter, xIntrospection, xCoreReflection, false ) );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
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@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
2018-02-14 22:17:57 +02:00
|
|
|
|
|
|
|
//TODO:throw( Exception("no default construction of invocation adapter possible!", *this) );
|
|
|
|
return Reference<XInterface>();
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
2017-01-19 17:50:46 +01:00
|
|
|
/// @throws RuntimeException
|
2017-12-08 15:58:41 +02:00
|
|
|
Reference<XInterface> InvocationService_CreateInstance( const Reference<XComponentContext> & xCtx )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2015-11-05 09:30:03 +02:00
|
|
|
Reference<XInterface> xService( *new InvocationService( xCtx ) );
|
2000-09-18 14:29:57 +00:00
|
|
|
return xService;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2001-06-22 15:21:02 +00:00
|
|
|
using namespace stoc_inv;
|
2013-08-22 13:59:45 +09:00
|
|
|
static const struct ImplementationEntry g_entries[] =
|
2001-06-22 15:21:02 +00:00
|
|
|
{
|
|
|
|
{
|
|
|
|
InvocationService_CreateInstance, inv_getImplementationName,
|
|
|
|
inv_getSupportedServiceNames, createSingleComponentFactory,
|
2015-11-10 10:24:34 +01:00
|
|
|
nullptr, 0
|
2001-06-22 15:21:02 +00:00
|
|
|
},
|
2015-11-10 10:24:34 +01:00
|
|
|
{ nullptr, nullptr, nullptr, nullptr, nullptr, 0 }
|
2001-06-22 15:21:02 +00:00
|
|
|
};
|
|
|
|
|
2017-12-08 15:58:41 +02:00
|
|
|
extern "C" SAL_DLLPUBLIC_EXPORT void * invocation_component_getFactory(
|
2000-09-18 14:29:57 +00:00
|
|
|
const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
|
|
|
|
{
|
2001-06-22 15:21:02 +00:00
|
|
|
return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2001-06-22 15:21:02 +00:00
|
|
|
|
2010-10-14 08:30:07 +02:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|