/******************************************************************************* * Copyright (c) 2008, 2011 Obeo. * 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: * Obeo - initial API and implementation *******************************************************************************/ package org.eclipse.emf.eef.modelingBot.menu; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import org.eclipse.swt.SWT; 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.swt.widgets.Shell; import org.eclipse.swtbot.swt.finder.finders.ContextMenuFinder; import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; import org.eclipse.swtbot.swt.finder.results.ListResult; import org.hamcrest.Matcher; /** * A context menu finder, which stops to search when he found one result. * * @author <a href="mailto:nathalie.lepine@obeo.fr">Nathalie Lepine</a> */ public class FirstContextMenuFinder extends ContextMenuFinder { /** * Constructs the context menu finder for the given control to be searched. * * @param control * the control that has a context menu. */ public FirstContextMenuFinder(Control control) { super(control); } /** * Finds all the menus using the given matcher in the set of shells * provided. If recursive is set, it will attempt to find the controls * recursively in each of the menus it that is found. * * @param shells * the shells to probe for menus. * @param matcher * the matcher that can match menus and menu items. * @param recursive * if set to true, will find sub-menus as well. * @return all menus in the specified shells that match the matcher. */ public List<MenuItem> findMenus(Shell[] shells, Matcher<MenuItem> matcher, boolean recursive) { LinkedHashSet<MenuItem> result = new LinkedHashSet<MenuItem>(); for (Shell shell : shells) { result.addAll(findMenus(shell, matcher, recursive)); if (!result.isEmpty()) break; } return new ArrayList<MenuItem>(result); } /** * {@inheritDoc} * * @see org.eclipse.swtbot.swt.finder.finders.MenuFinder#findMenus(org.eclipse.swt.widgets.Menu, * org.hamcrest.Matcher, boolean) */ public List<MenuItem> findMenus(final Menu bar, final Matcher<MenuItem> matcher, final boolean recursive) { return UIThreadRunnable.syncExec(display, new ListResult<MenuItem>() { public List<MenuItem> run() { return findMenuInternal(bar, matcher, recursive); } }); } /** * @param bar * @param matcher * @param recursive * @return */ private List<MenuItem> findMenuInternal(final Menu bar, final Matcher<MenuItem> matcher, final boolean recursive) { LinkedHashSet<MenuItem> result = new LinkedHashSet<MenuItem>(); if (bar != null) { bar.notifyListeners(SWT.Show, new Event()); MenuItem[] items = bar.getItems(); for (MenuItem menuItem : items) { if (isSeparator(menuItem)) { continue; } if (matcher.matches(menuItem)) { result.add(menuItem); /* we found one, do not continue */ break; } if (recursive) { result.addAll(findMenuInternal(menuItem.getMenu(), matcher, recursive)); if (!result.isEmpty()) break; } } bar.notifyListeners(SWT.Hide, new Event()); } return new ArrayList<MenuItem>(result); } private boolean isSeparator(MenuItem menuItem) { return (menuItem.getStyle() & SWT.SEPARATOR) != 0; } }