/******************************************************************************* * Copyright (c) 2010, 2016 SAP AG * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Stefan Seelmann - initial implementation posted to * http://www.eclipse.org/forums/index.php?t=msg&th=11863&start=2 *******************************************************************************/ package org.eclipse.linuxtools.changelog.ui.tests.utils; import static org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory.withMnemonic; import static org.hamcrest.core.AllOf.allOf; import static org.hamcrest.core.IsInstanceOf.instanceOf; import java.util.Arrays; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException; import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; import org.eclipse.swtbot.swt.finder.results.WidgetResult; import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot; import org.hamcrest.Matcher; public class ContextMenuHelper { /** * Clicks the context menu matching the text. * * @param bot * * @param texts * the text on the context menu. * @throws WidgetNotFoundException * if the widget is not found. * @throws SWTException * if the menu item is disabled (the root cause being an * {@link IllegalStateException}) */ public static void clickContextMenu(final AbstractSWTBot<?> bot, final String... texts) { // show final MenuItem menuItem = UIThreadRunnable .syncExec((WidgetResult<MenuItem>) () -> { MenuItem theItem = getMenuItem(bot, texts); if (theItem != null && !theItem.isEnabled()) throw new IllegalStateException("Menu item is diabled"); return theItem; }); if (menuItem == null) { throw new WidgetNotFoundException("Could not find menu: " + Arrays.asList(texts)); } // click click(menuItem); // hide UIThreadRunnable.syncExec(() -> { if (menuItem.isDisposed()) return; // menu already gone hide(menuItem.getParent()); }); } private static MenuItem getMenuItem(final AbstractSWTBot<?> bot, final String... texts) { MenuItem theItem = null; Control control = (Control) bot.widget; // for dynamic menus, we need to issue this event control.notifyListeners(SWT.MenuDetect, new Event()); Menu menu = control.getMenu(); for (String text : texts) { Matcher<MenuItem> matcher = allOf(instanceOf(MenuItem.class), withMnemonic(text)); theItem = show(menu, matcher); if (theItem != null) { menu = theItem.getMenu(); } else { hide(menu); break; } } return theItem; } private static MenuItem show(final Menu menu, final Matcher<MenuItem> matcher) { if (menu != null) { menu.notifyListeners(SWT.Show, new Event()); MenuItem[] items = menu.getItems(); for (final MenuItem menuItem : items) { if (matcher.matches(menuItem)) { return menuItem; } } menu.notifyListeners(SWT.Hide, new Event()); } return null; } private static void click(final MenuItem menuItem) { final Event event = new Event(); event.time = (int) System.currentTimeMillis(); event.widget = menuItem; event.display = menuItem.getDisplay(); event.type = SWT.Selection; UIThreadRunnable.asyncExec(menuItem.getDisplay(), () -> menuItem.notifyListeners(SWT.Selection, event)); } private static void hide(final Menu menu) { menu.notifyListeners(SWT.Hide, new Event()); if (menu.getParentMenu() != null) { hide(menu.getParentMenu()); } } }