[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