Verdan
Verdan

Reputation: 21

How to make a Dynamic Context Menu for an Eclipse plug-in?

I am trying to make an Eclipse plugin which would be capable of dynamically change the context menu of the navigation view according to other plugins using an extension point that first plugin provides.

With a little Schematic : http://hpics.li/bddf781

The aim is that all the commands provided by plugin 2, 3 ... can be accessed in the navigation context menu thanks to plugin 1

I've already googled but I can't get anything to work.

For instance :

package com.sigasi;

 import java.util.Date;

 import org.eclipse.jface.action.ContributionItem;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.MenuItem;


 public class MyDynamicMenu extends ContributionItem {

    public MyDynamicMenu() {
    }

    public MyDynamicMenu(String id) {
    super(id);
    }

@Override
public void fill(Menu menu, int index) {
    //Here you could get selection and decide what to do
    //You can also simply return if you do not want to show a menu

    //create the menu item
    MenuItem menuItem = new MenuItem(menu, SWT.CHECK, index);
    menuItem.setText("My menu item (" + new Date() + ")");
    menuItem.addSelectionListener(new SelectionAdapter() {
        public void widgetSelected(SelectionEvent e) {
            //what to do when menu is subsequently selected.
            System.err.println("Dynamic menu selected");
        }
    });
}
}

with :

<extension point="org.eclipse.ui.menus">
<menuContribution locationURI="popup:org.eclipse.ui.navigator.ProjectExplorer#PopupMenu?after=additions">
    <dynamic
              class="com.sigasi.MydynamicMenu"
              id="com.sigasi.myDynamicMenu">
    </dynamic>
  </menuContribution>
</extension>

Source : http://www.sigasi.com/content/dynamic-menu-items-eclipse

Which could be great if it wouldn't add just one item to the Menu. I tried to adapt it to my need without success.

Edit : I tried to change the super class of the java class up there to CompoundContributionItem; it allows to add multiple items to the menu but seems to replace existing ones depending on the index instead of simply adding it. Moreover, I still couldn't insert a Menu. Here is what I did :

package fr.cardinjoseph.extensionpoint.definition;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.CompoundContributionItem;
import org.eclipse.ui.menus.CommandContributionItem;
import org.eclipse.ui.menus.CommandContributionItemParameter;

public class MyDynamicMenu extends CompoundContributionItem {

    ExtensionsFinder ef;

    public MyDynamicMenu() {
        ef = new ExtensionsFinder();
        ef.evaluateExtensions();
    }

    public MyDynamicMenu(String id) {
        super(id);
    }

    @Override
    public void fill(Menu menu, int index) {
        // Here you could get selection and decide what to do
        // You can also simply return if you do not want to show a menu

        // create the menu item

          Menu commandMenu = new Menu(menu);


         MenuItem test = new MenuItem(menu, index); test.setText("Test");
         test.addSelectionListener(new SelectionAdapter() { public void
         widgetSelected(SelectionEvent e) {  System.err.println("Dynamic menu selected"); }
         });


    }

    @Override
    protected IContributionItem[] getContributionItems() {
        // TODO Auto-generated method stub
        int size = ef.getExtensions().size();
        IContributionItem[] list = new IContributionItem[size];

        IWorkbench wb = PlatformUI.getWorkbench();
        IWorkbenchWindow win = wb.getActiveWorkbenchWindow();

        for(int i = 0 ; i< size ; i++){
            list[i] = new CommandContributionItem(new CommandContributionItemParameter(win, "MenuCommandeId_"+i, "CommandeId_"+i, SWT.None));
        }

        System.out.println("test");

        return list;
    }

    @Override
    public boolean isDynamic(){
        return true;
    }

}

Upvotes: 2

Views: 5313

Answers (2)

Alex K.
Alex K.

Reputation: 3304

There is a possibility to show/hide, enable/disable menus by using enabledWhen/visibleWhen elements and implementing your own property testers or source providers. Please see also following tutorial for example.

In this case you would create all menu items and test required conditions when you want to show those. Something like this:

<extension point="org.eclipse.ui.menus">
<menuContribution allPopups="false" locationURI="menu:org.eclipse.ui.main.menu">
           <menu id="id" label="%label">
               <visibleWhen
                    checkEnabled="false">
                    <with
                        variable="SomeProvider.var1">
                    </with>
              </visibleWhen>
              <command commandId="command1" id="com1" label="%test" style="push">
              </command>
           </menu>
        </menuContribution>
 </extension>

 <extension
         point="org.eclipse.ui.services">
      <sourceProvider
            provider="com.your_package.SomeProvider">
         <variable
               name="SomeProvider.var1"
               priorityLevel="workbench">
         </variable>
      </sourceProvider>
</extension>
public class SomeProvider extends AbstractSourceProvider {
   private static final String VAR1 = "SomeProvider.var1";

    @Override
    public Map getCurrentState() {
        Map<String, String> stateMap = new HashMap<String, String>();
                stateMap.put(VAR1, testIfMenuForVar1ShouldBeShown());
        return stateMap;
    }
}

Upvotes: 1

Wernke
Wernke

Reputation: 41

You can add multiple menu items like this:

    @Override
    public void fill(Menu menu, int index) {
        MenuItem menuItem = new MenuItem(menu, SWT.CHECK, index);
        menuItem.setText("1. menu item (" + new Date() + ")");

        menuItem = new MenuItem(menu, SWT.CHECK, index);
        menuItem.setText("2. menu item (" + new Date() + ")");

        menuItem = new MenuItem(menu, SWT.CHECK, index);
        menuItem.setText("3. menu item (" + new Date() + ")");
    }

or add a cascading menu like this:

    @Override
    public void fill(Menu menu, int index) {
        Menu cascMenu = new Menu(menu);
        MenuItem cascade = new MenuItem(cascMenu, SWT.CASCADE, index);
        cascade.setText("Cascade...");
        cascade.setMenu(cascMenu);

        MenuItem menuItem = new MenuItem(cascade, SWT.CHECK, index);
        menuItem.setText("1. menu item (" + new Date() + ")");
        // etc.
    }

Upvotes: 1

Related Questions