[Solved] C++ code required for XDispatchProviderInterceptor

Java, C++, C#, Delphi, ??? - Using the UNO bridges

[Solved] C++ code required for XDispatchProviderInterceptor

Postby mangesh » Mon Feb 04, 2013 1:04 pm

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
Last edited by mangesh on Tue Feb 05, 2013 10:07 am, edited 1 time in total.
OpenOffice3.4.0 Win7 x64.
mangesh
 
Posts: 26
Joined: Tue Aug 21, 2012 10:48 am

Re: Sample C++ code required for XDispatchProviderIntercepto

Postby mangesh » Tue Feb 05, 2013 10:06 am

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


Code: Select all   Expand viewCollapse view
#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.
OpenOffice3.4.0 Win7 x64.
mangesh
 
Posts: 26
Joined: Tue Aug 21, 2012 10:48 am

Re: Sample C++ code required for XDispatchProviderIntercepto

Postby Villeroy » Tue Feb 05, 2013 10:17 am

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, no OpenOffice, LibreOffice 6.4
User avatar
Villeroy
Volunteer
 
Posts: 28431
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany


Return to External Programs

Who is online

Users browsing this forum: No registered users and 1 guest