[Libreoffice-commits] core.git: 3 commits - extensions/source oovbaapi/ooo sw/inc sw/source

Tor Lillqvist tml at collabora.com
Thu May 31 11:02:06 UTC 2018


 extensions/source/ole/unoobjw.cxx              |  126 +++++++++++++++++++++++--
 oovbaapi/ooo/vba/word/XApplicationOutgoing.idl |    1 
 sw/inc/docsh.hxx                               |    3 
 sw/source/uibase/app/docsh.cxx                 |    5 
 4 files changed, 129 insertions(+), 6 deletions(-)

New commits:
commit b01c131e5776c104e86da2966d5ac93aa4601d24
Author: Tor Lillqvist <tml at collabora.com>
Date:   Mon Apr 9 16:19:36 2018 +0300

    Add ooo::vba::word::XApplicationOutgoing::DocumentBeforeClose() callback
    
    Change-Id: Iccdb7bc262b8f85caf7efb4407a1f00ff0cfb4a8

diff --git a/oovbaapi/ooo/vba/word/XApplicationOutgoing.idl b/oovbaapi/ooo/vba/word/XApplicationOutgoing.idl
index e38dba8479e8..9b62f02ad27c 100644
--- a/oovbaapi/ooo/vba/word/XApplicationOutgoing.idl
+++ b/oovbaapi/ooo/vba/word/XApplicationOutgoing.idl
@@ -27,6 +27,7 @@ interface XApplicationOutgoing : XInterfaceWithIID
 {
     void DocumentChange();
     void Quit();
+    void DocumentBeforeClose([in] any Document, [out] any Cancel);
 };
 
 }; }; };
commit a9f7d22fa80c422275259c57e9c0d50cd8a0447e
Author: Tor Lillqvist <tml at collabora.com>
Date:   Mon Apr 9 15:57:12 2018 +0300

    We need to keep an ooo::vba::word::XDocument ref in the SwDocShell for...
    
    ... Application callbacks that want to pass a
    such. DocumentBeforeClose() is one. (Not yet implemented.)
    
    Change-Id: I1e065d608a55e054fb41b0006a76c731915f3ebb

diff --git a/sw/inc/docsh.hxx b/sw/inc/docsh.hxx
index d93f626b585b..d61cd712a51a 100644
--- a/sw/inc/docsh.hxx
+++ b/sw/inc/docsh.hxx
@@ -23,6 +23,7 @@
 #include <rtl/ref.hxx>
 #include <com/sun/star/uno/Sequence.h>
 #include <ooo/vba/XSinkCaller.hpp>
+#include <ooo/vba/word/XDocument.hpp>
 #include <sfx2/docfac.hxx>
 #include <sfx2/objsh.hxx>
 #include "swdllapi.h"
@@ -88,6 +89,7 @@ class SW_DLLPUBLIC SwDocShell
         ///< SID_MAIL_EXPORT_FINISHED needs to restore
 
     css::uno::Reference< ooo::vba::XSinkCaller > mxAutomationDocumentEventsCaller;
+    css::uno::Reference< ooo::vba::word::XDocument> mxAutomationDocumentObject;
 
     /// Methods for access to doc.
     SAL_DLLPRIVATE void                  AddLink();
@@ -315,6 +317,7 @@ public:
 
     void RegisterAutomationDocumentEventsCaller(css::uno::Reference< ooo::vba::XSinkCaller > const& xCaller);
     void CallAutomationDocumentEventSinks(const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments);
+    void RegisterAutomationDocumentObject(css::uno::Reference< ooo::vba::word::XDocument > const& xDocument);
 };
 
 /** Find the right DocShell and create a new one:
diff --git a/sw/source/uibase/app/docsh.cxx b/sw/source/uibase/app/docsh.cxx
index fadf271a19c3..96608f2f1dee 100644
--- a/sw/source/uibase/app/docsh.cxx
+++ b/sw/source/uibase/app/docsh.cxx
@@ -1389,4 +1389,9 @@ void SwDocShell::CallAutomationDocumentEventSinks(const OUString& Method, css::u
         mxAutomationDocumentEventsCaller->CallSinks(Method, Arguments);
 }
 
+void SwDocShell::RegisterAutomationDocumentObject(css::uno::Reference< ooo::vba::word::XDocument > const& xDocument)
+{
+    mxAutomationDocumentObject = xDocument;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 2774593a4b23ba831b3b4d5729a241416634e917
Author: Tor Lillqvist <tml at collabora.com>
Date:   Mon Apr 9 15:43:41 2018 +0300

    First attempt at passing arguments, also in and inout, to Automation callbacks
    
    Change-Id: Iff629243888153250b655a5e942ced024e3338a7

diff --git a/extensions/source/ole/unoobjw.cxx b/extensions/source/ole/unoobjw.cxx
index ddcf1ddf89f5..0a30609fc03e 100644
--- a/extensions/source/ole/unoobjw.cxx
+++ b/extensions/source/ole/unoobjw.cxx
@@ -2067,7 +2067,8 @@ class Sink : public cppu::WeakImplHelper<ooo::vba::XSink>
 public:
     Sink(IUnknown* pUnkSink,
          Reference<XMultiServiceFactory> xMSF,
-         ooo::vba::TypeAndIID aTypeAndIID);
+         ooo::vba::TypeAndIID aTypeAndIID,
+         InterfaceOleWrapper* pInterfaceOleWrapper);
 
     // XSink
     void SAL_CALL Call( const OUString& Method, Sequence< Any >& Arguments ) override;
@@ -2076,14 +2077,17 @@ private:
     IUnknown* mpUnkSink;
     Reference<XMultiServiceFactory> mxMSF;
     ooo::vba::TypeAndIID maTypeAndIID;
+    InterfaceOleWrapper* mpInterfaceOleWrapper;
 };
 
 Sink::Sink(IUnknown* pUnkSink,
            Reference<XMultiServiceFactory> xMSF,
-           ooo::vba::TypeAndIID aTypeAndIID) :
+           ooo::vba::TypeAndIID aTypeAndIID,
+           InterfaceOleWrapper* pInterfaceOleWrapper) :
     mpUnkSink(pUnkSink),
     mxMSF(xMSF),
-    maTypeAndIID(aTypeAndIID)
+    maTypeAndIID(aTypeAndIID),
+    mpInterfaceOleWrapper(pInterfaceOleWrapper)
 {
     mpUnkSink->AddRef();
 }
@@ -2117,16 +2121,126 @@ Sink::Call( const OUString& Method, Sequence< Any >& Arguments )
     {
         if (aMethods[i]->getName() == Method)
         {
+            // FIXME: Handle mismatch in type of actual argument and parameter of the method.
+
+            // FIXME: Handle mismatch in number of arguments passed and actual number of parameters
+            // of the method.
+
+            auto aParamInfos = aMethods[i]->getParameterInfos();
+
+            assert(Arguments.getLength() == aParamInfos.getLength());
+
             DISPPARAMS aDispParams;
-            aDispParams.rgvarg = NULL;
             aDispParams.rgdispidNamedArgs = NULL;
-            aDispParams.cArgs = 0;
+            aDispParams.cArgs = Arguments.getLength();
             aDispParams.cNamedArgs = 0;
+            aDispParams.rgvarg = new VARIANT[aDispParams.cArgs];
+            for (unsigned i = 0; i < aDispParams.cArgs; i++)
+            {
+                VariantInit(aDispParams.rgvarg+i);
+                // Note: Reverse order of arguments in Arguments and aDispParams.rgvarg!
+                const unsigned nIncomingArgIndex = aDispParams.cArgs - i - 1;
+                mpInterfaceOleWrapper->anyToVariant(aDispParams.rgvarg+i, Arguments[nIncomingArgIndex]);
+
+                // Handle OUT and INOUT arguments. For instance, the second ('Cancel') parameter to
+                // DocumentBeforeClose() should be a VT_BYREF|VT_BOOL parameter. Need to handle that
+                // here.
+
+                if (aParamInfos[nIncomingArgIndex].aMode == ParamMode_OUT ||
+                    aParamInfos[nIncomingArgIndex].aMode == ParamMode_INOUT)
+                {
+                    switch (aDispParams.rgvarg[i].vt)
+                    {
+                    case VT_I2:
+                        aDispParams.rgvarg[i].byref = new SHORT(aDispParams.rgvarg[i].iVal);
+                        aDispParams.rgvarg[i].vt |= VT_BYREF;
+                        break;
+                    case VT_I4:
+                        aDispParams.rgvarg[i].byref = new LONG(aDispParams.rgvarg[i].lVal);
+                        aDispParams.rgvarg[i].vt |= VT_BYREF;
+                        break;
+                    case VT_BSTR:
+                        aDispParams.rgvarg[i].byref = new BSTR(aDispParams.rgvarg[i].bstrVal);
+                        aDispParams.rgvarg[i].vt |= VT_BYREF;
+                        break;
+                    case VT_BOOL:
+                        // SAL_ DEBUG("===> VT_BOOL is initially " << (int)aDispParams.rgvarg[i].boolVal);
+                        aDispParams.rgvarg[i].byref = new VARIANT_BOOL(aDispParams.rgvarg[i].boolVal);
+                        // SAL_ DEBUG("     byref=" << aDispParams.rgvarg[i].byref);
+                        aDispParams.rgvarg[i].vt |= VT_BYREF;
+                        break;
+                    default:
+                        assert(false && "Not handled yet");
+                        break;
+                    }
+                }
+            }
+
             VARIANT aVarResult;
             VariantInit(&aVarResult);
             UINT uArgErr;
+
             nResult = pDispatch->Invoke(nMemId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &aDispParams, &aVarResult, NULL, &uArgErr);
             SAL_WARN_IF(!SUCCEEDED(nResult), "extensions.olebridge", "Call to " << Method << " failed: " << WindowsErrorStringFromHRESULT(nResult));
+
+            // Undo VT_BYREF magic done above. Copy out parameters back to the Anys in Arguments
+            for (unsigned i = 0; i < aDispParams.cArgs; i++)
+            {
+                const unsigned nIncomingArgIndex = aDispParams.cArgs - i - 1;
+                if (aParamInfos[nIncomingArgIndex].aMode == ParamMode_OUT ||
+                    aParamInfos[nIncomingArgIndex].aMode == ParamMode_INOUT)
+                {
+                    switch (aDispParams.rgvarg[i].vt)
+                    {
+                    case VT_BYREF|VT_I2:
+                        {
+                            SHORT *pI = (SHORT*)aDispParams.rgvarg[i].byref;
+                            Arguments[i] <<= (sal_Int16)*pI;
+                            delete pI;
+                        }
+                        break;
+                    case VT_BYREF|VT_I4:
+                        {
+                            LONG *pL = (LONG*)aDispParams.rgvarg[i].byref;
+                            Arguments[i] <<= (sal_Int32)*pL;
+                            delete pL;
+                        }
+                        break;
+                    case VT_BYREF|VT_BSTR:
+                        {
+                            BSTR *pBstr = (BSTR*)aDispParams.rgvarg[i].byref;
+                            Arguments[i] <<= OUString(o3tl::toU(*pBstr));
+                            // Undo SysAllocString() done in anyToVariant()
+                            SysFreeString(*pBstr);
+                            delete pBstr;
+                        }
+                        break;
+                    case VT_BYREF|VT_BOOL:
+                        {
+                            VARIANT_BOOL *pBool = (VARIANT_BOOL*)aDispParams.rgvarg[i].byref;
+                            // SAL_ DEBUG("===> VT_BOOL: byref is now " << aDispParams.rgvarg[i].byref << ", " << (int)*pBool);
+                            Arguments[i] <<= (sal_Bool)(*pBool != VARIANT_FALSE ? sal_True : sal_False);
+                            delete pBool;
+                        }
+                        break;
+                    default:
+                        assert(false && "Not handled yet");
+                        break;
+                    }
+                }
+                else
+                {
+                    switch (aDispParams.rgvarg[i].vt)
+                    {
+                    case VT_BSTR:
+                        // Undo SysAllocString() done in anyToVariant()
+                        SysFreeString(aDispParams.rgvarg[i].bstrVal);
+                        break;
+                    }
+                }
+            }
+
+            delete[] aDispParams.rgvarg;
             return;
         }
         nMemId++;
@@ -2191,7 +2305,7 @@ public:
         if (!pdwCookie)
             return E_POINTER;
 
-        Reference<ooo::vba::XSink> xSink(new Sink(pUnkSink, mxMSF, maTypeAndIID));
+        Reference<ooo::vba::XSink> xSink(new Sink(pUnkSink, mxMSF, maTypeAndIID, mpInterfaceOleWrapper));
 
         mvISinks.push_back(pUnkSink);
         *pdwCookie = mvISinks.size();


More information about the Libreoffice-commits mailing list