package de.ralfebert.rcputils.menus; import org.eclipse.core.commands.common.CommandException; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MenuAdapter; import org.eclipse.swt.events.MenuEvent; import org.eclipse.swt.events.MenuListener; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchPartSite; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.menus.CommandContributionItem; import de.ralfebert.rcputils.internal.RcpUtilsPlugin; /** * ContextMenu creates a context menu for a structured viewer and registers it * with the workbench. It can assist with handling the default menu item. * * @author Ralf Ebert * @see http://www.ralfebert.de/blog/eclipsercp/commands_context_menu/ */ public class ContextMenu { private static final String MENU_ID_DEFAULT = ".default"; private final Menu menu; private final IWorkbenchPartSite site; private final StructuredViewer viewer; private final boolean defaultItemHandling = false; /** * Creates an empty context menu for a structured viewer and registers it * for the given workbench part site. The created menu is intended to be * filled using contributions to "org.eclipse.ui.menus" with locationURI * "popup:<viewid>". If defaultItemHandling = true, */ public ContextMenu(StructuredViewer viewer, final IWorkbenchPartSite site) { this.viewer = viewer; this.site = site; MenuManager menuManager = new MenuManager(); menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); this.menu = menuManager.createContextMenu(viewer.getControl()); viewer.getControl().setMenu(menu); site.registerContextMenu(menuManager, viewer); site.setSelectionProvider(viewer); } @Deprecated public ContextMenu(StructuredViewer viewer, final IWorkbenchPartSite site, boolean defaultItemHandling) { this(viewer, site); setDefaultItemHandling(defaultItemHandling); } /** * Activates default item handling. When set to true, the menu is extended * so that the first command contribution whose contribution id ends with * ".default" is set as default item for the menu. The double click event is * handled by executing the default command. */ public void setDefaultItemHandling(boolean defaultItemHandling) { if (this.defaultItemHandling != defaultItemHandling) { if (defaultItemHandling) { menu.addMenuListener(listenerSetDefaultItem); viewer.addDoubleClickListener(listenerExecuteDefaultCommand); } else { menu.removeMenuListener(listenerSetDefaultItem); viewer.removeDoubleClickListener(listenerExecuteDefaultCommand); } } } private MenuItem getDefaultMenuItem() { for (MenuItem menuItem : menu.getItems()) { if (menuItem.getData() instanceof CommandContributionItem) { CommandContributionItem contributionItem = (CommandContributionItem) menuItem.getData(); if (contributionItem.getId() != null && contributionItem.getId().endsWith(MENU_ID_DEFAULT)) { return menuItem; } } } return null; } private final MenuListener listenerSetDefaultItem = new MenuAdapter() { @Override public void menuShown(MenuEvent event) { menu.setDefaultItem(getDefaultMenuItem()); } }; private final IDoubleClickListener listenerExecuteDefaultCommand = new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { menu.notifyListeners(SWT.Show, new Event()); MenuItem defaultItem = getDefaultMenuItem(); if (defaultItem != null) { CommandContributionItem contribution = (CommandContributionItem) defaultItem.getData(); IHandlerService handlerService = (IHandlerService) site.getService(IHandlerService.class); try { handlerService.executeCommand(contribution.getCommand(), null); } catch (CommandException e) { RcpUtilsPlugin.logException(e); } } } }; }