blob: 1e78d7e8455940c07439fbb69ad9caf1dfc1ed1d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2017 http://www.inria.fr/ 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:
* http://www.inria.fr/ - initial API and implementation
* Cédric Chabanois - bug 269164
* Patrick Tasse - Improve SWTBot menu API and implementation (Bug 479091)
* - Add support for click(int) and doubleClick()
* Aparna Argade(Cadence Design Systems, Inc.) - Bug 496519
*******************************************************************************/
package org.eclipse.swtbot.swt.finder.widgets;
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.Event;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
import org.eclipse.swtbot.swt.finder.results.BoolResult;
import org.eclipse.swtbot.swt.finder.results.Result;
import org.eclipse.swtbot.swt.finder.results.StringResult;
import org.eclipse.swtbot.swt.finder.results.VoidResult;
import org.eclipse.swtbot.swt.finder.results.WidgetResult;
import org.eclipse.swtbot.swt.finder.utils.MessageFormat;
import org.eclipse.swtbot.swt.finder.utils.internal.Assert;
import org.hamcrest.SelfDescribing;
/**
* @author Vincent MAHE <vmahe [at] free [dot]fr>
* @author Cédric Chabanois
* @version $Id$
* @since 1.3
*/
public class SWTBotTableItem extends AbstractSWTBot<TableItem> {
private Table table;
/**
* @param tableItem the widget.
* @throws WidgetNotFoundException if the widget is <code>null</code> or widget has been disposed.
*/
public SWTBotTableItem(final TableItem tableItem) throws WidgetNotFoundException {
this(tableItem, null);
}
/**
* @param tableItem the widget.
* @param description the description of the widget, this will be reported by {@link #toString()}
* @throws WidgetNotFoundException if the widget is <code>null</code> or widget has been disposed.
*/
public SWTBotTableItem(final TableItem tableItem, SelfDescribing description) throws WidgetNotFoundException {
super(tableItem, description);
this.table = syncExec(new WidgetResult<Table>() {
public Table run() {
return tableItem.getParent();
}
});
}
/**
* Selects the current table item. Replaces the current selection.
*
* @return the current node.
*/
public SWTBotTableItem select() {
waitForEnabled();
syncExec(new VoidResult() {
public void run() {
table.setFocus();
table.setSelection(widget);
}
});
notifySelect();
return this;
}
/**
* Click on the table at given coordinates
*
* @param x the x co-ordinate of the click
* @param y the y co-ordinate of the click
*/
@Override
protected void clickXY(int x, int y) {
log.debug(MessageFormat.format("Clicking on {0}", this)); //$NON-NLS-1$
notifyTable(SWT.MouseEnter, createMouseEvent(x, y, 0, SWT.NONE, 0));
notifyTable(SWT.Activate, super.createEvent());
syncExec(new VoidResult() {
public void run() {
if (table.getSelectionCount() != 1 || !table.getSelection()[0].equals(widget)) {
table.setSelection(widget);
}
if (!table.isFocusControl()) {
table.setFocus();
}
}
});
notifyTable(SWT.FocusIn, super.createEvent());
notifyTable(SWT.MouseDown, createMouseEvent(x, y, 1, SWT.NONE, 1));
notifyTable(SWT.Selection);
notifyTable(SWT.MouseUp, createMouseEvent(x, y, 1, SWT.BUTTON1, 1));
notifyTable(SWT.MouseExit, createMouseEvent(x, y, 0, SWT.NONE, 0));
notifyTable(SWT.Deactivate, super.createEvent());
notifyTable(SWT.FocusOut, super.createEvent());
log.debug(MessageFormat.format("Clicked on {0}", this)); //$NON-NLS-1$
}
private void notifyTable(int eventType, Event event) {
notify(eventType, event, table);
}
private void notifyTable(int event) {
notifyTable(event, createEvent());
}
/**
* Clicks on this node.
*
* @return the current node.
*/
@Override
public SWTBotTableItem click() {
waitForEnabled();
Point center = getCenter(getBounds());
clickXY(center.x, center.y);
return this;
}
/**
* Clicks on this node at the given column index.
*
* @return the current node.
* @since 2.5
*/
public SWTBotTableItem click(final int column) {
waitForEnabled();
Point center = getCenter(getCellBounds(column));
clickXY(center.x, center.y);
return this;
}
/**
* Double clicks on this node.
*
* @return the current node.
* @since 2.5
*/
public SWTBotTableItem doubleClick() {
waitForEnabled();
log.debug(MessageFormat.format("Double-clicking on {0}", this)); //$NON-NLS-1$
notifyTable(SWT.MouseEnter, createMouseEvent(0, SWT.NONE, 0));
notifyTable(SWT.Activate, super.createEvent());
syncExec(new VoidResult() {
public void run() {
if (table.getSelectionCount() != 1 || !table.getSelection()[0].equals(widget)) {
table.setSelection(widget);
}
if (!table.isFocusControl()) {
table.setFocus();
}
}
});
notifyTable(SWT.FocusIn, super.createEvent());
notifyTable(SWT.MouseDown, createMouseEvent(1, SWT.NONE, 1));
notifyTable(SWT.Selection);
notifyTable(SWT.MouseUp, createMouseEvent(1, SWT.BUTTON1, 1));
notifyTable(SWT.MouseDown, createMouseEvent(1, SWT.NONE, 2));
notifyTable(SWT.Selection);
notifyTable(SWT.MouseDoubleClick, createMouseEvent(1, SWT.NONE, 2));
notifyTable(SWT.DefaultSelection);
notifyTable(SWT.MouseUp, createMouseEvent(1, SWT.BUTTON1, 2));
notifyTable(SWT.MouseExit, createMouseEvent(0, SWT.NONE, 0));
notifyTable(SWT.Deactivate, super.createEvent());
notifyTable(SWT.FocusOut, super.createEvent());
log.debug(MessageFormat.format("Double-clicked on {0}", this)); //$NON-NLS-1$
return this;
}
@Override
protected Control getDNDControl() {
return table;
}
@Override
protected void dragStart() {
syncExec(new VoidResult() {
public void run() {
table.setFocus();
table.setSelection(widget);
}
});
notifyTable(SWT.Activate);
notifyTable(SWT.FocusIn);
notifyTable(SWT.MouseDown, createMouseEvent(1, SWT.NONE, 1));
notifyTable(SWT.Selection, createSelectionEvent(SWT.BUTTON1));
}
@Override
protected Rectangle getBounds() {
return syncExec(new Result<Rectangle>() {
public Rectangle run() {
return widget.getBounds();
}
});
}
/**
* Get the cell bounds. widget should be enabled before calling this method.
*
* @param column the table column index
* @return the cell bounds
*/
private Rectangle getCellBounds(final int column) {
return syncExec(new Result<Rectangle>() {
public Rectangle run() {
return widget.getBounds(column);
}
});
}
/**
* Get the center of the given rectangle.
*
* @param bounds the rectangle
* @return the center.
*/
private Point getCenter(Rectangle bounds) {
return new Point(bounds.x + (bounds.width / 2), bounds.y + (bounds.height / 2));
}
@Override
public String getText() {
return syncExec(new StringResult() {
public String run() {
return widget.getText();
}
});
}
public String getText(final int index) {
return syncExec(new StringResult() {
public String run() {
return widget.getText(index);
}
});
}
@Override
public SWTBotRootMenu contextMenu() throws WidgetNotFoundException {
waitForEnabled();
select();
return contextMenu(table);
}
/**
* Toggle the table item.
*/
public void toggleCheck() {
setChecked(!isChecked());
}
/**
* Check the table item.
*/
public void check() {
setChecked(true);
}
/**
* Uncheck the table item.
*/
public void uncheck() {
setChecked(false);
}
/**
* Gets if the checkbox button is checked.
*
* @return <code>true</code> if the checkbox is checked. Otherwise <code>false</code>.
*/
public boolean isChecked() {
assertIsCheck();
return syncExec(new BoolResult() {
public Boolean run() {
return widget.getChecked();
}
});
}
/**
* Gets if the checkbox button is grayed.
*
* @return <code>true</code> if the checkbox is grayed, <code>false</code> otherwise.
*/
public boolean isGrayed() {
assertIsCheck();
return syncExec(new BoolResult() {
public Boolean run() {
return widget.getGrayed();
}
});
}
/**
* Creates an event for CheckboxTableItem case.
*
* @return an event that encapsulates {@link #widget} and {@link #display}.
*/
private Event createCheckEvent() {
Event event = createEvent();
event.detail = SWT.CHECK;
return event;
}
@Override
protected Event createEvent() {
Event event = super.createEvent();
event.widget = table;
event.item = widget;
return event;
}
private void setChecked(final boolean checked) {
waitForEnabled();
assertIsCheck();
syncExec(new VoidResult() {
public void run() {
TableItem item = widget;
log.debug(MessageFormat.format("Setting state to {0} on: {1}", (checked ? "checked" : "unchecked"), item.getText())); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
item.setChecked(checked);
}
});
notifyCheck();
}
private void assertIsCheck() {
Assert.isLegal(hasStyle(table, SWT.CHECK), "The table does not have the style SWT.CHECK"); //$NON-NLS-1$
}
/**
* notify listeners about checkbox state change.
*
* @since 1.3
*/
private void notifyCheck() {
syncExec(new VoidResult() {
public void run() {
table.notifyListeners(SWT.Selection, createCheckEvent());
}
});
}
private void notifySelect() {
notifyTable(SWT.MouseEnter);
notifyTable(SWT.MouseMove);
notifyTable(SWT.Activate);
notifyTable(SWT.FocusIn);
notifyTable(SWT.MouseDown, createMouseEvent(1, SWT.NONE, 1));
notifyTable(SWT.Selection, createSelectionEvent(SWT.BUTTON1));
notifyTable(SWT.MouseUp, createMouseEvent(1, SWT.BUTTON1, 1));
}
@Override
protected void waitForEnabled() {
new SWTBotTable(table).waitForEnabled();
}
@Override
protected Event createSelectionEvent(int stateMask) {
Event event = super.createSelectionEvent(stateMask);
event.item = widget;
return event;
}
@Override
public boolean isEnabled() {
return syncExec(new BoolResult() {
public Boolean run() {
return table.isEnabled();
}
});
}
@Override
protected Rectangle absoluteLocation() {
return syncExec(new Result<Rectangle>() {
public Rectangle run() {
return display.map(widget.getParent(), null, widget.getBounds());
}
});
}
}