[Solved] C++ code required for XDispatchProviderInterceptor

Java, C++, C#, Delphi... - Using the UNO bridges
Post Reply
mangesh
Posts: 26
Joined: Tue Aug 21, 2012 10:48 am

[Solved] C++ code required for XDispatchProviderInterceptor

Post by mangesh »

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

Post by mangesh »

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

#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.
User avatar
Villeroy
Volunteer
Posts: 31269
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Sample C++ code required for XDispatchProviderIntercepto

Post by Villeroy »

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
Post Reply