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

Modify Contextual Menu 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 Aug 03, 2006 2:04 am    Post subject: Modify Contextual Menu in C++ Reply with quote

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
View user's profile Send private message
SergeM
Super User
Super User


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

PostPosted: Fri Aug 04, 2006 12:37 am    Post subject: Reply with quote

Manuguy,
Happy to see you again.
Thank you for this code.
Is this code working for 1.1 and 2.0 OOo version ?
(I have not checked it at the moment)
_________________
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
manuguy
General User
General User


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

PostPosted: Fri Aug 04, 2006 4:46 am    Post subject: Reply with quote

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
View user's profile Send private message
picris
General User
General User


Joined: 19 Feb 2010
Posts: 5

PostPosted: Wed Apr 21, 2010 11:00 pm    Post subject: Reply with quote

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
View user's profile Send private message
SergeM
Super User
Super User


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

PostPosted: Tue Apr 27, 2010 8:30 am    Post subject: Reply with quote

If you are a beginner, please read this document :
http://wiki.services.openoffice.org/wiki/Using_Cpp_with_the_OOo_SDK
and particularly :
http://wiki.services.openoffice.org/wiki/SDKInstallation
Good luck.
_________________
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
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