blob: fa573b853f051d1be7c807664934f7e7517bb728 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008-2009 Ketan Padegaonkar and others.
* 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:
* Ketan Padegaonkar - initial API and implementation
*******************************************************************************/
package org.eclipse.swtbot.eclipse.finder.widgets;
import static org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory.withMnemonic;
import static org.hamcrest.Matchers.any;
import static org.hamcrest.Matchers.anything;
import static org.hamcrest.Matchers.equalTo;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.finders.CommandFinder;
import org.eclipse.swtbot.eclipse.finder.finders.ViewMenuFinder;
import org.eclipse.swtbot.eclipse.finder.widgets.utils.PartLabelDescription;
import org.eclipse.swtbot.swt.finder.SWTBot;
import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
import org.eclipse.swtbot.swt.finder.finders.Finder;
import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
import org.eclipse.swtbot.swt.finder.results.ListResult;
import org.eclipse.swtbot.swt.finder.results.VoidResult;
import org.eclipse.swtbot.swt.finder.utils.MessageFormat;
import org.eclipse.swtbot.swt.finder.utils.SWTUtils;
import org.eclipse.swtbot.swt.finder.utils.internal.Assert;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarButton;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarDropDownButton;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarPushButton;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarRadioButton;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarSeparatorButton;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarToggleButton;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.internal.PartPane;
import org.eclipse.ui.internal.WorkbenchPartReference;
import org.hamcrest.Matcher;
import org.hamcrest.SelfDescribing;
/**
* This represents the eclipse {@link IWorkbenchPartReference} item, subclasses must extend this to implement support
* for various {@link IWorkbenchPartReference}s.
*
* @author Ketan Padegaonkar <KetanPadegaonkar [at] gmail [dot] com>
* @author Ralf Ebert www.ralfebert.de (bug 271630)
* @version $Id$
* @since 2.0
*/
public abstract class SWTBotWorkbenchPart<T extends IWorkbenchPartReference> {
/** The IWorkbenchPartReference reference that this part encapsulates. */
protected final T partReference;
/** The logger. */
protected final Logger log;
/** A helper swtbot instance. */
protected final SWTWorkbenchBot bot;
private final ViewMenuFinder menuFinder;
private final SelfDescribing description;
private Widget widget;
/**
* Creates an instance of a workbench part.
*
* @param partReference the part reference.
* @param bot the helper bot.
*/
public SWTBotWorkbenchPart(T partReference, SWTWorkbenchBot bot) {
this(partReference, bot, new PartLabelDescription<T>(partReference));
}
/**
* Creates an instance of a workbench part.
*
* @param partReference the part reference.
* @param bot the helper bot.
* @param description the description of the workbench part.
*/
public SWTBotWorkbenchPart(T partReference, SWTWorkbenchBot bot, SelfDescribing description) {
this.bot = bot;
if (description == null )
description = new PartLabelDescription<T>(partReference);
this.description = description;
Assert.isNotNull(partReference, "The part reference cannot be null"); //$NON-NLS-1$
this.partReference = partReference;
this.menuFinder = new ViewMenuFinder();
log = Logger.getLogger(getClass());
}
/**
* @return the reference for this part.
*/
public T getReference() {
return partReference;
}
/**
* Close the partReference.
*/
public void close() {
UIThreadRunnable.syncExec(new VoidResult() {
public void run() {
IViewReference viewReference = (IViewReference) partReference;
viewReference.getPage().hideView(viewReference);
}
});
}
/**
* Shows the part if it is visible.
*/
public void show() {
UIThreadRunnable.syncExec(new VoidResult() {
public void run() {
try {
partReference.getPage().activate(partReference.getPart(true));
partReference.getPage().showView(partReference.getId());
} catch (PartInitException e) {
throw new RuntimeException("Could not show partReference - " + partReference.getPartName(), e); //$NON-NLS-1$
}
}
});
}
/**
* Gets the title of the partReference.
*
* @return the title of the part as visible in the tab
*/
public String getTitle() {
return partReference.getPartName();
}
/**
* Gets a list of all menus within the partReference. This will also include sub menus.
*
* @return The list of menus
*/
public List<SWTBotViewMenu> menus() {
return menuFinder.findMenus((IViewReference) partReference, anything(), true);
}
/**
* Gets a menu item matching the give label within the partReference menu if one exists.
*
* @param label The label matching name in the menu.
* @return The {@link SWTBotMenu} item.
* @throws WidgetNotFoundException Thrown if the menu can not be found or if the partReference does not contain a
* menu.
*/
public SWTBotViewMenu menu(String label) throws WidgetNotFoundException {
return menu(label, 0);
}
/**
* Gets a menu item matching the give label within the partReference menu if one exists.
*
* @param label The label matching name in the menu.
* @param index The index of the menu to choose.
* @return The {@link SWTBotMenu} item.
* @throws WidgetNotFoundException Thrown if the menu can not be found or if the partReference does not contain a
* menu.
*/
public SWTBotViewMenu menu(String label, int index) throws WidgetNotFoundException {
try {
List<SWTBotViewMenu> menuItems = menuFinder.findMenus((IViewReference) partReference, withMnemonic(label), true);
if ((menuItems == null) || (menuItems.size() < 1)) {
CommandFinder finder = new CommandFinder();
List<SWTBotCommand> command = finder.findCommand(equalTo(label));
return command.get(index);
}
return menuItems.get(index);
} catch (Exception e) {
throw new WidgetNotFoundException("Could not find view menu with label " + label + " at index " + index, e); //$NON-NLS-1$ //$NON-NLS-2$
}
}
/**
* Gets the toolbar buttons currently visible.
*
* @return The set of toolbar buttons.
*/
public List<SWTBotToolbarButton> getToolbarButtons() {
return UIThreadRunnable.syncExec(new ListResult<SWTBotToolbarButton>() {
public List<SWTBotToolbarButton> run() {
PartPane obj = ((WorkbenchPartReference) partReference).getPane();
ToolBar toolbar = (ToolBar) obj.getToolBar();
final List<SWTBotToolbarButton> l = new ArrayList<SWTBotToolbarButton>();
if (toolbar == null)
return l;
ToolItem[] items = toolbar.getItems();
log.debug("number of items : " + items.length);
for (int i = 0; i < items.length; i++) {
try {
if (SWTUtils.hasStyle(items[i], SWT.PUSH))
l.add(new SWTBotToolbarPushButton(items[i]));
else if(SWTUtils.hasStyle(items[i], SWT.CHECK))
l.add(new SWTBotToolbarToggleButton(items[i]));
else if(SWTUtils.hasStyle(items[i], SWT.RADIO))
l.add(new SWTBotToolbarRadioButton(items[i]));
else if(SWTUtils.hasStyle(items[i], SWT.DROP_DOWN))
l.add(new SWTBotToolbarDropDownButton(items[i]));
else if(SWTUtils.hasStyle(items[i], SWT.SEPARATOR))
l.add(new SWTBotToolbarSeparatorButton(items[i]));
} catch (WidgetNotFoundException e) {
log.warn("Failed to find widget " + items[i].getText(), e); //$NON-NLS-1$
}
}
return l;
}
});
}
/**
* Gets the toolbar drop down button matching the given toolbar button.
*
* @param tooltip The tooltip to use to find the button to return.
* @return The toolbar button.
* @throws WidgetNotFoundException Thrown if the widget was not found matching the given tooltip.
*/
public SWTBotToolbarDropDownButton toolbarDropDownButton(String tooltip) throws WidgetNotFoundException {
SWTBotToolbarButton abstractButton = toolbarButton(tooltip);
if (abstractButton instanceof SWTBotToolbarDropDownButton)
return (SWTBotToolbarDropDownButton) abstractButton;
throw new WidgetNotFoundException("Unable to find toolitem with the given tooltip '" + tooltip + "'"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Gets the toolbar radio button matching the given toolbar button.
*
* @param tooltip The tooltip to use to find the button to return.
* @return The toolbar button.
* @throws WidgetNotFoundException Thrown if the widget was not found matching the given tooltip.
*/
public SWTBotToolbarRadioButton toolbarRadioButton(String tooltip) throws WidgetNotFoundException {
SWTBotToolbarButton abstractButton = toolbarButton(tooltip);
if (abstractButton instanceof SWTBotToolbarRadioButton)
return (SWTBotToolbarRadioButton) abstractButton;
throw new WidgetNotFoundException("Unable to find toolitem with the given tooltip '" + tooltip + "'"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Gets the toolbar push button matching the given toolbar button.
*
* @param tooltip The tooltip to use to find the button to return.
* @return The toolbar button.
* @throws WidgetNotFoundException Thrown if the widget was not found matching the given tooltip.
*/
public SWTBotToolbarPushButton toolbarPushButton(String tooltip) throws WidgetNotFoundException {
SWTBotToolbarButton abstractButton = toolbarButton(tooltip);
if (abstractButton instanceof SWTBotToolbarPushButton)
return (SWTBotToolbarPushButton) abstractButton;
throw new WidgetNotFoundException("Unable to find toolitem with the given tooltip '" + tooltip + "'"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Gets the toggle toolbar button matching the given toolbar button.
*
* @param tooltip The tooltip to use to find the button to return.
* @return The toolbar button.
* @throws WidgetNotFoundException Thrown if the widget was not found matching the given tooltip.
*/
public SWTBotToolbarToggleButton toolbarToggleButton(String tooltip) throws WidgetNotFoundException {
SWTBotToolbarButton abstractButton = toolbarButton(tooltip);
if (abstractButton instanceof SWTBotToolbarToggleButton)
return (SWTBotToolbarToggleButton) abstractButton;
throw new WidgetNotFoundException("Unable to find toolitem with the given tooltip '" + tooltip + "'"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Gets the toolbar button matching the given toolbar button.
*
* @param tooltip The tooltip to use to find the button to return.
* @return The toolbar button.
* @throws WidgetNotFoundException Thrown if the widget was not found matching the given tooltip.
*/
public SWTBotToolbarButton toolbarButton(String tooltip) throws WidgetNotFoundException {
List<SWTBotToolbarButton> l = getToolbarButtons();
for (int i = 0; i < l.size(); i++) {
SWTBotToolbarButton item = l.get(i);
if (item.getToolTipText().equals(tooltip)) {
return item;
}
}
throw new WidgetNotFoundException("Unable to find toolitem with the given tooltip '" + tooltip + "'"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* @param matcher a matcher.
* @return a widget within the parent widget that matches the specified matcher.
*/
protected <S extends Widget> S findWidget(Matcher<S> matcher) {
return findWidgets(matcher).get(0);
}
/**
* @param matcher a matcher.
* @return a widget within the parent widget that matches the specified matcher.
*/
protected <S extends Widget> List<? extends S> findWidgets(Matcher<S> matcher) {
Finder finder = bot.getFinder();
Control control = getControl();
boolean shouldFindInvisibleControls = finder.shouldFindInvisibleControls();
finder.setShouldFindInvisibleControls(true);
try {
return bot.widgets(matcher, control);
} catch (Exception e) {
throw new WidgetNotFoundException("Could not find any control inside the view " + partReference.getPartName(), e); //$NON-NLS-1$
} finally {
finder.setShouldFindInvisibleControls(shouldFindInvisibleControls);
}
}
/**
* Returns the workbench pane control.
*
* @return returns the workbench pane control.
*/
private Control getControl() {
return ((WorkbenchPartReference) partReference).getPane().getControl();
}
/**
* Returns a SWTBot instance that matches the contents of this workbench part.
*
* @return SWTBot
*/
public SWTBot bot() {
return new SWTBot(getControl());
}
/**
* Asserts that the viewpart is active.
*
*/
protected void assertActive() {
Assert.isLegal(isActive(), MessageFormat.format("The workbench part {0}is not active", description));
}
/**
* @return <code>true</code> if the part is currently active.
*/
public abstract boolean isActive();
/**
* Sets focus on the current part.
*/
public abstract void setFocus();
/**
* The parent widget inside the partReference. If you want to look for a particular widget within the part, this is
* a good place to start searching for the widget.
* <p>
* <b>NOTE:</b> Clients must ensure that the part is active at the time of making this call. If the part is not
* active, then this method will throw a {@link WidgetNotFoundException}.
* </p>
*
* @return the parent widget in the part.
* @see #findWidget(org.hamcrest.Matcher)
* @see #assertActive()
* @see #show()
*/
public Widget getWidget() {
show();
if (widget == null)
widget = findWidget(any(Widget.class));
return widget;
}
}