package abbot.tester.swt; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Display; import com.windowtester.internal.runtime.provisional.WTInternal; import com.windowtester.runtime.WT; import com.windowtester.runtime.swt.internal.operation.SWTControlLocation; import com.windowtester.runtime.swt.internal.operation.SWTMouseOperation; import abbot.Log; import abbot.script.Condition; /** * Provides widget-specific actions, assertions, and getter methods for * widgets of type Combo. */ public class ComboTester extends CompositeTester { public static final String copyright = "Licensed Materials -- Property of IBM\n"+ "(c) Copyright International Business Machines Corporation, 2003\nUS Government "+ "Users Restricted Rights - Use, duplication or disclosure restricted by GSA "+ "ADP Schedule Contract with IBM Corp."; /* Begin getters */ /** * Proxy for {@link Combo#getItemCount()}. * <p/> * @param combo the combo under test. * @return the number of items. */ public int getItemCount(final Combo combo) { Integer result = (Integer) Robot.syncExec(combo.getDisplay(), new RunnableWithResult() { public Object runWithResult() { return new Integer(combo.getItemCount()); } }); return result.intValue(); } /** * Proxy for {@link Combo#getItemHeight()}. * <p/> * @param combo the combo under test. * @return the height of one item. */ public int getItemHeight(final Combo combo) { Integer result = (Integer) Robot.syncExec(combo.getDisplay(), new RunnableWithResult() { public Object runWithResult() { return new Integer(combo.getItemHeight()); } }); return result.intValue(); } /** * Proxy for {@link Combo#getItems()}. * <p/> * @param combo the combo under test. * @return the items in the combo's list. */ public String[] getItems(final Combo combo) { String[] result = (String[]) Robot.syncExec(combo.getDisplay(), new RunnableWithResult() { public Object runWithResult() { return combo.getItems(); } }); return result; } /** * Proxy for {@link Combo#getSelection()}. * <p/> * @param combo the combo under test. * @return a point representing the selection start and end. */ public Point getSelection(final Combo combo) { Point result = (Point) Robot.syncExec(combo.getDisplay(), new RunnableWithResult() { public Object runWithResult() { return combo.getSelection(); } }); return result; } /** * Proxy for {@link Combo#getSelectionIndex()}. * <p/> * @param combo the combo under test. * @return the selected index. */ public int getSelectionIndex(final Combo combo) { Integer result = (Integer) Robot.syncExec(combo.getDisplay(), new RunnableWithResult() { public Object runWithResult() { return new Integer(combo.getSelectionIndex()); } }); return result.intValue(); } /** * Proxy for {@link Combo#getText()}. * <p/> * @param combo the combo under test. * @return the contents of the text field. */ public String getText(final Combo combo) { String result = (String) Robot.syncExec(combo.getDisplay(), new RunnableWithResult() { public Object runWithResult() { return combo.getText(); } }); return result; } /** * Proxy for {@link Combo#getTextHeight()}. * <p/> * @param combo the combo under test. * @return the text height. */ public int getTextHeight(final Combo combo) { Integer result = (Integer) Robot.syncExec(combo.getDisplay(), new RunnableWithResult() { public Object runWithResult() { return new Integer(combo.getTextHeight()); } }); return result.intValue(); } /** * Proxy for {@link Combo#getTextLimit()}. * <p/> * @param combo the combo under test. * @return the text limit. */ public int getTextLimit(final Combo combo) { Integer result = (Integer) Robot.syncExec(combo.getDisplay(), new RunnableWithResult() { public Object runWithResult() { return new Integer(combo.getTextLimit()); } }); return result.intValue(); } /* End getters */ /** * Drop down the menu for the given Combo box * WARNING: This method is platform-dependent. */ protected void dropDownCombo(Combo combo){ // int style = getStyle(combo); // final int BUTTON_SIZE = 16; // if((style&SWT.DROP_DOWN)==SWT.DROP_DOWN){ // Rectangle bounds = getGlobalBounds(combo); // int x = bounds.x+bounds.width-BUTTON_SIZE/2; // int y = bounds.y+bounds.height-BUTTON_SIZE/2; // //!pq: event posting fixes // //mouseMove( bounds.x+bounds.width-BUTTON_SIZE/2, // // bounds.y+bounds.height-BUTTON_SIZE/2); // mouseMove2(x, y); // //mousePress(SWT.BUTTON1); // //mouseRelease(SWT.BUTTON1); // mousePress2(SWT.BUTTON1); // //mouseRelease2(SWT.BUTTON1); <-- this doesn't seem right... new SWTMouseOperation(WT.BUTTON1).at(new SWTControlLocation(combo, WTInternal.RIGHT).offset(-8, 0)).execute(); actionWaitForIdle(combo.getDisplay()); // } } /** Move the mouse pointer over the item with the given index **/ public void mouseMoveIndex(Combo combo, int index){ int style = getStyle(combo); if((style&SWT.DROP_DOWN)==SWT.DROP_DOWN){ // TODO Add code to scroll down and move the mouse pointer; // may not be possible b/c combo.getVerticalBar() returns null even when the // bar on the drop-down is visible } else{// SWT.SIMPLE // TODO Add code to scroll so item is visible and move // pointer over item } } /** * Select the item from the Combo at the given index. * * @param combo Combo from which to select * @param index Index of item to select */ public void actionSelectIndex(final Combo combo, final int index){ actionFocus(combo); Display display = combo.getDisplay(); int current = getSelectionIndex(combo); dropDownCombo(combo); while (current != index) { if (current < index) { //!pq: keyClick fix // actionKeyPress(SWT.ARROW_DOWN,display); // actionKeyRelease(SWT.ARROW_DOWN,display); keyClick(SWT.ARROW_DOWN); waitForIdle(display); current++; } else { //!pq: keyClick fix //actionKeyPress(SWT.ARROW_UP,display); //actionKeyRelease(SWT.ARROW_UP,display); keyClick(SWT.ARROW_UP); waitForIdle(display); current--; } } //!pq: keyClick fix //actionKeyChar(SWT.CR,display); keyClick(SWT.CR); actionWaitForIdle(display); int selected = getSelectionIndex(combo); if (selected != index) { String msg = "Was not able to select the correct index for Combo:"+selected+"!="+index; throw new AssertionError(msg); } } /** * Select the given item from the Combo. * * @param combo Combo from which to select * @param item String to select */ public void actionSelectItem(final Combo combo, String item){ String [] items = getItems(combo); boolean found = false; for (int i = 0; i < items.length; i++){ if(item.equals(items[i])){ found = true; actionSelectIndex(combo,i); break; } } if (!found) { /* @todo: i think we should REALLY throw a WidgetNotFound exception, here, * but that would require an api change, and i think that should be part of * a change that tries to standardize on that, i.e. in TreeItemTester, and MenuItemTester. * And the signature should, also, throw a MultipleWidgetsFoundException. */ Log.debug("actionSelectItem: item \""+item+"\" not found"); } } /** * Returns the item at the given index. * * @param combo Combo from which to obtain the item * @param index Index of the item * @return the item at the given index, or null if index is out-of-bounds */ public String getItem(final Combo combo, final int index){ String result = (String) Robot.syncExec(combo.getDisplay(), new RunnableWithResult() { public Object runWithResult() { return combo.getItem(index); } }); return result; } /** * Indicates if the given index is the index of the currently selected item. * * @param combo Combo to check * @param index Index of the item to check * @return whether the item at the given index is selected */ public boolean assertIndexSelected(final Combo combo, int index){ /* @todo: this might be better served as a Condition */ int selected = getSelectionIndex(combo); return selected == index; } /** * Indicates if the given item is currently selected. * * @param combo Combo to check * @param item Item to check * @return whether the given item is selected */ public boolean assertItemSelected(final Combo combo, String item){ /* @todo: this might be better served as a Condition */ int selected = getSelectionIndex(combo); if (selected < 0) { Log.debug("No item was selected while trying to assert "+item+" was selected."); return false; } String selectedItem = getItem(combo,selected); return item.equals(selectedItem); } /** * Proxy for {@link Combo#setText(String)}. */ public void setText(final Combo combo, final String text) { actionFocus(combo); Robot.syncExec(combo.getDisplay(),null,new Runnable(){ public void run(){ combo.setText(text); } }); Robot.wait(new Condition() { public boolean test() { return text.equals(getText(combo)); } //@Override public String toString() { return "Combo to have text set to " + text; } }); } }