OpenOffice.org Forum at OOoForum.orgThe OpenOffice.org Forum
 
 [Home]   [FAQ]   [Search]   [Memberlist]   [Usergroups]   [Register
 [Profile]   [Log in to check your private messages]   [Log in

How to change a menu action with Dispatch Interceptor in C++

 
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Code Snippets
View previous topic :: View next topic  
Author Message
manuguy
General User
General User


Joined: 25 Nov 2004
Posts: 38
Location: Massy - FRANCE

PostPosted: Thu Jan 20, 2005 7:29 am    Post subject: How to change a menu action with Dispatch Interceptor in C++ Reply with quote

The example below show how to change an action when the user click on an OO Menu.
In my example, I change the "SaveAs" action.

Code :
#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 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch >
SAL_CALL queryDispatch( const ::com::sun::star::util::URL& aURL,
const ::rtl::OUString& sTarget, sal_Int32 nSearchFlags )
throw( ::com::sun::star::uno::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 ::com::sun::star::uno::Sequence < ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > >
SAL_CALL queryDispatches(
const ::com::sun::star::uno::Sequence < ::com::sun::star::frame::DispatchDescriptor >& seqDescriptor )
throw( ::com::sun::star::uno::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> getSlaveDispatchProvider()
throw (com::sun::star::uno::RuntimeException)
{
printf("get Slave\n");
fflush(stdout);
return m_xSlave;
}

virtual void setSlaveDispatchProvider(const Reference <XDispatchProvider> &xSlave)
throw (com::sun::star::uno::RuntimeException)
{
printf("set Slave\n");
fflush(stdout);

m_xSlave = xSlave;
}

virtual Reference <XDispatchProvider> getMasterDispatchProvider()
throw (com::sun::star::uno::RuntimeException)
{
printf("get Master\n");
fflush(stdout);

return m_xMaster;
}

virtual void setMasterDispatchProvider(const Reference <XDispatchProvider> &xMaster)
throw (com::sun::star::uno::RuntimeException)
{
printf("set Master\n");
fflush(stdout);

m_xMaster = xMaster;
}


// XDispatch
virtual void SAL_CALL dispatch( const URL& aURL, const Sequence< PropertyValue >& lArgs )
throw (::com::sun::star::uno::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:///tmp/test.sxw"), Sequence < ::com::sun::star::beans::PropertyValue >() );

}
virtual void SAL_CALL addStatusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& xControl,
const ::com::sun::star::util::URL& aURL ) throw (::com::sun::star::uno::RuntimeException) {};
virtual void SAL_CALL removeStatusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& xControl, const ::com::sun::star::util::URL& aURL ) throw (::com::sun::star::uno::RuntimeException) {};

};

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;
}
Back to top
View user's profile Send private message
SergeM
Super User
Super User


Joined: 09 Sep 2003
Posts: 3211
Location: Troyes France

PostPosted: Thu Jan 20, 2005 9:16 am    Post subject: Reply with quote

Manuguy,
Thank you for the very interesting example example. I will try to add it in my document.
_________________
Linux & Windows OOo3.0
UNO & C++ : WIKI
http://wiki.services.openoffice.org/wiki/Using_Cpp_with_the_OOo_SDK
In French
http://wiki.services.openoffice.org/wiki/Documentation/FR/Cpp_Guide
Back to top
View user's profile Send private message Visit poster's website
lirincy
Newbie
Newbie


Joined: 26 Jan 2005
Posts: 3

PostPosted: Thu Jan 27, 2005 12:21 am    Post subject: Reply with quote

hi, manuguy:
thanks for your code, it really useful to us, we need to changed or intercept save/ save as menu action. when I compile your code, it reply errors like:
changesave.cxx(94) : error C2695: 'DispInterceptor::getSlaveDispatchProvider': overriding virtual function differs from 'com::sun::star::frame::XDispatchProviderInterceptor::getSlaveDispatchProvider' only by calling convention
o:\SRC680\wntmsci10.pro\inc.m73\com\sun\star\frame\XDispatchProviderInte
rceptor.hdl(32) : see declaration of 'com::sun::star::frame::XDispatchProviderIn
terceptor::getSlaveDispatchProvider'
...

how can I compile successfully and see the result?
Back to top
View user's profile Send private message
manuguy
General User
General User


Joined: 25 Nov 2004
Posts: 38
Location: Massy - FRANCE

PostPosted: Thu Jan 27, 2005 1:29 am    Post subject: Reply with quote

Hi,

I don't understand because the code I gave compiles correctly for me.
Did you copy it exactly? According to your message, it seems that you didn't
respect the signature of the method getSlaveDispatchProvider. Check the com\sun\star\frame\XDispatchProviderInterceptor.hdl file to see if it is the correct
signature. Don't forget the "throw (com::sun::star::uno::RuntimeException)".

Regards.
Back to top
View user's profile Send private message
SergeM
Super User
Super User


Joined: 09 Sep 2003
Posts: 3211
Location: Troyes France

PostPosted: Sat Jan 29, 2005 4:03 am    Post subject: Reply with quote

For me the code compile even if I encounter such unexplicable problems with IDL and hpp.
But i cannot make your code working.
_________________
Linux & Windows OOo3.0
UNO & C++ : WIKI
http://wiki.services.openoffice.org/wiki/Using_Cpp_with_the_OOo_SDK
In French
http://wiki.services.openoffice.org/wiki/Documentation/FR/Cpp_Guide
Back to top
View user's profile Send private message Visit poster's website
SergeM
Super User
Super User


Joined: 09 Sep 2003
Posts: 3211
Location: Troyes France

PostPosted: Sun Feb 06, 2005 6:27 am    Post subject: Reply with quote

Your code works.
I had done a mistake in the rdb name with my makefile.
_________________
Linux & Windows OOo3.0
UNO & C++ : WIKI
http://wiki.services.openoffice.org/wiki/Using_Cpp_with_the_OOo_SDK
In French
http://wiki.services.openoffice.org/wiki/Documentation/FR/Cpp_Guide
Back to top
View user's profile Send private message Visit poster's website
fledain
General User
General User


Joined: 26 Oct 2005
Posts: 6

PostPosted: Mon Nov 28, 2005 8:36 am    Post subject: Reply with quote

Hi.

I got the same problem: the issue is caused by the lack of SAL_CALL for such methods.

For example:

Code:
 virtual Reference <XDispatchProvider> [b]SAL_TYPE[/b] getSlaveDispatchProvider()
throw (com::sun::star::uno::RuntimeException)
{ ... }


Fred
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Code Snippets All times are GMT - 8 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group