package rocks.inspectit.ui.rcp.action; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IMenuCreator; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; /** * Action to add a menu to the preference view. * * @author Patrice Bouillet, Alexander Wert * */ public final class MenuAction extends Action implements IMenuCreator { /** * The menu manager. */ private final MenuManager menuManager; /** * The task to execute when action is selected. */ private RunTask runTask; /** * Constructor. Creates a new menu. */ public MenuAction() { this(null, "", null); } /** * Constructor. Creates a new menu. * * @param text * The menu text. * @param image * The menu image. */ public MenuAction(String text, ImageDescriptor image) { this(null, text, image); } /** * Constructor. Creates a new menu. * * @param runnable * The task to execute when action is selected. If null, no task will be performed. */ public MenuAction(RunTask runnable) { this(runnable, "", null); } /** * Constructor. Creates a new menu. * * @param runnable * The task to execute when action is selected. If null, no task will be performed. * @param text * The menu text. * @param image * The menu image. */ public MenuAction(RunTask runnable, String text, ImageDescriptor image) { super("", Action.AS_DROP_DOWN_MENU); menuManager = new MenuManager(text, image, text); setText(text); if (null != image) { setImageDescriptor(image); } setRunTask(runnable); setMenuCreator(this); } /** * Adds a contribution item to this manager, like a sub-menu ... * * @param contributionItem * THe contribution item to add. */ public void addContributionItem(IContributionItem contributionItem) { menuManager.add(contributionItem); } /** * Adds an action to this manager. * * @param action * The action to add. */ public void addAction(IAction action) { menuManager.add(action); } /** * @see MenuManager#getSize() * @return the number of contributions in this manager. */ public int getSize() { return menuManager.getSize(); } /** * {@inheritDoc} */ @Override public Menu getMenu(Control parent) { return menuManager.createContextMenu(parent); } /** * {@inheritDoc} */ @Override public Menu getMenu(Menu parent) { Menu dropDownMenu = new Menu(parent.getParent(), SWT.DROP_DOWN); int i = 0; for (IContributionItem ci : menuManager.getItems()) { ci.fill(dropDownMenu, i); i++; } return dropDownMenu; } /** * {@inheritDoc} */ @Override public void dispose() { menuManager.dispose(); } /** * {@inheritDoc} */ @Override public void runWithEvent(Event event) { RunTask runTask = getRunTask(); if (null != runTask) { runTask.setEvent(event); if (runTask instanceof ToolbarDropDownTask) { ((ToolbarDropDownTask) runTask).setMenuAction(this); } Display.getDefault().syncExec(runTask); } } /** * Gets {@link #runTask}. * * @return {@link #runTask} */ public RunTask getRunTask() { return runTask; } /** * Sets {@link #runTask}. * * @param runTask * New value for {@link #runTask} */ public void setRunTask(RunTask runTask) { this.runTask = runTask; } /** * This is special {@link Runnable} that is aware of an {@link Event} that has triggered the * execution of the {@link Runnable}. * * @author Alexander Wert * */ public abstract static class RunTask implements Runnable { /** * Event that trigger the execution of this task. */ private Event event; /** * Gets {@link #event}. * * @return {@link #event} */ public Event getEvent() { return event; } /** * Sets {@link #event}. * * @param event * New value for {@link #event} */ public void setEvent(Event event) { this.event = event; } } /** * This is special {@link RunTask} that executes the drop down of the menu when the * {@link MenuAction} is selected in a {@link ToolBar}. * * @author Alexander Wert * */ public static class ToolbarDropDownTask extends RunTask { /** * {@link ToolBar} containing the corresponding {@link MenuAction} as an {@link ToolItem}. */ private final ToolBar toolbar; /** * {@link MenuAction} to execute this task for. */ private MenuAction menuAction; /** * Constructor. * * @param toolbar * {@link ToolBar} containing the corresponding {@link MenuAction} as an * {@link ToolItem}. */ public ToolbarDropDownTask(ToolBar toolbar) { this.toolbar = toolbar; } /** * {@inheritDoc} */ @Override public void run() { Menu menu = getMenuAction().getMenu(toolbar); if (menu != null && getEvent().widget instanceof ToolItem) { Rectangle rect = ((ToolItem) getEvent().widget).getBounds(); Point point = toolbar.toDisplay(rect.x, rect.y + toolbar.getBounds().height); menu.setLocation(point.x, point.y); menu.setVisible(true); } } /** * Gets {@link #menuAction}. * * @return {@link #menuAction} */ public MenuAction getMenuAction() { return menuAction; } /** * Sets {@link #menuAction}. * * @param menuAction * New value for {@link #menuAction} */ public void setMenuAction(MenuAction menuAction) { this.menuAction = menuAction; } } }