I am looking for some sample code in C++ for the functionality available through XDispatchProviderInterceptor . I wish to track some menu items in the menu bar (created using Add-ons). When the user clicks on the Add-on Menu buttons, I wish to intercept the call using the XDispatchProviderInterceptor interface in an external application which is connected to OpenOffice. Is this possible?
I will be grateful if you can provide some sample code to demonstrate the above or comment on how I should go about it.
thanks
Mangesh
[Solved] C++ code required for XDispatchProviderInterceptor
[Solved] C++ code required for XDispatchProviderInterceptor
Last edited by mangesh on Tue Feb 05, 2013 10:07 am, edited 1 time in total.
OpenOffice3.4.0 Win7 x64.
Re: Sample C++ code required for XDispatchProviderIntercepto
I got the sample code I was looking for in the oooforum. I found the links at several places, but the links failed to open up. I am attaching the code for reference on this forum.
Here is the link to the original article
http://www.oooforum.org/forum/viewtopic.phtml?t=16224
Here is the link to the original article
http://www.oooforum.org/forum/viewtopic.phtml?t=16224
Code: Select all
#include <stdio.h>
#include <osl/file.hxx>
#include <cppuhelper/bootstrap.hxx>
#include <osl/file.hxx>
#include <osl/process.h>
#include <com/sun/star/bridge/XUnoUrlResolver.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/frame/XDispatchHelper.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/frame/XDispatchProviderInterceptor.hpp>
#include <com/sun/star/frame/XDispatchProviderInterception.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XMultiPropertySet.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/text/XTextDocument.hpp>
#include <com/sun/star/text/XText.hpp>
#include <string.h>
#include <strings.h>
#include <rtl/bootstrap.h>
#include <com/sun/star/container/XIndexAccess.hpp>
#include <cppuhelper/implbase1.hxx> // pour WeakImplHelper1
#include <cppuhelper/implbase2.hxx> // pour WeakImplHelper2
using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::util;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::bridge;
using namespace com::sun::star::frame;
using namespace com::sun::star::registry;
using namespace com::sun::star::text;
using namespace com::sun::star::awt;
using namespace com::sun::star::container;
using namespace com::sun::star::io;
using namespace cppu;
#define _(str) OUString::createFromAscii(str)
class DispInterceptor : public WeakImplHelper2 < ::com::sun::star::frame::XDispatchProviderInterceptor, com::sun::star::frame::XDispatch >
{
private:
Reference <XDispatchProvider> m_xMaster;
Reference <XDispatchProvider> m_xSlave;
Reference <XComponent> mxComponent;
public:
//DispInterceptor();
// ~DispInterceptor();
void SAL_CALL initialize(Reference<XComponent> theComponent ) throw ( Exception, RuntimeException)
{
mxComponent = theComponent;
}
virtual Reference< XDispatch > SAL_CALL queryDispatch( const URL& aURL, const OUString& sTarget, sal_Int32 nSearchFlags ) throw( RuntimeException )
{
if ((aURL.Complete.compareToAscii(".uno:SaveAs") == 0) || (aURL.Complete.compareToAscii(".uno:Save") == 0))
{
printf("intercept Save or SaveAs !\n");
fflush(stdout);
return this; // return this to call this->dispatch at next SaveAs
}
if (m_xSlave!=NULL)
return m_xSlave->queryDispatch(aURL, sTarget, nSearchFlags);
return NULL;
}
virtual Sequence < Reference<XDispatch > > SAL_CALL queryDispatches( const Sequence < DispatchDescriptor >& seqDescriptor ) throw( RuntimeException )
{
sal_Int32 nCount = seqDescriptor.getLength();
Sequence < Reference < XDispatch > > lDispatcher( nCount );
for( sal_Int32 i=0; i<nCount; ++i )
lDispatcher[i] = queryDispatch( seqDescriptor[i].FeatureURL, seqDescriptor[i].FrameName, seqDescriptor[i].SearchFlags );
return lDispatcher;
}
// XDispatchProviderInterceptor
virtual Reference <XDispatchProvider> SAL_CALL getSlaveDispatchProvider() throw (RuntimeException)
{
printf("get Slave\n");
fflush(stdout);
return m_xSlave;
}
virtual void SAL_CALL setSlaveDispatchProvider(const Reference <XDispatchProvider> &xSlave) throw (RuntimeException)
{
printf("set Slave\n");
fflush(stdout);
m_xSlave = xSlave;
}
virtual Reference <XDispatchProvider> SAL_CALL getMasterDispatchProvider() throw (RuntimeException)
{
printf("get Master\n");
fflush(stdout);
return m_xMaster;
}
virtual void SAL_CALL setMasterDispatchProvider(const Reference <XDispatchProvider> &xMaster) throw (RuntimeException)
{
printf("set Master\n");
fflush(stdout);
m_xMaster = xMaster;
}
// XDispatch
virtual void SAL_CALL dispatch( const URL& aURL, const Sequence< PropertyValue >& lArgs ) throw (RuntimeException)
{
printf("Dispatch: %s\n", OUStringToOString(aURL.Complete, RTL_TEXTENCODING_ISO_8859_1).getStr());
fflush(stdout);
// Implement what you want here instead of SaveAs
// save to a URL (for example)
Reference <XStorable> xStore (mxComponent, UNO_QUERY);
xStore->storeAsURL(_("file:///e:/tmp/test.sxw"), Sequence < ::com::sun::star::beans::PropertyValue >() );
}
virtual void SAL_CALL addStatusListener( const Reference< XStatusListener >& xControl, const URL& aURL ) throw (RuntimeException)
{
printf(" addStatusListener : %s \n", OUStringToOString(aURL.Complete, RTL_TEXTENCODING_ISO_8859_1).getStr());
}
virtual void SAL_CALL removeStatusListener( const Reference< XStatusListener >& xControl, const URL& aURL ) throw (RuntimeException)
{
printf(" removeStatusListener : %s \n", OUStringToOString(aURL.Complete, RTL_TEXTENCODING_ISO_8859_1).getStr());
}
};
int SAL_CALL main( int argc, char **argv )
{
OUString sConnectionString(RTL_CONSTASCII_USTRINGPARAM("uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager"));
// Creates a simple registry service instance.
Reference< XSimpleRegistry > xSimpleRegistry(
::cppu::createSimpleRegistry() );
// Connects the registry to a persistent data source represented by an URL.
xSimpleRegistry->open( OUString( RTL_CONSTASCII_USTRINGPARAM(
"dispatch_interceptor.rdb") ), sal_True, sal_False );
Reference< XComponentContext > xComponentContext(
::cppu::bootstrap_InitialComponentContext( xSimpleRegistry ) );
Reference< XMultiComponentFactory > xMultiComponentFactoryClient(
xComponentContext->getServiceManager() );
/* Creates an instance of a component which supports the services specified
by the factory. */
Reference< XInterface > xInterface =
xMultiComponentFactoryClient->createInstanceWithContext(
OUString::createFromAscii( "com.sun.star.bridge.UnoUrlResolver" ),
xComponentContext );
Reference< XUnoUrlResolver > resolver( xInterface, UNO_QUERY );
// Resolves the component context from the office, on the uno URL given by argv[1].
try
{
xInterface = Reference< XInterface >(
resolver->resolve( sConnectionString ), UNO_QUERY );
}
catch ( Exception& e )
{
printf("Error: cannot establish a connection using '%s':\n %s\n",
OUStringToOString(sConnectionString, RTL_TEXTENCODING_ASCII_US).getStr(),
OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
exit(1);
}
// gets the server component context as property of the office component factory
Reference< XPropertySet > xPropSet( xInterface, UNO_QUERY );
xPropSet->getPropertyValue( OUString::createFromAscii("DefaultContext") ) >>= xComponentContext;
// gets the service manager from the office
Reference< XMultiComponentFactory > xMultiComponentFactoryServer(
xComponentContext->getServiceManager() );
/* Creates an instance of a component which supports the services specified
by the factory. Important: using the office component context.*/
Reference < XComponentLoader > xComponentLoader(
xMultiComponentFactoryServer->createInstanceWithContext(
OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop" ) ),
xComponentContext ), UNO_QUERY );
Reference<XComponent> xComponent = xComponentLoader->loadComponentFromURL(
OUString::createFromAscii("private:factory/swriter"),
OUString( RTL_CONSTASCII_USTRINGPARAM("_blank") ), 0,
//OUString( RTL_CONSTASCII_USTRINGPARAM("_default") ), 0,
Sequence < ::com::sun::star::beans::PropertyValue >() );
Reference<XModel> xModel (xComponent, UNO_QUERY);
// then get the current controller from the model
Reference<XController> xController = xModel->getCurrentController();
Reference<XFrame> xFrame = xController->getFrame();
// Dispatch interception : in order to modify actions
Reference <XDispatchProviderInterception> aFrDispatchInteception (xFrame, UNO_QUERY);
DispInterceptor *xDispIntercept=new DispInterceptor();
xDispIntercept->initialize(xComponent);
Reference< ::com::sun::star::frame::XDispatchProviderInterceptor > myInterceptor
= static_cast< ::com::sun::star::frame::XDispatchProviderInterceptor* > ( xDispIntercept );
aFrDispatchInteception->registerDispatchProviderInterceptor(myInterceptor);
getchar();
// dispose the local service manager
Reference< XComponent >::query( xMultiComponentFactoryClient )->dispose();
xComponent->dispose();
return 0;
}
Last edited by RoryOF on Tue Feb 05, 2013 10:24 am, edited 1 time in total.
Reason: Duplicate post removed to tidy the thread.
Reason: Duplicate post removed to tidy the thread.
OpenOffice3.4.0 Win7 x64.
Re: Sample C++ code required for XDispatchProviderIntercepto
Thank you for digging this out and posting here.
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice