[Libreoffice-commits] core.git: 10 commits - comphelper/Library_comphelper.mk comphelper/source extensions/source include/comphelper oovbaapi/ooo oovbaapi/UnoApi_oovbaapi.mk sc/inc sc/Library_scd.mk sc/Library_scfilt.mk sc/Library_sc.mk sc/Library_scui.mk sc/source stoc/source sw/source vbahelper/source

Tor Lillqvist tml at collabora.com
Thu May 31 12:34:23 UTC 2018


 comphelper/Library_comphelper.mk                 |    1 
 comphelper/source/misc/automationinvokedzone.cxx |   36 ++
 extensions/source/ole/servprov.cxx               |   16 
 extensions/source/ole/unoobjw.cxx                |  381 +++++++++++++++++------
 include/comphelper/automationinvokedzone.hxx     |   39 ++
 oovbaapi/UnoApi_oovbaapi.mk                      |    1 
 oovbaapi/ooo/vba/excel/XApplication.idl          |    2 
 oovbaapi/ooo/vba/excel/XApplicationOutgoing.idl  |   36 ++
 sc/Library_sc.mk                                 |    6 
 sc/Library_scd.mk                                |    6 
 sc/Library_scfilt.mk                             |    6 
 sc/Library_scui.mk                               |    6 
 sc/inc/scmod.hxx                                 |    7 
 sc/source/ui/app/scmod.cxx                       |   11 
 sc/source/ui/vba/vbaapplication.cxx              |  102 ++++++
 sc/source/ui/vba/vbaapplication.hxx              |   23 +
 stoc/source/invocation/invocation.cxx            |  132 ++++---
 sw/source/uibase/uno/unotxdoc.cxx                |    7 
 vbahelper/source/vbahelper/vbahelper.cxx         |    8 
 19 files changed, 670 insertions(+), 156 deletions(-)

New commits:
commit 469b8334ad858723b83be1c285cde1d991df86c6
Author: Tor Lillqvist <tml at collabora.com>
Date:   Wed Apr 25 16:41:50 2018 +0300

    Enter AutomationInvokedZone appropriately
    
    Change-Id: Ic76fc43fc521a6fd6642e22b71c311370788d4aa

diff --git a/extensions/source/ole/unoobjw.cxx b/extensions/source/ole/unoobjw.cxx
index 083688683e0b..fb86cee88821 100644
--- a/extensions/source/ole/unoobjw.cxx
+++ b/extensions/source/ole/unoobjw.cxx
@@ -61,6 +61,7 @@
 #include <ooo/vba/msforms/XCheckBox.hpp>
 #include <osl/interlck.h>
 #include <com/sun/star/uno/genfunc.h>
+#include <comphelper/automationinvokedzone.hxx>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/profilezone.hxx>
 #include <comphelper/windowsdebugoutput.hxx>
@@ -188,6 +189,8 @@ InterfaceOleWrapper::~InterfaceOleWrapper()
 
 STDMETHODIMP InterfaceOleWrapper::QueryInterface(REFIID riid, LPVOID FAR * ppv)
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::QueryInterface(" << riid << ")");
 
     HRESULT ret= S_OK;
@@ -264,6 +267,8 @@ STDMETHODIMP InterfaceOleWrapper::getOriginalUnoObject( Reference<XInterface>* p
 }
 STDMETHODIMP  InterfaceOleWrapper::getOriginalUnoStruct( Any * pStruct)
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     HRESULT ret= E_FAIL;
     if( !m_xOrigin.is())
     {
@@ -425,6 +430,8 @@ public:
     virtual HRESULT STDMETHODCALLTYPE GetTypeInfoOfGuid(REFGUID guid,
                                                         ITypeInfo **ppTInfo) override
     {
+        comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
         SAL_INFO("extensions.olebridge", this << "@CXTypeLib::GetTypeInfoOfGuid(" << guid << ")");
         if (!ppTInfo)
             return E_POINTER;
@@ -596,6 +603,8 @@ void CXTypeInfo::InitForOutgoing(Reference<XInterface> xOrigin,
 
 HRESULT STDMETHODCALLTYPE CXTypeInfo::GetTypeAttr(TYPEATTR **ppTypeAttr)
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetTypeAttr");
 
     if (!ppTypeAttr)
@@ -684,6 +693,8 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetTypeComp(ITypeComp **ppTComp)
 HRESULT STDMETHODCALLTYPE CXTypeInfo::GetFuncDesc(UINT index,
                                                   FUNCDESC **ppFuncDesc)
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     if (!ppFuncDesc)
         return E_POINTER;
 
@@ -795,6 +806,8 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetNames(MEMBERID memid,
                                                UINT cMaxNames,
                                                UINT *pcNames)
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetNames(" << memid << ")");
     assert(meKind != Kind::COCLASS);
 
@@ -855,6 +868,8 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetRefTypeOfImplType(UINT index,
 HRESULT STDMETHODCALLTYPE CXTypeInfo::GetImplTypeFlags(UINT index,
                                                        INT *pImplTypeFlags)
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetImplTypeFlags(" << index << ")");
 
     if (!pImplTypeFlags)
@@ -907,7 +922,10 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetDocumentation(MEMBERID memid,
                                                        DWORD *pdwHelpContext,
                                                        BSTR *pBstrHelpFile)
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetDocumentation(" << memid << ")");
+
     if (pBstrName)
     {
         if (memid == MEMBERID_NIL)
@@ -952,6 +970,8 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetDllEntry(MEMBERID memid,
 HRESULT STDMETHODCALLTYPE CXTypeInfo::GetRefTypeInfo(HREFTYPE hRefType,
                                                      ITypeInfo **ppTInfo)
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetRefTypeInfo(" << hRefType << ")");
 
     if (!ppTInfo)
@@ -1024,6 +1044,8 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetMops(MEMBERID memid,
 HRESULT STDMETHODCALLTYPE CXTypeInfo::GetContainingTypeLib(ITypeLib **ppTLib,
                                                            UINT *pIndex)
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetContainingTypeLib");
 
     if (!ppTLib || !pIndex)
@@ -1068,6 +1090,8 @@ void STDMETHODCALLTYPE CXTypeInfo::ReleaseVarDesc(VARDESC *pVarDesc)
 
 STDMETHODIMP InterfaceOleWrapper::GetTypeInfo(unsigned int iTInfo, LCID, ITypeInfo ** ppTInfo)
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::GetTypeInfo(" << iTInfo << ")");
 
     if (!ppTInfo)
@@ -1108,6 +1132,8 @@ STDMETHODIMP InterfaceOleWrapper::GetIDsOfNames(REFIID /*riid*/,
                                                 LCID /*lcid*/,
                                                 DISPID * rgdispid )
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::GetIDsOfNames("
              << OUString(o3tl::toU(rgszNames[0]))
              << (cNames > 1 ? "...!" : "") << "," << cNames << ")");
@@ -1776,6 +1802,8 @@ STDMETHODIMP InterfaceOleWrapper::Invoke(DISPID dispidMember,
                                          EXCEPINFO * pexcepinfo,
                                          unsigned int * puArgErr )
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::Invoke(" << dispidMember << ")");
 
     comphelper::ProfileZone aZone("COM Bridge");
@@ -2063,6 +2091,8 @@ public:
                                            VARIANT *rgVar,
                                            ULONG *pCeltFetched) override
     {
+        comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
         if (pCeltFetched)
             *pCeltFetched = 0;
 
@@ -2097,6 +2127,8 @@ public:
 
     virtual HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE Skip(ULONG celt) override
     {
+        comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
         while (celt > 0)
         {
             if (!mxEnumeration->hasMoreElements())
@@ -2339,6 +2371,8 @@ public:
                                            LPCONNECTDATA rgcd,
                                            ULONG *pcFetched) override
     {
+        comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
         if (!rgcd)
         {
             SAL_INFO("extensions.olebridge", this << "@CXEnumConnections::Next(" << cConnections << "): E_POINTER");
@@ -2453,6 +2487,8 @@ public:
     virtual HRESULT STDMETHODCALLTYPE Advise(IUnknown *pUnkSink,
                                              DWORD *pdwCookie) override
     {
+        comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
         SAL_INFO("extensions.olebridge", this << "@CXConnectionPoint::Advise(" << pUnkSink << ")");
 
         if (!pdwCookie)
@@ -2474,6 +2510,8 @@ public:
 
     virtual HRESULT STDMETHODCALLTYPE Unadvise(DWORD dwCookie) override
     {
+        comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
         SAL_INFO("extensions.olebridge", this << "@CXConnectionPoint::Unadvise(" << dwCookie << ")");
 
         if (dwCookie == 0 || dwCookie > mvISinks.size())
@@ -2490,6 +2528,8 @@ public:
 
     virtual HRESULT STDMETHODCALLTYPE EnumConnections(IEnumConnections **ppEnum) override
     {
+        comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
         HRESULT nResult;
 
         SAL_INFO("extensions.olebridge", this << "@CXConnectionPoint::EnumConnections...");
@@ -2751,6 +2791,8 @@ STDMETHODIMP InterfaceOleWrapper::GetNameSpaceParent(
 HRESULT STDMETHODCALLTYPE InterfaceOleWrapper::GetClassInfo (
     /* [out] */ ITypeInfo **ppTI)
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::GetClassInfo");
 
     if (!ppTI)
@@ -2795,6 +2837,8 @@ HRESULT STDMETHODCALLTYPE InterfaceOleWrapper::FindConnectionPoint(
     /* [in] */ REFIID riid,
     /* [out] */ IConnectionPoint **ppCP)
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::FindConnectionPoint(" << riid << ")");
 
     if (!ppCP)
@@ -2909,6 +2953,8 @@ STDMETHODIMP  UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember, REFIID /*
                          DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,
                          unsigned int * puArgErr )
 {
+    comphelper::Automation::AutomationInvokedZone aAutomationActive;
+
     HRESULT ret = S_OK;
     try
     {
commit 08259ed73142e8644f8e254644d2e18487a66855
Author: Tor Lillqvist <tml at collabora.com>
Date:   Wed Apr 25 16:09:59 2018 +0300

    Introduce comphelper::Automation::AutomationInvokedZone
    
    Enables finding out anywhere whether the thread is processing a call
    from an Automation client. Not sure how I have managed without this
    until now.
    
    Presumably the Invocation_Impl::mbFromOLE variable in stoc can be
    replaced by a call of comphelper::Automation::AutomationInvokedZone::
    isActive().
    
    Change-Id: Ib79ec5f6dff17af25c8539d2907c7cd5d7b9a62c

diff --git a/comphelper/Library_comphelper.mk b/comphelper/Library_comphelper.mk
index 4a24d65da15c..388e036d64c8 100644
--- a/comphelper/Library_comphelper.mk
+++ b/comphelper/Library_comphelper.mk
@@ -91,6 +91,7 @@ $(eval $(call gb_Library_add_exception_objects,comphelper,\
     comphelper/source/misc/accimplaccess \
     comphelper/source/misc/anytostring \
     comphelper/source/misc/asyncnotification \
+    comphelper/source/misc/automationinvokedzone \
     comphelper/source/misc/backupfilehelper \
     comphelper/source/misc/base64 \
     comphelper/source/misc/comphelper_module \
diff --git a/comphelper/source/misc/automationinvokedzone.cxx b/comphelper/source/misc/automationinvokedzone.cxx
new file mode 100644
index 000000000000..2134217a1eaa
--- /dev/null
+++ b/comphelper/source/misc/automationinvokedzone.cxx
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#include <cassert>
+
+#include <comphelper/automationinvokedzone.hxx>
+
+namespace comphelper
+{
+namespace Automation
+{
+thread_local static int nActiveount = 0;
+
+bool AutomationInvokedZone::isActive() { return nActiveount > 0; }
+
+AutomationInvokedZone::AutomationInvokedZone()
+{
+    assert(nActiveount < 1000);
+    nActiveount++;
+}
+
+AutomationInvokedZone::~AutomationInvokedZone()
+{
+    assert(nActiveount > 0);
+    nActiveount--;
+}
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/comphelper/automationinvokedzone.hxx b/include/comphelper/automationinvokedzone.hxx
new file mode 100644
index 000000000000..13b674efa7e1
--- /dev/null
+++ b/include/comphelper/automationinvokedzone.hxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#ifndef INCLUDED_COMPHELPER_AUTOMATIONINVOKEDZONE_HXX
+#define INCLUDED_COMPHELPER_AUTOMATIONINVOKEDZONE_HXX
+
+#include <comphelper/comphelperdllapi.h>
+
+// Helpers for use when calling into LO from an Automation (OLE
+// Automation) client.
+
+namespace comphelper
+{
+namespace Automation
+{
+// Create an object of this class at the start of a function directly invoked from an Automation
+// client.
+
+class COMPHELPER_DLLPUBLIC AutomationInvokedZone
+{
+public:
+    AutomationInvokedZone();
+
+    ~AutomationInvokedZone();
+
+    static bool isActive();
+};
+}
+}
+
+#endif // INCLUDED_COMPHELPER_AUTOMATIONINVOKEDZONE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit dee3ca5695927900a2fa33f43adc7357f85781b9
Author: Tor Lillqvist <tml at collabora.com>
Date:   Tue Apr 24 22:36:40 2018 +0300

    Do same trick in setValue() as earlier in getValue() for Automation clients
    
    Also, it is UnknownPropertyException that we need to catch, not
    RuntimeException. Did I not actually exercise my change to getValue()
    back in February?
    
    Change-Id: If13eaa9bbecd15f5330a4102ae932f2ec0c7ecd4

diff --git a/stoc/source/invocation/invocation.cxx b/stoc/source/invocation/invocation.cxx
index 68ea0ce3ccc3..5ffbb9cf586e 100644
--- a/stoc/source/invocation/invocation.cxx
+++ b/stoc/source/invocation/invocation.cxx
@@ -482,7 +482,7 @@ Any Invocation_Impl::getValue( const OUString& PropertyName )
         if (_xDirect.is())
             return _xDirect->getValue( PropertyName );
     }
-    catch (RuntimeException &)
+    catch (UnknownPropertyException &)
     {
         if (!mbFromOLE)
             throw;
@@ -518,75 +518,83 @@ Any Invocation_Impl::getValue( const OUString& PropertyName )
 
 void Invocation_Impl::setValue( const OUString& PropertyName, const Any& Value )
 {
-    if (_xDirect.is())
-        _xDirect->setValue( PropertyName, Value );
-    else
+    try
     {
-        try
-        {
-            // 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
-                    throw RuntimeException( "no type converter service!" );
-            }
-            // NameContainer
-            else if( _xNameContainer.is() )
-            {
-                // Note: This misfeature deliberately not adapted to apply to objects which
-                // have XNameReplace but not XNameContainer
-                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
-                    throw RuntimeException( "no type converter service!" );
-
-                // Replace if present, otherwise insert
-                if (_xNameContainer->hasByName( PropertyName ))
-                    _xNameContainer->replaceByName( PropertyName, aConv );
-                else
-                    _xNameContainer->insertByName( PropertyName, aConv );
-            }
-            else
-                throw UnknownPropertyException( "no introspection nor name container!" );
-        }
-        catch (UnknownPropertyException &)
-        {
-            throw;
-        }
-        catch (CannotConvertException &)
+        if (_xDirect.is())
         {
-            throw;
+            _xDirect->setValue( PropertyName, Value );
+            return;
         }
-        catch (InvocationTargetException &)
-        {
+    }
+    catch (UnknownPropertyException &)
+    {
+        if (!mbFromOLE)
             throw;
-        }
-        catch (RuntimeException &)
+    }
+    try
+    {
+        // Properties
+        if( _xIntrospectionAccess.is() && _xPropertySet.is()
+            && _xIntrospectionAccess->hasProperty(
+                PropertyName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
         {
-            throw;
+            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
+                throw RuntimeException( "no type converter service!" );
         }
-        catch (const Exception & exc)
+        // NameContainer
+        else if( _xNameContainer.is() )
         {
-            css::uno::Any anyEx = cppu::getCaughtException();
-            throw InvocationTargetException(
-                "exception occurred in setValue(): " + exc.Message,
-                Reference< XInterface >(), anyEx );
+            // Note: This misfeature deliberately not adapted to apply to objects which
+            // have XNameReplace but not XNameContainer
+            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
+                throw RuntimeException( "no type converter service!" );
+
+            // Replace if present, otherwise insert
+            if (_xNameContainer->hasByName( PropertyName ))
+                _xNameContainer->replaceByName( PropertyName, aConv );
+            else
+                _xNameContainer->insertByName( PropertyName, aConv );
         }
+        else
+            throw UnknownPropertyException( "no introspection nor name container!" );
+    }
+    catch (UnknownPropertyException &)
+    {
+        throw;
+    }
+    catch (CannotConvertException &)
+    {
+        throw;
+    }
+    catch (InvocationTargetException &)
+    {
+        throw;
+    }
+    catch (RuntimeException &)
+    {
+        throw;
+    }
+    catch (const Exception & exc)
+    {
+        css::uno::Any anyEx = cppu::getCaughtException();
+        throw InvocationTargetException(
+            "exception occurred in setValue(): " + exc.Message,
+            Reference< XInterface >(), anyEx );
     }
 }
 
commit 5cc28c5e9455a7923153f82dcf18e76570e36717
Author: Tor Lillqvist <tml at collabora.com>
Date:   Tue Apr 24 21:58:59 2018 +0300

    Decrease fragility in odd use cases with no current document (yet)
    
    Especially, this happens when an Automation client wants to open a
    Calc document. Equivalent to the code for the same situation in
    getCurrentWordDoc().
    
    Change-Id: I209a72dcae49f18cd265e0c6c2790618e1ebb4a1

diff --git a/vbahelper/source/vbahelper/vbahelper.cxx b/vbahelper/source/vbahelper/vbahelper.cxx
index 55c613341bcd..c34559b769f6 100644
--- a/vbahelper/source/vbahelper/vbahelper.cxx
+++ b/vbahelper/source/vbahelper/vbahelper.cxx
@@ -262,7 +262,13 @@ getCurrentExcelDoc( const uno::Reference< uno::XComponentContext >& xContext )
     }
     catch (const uno::Exception&)
     {
-        xModel = getThisExcelDoc( xContext );
+        try
+        {
+            xModel = getThisExcelDoc( xContext );
+        }
+        catch (const uno::Exception&)
+        {
+        }
     }
     return xModel;
 }
commit e4a99a3c502c0285b6fb542d84a9bffde045e526
Author: Tor Lillqvist <tml at collabora.com>
Date:   Tue Apr 24 19:56:17 2018 +0300

    Make convertDispparamsArgs() handle mismatch in number of parameters sanely
    
    Parameters come in in reverse order in pdispparams. There might be
    less parameters than expected. In that case, assume the missing ones
    are "optional" (but can't be marked as such in UNO IDL), and fill in
    the rest with empty Anys. There might also be more parameters than
    expected. In that case, assume the oovbaapi UNO IDL hasn't kept up
    with added optional parameters in MSO, and just ignore the extra ones,
    as long as they are empty.
    
    An example: incoming parameters: <12, 13, "foo/bar.tem">
    
    Expected paramters: (string filename, int something, int
    somethingElse, Any whatever, Any whateverElse)
    
    Here the existing incoming parameters are placed in reverse order in
    the first three outgoing parameters, and the rest of the outgoing
    paramters are passed as empty Anys.
    
    Another example: incoming parameters: <EMPTY, TRUE>
    
    Expected parameters: (bool flag)
    
    Here the TRUE is passed as the sole outgoing parameter, and the
    incoming EMPTY is ignored.
    
    Still an example: incoming parameters: <"foo.doc", TRUE>
    
    Expected parameters: (bool flag)
    
    This throws an error as the incoming non-empty extra parameter
    presumably indicates something important, but there is no
    corresponding outgoing parameter to pass it in.
    
    Change-Id: Ib04f9701099ecb899e792d99ff86588022b3bbf6

diff --git a/extensions/source/ole/unoobjw.cxx b/extensions/source/ole/unoobjw.cxx
index 35a70c5aa8d8..083688683e0b 100644
--- a/extensions/source/ole/unoobjw.cxx
+++ b/extensions/source/ole/unoobjw.cxx
@@ -1253,8 +1253,35 @@ STDMETHODIMP InterfaceOleWrapper::GetIDsOfNames(REFIID /*riid*/,
 void InterfaceOleWrapper::convertDispparamsArgs(DISPID id,
     unsigned short /*wFlags*/, DISPPARAMS* pdispparams, Sequence<Any>& rSeq)
 {
+    // Parameters come in in reverse order in pdispparams. There might be less parameters than
+    // expected. In that case, assume they are "optional" (but can't be marked as such in UNO IDL),
+    // and fill in the rest with empty Anys. There might also be more than expected. In that case,
+    // assume the oovbaapi UNO IDL hasn't kept up with added optional parameters in MSO, and just
+    // ignore the extra ones, as long as they are empty.
+
+    // An example: incoming parameters: <12, 13, "foo/bar.tem">
+    //
+    // Expected paramters: (string filename, int something, int somethingElse, Any whatever, Any
+    // whateverElse)
+    //
+    // Here the existing incoming parameters are placed in reverse order in the first three outgoing
+    // parameters, and the rest of the outgoing paramters are kept as empty Anys.
+    //
+    // Another example: incoming parameters: <EMPTY, TRUE>
+    //
+    // Expected parameters: (bool flag)
+    //
+    // Here the TRUE is passed as the sole outgoing parameter, and the incoming EMPTY is ignored.
+    //
+    // Still an example: incoming parameters: <"foo.doc", TRUE>
+    //
+    // Expected parameters: (bool flag)
+    //
+    // This throws an error as the incoming string parameter presumably should do something important,
+    // but there is no corresponding outgoing parameter.
+
     HRESULT hr = S_OK;
-    const int countArgs = pdispparams->cArgs;
+    const int countIncomingArgs = pdispparams->cArgs;
 
     //Get type information for the current call
     InvocationInfo info;
@@ -1263,33 +1290,39 @@ void InterfaceOleWrapper::convertDispparamsArgs(DISPID id,
                   "[automation bridge]InterfaceOleWrapper::convertDispparamsArgs \n"
                   "Could not obtain type information for current call.");
 
-    // We accept less or even more parameters (on certain conditions) than expected. So size rSeq
-    // according to the number of expected parameters.
-    const int expectedArgs = info.aParamTypes.getLength();
+    // Size rSeq according to the number of expected parameters.
+    const int expectedArgs = info.aParamTypes.getLength() + (info.eMemberType == MemberType_PROPERTY ? 1 : 0);
     rSeq.realloc( expectedArgs );
     Any* pParams = rSeq.getArray();
 
     Any anyParam;
 
-    for (int i = 0; i < std::max(countArgs, expectedArgs); i++)
+    int outgoingArgIndex = 0;
+
+    // Go through incoming parameters in reverse order, i.e. in the order as declared in IDL
+    for (int i = std::max(countIncomingArgs, expectedArgs) - 1; i >= 0; i--)
     {
         // Ignore too many parameters if they are VT_EMPTY anyway
-        if ( i < countArgs && i >= expectedArgs && pdispparams->rgvarg[i].vt == VT_EMPTY )
+        if ( outgoingArgIndex >= expectedArgs && pdispparams->rgvarg[i].vt == VT_EMPTY )
             continue;
 
         // But otherwise too many parameters is an error
-        if ( i < countArgs && i >= expectedArgs )
+        if ( outgoingArgIndex >= expectedArgs )
             throw BridgeRuntimeError( "[automation bridge] Too many parameters" );
 
         if (info.eMemberType == MemberType_METHOD &&
-            info.aParamModes[ expectedArgs - i - 1 ] == ParamMode_OUT)
+            info.aParamModes[ outgoingArgIndex ] == ParamMode_OUT)
+        {
+            outgoingArgIndex++;
             continue;
+        }
 
-        if (i < countArgs)
+        if (i < countIncomingArgs)
         {
             if(convertValueObject( & pdispparams->rgvarg[i], anyParam))
             { //a param is a ValueObject and could be converted
-                pParams[ expectedArgs - i - 1 ] = anyParam;
+                pParams[ outgoingArgIndex ] = anyParam;
+                outgoingArgIndex++;
                 continue;
             }
         }
@@ -1297,6 +1330,7 @@ void InterfaceOleWrapper::convertDispparamsArgs(DISPID id,
         {
             // A missing arg. Let's hope it is de facto optional (there is no way in UNO IDL to mark
             // a parameter as optional). The corresponding slot in pParams is already a void Any.
+            // Here we don't increase outgoingArgIndex!
             continue;
         }
 
@@ -1309,9 +1343,13 @@ void InterfaceOleWrapper::convertDispparamsArgs(DISPID id,
 
         // Check for JScript out and in/out paramsobjects (VT_DISPATCH).
         // To find them out we use typeinformation of the function being called.
+
+        // No idea how this stuff, originally written for JScript, works for other Automation
+        // clients.
+
         if( pdispparams->rgvarg[i].vt == VT_DISPATCH )
         {
-            if( info.eMemberType == MemberType_METHOD && info.aParamModes[ expectedArgs - i - 1 ] == ParamMode_INOUT)
+            if( info.eMemberType == MemberType_METHOD && info.aParamModes[ outgoingArgIndex ] == ParamMode_INOUT)
             {
                 // INOUT-param
                 // Index ( property) "0" contains the actual IN-param. The object is a JScript
@@ -1340,13 +1378,15 @@ void InterfaceOleWrapper::convertDispparamsArgs(DISPID id,
 
         if(info.eMemberType == MemberType_METHOD)
             variantToAny( & varParam, anyParam,
-                           info.aParamTypes[ expectedArgs - i - 1 ]);
+                           info.aParamTypes[ outgoingArgIndex ]);
         else if(info.eMemberType == MemberType_PROPERTY)
             variantToAny( & varParam, anyParam, info.aType);
         else
             OSL_ASSERT(false);
 
-        pParams[ expectedArgs - i - 1 ]= anyParam;
+        if (outgoingArgIndex < expectedArgs)
+            pParams[ outgoingArgIndex ]= anyParam;
+        outgoingArgIndex++;
     }// end for / iterating over all parameters
 }
 
commit 16a1bd541610c53aee4df08e9f95e06abb36be37
Author: Tor Lillqvist <tml at collabora.com>
Date:   Tue Apr 24 01:29:58 2018 +0300

    Implement EnumConnections, and fix handling of mismatched parameter number
    
    If we have too few parameters, fill with empty ones, as before. If we
    have more paramters than the called method expects, but the extra ones
    are empty anyway, ignore them. Do all of this in
    convertDispparamsArgs(). This improves interoperability with typical
    Automation clients.
    
    Change-Id: I47376993dc10b401e4c349e19b2bbe4be9f8f444

diff --git a/extensions/source/ole/unoobjw.cxx b/extensions/source/ole/unoobjw.cxx
index 4820772f5748..35a70c5aa8d8 100644
--- a/extensions/source/ole/unoobjw.cxx
+++ b/extensions/source/ole/unoobjw.cxx
@@ -1253,15 +1253,8 @@ STDMETHODIMP InterfaceOleWrapper::GetIDsOfNames(REFIID /*riid*/,
 void InterfaceOleWrapper::convertDispparamsArgs(DISPID id,
     unsigned short /*wFlags*/, DISPPARAMS* pdispparams, Sequence<Any>& rSeq)
 {
-    HRESULT hr= S_OK;
-    sal_Int32 countArgs= pdispparams->cArgs;
-    if( countArgs == 0)
-        return;
-
-    rSeq.realloc( countArgs);
-    Any*    pParams = rSeq.getArray();
-
-    Any anyParam;
+    HRESULT hr = S_OK;
+    const int countArgs = pdispparams->cArgs;
 
     //Get type information for the current call
     InvocationInfo info;
@@ -1270,17 +1263,42 @@ void InterfaceOleWrapper::convertDispparamsArgs(DISPID id,
                   "[automation bridge]InterfaceOleWrapper::convertDispparamsArgs \n"
                   "Could not obtain type information for current call.");
 
-    for (int i = 0; i < countArgs; i++)
+    // We accept less or even more parameters (on certain conditions) than expected. So size rSeq
+    // according to the number of expected parameters.
+    const int expectedArgs = info.aParamTypes.getLength();
+    rSeq.realloc( expectedArgs );
+    Any* pParams = rSeq.getArray();
+
+    Any anyParam;
+
+    for (int i = 0; i < std::max(countArgs, expectedArgs); i++)
     {
+        // Ignore too many parameters if they are VT_EMPTY anyway
+        if ( i < countArgs && i >= expectedArgs && pdispparams->rgvarg[i].vt == VT_EMPTY )
+            continue;
+
+        // But otherwise too many parameters is an error
+        if ( i < countArgs && i >= expectedArgs )
+            throw BridgeRuntimeError( "[automation bridge] Too many parameters" );
+
         if (info.eMemberType == MemberType_METHOD &&
-            info.aParamModes[ countArgs - i -1 ]  == ParamMode_OUT)
+            info.aParamModes[ expectedArgs - i - 1 ] == ParamMode_OUT)
             continue;
 
-         if(convertValueObject( & pdispparams->rgvarg[i], anyParam))
-         { //a param is a ValueObject and could be converted
-            pParams[countArgs - (i + 1)] = anyParam;
-             continue;
-         }
+        if (i < countArgs)
+        {
+            if(convertValueObject( & pdispparams->rgvarg[i], anyParam))
+            { //a param is a ValueObject and could be converted
+                pParams[ expectedArgs - i - 1 ] = anyParam;
+                continue;
+            }
+        }
+        else
+        {
+            // A missing arg. Let's hope it is de facto optional (there is no way in UNO IDL to mark
+            // a parameter as optional). The corresponding slot in pParams is already a void Any.
+            continue;
+        }
 
         // If the param is an out, in/out parameter in
         // JScript (Array object, with value at index 0) then we
@@ -1293,7 +1311,7 @@ void InterfaceOleWrapper::convertDispparamsArgs(DISPID id,
         // To find them out we use typeinformation of the function being called.
         if( pdispparams->rgvarg[i].vt == VT_DISPATCH )
         {
-            if( info.eMemberType == MemberType_METHOD && info.aParamModes[ countArgs - i -1 ]  == ParamMode_INOUT)
+            if( info.eMemberType == MemberType_METHOD && info.aParamModes[ expectedArgs - i - 1 ] == ParamMode_INOUT)
             {
                 // INOUT-param
                 // Index ( property) "0" contains the actual IN-param. The object is a JScript
@@ -1318,17 +1336,17 @@ void InterfaceOleWrapper::convertDispparamsArgs(DISPID id,
         }
 
         if( varParam.vt == VT_EMPTY) // then it was no in/out parameter
-                 varParam= pdispparams->rgvarg[i];
+            varParam= pdispparams->rgvarg[i];
 
         if(info.eMemberType == MemberType_METHOD)
             variantToAny( & varParam, anyParam,
-                           info.aParamTypes[ countArgs - i - 1]);
+                           info.aParamTypes[ expectedArgs - i - 1 ]);
         else if(info.eMemberType == MemberType_PROPERTY)
             variantToAny( & varParam, anyParam, info.aType);
         else
             OSL_ASSERT(false);
 
-        pParams[countArgs - (i + 1)]= anyParam;
+        pParams[ expectedArgs - i - 1 ]= anyParam;
     }// end for / iterating over all parameters
 }
 
@@ -1748,17 +1766,6 @@ STDMETHODIMP InterfaceOleWrapper::Invoke(DISPID dispidMember,
 
                         convertDispparamsArgs(dispidMember, wFlags, pdispparams , params );
 
-                        // Pass missing (hopefully optional) parameters as Any().
-                        InvocationInfo aInvocationInfo;
-                        getInvocationInfoForCall(dispidMember, aInvocationInfo);
-                        if (pdispparams->cArgs < sal_uInt32(aInvocationInfo.aParamTypes.getLength()))
-                        {
-                            params.realloc(aInvocationInfo.aParamTypes.getLength());
-                            Any* pParams = params.getArray();
-                            for (int i = pdispparams->cArgs; i < aInvocationInfo.aParamTypes.getLength(); ++i)
-                                pParams[i] = Any();
-                        }
-
                         ret= doInvoke(pdispparams, pvarResult,
                                       pexcepinfo, puArgErr, d.name, params);
                     }
@@ -2261,6 +2268,99 @@ Sink::Call( const OUString& Method, Sequence< Any >& Arguments )
     SAL_WARN("extensions.olebridge", "Sink::Call: Uknown method '" << Method << "'");
 }
 
+class CXEnumConnections : public IEnumConnections,
+                          public CComObjectRoot
+{
+public:
+    CXEnumConnections()
+    {
+    }
+
+    ~CXEnumConnections()
+    {
+    }
+
+    BEGIN_COM_MAP(CXEnumConnections)
+        COM_INTERFACE_ENTRY(IEnumConnections)
+    END_COM_MAP()
+
+    DECLARE_NOT_AGGREGATABLE(CXEnumConnections)
+
+    void Init(std::vector<IUnknown*>& rUnknowns, std::vector<DWORD>& rCookies)
+    {
+        SAL_INFO("extensions.olebridge", this << "@CXEnumConnections::Init");
+        SAL_WARN_IF(rUnknowns.size() != rCookies.size(), "extensions.olebridge", "Vectors of different size");
+        mvUnknowns = rUnknowns;
+        mvCookies = rCookies;
+        mnIndex = 0;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Next(ULONG cConnections,
+                                           LPCONNECTDATA rgcd,
+                                           ULONG *pcFetched) override
+    {
+        if (!rgcd)
+        {
+            SAL_INFO("extensions.olebridge", this << "@CXEnumConnections::Next(" << cConnections << "): E_POINTER");
+            return E_POINTER;
+        }
+
+        if (pcFetched && cConnections != 1)
+        {
+            SAL_INFO("extensions.olebridge", this << "@CXEnumConnections::Next(" << cConnections << "): E_INVALIDARG");
+            return E_POINTER;
+        }
+
+        ULONG nFetched = 0;
+        while (nFetched < cConnections && mnIndex < mvUnknowns.size())
+        {
+            rgcd[nFetched].pUnk = mvUnknowns[mnIndex];
+            rgcd[nFetched].pUnk->AddRef();
+            rgcd[nFetched].dwCookie = mvCookies[mnIndex];
+            ++nFetched;
+            ++mnIndex;
+        }
+        if (nFetched != cConnections)
+        {
+            SAL_INFO("extensions.olebridge", this << "@CXEnumConnections::Next(" << cConnections << "): S_FALSE");
+            if (pcFetched)
+                *pcFetched = nFetched;
+            return S_FALSE;
+        }
+        SAL_INFO("extensions.olebridge", this << "@CXEnumConnections::Next(" << cConnections << "): S_OK");
+        if (pcFetched)
+            *pcFetched = nFetched;
+
+        return S_OK;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Skip(ULONG cConnections) override
+    {
+        SAL_INFO("extensions.olebridge", this << "@CXEnumConnections::Skip(" << cConnections << "): E_NOTIMPL");
+
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Reset() override
+    {
+        SAL_INFO("extensions.olebridge", this << "@CXEnumConnections::Reset: E_NOTIMPL");
+
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Clone(IEnumConnections** /* ppEnum */) override
+    {
+        SAL_INFO("extensions.olebridge", this << "@CXEnumConnections::Clone: E_NOTIMPL");
+
+        return E_NOTIMPL;
+    }
+
+private:
+    std::vector<IUnknown*> mvUnknowns;
+    std::vector<DWORD> mvCookies;
+    ULONG mnIndex;
+};
+
 class CXConnectionPoint : public IConnectionPoint,
                           public CComObjectRoot
 {
@@ -2350,16 +2450,39 @@ public:
 
     virtual HRESULT STDMETHODCALLTYPE EnumConnections(IEnumConnections **ppEnum) override
     {
-        (void) ppEnum;
-        SAL_WARN("extensions.olebridge", this << "@CXConnectionPoint::EnumConnections: E_NOTIMPL");
-        return E_NOTIMPL;
+        HRESULT nResult;
+
+        SAL_INFO("extensions.olebridge", this << "@CXConnectionPoint::EnumConnections...");
+
+        if (!ppEnum)
+        {
+            SAL_INFO("extensions.olebridge", "..." << this << "@CXConnectionPoint::EnumConnections: E_POINTER");
+            return E_POINTER;
+        }
+
+        CComObject<CXEnumConnections>* pEnumConnections;
+
+        nResult = CComObject<CXEnumConnections>::CreateInstance(&pEnumConnections);
+        if (FAILED(nResult))
+        {
+            SAL_INFO("extensions.olebridge", "..." << this << "@CXConnectionPoint::EnumConnections: " << WindowsErrorStringFromHRESULT(nResult));
+            return nResult;
+        }
+
+        pEnumConnections->AddRef();
+
+        pEnumConnections->Init(mvISinks, mvCookies);
+        *ppEnum = pEnumConnections;
+
+        SAL_INFO("extensions.olebridge", "..." << this << "@CXConnectionPoint::EnumConnections: S_OK");
+
+        return S_OK;
     }
 
-private:
     InterfaceOleWrapper* mpInterfaceOleWrapper;
     std::vector<IUnknown*> mvISinks;
     std::vector<Reference<ooo::vba::XSink>> mvXSinks;
-    std::vector<sal_uInt32> mvCookies;
+    std::vector<DWORD> mvCookies;
     Reference<XMultiServiceFactory> mxMSF;
     Reference<ooo::vba::XConnectionPoint> mxCP;
     ooo::vba::TypeAndIID maTypeAndIID;
commit c86c08ea00e284ce4381b26609cd83fab17e4991
Author: Tor Lillqvist <tml at collabora.com>
Date:   Mon Apr 23 22:20:52 2018 +0300

    Make SAL_INFO logging style more useful
    
    Make it easier to search for a specific class and function in the
    output by outputting the 'this' pointer first, not between the class
    and function name.
    
    Change-Id: Ia6e087e3a4be9e701c418aedb9b6af5fd4f6e828

diff --git a/extensions/source/ole/unoobjw.cxx b/extensions/source/ole/unoobjw.cxx
index f0e533a43025..4820772f5748 100644
--- a/extensions/source/ole/unoobjw.cxx
+++ b/extensions/source/ole/unoobjw.cxx
@@ -188,7 +188,7 @@ InterfaceOleWrapper::~InterfaceOleWrapper()
 
 STDMETHODIMP InterfaceOleWrapper::QueryInterface(REFIID riid, LPVOID FAR * ppv)
 {
-    SAL_INFO("extensions.olebridge", "InterfaceOleWrapper@" << this << "::QueryInterface " << riid);
+    SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::QueryInterface(" << riid << ")");
 
     HRESULT ret= S_OK;
 
@@ -283,7 +283,7 @@ STDMETHODIMP  InterfaceOleWrapper::getOriginalUnoStruct( Any * pStruct)
 
 STDMETHODIMP InterfaceOleWrapper::GetTypeInfoCount( unsigned int *pctinfo )
 {
-    SAL_INFO("extensions.olebridge", "InterfaceOleWrapper@" << this << "::GetTypeInfoCount()");
+    SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::GetTypeInfoCount");
 
     if (!pctinfo)
         return E_POINTER;
@@ -392,7 +392,7 @@ public:
               const OUString& sImplementationName,
               Reference<XMultiServiceFactory> xMSF)
     {
-        SAL_INFO("extensions.olebridge", "CXTypeLib::Init() this=" << this << " for " << sImplementationName);
+        SAL_INFO("extensions.olebridge", this << "@CXTypeLib::Init for " << sImplementationName);
         mxOrigin = xOrigin;
         msImplementationName = sImplementationName;
         mxMSF = xMSF;
@@ -400,7 +400,7 @@ public:
 
     virtual UINT STDMETHODCALLTYPE GetTypeInfoCount() override
     {
-        SAL_WARN("extensions.olebridge", "CXTypeLib@" << this << "::GetTypeInfoCount()");
+        SAL_WARN("extensions.olebridge", this << "@CXTypeLib::GetTypeInfoCount");
         return 1;
     }
 
@@ -409,7 +409,7 @@ public:
     {
         (void) index;
         (void) ppTInfo;
-        SAL_WARN("extensions.olebridge", "CXTypeLib@" << this << "::GetTypeInfo: NOTIMPL");
+        SAL_WARN("extensions.olebridge", this << "@CXTypeLib::GetTypeInfo: E_NOTIMPL");
         return E_NOTIMPL;
     }
 
@@ -418,14 +418,14 @@ public:
     {
         (void) index;
         (void) pTKind;
-        SAL_WARN("extensions.olebridge", "CXTypeLib@" << this << "::GetTypeInfoType: NOTIMPL");
+        SAL_WARN("extensions.olebridge", this << "@CXTypeLib::GetTypeInfoType: E_NOTIMPL");
         return E_NOTIMPL;
     }
 
     virtual HRESULT STDMETHODCALLTYPE GetTypeInfoOfGuid(REFGUID guid,
                                                         ITypeInfo **ppTInfo) override
     {
-        SAL_INFO("extensions.olebridge", "CXTypeLib@" << this << "::GetTypeInfoOfGuid(" << guid << ")");
+        SAL_INFO("extensions.olebridge", this << "@CXTypeLib::GetTypeInfoOfGuid(" << guid << ")");
         if (!ppTInfo)
             return E_POINTER;
 
@@ -489,14 +489,14 @@ public:
     virtual HRESULT STDMETHODCALLTYPE GetLibAttr(TLIBATTR **ppTLibAttr) override
     {
         (void) ppTLibAttr;
-        SAL_WARN("extensions.olebridge", "CXTypeLib@" << this << "::GetLibAttr: NOTIMPL");
+        SAL_WARN("extensions.olebridge", this << "@CXTypeLib::GetLibAttr: E_NOTIMPL");
         return E_NOTIMPL;
     }
 
     virtual HRESULT STDMETHODCALLTYPE GetTypeComp(ITypeComp **ppTComp) override
     {
         (void) ppTComp;
-        SAL_WARN("extensions.olebridge", "CXTypeLib@" << this << "::GetTypeComp: NOTIMPL");
+        SAL_WARN("extensions.olebridge", this << "@CXTypeLib::GetTypeComp: E_NOTIMPL");
         return E_NOTIMPL;
     }
 
@@ -511,7 +511,7 @@ public:
         (void) pBstrDocString;
         (void) pdwHelpContext;
         (void) pBstrHelpFile;
-        SAL_WARN("extensions.olebridge", "CXTypeLib@" << this << "::GetDocumentation: NOTIMPL");
+        SAL_WARN("extensions.olebridge", this << "@CXTypeLib::GetDocumentation: E_NOTIMPL");
         return E_NOTIMPL;
     }
 
@@ -522,7 +522,7 @@ public:
         (void) szNameBuf;
         (void) lHashVal;
         (void) pfName;
-        SAL_WARN("extensions.olebridge", "CXTypeLib@" << this << "::IsName: NOTIMPL");
+        SAL_WARN("extensions.olebridge", this << "@CXTypeLib:IsName: E_NOTIMPL");
         return E_NOTIMPL;
     }
 
@@ -537,14 +537,14 @@ public:
         (void) ppTInfo;
         (void) rgMemId;
         (void) pcFound;
-        SAL_WARN("extensions.olebridge", "CXTypeLib@" << this << "::FindName: NOTIMPL");
+        SAL_WARN("extensions.olebridge", this << "@CXTypeLib::FindName: E_NOTIMPL");
         return E_NOTIMPL;
     }
 
     virtual void STDMETHODCALLTYPE ReleaseTLibAttr(TLIBATTR *pTLibAttr) override
     {
         (void) pTLibAttr;
-        SAL_WARN("extensions.olebridge", "CXTypeLib@" << this << "::ReleaseTLibAttr: NOTIMPL");
+        SAL_WARN("extensions.olebridge", this << "@CXTypeLib::ReleaseTLibAttr: E_NOTIMPL");
     }
 
 private:
@@ -558,7 +558,7 @@ void CXTypeInfo::InitForCoclass(Reference<XInterface> xOrigin,
                                 const IID& rIID,
                                 Reference<XMultiServiceFactory> xMSF)
 {
-    SAL_INFO("extensions.olebridge", "CXTypeInfo::InitForCoclass() this=" << this << " for " << rIID << " (" << sImplementationName << ")");
+    SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::InitForCoclass(" << sImplementationName << "," << rIID << ")");
     meKind = Kind::COCLASS;
     mxOrigin = xOrigin;
     msImplementationName = sImplementationName;
@@ -571,7 +571,7 @@ void CXTypeInfo::InitForClassItself(Reference<XInterface> xOrigin,
                                     const IID& rIID,
                                     Reference<XMultiServiceFactory> xMSF)
 {
-    SAL_INFO("extensions.olebridge", "CXTypeInfo::InitForClassItself() this=" << this << " for " << rIID << " (" << sImplementationName << ")");
+    SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::InitForClassItself(" << sImplementationName << "," << rIID << ")");
     meKind = Kind::MAIN;
     mxOrigin = xOrigin;
     msImplementationName = sImplementationName;
@@ -585,7 +585,7 @@ void CXTypeInfo::InitForOutgoing(Reference<XInterface> xOrigin,
                                  Reference<XMultiServiceFactory> xMSF,
                                  Type aType)
 {
-    SAL_INFO("extensions.olebridge", "CXTypeInfo::InitForOutgoing() this=" << this << " for " << rIID << " (" << sInterfaceName << ")");
+    SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::InitForOutgoing(" << sInterfaceName << "," << rIID << ")");
     meKind = Kind::OUTGOING;
     mxOrigin = xOrigin;
     msInterfaceName = sInterfaceName;
@@ -596,7 +596,7 @@ void CXTypeInfo::InitForOutgoing(Reference<XInterface> xOrigin,
 
 HRESULT STDMETHODCALLTYPE CXTypeInfo::GetTypeAttr(TYPEATTR **ppTypeAttr)
 {
-    SAL_INFO("extensions.olebridge", "CXTypeInfo@" << this << "::GetTypeAttr()");
+    SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetTypeAttr");
 
     if (!ppTypeAttr)
         return E_POINTER;
@@ -667,7 +667,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetTypeAttr(TYPEATTR **ppTypeAttr)
     pTypeAttr->wMinorVerNum = 0;
     pTypeAttr->idldescType.wIDLFlags = IDLFLAG_NONE;
 
-    SAL_INFO("extensions.olebridge", "CXTypeInfo@" << this << "::GetTypeAttr(): " << pTypeAttr);
+    SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetTypeAttr: " << pTypeAttr);
 
     *ppTypeAttr = pTypeAttr;
 
@@ -677,7 +677,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetTypeAttr(TYPEATTR **ppTypeAttr)
 HRESULT STDMETHODCALLTYPE CXTypeInfo::GetTypeComp(ITypeComp **ppTComp)
 {
     (void) ppTComp;
-    SAL_WARN("extensions.olebridge", "CXTypeInfo@" << this << "::GetTypeComp: NOTIMPL");
+    SAL_WARN("extensions.olebridge", this << "@CXTypeInfo::GetTypeComp: E_NOTIMPL");
     return E_NOTIMPL;
 }
 
@@ -742,7 +742,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetFuncDesc(UINT index,
         (*ppFuncDesc)->cScodes = 0;
         (*ppFuncDesc)->wFuncFlags = FUNCFLAG_FRESTRICTED;
 
-        SAL_INFO("extensions.olebridge", "CXTypeInfo@" << this << "::GetFuncDesc(" << index << "): S_OK: " << *ppFuncDesc);
+        SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetFuncDesc(" << index << "): S_OK: " << *ppFuncDesc);
 
         return S_OK;
     }
@@ -776,7 +776,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetFuncDesc(UINT index,
     (*ppFuncDesc)->elemdescFunc.tdesc.vt = VT_VOID; // ???
     (*ppFuncDesc)->wFuncFlags = 0;
 
-    SAL_INFO("extensions.olebridge", "CXTypeInfo@" << this << "::GetFuncDesc(" << index << "): S_OK: " << *ppFuncDesc);
+    SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetFuncDesc(" << index << "): S_OK: " << *ppFuncDesc);
 
     return S_OK;
 }
@@ -786,7 +786,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetVarDesc(UINT index,
 {
     (void) index;
     (void) ppVarDesc;
-    SAL_WARN("extensions.olebridge", "CXTypeInfo@" << this << "::GetVarDesc: NOTIMPL");
+    SAL_WARN("extensions.olebridge", this << "@CXTypeInfo::GetVarDesc: E_NOTIMPL");
     return E_NOTIMPL;
 }
 
@@ -795,7 +795,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetNames(MEMBERID memid,
                                                UINT cMaxNames,
                                                UINT *pcNames)
 {
-    SAL_INFO("extensions.olebridge", "CXTypeInfo@" << this << "::GetNames(" << memid << ")");
+    SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetNames(" << memid << ")");
     assert(meKind != Kind::COCLASS);
 
     if (!rgBstrNames)
@@ -830,7 +830,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetNames(MEMBERID memid,
     if (memid > aMethods.getLength() - 3)
         return E_INVALIDARG;
 
-    SAL_INFO("extensions.olebridge", "...CXTypeInfo@" << this << "::GetNames(" << memid << "): " << aMethods[memid + 2]->getName());
+    SAL_INFO("extensions.olebridge", "..." << this << "@CXTypeInfo::GetNames(" << memid << "): " << aMethods[memid + 2]->getName());
     rgBstrNames[0] = SysAllocString((LPOLESTR) aMethods[memid + 2]->getName().pData->buffer);
     *pcNames = 1;
 
@@ -840,7 +840,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetNames(MEMBERID memid,
 HRESULT STDMETHODCALLTYPE CXTypeInfo::GetRefTypeOfImplType(UINT index,
                                                            HREFTYPE *pRefType)
 {
-    SAL_INFO("extensions.olebridge", "CXTypeInfo@" << this << "::GetRefTypeOfImplType(" << index << ")");
+    SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetRefTypeOfImplType(" << index << ")");
 
     if (!pRefType)
         return E_POINTER;
@@ -855,7 +855,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetRefTypeOfImplType(UINT index,
 HRESULT STDMETHODCALLTYPE CXTypeInfo::GetImplTypeFlags(UINT index,
                                                        INT *pImplTypeFlags)
 {
-    SAL_INFO("extensions.olebridge", "CXTypeInfo@" << this << "::GetImplTypeFlags(" << index << ")");
+    SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetImplTypeFlags(" << index << ")");
 
     if (!pImplTypeFlags)
         return E_POINTER;
@@ -878,7 +878,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetIDsOfNames(LPOLESTR *rgszNames,
     (void) rgszNames;
     (void) cNames;
     (void) pMemId;
-    SAL_WARN("extensions.olebridge", "CXTypeInfo@" << this << "::GetIDsOfNames: NOTIMPL");
+    SAL_WARN("extensions.olebridge", this << "@CXTypeInfo::GetIDsOfNames: E_NOTIMPL");
     return E_NOTIMPL;
 }
 
@@ -897,7 +897,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::Invoke(PVOID pvInstance,
     (void) pVarResult;
     (void) pExcepInfo;
     (void) puArgErr;
-    SAL_WARN("extensions.olebridge", "CXTypeInfo@" << this << "::Invoke: NOTIMPL");
+    SAL_WARN("extensions.olebridge", this << "@CXTypeInfo::Invoke: E_NOTIMPL");
     return E_NOTIMPL;
 }
 
@@ -907,7 +907,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetDocumentation(MEMBERID memid,
                                                        DWORD *pdwHelpContext,
                                                        BSTR *pBstrHelpFile)
 {
-    SAL_INFO("extensions.olebridge", "CXTypeInfo@" << this << "::GetDocumentation(" << memid << ")");
+    SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetDocumentation(" << memid << ")");
     if (pBstrName)
     {
         if (memid == MEMBERID_NIL)
@@ -945,14 +945,14 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetDllEntry(MEMBERID memid,
     (void) pBstrDllName;
     (void) pBstrName;
     (void) pwOrdinal;
-    SAL_WARN("extensions.olebridge", "CXTypeInfo@" << this << "::GetDllEntry: NOTIMPL");
+    SAL_WARN("extensions.olebridge", this << "@CXTypeInfo::GetDllEntry: E_NOTIMPL");
     return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CXTypeInfo::GetRefTypeInfo(HREFTYPE hRefType,
                                                      ITypeInfo **ppTInfo)
 {
-    SAL_INFO("extensions.olebridge", "CXTypeInfo@" << this << "::GetRefTypeInfo(" << hRefType << ")");
+    SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetRefTypeInfo(" << hRefType << ")");
 
     if (!ppTInfo)
         return E_POINTER;
@@ -994,7 +994,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::AddressOfMember(MEMBERID memid,
     (void) memid;
     (void) invKind;
     (void) ppv;
-    SAL_WARN("extensions.olebridge", "CXTypeInfo@" << this << "::AddressOfMember: NOTIMPL");
+    SAL_WARN("extensions.olebridge", this << "@CXTypeInfo::AddressOfMember: E_NOTIMPL");
     return E_NOTIMPL;
 }
 
@@ -1005,7 +1005,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::CreateInstance(IUnknown *pUnkOuter,
     (void) pUnkOuter;
     (void) riid;
     (void) ppvObj;
-    SAL_WARN("extensions.olebridge", "CXTypeInfo@" << this << "::CreateInstance: NOTIMPL");
+    SAL_WARN("extensions.olebridge", this << "@CXTypeInfo::CreateInstance: E_NOTIMPL");
     return E_NOTIMPL;
 }
 
@@ -1014,7 +1014,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetMops(MEMBERID memid,
 {
     (void) memid;
     (void) pBstrMops;
-    SAL_WARN("extensions.olebridge", "CXTypeInfo@" << this << "::GetMops: NOTIMPL");
+    SAL_WARN("extensions.olebridge", this << "@CXTypeInfo::GetMops: E_NOTIMPL");
     return E_NOTIMPL;
 }
 
@@ -1024,7 +1024,7 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetMops(MEMBERID memid,
 HRESULT STDMETHODCALLTYPE CXTypeInfo::GetContainingTypeLib(ITypeLib **ppTLib,
                                                            UINT *pIndex)
 {
-    SAL_INFO("extensions.olebridge", "CXTypeInfo@" << this << "::GetContainingTypeLib");
+    SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::GetContainingTypeLib");
 
     if (!ppTLib || !pIndex)
         return E_POINTER;
@@ -1048,14 +1048,14 @@ HRESULT STDMETHODCALLTYPE CXTypeInfo::GetContainingTypeLib(ITypeLib **ppTLib,
 
 void STDMETHODCALLTYPE CXTypeInfo::ReleaseTypeAttr(TYPEATTR *pTypeAttr)
 {
-    SAL_INFO("extensions.olebridge", "CXTypeInfo@" << this << "::ReleaseTypeAttr(" << pTypeAttr << ")");
+    SAL_INFO("extensions.olebridge", this << "@CXTypeInfo::ReleaseTypeAttr(" << pTypeAttr << ")");
 
     delete pTypeAttr;
 }
 
 void STDMETHODCALLTYPE CXTypeInfo::ReleaseFuncDesc(FUNCDESC *pFuncDesc)
 {
-    SAL_WARN("extensions.olebridge", "CXTypeInfo@" << this << "::ReleaseFuncDesc(" << pFuncDesc << ")");
+    SAL_WARN("extensions.olebridge", this << "@CXTypeInfo::ReleaseFuncDesc(" << pFuncDesc << ")");
 
     delete pFuncDesc;
 }
@@ -1063,12 +1063,12 @@ void STDMETHODCALLTYPE CXTypeInfo::ReleaseFuncDesc(FUNCDESC *pFuncDesc)
 void STDMETHODCALLTYPE CXTypeInfo::ReleaseVarDesc(VARDESC *pVarDesc)
 {
     (void) pVarDesc;
-    SAL_WARN("extensions.olebridge", "CXTypeInfo@" << this << "::ReleaseVarDesc: NOTIMPL");
+    SAL_WARN("extensions.olebridge", this << "@CXTypeInfo::ReleaseVarDesc: E_NOTIMPL");
 }
 
 STDMETHODIMP InterfaceOleWrapper::GetTypeInfo(unsigned int iTInfo, LCID, ITypeInfo ** ppTInfo)
 {
-    SAL_INFO("extensions.olebridge", "InterfaceOleWrapper@" << this << "::GetTypeInfo(" << iTInfo << ")");
+    SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::GetTypeInfo(" << iTInfo << ")");
 
     if (!ppTInfo)
         return E_POINTER;
@@ -1108,7 +1108,7 @@ STDMETHODIMP InterfaceOleWrapper::GetIDsOfNames(REFIID /*riid*/,
                                                 LCID /*lcid*/,
                                                 DISPID * rgdispid )
 {
-    SAL_INFO("extensions.olebridge", "InterfaceOleWrapper@" << this << "::GetIDsOfNames("
+    SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::GetIDsOfNames("
              << OUString(o3tl::toU(rgszNames[0]))
              << (cNames > 1 ? "...!" : "") << "," << cNames << ")");
 
@@ -1442,7 +1442,7 @@ void SAL_CALL InterfaceOleWrapper::initialize( const Sequence< Any >& aArguments
         if (xServiceInfo.is())
             m_sImplementationName = xServiceInfo->getImplementationName();
 
-        SAL_INFO("extensions.olebridge", "InterfaceOleWrapper@" << this << "::initialize for "
+        SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::initialize for "
                  << (m_sImplementationName.isEmpty()?"an unknown implementation":m_sImplementationName));
         break;
     }
@@ -1718,7 +1718,7 @@ STDMETHODIMP InterfaceOleWrapper::Invoke(DISPID dispidMember,
                                          EXCEPINFO * pexcepinfo,
                                          unsigned int * puArgErr )
 {
-    SAL_INFO("extensions.olebridge", "InterfaceOleWrapper@" << this << "::Invoke(" << dispidMember << ")");
+    SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::Invoke(" << dispidMember << ")");
 
     comphelper::ProfileZone aZone("COM Bridge");
     HRESULT ret = S_OK;
@@ -2276,7 +2276,7 @@ public:
               Reference<XMultiServiceFactory>& xMSF,
               ooo::vba::TypeAndIID aTypeAndIID)
     {
-        SAL_INFO("extensions.olebridge", "CXConnectionPoint::Init() this=" << this << " for " << pInterfaceOleWrapper->getImplementationName());
+        SAL_INFO("extensions.olebridge", this << "@CXConnectionPoint::Init for " << pInterfaceOleWrapper->getImplementationName());
 
         IUnknown *pUnknown;
         if (SUCCEEDED(QueryInterface(IID_IUnknown, (void **)&pUnknown)))
@@ -2293,7 +2293,7 @@ public:
 
     virtual HRESULT STDMETHODCALLTYPE GetConnectionInterface(IID *pIID) override
     {
-        SAL_WARN("extensions.olebridge", "CXConnectionPoint@" << this << "::GetConnectionInterface(" << *pIID << "): NOTIMPL");
+        SAL_WARN("extensions.olebridge", this << "@CXConnectionPoint::GetConnectionInterface(" << *pIID << "): E_NOTIMPL");
 
         // FIXME: Needed?
 
@@ -2303,7 +2303,7 @@ public:
     virtual HRESULT STDMETHODCALLTYPE GetConnectionPointContainer(IConnectionPointContainer **ppCPC) override
     {
         (void) ppCPC;
-        SAL_WARN("extensions.olebridge", "CXConnectionPoint@" << this << "::GetConnectionInterface: NOTIMPL");
+        SAL_WARN("extensions.olebridge", this << "@CXConnectionPoint::GetConnectionInterface: E_NOTIMPL");
 
         // FIXME: Needed?
 
@@ -2313,7 +2313,7 @@ public:
     virtual HRESULT STDMETHODCALLTYPE Advise(IUnknown *pUnkSink,
                                              DWORD *pdwCookie) override
     {
-        SAL_INFO("extensions.olebridge", "CXConnectionPoint@" << this << "::Advise(" << pUnkSink << ")");
+        SAL_INFO("extensions.olebridge", this << "@CXConnectionPoint::Advise(" << pUnkSink << ")");
 
         if (!pdwCookie)
             return E_POINTER;
@@ -2334,7 +2334,7 @@ public:
 
     virtual HRESULT STDMETHODCALLTYPE Unadvise(DWORD dwCookie) override
     {
-        SAL_INFO("extensions.olebridge", "CXConnectionPoint@" << this << "::Unadvise(" << dwCookie << ")");
+        SAL_INFO("extensions.olebridge", this << "@CXConnectionPoint::Unadvise(" << dwCookie << ")");
 
         if (dwCookie == 0 || dwCookie > mvISinks.size())
             return E_POINTER;
@@ -2351,7 +2351,7 @@ public:
     virtual HRESULT STDMETHODCALLTYPE EnumConnections(IEnumConnections **ppEnum) override
     {
         (void) ppEnum;
-        SAL_WARN("extensions.olebridge", "CXConnectionPoint@" << this << "::EnumConnections: NOTIMPL");
+        SAL_WARN("extensions.olebridge", this << "@CXConnectionPoint::EnumConnections: E_NOTIMPL");
         return E_NOTIMPL;
     }
 
@@ -2588,7 +2588,7 @@ STDMETHODIMP InterfaceOleWrapper::GetNameSpaceParent(
 HRESULT STDMETHODCALLTYPE InterfaceOleWrapper::GetClassInfo (
     /* [out] */ ITypeInfo **ppTI)
 {
-    SAL_INFO("extensions.olebridge", "InterfaceOleWrapper@" << this << "::GetClassInfo");
+    SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::GetClassInfo");
 
     if (!ppTI)
         return E_POINTER;
@@ -2624,7 +2624,7 @@ HRESULT STDMETHODCALLTYPE InterfaceOleWrapper::EnumConnectionPoints(
     /* [out] */ IEnumConnectionPoints **ppEnum)
 {
     (void) ppEnum;
-    SAL_INFO("extensions.olebridge", "InterfaceOleWrapper@" << this << "::EnumConnectionPoints");
+    SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::EnumConnectionPoints");
     return ResultFromScode(E_NOTIMPL);
 }
 
@@ -2632,7 +2632,7 @@ HRESULT STDMETHODCALLTYPE InterfaceOleWrapper::FindConnectionPoint(
     /* [in] */ REFIID riid,
     /* [out] */ IConnectionPoint **ppCP)
 {
-    SAL_INFO("extensions.olebridge", "InterfaceOleWrapper@" << this << "::FindConnectionPoint " << riid);
+    SAL_INFO("extensions.olebridge", this << "@InterfaceOleWrapper::FindConnectionPoint(" << riid << ")");
 
     if (!ppCP)
         return E_POINTER;
commit b9ef6b66e7a67a448b1a840c47146d8789a92a6d
Author: Tor Lillqvist <tml at collabora.com>
Date:   Mon Apr 23 20:50:43 2018 +0300

    Initial steps to make also Calc usable from Automation clients
    
    Largely parallel to what we do for Writer.
    
    Yes, there is a fair amount of duplicated code now for the outgoing
    ("sink") stuff in sw and sc, that should be factored out (to
    vbahelper, probably).
    
    Change-Id: I8df4a81c3b9043e8d6b0b206e3c04660205987c7

diff --git a/extensions/source/ole/servprov.cxx b/extensions/source/ole/servprov.cxx
index 2fccd9a59b9f..45e693b20982 100644
--- a/extensions/source/ole/servprov.cxx
+++ b/extensions/source/ole/servprov.cxx
@@ -54,6 +54,10 @@ DEFINE_GUID(OID_ServiceManager, 0x82154420, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50
 // {82154421-0FBF-11d4-8313-005004526AB4}
 DEFINE_GUID(OID_LibreOfficeWriterApplication, 0x82154421, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
 
+// For Calc
+// {82154425-0FBF-11d4-8313-005004526AB4}
+DEFINE_GUID(OID_LibreOfficeCalcApplication, 0x82154425, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
+
 OneInstanceOleWrapper::OneInstanceOleWrapper(  const Reference<XMultiServiceFactory>& smgr,
                                                std::function<const Reference<XInterface>()> xInstFunction )
     : m_refCount(0)
@@ -488,6 +492,18 @@ OleServer::OleServer( const Reference<XMultiServiceFactory>& smgr):
                                 return xApplication;
                             },
                             &OID_LibreOfficeWriterApplication );
+
+    (void) provideInstance( [&]
+                            {
+                                // Ditto for sc
+                                static const Reference<XInterface> xCalcGlobals = m_smgr->createInstance("ooo.vba.excel.Globals");
+                                const Reference<ooo::vba::XHelperInterface> xHelperInterface(xCalcGlobals, UNO_QUERY);
+                                Any aApplication = xHelperInterface->Application();
+                                Reference<XInterface> xApplication;
+                                aApplication >>= xApplication;
+                                return xApplication;
+                            },
+                            &OID_LibreOfficeCalcApplication );
 }
 
 OleServer::~OleServer()
diff --git a/oovbaapi/ooo/vba/excel/XApplication.idl b/oovbaapi/ooo/vba/excel/XApplication.idl
index e315b27ddaf3..ceceaf777d97 100644
--- a/oovbaapi/ooo/vba/excel/XApplication.idl
+++ b/oovbaapi/ooo/vba/excel/XApplication.idl
@@ -30,6 +30,8 @@ interface XApplication
     interface ::com::sun::star::beans::XExactName;
     interface ::com::sun::star::script::XInvocation;
 
+    interface XConnectable;
+
 //  interface ::ooo::vba::XHelperInterface;
 
     [attribute, readonly] any Selection;
diff --git a/oovbaapi/ooo/vba/excel/XApplicationOutgoing.idl b/oovbaapi/ooo/vba/excel/XApplicationOutgoing.idl
index d9b1da42bc4b..9e601c5331d6 100644
--- a/oovbaapi/ooo/vba/excel/XApplicationOutgoing.idl
+++ b/oovbaapi/ooo/vba/excel/XApplicationOutgoing.idl
@@ -25,6 +25,8 @@ module ooo {  module vba {  module excel {
 
 interface XApplicationOutgoing : XInterfaceWithIID
 {
+    void WorkbookOpen([in] any Wb);
+    void WorkbookBeforeClose([in] any Wb, [out] any Cancel);
 };
 
 }; }; };
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 00db6e4a44c0..2f4f06b6ea25 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -40,7 +40,11 @@ $(eval $(call gb_Library_use_custom_headers,sc,\
     officecfg/registry \
 ))
 
-$(eval $(call gb_Library_use_sdk_api,sc))
+$(eval $(call gb_Library_use_api,sc,\
+	udkapi \
+	offapi \
+	oovbaapi \
+))
 
 $(eval $(call gb_Library_use_externals,sc,\
     boost_headers \
diff --git a/sc/Library_scd.mk b/sc/Library_scd.mk
index 1b491afc5cd8..1a6a132f74f9 100644
--- a/sc/Library_scd.mk
+++ b/sc/Library_scd.mk
@@ -18,7 +18,11 @@ $(eval $(call gb_Library_set_include,scd,\
 
 $(eval $(call gb_Library_use_external,scd,boost_headers))
 
-$(eval $(call gb_Library_use_sdk_api,scd))
+$(eval $(call gb_Library_use_api,scd,\
+	udkapi \
+	offapi \
+	oovbaapi \
+))
 
 $(eval $(call gb_Library_use_libraries,scd,\
 	comphelper \
diff --git a/sc/Library_scfilt.mk b/sc/Library_scfilt.mk
index e4b6fe154e89..4766ed02f096 100644
--- a/sc/Library_scfilt.mk
+++ b/sc/Library_scfilt.mk
@@ -21,7 +21,11 @@ $(eval $(call gb_Library_set_include,scfilt,\
 
 $(eval $(call gb_Library_set_precompiled_header,scfilt,$(SRCDIR)/sc/inc/pch/precompiled_scfilt))
 
-$(eval $(call gb_Library_use_sdk_api,scfilt))
+$(eval $(call gb_Library_use_api,scfilt,\
+	udkapi \
+	offapi \
+	oovbaapi \
+))
 
 $(eval $(call gb_Library_use_custom_headers,scfilt,\
 	oox/generated \
diff --git a/sc/Library_scui.mk b/sc/Library_scui.mk
index d576ca51a5c1..7105f59e11db 100644
--- a/sc/Library_scui.mk
+++ b/sc/Library_scui.mk
@@ -28,7 +28,11 @@ $(eval $(call gb_Library_use_custom_headers,scui,\
     officecfg/registry \
 ))
 
-$(eval $(call gb_Library_use_sdk_api,scui))
+$(eval $(call gb_Library_use_api,scui,\
+	udkapi \
+	offapi \
+	oovbaapi \
+))
 
 $(eval $(call gb_Library_use_externals,scui,\
 	boost_headers \
diff --git a/sc/inc/scmod.hxx b/sc/inc/scmod.hxx
index e38c07dccca5..be90897627be 100644
--- a/sc/inc/scmod.hxx
+++ b/sc/inc/scmod.hxx
@@ -28,6 +28,7 @@
 #include "global.hxx"
 #include "shellids.hxx"
 #include <unotools/options.hxx>
+#include <ooo/vba/XSinkCaller.hpp>
 
 #include <com/sun/star/datatransfer/XTransferable2.hpp>
 
@@ -107,6 +108,9 @@ class ScModule: public SfxModule, public SfxListener, public utl::ConfigurationL
     bool                m_bIsInSharedDocSaving:1;
 
     std::map<sal_uInt16, std::vector<VclPtr<vcl::Window> > > m_mapRefWindow;
+
+    css::uno::Reference< ooo::vba::XSinkCaller > mxAutomationApplicationEventsCaller;
+
 public:
                     SFX_DECL_INTERFACE(SCID_APP)
 
@@ -245,6 +249,9 @@ public:
     SC_DLLPUBLIC void   RegisterRefWindow( sal_uInt16 nSlotId, vcl::Window *pWnd );
     SC_DLLPUBLIC void   UnregisterRefWindow( sal_uInt16 nSlotId, vcl::Window *pWnd );
     SC_DLLPUBLIC vcl::Window * Find1RefWindow( sal_uInt16 nSlotId, vcl::Window *pWndAncestor );
+
+    SC_DLLPUBLIC void RegisterAutomationApplicationEventsCaller(css::uno::Reference< ooo::vba::XSinkCaller > const& xCaller);
+    SC_DLLPUBLIC void CallAutomationApplicationEventSinks(const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments);
 };
 
 #define SC_MOD() ( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule::Calc)) )
diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx
index 26652ddf1808..fcf1e889bc05 100644
--- a/sc/source/ui/app/scmod.cxx
+++ b/sc/source/ui/app/scmod.cxx
@@ -2288,4 +2288,15 @@ SfxStyleFamilies* ScModule::CreateStyleFamilies()
     return pStyleFamilies;
 }
 
+void ScModule::RegisterAutomationApplicationEventsCaller(css::uno::Reference< ooo::vba::XSinkCaller > const& xCaller)
+{
+    mxAutomationApplicationEventsCaller = xCaller;
+}
+
+void ScModule::CallAutomationApplicationEventSinks(const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments)
+{
+    if (mxAutomationApplicationEventsCaller.is())
+        mxAutomationApplicationEventsCaller->CallSinks(Method, Arguments);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaapplication.cxx b/sc/source/ui/vba/vbaapplication.cxx
index 25f125f90ba4..fde8c942a172 100644
--- a/sc/source/ui/vba/vbaapplication.cxx
+++ b/sc/source/ui/vba/vbaapplication.cxx
@@ -30,6 +30,7 @@
 #include <com/sun/star/util/PathSettings.hpp>
 #include <com/sun/star/view/XSelectionSupplier.hpp>
 #include <ooo/vba/XExecutableDialog.hpp>
+#include <ooo/vba/excel/XApplicationOutgoing.hpp>
 #include <ooo/vba/excel/XlCalculation.hpp>
 #include <ooo/vba/excel/XlMousePointer.hpp>
 #include <ooo/vba/office/MsoShapeType.hpp>
@@ -125,6 +126,41 @@ ScVbaAppSettings::ScVbaAppSettings() :
 
 struct ScVbaStaticAppSettings : public ::rtl::Static< ScVbaAppSettings, ScVbaStaticAppSettings > {};
 
+class ScVbaApplicationOutgoingConnectionPoint : public cppu::WeakImplHelper<XConnectionPoint>
+{
+private:
+    ScVbaApplication* mpApp;
+
+public:
+    ScVbaApplicationOutgoingConnectionPoint( ScVbaApplication* pApp );
+
+    // XConnectionPoint
+    sal_uInt32 SAL_CALL Advise(const uno::Reference< XSink >& Sink ) override;
+    void SAL_CALL Unadvise( sal_uInt32 Cookie ) override;
+};
+
+sal_uInt32
+ScVbaApplication::AddSink( const uno::Reference< XSink >& xSink )
+{
+    {
+        SolarMutexGuard aGuard;
+        ScDLL::Init();
+    }
+    // No harm in potentially calling this several times
+    SC_MOD()->RegisterAutomationApplicationEventsCaller( uno::Reference< XSinkCaller >(this) );
+    mvSinks.push_back(xSink);
+    return mvSinks.size();;
+}
+
+void
+ScVbaApplication::RemoveSink( sal_uInt32 nNumber )
+{
+    if (nNumber < 1 || nNumber > mvSinks.size())
+        return;
+
+    mvSinks[nNumber-1] = uno::Reference< XSink >();
+}
+
 ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ) :
     ScVbaApplication_BASE( xContext ),
     mrAppSettings( ScVbaStaticAppSettings::get() ),
@@ -1380,6 +1416,52 @@ void SAL_CALL ScVbaApplication::Undo()
         dispatchExecute( pViewShell, SID_UNDO );
 }
 
+// XInterfaceWithIID
+
+OUString SAL_CALL
+ScVbaApplication::getIID()
+{
+    return OUString("{82154425-0FBF-11d4-8313-005004526AB4}");
+}
+
+// XConnectable
+
+OUString SAL_CALL
+ScVbaApplication::GetIIDForClassItselfNotCoclass()
+{
+    return OUString("{82154426-0FBF-11D4-8313-005004526AB4}");
+}
+
+TypeAndIID SAL_CALL
+ScVbaApplication::GetConnectionPoint()
+{
+    TypeAndIID aResult =
+        { excel::XApplicationOutgoing::static_type(),
+          "{82154427-0FBF-11D4-8313-005004526AB4}"
+        };
+
+    return aResult;
+}
+
+uno::Reference<XConnectionPoint> SAL_CALL
+ScVbaApplication::FindConnectionPoint()
+{
+    uno::Reference<XConnectionPoint> xCP(new ScVbaApplicationOutgoingConnectionPoint(this));
+    return xCP;
+}
+
+// XSinkCaller
+
+void SAL_CALL
+ScVbaApplication::CallSinks( const OUString& Method, uno::Sequence< uno::Any >& Arguments )
+{
+    for (auto& i : mvSinks)
+    {
+        if (i.is())
+            i->Call(Method, Arguments);
+    }
+}
+
 OUString
 ScVbaApplication::getServiceImplName()
 {
@@ -1408,4 +1490,24 @@ sdecl::ServiceDecl const serviceDecl(
     "ooo.vba.excel.Application" );
 }
 
+// ScVbaApplicationOutgoingConnectionPoint
+
+ScVbaApplicationOutgoingConnectionPoint::ScVbaApplicationOutgoingConnectionPoint( ScVbaApplication* pApp ) :
+    mpApp(pApp)
+{
+}
+
+// XConnectionPoint
+sal_uInt32 SAL_CALL
+ScVbaApplicationOutgoingConnectionPoint::Advise( const uno::Reference< XSink >& Sink )
+{
+    return mpApp->AddSink(Sink);
+}
+
+void SAL_CALL
+ScVbaApplicationOutgoingConnectionPoint::Unadvise( sal_uInt32 Cookie )
+{
+    mpApp->RemoveSink( Cookie );
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaapplication.hxx b/sc/source/ui/vba/vbaapplication.hxx
index 9a0d3137febb..6c9c58588ada 100644
--- a/sc/source/ui/vba/vbaapplication.hxx
+++ b/sc/source/ui/vba/vbaapplication.hxx
@@ -19,6 +19,10 @@
 #ifndef INCLUDED_SC_SOURCE_UI_VBA_VBAAPPLICATION_HXX
 #define INCLUDED_SC_SOURCE_UI_VBA_VBAAPPLICATION_HXX
 
+#include <vector>
+
+#include <ooo/vba/XSink.hpp>
+#include <ooo/vba/XSinkCaller.hpp>
 #include <ooo/vba/excel/XWorksheetFunction.hpp>
 #include <ooo/vba/excel/XApplication.hpp>
 #include <ooo/vba/excel/XFileDialog.hpp>
@@ -28,7 +32,7 @@
 #include <vbahelper/vbaapplicationbase.hxx>
 #include <cppuhelper/implbase.hxx>
 
-typedef cppu::ImplInheritanceHelper< VbaApplicationBase, ov::excel::XApplication > ScVbaApplication_BASE;
+typedef cppu::ImplInheritanceHelper< VbaApplicationBase, ov::excel::XApplication, ov::XSinkCaller > ScVbaApplication_BASE;
 
 struct ScVbaAppSettings;
 
@@ -45,6 +49,8 @@ private:
     /// @throws css::uno::RuntimeException
     OUString getOfficePath( const OUString& sPath );
 
+    std::vector<css::uno::Reference< ooo::vba::XSink >> mvSinks;
+
 protected:
     virtual css::uno::Reference< css::frame::XModel > getCurrentDocument() override;
 
@@ -55,6 +61,9 @@ public:
     /** Returns true, if VBA document events are enabled. */
     static bool getDocumentEventsEnabled();
 
+    sal_uInt32 AddSink( const css::uno::Reference< ooo::vba::XSink >& xSink );
+    void RemoveSink( sal_uInt32 nNumber );
+
     // XExactName
     virtual OUString SAL_CALL getExactName( const OUString& aApproximateName ) override;
 
@@ -136,9 +145,21 @@ public:
     virtual css::uno::Any SAL_CALL MenuBars( const css::uno::Any& aIndex ) override;
     virtual css::uno::Any SAL_CALL Caller( const css::uno::Any& aIndex ) override;
     virtual void SAL_CALL Undo() override;
+
     // XHelperInterface
     virtual OUString getServiceImplName() override;
     virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+    // XInterfaceWithIID
+    virtual OUString SAL_CALL getIID() override;
+
+    // XConnectable
+    virtual OUString SAL_CALL GetIIDForClassItselfNotCoclass() override;
+    virtual ov::TypeAndIID SAL_CALL GetConnectionPoint() override;
+    virtual css::uno::Reference<ov::XConnectionPoint> SAL_CALL FindConnectionPoint() override;
+
+    // XSinkCaller
+    virtual void SAL_CALL CallSinks( const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments ) override;
 };
 #endif // INCLUDED_SC_SOURCE_UI_VBA_VBAAPPLICATION_HXX
 
commit 8a2f30e548f930f0ddd869e07f58947616ba9ea4
Author: Tor Lillqvist <tml at collabora.com>
Date:   Tue May 15 22:14:40 2018 +0300

    Avoid crash if pDocShell is null
    
    Change-Id: I4d43bdd6789bdf01cd9b7b38377b19294a544477

diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 4b02af2c5ded..31650d253f7f 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -629,8 +629,11 @@ void SwXTextDocument::dispose()
 
 void SwXTextDocument::close( sal_Bool bDeliverOwnership )
 {
-    uno::Sequence< uno::Any > aArgs;
-    pDocShell->CallAutomationDocumentEventSinks( "Close", aArgs );
+    if(pDocShell)
+    {
+        uno::Sequence< uno::Any > aArgs;
+        pDocShell->CallAutomationDocumentEventSinks( "Close", aArgs );
+    }
     SolarMutexGuard aGuard;
     if(IsValid() && m_pHiddenViewFrame)
         lcl_DisposeView( m_pHiddenViewFrame, pDocShell);
commit a03d44076f74d73398d632cee5358bfc3103dd01
Author: Tor Lillqvist <tml at collabora.com>
Date:   Sat Apr 21 01:27:08 2018 +0300

    Add ooo.vba.excel.XApplicationOutgoing
    
    Change-Id: I50ba5482742296609187e8b41bd3a2910c44ca4e

diff --git a/oovbaapi/UnoApi_oovbaapi.mk b/oovbaapi/UnoApi_oovbaapi.mk
index 009405a80ca7..bb9601f8152b 100644
--- a/oovbaapi/UnoApi_oovbaapi.mk
+++ b/oovbaapi/UnoApi_oovbaapi.mk
@@ -219,6 +219,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,oovbaapi,ooo/vba/dao,\
 $(eval $(call gb_UnoApi_add_idlfiles,oovbaapi,ooo/vba/excel,\
     Constants \
 	XApplication \
+	XApplicationOutgoing \
 	XAxes \
 	XAxis \
 	XAxisTitle \
diff --git a/oovbaapi/ooo/vba/excel/XApplicationOutgoing.idl b/oovbaapi/ooo/vba/excel/XApplicationOutgoing.idl
new file mode 100644
index 000000000000..d9b1da42bc4b
--- /dev/null
+++ b/oovbaapi/ooo/vba/excel/XApplicationOutgoing.idl
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#ifndef __ooo_vba_excel_XApplicationOutgoing_idl__
+#define __ooo_vba_excel_XApplicationOutgoing_idl__
+
+module ooo {  module vba {  module excel {
+
+// Despite being here in ooo::vba, this has nothing to do with "VBA" (Visual Basic for
+// Applications), or the VBA compatibility in StarBasic. This is related to using LibreOffice from
+// (OLE) Automation clients. It is here anyway because much of the API available to such clients
+// is identical to that offered to StarBasic code written in a VBA-like fashion.
+
+// This interface exists for technical reasons only, we don't actually have any UNO object that
+// would implement (inherit from) this. We just advertise the type of this interface from Writer to
+// the Automation-UNO bridge code (in extensions/source/ole) so that it can tell the Automation
+// client what the Automation server expects and construct a corresponding COM interface that can
+// receive the callbacks. Or something like that.
+
+interface XApplicationOutgoing : XInterfaceWithIID
+{
+};
+
+}; }; };
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list