| View previous topic :: View next topic |
| Author |
Message |
manuguy General User

Joined: 25 Nov 2004 Posts: 38 Location: Massy - FRANCE
|
Posted: Thu Jan 20, 2005 7:29 am Post subject: How to change a menu action with Dispatch Interceptor in C++ |
|
|
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 |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
lirincy Newbie

Joined: 26 Jan 2005 Posts: 3
|
Posted: Thu Jan 27, 2005 12:21 am Post subject: |
|
|
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 |
|
 |
manuguy General User

Joined: 25 Nov 2004 Posts: 38 Location: Massy - FRANCE
|
Posted: Thu Jan 27, 2005 1:29 am Post subject: |
|
|
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 |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
fledain General User


Joined: 26 Oct 2005 Posts: 6
|
Posted: Mon Nov 28, 2005 8:36 am Post subject: |
|
|
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 |
|
 |
|
|
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
|