Choub890
Choub890

Reputation: 1163

Eclipse Plugin: Populating dynamically a menu with commands and corresponding handlers

I am trying to create a plugin in eclipse which adds a menu item when right clicking on a file or folder in the package explorer. That menu item contains certain commands that have to be loaded dynamically (so i can't hardcode them in the plugin.xml). The commands are actually in another extension which attaches itself to my plugin via an extension point that i have provided.

What i am doing right now is creating the menu item, populating it with all the commands that are attached to my extension point and adding a ButtonListener to all of them. Everything works that way, but there is one problem. I need to get the information on which item in the package explorer the user right clicked (is it an IFile or IFolder item?) and, from my research, i need to do that in the handler like follows:

public Object execute(ExecutionEvent event) throws ExecutionException {

    ISelection currentSelection = HandlerUtil.getCurrentSelection(event);
    TreeSelection treeSelection = (TreeSelection) currentSelection;
    Object firstElement = treeSelection.getFirstElement();

    ActionMenu.setNode(firstElement);

    return null;
}

Where Action menu is the actual class representing the menu item and is in charge of populating it. Unfortunately, that code is never called right now in my plugin.

My question is:

How can i create dynamically a handler per command in order for the execute() function to get called? Or is there a better way, in my ActionMenu class, to get the selection of the user's right click (to know if it's an IFolder or IFile)?

Here is the relevant code in my ActionMenu class (the fill() function which adds each commands as a sub menu item and the ButtonListener nested class). ICommand is the interface the commands must implement in the other extension:

...

public final void fill(final Menu menu, final 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

    List<ICommand> commands = new ArrayList<ICommand>();
    IConfigurationElement[] contributions = Platform.getExtensionRegistry().getConfigurationElementsFor(Extension_Point_ID);

    try {
        for (IConfigurationElement e : contributions) {
            final Object o =
                e.createExecutableExtension("class");
            commands.add((ICommand) o);
        }
    } catch (CoreException ex) {
        System.out.println(ex.getMessage());
    }

    for (ICommand command : commands)
    {
        MenuItem menuItem = new MenuItem(menu, SWT.CHECK, index);
        menuItem.setText(command.getName());
        menuItem.addSelectionListener(new ButtonListener(command));
    }
}

public class ButtonListener extends SelectionAdapter {

    ICommand command_;

    public ButtonListener(ICommand command) {
        command_ = command;
    }

    @Override
    public final void widgetSelected(final SelectionEvent e) {

        if (node_ instanceof org.eclipse.core.resources.IFile) {
            command_.executeFile(node_);
        }

        else if (node_ instanceof org.eclipse.core.resources.IFolder) {
            command_.executeFolder(node_);
        }
    }
}

Here is the content of my plugin.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
   <extension-point id="ca.polymtl.log8430.Command" name="Command" schema="schema/ca.polymtl.log8430.Command.exsd"/>

<extension point="org.eclipse.ui.menus">
    <menuContribution locationURI="popup:org.eclipse.ui.navigator.ProjectExplorer#PopupMenu?after=additions">
    <menu
        id="apply_command"
        label="ApplyCommand">
    </menu>
    </menuContribution>

    <menuContribution locationURI="popup:apply_command?after=additions">
        <dynamic
                  class="ca.polymtl.log8430.popup.ActionMenu"
                  id="ca.polymtl.log8430.popup.actionMenu">   
        </dynamic>
    </menuContribution>
</extension>

 <extension
   point="org.eclipse.ui.handlers">
    <handler
      class="ca.polymtl.log8430.Handler"
      commandId="ca.polymtl.log8430.Command1">
    </handler>
 </extension>
 <extension
   point="org.eclipse.ui.commands">
    <command
      id="ca.polymtl.log8430.Command1"
      name="Command_1">
    </command>
 </extension>

</plugin>

Thanks for your help, and if you need more details, please don't hesitate to ask.

Upvotes: 3

Views: 1925

Answers (1)

greg-449
greg-449

Reputation: 111217

Given the way you have set up the menus you don't need to use a handler. You can simply get the current selection in your widgetSelected method of the listener:

IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();

IStructuredSelection selection = (IStructuredSelection)page.getSelection();

Note: The actual selection may not implement IFile or IFolder directly, so you should use the platform adapter manager to see if they adapt to the resource:

Object selObject = selection.getFirstElement();

IResource resource = (IResource)Platform.getAdapterManager().getAdapter(selObject, IResource.class);

and then test resource to see if it is an IFile or IFolder.

Upvotes: 1

Related Questions