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

Joined: 25 Nov 2004 Posts: 38 Location: Massy - FRANCE
|
Posted: Thu Aug 03, 2006 2:04 am Post subject: Modify Contextual Menu in C++ |
|
|
Hello,
Here is the code (in C++) to modify and implement a new function in a Contextual Menu.
I didn't put all includes and namespace to use. Don't forget them.
| Code: |
[...]
#include <cppuhelper/implbase1.hxx> // for WeakImplHelper1
#include <cppuhelper/implbase2.hxx> // for WeakImplHelper2
[...]
// Class to implement the new functions of Contextual Menu (or any other Menu)
class DispInterceptor : public WeakImplHelper2 < XDispatchProviderInterceptor, XDispatch >
{
private:
Reference <XDispatchProvider> m_xMaster;
Reference <XDispatchProvider> m_xSlave;
public:
// Redirect here all new functions, to implement them in method "dispatch"
virtual Reference< XDispatch > SAL_CALL queryDispatch(const ::com::sun::star::util::URL& aURL,
const ::rtl::OUString& sTarget, sal_Int32 nSearchFlags )
throw( ::com::sun::star::uno::RuntimeException )
{
// printf ("QDisp = %s\n", OUStringToOString(aURL.Complete, RTL_TEXTENCODING_ISO_8859_1).getStr()) ;
if (aURL.Complete.compareToAscii("MyNewMenu") == 0)
return this; // return "this" for all new functions to implement
// Then implement your functions in method : dispatch (see below)
// Don't modify other existing functions
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( ::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)
{
return m_xSlave;
}
virtual void setSlaveDispatchProvider(const Reference <XDispatchProvider> &xSlave)
throw (com::sun::star::uno::RuntimeException)
{
m_xSlave = xSlave;
}
virtual Reference <XDispatchProvider> getMasterDispatchProvider()
throw (com::sun::star::uno::RuntimeException)
{
return m_xMaster;
}
virtual void setMasterDispatchProvider(const Reference <XDispatchProvider> &xMaster)
throw (com::sun::star::uno::RuntimeException)
{
m_xMaster = xMaster;
}
// XDispatch : implement HERE the new functions of contextual Menu (or any other Menu)
virtual void SAL_CALL dispatch( const URL& aURL, const Sequence< PropertyValue >& lArgs )
throw (::com::sun::star::uno::RuntimeException)
{
printf("Disp = %s\n", OUStringToOString(aURL.Complete, RTL_TEXTENCODING_ISO_8859_1).getStr());
if (aURL.Complete.compareToAscii("MyNewMenu") == 0)
{
// WRITE HERE THE CODE FOR "MyNewMenu"
}
}
virtual void SAL_CALL addStatusListener( const Reference < XStatusListener > &xControl, const URL& aURL )
throw (::com::sun::star::uno::RuntimeException) {};
virtual void SAL_CALL removeStatusListener( const Reference < XStatusListener > &xControl, const URL& aURL )
throw (::com::sun::star::uno::RuntimeException) {};
};
// Class to intercept and modify the contextual Menu
class MenuInterceptor : public WeakImplHelper1< ::com::sun::star::ui::XContextMenuInterceptor >
{
virtual ::com::sun::star::ui::ContextMenuInterceptorAction SAL_CALL notifyContextMenuExecute(const ContextMenuExecuteEvent &aEvent)
throw( ::com::sun::star::uno::RuntimeException )
{
printf("notifyContextMenuExecute called\n");
// Get the Menu
Reference <XIndexContainer> xContextMenu = aEvent.ActionTriggerContainer;
Reference <XMultiServiceFactory> xMenuElementFactory (xContextMenu, UNO_QUERY);
if ( xMenuElementFactory != NULL )
{
// Create a root menu entry
Reference <XPropertySet> xRootMenuEntry (xMenuElementFactory->createInstance(OUString::createFromAscii("com.sun.star.ui.ActionTrigger") ), UNO_QUERY);
// Create a separator line for our new menu
Reference <XPropertySet> xSeparator (xMenuElementFactory->createInstance(OUString::createFromAscii("com.sun.star.ui.ActionTriggerSeparator") ), UNO_QUERY);
xSeparator->setPropertyValue(OUString::createFromAscii( "SeparatorType"), makeAny((sal_Int8) 0) );
xRootMenuEntry->setPropertyValue( OUString::createFromAscii("Text"), makeAny(OUString::createFromAscii("MyMenu")));
xRootMenuEntry->setPropertyValue( OUString::createFromAscii("CommandURL"), makeAny(OUString::createFromAscii("MyNewMenu")));
xContextMenu->insertByIndex( 0, makeAny(xSeparator) );
xContextMenu->insertByIndex( 0, makeAny(xRootMenuEntry) );
}
// The controller should execute the modified context menu and stop notifying other interceptors
ContextMenuInterceptorAction action = (com::sun::star::ui::ContextMenuInterceptorAction) 2; // EXECUTE_MODIFIED
return action;
}
};
// MAIN
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(
"YOUR_PROGNAME.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
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 );
// Create new spreadsheet document
Reference<XComponent> xComponent = xComponentLoader->loadComponentFromURL(
OUString::createFromAscii("private:factory/scalc"),
OUString( RTL_CONSTASCII_USTRINGPARAM("_blank") ), 0,
Sequence < ::com::sun::star::beans::PropertyValue >() );
// GET THE COMPONENT FACTORY
Reference<XMultiServiceFactory> xDocFactory(xComponent,UNO_QUERY);
Reference<XModel> xModel (xComponent, UNO_QUERY);
// then get the current controller from the model
Reference<XController> xController = xModel->getCurrentController();
// Modify Contextual Menu (add or remove items)
Reference <XContextMenuInterception> aMenuInterceptor (xController, UNO_QUERY);
MenuInterceptor *xMenuIntercept = new MenuInterceptor();
Reference <XContextMenuInterceptor> myInterceptor
= static_cast< XContextMenuInterceptor* > ( xMenuIntercept );
aMenuInterceptor->registerContextMenuInterceptor(myInterceptor);
// Interception of Menu functions to implement them
Reference <XFrame> xFrame = xController->getFrame();
Reference <XDispatchProviderInterception> aFrDispatchInteception (xFrame, UNO_QUERY);
DispInterceptor *xDispIntercept=new DispInterceptor();
Reference< ::com::sun::star::frame::XDispatchProviderInterceptor > myInterceptor2
= static_cast< ::com::sun::star::frame::XDispatchProviderInterceptor* > ( xDispIntercept );
aFrDispatchInteception->registerDispatchProviderInterceptor(myInterceptor2);
// Wait for events
getchar();
// dispose the local service manager
Reference< XComponent >::query( xMultiComponentFactoryClient )->dispose();
xComponent->dispose(); // close Component
return 0;
}
|
Hope that will help.
Regards. |
|
| Back to top |
|
 |
SergeM Super User

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

Joined: 25 Nov 2004 Posts: 38 Location: Massy - FRANCE
|
Posted: Fri Aug 04, 2006 4:46 am Post subject: |
|
|
Hello Serge,
I tested the code only with 2.0, but I didn't use anything specific for 2.0, so
it should work also for 1.1.x.
Regards. |
|
| Back to top |
|
 |
picris General User

Joined: 19 Feb 2010 Posts: 5
|
Posted: Wed Apr 21, 2010 11:00 pm Post subject: |
|
|
hello
I am a beginner in programming open office and I want custom the contextual Menu. I tested this code but I can't get it to work because I don't find what are the includes and namespace is missing. Could you tell me all includes and namespace?
thank you in advance,
Regards, |
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| 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
|