summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2018-03-16 16:39:37 +0200
committerTor Lillqvist <tml@collabora.com>2018-05-30 23:55:11 +0200
commitf7e0297b01f739e17f2f9517bf3d89baaee654ab (patch)
tree50f736835ec776150465600dc152c55f89d68f50 /sw
parent63e65d1743264dfa26d2aba615d71978e65784e8 (diff)
Work in progress related to invoking events in Automation clients
XConnectable interfaces need a second IID, for the interface "itself", not the coclass. (I am sure there is some catchy short term for that, I just can't find it right now.) Allow several simultaneous sinks for a SwVbaApplication. Not sure in what case such would be needed, but you never know about 3rd-party client code, and it's trivial to handle anyway, so why not. Lots of FIXMEs still. There is likely also a lot of leaks. But at least an event handler in a simple VBScript script does get invoked. Note that the changed and added code in extensions/source/ole is totally unaware of what outgoing ("event") interfaces Writer or Calc implements, it is all handled generically through the UNO interfaces I added recently. One particular thing that needs doing is to actually make Writer (and Calc) raise this kind of events when necessary. The current code to invoke events handlers in StarBasic (including StarBasic code running in "VBA" compaibility) is very much tied to having StarBasic running (not surprisingly), which of course is not at all the case when it is an Automation client that is manipulating a Writer or Calc instance and wants events. There is demonstration-only code in SwVbaApplication::Documents() to raise the "Quit" event. (I would have put that in the SwVbaApplication destructor but that doesn't seem to get called.) That should of course go away once we invoke other relevant events in appropriate places. And the "Quit" event needs to be invoked when the application is quitting. The whole callback mechanism with IConnectionPoint etc is still partly a mystery to me. It is entirely possible that even if this now works for a simple VBScript client, it won't work for (for instance) a VB6 client that might exercise the APIs of the COM interfaces we provide in a different way. Add XSinkCaller, for something that perhaps calls one or several XSinks. Change-Id: Ica03344010e374542f4aceff5ec032c78579f937 Reviewed-on: https://gerrit.libreoffice.org/55093 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tor Lillqvist <tml@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/source/ui/vba/vbaapplication.cxx103
-rw-r--r--sw/source/ui/vba/vbaapplication.hxx20
2 files changed, 121 insertions, 2 deletions
diff --git a/sw/source/ui/vba/vbaapplication.cxx b/sw/source/ui/vba/vbaapplication.cxx
index 4ffd6766d7af..f86032a249e7 100644
--- a/sw/source/ui/vba/vbaapplication.cxx
+++ b/sw/source/ui/vba/vbaapplication.cxx
@@ -27,7 +27,9 @@
#include "vbadocuments.hxx"
#include "vbaaddins.hxx"
#include "vbadialogs.hxx"
+#include <ooo/vba/XConnectionPoint.hpp>
#include <ooo/vba/word/WdEnableCancelKey.hpp>
+#include <ooo/vba/word/XApplicationOutgoing.hpp>
#include <basic/sbuno.hxx>
#include <editeng/acorrcfg.hxx>
#include "wordvbahelper.hxx"
@@ -38,12 +40,48 @@ using namespace ::ooo;
using namespace ::ooo::vba;
using namespace ::com::sun::star;
-SwVbaApplication::SwVbaApplication( uno::Reference<uno::XComponentContext >& xContext ): SwVbaApplication_BASE( xContext )
+class SwVbaApplicationOutgoingConnectionPoint : public cppu::WeakImplHelper<XConnectionPoint>
+{
+private:
+ SwVbaApplication* mpApp;
+
+public:
+ SwVbaApplicationOutgoingConnectionPoint( SwVbaApplication* pApp );
+
+ // XConnectionPoint
+ sal_uInt32 SAL_CALL Advise(const uno::Reference< XSink >& Sink ) override;
+ void SAL_CALL Unadvise( sal_uInt32 Cookie ) override;
+};
+
+SwVbaApplication::SwVbaApplication( uno::Reference<uno::XComponentContext >& xContext ):
+ SwVbaApplication_BASE( xContext )
{
}
SwVbaApplication::~SwVbaApplication()
{
+ // FIXME: Sadly this is not the place to do this, this dtor is never called, it seems
+ for (auto& i : mvSinks)
+ {
+ if (i.is())
+ i->Call("Quit", uno::Sequence<uno::Any>());
+ }
+}
+
+sal_uInt32
+SwVbaApplication::AddSink( const css::uno::Reference< XSink >& xSink )
+{
+ mvSinks.push_back(xSink);
+ return mvSinks.size();;
+}
+
+void
+SwVbaApplication::RemoveSink( sal_uInt32 nNumber )
+{
+ if (nNumber < 1 || nNumber > mvSinks.size())
+ return;
+
+ mvSinks[nNumber-1] = uno::Reference< XSink >();
}
OUString SAL_CALL
@@ -94,6 +132,13 @@ SwVbaApplication::getSelection()
uno::Any SAL_CALL
SwVbaApplication::Documents( const uno::Any& index )
{
+ // FIXME DUMMY just to test calling this somewhere... the dtor is never called
+ for (auto& i : mvSinks)
+ {
+ if (i.is())
+ i->Call("Quit", uno::Sequence<uno::Any>());
+ }
+
uno::Reference< XCollection > xCol( new SwVbaDocuments( this, mxContext ) );
if ( index.hasValue() )
return xCol->Item( index, uno::Any() );
@@ -159,12 +204,48 @@ void SAL_CALL SwVbaApplication::ShowMe()
// No idea what we should or could do
}
+// XInterfaceWithIID
+
+OUString SAL_CALL
+SwVbaApplication::getIID()
+{
+ return OUString("{82154421-0FBF-11d4-8313-005004526AB4}");
+}
+
uno::Reference< frame::XModel >
SwVbaApplication::getCurrentDocument()
{
return getCurrentWordDoc( mxContext );
}
+// XConnectable
+
+OUString SAL_CALL
+SwVbaApplication::GetIIDForClassItselfNotCoclass()
+{
+ return OUString("{82154423-0FBF-11D4-8313-005004526AB4}");
+}
+
+TypeAndIID SAL_CALL
+SwVbaApplication::GetConnectionPoint()
+{
+ TypeAndIID aResult =
+ { word::XApplicationOutgoing::static_type(),
+ "{82154422-0FBF-11D4-8313-005004526AB4}"
+ };
+
+ return aResult;
+}
+
+uno::Reference<XConnectionPoint> SAL_CALL
+SwVbaApplication::FindConnectionPoint()
+{
+ uno::Reference<XConnectionPoint> xCP(new SwVbaApplicationOutgoingConnectionPoint(this));
+ return xCP;
+}
+
+// XHelperInterface
+
OUString
SwVbaApplication::getServiceImplName()
{
@@ -183,4 +264,24 @@ SwVbaApplication::getServiceNames()
return aServiceNames;
}
+SwVbaApplicationOutgoingConnectionPoint::SwVbaApplicationOutgoingConnectionPoint( SwVbaApplication* pApp ) :
+ mpApp(pApp)
+{
+}
+
+// SwVbaApplicationOutgoingConnectionPoint
+
+// XConnectionPoint
+sal_uInt32 SAL_CALL
+SwVbaApplicationOutgoingConnectionPoint::Advise( const uno::Reference< XSink >& Sink )
+{
+ return mpApp->AddSink(Sink);
+}
+
+void SAL_CALL
+SwVbaApplicationOutgoingConnectionPoint::Unadvise( sal_uInt32 Cookie )
+{
+ mpApp->RemoveSink( Cookie );
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaapplication.hxx b/sw/source/ui/vba/vbaapplication.hxx
index 161a5284d86b..73e16c5f71d1 100644
--- a/sw/source/ui/vba/vbaapplication.hxx
+++ b/sw/source/ui/vba/vbaapplication.hxx
@@ -1,4 +1,4 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This file is part of the LibreOffice project.
*
@@ -19,6 +19,9 @@
#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAAPPLICATION_HXX
#define INCLUDED_SW_SOURCE_UI_VBA_VBAAPPLICATION_HXX
+#include <vector>
+
+#include <ooo/vba/XSink.hpp>
#include <ooo/vba/word/XApplication.hpp>
#include <ooo/vba/word/XDocument.hpp>
#include <ooo/vba/word/XWindow.hpp>
@@ -34,10 +37,16 @@ typedef cppu::ImplInheritanceHelper< VbaApplicationBase, ooo::vba::word::XApplic
class SwVbaApplication : public SwVbaApplication_BASE
{
+ // FIXME: We allow just one sink at a time
+ std::vector<css::uno::Reference< ooo::vba::XSink >> mvSinks;
+
public:
explicit SwVbaApplication( css::uno::Reference< css::uno::XComponentContext >& m_xContext );
virtual ~SwVbaApplication() override;
+ sal_uInt32 AddSink( const css::uno::Reference< ooo::vba::XSink >& xSink );
+ void RemoveSink( sal_uInt32 nNumber );
+
// XApplication
virtual OUString SAL_CALL getName() override;
virtual css::uno::Reference< ooo::vba::word::XSystem > SAL_CALL getSystem() override;
@@ -56,6 +65,15 @@ public:
virtual void SAL_CALL setEnableCancelKey( sal_Int32 _enableCancelKey ) override;
virtual float SAL_CALL CentimetersToPoints( float Centimeters ) override;
virtual void SAL_CALL ShowMe() 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;
+
// XHelperInterface
virtual OUString getServiceImplName() override;
virtual css::uno::Sequence<OUString> getServiceNames() override;