Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

e4 dynamic menu contributions

Tags:

eclipse

e4

This feature has been realized as of Kepler M4, for a detailed information on the usage see my blog

I want to realize a fully dynamic menu contribution to the menu of a handler located in a view toolbar. In Eclipse 3 it was possible to add "dynamic" as org.eclipse.ui.menus contribution to a Menu!

I already found out about www.vogella.com/blog/2010/10/26/processors-e4-model explaining on how to dynamically contribute to menus by means of processor model extensions but I am talking about a completely dynamic menu implementation which changes on every call of the resp. submenu. As mentioned this was no problem to realize in Eclipse 3.x via the dynamic menu contribution and the set of isDynamic() to true.

I already tried several approaches:

  • Registering a processor hooking to a menu => no dynamic add possible (new elements are simply not shown, also discussed in Eclipse Forum - Cannot replace menu items at runtime)
  • Listening to the UIEventTopic for the event of creating the menu, getting the widget for Modification => modifications to the swt.Menu gathered are simply ignored (every listener, element etc.) (for info RCP Event Model

Open, untried solutions

  • Inserting a ToolControl to try an SWT approach -> quite complicated but may work

I've been banging my head for some time now, but can't seem to understand the correct implementation of this problem within E4.

-- This question was also asked in Eclipse Forum - Dynamic menu contributions

----- UPDATE

I tried a different approach up to now:

I added a HandledToolItem to the Menu (please see the following image)

Fragment command approach

and with the following code I am trying to interfere with the menus way to build, where the code is called by the resp. command handleer as referenced in the image.

@CanExecute
    public boolean canExecute(@Optional MApplication application) {
        System.out.println("CanExecute Counter="+counter);
            // --- 1 ---
        // Find the required MMenu Entry in the Application Model
        if(application == null) return true;
        EModelService modelService = (EModelService) application.getContext().get(EModelService.class.getName());
        MPart part = (MPart) modelService.find("at.medevit.emr.contacts.ui.contactselector", application);
        List<MToolBarElement> lmte = part.getToolbar().getChildren();
        HandledToolItemImpl htil = null;
        for (MToolBarElement mToolBarElement : lmte) {
            if(mToolBarElement.getElementId().equals("at.medevit.emr.contacts.ui.contactselector.toolbar.handledtoolitem.filter")) htil = (HandledToolItemImpl) mToolBarElement;
        }
        if(htil != null) {
            MMenu elemMenu = htil.getMenu();
        // --- 2 ---
            // Found it hopefully, let's start the real work, simply add a new item
        MDirectMenuItem mdi = MMenuFactory.INSTANCE.createDirectMenuItem();
        mdi.setLabel("Counter "+counter);
        counter++;
            // --- 3 ---
        elemMenu.getChildren().add(mdi); // ConcurrentModificationException
        }

As one can see, this code is queried once the menu is created, to determine whether the command is executable or not. All the code from 1 - 2 is to find the correct MMenu element to work on. The code from 2 - 3 creates a MenuItem and increments a counter in the field.

BUT at 3 I face a java.util.ConcurrentModificationException the first time the menu is opened! I assume that at this very point the menu is iterating over elemMenu.getChildren() and I am not allowed to enable!

So whats all the fuzz about the entire e4 model being changeable all the time ;) (just kiddin' I know this is a baaaad hack!!!)

Thing is: I really think that the possibility to add fully dynamic menu parts is one of the best usability tools, and if it is not possible to realize it in E4 as it was in E3 this is a very serious degradation of possibilities!!!

-- UPDATE

An Eclipse Bug has been filed for this https://bugs.eclipse.org/bugs/show_bug.cgi?id=389063

like image 389
col.panic Avatar asked Nov 04 '22 16:11

col.panic


1 Answers

Proper dynamic model updates should be handled in the bug you've opened. As a workaround in Eclipse4 in Juno, a MRenderedMenuItem can be created in Eclipse4 to provide the equivalent functionality to the dynamic element (although if you are using 4.2, you would just use org.eclipse.ui.menus).

ex:

ContextFunction generator = new ContextFunction() {
    @Override
    public Object compute(IEclipseContext context) {
        return new MyCompoundContributionItem(context);
    }
};

MRenderedMenuItem menuItem = MenuFactoryImpl.eINSTANCE.createRenderedMenuItem();
menuItem.setElementId(id);
menuItem.setContributionItem(generator);
container.getChildren().add(menuItem);

This effectively provides a CompoundContributionItem directly to the Eclipse4 menu renderer.

like image 169
Paul Webster Avatar answered Nov 15 '22 07:11

Paul Webster