Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 223499 Details for
Bug 394179
Enhancement: Refactoring and generalization of the RC Swing and SWT
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
generalized implementation of Buttons,Trees, Tables and Menus
generalized_Swing_SWT_rc.patch (text/plain), 417.09 KB, created by
Marvin Mueller
on 2012-11-13 08:25:06 EST
(
hide
)
Description:
generalized implementation of Buttons,Trees, Tables and Menus
Filename:
MIME Type:
Creator:
Marvin Mueller
Created:
2012-11-13 08:25:06 EST
Size:
417.09 KB
patch
obsolete
>From e660fcb2b2312965f4641b4955ef83b9a1bedcbb Mon Sep 17 00:00:00 2001 >From: Marvin Mueller <marvin.mueller@bredex.de> >Date: Fri, 13 Jul 2012 09:59:45 +0200 >Subject: [PATCH] Generalized the SWT and SWING Toolkit support (buttons, > menus, trees and tables) > >--- > org.eclipse.jubula.rc.common/META-INF/MANIFEST.MF | 3 + > .../jubula/rc/common/caps/AbstractButtonCAPs.java | 83 ++ > .../jubula/rc/common/caps/AbstractMenuCAPs.java | 584 ++++++++++ > .../jubula/rc/common/caps/AbstractTableCAPs.java | 1196 ++++++++++++++++++++ > .../rc/common/caps/AbstractTextInputSupport.java | 53 + > .../rc/common/caps/AbstractTextVerifiable.java | 43 + > .../jubula/rc/common/caps/AbstractTreeCAPs.java | 754 ++++++++++++ > .../jubula/rc/common/caps/AbstractUICAPs.java | 78 ++ > .../jubula/rc/common/caps/AbstractWidgetCAPs.java | 486 ++++++++ > .../jubula/rc/common/driver/DragAndDropHelper.java | 18 + > .../factory/GUIAdapterFactoryRegistry.java | 99 ++ > .../uiadapter/factory/IUIAdapterFactory.java | 36 + > .../uiadapter/interfaces/IButtonAdapter.java | 41 + > .../uiadapter/interfaces/IComponentAdapter.java | 26 + > .../common/uiadapter/interfaces/IMenuAdapter.java | 35 + > .../uiadapter/interfaces/IMenuItemAdapter.java | 80 ++ > .../common/uiadapter/interfaces/ITableAdapter.java | 128 +++ > .../common/uiadapter/interfaces/ITreeAdapter.java | 41 + > .../uiadapter/interfaces/IWidgetAdapter.java | 110 ++ > .../eclipse/jubula/rc/swing/SwingAUTServer.java | 7 + > .../rc/swing/swing/caps/AbstractButtonCAPs.java | 60 + > .../jubula/rc/swing/swing/caps/CapUtil.java | 243 ++++ > .../jubula/rc/swing/swing/caps/JMenuBarCAPs.java | 207 ++++ > .../jubula/rc/swing/swing/caps/JTableCAPs.java | 213 ++++ > .../jubula/rc/swing/swing/caps/JTreeCAPs.java | 194 ++++ > .../swing/uiadapter/AbstractButtonAdapter.java | 103 ++ > .../rc/swing/swing/uiadapter/JMenuAdapter.java | 90 ++ > .../rc/swing/swing/uiadapter/JMenuBarAdapter.java | 73 ++ > .../rc/swing/swing/uiadapter/JMenuItemAdapter.java | 240 ++++ > .../swing/swing/uiadapter/JPopupMenuAdapter.java | 67 ++ > .../rc/swing/swing/uiadapter/JTableAdapter.java | 377 ++++++ > .../rc/swing/swing/uiadapter/JTreeAdapter.java | 65 ++ > .../rc/swing/swing/uiadapter/WidgetAdapter.java | 334 ++++++ > .../uiadapter/factory/SwingAdapterFactory.java | 92 ++ > .../org/eclipse/jubula/rc/swt/SwtAUTServer.java | 10 +- > .../org/eclipse/jubula/rc/swt/caps/ButtonCAPs.java | 52 + > .../org/eclipse/jubula/rc/swt/caps/CAPUtil.java | 108 ++ > .../org/eclipse/jubula/rc/swt/caps/MenuCAPs.java | 328 ++++++ > .../org/eclipse/jubula/rc/swt/caps/TableCAPs.java | 737 ++++++++++++ > .../org/eclipse/jubula/rc/swt/caps/TreeCAPs.java | 927 +++++++++++++++ > .../jubula/rc/swt/uiadapter/ButtonAdapter.java | 70 ++ > .../jubula/rc/swt/uiadapter/MenuAdapter.java | 121 ++ > .../jubula/rc/swt/uiadapter/MenuItemAdapter.java | 548 +++++++++ > .../jubula/rc/swt/uiadapter/TableAdapter.java | 526 +++++++++ > .../jubula/rc/swt/uiadapter/TreeAdapter.java | 66 ++ > .../jubula/rc/swt/uiadapter/WidgetAdapter.java | 427 +++++++ > .../swt/uiadapter/factory/SWTAdapterFactory.java | 67 ++ > .../resources/xml/ComponentConfiguration.xml | 10 +- > .../resources/xml/ComponentConfiguration.xml | 10 +- > 49 files changed, 10255 insertions(+), 11 deletions(-) > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractButtonCAPs.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractMenuCAPs.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTableCAPs.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTextInputSupport.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTextVerifiable.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTreeCAPs.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractUICAPs.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractWidgetCAPs.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/factory/GUIAdapterFactoryRegistry.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/factory/IUIAdapterFactory.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IButtonAdapter.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IComponentAdapter.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IMenuAdapter.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IMenuItemAdapter.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/ITableAdapter.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/ITreeAdapter.java > create mode 100644 org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IWidgetAdapter.java > create mode 100644 org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/AbstractButtonCAPs.java > create mode 100644 org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/CapUtil.java > create mode 100644 org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/JMenuBarCAPs.java > create mode 100644 org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/JTableCAPs.java > create mode 100644 org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/JTreeCAPs.java > create mode 100644 org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/AbstractButtonAdapter.java > create mode 100644 org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JMenuAdapter.java > create mode 100644 org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JMenuBarAdapter.java > create mode 100644 org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JMenuItemAdapter.java > create mode 100644 org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JPopupMenuAdapter.java > create mode 100644 org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JTableAdapter.java > create mode 100644 org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JTreeAdapter.java > create mode 100644 org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/WidgetAdapter.java > create mode 100644 org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/factory/SwingAdapterFactory.java > create mode 100644 org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/ButtonCAPs.java > create mode 100644 org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/CAPUtil.java > create mode 100644 org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/MenuCAPs.java > create mode 100644 org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/TableCAPs.java > create mode 100644 org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/TreeCAPs.java > create mode 100644 org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/ButtonAdapter.java > create mode 100644 org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/MenuAdapter.java > create mode 100644 org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/MenuItemAdapter.java > create mode 100644 org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/TableAdapter.java > create mode 100644 org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/TreeAdapter.java > create mode 100644 org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/WidgetAdapter.java > create mode 100644 org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/factory/SWTAdapterFactory.java > >diff --git a/org.eclipse.jubula.rc.common/META-INF/MANIFEST.MF b/org.eclipse.jubula.rc.common/META-INF/MANIFEST.MF >index 8c481b0..4d88ec2 100644 >--- a/org.eclipse.jubula.rc.common/META-INF/MANIFEST.MF >+++ b/org.eclipse.jubula.rc.common/META-INF/MANIFEST.MF >@@ -7,6 +7,7 @@ Bundle-Vendor: Eclipse Jubula > Export-Package: org.eclipse.jubula.rc.common, > org.eclipse.jubula.rc.common.adaptable, > org.eclipse.jubula.rc.common.businessprocess, >+ org.eclipse.jubula.rc.common.caps, > org.eclipse.jubula.rc.common.classloader, > org.eclipse.jubula.rc.common.commands, > org.eclipse.jubula.rc.common.components, >@@ -18,6 +19,8 @@ Export-Package: org.eclipse.jubula.rc.common, > org.eclipse.jubula.rc.common.listener, > org.eclipse.jubula.rc.common.logger, > org.eclipse.jubula.rc.common.registration, >+ org.eclipse.jubula.rc.common.uiadapter.factory, >+ org.eclipse.jubula.rc.common.uiadapter.interfaces, > org.eclipse.jubula.rc.common.util > Require-Bundle: org.apache.commons.beanutils;bundle-version="[1.7.0,2.0.0)", > org.apache.commons.lang;bundle-version="[2.4.0,3.0.0)", >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractButtonCAPs.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractButtonCAPs.java >new file mode 100644 >index 0000000..2486836 >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractButtonCAPs.java >@@ -0,0 +1,83 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.caps; >+ >+import org.eclipse.jubula.rc.common.implclasses.MatchUtil; >+import org.eclipse.jubula.rc.common.implclasses.Verifier; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IButtonAdapter; >+ >+ >+/** >+ * Implementation for all Button like classes, it holds the >+ * general methods for the testing of buttons. >+ * >+ * @author BREDEX GmbH >+ * >+ */ >+public abstract class AbstractButtonCAPs extends AbstractWidgetCAPs { >+ >+ /** >+ * Action to read the value of a JButton to store it in a variable in the >+ * Client >+ * >+ * @param variable the name of the variable >+ * @return the text value. >+ */ >+ public String gdReadValue(String variable) { >+ return ((IButtonAdapter) this.getComponent()).getText(); >+ } >+ /** >+ * >+ * @return the IButtonAdapter for the component. >+ */ >+ private IButtonAdapter getButtonAdapter() { >+ return (IButtonAdapter)getComponent(); >+ } >+ >+ /** >+ * Verifies the selected property. >+ * >+ * @param selected The selected property value to verify. >+ */ >+ public void gdVerifySelected(boolean selected) { >+ >+ Verifier.equals(selected, getButtonAdapter().isSelected()); >+ } >+ >+ /** >+ * Verifies the passed text. >+ * >+ * @param text The text to verify >+ * @param operator The RegEx operator used to verify >+ */ >+ public void gdVerifyText(String text, String operator) { >+ verifyText(text, operator); >+ } >+ >+ /** >+ * Verifies the passed text. >+ * >+ * @param text The text to verify >+ */ >+ public void gdVerifyText(String text) { >+ gdVerifyText(text, MatchUtil.DEFAULT_OPERATOR); >+ } >+ /** >+ * Verifies the passed text. >+ * @param text The text to verify >+ * @param operator The operator used to verify >+ */ >+ public void verifyText(String text, String operator) { >+ String value = getButtonAdapter().getText(); >+ Verifier.match(value, text, operator); >+ } >+ >+} >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractMenuCAPs.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractMenuCAPs.java >new file mode 100644 >index 0000000..43d9ef0 >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractMenuCAPs.java >@@ -0,0 +1,584 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.caps; >+ >+import java.util.ArrayList; >+import java.util.List; >+ >+import org.eclipse.jubula.rc.common.driver.ClickOptions; >+import org.eclipse.jubula.rc.common.driver.RobotTiming; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.implclasses.MatchUtil; >+import org.eclipse.jubula.rc.common.implclasses.MenuUtilBase; >+import org.eclipse.jubula.rc.common.implclasses.Verifier; >+import org.eclipse.jubula.rc.common.logger.AutServerLogger; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuAdapter; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuItemAdapter; >+import org.eclipse.jubula.tools.i18n.I18n; >+import org.eclipse.jubula.tools.objects.event.EventFactory; >+import org.eclipse.jubula.tools.objects.event.TestErrorEvent; >+import org.eclipse.jubula.tools.utils.TimeUtil; >+ >+/** >+ * General implementation for Menus. Also used for context menus >+ * if they behave the same. >+ * >+ * @author BREDEX GmbH >+ * >+ */ >+public abstract class AbstractMenuCAPs extends AbstractUICAPs { >+ >+ /** the logger */ >+ private static AutServerLogger log = new AutServerLogger( >+ AbstractMenuCAPs.class); >+ >+ /** >+ * @return the log >+ */ >+ public static AutServerLogger getLog() { >+ return log; >+ } >+ >+ /** >+ * This method gets the object which should implementet the menu Interface. >+ * It is saved as Component so it must be casted. >+ * @return the MenuAdapter >+ */ >+ public IMenuAdapter getMenuAdapter() { >+ return (IMenuAdapter) getComponent(); >+ } >+ /** >+ * Checks if the specified menu item is enabled. >+ * >+ * @param menuItem the menu item as a text path to verify against >+ * @param operator operator used for matching >+ * @param enabled is the specified menu item enabled? >+ */ >+ public void verifyEnabled(String menuItem, String operator, boolean enabled) >+ { >+ verifyEnabled(MenuUtilBase.splitPath(menuItem), operator, enabled); >+ } >+ >+ /** >+ * Checks if the specified menu item is enabled. >+ * >+ * @param menuItem the menu item to verify against >+ * @param operator operator used for matching >+ * @param enabled is the specified menu item enabled? >+ */ >+ public void verifyEnabled(String[] menuItem, String operator, >+ boolean enabled) { >+ checkPathLength(menuItem.length); >+ final IMenuItemAdapter item = navigateToMenuItem( >+ getAndCheckMenu(), menuItem, operator); >+ checkIsNull(item); >+ try { >+ Verifier.equals(enabled, item.isEnabled()); >+ } finally { >+ closeMenu(getAndCheckMenu(), menuItem, operator); >+ } >+ >+ } >+ /** >+ * Checks if the given MenuItemAdapter is null and thorws an Exception >+ * >+ * @param item the MenuItemAdapter which should be checked >+ */ >+ private void checkIsNull(final IMenuItemAdapter item) { >+ if (item.getRealComponent() == null) { >+ throwMenuItemNotFound(); >+ } >+ } >+ >+ /** >+ * Checks if the specified menu item is enabled. >+ * >+ * @param menuItem the menu item as a text path to verify against >+ * @param enabled is the specified menu item enabled? >+ */ >+ public void verifyEnabledByIndexpath(String menuItem, boolean enabled) { >+ verifyEnabledByIndexpath(MenuUtilBase.splitIndexPath(menuItem), >+ enabled); >+ } >+ >+ /** >+ * Checks if the specified menu item is enabled. >+ * >+ * @param menuItem the menu item to verify against >+ * @param enabled is the specified menu item enabled? >+ */ >+ public void verifyEnabledByIndexpath(int[] menuItem, boolean enabled) { >+ checkPathLength(menuItem.length); >+ final IMenuItemAdapter item = navigateToMenuItem( >+ getAndCheckMenu(), menuItem); >+ checkIsNull(item); >+ try { >+ Verifier.equals(enabled, item.isEnabled()); >+ } finally { >+ closeMenu(getAndCheckMenu(), menuItem); >+ } >+ } >+ >+ >+ >+ /** >+ * Verifies if the specified menu item exists >+ * >+ * @param menuItem the menu item to verifiy against >+ * @param operator operator used for matching >+ * @param exists should the menu item exist? >+ */ >+ public void verifyExists(String menuItem, String operator, boolean exists) { >+ verifyExists(MenuUtilBase.splitPath(menuItem), operator, exists); >+ } >+ >+ /** >+ * Verifies if the specified menu item exists >+ * >+ * @param menuItem the menu item to verify against >+ * @param operator operator used for matching >+ * @param exists should the menu item exist? >+ */ >+ public void verifyExists(String[] menuItem, String operator, boolean exists) >+ { >+ checkPathLength(menuItem.length); >+ final IMenuItemAdapter item = navigateToMenuItem( >+ getAndCheckMenu(), menuItem, operator); >+ try { >+ Verifier.equals(exists, item.isExisting()); >+ } finally { >+ closeMenu(getAndCheckMenu(), menuItem, operator); >+ } >+ } >+ >+ >+ /** >+ * Verifies if the specified menu item exists >+ * @param menuItem the menu item to verifiy against >+ * @param exists should the menu item exist? >+ */ >+ public void verifyExistsByIndexpath(String menuItem, boolean exists) { >+ verifyExistsByIndexpath(MenuUtilBase.splitIndexPath(menuItem), exists); >+ } >+ >+ /** >+ * Verifies if the specified menu item exists >+ * >+ * @param menuItem the menu item to verify against >+ * @param exists should the menu item exist? >+ */ >+ public void verifyExistsByIndexpath(int[] menuItem, boolean exists) { >+ checkPathLength(menuItem.length); >+ final IMenuItemAdapter item = navigateToMenuItem( >+ getAndCheckMenu(), menuItem); >+ try { >+ Verifier.equals(exists, item.isExisting()); >+ } finally { >+ closeMenu(getAndCheckMenu(), menuItem); >+ } >+ >+ } >+ >+ /** >+ * Checks if the specified menu item is selected. >+ * >+ * @param menuItem the menu item to verify against >+ * @param operator operator used for matching >+ * @param selected is the specified menu item selected? >+ */ >+ public void verifySelected(String menuItem, String operator, >+ boolean selected) { >+ verifySelected(MenuUtilBase.splitPath(menuItem), operator, selected); >+ } >+ >+ /** >+ * Checks if the specified menu item is selected. >+ * >+ * @param menuItem the menu item to verify against >+ * @param operator operator used for matching >+ * @param selected is the specified menu item selected? >+ */ >+ public void verifySelected(String[] menuItem, String operator, >+ boolean selected) { >+ checkPathLength(menuItem.length); >+ final IMenuItemAdapter item = navigateToMenuItem( >+ getAndCheckMenu(), menuItem, operator); >+ checkIsNull(item); >+ try { >+ Verifier.equals(selected, item.isSelected()); >+ >+ } finally { >+ closeMenu(getAndCheckMenu(), menuItem, operator); >+ } >+ >+ } >+ >+ /** >+ * Checks if the specified menu item is selected. >+ * >+ * @param menuItem the menu item to verify against >+ * @param selected is the specified menu item selected? >+ */ >+ public void verifySelectedByIndexpath(String menuItem, boolean selected) { >+ verifySelectedByIndexpath(MenuUtilBase.splitIndexPath(menuItem), >+ selected); >+ } >+ >+ /** >+ * Checks if the specified menu item is selected. >+ * >+ * @param menuItem the menu item to verify against >+ * @param selected is the specified menu item selected? >+ */ >+ public void verifySelectedByIndexpath(int[] menuItem, boolean selected) { >+ checkPathLength(menuItem.length); >+ final IMenuItemAdapter item = navigateToMenuItem( >+ getAndCheckMenu(), menuItem); >+ checkIsNull(item); >+ try { >+ Verifier.equals(selected, item.isSelected()); >+ >+ } finally { >+ closeMenu(getAndCheckMenu(), menuItem); >+ >+ } >+ >+ } >+ >+ /** >+ * Tries to select a menu item in a menu defined by an Index-Path >+ * @param indexPath the menu item to select >+ */ >+ public void selectMenuItemByIndexpath(String indexPath) { >+ int[] indexItems = MenuUtilBase.splitIndexPath(indexPath); >+ checkPathLength(indexItems.length); >+ >+ try { >+ final IMenuItemAdapter item = navigateToMenuItem( >+ getAndCheckMenu(), indexItems); >+ >+ checkIsNull(item); >+ >+ item.selectMenuItem(); >+ } catch (StepExecutionException e) { >+ try { >+ closeMenu(getAndCheckMenu(), indexItems); >+ } catch (StepExecutionException e1) { >+ // Menu item is disabled or menu is already closed >+ // Do nothing >+ if (getLog().isInfoEnabled()) { >+ getLog().info("Tried to close a disabled or already closed menu."); //$NON-NLS-1$ >+ } >+ } >+ throwMenuItemNotFound(); >+ } >+ >+ } >+ >+ /** >+ * Tries to select a menu item in a menu defined by a Text-Path >+ * @param namePath the menu item to select >+ * @param operator operator used for matching >+ */ >+ public void selectMenuItem(String namePath, final String operator) { >+ String[] menuItems = MenuUtilBase.splitPath(namePath); >+ if (menuItems.length == 0) { >+ throw new StepExecutionException("empty path to menuitem not allowed", //$NON-NLS-1$ >+ EventFactory.createActionError()); >+ } >+ IMenuItemAdapter item = navigateToMenuItem(getAndCheckMenu(), >+ menuItems, operator); >+ if (item == null) { >+ try { >+ closeMenu(getAndCheckMenu(), menuItems, operator); >+ } catch (StepExecutionException see) { >+ // Menu item is disabled or menu is already closed >+ // Do nothing >+ getLog().info("Tried to close a disabled or already closed menu."); //$NON-NLS-1$ >+ } >+ throw new StepExecutionException("no such menu item found", //$NON-NLS-1$ >+ EventFactory.createActionError(TestErrorEvent.NOT_FOUND)); >+ } >+ item.selectMenuItem(); >+ } >+ >+ >+ /** >+ * >+ * @return the IMenuAdapter. >+ * @throws StepExecutionException >+ * if the active window has no menu bar. >+ */ >+ protected IMenuAdapter getAndCheckMenu() throws StepExecutionException { >+ Object menu = getMenuAdapter().getRealComponent(); >+ // Verify that the active window has a menu bar >+ if (menu == null) { >+ throw new StepExecutionException( >+ I18n.getString(TestErrorEvent.NO_MENU_BAR), >+ EventFactory.createActionError(TestErrorEvent.NO_MENU_BAR)); >+ } >+ return getMenuAdapter(); >+ } >+ >+ /** >+ * >+ */ >+ private void throwMenuItemNotFound() { >+ throw new StepExecutionException("no such menu item found", //$NON-NLS-1$ >+ EventFactory.createActionError(TestErrorEvent.NOT_FOUND)); >+ } >+ >+ >+ /** >+ * this methods closes the hole menu. It is clicking on the parent item in the menu bar. >+ * >+ * If you need another implementation override this method. >+ * @param menuBar the main menu >+ * @param textPath the text path used for opening the menu >+ * @param operator the operator which was used for opening the menu >+ */ >+ protected void closeMenu(IMenuAdapter menuBar, String[] textPath, >+ String operator) { >+ IMenuItemAdapter menuitem = findMenu(menuBar, >+ getIndexForName(menuBar, textPath[0], operator)); >+ if (menuitem.getRealComponent() != null) { >+ getRobot().click( >+ menuitem.getRealComponent(), >+ null, >+ ClickOptions.create().setClickType( >+ ClickOptions.ClickType.RELEASED)); >+ >+ } >+ >+ } >+ /** >+ * this methods closes the hole menu. It is clicking on the parent item in the menu bar. >+ * >+ * If you need another implementation override this method. >+ * @param menuBar the main menu >+ * @param path the integer based path used for opening the menu >+ */ >+ protected void closeMenu(IMenuAdapter menuBar, int[] path) { >+ IMenuItemAdapter menuitem = findMenu(menuBar, path[0]); >+ if (menuitem.getRealComponent() != null) { >+ getRobot().click( >+ menuitem.getRealComponent(), >+ null, >+ ClickOptions.create().setClickType( >+ ClickOptions.ClickType.RELEASED)); >+ >+ } >+ } >+ >+ /** >+ * Gets the index of the specific menu entry with the name >+ * >+ * @param menu the menu in which all items are stored >+ * @param name the name of the item we want the index from >+ * @param operator the operator for the matching >+ * @return the index for the specific menu entry >+ */ >+ protected int getIndexForName(IMenuAdapter menu, String name, >+ String operator) { >+ IMenuItemAdapter [] subElements = menu.getItems(); >+ int downcount = 0; >+ for (int j = 0; j < subElements.length; j++) { >+ IMenuItemAdapter tempMenu = (IMenuItemAdapter)subElements[j]; >+ if (tempMenu.isSeparator()) { >+ downcount++; >+ } >+ if (tempMenu.isShowing() >+ && MatchUtil.getInstance().match( >+ tempMenu.getText(), name, operator)) { >+ return j - downcount; >+ } >+ } >+ return Integer.MAX_VALUE; >+ } >+ >+ >+ /** >+ * implementation for "wait for component" >+ * @param timeout the maximum amount of time to wait for the component >+ * @param delay the time to wait after the component is found >+ */ >+ public void waitForComponent(int timeout, int delay) { >+ if (getComponent().getRealComponent() == null) { >+ long start = System.currentTimeMillis(); >+ do { >+ RobotTiming.sleepWaitForComponentPollingDelay(); >+ } while (System.currentTimeMillis() - start < timeout >+ && getComponent().getRealComponent() == null); >+ if (getComponent().getRealComponent() == null) { >+ throw new StepExecutionException("No Menubar found.", //$NON-NLS-1$ >+ EventFactory.createComponentNotFoundErrorEvent()); >+ } >+ } >+ TimeUtil.delay(delay); >+ } >+ >+ /** >+ * Tries to navigate through the menu to the specified menu item. >+ * This method should be overridden if there is a need for a faster implementation. >+ * >+ * @param menuBar the menubar >+ * @param path the path where to navigate in the menu. >+ * @param operator operator used for matching >+ * @return the adapter at the end of the specified path or a adapter that contains no component. >+ */ >+ protected IMenuItemAdapter navigateToMenuItem( >+ IMenuAdapter menuBar, String[] path, String operator) { >+ checkPathLength(path.length); >+ IMenuAdapter currentmenu = menuBar; >+ IMenuItemAdapter currentMenuItem = null; >+ final int pathLength = path.length; >+ final int beforeLast = pathLength - 1; >+ >+ for (int i = 0; i < path.length; i++) { >+ int pathIndex = getIndexForName(currentmenu, path[i], operator); >+ currentMenuItem = getNextMenuItem(currentmenu, pathIndex); >+ >+ if ((currentMenuItem.getRealComponent() == null) >+ && (i < beforeLast)) { >+ return currentMenuItem; >+ } >+ >+ if (i < beforeLast) { >+ if (!currentMenuItem.hasSubMenu()) { >+ // the given path is longer than the menu levels >+ return newMenuItemAdapter(null); >+ } >+ currentmenu = currentMenuItem.openSubMenu(); >+ } >+ } >+ return currentMenuItem; >+ } >+ >+ /** >+ * Tries to navigate through the menu to the specified menu item. >+ * This method should be overridden if there is a need for a faster implementation. >+ * >+ * @param menubar the menubar >+ * @param path the path where to navigate in the menu. >+ * @return -the adapter at the end of the specified path or a adapter that contains no component. >+ */ >+ protected IMenuItemAdapter navigateToMenuItem( >+ IMenuAdapter menubar, int[] path) { >+ checkPathLength(path.length); >+ >+ IMenuAdapter currentmenu = menubar; >+ IMenuItemAdapter currentMenuItem = null; >+ final int pathLength = path.length; >+ final int beforeLast = pathLength - 1; >+ >+ for (int i = 0; i < path.length; i++) { >+ final int pathIndex = path[i]; >+ currentMenuItem = getNextMenuItem(currentmenu, pathIndex); >+ >+ if ((currentMenuItem.getRealComponent() == null) >+ && (i < beforeLast)) { >+ return currentMenuItem; >+ } >+ >+ if (i < beforeLast) { >+ if (!currentMenuItem.hasSubMenu()) { >+ // the given path is longer than the menu levels >+ return newMenuItemAdapter(null); >+ } >+ currentmenu = currentMenuItem.openSubMenu(); >+ } >+ >+ >+ >+ } >+ >+ return currentMenuItem; >+ } >+ /** >+ * gets the next menu item adapter from its specific index >+ * @param currentmenu the current menu >+ * @param pathIndex the index from the next menu item >+ * @return the wanted menu item in a adapter >+ */ >+ private IMenuItemAdapter getNextMenuItem(IMenuAdapter currentmenu, >+ final int pathIndex) { >+ IMenuItemAdapter currentMenuItem; >+ if (pathIndex < 0) { >+ throwInvalidPathException(); >+ } >+ currentMenuItem = findMenu(currentmenu, pathIndex); >+ return currentMenuItem; >+ } >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ /** >+ * @param menu menu >+ * @param idx index of the current wanted item >+ * @return the next IMenuItemAdapter from the next cascade >+ */ >+ private IMenuItemAdapter findMenu(IMenuAdapter menu, int idx) { >+ List visibleSubMenus = new ArrayList(); >+ IMenuItemAdapter[] subElements = menu.getItems(); >+ >+ for (int i = 0; i < subElements.length; ++i) { >+ >+ IMenuItemAdapter menuitem = subElements[i]; >+ if (menuitem.getRealComponent() != null && !menuitem.isSeparator() >+ && menuitem.isShowing()) { >+ visibleSubMenus.add(menuitem); >+ } >+ >+ } >+ >+ if (idx >= visibleSubMenus.size() || idx < 0) { >+ return newMenuItemAdapter(null); >+ } >+ >+ return (IMenuItemAdapter) visibleSubMenus.get(idx); >+ >+ } >+ >+ >+ /** >+ * Checks the path for it length and throws and StepExecutionExecption if it is 0 >+ * @param length the path length to be checked >+ */ >+ private void checkPathLength(int length) { >+ if (length < 1) { >+ throw new StepExecutionException("empty path to menuitem is not allowed", EventFactory //$NON-NLS-1$ >+ .createActionError( >+ TestErrorEvent.INVALID_PARAM_VALUE)); >+ } >+ } >+ >+ /** >+ * >+ */ >+ private static void throwInvalidPathException() { >+ throw new StepExecutionException("invalid path", EventFactory //$NON-NLS-1$ >+ .createActionError(TestErrorEvent.INVALID_PARAM_VALUE)); >+ } >+ /** >+ * This adapts or puts the new MenuItem in the context which is needed for >+ * the algorithms. >+ * @param component the new MenuItem which is used by the next step >+ * @return the adapted or casted MenuItem >+ */ >+ protected abstract IMenuItemAdapter newMenuItemAdapter(Object component); >+ >+} >\ No newline at end of file >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTableCAPs.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTableCAPs.java >new file mode 100644 >index 0000000..08e40b4 >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTableCAPs.java >@@ -0,0 +1,1196 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.caps; >+ >+import java.awt.Rectangle; >+import java.util.StringTokenizer; >+ >+import org.eclipse.jubula.rc.common.CompSystemConstants; >+import org.eclipse.jubula.rc.common.driver.ClickOptions; >+import org.eclipse.jubula.rc.common.driver.DragAndDropHelper; >+import org.eclipse.jubula.rc.common.driver.IRobot; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.implclasses.IndexConverter; >+import org.eclipse.jubula.rc.common.implclasses.MatchUtil; >+import org.eclipse.jubula.rc.common.implclasses.Verifier; >+import org.eclipse.jubula.rc.common.implclasses.table.Cell; >+import org.eclipse.jubula.rc.common.logger.AutServerLogger; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.ITableAdapter; >+import org.eclipse.jubula.rc.common.util.KeyStrokeUtil; >+import org.eclipse.jubula.tools.constants.InputConstants; >+import org.eclipse.jubula.tools.objects.event.EventFactory; >+import org.eclipse.jubula.tools.objects.event.TestErrorEvent; >+import org.eclipse.jubula.tools.utils.TimeUtil; >+ >+/** >+ * General implementation for tables. >+ * >+ * @author BREDEX GmbH >+ */ >+public abstract class AbstractTableCAPs extends AbstractTextInputSupport { >+ >+ /** the logger */ >+ private static AutServerLogger log = new AutServerLogger( >+ AbstractMenuCAPs.class); >+ >+ /** >+ * @return the log >+ */ >+ public static AutServerLogger getLog() { >+ return log; >+ } >+ >+ /** >+ * This method is mostly needed for clicks >+ * @return the real table as object >+ */ >+ private Object getRealTable() { >+ return getComponent().getRealComponent(); >+ } >+ /** >+ * >+ * @return the ITableAdapter of this table >+ */ >+ private ITableAdapter getTableAdapter() { >+ return (ITableAdapter) getComponent(); >+ } >+ >+ /** >+ * Verifies the rendered text inside the currently selected cell. >+ * >+ * @param text The cell text to verify. >+ * @throws StepExecutionException >+ * If there is no selected cell, or if the rendered text cannot >+ * be extracted. >+ */ >+ public void gdVerifyText(String text) >+ throws StepExecutionException { >+ >+ gdVerifyText(text, MatchUtil.DEFAULT_OPERATOR); >+ } >+ >+ /** >+ * Verifies the rendered text inside the currently selected cell. >+ * @param text The cell text to verify. >+ * @param operator The operation used to verify >+ * @throws StepExecutionException If there is no selected cell, or if the rendered text cannot be extracted. >+ */ >+ public void gdVerifyText(String text, String operator) >+ throws StepExecutionException { >+ ITableAdapter adapter = getTableAdapter(); >+ Cell cell = adapter.getSelectedCell(); >+ final int implRow = cell.getRow(); >+ final int implCol = cell.getCol(); >+ checkRowColBounds(implRow, implCol); >+ >+ adapter.scrollCellToVisible(implRow, implCol); >+ final String current = getCellText(implRow, implCol); >+ Verifier.match(current, text, operator); >+ } >+ >+ /** >+ * Verifies the rendered text inside the passed cell. >+ * @param row The row of the cell. >+ * @param rowOperator The row header operator >+ * @param col The column of the cell. >+ * @param colOperator The column header operator >+ * @param text The cell text to verify. >+ * @param operator The operation used to verify >+ * @throws StepExecutionException If the row or the column is invalid, or if the rendered text cannot be extracted. >+ */ >+ public void gdVerifyText(String text, String operator, final String row, >+ final String rowOperator, final String col, >+ final String colOperator) throws StepExecutionException { >+ ITableAdapter adapter = getTableAdapter(); >+ final int implRow = adapter.getRowFromString(row, rowOperator); >+ final int implCol = adapter.getColumnFromString(col, colOperator); >+ String current; >+ //if row is header and column is existing >+ if (implRow == -1 && implCol > -1) { >+ current = adapter.getColumnName(implCol); >+ } else { >+ checkRowColBounds(implRow, implCol); >+ adapter.scrollCellToVisible(implRow, implCol); >+ current = getCellText(implRow, implCol); >+ } >+ >+ >+ >+ >+ Verifier.match(current, text, operator); >+ } >+ >+ /** >+ * Selects the cell of the Table.<br> >+ * With the xPos, yPos, xunits and yUnits the click position inside the cell can be defined. >+ * @param row The row of the cell. >+ * @param rowOperator The row header operator >+ * @param col The column of the cell. >+ * @param colOperator The column header operator >+ * @param clickCount The number of clicks with the right mouse button >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param extendSelection Should this selection be part of a multiple selection >+ * @param button what mouse button should be used >+ * @throws StepExecutionException If the row or the column is invalid >+ */ >+ public void gdSelectCell(final String row, final String rowOperator, >+ final String col, final String colOperator, >+ final int clickCount, final int xPos, final String xUnits, >+ final int yPos, final String yUnits, final String extendSelection, >+ int button) >+ throws StepExecutionException { >+ ITableAdapter adapter = getTableAdapter(); >+ final int implRow = adapter.getRowFromString(row, rowOperator); >+ final int implCol = adapter.getColumnFromString(col, colOperator); >+ final boolean isExtendSelection = extendSelection.equals( >+ CompSystemConstants.EXTEND_SELECTION_YES); >+ if (log.isDebugEnabled()) { >+ log.debug("Selecting row, col: " + row + ", " + col); //$NON-NLS-1$//$NON-NLS-2$ >+ } >+ >+ Rectangle cellBounds; >+ //if row is header and col is existing >+ if (implRow == -1 && implCol > -1) { >+ cellBounds = adapter.getHeaderBounds(implCol); >+ } else { >+ cellBounds = adapter.scrollCellToVisible(implRow, implCol); >+ } >+ Object o = getSpecificRectangle(cellBounds); >+ ClickOptions clickOptions = ClickOptions.create(); >+ clickOptions.setClickCount(clickCount).setScrollToVisible(false); >+ clickOptions.setMouseButton(button); >+ try { >+ if (isExtendSelection) { >+ getRobot().keyPress(getRealTable(), >+ getExtendSelectionModifier()); >+ } >+ getRobot().click(getRealTable(), o, clickOptions, >+ xPos, xUnits.equalsIgnoreCase(POS_UNIT_PIXEL), >+ yPos, yUnits.equalsIgnoreCase(POS_UNIT_PIXEL)); >+ } finally { >+ if (isExtendSelection) { >+ getRobot().keyRelease(getRealTable(), >+ getExtendSelectionModifier()); >+ } >+ } >+ } >+ /** >+ * This is a workaround because the toolkit specific >+ * Robot implementation are using different rectangle types. >+ * @param rectangle the java.awt.rectangle which needs to >+ * casted >+ * @return the rectangle in the type for the specific robot >+ */ >+ protected Object getSpecificRectangle(Rectangle rectangle) { >+ //FIXME changing the Robots might be useful here >+ return rectangle; >+ } >+ /** >+ * Verifies, if value exists in column. >+ * >+ * @param col The column of the cell. >+ * @param colOperator the column header operator >+ * @param value The cell text to verify. >+ * @param operator The operation used to verify >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ * @param exists true if value exists, false otherwise >+ * @throws StepExecutionException >+ * If the row or the column is invalid, or if the rendered text >+ * cannot be extracted. >+ */ >+ public void gdVerifyValueInColumn(final String col, >+ final String colOperator, final String value, >+ final String operator, final String searchType, boolean exists) >+ throws StepExecutionException { >+ ITableAdapter adapter = getTableAdapter(); >+ final int implCol = adapter.getColumnFromString(col, colOperator); >+ >+ >+ boolean valueExists = isValueExisting(adapter, implCol, >+ value, operator, searchType); >+ >+ Verifier.equals(exists, valueExists); >+ } >+ /** >+ * Looks if value exists in the Column. >+ * >+ * @param adapter the teble adapter working on. >+ * @param implCol the implementation column of the cell. >+ * @param value the cellt text to verify. >+ * @param operator The operation used to verify. >+ * @param searchType searchType Determines where the search begins ("relative" or "absolute") >+ * @return <code>true</code> it the value exists in the column >+ */ >+ private boolean isValueExisting(ITableAdapter adapter, int implCol, >+ String value, String operator, final String searchType) { >+ final int rowCount = adapter.getRowCount(); >+ for (int i = getStartingRowIndex(searchType); >+ i < rowCount; ++i) { >+ if (MatchUtil.getInstance().match(getCellText(i, >+ implCol), value, operator)) { >+ return true; >+ } >+ } >+ if (adapter.isHeaderVisible()) { >+ String header = adapter.getColumnName(implCol); >+ if (MatchUtil.getInstance().match(header, value, >+ operator)) { >+ return true; >+ } >+ } >+ return false; >+ } >+ >+ >+ >+ /** >+ * Verifies, if value exists in row.. >+ * >+ * @param row The row of the cell. >+ * @param rowOperator the row header operator >+ * @param value The cell text to verify. >+ * @param operator The operation used to verify >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ * @param exists true if value exists, false otherwise >+ * @throws StepExecutionException >+ * If the row or the column is invalid, or if the rendered text >+ * cannot be extracted. >+ */ >+ public void gdVerifyValueInRow(final String row, final String rowOperator, >+ final String value, final String operator, final String searchType, >+ boolean exists) >+ throws StepExecutionException { >+ final ITableAdapter adapter = getTableAdapter(); >+ final int implRow = adapter.getRowFromString(row, rowOperator); >+ boolean valueIsExisting = false; >+ //if row is header >+ if (implRow == -1) { >+ >+ for (int k = getStartingColIndex(searchType); >+ k < adapter.getColumnCount(); ++k) { >+ if (MatchUtil.getInstance().match( >+ adapter.getColumnName(k), >+ value, operator)) { >+ valueIsExisting = true; >+ break; >+ } >+ } >+ >+ >+ } else { >+ >+ final int columnCount = adapter.getColumnCount(); >+ if (columnCount > 0) { >+ for (int i = getStartingColIndex(searchType); >+ i < columnCount; ++i) { >+ if (MatchUtil.getInstance().match( >+ getCellText(implRow, i), value, operator)) { >+ valueIsExisting = true; >+ break; >+ } >+ } >+ } else { >+ // No columns found. This table is used to present a >+ // list-like component. >+ if (MatchUtil.getInstance().match( >+ adapter.getRowName(implRow), >+ value, operator)) { >+ valueIsExisting = true; >+ >+ } >+ } >+ >+ } >+ Verifier.equals(exists, valueIsExisting); >+ } >+ >+ /** >+ * Verifies the editable property of the given indices. >+ * >+ * @param editable >+ * The editable property to verify. >+ * @param row the row to select >+ * @param rowOperator the row header operator >+ * @param col the column to select >+ * @param colOperator the column header operator >+ */ >+ public void gdVerifyEditable(boolean editable, String row, >+ String rowOperator, String col, String colOperator) { >+ //if row is header row >+ >+ if (getTableAdapter().getRowFromString(row, rowOperator) == -1) { >+ throw new StepExecutionException("Unsupported Header Action", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.UNSUPPORTED_HEADER_ACTION)); >+ } >+ gdSelectCell(row, rowOperator, col, colOperator, ClickOptions.create(), >+ CompSystemConstants.EXTEND_SELECTION_NO); >+ gdVerifyEditable(editable); >+ } >+ >+ >+ /** >+ * Selects a table cell in the given row and column via click in the midle of the cell. >+ * @param row The row of the cell. >+ * @param rowOperator The row header operator >+ * @param col The column of the cell. >+ * @param colOperator The column header operator >+ * @param co the click options to use >+ * @param extendSelection Should this selection be part of a multiple selection >+ */ >+ private void gdSelectCell(final String row, final String rowOperator, >+ final String col, final String colOperator, >+ final ClickOptions co, final String extendSelection) { >+ >+ gdSelectCell(row, rowOperator, col, colOperator, co.getClickCount(), >+ 50, POS_UNI_PERCENT, 50, POS_UNI_PERCENT, extendSelection, >+ co.getMouseButton()); >+ } >+ >+ >+ /** >+ * Verifies the rendered text inside cell at the mouse position on screen. >+ * >+ * @param text The cell text to verify. >+ * @param operator The operation used to verify >+ * @throws StepExecutionException If there is no selected cell, or if the >+ * rendered text cannot be extracted. >+ */ >+ public void gdVerifyTextAtMousePosition(String text, String operator) >+ throws StepExecutionException { >+ if (isMouseOnHeader()) { >+ throw new StepExecutionException("Unsupported Header Action", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.UNSUPPORTED_HEADER_ACTION)); >+ } >+ Cell cell = getCellAtMousePosition(); >+ gdVerifyText(text, operator, >+ Integer.toString(IndexConverter.toUserIndex(cell.getRow())), >+ MatchUtil.EQUALS, >+ Integer.toString(IndexConverter.toUserIndex(cell.getCol())), >+ MatchUtil.EQUALS); >+ } >+ >+ /** >+ * Verifies the editable property of the selected cell. >+ * >+ * @param editable the editable property to verify. >+ */ >+ public void gdVerifyEditableSelected(boolean editable) { >+ gdVerifyEditable(editable); >+ } >+ >+ /** >+ * Verifies the editable property of the current selected cell. >+ * >+ * @param editable The editable property to verify. >+ */ >+ public void gdVerifyEditable(boolean editable) { >+ Cell cell = getTableAdapter().getSelectedCell(); >+ >+ Verifier.equals(editable, getTableAdapter() >+ .isCellEditable(cell.getRow(), cell.getCol())); >+ } >+ >+ /** >+ * Verifies the editable property of the cell under current mouse position. >+ * >+ * @param editable the editable property to verify. >+ */ >+ public void gdVerifyEditableMousePosition(boolean editable) { >+ //if row is header row >+ if (isMouseOnHeader()) { >+ throw new StepExecutionException("Unsupported Header Action", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.UNSUPPORTED_HEADER_ACTION)); >+ } >+ Cell cell = getCellAtMousePosition(); >+ boolean isEditable = getTableAdapter().isCellEditable( >+ cell.getRow(), cell.getCol()); >+ Verifier.equals(editable, isEditable); >+ } >+ /** >+ * Finds the first row which contains the value <code>value</code> >+ * in column <code>col</code> and selects this row. >+ * @param col the column >+ * @param colOperator the column header operator >+ * @param value the value >+ * @param clickCount the number of clicks. >+ * @param regexOp the regex operator >+ * @param extendSelection Should this selection be part of a multiple selection >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ * @param button what mouse button should be used >+ */ >+ public void gdSelectRowByValue(String col, String colOperator, >+ final String value, final String regexOp, int clickCount, >+ final String extendSelection, final String searchType, int button) { >+ gdSelectRowByValue(col, colOperator, value, regexOp, extendSelection, >+ searchType, ClickOptions.create() >+ .setClickCount(clickCount) >+ .setMouseButton(button)); >+ } >+ >+ /** >+ * Finds the first row which contains the value <code>value</code> >+ * in column <code>col</code> and selects this row. >+ * >+ * @param col the column >+ * @param colOperator the column header operator >+ * @param value the value >+ * @param regexOp the regex operator >+ * @param extendSelection Should this selection be part of a multiple selection >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ * @param co the clickOptions to use >+ */ >+ protected void gdSelectRowByValue(String col, String colOperator, >+ final String value, final String regexOp, final String extendSelection, >+ final String searchType, ClickOptions co) { >+ ITableAdapter adapter = getTableAdapter(); >+ final int implCol = adapter.getColumnFromString(col, colOperator); >+ Integer implRow = null; >+ final int rowCount = adapter.getRowCount(); >+ >+ for (int i = getStartingRowIndex(searchType); i < rowCount; ++i) { >+ if (MatchUtil.getInstance().match(getCellText(i, implCol), >+ value, regexOp)) { >+ >+ implRow = new Integer(i); >+ break; >+ } >+ } >+ if (implRow == null) { >+ String header = adapter.getColumnName(implCol); >+ if (MatchUtil.getInstance().match(header, value, regexOp)) { >+ implRow = new Integer(-1); >+ } >+ } >+ >+ if (implRow == null) { >+ throw new StepExecutionException("no such row found", //$NON-NLS-1$ >+ EventFactory.createActionError(TestErrorEvent.NOT_FOUND)); >+ } >+ >+ String userIdxRow = new Integer(IndexConverter.toUserIndex( >+ implRow.intValue())).toString(); >+ String userIdxCol = new Integer(IndexConverter.toUserIndex( >+ implCol)).toString(); >+ >+ gdSelectCell(userIdxRow, MatchUtil.EQUALS, userIdxCol, colOperator, co, >+ extendSelection); >+ } >+ >+ /** >+ * Finds the first column which contains the value <code>value</code> >+ * in the given row and selects the cell. >+ * >+ * @param row the row to select >+ * @param rowOperator the row header operator >+ * @param value the value >+ * @param clickCount the number of clicks >+ * @param regex search using regex >+ * @param extendSelection Should this selection be part of a multiple selection >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ * @param button what mouse button should be used >+ */ >+ public void gdSelectCellByColValue(String row, String rowOperator, >+ final String value, final String regex, int clickCount, >+ final String extendSelection, final String searchType, int button) { >+ gdSelectCellByColValue(row, rowOperator, value, regex, extendSelection, >+ searchType, ClickOptions.create() >+ .setClickCount(clickCount) >+ .setMouseButton(button)); >+ } >+ >+ /** >+ * Finds the first column which contains the value <code>value</code> >+ * in the given row and selects the cell. >+ * >+ * @param row the row >+ * @param rowOperator the row header operator >+ * @param value the value >+ * @param regex search using regex >+ * @param extendSelection Should this selection be part of a multiple selection >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ * @param co the click options to use >+ */ >+ protected void gdSelectCellByColValue(String row, String rowOperator, >+ final String value, final String regex, final String extendSelection, >+ final String searchType, ClickOptions co) { >+ ITableAdapter adapter = getTableAdapter(); >+ final int implRow = adapter.getRowFromString(row, rowOperator); >+ int colCount = adapter.getColumnCount(); >+ Integer implCol = null; >+ if (implRow == -1) { >+ >+ for (int i = getStartingColIndex(searchType); i < colCount; ++i) { >+ if (MatchUtil.getInstance().match(adapter.getColumnName(i), >+ value, regex)) { >+ implCol = new Integer(i); >+ break; >+ } >+ } >+ } else { >+ for (int i = getStartingColIndex(searchType); i < colCount; ++i) { >+ if (MatchUtil.getInstance().match(getCellText(implRow, i), >+ value, regex)) { >+ >+ implCol = new Integer(i); >+ break; >+ } >+ } >+ } >+ if (implCol == null) { >+ throw new StepExecutionException("no such cell found", EventFactory //$NON-NLS-1$ >+ .createActionError(TestErrorEvent.NOT_FOUND)); >+ } >+ >+ String usrIdxRowStr = new Integer(IndexConverter.toUserIndex( >+ implRow)).toString(); >+ String usrIdxColStr = new Integer(IndexConverter.toUserIndex( >+ implCol.intValue())).toString(); >+ >+ gdSelectCell(usrIdxRowStr, rowOperator, usrIdxColStr, MatchUtil.EQUALS, >+ co, extendSelection); >+ >+ } >+ >+ /** >+ * Action to read the value of the current selected cell of the JTable >+ * to store it in a variable in the Client >+ * @param variable the name of the variable >+ * @return the text value. >+ */ >+ public String gdReadValue(String variable) { >+ final Cell selectedCell = getTableAdapter().getSelectedCell(); >+ return getCellText(selectedCell.getRow(), selectedCell.getCol()); >+ } >+ >+ /** >+ * Action to read the value of the passed cell of the JTable >+ * to store it in a variable in the Client >+ * @param variable the name of the variable >+ * @param row the row to select >+ * @param rowOperator the row header operator >+ * @param col the column to select >+ * @param colOperator the column header operator >+ * @return the text value. >+ */ >+ public String gdReadValue(String variable, String row, String rowOperator, >+ String col, String colOperator) { >+ ITableAdapter adapter = getTableAdapter(); >+ final int implRow = adapter.getRowFromString(row, rowOperator); >+ final int implCol = adapter.getColumnFromString(col, colOperator); >+ >+ //if row is header and column is existing >+ if (implRow == -1 && implCol > -1) { >+ return adapter.getColumnName(implCol); >+ } >+ >+ checkRowColBounds(implRow, implCol); >+ >+ adapter.scrollCellToVisible(implRow, implCol); >+ return getCellText(implRow, implCol); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String gdReadValueAtMousePosition(String variable) { >+ Cell cellAtMousePosition = getTableAdapter().getSelectedCell(); >+ return getCellText(cellAtMousePosition.getRow(), >+ cellAtMousePosition.getCol()); >+ } >+ >+ /** >+ * Tries to click in the cell under the mouse position. If the mouse is not >+ * over a cell, the current selected cell will be clicked on. If there is no >+ * selected cell, the middle of the table is used to click on. >+ * @param count Number of clicks >+ * @param button The mouse button >+ */ >+ public void gdClick(int count, int button) { >+ ITableAdapter adapter = getTableAdapter(); >+ Cell cell = null; >+ if (isMouseOverCell()) { >+ cell = getCellAtMousePosition(); >+ } else if (adapter.hasCellSelection()) { >+ cell = adapter.getSelectedCell(); >+ } >+ if (cell != null) { >+ Rectangle cellRect = >+ adapter.scrollCellToVisible(cell.getRow(), cell.getCol()); >+ getRobot().click(getRealTable(), cellRect, ClickOptions.create() >+ .setClickCount(count).setMouseButton(button)); >+ } else { >+ super.gdClick(count, button); >+ } >+ } >+ >+ /** >+ * Selects a cell relative to the cell at the current mouse position. >+ * If the mouse is not at any cell, the current selected cell is used. >+ * @param direction the direction to move. >+ * @param cellCount the amount of cells to move >+ * @param clickCount the click count to select the new cell. >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param extendSelection Should this selection be part of a multiple selection >+ * @throws StepExecutionException if any error occurs >+ */ >+ public void gdMove(String direction, int cellCount, int clickCount, >+ final int xPos, final String xUnits, >+ final int yPos, final String yUnits, final String extendSelection) >+ throws StepExecutionException { >+ if (isMouseOnHeader()) { >+ throw new StepExecutionException("Unsupported Header Action", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.UNSUPPORTED_HEADER_ACTION)); >+ } >+ Cell currCell = null; >+ try { >+ currCell = getCellAtMousePosition(); >+ } catch (StepExecutionException e) { >+ currCell = getTableAdapter().getSelectedCell(); >+ } >+ int newCol = currCell.getCol(); >+ int newRow = currCell.getRow(); >+ if (CompSystemConstants.TABLE_MOVE_UP >+ .equalsIgnoreCase(direction)) { >+ newRow -= cellCount; >+ } else if (CompSystemConstants.TABLE_MOVE_DOWN >+ .equalsIgnoreCase(direction)) { >+ newRow += cellCount; >+ } else if (CompSystemConstants.TABLE_MOVE_LEFT >+ .equalsIgnoreCase(direction)) { >+ newCol -= cellCount; >+ } else if (CompSystemConstants.TABLE_MOVE_RIGHT >+ .equalsIgnoreCase(direction)) { >+ newCol += cellCount; >+ } >+ newRow = IndexConverter.toUserIndex(newRow); >+ newCol = IndexConverter.toUserIndex(newCol); >+ String row = Integer.toString(newRow); >+ String col = Integer.toString(newCol); >+ gdSelectCell(row, MatchUtil.DEFAULT_OPERATOR , col, >+ MatchUtil.DEFAULT_OPERATOR, clickCount, xPos, >+ xUnits, yPos, yUnits, extendSelection, >+ InputConstants.MOUSE_BUTTON_LEFT); >+// gdSelectCell(newRow, newCol, clickCount, >+// xPos, xUnits, yPos, yUnits, extendSelection); >+ } >+ >+ /** >+ * Writes the passed text into the currently selected cell. >+ * >+ * @param text >+ * The text. >+ * @throws StepExecutionException >+ * If there is no selected cell, or if the cell is not editable, >+ * or if the table cell editor permits the text to be written. >+ */ >+ public void gdInputText(final String text) throws StepExecutionException { >+ inputText(text, false); >+ } >+ >+ /** >+ * Types the text in the specified cell. >+ * @param text The text >+ * @param row The row of the cell. >+ * @param rowOperator The row operator >+ * @param col The column of the cell. >+ * @param colOperator The column operator >+ * @throws StepExecutionException If the text input fails >+ */ >+ public void gdInputText(String text, String row, String rowOperator, >+ String col, String colOperator) >+ throws StepExecutionException { >+ //if row is header row >+ if (getTableAdapter().getRowFromString(row, rowOperator) == -1) { >+ throw new StepExecutionException("Unsupported Header Action", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.UNSUPPORTED_HEADER_ACTION)); >+ } >+ gdSelectCell(row, rowOperator, col, colOperator, >+ ClickOptions.create().setClickCount(1), >+ CompSystemConstants.EXTEND_SELECTION_NO); >+ gdInputText(text); >+ } >+ >+ /** >+ * Types <code>text</code> into the component. This replaces the shown >+ * content in the current selected cell. >+ * >+ * @param text the text to type in >+ * @throws StepExecutionException >+ * If there is no selected cell, or if the cell is not editable, >+ * or if the table cell editor permits the text to be written. >+ */ >+ public void gdReplaceText(String text) throws StepExecutionException { >+ inputText(text, true); >+ } >+ >+ /** >+ * Replaces the given text in the given cell coordinates >+ * @param text the text to replace >+ * @param row The row of the cell. >+ * @param rowOperator The row operator >+ * @param col The column of the cell. >+ * @param colOperator The column operator >+ */ >+ public void gdReplaceText(String text, String row, String rowOperator, >+ String col, String colOperator) { >+ //if row is header row >+ if (getTableAdapter().getRowFromString(row, rowOperator) == -1) { >+ throw new StepExecutionException("Unsupported Header Action", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.UNSUPPORTED_HEADER_ACTION)); >+ } >+ gdSelectCell(row, rowOperator, col, colOperator, >+ ClickOptions.create().setClickCount(1), >+ CompSystemConstants.EXTEND_SELECTION_NO); >+ inputText(text, true); >+ } >+ >+ /** >+ * Drags the cell of the Table.<br> >+ * With the xPos, yPos, xunits and yUnits the click position inside the >+ * cell can be defined. >+ * >+ * @param mouseButton the mouseButton. >+ * @param modifier the modifier. >+ * @param row the row to select >+ * @param rowOperator the row header operator >+ * @param col the column to select >+ * @param colOperator the column header operator >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @throws StepExecutionException >+ * If the row or the column is invalid >+ */ >+ public void gdDragCell(final int mouseButton, final String modifier, >+ final String row, final String rowOperator, >+ final String col, final String colOperator, final int xPos, >+ final String xUnits, final int yPos, final String yUnits) >+ throws StepExecutionException { >+ >+ final DragAndDropHelper dndHelper = DragAndDropHelper.getInstance(); >+ dndHelper.setModifier(modifier); >+ dndHelper.setMouseButton(mouseButton); >+ dndHelper.setDragComponent(null); >+ gdSelectCell(row, rowOperator, col, colOperator, 0, xPos, xUnits, yPos, >+ yUnits, CompSystemConstants.EXTEND_SELECTION_NO, 1); >+ pressOrReleaseModifiers(modifier, true); >+ getRobot().mousePress(null, null, mouseButton); >+ } >+ >+ /** >+ * Drops on the cell of the JTable.<br> >+ * With the xPos, yPos, xunits and yUnits the click position inside the >+ * cell can be defined. >+ * >+ * @param row the row to select >+ * @param rowOperator the row header operator >+ * @param col the column to select >+ * @param colOperator the column header operator >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param delayBeforeDrop the amount of time (in milliseconds) to wait >+ * between moving the mouse to the drop point and >+ * releasing the mouse button >+ * @throws StepExecutionException >+ * If the row or the column is invalid >+ */ >+ public void gdDropCell(final String row, final String rowOperator, >+ final String col, final String colOperator, final int xPos, >+ final String xUnits, final int yPos, final String yUnits, >+ int delayBeforeDrop) throws StepExecutionException { >+ >+ final DragAndDropHelper dndHelper = DragAndDropHelper.getInstance(); >+ try { >+ gdSelectCell(row, rowOperator, col, colOperator, 0, xPos, xUnits, >+ yPos, yUnits, CompSystemConstants.EXTEND_SELECTION_NO, 1); >+ waitBeforeDrop(delayBeforeDrop); >+ } finally { >+ getRobot().mouseRelease(null, null, dndHelper.getMouseButton()); >+ pressOrReleaseModifiers(dndHelper.getModifier(), false); >+ } >+ } >+ >+ /** >+ * Finds the first row which contains the value <code>value</code> >+ * in column <code>col</code> and drags this row. >+ * >+ * @param mouseButton the mouse button >+ * @param modifier the modifier >+ * @param col the column >+ * @param colOperator the column header operator >+ * @param value the value >+ * @param regexOp the regex operator >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ */ >+ public void gdDragRowByValue(int mouseButton, String modifier, String col, >+ String colOperator, final String value, final String regexOp, >+ final String searchType) { >+ >+ final DragAndDropHelper dndHelper = DragAndDropHelper.getInstance(); >+ dndHelper.setModifier(modifier); >+ dndHelper.setMouseButton(mouseButton); >+ gdSelectRowByValue(col, colOperator, value, regexOp, 1, >+ CompSystemConstants.EXTEND_SELECTION_NO, searchType, 1); >+ pressOrReleaseModifiers(modifier, true); >+ getRobot().mousePress(null, null, mouseButton); >+ } >+ >+ /** >+ * Finds the first row which contains the value <code>value</code> >+ * in column <code>col</code> and drops on this row. >+ * >+ * @param col the column to select >+ * @param colOperator the column header operator >+ * @param value the value >+ * @param regexOp the regex operator >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ * @param delayBeforeDrop the amount of time (in milliseconds) to wait >+ * between moving the mouse to the drop point and >+ * releasing the mouse button >+ */ >+ public void gdDropRowByValue(String col, String colOperator, >+ final String value, final String regexOp, final String searchType, >+ int delayBeforeDrop) { >+ >+ final DragAndDropHelper dndHelper = DragAndDropHelper.getInstance(); >+ try { >+ gdSelectRowByValue(col, colOperator, value, regexOp, >+ CompSystemConstants.EXTEND_SELECTION_NO, >+ searchType, ClickOptions >+ .create().setClickCount(0)); >+ waitBeforeDrop(delayBeforeDrop); >+ } finally { >+ getRobot().mouseRelease(null, null, dndHelper.getMouseButton()); >+ pressOrReleaseModifiers(dndHelper.getModifier(), false); >+ } >+ } >+ >+ /** >+ * Finds the first column which contains the value <code>value</code> >+ * in the given row and drags the cell. >+ * >+ * @param mouseButton the mouse button >+ * @param modifier the modifiers >+ * @param row the row to select >+ * @param rowOperator the row header operator >+ * @param value the value >+ * @param regex search using regex >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ */ >+ public void gdDragCellByColValue(int mouseButton, String modifier, >+ String row, String rowOperator, final String value, >+ final String regex, final String searchType) { >+ >+ final DragAndDropHelper dndHelper = DragAndDropHelper.getInstance(); >+ dndHelper.setModifier(modifier); >+ dndHelper.setMouseButton(mouseButton); >+ >+ gdSelectCellByColValue(row, rowOperator, value, regex, >+ CompSystemConstants.EXTEND_SELECTION_NO, searchType, >+ ClickOptions.create().setClickCount(0)); >+ pressOrReleaseModifiers(modifier, true); >+ getRobot().mousePress(null, null, mouseButton); >+ } >+ >+ /** >+ * Finds the first column which contains the value <code>value</code> >+ * in the given row and drops on the cell. >+ * >+ * @param row the row to select >+ * @param rowOperator the row header operator >+ * @param value the value >+ * @param regex search using regex >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ * @param delayBeforeDrop the amount of time (in milliseconds) to wait >+ * between moving the mouse to the drop point and >+ * releasing the mouse button >+ */ >+ public void gdDropCellByColValue(String row, String rowOperator, >+ final String value, final String regex, final String searchType, >+ int delayBeforeDrop) { >+ >+ final DragAndDropHelper dndHelper = DragAndDropHelper.getInstance(); >+ try { >+ gdSelectCellByColValue(row, rowOperator, value, regex, >+ CompSystemConstants.EXTEND_SELECTION_NO, searchType, >+ ClickOptions.create().setClickCount(0)); >+ waitBeforeDrop(delayBeforeDrop); >+ } finally { >+ getRobot().mouseRelease(null, null, dndHelper.getMouseButton()); >+ pressOrReleaseModifiers(dndHelper.getModifier(), false); >+ } >+ } >+ >+ >+ /** >+ * Gets the text from the specific cell which is given >+ * by the row and the column. >+ * @param row the zero based index of the row >+ * @param column the zero based index of the column >+ * @return the text of the cell of the given coordinates >+ */ >+ private String getCellText(final int row, final int column) { >+ return getTableAdapter().getCellText(row, column); >+ >+ } >+ >+ /** >+ * Presses or releases the given modifier. >+ * @param modifier the modifier. >+ * @param press if true, the modifier will be pressed. >+ * if false, the modifier will be released. >+ */ >+ protected void pressOrReleaseModifiers(String modifier, boolean press) { >+ final IRobot robot = getRobot(); >+ final StringTokenizer modTok = new StringTokenizer( >+ KeyStrokeUtil.getModifierString(modifier), " "); //$NON-NLS-1$ >+ while (modTok.hasMoreTokens()) { >+ final String mod = modTok.nextToken(); >+ final int keyCode = getKeyCode(mod); >+ if (press) { >+ robot.keyPress(null, keyCode); >+ } else { >+ robot.keyRelease(null, keyCode); >+ } >+ } >+ } >+ >+ /** >+ * Gets the key code for a specific modifier >+ * @param mod the modifier >+ * @return the integer key code value >+ */ >+ protected abstract int getKeyCode(String mod); >+ >+ /** >+ * Checks whether <code>0 <= value < count</code>. >+ * @param value The value to check. >+ * @param count The upper bound. >+ */ >+ private void checkBounds(int value, int count) { >+ if (value < 0 || value >= count) { >+ throw new StepExecutionException("Invalid row/column: " + value, //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.INVALID_INDEX_OR_HEADER)); >+ } >+ } >+ >+ /** >+ * Checks if the passed row and column are inside the bounds of the Table. >+ * @param row The row >+ * @param column The column >+ * @throws StepExecutionException If the row or the column is outside of the Table's bounds. >+ */ >+ protected void checkRowColBounds(int row, int column) >+ throws StepExecutionException { >+ ITableAdapter adapter = getTableAdapter(); >+ checkBounds(row, adapter.getRowCount()); >+ >+ // Corner case: Only check the bounds if the table is not being >+ // used as a list or anything other than the first column >+ // is being checked. >+ int colCount = adapter.getColumnCount(); >+ if (colCount > 0 || column > 0) { >+ checkBounds(column, colCount); >+ } >+ } >+ >+ /** >+ * @param searchType Determines column where the search begins ("relative" or "absolute") >+ * @return The index from which to begin a search, based on the search type >+ * and (if appropriate) the currently selected cell. >+ */ >+ private int getStartingColIndex(String searchType) { >+ int startingIndex = 0; >+ if (searchType.equalsIgnoreCase( >+ CompSystemConstants.SEARCH_TYPE_RELATIVE)) { >+ startingIndex = getTableAdapter().getSelectedCell().getCol() + 1; >+ } >+ return startingIndex; >+ } >+ >+ /** >+ * @param searchType Determines the row where the search begins ("relative" or "absolute") >+ * @return The index from which to begin a search, based on the search type >+ * and (if appropriate) the currently selected cell. >+ */ >+ private int getStartingRowIndex(String searchType) { >+ int startingIndex = 0; >+ if (searchType.equalsIgnoreCase( >+ CompSystemConstants.SEARCH_TYPE_RELATIVE)) { >+ startingIndex = getTableAdapter().getSelectedCell().getRow() + 1; >+ } >+ return startingIndex; >+ } >+ >+ /** >+ * inputs/replaces the given text >+ * @param text the text to input >+ * @param replace wheter to replace or not >+ * @throws StepExecutionException If there is no selected cell, >+ * or if the cell is not editable, or if the table cell editor permits >+ * the text to be written. >+ */ >+ private void inputText(final String text, boolean replace) >+ throws StepExecutionException { >+ ITableAdapter adapter = getTableAdapter(); >+ >+ final Cell cell = adapter.getSelectedCell(); >+ // Ensure that the cell is visible. >+ Rectangle rectangle = >+ adapter.scrollCellToVisible(cell.getRow(), cell.getCol()); >+ >+ Object editor = activateEditor(cell, rectangle); >+ editor = setEditorToReplaceMode(editor, replace); >+ >+ getRobot().type(editor, text); >+ } >+ >+ /** >+ * @return true if the mouse pointer is over any cell, false otherwise. >+ */ >+ private boolean isMouseOverCell() { >+ try { >+ getCellAtMousePosition(); >+ } catch (StepExecutionException se) { >+ return false; >+ } >+ return true; >+ } >+ >+ /** >+ * Waits the given amount of time. Logs a drop-related error if interrupted. >+ * >+ * @param delayBeforeDrop the amount of time (in milliseconds) to wait >+ * between moving the mouse to the drop point and >+ * releasing the mouse button >+ */ >+ static void waitBeforeDrop(int delayBeforeDrop) { >+ TimeUtil.delay(delayBeforeDrop); >+ } >+ >+ /** >+ * Sets the specific editor to an replace mode. Means that the next key >+ * input will override the complete text of the editor. >+ * @param editor >+ * @param replace if <code>true</code> than the editor has to override >+ * the complete text with the next key input. Else the next >+ * key input will append to the end. >+ * @return the editor if it changed >+ */ >+ protected abstract Object setEditorToReplaceMode(Object editor, >+ boolean replace); >+ >+ /** >+ * Activates the editor of the specific cell. >+ * @param cell >+ * @param rectangle >+ * @return the editor of the cell >+ */ >+ protected abstract Object activateEditor(Cell cell, Rectangle rectangle); >+ >+ >+ /** >+ * Gets The modifier for an extended selection (more than one item) >+ * @return the modifier >+ */ >+ protected abstract int getExtendSelectionModifier(); >+ >+ /** >+ * @return the cell under the current mouse position. >+ * @throws StepExecutionException If no cell is found. >+ */ >+ protected abstract Cell getCellAtMousePosition() >+ throws StepExecutionException; >+ >+ /** >+ * Verifies if mouse is on header. >+ * @return true if mouse is on header >+ */ >+ protected abstract boolean isMouseOnHeader(); >+ >+ /** >+ * Selects the passed row of the JTable. This is actually a selection of the >+ * cell <code>(row, 0)</code>. >+ * >+ * @param row >+ * The row >+ * @param extendSelection Should this selection be part of a multiple selection >+ * @throws StepExecutionException >+ * If the row is invalid >+ * @deprecated the same as gdSelectCell >+ * Will be removed! >+ */ >+ public void gdSelectRow(int row, String extendSelection) >+ throws StepExecutionException { >+ // FIXME this is only here for testing purpose (to get all CaA tests running) >+ gdSelectCell(String.valueOf(row), MatchUtil.DEFAULT_OPERATOR, "1", //$NON-NLS-1$ >+ MatchUtil.DEFAULT_OPERATOR, >+ ClickOptions.create().setClickCount(1), extendSelection); >+ } >+ >+ /** >+ * Finds the first column which contains the value <code>value</code> >+ * in the given row and selects the cell. >+ * >+ * @param row the row >+ * @param value the value >+ * @param clickCount the mouse clicks. >+ * @param regex search using regex >+ * @param extendSelection Should this selection be part of a multiple selection >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ * @deprecated Will be removed with gdSelectCellByColValue with String parameter >+ * for Row/Column >+ */ >+ public void gdSelectCellByColValue(int row, final String value, >+ final String regex, int clickCount, final String extendSelection, >+ final String searchType) { >+ // FIXME this is only here for testing purpose (to get all CaA tests running) >+ gdSelectCellByColValue(String.valueOf(row), MatchUtil.DEFAULT_OPERATOR, >+ value, regex, clickCount, extendSelection, searchType, 1); >+ >+ } >+ >+ /** >+ * Finds the first row which contains the value <code>value</code> >+ * in column <code>col</code> and selects this row. >+ * @param col the column >+ * @param value the value >+ * @param clickCount the number of clicks. >+ * @param regexOp the regex operator >+ * @param extendSelection Should this selection be part of a multiple selection >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ * @deprecated Will be removed with gdSelectRowByValue with String parameter >+ * for Row/Column >+ */ >+ public void gdSelectRowByValue(int col, final String value, >+ int clickCount, final String regexOp, final String extendSelection, >+ final String searchType) { >+ // FIXME this is only here for testing purpose (to get all CaA tests running) >+ gdSelectRowByValue(String.valueOf(col), MatchUtil.DEFAULT_OPERATOR, >+ value, regexOp, clickCount, extendSelection, searchType, 1); >+ } >+} >\ No newline at end of file >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTextInputSupport.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTextInputSupport.java >new file mode 100644 >index 0000000..ba91ed6 >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTextInputSupport.java >@@ -0,0 +1,53 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.caps; >+ >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+ >+/** >+ * This class represents the general implmentation for components, >+ * which have text input support. >+ * >+ * @author BREDEX GmbH >+ */ >+public abstract class AbstractTextInputSupport extends AbstractTextVerifiable { >+ >+ /** >+ * Verifies the editable property of the current component.<br> >+ * If it is a complex component, it is always the selected object. >+ * @param editable The editable property to verify. >+ */ >+ public abstract void gdVerifyEditable(boolean editable); >+ // FIXME this is only a pattern because only Tables uses this at the moment >+ /** >+ * Types <code>text</code> into the component. This replaces the shown >+ * content.<br> >+ * If it is a complex component, it is always the selected object. >+ * @param text the text to type in >+ * @throws StepExecutionException >+ * If there is no selected cell, or if the cell is not editable, >+ * or if the table cell editor permits the text to be written. >+ */ >+ public abstract void gdReplaceText(String text) >+ throws StepExecutionException; >+ // FIXME this is only a pattern because only Tables uses this at the moment >+ /** >+ * Writes the passed text into the currently component.<br> >+ * If it is a complex component, it is always the selected object. >+ * @param text The text. >+ * @throws StepExecutionException >+ * If there is no selected cell, or if the cell is not editable, >+ * or if the table cell editor permits the text to be written. >+ */ >+ public abstract void gdInputText(final String text) >+ throws StepExecutionException; >+ // FIXME this is only a pattern because only Tables uses this at the moment >+} >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTextVerifiable.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTextVerifiable.java >new file mode 100644 >index 0000000..bac865d >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTextVerifiable.java >@@ -0,0 +1,43 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.caps; >+ >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+ >+/** >+ * This class represents the general implementation for components >+ * which have readable text. >+ * >+ * @author BREDEX GmbH >+ */ >+public abstract class AbstractTextVerifiable extends AbstractWidgetCAPs { >+ >+ /** >+ * Action to read the value of the current component >+ * to store it in a variable in the Client.<br> >+ * If it is a complex component, it is always the selected object. >+ * @param variable the name of the variable >+ * @return the text value. >+ */ >+ public abstract String gdReadValue(String variable); >+ // FIXME this is only a pattern because only Tables uses this at the moment >+ >+ /** >+ * Verifies the rendered text inside the currently component.<br> >+ * If it is a complex component, it is always the selected object. >+ * @param text The text to verify. >+ * @param operator The operation used to verify >+ * @throws StepExecutionException If the rendered text cannot be extracted. >+ */ >+ public abstract void gdVerifyText(String text, String operator) >+ throws StepExecutionException; >+ // FIXME this is only a pattern because only Tables uses this at the moment >+} >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTreeCAPs.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTreeCAPs.java >new file mode 100644 >index 0000000..b1e153b >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractTreeCAPs.java >@@ -0,0 +1,754 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.caps; >+ >+import java.util.Collection; >+import java.util.Iterator; >+ >+import org.apache.commons.lang.Validate; >+import org.eclipse.jubula.rc.common.CompSystemConstants; >+import org.eclipse.jubula.rc.common.driver.ClickOptions; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.exception.StepVerifyFailedException; >+import org.eclipse.jubula.rc.common.implclasses.IndexConverter; >+import org.eclipse.jubula.rc.common.implclasses.MatchUtil; >+import org.eclipse.jubula.rc.common.implclasses.Verifier; >+import org.eclipse.jubula.rc.common.implclasses.tree.AbstractTreeNodeTraverser; >+import org.eclipse.jubula.rc.common.implclasses.tree.AbstractTreeOperationContext; >+import org.eclipse.jubula.rc.common.implclasses.tree.ChildTraverser; >+import org.eclipse.jubula.rc.common.implclasses.tree.ExpandCollapseTreeNodeOperation; >+import org.eclipse.jubula.rc.common.implclasses.tree.INodePath; >+import org.eclipse.jubula.rc.common.implclasses.tree.IndexNodePath; >+import org.eclipse.jubula.rc.common.implclasses.tree.ParentTraverser; >+import org.eclipse.jubula.rc.common.implclasses.tree.PathBasedTraverser; >+import org.eclipse.jubula.rc.common.implclasses.tree.SelectTreeNodeOperation; >+import org.eclipse.jubula.rc.common.implclasses.tree.SiblingTraverser; >+import org.eclipse.jubula.rc.common.implclasses.tree.StringNodePath; >+import org.eclipse.jubula.rc.common.implclasses.tree.TreeNodeOperation; >+import org.eclipse.jubula.rc.common.implclasses.tree.TreeNodeOperationConstraint; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.ITreeAdapter; >+import org.eclipse.jubula.tools.constants.StringConstants; >+import org.eclipse.jubula.tools.constants.TestDataConstants; >+import org.eclipse.jubula.tools.objects.event.EventFactory; >+import org.eclipse.jubula.tools.objects.event.TestErrorEvent; >+import org.eclipse.jubula.tools.utils.StringParsing; >+ >+ >+/** >+ * General implementation for Trees. >+ * >+ * @author BREDEX GmbH >+ */ >+public abstract class AbstractTreeCAPs extends AbstractWidgetCAPs { >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String[] getTextArrayFromComponent() { >+ //FIXME is here an TextArray? >+ return null; >+ } >+ >+ /** >+ * This method is only casting the IComponentAdapter to the wanted ITreeAdapter >+ * @return The ITreeAdapter out of the stored IComponentAdapter >+ */ >+ private ITreeAdapter getTreeAdapter() { >+ return (ITreeAdapter)getComponent(); >+ >+ } >+ >+ /** >+ * Verifies the text of the Node at mousePosition >+ * @param text the text to check >+ * @param operator the operator for the verification >+ */ >+ public abstract void gdVerifyTextAtMousePosition( >+ String text, >+ String operator); >+ /** >+ * Splits the <code>treepath</code> string into an array, one entry for each level in the path >+ * >+ * @param treePath The tree path >+ * @return An array of string representing the tree path >+ */ >+ protected String[] splitTextTreePath(String treePath) { >+ return StringParsing.splitToArray(treePath, >+ TestDataConstants.PATH_CHAR_DEFAULT, >+ TestDataConstants.ESCAPE_CHAR_DEFAULT, >+ true); >+ } >+ >+ /** >+ * Splits the <code>treepath</code> string into an array, one entry for each level in the path >+ * >+ * @param treePath The tree path >+ * @return An array of indices (type <code>Integer</code>) representing >+ * the tree path >+ * @throws StepExecutionException >+ * If the values of the passed path cannot be parsed >+ */ >+ protected Integer[] splitIndexTreePath(String treePath) >+ throws StepExecutionException { >+ Integer[] indexPath = null; >+ String[] path = splitTextTreePath(treePath); >+ if (path != null) { >+ indexPath = new Integer[path.length]; >+ for (int i = 0; i < path.length; i++) { >+ indexPath[i] = new Integer(IndexConverter.intValue(path[i])); >+ } >+ } >+ return IndexConverter.toImplementationIndices(indexPath); >+ } >+ >+ /** >+ * Splits the <code>treepath</code> string into an array, one entry for each level in the path >+ * >+ * @param treePath The tree path >+ * @param operator The operator >+ * @return An array of string representing the tree path >+ */ >+ protected INodePath createStringNodePath(String [] treePath, >+ String operator) { >+ return new StringNodePath(treePath, operator); >+ } >+ >+ /** >+ * Splits the <code>treepath</code> string into an array, one entry for each level in the path >+ * >+ * @param treePath The tree path >+ * @return An array of string representing the tree path >+ */ >+ protected INodePath createIndexNodePath(Integer [] treePath) { >+ return new IndexNodePath(treePath); >+ } >+ >+ >+ /** >+ * Traverses the tree by searching for the nodes in the tree >+ * path entry and calling the given operation on each matching node. >+ * >+ * @param treePath The tree path. >+ * @param pathType For example, "relative" or "absolute". >+ * @param preAscend Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param operation The tree node operation. >+ * @throws StepExecutionException If the path traversion fails. >+ */ >+ protected void traverseTreeByPath(INodePath treePath, String pathType, >+ int preAscend, TreeNodeOperation operation) >+ throws StepExecutionException { >+ >+ Validate.notNull(treePath); >+ Validate.notNull(operation); >+ >+ ITreeAdapter adapter = getTreeAdapter(); >+ AbstractTreeOperationContext context = adapter.getContext(); >+ >+ AbstractTreeNodeTraverser traverser = >+ new PathBasedTraverser(context, treePath); >+ >+ traverser.traversePath(operation, >+ getStartNode(pathType, preAscend, context)); >+ >+ } >+ >+ /** >+ * Traverses the tree by searching for the nodes in the tree >+ * path entry and calling the given operation on the last element in the path. >+ * @param treePath The tree path. >+ * @param pathType For example, "relative" or "absolute". >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param operation The tree node operation. >+ * @throws StepExecutionException If the path traversion fails. >+ */ >+ protected void traverseLastElementByPath(INodePath treePath, >+ String pathType, int preAscend, TreeNodeOperation operation) >+ throws StepExecutionException { >+ >+ Validate.notNull(treePath); >+ Validate.notNull(operation); >+ >+ AbstractTreeOperationContext context = getTreeAdapter().getContext(); >+ Object startNode = getStartNode(pathType, preAscend, context); >+ >+ AbstractTreeNodeTraverser traverser = new PathBasedTraverser( >+ context, treePath, new TreeNodeOperationConstraint()); >+ >+ traverser.traversePath(operation, startNode); >+ } >+ >+ /** >+ * @param pathType pathType >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param objectPath objectPath >+ * @param co the click options to use >+ */ >+ private void selectByPath(String pathType, int preAscend, >+ INodePath objectPath, ClickOptions co) { >+ >+ TreeNodeOperation expOp = new ExpandCollapseTreeNodeOperation(false); >+ TreeNodeOperation selectOp = new SelectTreeNodeOperation(co); >+ INodePath subPath = objectPath.subPath(0, objectPath.getLength() - 1); >+ >+ traverseTreeByPath(subPath, pathType, preAscend, expOp); >+ traverseLastElementByPath(objectPath, pathType, preAscend, selectOp); >+ } >+ >+ /** >+ * Returns the selected node >+ * @param context context >+ * @return node >+ */ >+ protected Object getSelectedNode(AbstractTreeOperationContext context) { >+ return context.getSelectedNode(); >+ } >+ >+ /** >+ * Clicks the tree. >+ * If the mouse pointer is in the tree no mouse move will be perfomed. >+ * Otherwise, the mouse is first moved to the center of the tree. >+ * >+ * @param count Number of mouse clicks >+ * @param button Pressed button >+ */ >+ public void gdClick(int count, int button) { >+ if (getRobot().isMouseInComponent( >+ getTreeAdapter().getRealComponent())) { >+ getRobot().clickAtCurrentPosition( >+ getTreeAdapter().getRealComponent(), count, button); >+ } else { >+ getRobot().click(getTreeAdapter().getRealComponent(), null, >+ ClickOptions.create().setClickCount(count) >+ .setMouseButton(button)); >+ } >+ } >+ >+ /** >+ * Collapses the JTree. The passed tree path is a slash-seperated list of >+ * nodes that specifies a valid top-down path in the JTree. The last node of >+ * the tree path is collapsed if it is currently expanded. Otherwise, the JTree is >+ * left unchanged. >+ * >+ * @param pathType whether the path is relative or absolute >+ * @param preAscend Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param treePath The tree path. >+ * @param operator >+ * Whether regular expressions are used to determine the tree path. >+ * <code>"matches"</code> for regex, <code>"equals"</code> for simple matching. >+ * @throws StepExecutionException >+ * If the tree path is invalid or the double click to collapse >+ * the node fails. >+ */ >+ public void gdCollapse(String pathType, int preAscend, >+ String treePath, String operator) throws StepExecutionException { >+ traverseLastElementByPath( >+ createStringNodePath(splitTextTreePath(treePath), operator), >+ pathType, preAscend, >+ new ExpandCollapseTreeNodeOperation(true)); >+ } >+ >+ /** >+ * Collapses the tree. This method works like {@link #gdCollapse(String, int, String, String)}, >+ * but expects an enumeration of indices representing the top-down tree >+ * path. Any index is the node's position at the current tree level. >+ * >+ * @param pathType whether the path is relative or absolute >+ * @param preAscend Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param indexPath The index path >+ * @throws StepExecutionException >+ * If the tree path is invalid or the double-click to collapse >+ * the node fails. >+ */ >+ public void gdCollapseByIndices(String pathType, int preAscend, >+ String indexPath) throws StepExecutionException { >+ >+ try { >+ traverseLastElementByPath( >+ createIndexNodePath(splitIndexTreePath(indexPath)), >+ pathType, preAscend, >+ new ExpandCollapseTreeNodeOperation(true)); >+ } catch (NumberFormatException e) { >+ throw new StepExecutionException(e.getMessage(), EventFactory >+ .createActionError(TestErrorEvent.INVALID_INDEX)); >+ } >+ } >+ >+ /** >+ * <p> >+ * Expands the Tree. Any node defined by the passed tree path is expanded, >+ * if it is collapsed. The node is expanded by performing a double click >+ * onto the node. If the node is already expanded, the JTree is left >+ * unchanged. The tree path is a slash-seperated list of nodes that specifies >+ * a valid top-down path in the JTree. >+ * </p> >+ * >+ * An example: Say the passed tree path is <code>animals/birds/kakadu</code>. >+ * To get a valid expansion, the JTree has to look as follows: >+ * >+ * <pre> >+ * animals >+ * | >+ * - -- birds >+ * | >+ * - -- kakadu >+ * </pre> >+ * >+ * <code>animals</code> is the Tree's root node, if the root node has >+ * been set to visible, >+ * or it is one of the root node's children, if the root node has been set >+ * to invisible. >+ * >+ * <p> >+ * It is important to know that the tree path entries have to match the >+ * rendered node texts, but not the underlying user object data etc. >+ * </p> >+ * >+ * @param pathType whether the path is relative or absolute >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param treePath >+ * The tree path. >+ * @param operator >+ * If regular expressions are used to determine the tree path >+ * @throws StepExecutionException >+ * If the tree path is invalid or the double click fails. >+ */ >+ public void gdExpand(String pathType, int preAscend, >+ String treePath, String operator) throws StepExecutionException { >+ traverseTreeByPath( >+ createStringNodePath(splitTextTreePath(treePath), operator), >+ pathType, preAscend, >+ new ExpandCollapseTreeNodeOperation(false)); >+ } >+ >+ /** >+ * Expands the tree. This method works like {@link #gdExpand(String, int, String, String)}, but >+ * expects an enumeration of indices representing the top-down tree path. >+ * Any index is the node's position at the current tree level. >+ * >+ * @param pathType whether the path is relative or absolute >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param indexPath The index path >+ * @throws StepExecutionException >+ * If the tree path is invalid or the double-click fails. >+ */ >+ public void gdExpandByIndices(String pathType, int preAscend, >+ String indexPath) throws StepExecutionException { >+ >+ try { >+ traverseTreeByPath( >+ createIndexNodePath(splitIndexTreePath(indexPath)), >+ pathType, preAscend, >+ new ExpandCollapseTreeNodeOperation(false)); >+ } catch (NumberFormatException e) { >+ throw new StepExecutionException(e.getMessage(), EventFactory >+ .createActionError(TestErrorEvent.INVALID_INDEX)); >+ } >+ } >+ >+ >+ >+ /** >+ * Selects a node relative to the currently selected node. >+ * @param direction the direction to move. >+ * directions: >+ * UP - Navigates through parents >+ * DOWN - Navigates through children >+ * NEXT - Navigates to next sibling >+ * PREVIOUS - Navigates to previous sibling >+ * @param distance the distance to move >+ * @param clickCount the click count to select the new cell. >+ * @throws StepExecutionException if any error occurs >+ */ >+ public void gdMove(String direction, int distance, int clickCount) >+ throws StepExecutionException { >+ >+ AbstractTreeOperationContext context = getTreeAdapter().getContext(); >+ >+ Object selectedNode = getSelectedNode(context); >+ >+ TreeNodeOperation selectOp = >+ new SelectTreeNodeOperation( >+ ClickOptions.create().setClickCount(clickCount)); >+ TreeNodeOperationConstraint constraint = >+ new TreeNodeOperationConstraint(); >+ >+ if (CompSystemConstants.TREE_MOVE_UP.equalsIgnoreCase(direction)) { >+ AbstractTreeNodeTraverser traverser = >+ new ParentTraverser(context, distance, constraint); >+ traverser.traversePath(selectOp, selectedNode); >+ } else if (CompSystemConstants >+ .TREE_MOVE_DOWN.equalsIgnoreCase(direction)) { >+ TreeNodeOperation expandOp = >+ new ExpandCollapseTreeNodeOperation(false); >+ AbstractTreeNodeTraverser expandTraverser = >+ new ChildTraverser(context, distance - 1); >+ expandTraverser.traversePath(expandOp, selectedNode); >+ >+ AbstractTreeNodeTraverser selectTraverser = >+ new ChildTraverser(context, distance, constraint); >+ selectTraverser.traversePath(selectOp, selectedNode); >+ >+ } else if (CompSystemConstants >+ .TREE_MOVE_NEXT.equalsIgnoreCase(direction)) { >+ // Look through siblings >+ AbstractTreeNodeTraverser traverser = >+ new SiblingTraverser(context, distance, true, constraint); >+ traverser.traversePath(selectOp, selectedNode); >+ >+ } else if (CompSystemConstants >+ .TREE_MOVE_PREVIOUS.equalsIgnoreCase(direction)) { >+ // Look through siblings >+ AbstractTreeNodeTraverser traverser = >+ new SiblingTraverser(context, distance, false, constraint); >+ traverser.traversePath(selectOp, selectedNode); >+ } >+ >+ } >+ >+ /** >+ * Selects the node at the end of the <code>treepath</code>. >+ * >+ * @param pathType whether the path is relative or absolute >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param treePath The tree path. >+ * @param operator If regular expressions are used to match the tree path >+ * @param clickCount the click count >+ * @param button what mouse button should be used >+ * @param extendSelection Whether this selection extends a previous >+ * selection. >+ * @throws StepExecutionException If the tree path is invalid, if the >+ * double-click to expand the node fails, or if the selection is invalid. >+ */ >+ public void gdSelect(String pathType, int preAscend, String treePath, >+ String operator, int clickCount, int button, >+ final String extendSelection) >+ throws StepExecutionException { >+ selectByPath(pathType, preAscend, >+ createStringNodePath(splitTextTreePath(treePath), operator), >+ ClickOptions.create() >+ .setClickCount(clickCount) >+ .setMouseButton(button) >+ .setClickModifier(getClickModifier(extendSelection))); >+ } >+ /** >+ * Selects the last node of the path given by <code>indexPath</code> >+ * @param pathType whether the path is relative or absolute >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param indexPath the index path >+ * @param clickCount the number of times to click >+ * @param button what mouse button should be used >+ * @param extendSelection Whether this selection extends a previous >+ * selection. >+ * @throws StepExecutionException if <code>indexPath</code> is not a valid >+ * path >+ */ >+ public void gdSelectByIndices(String pathType, int preAscend, >+ String indexPath, int clickCount, int button, >+ final String extendSelection) >+ throws StepExecutionException { >+ >+ selectByPath(pathType, preAscend, >+ createIndexNodePath(splitIndexTreePath(indexPath)), >+ ClickOptions.create() >+ .setClickCount(clickCount) >+ .setMouseButton(button) >+ .setClickModifier(getClickModifier(extendSelection))); >+ } >+ >+ /** >+ * Tests whether the given treePath exists or not >+ * @param pathType whether the path is relative or absolute >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param treePath the path to check >+ * @param operator the RegEx operator >+ * @param exists if true, the verify succeeds if the path DOES exist. >+ * If false, the verify succeeds if the path DOES NOT exist. >+ */ >+ public void gdVerifyPath(String pathType, int preAscend, >+ String treePath, String operator, boolean exists) { >+ try { >+ gdExpand(pathType, preAscend, treePath, operator); >+ } catch (StepExecutionException e) { >+ if (exists) { >+ throw new StepVerifyFailedException( >+ "Verify failed on tree-path: " //$NON-NLS-1$ >+ + treePath, EventFactory.createVerifyFailed( >+ treePath, StringConstants.EMPTY)); >+ } >+ return; >+ } >+ if (!exists) { >+ throw new StepVerifyFailedException("Verify failed on tree-path: ", //$NON-NLS-1$ >+ EventFactory.createVerifyFailed( >+ StringConstants.EMPTY, treePath)); >+ } >+ } >+ >+ /** >+ * Tests whether the given treePath exists or not >+ * @param pathType whether the path is relative or absolute >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param treePath the path to check >+ * @param exists if true, the verify succeeds if the path DOES exist. >+ * If false, the verify succeeds if the path DOES NOT exist. >+ */ >+ public void gdVerifyPathByIndices(String pathType, int preAscend, >+ String treePath, boolean exists) { >+ try { >+ gdExpandByIndices(pathType, preAscend, treePath); >+ } catch (StepExecutionException e) { >+ if (exists) { >+ throw new StepVerifyFailedException("Verify failed on tree-path: " //$NON-NLS-1$ >+ + treePath, >+ EventFactory.createVerifyFailed(treePath, >+ StringConstants.EMPTY)); >+ } >+ return; >+ } >+ if (!exists) { >+ throw new StepVerifyFailedException("Verify failed on tree-path: ", //$NON-NLS-1$ >+ EventFactory.createVerifyFailed( >+ StringConstants.EMPTY, treePath)); >+ } >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String gdStoreSelectedNodeValue(String variable) { >+ AbstractTreeOperationContext context = getTreeAdapter().getContext(); >+ Object selectedNode = >+ getSelectedNode(context); >+ if (selectedNode == null) { >+ throw new StepExecutionException("No tree item selected", //$NON-NLS-1$ >+ EventFactory.createActionError(TestErrorEvent.NO_SELECTION)); >+ } >+ >+ return context.getRenderedText(selectedNode); >+ } >+ >+ /** >+ * Returns the text from the mouse position. >+ * @param variable - >+ * @return the text from the node at mouse position >+ */ >+ public String gdStoreValueAtMousePosition(String variable) { >+ AbstractTreeOperationContext context = getTreeAdapter().getContext(); >+ >+ return context.getRenderedText(getNodeAtMousePosition()); >+ } >+ /** >+ * >+ * @return the tree node at the current mouse position. >+ * @throws StepExecutionException If no tree node can be found at the >+ * current mouse position. >+ */ >+ protected abstract Object getNodeAtMousePosition() >+ throws StepExecutionException; >+ >+ /** >+ * Verifies whether the first selection in the tree has a rendered text that is >+ * equal to <code>selection</code>. >+ * >+ * @param selection >+ * The selection to verify >+ * @throws StepExecutionException >+ * If no node is selected or the verification fails. >+ */ >+ public void gdVerifySelectedValue(String selection) >+ throws StepExecutionException { >+ gdVerifySelectedValue(selection, MatchUtil.DEFAULT_OPERATOR); >+ } >+ >+ /** >+ * Verifies whether the first selection in the tree has a rendered text that is >+ * equal to <code>pattern</code>. >+ * >+ * @param pattern >+ * The expected text >+ * @param operator >+ * The operator to use when comparing the expected and >+ * actual values. >+ * @throws StepExecutionException >+ * If no node is selected or the verification fails. >+ */ >+ public void gdVerifySelectedValue(String pattern, String operator) >+ throws StepExecutionException { >+ >+ AbstractTreeOperationContext context = getTreeAdapter().getContext(); >+ checkNodeText(getSelectedNode(context), pattern, operator); >+ } >+ >+ >+ >+ /** >+ * Checks the text for the given node against the given pattern and >+ * operator. >+ * >+ * @param node The node containing the text to check. >+ * @param pattern The expected text. >+ * @param operator The operator to use when comparing the expected and >+ * actual values. >+ * @throws StepVerifyFailedException If the verification fails. >+ */ >+ protected void checkNodeText(Object node, String pattern, String operator) >+ throws StepVerifyFailedException { >+ >+ AbstractTreeOperationContext context = getTreeAdapter().getContext(); >+ Collection nodeTextList = context.getNodeTextList(node); >+ Iterator it = nodeTextList.iterator(); >+ boolean isMatched = false; >+ while (it.hasNext() && !isMatched) { >+ try { >+ Verifier.match((String)it.next(), pattern, operator); >+ isMatched = true; >+ } catch (StepVerifyFailedException svfe) { >+ if (!it.hasNext()) { >+ throw svfe; >+ } >+ // Otherwise just try the next element >+ } >+ } >+ } >+ >+ /** >+ * @param pathType For example, "relative" or "absolute". >+ * @param preAscend Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param context The context of the traversal. >+ * @return The node at which to begin the traversal or <code>null</code> >+ * if the traversal should begin at the root of the node. >+ */ >+ protected Object getStartNode(String pathType, int preAscend, >+ AbstractTreeOperationContext context) { >+ Object startNode; >+ ITreeAdapter tree = getTreeAdapter(); >+ if (pathType.equals( >+ CompSystemConstants.TREE_PATH_TYPE_RELATIVE)) { >+ startNode = getSelectedNode(context); >+ Object child = startNode; >+ for (int i = 0; i < preAscend; ++i) { >+ if ((startNode == null) || ((tree.isRootVisible()) >+ && (tree.getRootNode() == null))) { >+ TestErrorEvent event = EventFactory >+ .createActionError(TestErrorEvent.TREE_NODE_NOT_FOUND); >+ throw new StepExecutionException( >+ "Tree node not found: Parent of " //$NON-NLS-1$ >+ + child.toString(), event); >+ } >+ child = startNode; >+ startNode = context.getParent(startNode); >+ >+ } >+ // Extra handling for tree without visible root node >+ if ((startNode == null) || ((tree.isRootVisible()) >+ && (tree.getRootNode() == null))) { >+ startNode = null; >+ } >+ } else if (pathType.equals( >+ CompSystemConstants.TREE_PATH_TYPE_ABSOLUTE)) { >+ startNode = null; >+ } else { >+ throw new StepExecutionException( >+ pathType + " is not a valid Path Type", EventFactory //$NON-NLS-1$ >+ .createActionError(TestErrorEvent.INVALID_PARAM_VALUE)); >+ >+ } >+ >+ return startNode; >+ } >+ >+ /** >+ * @param mouseButton mouseButton >+ * @param modifierSpecification modifierSpecification >+ * @param pathType pathType >+ * @param preAscend preAscend >+ * @param treeTextPath treeTextPath >+ * @param operator operator */ >+ public abstract void gdDragByTextPath( >+ int mouseButton, >+ String modifierSpecification, >+ String pathType, >+ int preAscend, >+ String treeTextPath, >+ String operator); >+ >+ /** >+ * @param pathType pathType >+ * @param preAscend preAscend >+ * @param treeTextPath treeTextPath >+ * @param operator operator >+ * @param delayBeforeDrop delayBeforeDrop */ >+ public abstract void gdDropByTextPath( >+ String pathType, >+ int preAscend, >+ String treeTextPath, >+ String operator, >+ int delayBeforeDrop); >+ >+ /** >+ * @param mouseButton mouseButton >+ * @param modifierSpecification modifierSpecification >+ * @param pathType pathType >+ * @param preAscend preAscend >+ * @param treeIndexPath treeIndexPath */ >+ public abstract void gdDragByIndexPath( >+ int mouseButton, >+ String modifierSpecification, >+ String pathType, >+ int preAscend, >+ String treeIndexPath); >+ >+ /** >+ * @param pathType pathType >+ * @param preAscend preAscend >+ * @param treeIndexPath treeIndexPath >+ * @param delayBeforeDrop delayBeforeDrop */ >+ public abstract void gdDropByIndexPath( >+ String pathType, >+ int preAscend, >+ String treeIndexPath, >+ int delayBeforeDrop); >+ >+ >+ >+} >\ No newline at end of file >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractUICAPs.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractUICAPs.java >new file mode 100644 >index 0000000..f1aa6a5 >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractUICAPs.java >@@ -0,0 +1,78 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.caps; >+ >+ >+import org.eclipse.jubula.rc.common.AUTServer; >+import org.eclipse.jubula.rc.common.driver.IRobot; >+import org.eclipse.jubula.rc.common.driver.IRobotFactory; >+import org.eclipse.jubula.rc.common.exception.RobotException; >+import org.eclipse.jubula.rc.common.implclasses.IBaseImplementationClass; >+import org.eclipse.jubula.rc.common.uiadapter.factory.GUIAdapterFactoryRegistry; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IComponentAdapter; >+/** >+ * Implementation of basic functions for all tester classes. This class >+ * gives the basic functions which are needed for testing. >+ * >+ * >+ * @author BREDEX GmbH >+ */ >+public abstract class AbstractUICAPs implements IBaseImplementationClass { >+ >+ >+ >+ /** constants for communication */ >+ protected static final String POS_UNIT_PIXEL = "Pixel"; //$NON-NLS-1$ >+ >+ /** constants for communication */ >+ protected static final String POS_UNI_PERCENT = "Percent"; //$NON-NLS-1$ >+ /** */ >+ private IComponentAdapter m_component; >+ >+ >+ /** >+ * Gets the Robot. >+ * @return The Robot >+ * @throws RobotException If the Robot cannot be created. >+ */ >+ protected IRobot getRobot() throws RobotException { >+ return AUTServer.getInstance().getRobot(); >+ } >+ /** >+ * Gets the Robot factory. The factory is created once per instance. >+ * @return The Robot factory. >+ */ >+ protected abstract IRobotFactory getRobotFactory(); >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void setComponent(Object graphicsComponent) { >+ GUIAdapterFactoryRegistry afr = GUIAdapterFactoryRegistry.getInstance(); >+ m_component = null; >+ IComponentAdapter adapter = >+ (IComponentAdapter)afr.getAdapter(graphicsComponent); >+ m_component = adapter; >+ } >+ /** >+ * Getter for the stored GraphicalComponent >+ * @return gets the stored IComponentAdapter >+ */ >+ public IComponentAdapter getComponent() { >+ return m_component; >+ } >+ >+ >+ >+ >+ >+ >+} >\ No newline at end of file >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractWidgetCAPs.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractWidgetCAPs.java >new file mode 100644 >index 0000000..b6c9ea4 >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/caps/AbstractWidgetCAPs.java >@@ -0,0 +1,486 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.caps; >+ >+import org.eclipse.jubula.rc.common.CompSystemConstants; >+import org.eclipse.jubula.rc.common.driver.ClickOptions; >+import org.eclipse.jubula.rc.common.driver.ClickOptions.ClickModifier; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.implclasses.Verifier; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IWidgetAdapter; >+/** >+ * Implementation of basic functions for a lot of graphics components >+ * except for context menus and menus. >+ * >+ * @author BREDEX GmbH >+ */ >+public abstract class AbstractWidgetCAPs extends AbstractUICAPs { >+ >+ >+ /** >+ * Casts the IComponentAdapter to an IWidgetAdapter for better access >+ * @return The widgetAdapter >+ */ >+ private IWidgetAdapter getWidgetAdapter() { >+ return (IWidgetAdapter) getComponent(); >+ } >+ >+ /** >+ * Verifies that the component exists and is visible. >+ * >+ * @param exists <code>True</code> if the component is expected to exist >+ * and be visible, otherwise <code>false</code>. >+ */ >+ public void gdVerifyExists(boolean exists) { >+ Verifier.equals(exists, getWidgetAdapter().isShowing()); >+ } >+ >+ >+ /** >+ * Verifies if the component has the focus. >+ * @param hasFocus <code>True</code> if the component is expected to has >+ * the focus, otherwise <code>false</code> >+ */ >+ public void gdVerifyFocus(boolean hasFocus) { >+ Verifier.equals(hasFocus, getWidgetAdapter().hasFocus()); >+ } >+ /** >+ * Verifies if the component is enabled >+ * @param enabled <code>True</code> if the component is expected to be >+ * enabled, otherwise <code>false</code> >+ */ >+ public void gdVerifyEnabled(boolean enabled) { >+ Verifier.equals(enabled, getWidgetAdapter().isEnabled()); >+ } >+ >+ /** >+ * Verifies the value of the property with the name <code>name</code>. >+ * The name of the property has be specified according to the JavaBean >+ * specification. The value returned by the property is converted into a >+ * string by calling <code>toString()</code> and is compared to the passed >+ * <code>value</code>. >+ * >+ * @param name The name of the property >+ * @param value The value of the property as a string >+ * @param operator The operator used to verify >+ */ >+ public void gdVerifyProperty(final String name, String value, >+ String operator) { >+ >+ final IWidgetAdapter bean = (IWidgetAdapter) getComponent(); >+ bean.getPropteryValue(name); >+ >+ final String propToStr = bean.getPropteryValue(name); >+ Verifier.match(propToStr, value, operator); >+ } >+ >+ >+ /** >+ * Clicks the center of the component. >+ * @param count Number of mouse clicks >+ * @param button Pressed button >+ */ >+ public void gdClick(int count, int button) { >+ getRobot().click(getComponent().getRealComponent(), null, >+ ClickOptions.create() >+ .setClickCount(count) >+ .setMouseButton(button)); >+ } >+ /** >+ * clicks into a component. >+ * >+ * @param count amount of clicks >+ * @param button what mouse button should be used >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @throws StepExecutionException error >+ */ >+ public void gdClickDirect(int count, int button, int xPos, String xUnits, >+ int yPos, String yUnits) throws StepExecutionException { >+ >+ getRobot().click(getComponent().getRealComponent(), null, >+ ClickOptions.create() >+ .setClickCount(count) >+ .setMouseButton(button), >+ xPos, xUnits.equalsIgnoreCase(POS_UNIT_PIXEL), >+ yPos, yUnits.equalsIgnoreCase(POS_UNIT_PIXEL)); >+ } >+ >+ /** >+ * Performs a Drag. Moves into the middle of the Component and presses and >+ * holds the given modifier and the given mouse button. >+ * @param mouseButton the mouse button. >+ * @param modifier the modifier, e.g. shift, ctrl, etc. >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ */ >+ public void gdDrag(int mouseButton, String modifier, int xPos, >+ String xUnits, int yPos, String yUnits) { >+ getWidgetAdapter().gdDrag(mouseButton, modifier, xPos, xUnits, >+ yPos, yUnits); >+ } >+ >+ >+ /** >+ * Performs a Drop. Moves into the middle of the Component and releases >+ * the modifier and mouse button pressed by gdDrag. >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param delayBeforeDrop the amount of time (in milliseconds) to wait >+ * between moving the mouse to the drop point and >+ * releasing the mouse button >+ */ >+ public void gdDrop(int xPos, String xUnits, int yPos, String yUnits, >+ int delayBeforeDrop) { >+ >+ getWidgetAdapter().gdDrop(xPos, xUnits, yPos, yUnits, >+ delayBeforeDrop); >+ } >+ >+ /** >+ * dummy method for "wait for component" >+ * @param timeout the maximum amount of time to wait for the component >+ * @param delay the time to wait after the component is found >+ * {@inheritDoc} >+ */ >+ public void gdWaitForComponent (int timeout, int delay) { >+ // do NOT delete this method! >+ // do nothing, implementation is in class CAPTestCommand.getImplClass >+ // because this action needs a special implementation! >+ } >+ >+ /** >+ * Stores the value of the property with the name <code>name</code>. >+ * The name of the property has be specified according to the JavaBean >+ * specification. The value returned by the property is converted into a >+ * string by calling <code>toString()</code> and is stored to the passed >+ * variable. >+ * >+ * @param variableName The name of the variable to store the property value in >+ * @param propertyName The name of the property >+ * @return the property value. >+ */ >+ public String gdStorePropertyValue(String variableName, >+ final String propertyName) { >+ IWidgetAdapter bean = (IWidgetAdapter) getComponent(); >+ >+ return bean.getPropteryValue(propertyName); >+ } >+ >+ /** >+ * Select an item in the popup menu >+ * @param indexPath path of item indices >+ * @param button MouseButton >+ * @throws StepExecutionException error >+ */ >+ public void gdPopupSelectByIndexPath(String indexPath, int button) >+ throws StepExecutionException { >+ >+ AbstractMenuCAPs popup = getWidgetAdapter().showPopup(button); >+ popup.selectMenuItemByIndexpath(indexPath); >+ } >+ /** >+ * Selects an item in the popup menu >+ * @param textPath path of item texts >+ * @param operator operator used for matching >+ * @param button MouseButton >+ * @throws StepExecutionException error >+ */ >+ public void gdPopupSelectByTextPath(String textPath, String operator, >+ int button) >+ throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter().showPopup(button); >+ popup.selectMenuItem(textPath, operator); >+ } >+ /** >+ * Selects an item in the popup menu >+ * >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param textPath path of item texts >+ * @param operator operator used for matching >+ * @param button MouseButton >+ * @throws StepExecutionException error >+ */ >+ public void gdPopupSelectByTextPath(final int xPos, final String xUnits, >+ final int yPos, final String yUnits, >+ String textPath, String operator, int button) >+ throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter() >+ .showPopup(xPos, xUnits, yPos, yUnits, button); >+ popup.selectMenuItem(textPath, operator); >+ } >+ >+ /** >+ * Opens the popup menu at the given position relative the current component >+ * and selects an item at the given position in the popup menu >+ * >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param indexPath path of item indices >+ * @param button MouseButton >+ * @throws StepExecutionException error >+ */ >+ public void gdPopupSelectByIndexPath( >+ int xPos, String xUnits, int yPos, String yUnits, >+ String indexPath, int button) throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter().showPopup(button); >+ popup.selectMenuItemByIndexpath(indexPath); >+ } >+ >+ /** >+ * Checks if the specified context menu entry is enabled. >+ * @param indexPath the menu item to verify >+ * @param enabled for checking enabled or disabled >+ * @param button MouseButton >+ */ >+ public void gdPopupVerifyEnabledByIndexPath(String indexPath, >+ boolean enabled, int button) >+ throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter().showPopup(button); >+ popup.verifyEnabledByIndexpath(indexPath, enabled); >+ } >+ >+ >+ /** >+ * Opens the popup menu at the given position relative the current component >+ * and checks if the specified context menu entry is enabled. >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param indexPath the menu item to verify >+ * @param enabled for checking enabled or disabled >+ * @param button MouseButton >+ */ >+ public void gdPopupVerifyEnabledByIndexPath(int xPos, String xUnits, >+ int yPos, String yUnits, String indexPath, >+ boolean enabled, int button) throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter() >+ .showPopup(xPos, xUnits, yPos, yUnits, button); >+ popup.verifyEnabledByIndexpath(indexPath, enabled); >+ } >+ >+ /** >+ * Checks if the specified context menu entry is enabled. >+ * @param textPath the menu item to verify >+ * @param operator operator used for matching >+ * @param enabled for checking enabled or disabled >+ * @param button MouseButton >+ */ >+ public void gdPopupVerifyEnabledByTextPath(String textPath, >+ String operator, boolean enabled, int button) >+ throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter().showPopup(button); >+ popup.verifyEnabled(textPath, operator, enabled); >+ } >+ >+ /** >+ * Opens the popup menu at the given position relative the current component >+ * and checks if the specified context menu entry is enabled. >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param textPath the menu item to verify >+ * @param operator operator used for matching >+ * @param enabled for checking enabled or disabled >+ * @param button MouseButton >+ */ >+ public void gdPopupVerifyEnabledByTextPath(final int xPos, >+ final String xUnits, final int yPos, >+ final String yUnits, String textPath, String operator, >+ boolean enabled, int button) >+ throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter() >+ .showPopup(xPos, xUnits, yPos, yUnits, button); >+ popup.verifyEnabled(textPath, operator, enabled); >+ } >+ >+ /** >+ * Checks if the specified context menu entry is selected. >+ * @param indexPath the menu item to verify >+ * @param selected for checking if entry is selected >+ * @param button MouseButton >+ */ >+ public void gdPopupVerifySelectedByIndexPath(String indexPath, >+ boolean selected, int button) >+ throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter().showPopup(button); >+ popup.verifySelectedByIndexpath(indexPath, selected); >+ } >+ >+ /** >+ * Opens the popup menu at the given position relative the current component >+ * and checks if the specified context menu entry is selected. >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param indexPath the menu item to verify >+ * @param selected for checking if entry is selected >+ * @param button MouseButton >+ */ >+ public void gdPopupVerifySelectedByIndexPath(int xPos, String xUnits, >+ int yPos, String yUnits, String indexPath, boolean selected, >+ int button) throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter() >+ .showPopup(xPos, xUnits, yPos, yUnits, button); >+ popup.verifySelectedByIndexpath(indexPath, selected); >+ } >+ >+ /** >+ * Checks if the specified context menu entry is selected. >+ * @param textPath the menu item to verify >+ * @param operator operator used for matching >+ * @param selected for checking if entry is selected >+ * @param button MouseButton >+ */ >+ public void gdPopupVerifySelectedByTextPath(String textPath, >+ String operator, boolean selected, int button) >+ throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter().showPopup(button); >+ popup.verifySelected(textPath, operator, selected); >+ } >+ >+ /** >+ * Opens the popup menu at the given position relative the current component >+ * and checks if the specified context menu entry is selected. >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param textPath the menu item to verify >+ * @param operator operator used for matching >+ * @param selected for checking if entry is selected >+ * @param button MouseButton >+ */ >+ public void gdPopupVerifySelectedByTextPath(final int xPos, >+ final String xUnits, final int yPos, >+ final String yUnits, String textPath, String operator, >+ boolean selected, int button) >+ throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter() >+ .showPopup(xPos, xUnits, yPos, yUnits, button); >+ popup.verifySelected(textPath, operator, selected); >+ } >+ >+ /** >+ * Checks if the specified context menu entry exists. >+ * @param indexPath the menu item to verify >+ * @param exists for checking if entry exists >+ * @param button MouseButton >+ */ >+ public void gdPopupVerifyExistsByIndexPath(String indexPath, >+ boolean exists, int button) >+ throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter().showPopup(button); >+ popup.verifyExistsByIndexpath(indexPath, exists); >+ } >+ >+ /** >+ * Opens the popup menu at the given position relative the current component >+ * and checks if the specified context menu entry exists. >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param indexPath the menu item to verify >+ * @param exists for checking if entry exists >+ * @param button MouseButton >+ */ >+ public void gdPopupVerifyExistsByIndexPath(int xPos, String xUnits, >+ int yPos, String yUnits, String indexPath, >+ boolean exists, int button) throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter() >+ .showPopup(xPos, xUnits, yPos, yUnits, button); >+ popup.verifyExistsByIndexpath(indexPath, exists); >+ } >+ >+ /** >+ * Checks if the specified context menu entry exists. >+ * @param textPath the menu item to verify >+ * @param operator operator used for matching >+ * @param exists for checking if entry exists >+ * @param button MouseButton >+ */ >+ public void gdPopupVerifyExistsByTextPath(String textPath, >+ String operator, boolean exists, int button) >+ throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter().showPopup(button); >+ popup.verifyExists(textPath, operator, exists); >+ } >+ >+ /** >+ * Opens the popup menu at the given position relative the current component >+ * and checks if the specified context menu entry exists. >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param textPath the menu item to verify >+ * @param operator operator used for matching >+ * @param exists for checking if entry exists >+ * @param button MouseButton >+ */ >+ public void gdPopupVerifyExistsByTextPath(final int xPos, >+ final String xUnits, final int yPos, >+ final String yUnits, String textPath, String operator, >+ boolean exists, int button) >+ throws StepExecutionException { >+ AbstractMenuCAPs popup = getWidgetAdapter() >+ .showPopup(xPos, xUnits, yPos, yUnits, button); >+ popup.verifyExists(textPath, operator, exists); >+ } >+ /** >+ * >+ * @param extendSelection >+ * the string to indicate that the selection should be extended >+ * @return a ClickModifier for the given extend selection >+ */ >+ protected ClickModifier getClickModifier(String extendSelection) { >+ // FIXME This is a method which belongs in an upper class >+ >+ ClickModifier cm = ClickModifier.create(); >+ if (CompSystemConstants.EXTEND_SELECTION_YES >+ .equalsIgnoreCase(extendSelection)) { >+ cm.add(ClickModifier.M1); >+ } >+ return cm; >+ } >+ >+ /** >+ * Simulates a tooltip for demonstration purposes. >+ * >+ * @param text The text to show in the tooltip >+ * @param textSize The size of the text in points >+ * @param timePerWord The amount of time, in milliseconds, used to display a >+ * single word. A word is defined as a string surrounded >+ * by whitespace. >+ * @param windowWidth The width of the tooltip window in pixels. >+ */ >+ public void gdShowText(final String text, final int textSize, >+ final int timePerWord, final int windowWidth) { >+ getWidgetAdapter().showToolTip(text, textSize, >+ timePerWord, windowWidth); >+ } >+ >+} >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/driver/DragAndDropHelper.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/driver/DragAndDropHelper.java >index 4b4105f..c36b013 100644 >--- a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/driver/DragAndDropHelper.java >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/driver/DragAndDropHelper.java >@@ -30,6 +30,10 @@ public class DragAndDropHelper { > /** Flag if the Mouse is in drag mode (pressed key) */ > private boolean m_isDragMode = false; > >+ /** The Component to drag */ >+ private Object m_dragComponent = null; >+ >+ > /** > * hidden singleton constructor. > */ >@@ -92,4 +96,18 @@ public class DragAndDropHelper { > m_isDragMode = drag; > } > >+ /** >+ * @return the dragComponent >+ */ >+ public Object getDragComponent() { >+ return m_dragComponent; >+ } >+ >+ /** >+ * @param dragComponent the dragComponent to set >+ */ >+ public void setDragComponent(Object dragComponent) { >+ m_dragComponent = dragComponent; >+ } >+ > } >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/factory/GUIAdapterFactoryRegistry.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/factory/GUIAdapterFactoryRegistry.java >new file mode 100644 >index 0000000..c75e1bd >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/factory/GUIAdapterFactoryRegistry.java >@@ -0,0 +1,99 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.uiadapter.factory; >+ >+import java.util.HashMap; >+import java.util.Map; >+ >+import org.eclipse.jubula.rc.common.adaptable.IAdapterFactory; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IComponentAdapter; >+/** >+ * This factory registry holds all the toolkit specific factory's. >+ * These factory's holding the classes which are implementing the component >+ * specific interface. It could be an adapter or the specific component >+ * implementing the interface. >+ * >+ * You must register a factory before a test is started. >+ * @author BREDEX GmbH >+ * >+ */ >+public class GUIAdapterFactoryRegistry { >+ >+ /** >+ * Singleton instance of this class >+ */ >+ private static GUIAdapterFactoryRegistry instance = >+ new GUIAdapterFactoryRegistry(); >+ >+ /** >+ * Map that manages the registration. Key is always a class Value is a >+ * collection of IAdapterFactory >+ */ >+ private Map m_registrationMap = new HashMap(); >+ >+ /** >+ * Call Constructor only by using getInstance >+ */ >+ private GUIAdapterFactoryRegistry() { >+ } >+ >+ /** >+ * Return the singleton of this class >+ * >+ * @return singleton >+ */ >+ public static GUIAdapterFactoryRegistry getInstance() { >+ return instance; >+ } >+ >+ /** >+ * Register adapter factory with all its supported classes >+ * >+ * @param factory >+ * adapter factory that should be registered >+ */ >+ public void registerFactory(IUIAdapterFactory factory) { >+ Class[] supportedClasses = factory.getSupportedClasses(); >+ for (int i = 0; i < supportedClasses.length; i++) { >+ m_registrationMap.put(supportedClasses[i], factory); >+ } >+ } >+ >+ /** >+ * Sign off adapter factory from all its supported classes >+ * >+ * @param factory >+ * adapter factory that should be signed off >+ */ >+ public void signOffFactory(IAdapterFactory factory) { >+ Class[] supportedClasses = factory.getSupportedClasses(); >+ for (int i = 0; i < supportedClasses.length; i++) { >+ m_registrationMap.remove(supportedClasses[i]); >+ } >+ } >+ /** >+ * >+ * @param objectToAdapt >+ * @return - >+ */ >+ public IComponentAdapter getAdapter(Object objectToAdapt) { >+ Class adapteeclass = objectToAdapt.getClass(); >+ IUIAdapterFactory factory = (IUIAdapterFactory) m_registrationMap. >+ get(adapteeclass); >+ while (factory == null && adapteeclass != Object.class) { >+ factory = (IUIAdapterFactory) m_registrationMap. >+ get(adapteeclass.getSuperclass()); >+ } >+ >+ return factory.getAdapter(objectToAdapt); >+ >+ } >+} >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/factory/IUIAdapterFactory.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/factory/IUIAdapterFactory.java >new file mode 100644 >index 0000000..4d16650 >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/factory/IUIAdapterFactory.java >@@ -0,0 +1,36 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.uiadapter.factory; >+ >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IComponentAdapter; >+ >+/** >+ * This is the interface for the factory which is used by the >+ * <code>AbstractUI</code> to get the specific Object which implements the >+ * corresponding interface for the tester class. >+ * >+ * @author BREDEX GmbH >+ */ >+public interface IUIAdapterFactory { >+ /** >+ * @return all classes that will be supported by this adapter factory >+ */ >+ Class[] getSupportedClasses(); >+ >+ /** >+ * Adapts object to adapt to a new object of type targetAdapterClass >+ * >+ * @param objectToAdapt >+ * object that should be adapted >+ * @return the adapter for the object to adapt of type targetAdapterClass >+ */ >+ IComponentAdapter getAdapter(Object objectToAdapt); >+} >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IButtonAdapter.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IButtonAdapter.java >new file mode 100644 >index 0000000..3bd260c >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IButtonAdapter.java >@@ -0,0 +1,41 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.uiadapter.interfaces; >+ >+/** >+ * Interface for all necessary methods to test buttons. >+ * It extends the <code>IWidgetAdapter</code> to add button specific methods. >+ * >+ * >+ * @author BREDEX GmbH >+ */ >+ >+public interface IButtonAdapter extends IWidgetAdapter { >+ /** >+ * Gets the text from the button >+ * @return the text which is saved in the component >+ */ >+ public String getText(); >+ >+ /** >+ * isSelected is mostly for RadioButtons and CheckBoxes >+ * @return <code>true</code> if the component is selected >+ */ >+ public boolean isSelected(); >+ /** >+ * Action to read the value of a Button to store it in a variable >+ * in the Client >+ * @param variable the name of the variable >+ * @return the text value. >+ */ >+ public String readValue(String variable); >+ >+} >\ No newline at end of file >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IComponentAdapter.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IComponentAdapter.java >new file mode 100644 >index 0000000..5d2e200 >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IComponentAdapter.java >@@ -0,0 +1,26 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.uiadapter.interfaces; >+/** >+ * This is the main interface for classes which will hold or be the >+ * component that implement the methods we need for this >+ * specific component to test . >+ * >+ * @author BREDEX GmbH >+ */ >+public interface IComponentAdapter { >+ /** >+ * Gets the toolkit specific component >+ * @return toolkit specific component >+ */ >+ public Object getRealComponent(); >+ >+} >\ No newline at end of file >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IMenuAdapter.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IMenuAdapter.java >new file mode 100644 >index 0000000..26d1597 >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IMenuAdapter.java >@@ -0,0 +1,35 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.uiadapter.interfaces; >+ >+ >+/** >+ * This interface is for the functionality of menus. This is only for the >+ * not visible part of menus which only contains the next menuitems in the >+ * Hierarchy of the menu. >+ * >+ * @author BREDEX GmbH >+ */ >+public interface IMenuAdapter extends IComponentAdapter { >+ >+ /** >+ * >+ * @return the items of the menu >+ */ >+ public IMenuItemAdapter[] getItems(); >+ >+ /** >+ * Gets the amount of items in the menu >+ * >+ * @return the amount of Items in the menu (with Seperator) >+ */ >+ public int getItemCount(); >+} >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IMenuItemAdapter.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IMenuItemAdapter.java >new file mode 100644 >index 0000000..b79ad73 >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IMenuItemAdapter.java >@@ -0,0 +1,80 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.uiadapter.interfaces; >+ >+/** >+ * Interface for all necessary methods for testing menuitems. >+ * >+ * @author BREDEX GmbH >+ */ >+public interface IMenuItemAdapter extends IComponentAdapter { >+ >+ /** >+ * >+ * @return the text which is saved in the item >+ */ >+ public String getText(); >+ /** >+ * >+ * @return <code>true</code> if the component is visible >+ */ >+ public boolean isEnabled(); >+ /** >+ * >+ * @return <code>true</code> if the component exists >+ * that means there is an item in this wrapper >+ */ >+ public boolean isExisting(); >+ /** >+ * >+ * @return <code>true</code> if the component is selected >+ * >+ */ >+ public boolean isSelected(); >+ /** >+ * >+ * @return <code>true</code> if the component is Showing >+ */ >+ public boolean isShowing(); >+ >+ /** Gets the menu of the menuitem >+ * @return the menu which is attached to the item >+ */ >+ public IMenuAdapter getMenu(); >+ >+ /** >+ * >+ * @return <code>true</code> if the menuitem has a menu >+ */ >+ public boolean hasSubMenu(); >+ /** >+ * Checks whether the given menu item is a separator. >+ * This method runs in the GUI thread. >+ * @return <code>true</code> if <code>menuItem</code> is a separator item. >+ * Otherwise <code>false</code>. >+ */ >+ public boolean isSeparator(); >+ >+ /** >+ * This Methods selects the specific menuItem with an click >+ * or in another toolkit specitif way >+ */ >+ public void selectMenuItem(); >+ >+ /** >+ * This method trys to open the the next Menu in the cascade >+ * >+ * @return the next SubMenu in the Menu >+ */ >+ public IMenuAdapter openSubMenu(); >+ >+ >+} >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/ITableAdapter.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/ITableAdapter.java >new file mode 100644 >index 0000000..b645cd5 >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/ITableAdapter.java >@@ -0,0 +1,128 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.uiadapter.interfaces; >+ >+import java.awt.Rectangle; >+ >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.implclasses.table.Cell; >+ >+/** >+ * Interface for all necessary methods for testing tables. >+ * >+ * @author BREDEX GmbH >+ */ >+public interface ITableAdapter extends IWidgetAdapter { >+ >+ >+ /** >+ * Gets the number of columns >+ * >+ * @return the number of columns >+ */ >+ public int getColumnCount(); >+ >+ /** >+ * Gets the number of rows >+ * >+ * @return the number of rows >+ */ >+ public int getRowCount(); >+ >+ /** >+ * @param row the zero based index of the row >+ * @param column the zero based index of the column >+ * @return the text of the cell of the given coordinates >+ */ >+ public String getCellText(int row, int column); >+ >+ /** >+ * Returns the name of the column appearing in the view at >+ * column position <code>column</code>. >+ * >+ * @param column the column in the view being queried >+ * @return the name of the column at position <code>column</code> >+ in the view where the first column is column 0 >+ */ >+ public String getColumnName(int column); >+ >+ /** >+ * Gets column index from string with header name or index >+ * >+ * @param col Headername or index of column >+ * @param operator The operation used to verify >+ * @return column index >+ */ >+ public int getColumnFromString(String col, String operator); >+ >+ /** >+ * This is only for a specific case where tables could act >+ * like lists. And the getText is not working. >+ * If this is not the case for the component return <code>null</code> >+ * @param row the row >+ * @return the text of the row >+ */ >+ public String getRowName(int row); >+ >+ /** >+ * Gets row index from string with index or text of first row >+ * >+ * @param row index or value in first col >+ * @param operator The operation used to verify >+ * @return integer of String of row >+ */ >+ public int getRowFromString(String row, String operator); >+ >+ /** >+ * gets header bounds for column >+ * @param col The column. >+ * @return The rectangle of the header >+ */ >+ public Rectangle getHeaderBounds(int col); >+ >+ /** >+ * @return The currently selected cell of the Table. >+ * @throws StepExecutionException If no cell is selected. >+ */ >+ public Cell getSelectedCell() throws StepExecutionException; >+ >+ /** >+ * >+ * @return <code>true</code> if the Header is visible, <code>false</code> otherwise >+ */ >+ public boolean isHeaderVisible(); >+ >+ /** >+ * >+ * @param row the row >+ * @param col the column >+ * @return <code>true</code> if the Cell is editable, <code>false</code> otherwise >+ */ >+ public boolean isCellEditable(int row, int col); >+ >+ /** >+ * @return true, if there is any cell selection in the table, false otherwise. >+ */ >+ public boolean hasCellSelection(); >+ >+ /** >+ * Scrolls the passed cell (as row and column) to visible.<br> >+ * This method must return null if there is no scrolling. >+ * @param row The row. >+ * @param col The column. >+ * @return The rectangle of the cell. >+ * @throws StepExecutionException If getting the cell rectangle or the scrolling fails. >+ */ >+ public Rectangle scrollCellToVisible (int row , int col) >+ throws StepExecutionException; >+ >+ >+} >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/ITreeAdapter.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/ITreeAdapter.java >new file mode 100644 >index 0000000..a7f0668 >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/ITreeAdapter.java >@@ -0,0 +1,41 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.uiadapter.interfaces; >+ >+import org.eclipse.jubula.rc.common.implclasses.tree.AbstractTreeOperationContext; >+ >+/** >+ * Interface for all necessary methods for testing trees. >+ * >+ * @author BREDEX GmbH >+ */ >+public interface ITreeAdapter extends IWidgetAdapter { >+ >+ /** >+ * Gets the root node(s) of the tree. >+ * This could be either a single node or multiple nodes >+ * @return The root node(s). >+ */ >+ public Object getRootNode(); >+ >+ /** >+ * Gets the TreeOperationContext which is created through an >+ * toolkit specific implementation. >+ * @return the TreeOperationContext for the tree >+ */ >+ public AbstractTreeOperationContext getContext(); >+ >+ /** >+ * >+ * @return The visibility of the Root Node >+ */ >+ public boolean isRootVisible(); >+} >diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IWidgetAdapter.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IWidgetAdapter.java >new file mode 100644 >index 0000000..c77f426 >--- /dev/null >+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/uiadapter/interfaces/IWidgetAdapter.java >@@ -0,0 +1,110 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.common.uiadapter.interfaces; >+ >+import org.eclipse.jubula.rc.common.caps.AbstractMenuCAPs; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+ >+/** >+ * This interface defines basic functionality for nearly all UI components. >+ * >+ * @author BREDEX GmbH >+ */ >+public interface IWidgetAdapter extends IComponentAdapter { >+ >+ /** >+ * >+ * @return <code>true</code> if the component is visible >+ */ >+ public boolean isShowing(); >+ /** >+ * >+ * @return <code>true</code> if the component is enabled >+ */ >+ public boolean isEnabled(); >+ /** >+ * >+ * @return <code>true</code> if the component has focus >+ */ >+ public boolean hasFocus(); >+ /** >+ * @param propertyname the name of the property value to return >+ * @return the property value >+ */ >+ public String getPropteryValue(String propertyname); >+ >+ >+ /** >+ * Shows and returns the popup menu >+ * >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param button MouseButton >+ * @return the popup menu >+ * @throws StepExecutionException error >+ */ >+ public AbstractMenuCAPs showPopup(final int xPos, >+ final String xUnits, final int yPos, >+ final String yUnits, final int button) >+ throws StepExecutionException; >+ >+ /** >+ * Shows and returns the popup menu >+ * @param button MouseButton >+ * @return the popup menu >+ */ >+ public AbstractMenuCAPs showPopup(int button); >+ >+ >+ >+ /** >+ * Simulates a tooltip for demonstration purposes. >+ * >+ * @param text The text to show in the tooltip >+ * @param textSize The size of the text in points >+ * @param timePerWord The amount of time, in milliseconds, used to display a >+ * single word. A word is defined as a string surrounded >+ * by whitespace. >+ * @param windowWidth The width of the tooltip window in pixels. >+ */ >+ public void showToolTip(final String text, final int textSize, >+ final int timePerWord, final int windowWidth); >+ >+ /** >+ * Performs a Drag. Moves into the middle of the Component and presses and >+ * holds the given modifier and the given mouse button. >+ * @param mouseButton the mouse button. >+ * @param modifier the modifier, e.g. shift, ctrl, etc. >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ */ >+ public void gdDrag(int mouseButton, String modifier, int xPos, >+ String xUnits, int yPos, String yUnits); >+ >+ /** >+ * Performs a Drop. Moves into the middle of the Component and releases >+ * the modifier and mouse button pressed by gdDrag. >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param delayBeforeDrop the amount of time (in milliseconds) to wait >+ * between moving the mouse to the drop point and >+ * releasing the mouse button >+ */ >+ public void gdDrop(int xPos, String xUnits, int yPos, String yUnits, >+ int delayBeforeDrop); >+ >+} >\ No newline at end of file >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/SwingAUTServer.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/SwingAUTServer.java >index d52d46f..cebb47e 100644 >--- a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/SwingAUTServer.java >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/SwingAUTServer.java >@@ -22,12 +22,14 @@ import org.eclipse.jubula.rc.common.AUTServer; > import org.eclipse.jubula.rc.common.driver.IRobot; > import org.eclipse.jubula.rc.common.driver.IRobotFactory; > import org.eclipse.jubula.rc.common.listener.BaseAUTListener; >+import org.eclipse.jubula.rc.common.uiadapter.factory.GUIAdapterFactoryRegistry; > import org.eclipse.jubula.rc.swing.driver.RobotFactoryConfig; > import org.eclipse.jubula.rc.swing.listener.CheckListener; > import org.eclipse.jubula.rc.swing.listener.ComponentHandler; > import org.eclipse.jubula.rc.swing.listener.FocusTracker; > import org.eclipse.jubula.rc.swing.listener.MappingListener; > import org.eclipse.jubula.rc.swing.listener.RecordListener; >+import org.eclipse.jubula.rc.swing.swing.uiadapter.factory.SwingAdapterFactory; > import org.eclipse.jubula.tools.constants.AUTServerExitConstants; > import org.eclipse.jubula.tools.constants.DebugConstants; > import org.eclipse.jubula.tools.utils.EnvironmentUtils; >@@ -220,6 +222,11 @@ public class SwingAUTServer extends AUTServer { > } > > AUTServer.getInstance().invokeAUT(); >+ >+ // FIXME dont know where to put >+ GUIAdapterFactoryRegistry.getInstance(). >+ registerFactory(new SwingAdapterFactory()); >+ System.out.println("AdapterFactory registered"); //$NON-NLS-1$ > } > > /** >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/AbstractButtonCAPs.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/AbstractButtonCAPs.java >new file mode 100644 >index 0000000..b60f776 >--- /dev/null >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/AbstractButtonCAPs.java >@@ -0,0 +1,60 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swing.swing.caps; >+ >+ >+import org.eclipse.jubula.rc.common.driver.IRobotFactory; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IButtonAdapter; >+import org.eclipse.jubula.rc.swing.driver.RobotFactoryConfig; >+ >+/** >+ * The implementation class for <code>AbstractButton</code> and subclasses. Note >+ * the "Abstract" in the class name implies only that this class can test >+ * <code>AbstractButton</code> components. The class itself should <em>NOT</em> >+ * be designated <code>abstract</code>, as this class is instantiated using >+ * reflection. >+ * >+ * @author BREDEX GmbH >+ */ >+public class AbstractButtonCAPs >+ extends org.eclipse.jubula.rc.common.caps.AbstractButtonCAPs { >+ >+ /** Robot Factory*/ >+ private IRobotFactory m_robotFactory; >+ >+ /** >+ * Clicks the button <code>count</code> times. >+ * >+ * @param count The number of clicks >+ */ >+ public void gdClick(int count) { >+ gdClick(count, 1); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String[] getTextArrayFromComponent() { >+ IButtonAdapter returnvalue = ((IButtonAdapter)getComponent()); >+ return new String[] { returnvalue.getText() }; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected IRobotFactory getRobotFactory() { >+ if (m_robotFactory == null) { >+ m_robotFactory = new RobotFactoryConfig().getRobotFactory(); >+ } >+ return m_robotFactory; >+ } >+ >+} >\ No newline at end of file >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/CapUtil.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/CapUtil.java >new file mode 100644 >index 0000000..ac2e378 >--- /dev/null >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/CapUtil.java >@@ -0,0 +1,243 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swing.swing.caps; >+ >+import java.awt.AWTEvent; >+import java.awt.Component; >+import java.awt.Container; >+import java.awt.event.ContainerEvent; >+import java.lang.reflect.InvocationTargetException; >+import java.lang.reflect.Method; >+import java.util.StringTokenizer; >+ >+import javax.swing.AbstractButton; >+import javax.swing.JLabel; >+import javax.swing.JPopupMenu; >+import javax.swing.JToggleButton; >+import javax.swing.text.JTextComponent; >+ >+import org.eclipse.jubula.rc.common.AUTServer; >+import org.eclipse.jubula.rc.common.adaptable.AdapterFactoryRegistry; >+import org.eclipse.jubula.rc.common.adaptable.ITextRendererAdapter; >+import org.eclipse.jubula.rc.common.driver.IRobot; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.util.KeyStrokeUtil; >+import org.eclipse.jubula.rc.swing.swing.driver.KeyCodeConverter; >+import org.eclipse.jubula.rc.swing.swing.implclasses.EventListener; >+import org.eclipse.jubula.tools.objects.event.EventFactory; >+import org.eclipse.jubula.tools.objects.event.TestErrorEvent; >+ >+/** >+ * Util class for Swing specific aspects. >+ * >+ * @author BREDEX GmbH >+ */ >+public class CapUtil { >+ >+ /** >+ * <code>RENDERER_FALLBACK_TEXT_GETTER_METHOD_1</code> >+ */ >+ public static final String RENDERER_FALLBACK_TEXT_GETTER_METHOD_1 = "getTestableText"; //$NON-NLS-1$ >+ >+ /** >+ * <code>RENDERER_FALLBACK_TEXT_GETTER_METHOD_2</code> >+ */ >+ public static final String RENDERER_FALLBACK_TEXT_GETTER_METHOD_2 = "getText"; //$NON-NLS-1$ >+ >+ >+ /** >+ * Is true, if a popup menu is shown >+ */ >+ public static class PopupShownCondition implements >+ EventListener.Condition { >+ >+ /** >+ * the popup menu >+ */ >+ private JPopupMenu m_popup = null; >+ >+ /** >+ * >+ * @return the popup menu >+ */ >+ public JPopupMenu getPopup() { >+ return m_popup; >+ } >+ >+ /** >+ * {@inheritDoc} >+ * @param event event >+ * @return result of the condition >+ */ >+ public boolean isTrue(AWTEvent event) { >+ if (event.getID() != ContainerEvent.COMPONENT_ADDED) { >+ return false; >+ } >+ ContainerEvent ce = (ContainerEvent)event; >+ if (ce.getChild() instanceof JPopupMenu) { >+ m_popup = (JPopupMenu)ce.getChild(); >+ return true; >+ } else if (ce.getChild() instanceof Container) { >+ Container popupContainer = (Container)ce.getChild(); >+ final int length = popupContainer.getComponents().length; >+ for (int i = 0; i < length; i++) { >+ if (popupContainer.getComponents()[i] >+ instanceof JPopupMenu) { >+ >+ m_popup = (JPopupMenu)popupContainer.getComponents()[i]; >+ return true; >+ } >+ } >+ } >+ return false; >+ } >+ } >+ /** >+ * >+ */ >+ private CapUtil() { } >+ >+ /** >+ * >+ * @return the Robot >+ */ >+ public static IRobot getRobot() { >+ return AUTServer.getInstance().getRobot(); >+ } >+ >+ >+ /** >+ * Presses or releases the given modifier. >+ * @param modifier the modifier. >+ * @param press if true, the modifier will be pressed. >+ * if false, the modifier will be released. >+ */ >+ public static void pressOrReleaseModifiers(String modifier, boolean press) { >+ final IRobot robot = getRobot(); >+ final StringTokenizer modTok = new StringTokenizer( >+ KeyStrokeUtil.getModifierString(modifier), " "); //$NON-NLS-1$ >+ while (modTok.hasMoreTokens()) { >+ final String mod = modTok.nextToken(); >+ final int keyCode = KeyCodeConverter.getKeyCode(mod); >+ if (press) { >+ robot.keyPress(null, keyCode); >+ } else { >+ robot.keyRelease(null, keyCode); >+ } >+ } >+ } >+ >+ /** >+ * @param renderer >+ * The component which is used as the renderer >+ * @return The string that the renderer displays. >+ * @throws StepExecutionException >+ * If the renderer component is not of type <code>JLabel</code>, >+ * <code>JToggleButton</code>, <code>AbstractButton</code>, >+ * <code>JTextComponent</code> or supports one of the fallback >+ * methods >+ */ >+ public static String getRenderedText(Component renderer) >+ throws StepExecutionException { >+ String renderedText = resolveRenderedText(renderer); >+ if (renderedText != null) { >+ return renderedText; >+ } >+ throw new StepExecutionException( >+ "Renderer not supported: " + renderer.getClass(), //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.RENDERER_NOT_SUPPORTED)); >+ } >+ >+ /** >+ * @param renderer >+ * The component which is used as the renderer >+ * @return The string that the renderer displays or <code>null</code> if it >+ * could not be resolved. >+ */ >+ private static String resolveRenderedText(Component renderer) { >+ if (renderer instanceof JLabel) { >+ return ((JLabel)renderer).getText(); >+ } else if (renderer instanceof JToggleButton) { >+ return ((JToggleButton)renderer).isSelected() ? Boolean.TRUE >+ .toString() : Boolean.FALSE.toString(); >+ } else if (renderer instanceof AbstractButton) { >+ return ((AbstractButton)renderer).getText(); >+ } else if (renderer instanceof JTextComponent) { >+ return ((JTextComponent)renderer).getText(); >+ } >+ // Check if an adapter exists >+ ITextRendererAdapter textRendererAdapter = >+ ((ITextRendererAdapter) AdapterFactoryRegistry >+ .getInstance().getAdapter( >+ ITextRendererAdapter.class, renderer)); >+ if (textRendererAdapter != null) { >+ return textRendererAdapter.getText(); >+ } else if (renderer != null) { >+ String[] methodNames = new String[] { >+ RENDERER_FALLBACK_TEXT_GETTER_METHOD_1, >+ RENDERER_FALLBACK_TEXT_GETTER_METHOD_2 }; >+ for (int i = 0; i < methodNames.length; i++) { >+ String text = getTextFromComponent(renderer, methodNames[i]); >+ if (text != null) { >+ return text; >+ } >+ } >+ } >+ return null; >+ } >+ >+ /** >+ * @param obj >+ * the object to invoke the method for >+ * @param getterName >+ * the name of the getter Method for string retrival >+ * @return the return value of the given method name or <code>null</code> if >+ * something went wrong during method invocation >+ */ >+ private static String getTextFromComponent(Object obj, String getterName) { >+ String text = null; >+ try { >+ Method getter = null; >+ Class objClass = obj.getClass(); >+ try { >+ getter = objClass.getDeclaredMethod(getterName, null); >+ } catch (NoSuchMethodException e) { >+ // ignore >+ } catch (SecurityException e) { >+ // ignore >+ } >+ if (getter == null) { >+ try { >+ getter = objClass.getMethod(getterName, null); >+ } catch (NoSuchMethodException e) { >+ return text; >+ } catch (SecurityException e) { >+ return text; >+ } >+ } >+ getter.setAccessible(true); >+ Object returnValue = getter.invoke(obj, null); >+ if (returnValue instanceof String) { >+ text = (String) returnValue; >+ } >+ return text; >+ } catch (SecurityException e) { >+ return text; >+ } catch (IllegalArgumentException e) { >+ return text; >+ } catch (IllegalAccessException e) { >+ return text; >+ } catch (InvocationTargetException e) { >+ return text; >+ } >+ } >+} >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/JMenuBarCAPs.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/JMenuBarCAPs.java >new file mode 100644 >index 0000000..a2aa007 >--- /dev/null >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/JMenuBarCAPs.java >@@ -0,0 +1,207 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swing.swing.caps; >+ >+import java.awt.Component; >+import java.awt.Container; >+import java.awt.Window; >+import java.awt.event.KeyEvent; >+import java.util.ArrayList; >+import java.util.Iterator; >+import java.util.List; >+ >+import javax.swing.JDialog; >+import javax.swing.JFrame; >+import javax.swing.JMenu; >+import javax.swing.JMenuBar; >+import javax.swing.JPopupMenu; >+import javax.swing.MenuElement; >+ >+import org.eclipse.jubula.rc.common.caps.AbstractMenuCAPs; >+import org.eclipse.jubula.rc.common.driver.IRobotFactory; >+import org.eclipse.jubula.rc.common.implclasses.IBaseImplementationClass; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IComponentAdapter; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuAdapter; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuItemAdapter; >+import org.eclipse.jubula.rc.swing.driver.RobotFactoryConfig; >+import org.eclipse.jubula.rc.swing.swing.implclasses.WindowHelper; >+import org.eclipse.jubula.rc.swing.swing.uiadapter.JMenuItemAdapter; >+ >+/** >+ * Toolkit specific commands for the <code>JMenuBar</code>. >+ * >+ * @author BREDEX GmbH >+ */ >+public class JMenuBarCAPs extends AbstractMenuCAPs >+ implements IBaseImplementationClass { >+ >+ /** The robot factory. */ >+ private IRobotFactory m_robotFactory; >+ /** >+ * {@inheritDoc} >+ */ >+ protected IRobotFactory getRobotFactory() { >+ if (m_robotFactory == null) { >+ m_robotFactory = new RobotFactoryConfig().getRobotFactory(); >+ } >+ return m_robotFactory; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String[] getTextArrayFromComponent() { >+ >+ return null; >+ } >+ >+ /** >+ * Workaround to get the menu bar existing somewhere in the given >+ * container's hierarchy. This method should <b>only</b> be used if >+ * {@link JFrame#getJMenuBar()} / {@link JDialog#getJMenuBar()} return >+ * <code>null</code>, which is a very rare case. >+ * >+ * This method also performs some unorthodox visibility testing in order >+ * to avoid retrieving the wrong menu. >+ * >+ * @param rootPane The root container from which to start the search for >+ * the menu bar. >+ * @return the first menu bar found in the hierarchy that: <ul> >+ * <li>is showing</li> >+ * <li>contains at least one visible menu</li> >+ */ >+ private JMenuBar getMenuBarWorkaround(Container rootPane) { >+ JMenuBar menuBar = null; >+ List menuList = new ArrayList(); >+ collectMenuBarsWorkaround(rootPane, menuList); >+ Iterator menuIter = menuList.iterator(); >+ while (menuIter.hasNext() && menuBar == null) { >+ JMenuBar menu = (JMenuBar)menuIter.next(); >+ boolean hasAtLeastOneItem = false; >+ MenuElement [] subElements = menu.getSubElements(); >+ for (int i = 0; >+ i < subElements.length && !hasAtLeastOneItem; >+ i++) { >+ if (subElements[i] instanceof JMenu) { >+ JMenu subMenu = (JMenu)subElements[i]; >+ hasAtLeastOneItem = >+ subMenu != null && subMenu.isShowing(); >+ } >+ } >+ if (hasAtLeastOneItem) { >+ menuBar = menu; >+ } >+ } >+ return menuBar; >+ } >+ >+ /** >+ * Adds all menu bars found in the hierarchy <code>container</code> to >+ * <code>menuBarList</code>. This is part of a workaround for finding menus >+ * in AUTs that don't make proper use of >+ * {@link JFrame#setJMenuBar()} / {@link JDialog#setJMenuBar()}. >+ * >+ * @see #getMenuBarWorkaround(Container) >+ * >+ * @param container The root container from which to start the search for >+ * the menu bars. >+ * @param menuBarList The list to which each menu bar found will be added. >+ * Only objects of type {@link JMenuBar} will be added >+ * to this list. >+ */ >+ private void collectMenuBarsWorkaround( >+ Container container, List menuBarList) { >+ Component [] children = container.getComponents(); >+ for (int i = 0; i < children.length; i++) { >+ if (children[i] instanceof JMenuBar >+ && children[i].isShowing()) { >+ menuBarList.add(children[i]); >+ } >+ } >+ >+ for (int i = 0; i < children.length; i++) { >+ if (children[i] instanceof Container >+ && children[i].isVisible()) { >+ collectMenuBarsWorkaround((Container)children[i], menuBarList); >+ } >+ } >+ >+ } >+ /** >+ * @return the component >+ */ >+ public IComponentAdapter getComponent() { >+ if (super.getComponent().getRealComponent() instanceof JPopupMenu) { >+ return super.getComponent(); >+ } >+ Window activeWindow = WindowHelper.getActiveWindow(); >+ if (activeWindow == null) { >+ getLog().warn("JMenuBarImplClass.getComponent(): No active window."); //$NON-NLS-1$ >+ } else { >+ JMenuBar menuBar = null; >+ Container rootPane = null; >+ if (activeWindow instanceof JDialog) { >+ JDialog dialog = (JDialog)activeWindow; >+ menuBar = dialog.getJMenuBar(); >+ rootPane = dialog.getRootPane(); >+ } else if (activeWindow instanceof JFrame) { >+ JFrame frame = (JFrame)activeWindow; >+ menuBar = frame.getJMenuBar(); >+ rootPane = frame.getRootPane(); >+ } >+ >+ if (menuBar == null) { >+ menuBar = getMenuBarWorkaround(rootPane); >+ } >+ >+ setComponent(menuBar); >+ } >+ return super.getComponent(); >+ } >+ >+ /** >+ *{@inheritDoc} >+ */ >+ protected void closeMenu(IMenuAdapter menuBar, String[] textPath, >+ String operator) { >+ if (menuBar.getRealComponent() instanceof JPopupMenu) { >+ for (int i = 0; i < textPath.length; i++) { >+ getRobot().keyType(menuBar.getRealComponent(), >+ KeyEvent.VK_ESCAPE); >+ } >+ return; >+ } >+ super.closeMenu(menuBar, textPath, operator); >+ >+ } >+ >+ /** >+ *{@inheritDoc} >+ */ >+ protected void closeMenu(IMenuAdapter menuBar, int[] path) { >+ if (menuBar.getRealComponent() instanceof JPopupMenu) { >+ for (int i = 0; i < path.length; i++) { >+ getRobot().keyType(menuBar.getRealComponent(), >+ KeyEvent.VK_ESCAPE); >+ } >+ return; >+ } >+ super.closeMenu(menuBar, path); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected IMenuItemAdapter newMenuItemAdapter(Object component) { >+ return new JMenuItemAdapter(component); >+ } >+ >+} >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/JTableCAPs.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/JTableCAPs.java >new file mode 100644 >index 0000000..c26754f >--- /dev/null >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/JTableCAPs.java >@@ -0,0 +1,213 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swing.swing.caps; >+ >+import java.awt.Component; >+import java.awt.IllegalComponentStateException; >+import java.awt.Point; >+import java.awt.Rectangle; >+ >+import javax.swing.JTable; >+import javax.swing.table.JTableHeader; >+import javax.swing.table.TableColumn; >+import javax.swing.table.TableColumnModel; >+ >+import org.eclipse.jubula.rc.common.caps.AbstractTableCAPs; >+import org.eclipse.jubula.rc.common.driver.ClickOptions; >+import org.eclipse.jubula.rc.common.driver.IEventThreadQueuer; >+import org.eclipse.jubula.rc.common.driver.IRobotFactory; >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.implclasses.table.Cell; >+import org.eclipse.jubula.rc.common.logger.AutServerLogger; >+import org.eclipse.jubula.rc.swing.driver.RobotFactoryConfig; >+import org.eclipse.jubula.rc.swing.swing.driver.KeyCodeConverter; >+import org.eclipse.jubula.rc.swing.utils.SwingUtils; >+/** >+ * Toolkit specific commands for the <code>JTable</code> >+ * >+ * @author BREDEX GmbH >+ */ >+public class JTableCAPs extends AbstractTableCAPs { >+ >+ /** the logger */ >+ private static AutServerLogger log = new AutServerLogger( >+ JTableCAPs.class); >+ >+ /** the RobotFactory from the AUT */ >+ private IRobotFactory m_robotFactory; >+ >+ /** >+ * @return the log >+ */ >+ public static AutServerLogger getLog() { >+ return log; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected IRobotFactory getRobotFactory() { >+ if (m_robotFactory == null) { >+ m_robotFactory = new RobotFactoryConfig().getRobotFactory(); >+ } >+ return m_robotFactory; >+ } >+ >+ /** >+ * >+ * @return the real AUT JTable >+ */ >+ private JTable getTable() { >+ return (JTable) getComponent().getRealComponent(); >+ } >+ >+ /** >+ * @return The event thread queuer. >+ */ >+ public IEventThreadQueuer getEventThreadQueuer() { >+ return getRobotFactory().getEventThreadQueuer(); >+ } >+ >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String[] getTextArrayFromComponent() { >+ final String[] componentTextArray; >+ TableColumnModel columnModel = getTable().getColumnModel(); >+ if (columnModel == null) { >+ componentTextArray = null; >+ } else { >+ componentTextArray = new String[columnModel.getColumnCount()]; >+ for (int i = 0; i < componentTextArray.length; i++) { >+ TableColumn tableColumn = columnModel.getColumn(i); >+ if (tableColumn == null) { >+ componentTextArray[i] = null; >+ } else { >+ Object headerValue = tableColumn.getHeaderValue(); >+ if (headerValue == null) { >+ componentTextArray[i] = null; >+ } else { >+ componentTextArray[i] = headerValue.toString(); >+ } >+ } >+ } >+ } >+ return componentTextArray; >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ protected int getExtendSelectionModifier() { >+ return SwingUtils.getSystemDefaultModifier(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected Cell getCellAtMousePosition() throws StepExecutionException { >+ JTable table = getTable(); >+ Point mousePos = getRobot().getCurrentMousePosition(); >+ Point tablePos = table.getLocationOnScreen(); >+ Point relativePos = new Point(mousePos.x - tablePos.x, >+ mousePos.y - tablePos.y); >+ final int column = table.columnAtPoint(relativePos); >+ final int row = table.rowAtPoint(relativePos); >+ if (log.isDebugEnabled()) { >+ log.debug("Selected row, col: " + row + ", " + column); //$NON-NLS-1$ //$NON-NLS-2$ >+ } >+ checkRowColBounds(row, column); >+ return new Cell(row, column); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected boolean isMouseOnHeader() { >+ JTable table = getTable(); >+ if (table.getTableHeader() == null >+ || !(table.getTableHeader().isShowing())) { >+ return false; >+ } >+ >+ JTableHeader header = table.getTableHeader(); >+ Point mousePos = getRobot().getCurrentMousePosition(); >+ try { >+ Point headerPos = header.getLocationOnScreen(); >+ Point relativePos = new Point(mousePos.x - headerPos.x, >+ mousePos.y - headerPos.y); >+ return header.getBounds().contains(relativePos); >+ } catch (IllegalComponentStateException icse) { >+ return false; >+ } >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected Object setEditorToReplaceMode(Object editor, boolean replace) { >+ Object returnvalue = editor; >+ if (replace) { >+ getRobot().clickAtCurrentPosition(editor, 3, 1); >+ } else { >+ returnvalue = getComponent().getRealComponent(); >+ } >+ return returnvalue; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected Object activateEditor(Cell cell, Rectangle rectangle) { >+ Object table = getComponent().getRealComponent(); >+ getRobot().click(table, rectangle); >+ Component editor = getTableCellEditor(cell); >+ // sometimes the editor only appears after doubleclick! >+ if (editor == null) { >+ ClickOptions co = ClickOptions.create().setClickCount(2); >+ getRobot().click(table, rectangle, co); >+ editor = getTableCellEditor(cell); >+ } >+ return editor; >+ } >+ >+ /** >+ * Gets the TableCellEditor of the given cell >+ * @param cell the cell. >+ * @return the TableCellEditor >+ */ >+ private Component getTableCellEditor(final Cell cell) { >+ final JTable table = (JTable) getComponent().getRealComponent(); >+ return (Component) getEventThreadQueuer() >+ .invokeAndWait("getCellEditor", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ Object value = table.getValueAt( >+ cell.getRow(), cell.getCol()); >+ boolean selected = table.isCellSelected( >+ cell.getRow(), cell.getCol()); >+ return table.getCellEditor(cell.getRow(), >+ cell.getCol()).getTableCellEditorComponent(table, >+ value, selected, cell.getRow(), cell.getCol()); >+ } >+ }); >+ } >+ >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected int getKeyCode(String key) { >+ return KeyCodeConverter.getKeyCode(key); >+ } >+ >+} >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/JTreeCAPs.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/JTreeCAPs.java >new file mode 100644 >index 0000000..4061446 >--- /dev/null >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/caps/JTreeCAPs.java >@@ -0,0 +1,194 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swing.swing.caps; >+ >+import java.awt.Point; >+import javax.swing.JTree; >+import javax.swing.tree.TreePath; >+ >+import org.eclipse.jubula.rc.common.CompSystemConstants; >+import org.eclipse.jubula.rc.common.caps.AbstractTreeCAPs; >+import org.eclipse.jubula.rc.common.driver.DragAndDropHelper; >+import org.eclipse.jubula.rc.common.driver.IEventThreadQueuer; >+import org.eclipse.jubula.rc.common.driver.IRobotFactory; >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.swing.driver.RobotFactoryConfig; >+import org.eclipse.jubula.tools.objects.event.EventFactory; >+import org.eclipse.jubula.tools.objects.event.TestErrorEvent; >+import org.eclipse.jubula.tools.utils.TimeUtil; >+/** >+ * Toolkit specific commands for the <code>JTree</code> >+ * >+ * @author BREDEX GmbH >+ */ >+public class JTreeCAPs extends AbstractTreeCAPs { >+ >+ /** Robot Factory*/ >+ private IRobotFactory m_robotFactory; >+ >+ >+ /** >+ * Waits the given amount of time. Logs a drop-related error if interrupted. >+ * >+ * @param delayBeforeDrop the amount of time (in milliseconds) to wait >+ * between moving the mouse to the drop point and >+ * releasing the mouse button >+ */ >+ static void waitBeforeDrop(int delayBeforeDrop) { >+ TimeUtil.delay(delayBeforeDrop); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdDragByTextPath(int mouseButton, >+ String modifier, String pathType, int preAscend, >+ String treeTextPath, String operator) { >+ final DragAndDropHelper dndHelper = DragAndDropHelper.getInstance(); >+ dndHelper.setModifier(modifier); >+ dndHelper.setMouseButton(mouseButton); >+ gdSelect(pathType, preAscend, treeTextPath, operator, 0, 1, >+ CompSystemConstants.EXTEND_SELECTION_NO); >+ pressOrReleaseModifiers(modifier, true); >+ getRobot().mousePress(null, null, mouseButton); >+ >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdDropByTextPath(String pathType, int preAscend, >+ String treeTextPath, String operator, int delayBeforeDrop) { >+ try { >+ gdSelect(pathType, preAscend, treeTextPath, operator, 0, 1, >+ CompSystemConstants.EXTEND_SELECTION_NO); >+ waitBeforeDrop(delayBeforeDrop); >+ } finally { >+ final DragAndDropHelper dndHelper = DragAndDropHelper.getInstance(); >+ getRobot().mouseRelease(null, null, dndHelper.getMouseButton()); >+ pressOrReleaseModifiers(dndHelper.getModifier(), false); >+ } >+ >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdDragByIndexPath(int mouseButton, >+ String modifier, String pathType, int preAscend, >+ String treeIndexPath) { >+ final DragAndDropHelper dndHelper = DragAndDropHelper.getInstance(); >+ dndHelper.setModifier(modifier); >+ dndHelper.setMouseButton(mouseButton); >+ gdSelectByIndices(pathType, preAscend, treeIndexPath, 0, 1, >+ CompSystemConstants.EXTEND_SELECTION_NO); >+ pressOrReleaseModifiers(modifier, true); >+ getRobot().mousePress(null, null, mouseButton); >+ >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdDropByIndexPath(String pathType, int preAscend, >+ String treeIndexPath, int delayBeforeDrop) { >+ try { >+ gdSelectByIndices(pathType, preAscend, treeIndexPath, 0, 1, >+ CompSystemConstants.EXTEND_SELECTION_NO); >+ waitBeforeDrop(delayBeforeDrop); >+ } finally { >+ final DragAndDropHelper dndHelper = DragAndDropHelper.getInstance(); >+ getRobot().mouseRelease(null, null, dndHelper.getMouseButton()); >+ pressOrReleaseModifiers(dndHelper.getModifier(), false); >+ } >+ >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdVerifyTextAtMousePosition(String text, String operator) { >+ checkNodeText(getNodeAtMousePosition(), text, operator); >+ } >+ /** >+ * >+ * @return the tree node at the current mouse position. >+ * @throws StepExecutionException If no tree node can be found at the >+ * current mouse position. >+ */ >+ protected Object getNodeAtMousePosition() throws StepExecutionException { >+ return getEventThreadQueuer().invokeAndWait("getNodeAtMousePosition", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() throws StepExecutionException { >+ Point mousePosition = getRobot().getCurrentMousePosition(); >+ Point treeLocation = getTreeComponent().getLocationOnScreen(); >+ Point relativePos = new Point( >+ mousePosition.x - treeLocation.x, >+ mousePosition.y - treeLocation.y); >+ >+ int rowAtMousePosition = >+ getTreeComponent(). >+ getRowForLocation(relativePos.x, relativePos.y); >+ >+ if (rowAtMousePosition != -1) { >+ TreePath treePath = >+ getTreeComponent(). >+ getPathForLocation(relativePos.x, relativePos.y); >+ >+ if (treePath != null >+ && treePath.getLastPathComponent() != null) { >+ return treePath.getLastPathComponent(); >+ } >+ >+ } >+ >+ throw new StepExecutionException("No tree node found at mouse position.", //$NON-NLS-1$ >+ EventFactory.createActionError(TestErrorEvent.NOT_FOUND)); >+ } >+ >+ }); >+ >+ } >+ /** >+ * >+ * @return The JTree >+ */ >+ private JTree getTreeComponent() { >+ return (JTree) getComponent().getRealComponent(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected IRobotFactory getRobotFactory() { >+ if (m_robotFactory == null) { >+ m_robotFactory = new RobotFactoryConfig().getRobotFactory(); >+ } >+ return m_robotFactory; >+ } >+ >+ /** >+ * Presses or releases the given modifier. >+ * @param modifier the modifier. >+ * @param press if true, the modifier will be pressed. >+ * if false, the modifier will be released. >+ */ >+ protected void pressOrReleaseModifiers(String modifier, boolean press) { >+ CapUtil.pressOrReleaseModifiers(modifier, press); >+ } >+ >+ /** >+ * @return The event thread queuer. >+ */ >+ protected IEventThreadQueuer getEventThreadQueuer() { >+ return getRobotFactory().getEventThreadQueuer(); >+ } >+} >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/AbstractButtonAdapter.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/AbstractButtonAdapter.java >new file mode 100644 >index 0000000..843d91d >--- /dev/null >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/AbstractButtonAdapter.java >@@ -0,0 +1,103 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swing.swing.uiadapter; >+ >+import javax.swing.AbstractButton; >+ >+import org.eclipse.jubula.rc.common.driver.IEventThreadQueuer; >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IButtonAdapter; >+/** >+ * Implementation of the button interface as an adapter which holds >+ * the <code>javax.swing.AbstractButton</code>. >+ * >+ * @author BREDEX GmbH >+ */ >+public class AbstractButtonAdapter extends WidgetAdapter >+ implements IButtonAdapter { >+ >+ /** >+ * Creates an object with the adapted JMenu. >+ * @param objectToAdapt this must be an object of the Type >+ * <code>AbstractButton</code> >+ */ >+ public AbstractButtonAdapter(Object objectToAdapt) { >+ super(objectToAdapt); >+ } >+ >+ /** >+ * >+ * @return the casted Object >+ */ >+ private AbstractButton getAbstractButton() { >+ return (AbstractButton) getRealComponent(); >+ } >+ /** >+ * @return The event thread queuer. >+ */ >+ public IEventThreadQueuer getEventThreadQueuer() { >+ return getRobotFactory().getEventThreadQueuer(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String getText() { >+ return (String) getEventThreadQueuer().invokeAndWait( >+ "getText", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return getAbstractButton().getText(); >+ } >+ }); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isEnabled() { >+ Boolean returnvalue = (Boolean) getEventThreadQueuer().invokeAndWait( >+ "isEnabled", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return getAbstractButton().getModel().isEnabled() >+ ? Boolean.TRUE : Boolean.FALSE; >+ } >+ }); >+ return (boolean) returnvalue.booleanValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isSelected() { >+ Boolean returnvalue = (Boolean) getEventThreadQueuer().invokeAndWait( >+ "isSelected", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return getAbstractButton().getModel().isSelected() >+ ? Boolean.TRUE : Boolean.FALSE; >+ } >+ }); >+ return (boolean) returnvalue.booleanValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String readValue(String variable) { >+ >+ return (String) getEventThreadQueuer().invokeAndWait( >+ "isShowing", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return getAbstractButton().getText(); >+ } >+ }); >+ } >+ >+} >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JMenuAdapter.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JMenuAdapter.java >new file mode 100644 >index 0000000..0b3e3b9 >--- /dev/null >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JMenuAdapter.java >@@ -0,0 +1,90 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swing.swing.uiadapter; >+ >+import java.util.Iterator; >+import java.util.LinkedList; >+import java.util.List; >+ >+import javax.swing.JMenu; >+import javax.swing.JMenuItem; >+ >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuAdapter; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuItemAdapter; >+/** >+ * Implementation of the menu interface for adapting the <code>JMenu</code>. >+ * In Swing we have three implementations of the menu interface because >+ * the Interface is used for the <code>JMenubar</code>, the <code>JPopupMenu</code> and the <code>JMenu</code>. >+ * All these behave same in the implementation. >+ * >+ * @author BREDEX GmbH >+ * >+ */ >+public class JMenuAdapter implements IMenuAdapter { >+ /** The JMenu from the AUT */ >+ private JMenu m_menu; >+ >+ /** >+ * Creates an object with the adapted JMenu. >+ * @param toAdapt graphics component which will be adapted >+ */ >+ public JMenuAdapter(Object toAdapt) { >+ m_menu = (JMenu) toAdapt; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public Object getRealComponent() { >+ return m_menu; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public IMenuItemAdapter[] getItems() { >+ List adapters = new LinkedList(); >+ >+ for (int i = 0; i < m_menu.getItemCount(); i++) { >+ JMenuItem getted = m_menu.getItem(i); >+ if (getted instanceof JMenuItem) { >+ adapters.add(new JMenuItemAdapter(getted)); >+ } >+ >+ } >+ >+ >+ IMenuItemAdapter[] allitems = null; >+ if (adapters.size() > 0) { >+ allitems = new IMenuItemAdapter[adapters.size()]; >+ int i = 0; >+ for (Iterator iterator = adapters.iterator(); iterator.hasNext();) { >+ Object object = (Object) iterator.next(); >+ >+ allitems[i] = (IMenuItemAdapter) object; >+ i++; >+ } >+ >+ } >+ >+ >+ return allitems; >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public int getItemCount() { >+ return m_menu.getItemCount(); >+ } >+ >+ >+ >+} >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JMenuBarAdapter.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JMenuBarAdapter.java >new file mode 100644 >index 0000000..5bfb7e4 >--- /dev/null >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JMenuBarAdapter.java >@@ -0,0 +1,73 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swing.swing.uiadapter; >+ >+import java.util.LinkedList; >+import java.util.List; >+ >+import javax.swing.JMenuBar; >+import javax.swing.JMenuItem; >+ >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuAdapter; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuItemAdapter; >+ >+/** >+ * Implementation of the menu interface for adapting the <code>JMenuBar</code>. >+ * In Swing we have three implementations of the menu interface because >+ * the Interface is used for the <code>JMenubar</code>, the <code>JPopupMenu</code> and the <code>JMenu</code>. >+ * All these behave same in the implementation. >+ * >+ * @author BREDEX GmbH >+ * >+ */ >+public class JMenuBarAdapter implements IMenuAdapter { >+ /** The JMenuBar */ >+ private JMenuBar m_menuBar; >+ >+ /** >+ * @param objectToAdapt >+ */ >+ public JMenuBarAdapter(Object objectToAdapt) { >+ m_menuBar = (JMenuBar) objectToAdapt; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public Object getRealComponent() { >+ >+ return m_menuBar; >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ >+ public IMenuItemAdapter[] getItems() { >+ Object[] menus = m_menuBar.getSubElements(); >+ List adapters = new LinkedList(); >+ for (int i = 0; i < menus.length; i++) { >+ if (menus[i] instanceof JMenuItem) { >+ adapters.add(new JMenuItemAdapter(menus[i])); >+ } >+ } >+ IMenuItemAdapter[] allitems = new IMenuItemAdapter[adapters.size()]; >+ adapters.toArray(allitems); >+ return allitems; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public int getItemCount() { >+ return m_menuBar.getMenuCount(); >+ } >+ >+} >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JMenuItemAdapter.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JMenuItemAdapter.java >new file mode 100644 >index 0000000..3ca11f6 >--- /dev/null >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JMenuItemAdapter.java >@@ -0,0 +1,240 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swing.swing.uiadapter; >+ >+import javax.swing.JMenu; >+import javax.swing.JMenuItem; >+ >+import org.eclipse.jubula.rc.common.driver.ClickOptions; >+import org.eclipse.jubula.rc.common.driver.IEventThreadQueuer; >+import org.eclipse.jubula.rc.common.driver.IRobot; >+import org.eclipse.jubula.rc.common.driver.IRobotFactory; >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.driver.RobotTiming; >+import org.eclipse.jubula.rc.common.exception.RobotException; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuAdapter; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuItemAdapter; >+import org.eclipse.jubula.rc.swing.driver.RobotFactoryConfig; >+import org.eclipse.jubula.tools.objects.event.EventFactory; >+import org.eclipse.jubula.tools.objects.event.TestErrorEvent; >+ >+/** >+ * Implementation of the MenuItem interface for adapting <code>JMenuItem</code>. >+ * @author BREDEX GmbH >+ * >+ */ >+public class JMenuItemAdapter >+ implements IMenuItemAdapter { >+ >+ /** the JMenuItem from the AUT */ >+ private JMenuItem m_menuItem; >+ >+ /** the RobotFactory from the AUT */ >+ private IRobotFactory m_robotFactory; >+ >+ /** >+ * >+ * @param objectToAdapt >+ */ >+ public JMenuItemAdapter(Object objectToAdapt) { >+ m_menuItem = (JMenuItem) objectToAdapt; >+ } >+ /** >+ * Gets the Robot factory. The factory is created once per instance. >+ * >+ * @return The Robot factory. >+ */ >+ protected IRobotFactory getRobotFactory() { >+ if (m_robotFactory == null) { >+ m_robotFactory = new RobotFactoryConfig().getRobotFactory(); >+ } >+ return m_robotFactory; >+ } >+ /** >+ * Gets the IEventThreadQueuer. >+ * >+ * @return The Robot >+ * @throws RobotException >+ * If the Robot cannot be created. >+ */ >+ protected IRobot getRobot() throws RobotException { >+ return getRobotFactory().getRobot(); >+ } >+ /** >+ * @return The event thread queuer. >+ */ >+ public IEventThreadQueuer getEventThreadQueuer() { >+ return getRobotFactory().getEventThreadQueuer(); >+ } >+ >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public Object getRealComponent() { >+ >+ return m_menuItem; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void setComponent(Object element) { >+ m_menuItem = (JMenuItem) element; >+ >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isEnabled() { >+ Boolean actual = (Boolean) getEventThreadQueuer().invokeAndWait( >+ "isEnabled", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ // see findBugs >+ return ((m_menuItem != null) >+ && (m_menuItem instanceof JMenuItem) >+ && m_menuItem.isEnabled()) >+ ? Boolean.TRUE : Boolean.FALSE; >+ } >+ }); >+ >+ return actual.booleanValue(); >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public String getText() { >+ return (String) getEventThreadQueuer().invokeAndWait( >+ "getText", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return m_menuItem.getText(); >+ } >+ }); >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isShowing() { >+ Boolean actual = (Boolean) getEventThreadQueuer().invokeAndWait( >+ "isShowing", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ // see findBugs >+ return ((m_menuItem != null) >+ && (m_menuItem instanceof JMenuItem) >+ && m_menuItem.isShowing()) >+ ? Boolean.TRUE : Boolean.FALSE; >+ } >+ }); >+ >+ return actual.booleanValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isExisting() { >+ if (m_menuItem != null) { >+ return true; >+ } >+ return false; >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isSelected() { >+ Boolean actual = (Boolean) getEventThreadQueuer().invokeAndWait( >+ "isSelected", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return ((m_menuItem != null) >+ && (m_menuItem instanceof JMenuItem) >+ && m_menuItem.isSelected()) >+ ? Boolean.TRUE : Boolean.FALSE; >+ } >+ }); >+ >+ return actual.booleanValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public IMenuAdapter getMenu() { >+ if (m_menuItem instanceof JMenu) { >+ return new JMenuAdapter(m_menuItem); >+ } >+ return null; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean hasSubMenu() { >+ if (m_menuItem.getSubElements().length > 0) { >+ return true; >+ } >+ return false; >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isSeparator() { >+ if (m_menuItem == null) { >+ return true; >+ } >+ return false; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void selectMenuItem() { >+ clickMenuItem(getRobot(), m_menuItem); >+ >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public IMenuAdapter openSubMenu() { >+ if (!m_menuItem.isEnabled()) { >+ throw new StepExecutionException("menu item not enabled", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.MENU_ITEM_NOT_ENABLED)); >+ } >+ if (!(m_menuItem instanceof JMenu)) { >+ throw new StepExecutionException("unexpected item found", //$NON-NLS-1$ >+ EventFactory.createActionError(TestErrorEvent.NOT_FOUND)); >+ } >+ JMenu menu = (JMenu) m_menuItem; >+ getRobot().click(m_menuItem, null, ClickOptions.create().setClickType( >+ ClickOptions.ClickType.RELEASED)); >+ RobotTiming.sleepPostShowSubMenuItem(menu.getDelay()); >+ return getMenu(); >+ } >+ >+ /** >+ * Clicks on a menu item >+ * >+ * @param robot the robot >+ * @param item the menu item >+ */ >+ private void clickMenuItem(IRobot robot, JMenuItem item) { >+ if (!item.isEnabled()) { >+ throw new StepExecutionException("menu item not enabled", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.MENU_ITEM_NOT_ENABLED)); >+ } >+ robot.click(item, null, ClickOptions.create().setClickType( >+ ClickOptions.ClickType.RELEASED)); >+ } >+} >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JPopupMenuAdapter.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JPopupMenuAdapter.java >new file mode 100644 >index 0000000..d5ef952 >--- /dev/null >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JPopupMenuAdapter.java >@@ -0,0 +1,67 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swing.swing.uiadapter; >+ >+import java.util.LinkedList; >+import java.util.List; >+ >+import javax.swing.JMenuItem; >+import javax.swing.JPopupMenu; >+ >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuAdapter; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuItemAdapter; >+/** >+ * Implementation of the menu interface for adapting the <code>JPopupMenu</code>. >+ * In Swing we have three implementations of the menu interface because >+ * the Interface is used for the <code>JMenubar</code>, the <code>JPopupMenu</code> and the <code>JMenu</code>. >+ * All these behave same in the implementation. >+ * >+ * @author BREDEX GmbH >+ * >+ */ >+public class JPopupMenuAdapter implements IMenuAdapter { >+ /** */ >+ private JPopupMenu m_contextMenu; >+ >+ /** >+ * >+ * @param adaptee >+ */ >+ public JPopupMenuAdapter(Object adaptee) { >+ m_contextMenu = (JPopupMenu) adaptee; >+ } >+ >+ /** {@inheritDoc} */ >+ public Object getRealComponent() { >+ return m_contextMenu; >+ } >+ >+ /** {@inheritDoc} */ >+ public IMenuItemAdapter[] getItems() { >+ Object[] menuItems = m_contextMenu.getSubElements(); >+ List adapters = new LinkedList(); >+ for (int i = 0; i < menuItems.length; i++) { >+ if (menuItems[i] instanceof JMenuItem) { >+ adapters.add(new JMenuItemAdapter(menuItems[i])); >+ } >+ } >+ IMenuItemAdapter[] allitems = new IMenuItemAdapter[adapters.size()]; >+ adapters.toArray(allitems); >+ return allitems; >+ } >+ >+ /** {@inheritDoc} */ >+ public int getItemCount() { >+ return m_contextMenu.getSubElements().length; >+ } >+ >+ >+} >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JTableAdapter.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JTableAdapter.java >new file mode 100644 >index 0000000..ba11276 >--- /dev/null >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JTableAdapter.java >@@ -0,0 +1,377 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swing.swing.uiadapter; >+ >+import java.awt.Component; >+import java.awt.Rectangle; >+ >+import javax.swing.JTable; >+import javax.swing.table.TableCellRenderer; >+ >+import org.eclipse.jubula.rc.common.caps.AbstractMenuCAPs; >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.implclasses.IndexConverter; >+import org.eclipse.jubula.rc.common.implclasses.MatchUtil; >+import org.eclipse.jubula.rc.common.implclasses.table.Cell; >+import org.eclipse.jubula.rc.common.logger.AutServerLogger; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.ITableAdapter; >+import org.eclipse.jubula.rc.swing.swing.caps.CapUtil; >+import org.eclipse.jubula.tools.objects.event.EventFactory; >+import org.eclipse.jubula.tools.objects.event.TestErrorEvent; >+/** >+ * Implements the table interface as an adapter for the <code>JTable</code>. >+ * >+ * @author BREDEX GmbH >+ */ >+public class JTableAdapter extends WidgetAdapter implements ITableAdapter { >+ >+ /** the logger */ >+ private static AutServerLogger log = new AutServerLogger( >+ AbstractMenuCAPs.class); >+ >+ /** The JTable from the AUT */ >+ private JTable m_table; >+ >+ /** >+ * Creates an object with the adapted JMenu. >+ * @param objectToAdapt the object which needed to be adapted >+ */ >+ public JTableAdapter(Object objectToAdapt) { >+ super(objectToAdapt); >+ m_table = (JTable) objectToAdapt; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void setComponent(Object element) { >+ m_table = (JTable) element; >+ >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public int getColumnCount() { >+ Integer returnvalue = (Integer) getEventThreadQueuer().invokeAndWait( >+ "getColumnCount", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return new Integer(m_table.getColumnCount()); >+ } >+ }); >+ return returnvalue.intValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public int getRowCount() { >+ Integer returnvalue = (Integer) getEventThreadQueuer().invokeAndWait( >+ "getRowCount", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return new Integer(m_table.getRowCount()); >+ } >+ }); >+ return returnvalue.intValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String getCellText(final int row, final int column) { >+ Object o = getEventThreadQueuer().invokeAndWait("getCellText", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ Object value = m_table.getValueAt(row, column); >+ boolean selected = m_table.isCellSelected(row, >+ column); >+ if (log.isDebugEnabled()) { >+ log.debug("Getting cell text:"); //$NON-NLS-1$ >+ log.debug("Row, col: " + row + ", " + column); //$NON-NLS-1$ //$NON-NLS-2$ >+ log.debug("Value: " + value); //$NON-NLS-1$ >+ } >+ TableCellRenderer renderer = m_table.getCellRenderer( >+ row, column); >+ Component c = renderer.getTableCellRendererComponent( >+ m_table, value, selected, true, row, >+ column); >+ >+ return CapUtil.getRenderedText(c); >+ } >+ }); >+ >+ String current = String.valueOf(o); >+ return current; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String getColumnName(final int column) { >+ String returnvalue = (String)getEventThreadQueuer().invokeAndWait( >+ "getColumnName", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ return m_table.getColumnName(column); >+ } >+ }); >+ return returnvalue; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public int getColumnFromString(final String col, final String operator) { >+ Integer returnvalue = (Integer) getEventThreadQueuer().invokeAndWait( >+ "getColumnFromString", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ int column = -2; >+ try { >+ int usrIdxCol = Integer.parseInt(col); >+ if (usrIdxCol == 0) { >+ usrIdxCol = usrIdxCol + 1; >+ } >+ column = IndexConverter.toImplementationIndex( >+ usrIdxCol); >+ } catch (NumberFormatException nfe) { >+ try { >+ if (m_table.getTableHeader() == null >+ || !(m_table.getTableHeader() >+ .isShowing())) { >+ throw new StepExecutionException("No Header", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.NO_HEADER)); >+ } >+ for (int i = 0; i < m_table.getColumnCount(); >+ i++) { >+ String header = m_table.getColumnName(i); >+ if (MatchUtil.getInstance().match( >+ header, col, operator)) { >+ column = i; >+ } >+ } >+ } catch (IllegalArgumentException iae) { >+ //do nothing here >+ } >+ } >+ >+ return new Integer(column); >+ } >+ }); >+ return returnvalue.intValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String getRowName(final int row) { >+ // JTable does not act like lists >+ return null; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public int getRowFromString(final String row, final String operator) { >+ Integer returnvalue = (Integer) getEventThreadQueuer().invokeAndWait( >+ "getRowFromString", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ int rowInt = -2; >+ try { >+ rowInt = IndexConverter.toImplementationIndex( >+ Integer.parseInt(row)); >+ if (rowInt == -1) { >+ if (m_table.getTableHeader() == null >+ || !(m_table.getTableHeader() >+ .isShowing())) { >+ throw new StepExecutionException("No Header", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.NO_HEADER)); >+ } >+ } >+ } catch (NumberFormatException nfe) { >+ for (int i = 0; i < m_table.getRowCount(); i++) { >+ String cellTxt = getCellText(i, 0); >+ if (MatchUtil.getInstance().match(cellTxt, row, >+ operator)) { >+ return new Integer(i); >+ } >+ } >+ } >+ return new Integer(rowInt); >+ } >+ }); >+ return returnvalue.intValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public Rectangle getBounds() { >+ Rectangle returnvalue = (Rectangle) getEventThreadQueuer() >+ .invokeAndWait("getBounds", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() throws StepExecutionException { >+ return m_table.getBounds(); >+ } >+ }); >+ >+ return returnvalue; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public Rectangle getHeaderBounds(int col) { >+ Rectangle returnvalue = (Rectangle) getEventThreadQueuer() >+ .invokeAndWait("getHeaderBounds", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() throws StepExecutionException { >+ return m_table.getTableHeader().getBounds(); >+ } >+ }); >+ >+ return returnvalue; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public Cell getSelectedCell() throws StepExecutionException { >+ >+ Cell returnvalue = (Cell) getEventThreadQueuer().invokeAndWait( >+ "getSelectedCell", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ >+ int row = m_table.getSelectedRow(); >+ int col = m_table.getSelectedColumn(); >+ if (log.isDebugEnabled()) { >+ log.debug("Selected row, col: " + row + ", " + col); //$NON-NLS-1$ //$NON-NLS-2$ >+ } >+ try { >+ checkRowColBounds(row, col); >+ } catch (StepExecutionException e) { >+ if ((e.getEvent() != null) >+ && (TestErrorEvent.INVALID_INDEX.equals( >+ e.getEvent() >+ .getProps().get(TestErrorEvent >+ .Property >+ .DESCRIPTION_KEY)))) { >+ // set "invalid index" to "no selection" -> better description! >+ throw new StepExecutionException("No selection", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.NO_SELECTION)); >+ } >+ throw e; >+ } >+ return new Cell(row, col); >+ } >+ }); >+ return returnvalue; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isHeaderVisible() { >+ Boolean returnvalue = (Boolean) getEventThreadQueuer().invokeAndWait( >+ "isHeaderVisible", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ if (m_table.getTableHeader() != null) { >+ return m_table.getTableHeader().isVisible() >+ ? Boolean.TRUE : Boolean.FALSE; >+ } >+ return Boolean.FALSE; >+ } >+ }); >+ return (boolean) returnvalue.booleanValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isCellEditable(int row, int col) { >+ Boolean editable = (Boolean) getEventThreadQueuer().invokeAndWait( >+ "isCellEditable", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ Cell cell = getSelectedCell(); >+ // see findBugs >+ return (m_table.isCellEditable(cell.getRow(), >+ cell.getCol())) ? Boolean.TRUE : Boolean.FALSE; >+ } >+ }); >+ return editable.booleanValue(); >+ } >+ >+ /** >+ * Checks wether <code>0 <= value < count</code>. >+ * >+ * @param value >+ * The value to check. >+ * @param count >+ * The upper bound. >+ */ >+ private void checkBounds(int value, int count) { >+ if ((value < 0) || (value >= count)) { >+ throw new StepExecutionException("Invalid row/column: " + value, //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.INVALID_INDEX_OR_HEADER)); >+ } >+ } >+ >+ /** >+ * Checks if the passed row and column are inside the bounds of the JTable. >+ * >+ * @param row >+ * The row >+ * @param column >+ * The column >+ * @throws StepExecutionException >+ * If the row or the column is outside of the JTable's bounds. >+ */ >+ private void checkRowColBounds(int row, int column) >+ throws StepExecutionException { >+ checkBounds(row, m_table.getRowCount()); >+ checkBounds(column, m_table.getColumnCount()); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean hasCellSelection() { >+ try { >+ getSelectedCell(); >+ } catch (StepExecutionException e) { >+ return false; >+ } >+ return true; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public Rectangle scrollCellToVisible(final int row, final int col) >+ throws StepExecutionException { >+ Rectangle bounds = (Rectangle) getEventThreadQueuer().invokeAndWait( >+ "getCellRect", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ return m_table >+ .getCellRect(row, col, true); >+ } >+ }); >+ >+ getRobot().scrollToVisible(m_table, bounds); >+ return bounds; >+ } >+} >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JTreeAdapter.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JTreeAdapter.java >new file mode 100644 >index 0000000..acc0012 >--- /dev/null >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/JTreeAdapter.java >@@ -0,0 +1,65 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swing.swing.uiadapter; >+ >+import javax.swing.JTree; >+ >+//import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.implclasses.tree.AbstractTreeOperationContext; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.ITreeAdapter; >+import org.eclipse.jubula.rc.swing.swing.implclasses.TreeOperationContext; >+/** >+ * Implementation of the Tree interface as an adapter for <code>JTree</code>. >+ * >+ * @author BREDEX GmbH >+ * >+ */ >+public class JTreeAdapter extends WidgetAdapter implements ITreeAdapter { >+ >+ >+ /** >+ * Creates an object with the adapted JMenu. >+ * @param objectToAdapt >+ */ >+ public JTreeAdapter(Object objectToAdapt) { >+ super(objectToAdapt); >+ } >+ >+ /** >+ * @return the casted Object >+ */ >+ private JTree getTable() { >+ return (JTree) getRealComponent(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public AbstractTreeOperationContext getContext() { >+ TreeOperationContext context = new TreeOperationContext( >+ getEventThreadQueuer(), getRobot(), getTable()); >+ return context; >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public Object getRootNode() { >+ >+ return getTable().getModel().getRoot(); >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isRootVisible() { >+ return getTable().isRootVisible(); >+ } >+ >+} >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/WidgetAdapter.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/WidgetAdapter.java >new file mode 100644 >index 0000000..190f1ad >--- /dev/null >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/WidgetAdapter.java >@@ -0,0 +1,334 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swing.swing.uiadapter; >+ >+ >+import java.awt.AWTEvent; >+import java.awt.Toolkit; >+ >+import javax.swing.JComponent; >+ >+import org.eclipse.jubula.rc.common.caps.AbstractMenuCAPs; >+import org.eclipse.jubula.rc.common.driver.ClickOptions; >+import org.eclipse.jubula.rc.common.driver.DragAndDropHelper; >+import org.eclipse.jubula.rc.common.driver.IEventThreadQueuer; >+import org.eclipse.jubula.rc.common.driver.IRobot; >+import org.eclipse.jubula.rc.common.driver.IRobotFactory; >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.driver.RobotTiming; >+import org.eclipse.jubula.rc.common.exception.RobotException; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.listener.EventLock; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IWidgetAdapter; >+import org.eclipse.jubula.rc.swing.driver.RobotFactoryConfig; >+import org.eclipse.jubula.rc.swing.swing.caps.CapUtil; >+import org.eclipse.jubula.rc.swing.swing.caps.JMenuBarCAPs; >+import org.eclipse.jubula.rc.swing.swing.caps.CapUtil.PopupShownCondition; >+import org.eclipse.jubula.rc.swing.swing.implclasses.EventListener; >+import org.eclipse.jubula.tools.constants.TimeoutConstants; >+import org.eclipse.jubula.tools.i18n.I18n; >+import org.eclipse.jubula.tools.objects.event.EventFactory; >+import org.eclipse.jubula.tools.objects.event.TestErrorEvent; >+import org.eclipse.jubula.tools.utils.TimeUtil; >+/** >+ * Implements the interface for widgets and supports basic methods >+ * which are needed for nearly all Swing ui components. >+ * This is a basic adaption for <code>JComponent</code>. >+ * >+ * @author BREDEX GmbH >+ */ >+public abstract class WidgetAdapter implements IWidgetAdapter { >+ >+ /** constants for communication */ >+ protected static final String POS_UNIT_PIXEL = "Pixel"; //$NON-NLS-1$ >+ /** constants for communication */ >+ protected static final String POS_UNI_PERCENT = "Percent"; //$NON-NLS-1$ >+ >+ /** the RobotFactory from the AUT */ >+ private IRobotFactory m_robotFactory; >+ >+ >+ >+ /** */ >+ private JComponent m_component; >+ >+ /** >+ * Used to store the component into the adapter. >+ * @param objectToAdapt >+ */ >+ protected WidgetAdapter(Object objectToAdapt) { >+ m_component = (JComponent) objectToAdapt; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public Object getRealComponent() { >+ return m_component; >+ } >+ >+ /** >+ * Gets the Robot factory. The factory is created once per instance. >+ * >+ * @return The Robot factory. >+ */ >+ protected IRobotFactory getRobotFactory() { >+ if (m_robotFactory == null) { >+ m_robotFactory = new RobotFactoryConfig().getRobotFactory(); >+ } >+ return m_robotFactory; >+ } >+ /** >+ * Gets the IEventThreadQueuer. >+ * >+ * @return The Robot >+ * @throws RobotException >+ * If the Robot cannot be created. >+ */ >+ protected IRobot getRobot() throws RobotException { >+ return getRobotFactory().getRobot(); >+ } >+ /** >+ * @return The event thread queuer. >+ */ >+ public IEventThreadQueuer getEventThreadQueuer() { >+ return getRobotFactory().getEventThreadQueuer(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String getPropteryValue(final String propertyname) { >+ Object prop = getEventThreadQueuer().invokeAndWait("getProperty", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() throws StepExecutionException { >+ try { >+ return getRobot().getPropertyValue( >+ getRealComponent(), propertyname); >+ } catch (RobotException e) { >+ throw new StepExecutionException( >+ e.getMessage(), >+ EventFactory.createActionError( >+ TestErrorEvent.PROPERTY_NOT_ACCESSABLE)); >+ } >+ } >+ }); >+ return String.valueOf(prop); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isShowing() { >+ Boolean returnvalue = (Boolean) getEventThreadQueuer().invokeAndWait( >+ "isShowing", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return m_component.isShowing() >+ ? Boolean.TRUE : Boolean.FALSE; >+ } >+ }); >+ return (boolean) returnvalue.booleanValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean hasFocus() { >+ Boolean returnvalue = (Boolean) getEventThreadQueuer().invokeAndWait( >+ "hasFocus", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return m_component.hasFocus() >+ ? Boolean.TRUE : Boolean.FALSE; >+ } >+ }); >+ return (boolean) returnvalue.booleanValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isEnabled() { >+ Boolean returnvalue = (Boolean) getEventThreadQueuer().invokeAndWait( >+ "isEnabled", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return m_component.isEnabled() >+ ? Boolean.TRUE : Boolean.FALSE; >+ } >+ }); >+ return (boolean) returnvalue.booleanValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public AbstractMenuCAPs showPopup(final int button) { >+ final Object component = m_component; >+ Runnable showPopup = new Runnable() { >+ public void run() { >+ RobotTiming.sleepPreShowPopupDelay(); >+ ClassLoader oldCl = Thread.currentThread() >+ .getContextClassLoader(); >+ Thread.currentThread().setContextClassLoader(component >+ .getClass().getClassLoader()); >+ if ((getRobot()).isMouseInComponent(component)) { >+ getRobot().clickAtCurrentPosition( >+ component, 1, button); >+ } else { >+ getRobot().click(component, null, >+ ClickOptions.create() >+ .setClickCount(1) >+ .setMouseButton(button)); >+ } >+ Thread.currentThread().setContextClassLoader(oldCl); >+ } >+ }; >+ >+ return showPopup(showPopup); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public AbstractMenuCAPs showPopup( >+ final int xPos, final String xUnits, >+ final int yPos, final String yUnits, final int button) >+ throws StepExecutionException { >+ final Object component = m_component; >+ Runnable showPopup = new Runnable() { >+ public void run() { >+ RobotTiming.sleepPreShowPopupDelay(); >+ boolean isAbsoluteCoordinatesX = >+ xUnits.equalsIgnoreCase(POS_UNIT_PIXEL); >+ boolean isAbsoluteCoordinatesY = >+ yUnits.equalsIgnoreCase(POS_UNIT_PIXEL); >+ getRobot().click(component, null, >+ ClickOptions.create().setMouseButton(button), >+ xPos, isAbsoluteCoordinatesX, >+ yPos, isAbsoluteCoordinatesY); >+ } >+ }; >+ return showPopup(showPopup); >+ } >+ >+ /** >+ * Shows a popup menu using the given runnable and waits for the popup >+ * menu to appear. >+ * >+ * @param showPopupOperation The implementation to use for opening the >+ * popup menu. >+ * @return the popup menu. >+ */ >+ public AbstractMenuCAPs showPopup(Runnable showPopupOperation) { >+ PopupShownCondition cond = new PopupShownCondition(); >+ EventLock lock = new EventLock(); >+ EventListener listener = new EventListener(lock, cond); >+ Toolkit.getDefaultToolkit().addAWTEventListener(listener, >+ AWTEvent.CONTAINER_EVENT_MASK); >+ >+ // showPopupOperation must run in the current thread in order to >+ // avoid a race condition. >+ showPopupOperation.run(); >+ >+ synchronized (lock) { >+ try { >+ long timeout = TimeoutConstants.SERVER_TIMEOUT_WAIT_FOR_POPUP; >+ long done = System.currentTimeMillis() + timeout; >+ long now; >+ while ((!lock.isReleased() || (cond.getPopup() == null) >+ || !cond.getPopup().isShowing()) >+ && (timeout > 0)) { >+ lock.wait(timeout); >+ now = System.currentTimeMillis(); >+ timeout = done - now; >+ } >+ } catch (InterruptedException e) { >+ // ignore >+ } finally { >+ Toolkit.getDefaultToolkit().removeAWTEventListener(listener); >+ } >+ } >+ if (!lock.isReleased() || (cond.getPopup() == null) >+ || !cond.getPopup().isShowing()) { >+ throw new StepExecutionException("popup not shown", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.POPUP_NOT_FOUND)); >+ } >+ AbstractMenuCAPs menuCAPs = new JMenuBarCAPs(); >+ menuCAPs.setComponent(cond.getPopup()); >+ return menuCAPs; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void showToolTip(final String text, final int textSize, >+ final int timePerWord, final int windowWidth) { >+ throw new StepExecutionException( >+ I18n.getString(TestErrorEvent.UNSUPPORTED_OPERATION_ERROR), >+ EventFactory.createActionError( >+ TestErrorEvent.UNSUPPORTED_OPERATION_ERROR)); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdDrag(int mouseButton, String modifier, int xPos, >+ String xUnits, int yPos, String yUnits) { >+ final DragAndDropHelper dndHelper = DragAndDropHelper.getInstance(); >+ dndHelper.setMouseButton(mouseButton); >+ dndHelper.setModifier(modifier); >+ final IRobot robot = getRobot(); >+ clickDirect(0, mouseButton, xPos, xUnits, yPos, yUnits); >+ CapUtil.pressOrReleaseModifiers(modifier, true); >+ robot.mousePress(null, null, mouseButton); >+ } >+ >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdDrop(int xPos, String xUnits, int yPos, String yUnits, >+ int delayBeforeDrop) { >+ >+ final DragAndDropHelper dndHelper = DragAndDropHelper.getInstance(); >+ final String modifier = dndHelper.getModifier(); >+ final int mouseButton = dndHelper.getMouseButton(); >+ try { >+ clickDirect(0, mouseButton, xPos, xUnits, yPos, yUnits); >+ TimeUtil.delay(delayBeforeDrop); >+ } finally { >+ getRobot().mouseRelease(null, null, mouseButton); >+ CapUtil.pressOrReleaseModifiers(modifier, false); >+ } >+ } >+ >+ /** >+ * clicks into the component. >+ * >+ * @param count amount of clicks >+ * @param button what mouse button should be used >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @throws StepExecutionException error >+ */ >+ private void clickDirect(int count, int button, int xPos, String xUnits, >+ int yPos, String yUnits) throws StepExecutionException { >+ >+ getRobot().click(m_component, null, >+ ClickOptions.create() >+ .setClickCount(count) >+ .setMouseButton(button), >+ xPos, xUnits.equalsIgnoreCase(POS_UNIT_PIXEL), >+ yPos, yUnits.equalsIgnoreCase(POS_UNIT_PIXEL)); >+ } >+} >diff --git a/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/factory/SwingAdapterFactory.java b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/factory/SwingAdapterFactory.java >new file mode 100644 >index 0000000..e043a5b >--- /dev/null >+++ b/org.eclipse.jubula.rc.swing/src/org/eclipse/jubula/rc/swing/swing/uiadapter/factory/SwingAdapterFactory.java >@@ -0,0 +1,92 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swing.swing.uiadapter.factory; >+ >+ >+import javax.swing.JButton; >+import javax.swing.JCheckBox; >+import javax.swing.JMenuBar; >+import javax.swing.JMenuItem; >+import javax.swing.JPopupMenu; >+import javax.swing.JRadioButton; >+import javax.swing.JTable; >+import javax.swing.JTree; >+ >+import org.eclipse.jubula.rc.common.uiadapter.factory.IUIAdapterFactory; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IComponentAdapter; >+import org.eclipse.jubula.rc.swing.swing.uiadapter.AbstractButtonAdapter; >+import org.eclipse.jubula.rc.swing.swing.uiadapter.JMenuBarAdapter; >+import org.eclipse.jubula.rc.swing.swing.uiadapter.JMenuItemAdapter; >+import org.eclipse.jubula.rc.swing.swing.uiadapter.JPopupMenuAdapter; >+import org.eclipse.jubula.rc.swing.swing.uiadapter.JTableAdapter; >+import org.eclipse.jubula.rc.swing.swing.uiadapter.JTreeAdapter; >+/** >+ * This is the adapter factory for all swing components. It is >+ * creating the specific adapter for a swing component. >+ * >+ * Since we are using adapter here, it is a adapter factory. But this must not >+ * be the case. It is only relevant that the object is implementing the >+ * specific interface. >+ * @author BREDEX GmbH >+ * >+ */ >+public class SwingAdapterFactory implements IUIAdapterFactory { >+ /** >+ * >+ */ >+ private static final Class[] SUPPORTEDCLASSES = new Class[] { >+ JButton.class, JCheckBox.class, JRadioButton.class, >+ JMenuBar.class, JMenuItem.class, JTree.class , >+ JCheckBox.class, JRadioButton.class, JTable.class, JPopupMenu.class}; >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public Class[] getSupportedClasses() { >+ >+ return SUPPORTEDCLASSES; >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public IComponentAdapter getAdapter(Object objectToAdapt) { >+ IComponentAdapter returnvalue = null; >+ if (objectToAdapt instanceof JButton) { >+ returnvalue = new AbstractButtonAdapter(objectToAdapt); >+ >+ } else if (objectToAdapt instanceof JRadioButton) { >+ returnvalue = new AbstractButtonAdapter(objectToAdapt); >+ >+ } else if (objectToAdapt instanceof JCheckBox) { >+ returnvalue = new AbstractButtonAdapter(objectToAdapt); >+ >+ } else if (objectToAdapt instanceof JMenuBar) { >+ >+ returnvalue = new JMenuBarAdapter(objectToAdapt); >+ >+ } else if (objectToAdapt instanceof JMenuItem) { >+ returnvalue = new JMenuItemAdapter(objectToAdapt); >+ >+ } else if (objectToAdapt instanceof JTree) { >+ returnvalue = new JTreeAdapter(objectToAdapt); >+ >+ } else if (objectToAdapt instanceof JTable) { >+ returnvalue = new JTableAdapter(objectToAdapt); >+ >+ } else if (objectToAdapt instanceof JPopupMenu) { >+ returnvalue = new JPopupMenuAdapter(objectToAdapt); >+ >+ } >+ >+ return returnvalue; >+ } >+ >+} >diff --git a/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/SwtAUTServer.java b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/SwtAUTServer.java >index f08722a..9ae5801 100644 >--- a/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/SwtAUTServer.java >+++ b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/SwtAUTServer.java >@@ -15,6 +15,7 @@ import java.lang.reflect.InvocationTargetException; > import org.eclipse.jubula.rc.common.AUTServer; > import org.eclipse.jubula.rc.common.driver.IRobot; > import org.eclipse.jubula.rc.common.listener.BaseAUTListener; >+import org.eclipse.jubula.rc.common.uiadapter.factory.GUIAdapterFactoryRegistry; > import org.eclipse.jubula.rc.swt.driver.RobotFactoryConfig; > import org.eclipse.jubula.rc.swt.driver.RobotFactorySwtImpl; > import org.eclipse.jubula.rc.swt.driver.RobotSwtImpl; >@@ -25,6 +26,7 @@ import org.eclipse.jubula.rc.swt.listener.FocusTracker; > import org.eclipse.jubula.rc.swt.listener.MappingListener; > import org.eclipse.jubula.rc.swt.listener.RecordListener; > import org.eclipse.jubula.rc.swt.listener.TableSelectionTracker; >+import org.eclipse.jubula.rc.swt.uiadapter.factory.SWTAdapterFactory; > import org.eclipse.jubula.tools.constants.AUTServerExitConstants; > import org.eclipse.jubula.tools.constants.DebugConstants; > import org.eclipse.swt.widgets.Display; >@@ -215,11 +217,17 @@ public class SwtAUTServer extends AUTServer { > */ > protected void startTasks() throws ExceptionInInitializerError, > InvocationTargetException, NoSuchMethodException { >- >+ >+ // FIXME Better place to put the registration of the factory >+ GUIAdapterFactoryRegistry.getInstance(). >+ registerFactory(new SWTAdapterFactory()); >+ System.out.println("AdapterFactory registered"); //$NON-NLS-1$ >+ > super.invokeAUT(); > if (getCommunicator() != null) { > getCommunicator().close(); > } >+ > } > > /** >diff --git a/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/ButtonCAPs.java b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/ButtonCAPs.java >new file mode 100644 >index 0000000..a24ca6d >--- /dev/null >+++ b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/ButtonCAPs.java >@@ -0,0 +1,52 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swt.caps; >+ >+ >+import org.eclipse.jubula.rc.common.caps.AbstractButtonCAPs; >+import org.eclipse.jubula.rc.common.driver.IRobotFactory; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IButtonAdapter; >+import org.eclipse.jubula.rc.swt.driver.RobotFactoryConfig; >+import org.eclipse.jubula.rc.swt.utils.SwtUtils; >+ >+ >+/** >+ * The Toolkit specific implementation for <code>SWTButton</code> and subclasses. >+ * >+ * @author BREDEX GmbH >+ */ >+public class ButtonCAPs extends AbstractButtonCAPs { >+ >+ /** The robot factory. */ >+ private IRobotFactory m_robotFactory; >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String[] getTextArrayFromComponent() { >+ return new String[] { >+ SwtUtils.removeMnemonics( >+ ((IButtonAdapter)getComponent()).getText())}; >+ } >+ >+ /** >+ * Gets the Robot factory. The factory is created once per instance. >+ * @return The Robot factory. >+ */ >+ protected IRobotFactory getRobotFactory() { >+ if (m_robotFactory == null) { >+ m_robotFactory = new RobotFactoryConfig().getRobotFactory(); >+ } >+ return m_robotFactory; >+ } >+ >+ >+} >\ No newline at end of file >diff --git a/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/CAPUtil.java b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/CAPUtil.java >new file mode 100644 >index 0000000..b1d0361 >--- /dev/null >+++ b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/CAPUtil.java >@@ -0,0 +1,108 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swt.caps; >+ >+import java.awt.Point; >+import java.util.StringTokenizer; >+ >+import org.eclipse.jubula.rc.common.AUTServer; >+import org.eclipse.jubula.rc.common.driver.IRobot; >+import org.eclipse.jubula.rc.common.exception.RobotException; >+import org.eclipse.jubula.rc.common.util.KeyStrokeUtil; >+import org.eclipse.jubula.rc.swt.driver.KeyCodeConverter; >+import org.eclipse.jubula.rc.swt.driver.SwtRobot; >+import org.eclipse.jubula.tools.utils.EnvironmentUtils; >+import org.eclipse.jubula.tools.utils.TimeUtil; >+import org.eclipse.swt.widgets.Display; >+/** >+ * Util class for some swt specific commands. >+ * >+ * @author BREDEX GmbH >+ */ >+public class CAPUtil { >+ >+ >+ /** >+ * >+ */ >+ private CAPUtil() { } >+ >+ >+ /** >+ * Gets the Robot. >+ * @return The Robot >+ * @throws RobotException If the Robot cannot be created. >+ */ >+ public static IRobot getRobot() throws RobotException { >+ return AUTServer.getInstance().getRobot(); >+ } >+ >+ /** >+ * Waits the given amount of time. Logs a drop-related error if interrupted. >+ * >+ * @param delayBeforeDrop the amount of time (in milliseconds) to wait >+ * between moving the mouse to the drop point and >+ * releasing the mouse button >+ */ >+ public static void waitBeforeDrop(int delayBeforeDrop) { >+ TimeUtil.delay(delayBeforeDrop); >+ } >+ >+ /** >+ * Move the mouse pointer from its current position to a few points in >+ * its proximity. This is used to initiate a drag operation. >+ * >+ */ >+ public static void shakeMouse() { >+ /** number of pixels by which a "mouse shake" offsets the mouse cursor */ >+ final int mouseShakeOffset = 10; >+ >+ Point origin = getRobot().getCurrentMousePosition(); >+ SwtRobot lowLevelRobot = new SwtRobot(Display.getDefault()); >+ lowLevelRobot.mouseMove( >+ origin.x + mouseShakeOffset, >+ origin.y + mouseShakeOffset); >+ lowLevelRobot.mouseMove( >+ origin.x - mouseShakeOffset, >+ origin.y - mouseShakeOffset); >+ lowLevelRobot.mouseMove(origin.x, origin.y); >+ if (!EnvironmentUtils.isWindowsOS() >+ && !EnvironmentUtils.isMacOS()) { >+ boolean moreEvents = true; >+ while (moreEvents) { >+ moreEvents = Display.getDefault().readAndDispatch(); >+ } >+ } >+ } >+ >+ /** >+ * Presses or releases the given modifier. >+ * @param modifier the modifier. >+ * @param press if true, the modifier will be pressed. >+ * if false, the modifier will be released. >+ */ >+ public static void pressOrReleaseModifiers(String modifier, boolean press) { >+ final IRobot robot = getRobot(); >+ final StringTokenizer modTok = new StringTokenizer( >+ KeyStrokeUtil.getModifierString(modifier), " "); //$NON-NLS-1$ >+ while (modTok.hasMoreTokens()) { >+ final String mod = modTok.nextToken(); >+ final int keyCode = KeyCodeConverter.getKeyCode(mod); >+ if (press) { >+ robot.keyPress(null, keyCode); >+ } else { >+ robot.keyRelease(null, keyCode); >+ } >+ } >+ } >+ >+ >+} >diff --git a/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/MenuCAPs.java b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/MenuCAPs.java >new file mode 100644 >index 0000000..77d5271 >--- /dev/null >+++ b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/MenuCAPs.java >@@ -0,0 +1,328 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swt.caps; >+ >+import org.apache.commons.lang.Validate; >+import org.eclipse.jubula.rc.common.caps.AbstractMenuCAPs; >+import org.eclipse.jubula.rc.common.driver.IEventThreadQueuer; >+import org.eclipse.jubula.rc.common.driver.IRobot; >+import org.eclipse.jubula.rc.common.driver.IRobotFactory; >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.exception.RobotException; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.implclasses.IBaseImplementationClass; >+import org.eclipse.jubula.rc.common.implclasses.MenuUtilBase; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IComponentAdapter; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuAdapter; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuItemAdapter; >+import org.eclipse.jubula.rc.swt.driver.EventThreadQueuerSwtImpl; >+import org.eclipse.jubula.rc.swt.driver.RobotFactoryConfig; >+import org.eclipse.jubula.rc.swt.driver.RobotSwtImpl; >+import org.eclipse.jubula.rc.swt.uiadapter.MenuItemAdapter; >+import org.eclipse.jubula.tools.i18n.I18n; >+import org.eclipse.jubula.tools.objects.event.EventFactory; >+import org.eclipse.jubula.tools.objects.event.TestErrorEvent; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.events.MenuEvent; >+import org.eclipse.swt.events.MenuListener; >+import org.eclipse.swt.graphics.Rectangle; >+import org.eclipse.swt.widgets.Menu; >+import org.eclipse.swt.widgets.Shell; >+/** >+ * Toolkit specific commands for the <code>Menu</code> >+ * >+ * @author BREDEX GmbH >+ */ >+public class MenuCAPs extends AbstractMenuCAPs >+ implements IBaseImplementationClass { >+ /** the RobotFactory from the AUT */ >+ private IRobotFactory m_robotFactory; >+ >+ /** Test variable for contextMenus*/ >+ private boolean m_isCM = false; >+ /** >+ * Gets the IEventThreadQueuer. >+ * >+ * @return The Robot >+ * @throws RobotException >+ * If the Robot cannot be created. >+ */ >+ protected IRobot getRobot() throws RobotException { >+ return getRobotFactory().getRobot(); >+ } >+ >+ /** >+ * @return The event thread queuer. >+ */ >+ public IEventThreadQueuer getEventThreadQueuer() { >+ return getRobotFactory().getEventThreadQueuer(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public IComponentAdapter getComponent() { >+ if (m_isCM) { >+ return super.getComponent(); >+ } >+ final Shell shell = ((RobotSwtImpl)getRobot()).getActiveWindow(); >+ if (shell == null) { >+ setComponent(null); >+ } else { >+ final IEventThreadQueuer queuer = new EventThreadQueuerSwtImpl(); >+ >+ queuer.invokeAndWait("setMenuBarComponent", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ Menu menu = shell.getMenuBar(); >+ setComponent(menu); >+ >+ return null; >+ } >+ }); >+ } >+ return super.getComponent(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String[] getTextArrayFromComponent() { >+ return null; >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ protected IRobotFactory getRobotFactory() { >+ if (m_robotFactory == null) { >+ m_robotFactory = new RobotFactoryConfig().getRobotFactory(); >+ } >+ return m_robotFactory; >+ } >+ >+ /** >+ * Tries to select a menu item in a menu defined by a Text-Path >+ * @param namePath the menu item to select >+ * @param operator operator used for matching >+ */ >+ public void selectMenuItem(String namePath, final String operator) { >+ final String[] pathItems = MenuUtilBase.splitPath(namePath); >+ if (pathItems.length == 0) { >+ throw new StepExecutionException("empty path to menuitem not allowed", //$NON-NLS-1$ >+ EventFactory.createActionError()); >+ } >+ >+ try { >+ >+ final MenuItemAdapter itemAdapter = >+ (MenuItemAdapter) navigateToMenuItem( >+ getAndCheckMenu(), pathItems, operator); >+ if (itemAdapter.getRealComponent() == null) { >+ throwMenuItemNotFound(); >+ } >+ >+ Rectangle bounds = itemAdapter.getMenuItemBounds(); >+ Rectangle nullBounds = new Rectangle(0, 0, 0, 0); >+ >+ if (bounds.equals(nullBounds)) { >+ itemAdapter.selectProgramatically(); >+ } else { >+ itemAdapter.selectMenuItem(); >+ } >+ } catch (StepExecutionException e) { >+ try { >+ closeMenu(getAndCheckMenu(), pathItems, operator); >+ } catch (StepExecutionException e1) { >+ if (getLog().isInfoEnabled()) { >+ getLog().info("Tried to close a disabled or already closed menu."); //$NON-NLS-1$ >+ } >+ } >+ throw e; >+ } >+ >+ } >+ >+ /** >+ * Tries to select a menu item in a menu defined by an Index-Path >+ * @param indexPath the menu item to select >+ */ >+ public void selectMenuItemByIndexpath(String indexPath) { >+ final int[] indexItems = MenuUtilBase.splitIndexPath(indexPath); >+ if (indexItems.length == 0) { >+ throw new StepExecutionException("empty path to menuitem not allowed", //$NON-NLS-1$ >+ EventFactory.createActionError()); >+ } >+ >+ try { >+ MenuItemAdapter menuItemAdapter = (MenuItemAdapter) >+ navigateToMenuItem(getAndCheckMenu(), indexItems); >+ if (menuItemAdapter.getRealComponent() == null) { >+ throwMenuItemNotFound(); >+ } >+ >+ Rectangle bounds = menuItemAdapter.getMenuItemBounds(); >+ Rectangle nullBounds = new Rectangle(0, 0, 0, 0); >+ >+ if (bounds.equals(nullBounds)) { >+ menuItemAdapter.selectProgramatically(); >+ } else { >+ menuItemAdapter.selectMenuItem(); >+ } >+ } catch (StepExecutionException e) { >+ try { >+ closeMenu(getAndCheckMenu(), indexItems); >+ } catch (StepExecutionException e1) { >+ if (getLog().isInfoEnabled()) { >+ getLog().info("Tried to close a disabled or already closed menu."); //$NON-NLS-1$ >+ } >+ } >+ throwMenuItemNotFound(); >+ } >+ } >+ >+ /** >+ * >+ * @return the IMenuAdapter. >+ * @throws StepExecutionException >+ * if the active window has no menu bar. >+ */ >+ protected IMenuAdapter getAndCheckMenu() throws StepExecutionException { >+ // Verify that there is an active window >+ if (((RobotSwtImpl)getRobot()).getActiveWindow() == null) { >+ throw new StepExecutionException( >+ I18n.getString(TestErrorEvent.NO_ACTIVE_WINDOW), >+ EventFactory.createActionError( >+ TestErrorEvent.NO_ACTIVE_WINDOW)); >+ } >+ return super.getAndCheckMenu(); >+ } >+ >+ >+ /** >+ * >+ */ >+ private void throwMenuItemNotFound() { >+ throw new StepExecutionException("no such menu item found", //$NON-NLS-1$ >+ EventFactory.createActionError(TestErrorEvent.NOT_FOUND)); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected IMenuItemAdapter newMenuItemAdapter(Object component) { >+ return new MenuItemAdapter(component); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected void closeMenu(IMenuAdapter menuBar, int[] path) { >+ Validate.notNull(getMenu(menuBar)); >+ closeMenu(menuBar, path.length); >+ >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected void closeMenu(IMenuAdapter menuBar, String[] textPath, >+ String operator) { >+ Validate.notNull(getMenu(menuBar)); >+ closeMenu(menuBar, textPath.length); >+ } >+ >+ /** >+ * Closes the menu cascade with the KEY ESC >+ * @param menuBar menu >+ * @param maxCascadeLength an integer so that the closing operation is not infinite >+ */ >+ private void closeMenu(final IMenuAdapter menuBar, int maxCascadeLength) { >+ final MenuHiddenListener menuListener = >+ new MenuHiddenListener(); >+ getMenu(menuBar).getDisplay().syncExec(new Runnable() { >+ public void run() { >+ getMenu(menuBar).addMenuListener(menuListener); >+ } >+ }); >+ // Press 'ESC' key until the first menu is gone or we reach >+ // the maxCascadeLength. This prevents infinite loops if this >+ // is used on a platform that does not use 'ESC' to close menus. >+ for (int i = 0; >+ i < maxCascadeLength && !menuListener.isMenuHidden(); >+ i++) { >+ >+ getRobot().keyType(getMenu(menuBar), SWT.ESC); >+ } >+ >+ } >+ >+ /** >+ * >+ * @param menu the menu adapter >+ * @return the real SWT menu >+ */ >+ private Menu getMenu(final IMenuAdapter menu) { >+ return (Menu) menu.getRealComponent(); >+ } >+ /** >+ * >+ * @return - >+ */ >+ public boolean isContextMenu() { >+ return m_isCM; >+ } >+ /** >+ * >+ * @param isCM >+ */ >+ public void setContextMenu(boolean isCM) { >+ this.m_isCM = isCM; >+ } >+ >+ /** >+ * Listens for a menu to be hidden, the removes itself from the menu's >+ * listener list. >+ * >+ * @author BREDEX GmbH >+ * @created Nov 01, 2011 >+ */ >+ private static final class MenuHiddenListener implements MenuListener { >+ >+ /** whether the expected event has occurred */ >+ private boolean m_eventOccurred = false; >+ >+ /** >+ * >+ * {@inheritDoc} >+ */ >+ public void menuHidden(MenuEvent e) { >+ m_eventOccurred = true; >+ ((Menu)e.widget).removeMenuListener(this); >+ } >+ >+ /** >+ * >+ * {@inheritDoc} >+ */ >+ public void menuShown(MenuEvent e) { >+ // no-op >+ } >+ >+ /** >+ * >+ * @return <code>true</code> if the menu has been hidden since this >+ * listener was registered. Otherwise, <code>false</code>. >+ */ >+ public boolean isMenuHidden() { >+ return m_eventOccurred; >+ } >+ } >+ >+} >diff --git a/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/TableCAPs.java b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/TableCAPs.java >new file mode 100644 >index 0000000..bbb668f >--- /dev/null >+++ b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/TableCAPs.java >@@ -0,0 +1,737 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swt.caps; >+ >+import java.awt.Point; >+import java.awt.Rectangle; >+ >+import org.eclipse.jubula.rc.common.CompSystemConstants; >+import org.eclipse.jubula.rc.common.caps.AbstractTableCAPs; >+import org.eclipse.jubula.rc.common.driver.ClickOptions; >+import org.eclipse.jubula.rc.common.driver.IEventThreadQueuer; >+import org.eclipse.jubula.rc.common.driver.IRobot; >+import org.eclipse.jubula.rc.common.driver.IRobotFactory; >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.implclasses.table.Cell; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.ITableAdapter; >+import org.eclipse.jubula.rc.swt.driver.DragAndDropHelperSwt; >+import org.eclipse.jubula.rc.swt.driver.KeyCodeConverter; >+import org.eclipse.jubula.rc.swt.driver.RobotFactoryConfig; >+import org.eclipse.jubula.rc.swt.uiadapter.TableAdapter; >+import org.eclipse.jubula.rc.swt.utils.SwtUtils; >+import org.eclipse.jubula.tools.constants.InputConstants; >+import org.eclipse.jubula.tools.objects.event.EventFactory; >+import org.eclipse.jubula.tools.objects.event.TestErrorEvent; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.graphics.FontMetrics; >+import org.eclipse.swt.graphics.GC; >+import org.eclipse.swt.graphics.Image; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Item; >+import org.eclipse.swt.widgets.Table; >+import org.eclipse.swt.widgets.TableColumn; >+import org.eclipse.swt.widgets.TableItem; >+import org.eclipse.swt.widgets.Widget; >+/** >+ * Toolkit specific commands for the <code>Table</code> >+ * >+ * @author BREDEX GmbH >+ */ >+public class TableCAPs extends AbstractTableCAPs { >+ >+ /** */ >+ private IRobotFactory m_robotFactory; >+ >+ /** >+ * Gets the real table component >+ * @return the table >+ */ >+ private Table getTable() { >+ return (Table)getComponent().getRealComponent(); >+ } >+ >+ /** >+ * @return The event thread queuer. >+ */ >+ public IEventThreadQueuer getEventThreadQueuer() { >+ return getRobotFactory().getEventThreadQueuer(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String[] getTextArrayFromComponent() { >+ final String[] componentTextArray; >+ Item[] itemArray = getTable().getColumns(); >+ componentTextArray = getTextArrayFromItemArray(itemArray); >+ return componentTextArray; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected int getKeyCode(String mod) { >+ return KeyCodeConverter.getKeyCode(mod); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected Object setEditorToReplaceMode(Object editor, boolean replace) { >+ if (replace) { >+ getRobot().clickAtCurrentPosition(editor, 3, >+ InputConstants.MOUSE_BUTTON_LEFT); >+ } else { >+ getRobot().clickAtCurrentPosition(editor, 1, >+ InputConstants.MOUSE_BUTTON_LEFT); >+ } >+ return editor; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected Object activateEditor(Cell cell, Rectangle rectangle) { >+ TableAdapter table = (TableAdapter) getComponent(); >+ return table.activateEditor(cell); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected Rectangle scrollCellToVisible(final int row, final int col) >+ throws StepExecutionException { >+ final Table table = getTable(); >+ getEventThreadQueuer().invokeAndWait("scrollCellToVisible", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ if (table.getColumnCount() > 0 || col > 0) { >+ table.showColumn(table.getColumn(col)); >+ } >+ table.showItem(table.getItem(row)); >+ return null; >+ } >+ }); >+ >+ final Rectangle cellBoundsRelativeToParent = getCellBounds(row, col); >+ >+ getEventThreadQueuer().invokeAndWait("getCellBoundsRelativeToParent", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ org.eclipse.swt.graphics.Point cellOriginRelativeToParent = >+ table.getDisplay().map( >+ table, table.getParent(), >+ new org.eclipse.swt.graphics.Point( >+ cellBoundsRelativeToParent.x, >+ cellBoundsRelativeToParent.y)); >+ cellBoundsRelativeToParent.x = >+ cellOriginRelativeToParent.x; >+ cellBoundsRelativeToParent.y = >+ cellOriginRelativeToParent.y; >+ return null; >+ } >+ }); >+ >+ Control parent = (Control)getEventThreadQueuer().invokeAndWait("getParent", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ table.getParent(); >+ return null; >+ } >+ }); >+ >+ >+ getRobot().scrollToVisible( >+ parent, cellBoundsRelativeToParent); >+ >+ return getVisibleBounds(getCellBounds(row, col)); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected int getExtendSelectionModifier() { >+ return SWT.MOD1; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected Cell getCellAtMousePosition() throws StepExecutionException { >+ >+ final Table table = getTable(); >+ final Point awtMousePos = getRobot().getCurrentMousePosition(); >+ Cell returnvalue = (Cell) getEventThreadQueuer().invokeAndWait( >+ "getCellAtMousePosition", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() throws StepExecutionException { >+ Cell cell = null; >+ final int itemCount = table.getItemCount(); >+ for (int rowCount = table.getTopIndex(); >+ rowCount < itemCount; rowCount++) { >+ if (cell != null) { >+ break; >+ } >+ final int columnCount = table.getColumnCount(); >+ if (columnCount > 0) { >+ for (int col = 0; col < columnCount; col++) { >+ final Rectangle itemBounds = getCellBounds( >+ rowCount, col); >+ final org.eclipse.swt.graphics.Point >+ absItemBounds = table >+ .toDisplay(itemBounds.x, >+ itemBounds.y); >+ final Rectangle absRect = new Rectangle( >+ absItemBounds.x, absItemBounds.y, >+ itemBounds.width, >+ itemBounds.height); >+ if (absRect.contains(awtMousePos)) { >+ cell = new Cell(rowCount, col); >+ break; >+ } >+ } >+ } else { >+ final Rectangle itemBounds = getCellBounds( >+ rowCount, 0); >+ final org.eclipse.swt.graphics.Point >+ absItemBounds = table >+ .toDisplay(itemBounds.x, itemBounds.y); >+ final Rectangle absRect = new Rectangle( >+ absItemBounds.x, absItemBounds.y, >+ itemBounds.width, itemBounds.height); >+ if (absRect.contains(awtMousePos)) { >+ cell = new Cell(rowCount, 0); >+ } >+ } >+ } >+ if (cell == null) { >+ throw new StepExecutionException( >+ "No cell under mouse position found!", //$NON-NLS-1$ >+ EventFactory >+ .createActionError( >+ TestErrorEvent.NOT_FOUND)); >+ } >+ return cell; >+ } >+ }); >+ return returnvalue; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected boolean isMouseOnHeader() { >+ final Table table = getTable(); >+ final ITableAdapter adapter = (ITableAdapter)getComponent(); >+ Boolean isVisible; >+ isVisible = (Boolean)getEventThreadQueuer().invokeAndWait( >+ "isMouseOnHeader", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ return new Boolean(table.getHeaderVisible()); >+ } >+ }); >+ >+ if (!(isVisible.booleanValue())) { >+ return false; >+ } >+ >+ Boolean isOnHeader = new Boolean(false); >+ isOnHeader = (Boolean)getEventThreadQueuer().invokeAndWait( >+ "isMouseOnHeader", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ final Point awtMousePos = getRobot() >+ .getCurrentMousePosition(); >+ org.eclipse.swt.graphics.Point mousePos = >+ new org.eclipse.swt.graphics.Point( >+ awtMousePos.x, awtMousePos.y); >+ >+ for (int j = 0; j < table.getColumnCount(); j++) { >+ final Rectangle constraints = >+ adapter.getHeaderBounds(j); >+ >+ org.eclipse.swt.graphics.Rectangle bounds = >+ SwtUtils.getWidgetBounds( >+ table); >+ >+ if (constraints != null) { >+ // Use SWT's mapping function, if possible, as it is more >+ // multi-platform than simply adding the x and y values. >+ org.eclipse.swt.graphics.Point >+ convertedLocation = getConvertedLocation( >+ constraints); >+ bounds.x = convertedLocation.x; >+ bounds.y = convertedLocation.y; >+ >+ bounds.height = constraints.height; >+ bounds.width = constraints.width; >+ } >+ >+ if (bounds.contains(mousePos)) { >+ return new Boolean(true); >+ } >+ } >+ return new Boolean(false); >+ } >+ }); >+ >+ return isOnHeader.booleanValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ protected IRobotFactory getRobotFactory() { >+ if (m_robotFactory == null) { >+ m_robotFactory = new RobotFactoryConfig().getRobotFactory(); >+ } >+ return m_robotFactory; >+ } >+ >+ >+ /** >+ * Returns an array of representation strings that corresponds to the given >+ * array of items or null if the given array is null; >+ * @param itemArray the item array whose item texts have to be read >+ * @return array of item texts corresponding to the given item array >+ */ >+ protected final String[] getTextArrayFromItemArray(Item[] itemArray) { >+ final String[] itemTextArray; >+ if (itemArray == null) { >+ itemTextArray = null; >+ } else { >+ itemTextArray = new String[itemArray.length]; >+ for (int i = 0; i < itemArray.length; i++) { >+ Item item = itemArray[i]; >+ if (item == null) { >+ itemTextArray[i] = null; >+ } else { >+ itemTextArray[i] = SwtUtils.removeMnemonics(item.getText()); >+ } >+ } >+ } >+ >+ return itemTextArray; >+ } >+ >+ /** >+ * Computes the visible cellBounds inside the visible bounds of the table.<br> >+ * The result is the intersection of the visible bounds of the table and the >+ * bounds of the cell. >+ * @param cellBounds the bounds of the cell to click in. These bounds must >+ * be relative to the table's location. >+ * @return the visible cell bounds, relative to the table's location. >+ */ >+ private Rectangle getVisibleBounds(Rectangle cellBounds) { >+ org.eclipse.swt.graphics.Rectangle r = >+ (org.eclipse.swt.graphics.Rectangle) >+ getEventThreadQueuer().invokeAndWait("getVisibleCellBounds: " + cellBounds, //$NON-NLS-1$ >+ new IRunnable() { >+ >+ public Object run() { >+ return getTable().getClientArea(); >+ } >+ }); >+ >+ Rectangle visibleTableBounds = new Rectangle( >+ r.x, r.y, r.width, r.height); >+ Rectangle visibleCellBounds = >+ visibleTableBounds.intersection(cellBounds); >+ return visibleCellBounds; >+ } >+ >+ /** >+ * @param constraints Rectangle >+ * @return converted Location of table >+ */ >+ private org.eclipse.swt.graphics.Point getConvertedLocation( >+ final Rectangle constraints) { >+ org.eclipse.swt.graphics.Point convertedLocation = >+ (org.eclipse.swt.graphics.Point)getEventThreadQueuer() >+ .invokeAndWait("toDisplay", new IRunnable() { //$NON-NLS-1$ >+ public Object run() throws StepExecutionException { >+ return getTable().toDisplay( >+ constraints.x, constraints.y); >+ } >+ }); >+ return convertedLocation; >+ } >+ >+ /** >+ * >+ * @param row The row of the cell >+ * @param col The column of the cell >+ * @return The bounding rectangle for the cell, relative to the table's >+ * location. >+ */ >+ private Rectangle getCellBounds(final int row, final int col) { >+ final Table table = getTable(); >+ Rectangle cellBounds = (Rectangle)getEventThreadQueuer().invokeAndWait( >+ "evaluateCellBounds", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ checkRowColBounds(row, col); >+ TableItem ti = table.getItem(row); >+ int column = (table.getColumnCount() > 0 || col > 0) >+ ? col : 0; >+ org.eclipse.swt.graphics.Rectangle r = >+ ti.getBounds(column); >+ String text = ti.getText(column); >+ Image image = ti.getImage(column); >+ if (text != null && text.length() != 0) { >+ GC gc = new GC(table); >+ int charWidth = 0; >+ try { >+ FontMetrics fm = gc.getFontMetrics(); >+ charWidth = fm.getAverageCharWidth(); >+ } finally { >+ gc.dispose(); >+ } >+ r.width = text.length() * charWidth; >+ if (image != null) { >+ r.width += image.getBounds().width; >+ } >+ } else if (image != null) { >+ r.width = image.getBounds().width; >+ } >+ if (column > 0) { >+ TableColumn tc = table.getColumn(column); >+ int alignment = tc.getAlignment(); >+ if (alignment == SWT.CENTER) { >+ r.x += ((double)tc.getWidth() / 2) >+ - ((double)r.width / 2); >+ } >+ if (alignment == SWT.RIGHT) { >+ r.x += tc.getWidth() - r.width; >+ } >+ } >+ >+ return new Rectangle(r.x, r.y, r.width, r.height); >+ } >+ }); >+ return cellBounds; >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ protected Object getSpecificRectangle(Rectangle rectangle) { >+ return new org.eclipse.swt.graphics.Rectangle(rectangle.x, rectangle.y, >+ rectangle.width, rectangle.height); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdClickDirect(int count, int button, int xPos, String xUnits, >+ int yPos, String yUnits) throws StepExecutionException { >+ >+ int correctedYPos = correctYPos(yPos, yUnits); >+ super.gdClickDirect(count, button, xPos, xUnits, correctedYPos, yUnits); >+ } >+ >+ /** >+ * Corrects the given Y position based on the height of the table's header. >+ * This ensures, for example, that test steps don't try to click within the >+ * table header (where we receive no confirmation events). >+ * >+ * @param pos The Y position to correct. >+ * @param units The units used for the Y position. >+ * @return The corrected Y position. >+ */ >+ private int correctYPos(int pos, String units) { >+ int correctedPos = pos; >+ int headerHeight = ((Integer)getEventThreadQueuer().invokeAndWait( >+ "getHeaderHeight", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() throws StepExecutionException { >+ return new Integer( >+ ((Table)getComponent().getRealComponent()) >+ .getHeaderHeight()); >+ } >+ >+ })).intValue(); >+ >+ if (POS_UNIT_PIXEL.equalsIgnoreCase(units)) { >+ // Pixel units >+ correctedPos += headerHeight; >+ } else { >+ // Percentage units >+ int totalHeight = ((Integer)getEventThreadQueuer().invokeAndWait( >+ "getWidgetBounds", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() throws StepExecutionException { >+ return new Integer( >+ SwtUtils.getWidgetBounds( >+ (Widget) getComponent(). >+ getRealComponent()).height); >+ } >+ >+ })).intValue(); >+ long targetHeight = totalHeight - headerHeight; >+ long targetPos = Math.round((double)targetHeight * (double)pos >+ / 100.0); >+ targetPos += headerHeight; >+ double heightPercentage = >+ (double)targetPos / (double)totalHeight * 100.0; >+ correctedPos = (int)Math.round(heightPercentage); >+ if (correctedPos > 100) { // rounding error >+ correctedPos = 100; >+ } >+ } >+ return correctedPos; >+ } >+ >+ /** >+ * Drags the cell of the Table.<br> >+ * With the xPos, yPos, xunits and yUnits the click position inside the >+ * cell can be defined. >+ * >+ * @param mouseButton the mouseButton. >+ * @param modifier the modifier. >+ * @param row The row of the cell. >+ * @param rowOperator the row header operator >+ * @param col The column of the cell. >+ * @param colOperator the column header operator >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @throws StepExecutionException >+ * If the row or the column is invalid >+ */ >+ public void gdDragCell(final int mouseButton, final String modifier, >+ final String row, String rowOperator, final String col, >+ final String colOperator, final int xPos, final String xUnits, >+ final int yPos, final String yUnits) >+ throws StepExecutionException { >+ >+ final DragAndDropHelperSwt dndHelper = DragAndDropHelperSwt >+ .getInstance(); >+ dndHelper.setMouseButton(mouseButton); >+ dndHelper.setModifier(modifier); >+ dndHelper.setDragComponent(null); >+ >+ gdSelectCell(row, rowOperator, col, colOperator, 0, xPos, >+ xUnits, yPos, yUnits, >+ CompSystemConstants.EXTEND_SELECTION_NO, 1); >+ } >+ >+ /** >+ * Drops on the cell of the JTable.<br> >+ * With the xPos, yPos, xunits and yUnits the click position inside the >+ * cell can be defined. >+ * >+ * @param row The row of the cell. >+ * @param rowOperator The row operator >+ * @param col The column of the cell. >+ * @param colOperator The column operator >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param delayBeforeDrop the amount of time (in milliseconds) to wait >+ * between moving the mouse to the drop point and >+ * releasing the mouse button >+ * @throws StepExecutionException >+ * If the row or the column is invalid >+ */ >+ public void gdDropCell(final String row, final String rowOperator, >+ final String col, final String colOperator, final int xPos, >+ final String xUnits, final int yPos, final String yUnits, >+ int delayBeforeDrop) throws StepExecutionException { >+ >+ final DragAndDropHelperSwt dndHelper = DragAndDropHelperSwt >+ .getInstance(); >+ final IRobot robot = getRobot(); >+ >+ pressOrReleaseModifiers(dndHelper.getModifier(), true); >+ try { >+ getEventThreadQueuer().invokeAndWait("gdDropCell", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() throws StepExecutionException { >+ // drag >+ robot.mousePress(dndHelper.getDragComponent(), null, >+ dndHelper.getMouseButton()); >+ >+ CAPUtil.shakeMouse(); >+ >+ // drop >+ gdSelectCell(row, rowOperator, col, colOperator, 0, xPos, >+ xUnits, yPos, yUnits, >+ CompSystemConstants.EXTEND_SELECTION_NO, 1); >+ return null; >+ } >+ }); >+ >+ CAPUtil.waitBeforeDrop(delayBeforeDrop); >+ >+ } finally { >+ robot.mouseRelease(dndHelper.getDragComponent(), null, >+ dndHelper.getMouseButton()); >+ pressOrReleaseModifiers(dndHelper.getModifier(), false); >+ } >+ } >+ >+ /** >+ * Finds the first row which contains the value <code>value</code> >+ * in column <code>col</code> and drags this row. >+ * >+ * @param mouseButton the mouse button >+ * @param modifier the modifier >+ * @param col the column >+ * @param colOperator the column header operator >+ * @param value the value >+ * @param regexOp the regex operator >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ */ >+ public void gdDragRowByValue(int mouseButton, String modifier, String col, >+ String colOperator, final String value, final String regexOp, >+ final String searchType) { >+ >+ final DragAndDropHelperSwt dndHelper = DragAndDropHelperSwt >+ .getInstance(); >+ dndHelper.setMouseButton(mouseButton); >+ dndHelper.setModifier(modifier); >+ dndHelper.setDragComponent(null); >+ >+ gdSelectRowByValue(col, colOperator, value, regexOp, 1, >+ CompSystemConstants.EXTEND_SELECTION_NO, >+ searchType, 1); >+ } >+ >+ /** >+ * Finds the first row which contains the value <code>value</code> >+ * in column <code>col</code> and drops on this row. >+ * >+ * @param col the column >+ * @param colOperator the column operator >+ * @param value the value >+ * @param regexOp the regex operator >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ * @param delayBeforeDrop the amount of time (in milliseconds) to wait >+ * between moving the mouse to the drop point and >+ * releasing the mouse button >+ */ >+ public void gdDropRowByValue(final String col, final String colOperator, >+ final String value, final String regexOp, final String searchType, >+ int delayBeforeDrop) { >+ >+ final DragAndDropHelperSwt dndHelper = DragAndDropHelperSwt >+ .getInstance(); >+ final IRobot robot = getRobot(); >+ pressOrReleaseModifiers(dndHelper.getModifier(), true); >+ >+ try { >+ getEventThreadQueuer().invokeAndWait("gdDropRowByValue", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() throws StepExecutionException { >+ // drag >+ robot.mousePress(dndHelper.getDragComponent(), null, >+ dndHelper.getMouseButton()); >+ >+ CAPUtil.shakeMouse(); >+ >+ // drop >+ gdSelectRowByValue(col, colOperator, value, regexOp, >+ CompSystemConstants.EXTEND_SELECTION_NO, >+ searchType, >+ ClickOptions.create().setClickCount(0)); >+ return null; >+ } >+ }); >+ >+ CAPUtil.waitBeforeDrop(delayBeforeDrop); >+ >+ } finally { >+ robot.mouseRelease(dndHelper.getDragComponent(), null, >+ dndHelper.getMouseButton()); >+ pressOrReleaseModifiers(dndHelper.getModifier(), false); >+ } >+ } >+ >+ /** >+ * Finds the first column which contains the value <code>value</code> >+ * in the given row and drags the cell. >+ * >+ * @param mouseButton the mouse button >+ * @param modifier the modifiers >+ * @param row the row >+ * @param rowOperator the row header operator >+ * @param value the value >+ * @param regex search using regex >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ */ >+ public void gdDragCellByColValue(int mouseButton, String modifier, >+ String row, String rowOperator, final String value, >+ final String regex, final String searchType) { >+ >+ final DragAndDropHelperSwt dndHelper = DragAndDropHelperSwt >+ .getInstance(); >+ dndHelper.setMouseButton(mouseButton); >+ dndHelper.setModifier(modifier); >+ dndHelper.setDragComponent(null); >+ gdSelectCellByColValue(row, rowOperator, value, regex, >+ CompSystemConstants.EXTEND_SELECTION_NO, >+ searchType, ClickOptions.create().setClickCount(0)); >+ } >+ >+ /** >+ * Finds the first column which contains the value <code>value</code> >+ * in the given row and drops on the cell. >+ * >+ * @param row the row >+ * @param rowOperator the row header operator >+ * @param value the value >+ * @param regex search using regex >+ * @param searchType Determines where the search begins ("relative" or "absolute") >+ * @param delayBeforeDrop the amount of time (in milliseconds) to wait >+ * between moving the mouse to the drop point and >+ * releasing the mouse button >+ */ >+ public void gdDropCellByColValue(final String row, final String rowOperator, >+ final String value, final String regex, final String searchType, >+ int delayBeforeDrop) { >+ >+ final DragAndDropHelperSwt dndHelper = DragAndDropHelperSwt >+ .getInstance(); >+ final IRobot robot = getRobot(); >+ pressOrReleaseModifiers(dndHelper.getModifier(), true); >+ >+ try { >+ getEventThreadQueuer().invokeAndWait("gdDropCellByColValue", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() throws StepExecutionException { >+ // drag >+ robot.mousePress(dndHelper.getDragComponent(), null, >+ dndHelper.getMouseButton()); >+ >+ CAPUtil.shakeMouse(); >+ >+ // drop >+ gdSelectCellByColValue(row, rowOperator, value, regex, >+ CompSystemConstants.EXTEND_SELECTION_NO, >+ searchType, >+ ClickOptions.create().setClickCount(0)); >+ return null; >+ } >+ }); >+ >+ CAPUtil.waitBeforeDrop(delayBeforeDrop); >+ >+ } finally { >+ robot.mouseRelease(dndHelper.getDragComponent(), null, >+ dndHelper.getMouseButton()); >+ pressOrReleaseModifiers(dndHelper.getModifier(), false); >+ } >+ } >+} >diff --git a/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/TreeCAPs.java b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/TreeCAPs.java >new file mode 100644 >index 0000000..fe9ad1a >--- /dev/null >+++ b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/caps/TreeCAPs.java >@@ -0,0 +1,927 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swt.caps; >+ >+import java.util.StringTokenizer; >+ >+import org.apache.commons.lang.Validate; >+import org.eclipse.jubula.rc.common.AUTServer; >+import org.eclipse.jubula.rc.common.CompSystemConstants; >+import org.eclipse.jubula.rc.common.caps.AbstractTreeCAPs; >+import org.eclipse.jubula.rc.common.driver.ClickOptions; >+import org.eclipse.jubula.rc.common.driver.IEventThreadQueuer; >+import org.eclipse.jubula.rc.common.driver.IRobot; >+import org.eclipse.jubula.rc.common.driver.IRobotFactory; >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.exception.RobotException; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.implclasses.IndexConverter; >+import org.eclipse.jubula.rc.common.implclasses.MatchUtil; >+import org.eclipse.jubula.rc.common.implclasses.Verifier; >+import org.eclipse.jubula.rc.common.implclasses.tree.AbstractTreeNodeOperation; >+import org.eclipse.jubula.rc.common.implclasses.tree.AbstractTreeNodeTraverser; >+import org.eclipse.jubula.rc.common.implclasses.tree.AbstractTreeOperationContext; >+import org.eclipse.jubula.rc.common.implclasses.tree.ChildTraverser; >+import org.eclipse.jubula.rc.common.implclasses.tree.ExpandCollapseTreeNodeOperation; >+import org.eclipse.jubula.rc.common.implclasses.tree.INodePath; >+import org.eclipse.jubula.rc.common.implclasses.tree.ParentTraverser; >+import org.eclipse.jubula.rc.common.implclasses.tree.PathBasedTraverser; >+import org.eclipse.jubula.rc.common.implclasses.tree.SelectTreeNodeOperation; >+import org.eclipse.jubula.rc.common.implclasses.tree.SiblingTraverser; >+import org.eclipse.jubula.rc.common.implclasses.tree.StandardDepthFirstTraverser; >+import org.eclipse.jubula.rc.common.implclasses.tree.TreeNodeOperation; >+import org.eclipse.jubula.rc.common.implclasses.tree.TreeNodeOperationConstraint; >+import org.eclipse.jubula.rc.common.util.KeyStrokeUtil; >+import org.eclipse.jubula.rc.swt.driver.DragAndDropHelperSwt; >+import org.eclipse.jubula.rc.swt.driver.KeyCodeConverter; >+import org.eclipse.jubula.rc.swt.driver.RobotFactoryConfig; >+import org.eclipse.jubula.rc.swt.implclasses.TableTreeOperationContext; >+import org.eclipse.jubula.rc.swt.implclasses.TreeOperationContext; >+import org.eclipse.jubula.rc.swt.implclasses.tree.ToggleCheckboxOperation; >+import org.eclipse.jubula.rc.swt.implclasses.tree.VerifyCheckboxOperation; >+import org.eclipse.jubula.rc.swt.utils.SwtUtils; >+import org.eclipse.jubula.tools.objects.event.EventFactory; >+import org.eclipse.jubula.tools.objects.event.TestErrorEvent; >+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.ScrollBar; >+import org.eclipse.swt.widgets.TreeItem; >+import org.eclipse.swt.widgets.Tree; >+/** >+ * Toolkit specific commands for the <code>Tree</code> >+ * >+ * @author BREDEX GmbH >+ */ >+public class TreeCAPs extends AbstractTreeCAPs { >+ >+ >+ /** >+ * Finds the item at a given position in the tree. >+ * >+ * @author BREDEX GmbH >+ * @created Jul 28, 2010 >+ */ >+ private static final class ItemAtPointTreeNodeOperation >+ extends AbstractTreeNodeOperation { >+ >+ /** the item that was found at the given position */ >+ private TreeItem m_itemAtPoint; >+ >+ /** the position (in absolute coordinates) at which to find the item */ >+ private Point m_absPoint; >+ >+ /** >+ * the bounds (in absolute coordinates) of the tree in which the >+ * search should take place >+ */ >+ private Rectangle m_absTreeBounds; >+ >+ >+ /** >+ * Constructor >+ * >+ * @param absPoint The position (in absolute coordinates) at which to >+ * find the item. >+ * @param absTreeBounds The bounds (in absolute coordinates) of the >+ * tree in which the search should take place. >+ */ >+ public ItemAtPointTreeNodeOperation(Point absPoint, >+ Rectangle absTreeBounds) { >+ m_absPoint = absPoint; >+ m_absTreeBounds = absTreeBounds; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean operate(Object node) throws StepExecutionException { >+ if (getContext().isVisible(node) && node instanceof TreeItem) { >+ TreeItem currentItem = (TreeItem)node; >+ final Rectangle absItemBounds = >+ SwtUtils.getBounds(currentItem); >+ absItemBounds.x = m_absTreeBounds.x; >+ absItemBounds.width = m_absTreeBounds.width; >+ if (SwtUtils.containsInclusive( >+ absItemBounds, m_absPoint)) { >+ m_itemAtPoint = currentItem; >+ return false; >+ } >+ } >+ >+ return true; >+ } >+ >+ /** >+ * >+ * @return the item found at the given position, or <code>null</code> if >+ * no item was found. Note that this method will always return >+ * <code>null</code> if called before or during execution of >+ * {@link #operate(Object)}. >+ */ >+ public TreeItem getItemAtPoint() { >+ return m_itemAtPoint; >+ } >+ } >+ >+ /** The robot factory. */ >+ private IRobotFactory m_robotFactory; >+ >+ /** >+ * Gets the Robot factory. The factory is created once per instance. >+ * @return The Robot factory. >+ */ >+ protected IRobotFactory getRobotFactory() { >+ if (m_robotFactory == null) { >+ m_robotFactory = new RobotFactoryConfig().getRobotFactory(); >+ } >+ return m_robotFactory; >+ } >+ /** >+ * Gets the Robot. >+ * @return The Robot >+ * @throws RobotException If the Robot cannot be created. >+ */ >+ protected IRobot getRobot() throws RobotException { >+ return AUTServer.getInstance().getRobot(); >+ } >+ >+ /** >+ * @return The event thread queuer. >+ */ >+ protected IEventThreadQueuer getEventThreadQueuer() { >+ return getRobotFactory().getEventThreadQueuer(); >+ } >+ /** >+ * >+ * @return the Tree >+ */ >+ private Tree getTree() { >+ return (Tree) getComponent().getRealComponent(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdVerifyTextAtMousePosition(String pattern, String operator) { >+ TreeItem itemAtMousePosition = (TreeItem) getNodeAtMousePosition(); >+ int column = getMouseColumn(); >+ AbstractTreeOperationContext context; >+ >+ if (column != -1) { >+ context = >+ new TableTreeOperationContext( >+ getEventThreadQueuer(), getRobot(), >+ getTree(), column); >+ } else { >+ context = >+ new TableTreeOperationContext( >+ getEventThreadQueuer(), getRobot(), >+ getTree()); >+ } >+ >+ Verifier.match(context.getRenderedText(itemAtMousePosition), >+ pattern, operator); >+ >+ } >+ >+ >+ >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdDragByTextPath(int mouseButton, String modifier, >+ String pathType, int preAscend, String treePath, String operator) { >+ >+ final DragAndDropHelperSwt dndHelper = DragAndDropHelperSwt >+ .getInstance(); >+ >+ dndHelper.setMouseButton(mouseButton); >+ dndHelper.setModifier(modifier); >+ dndHelper.setDragComponent(null); >+ >+ SwtUtils.waitForDisplayIdle(getTree().getDisplay()); >+ >+ gdSelect(pathType, preAscend, treePath, operator, 0, 1, >+ CompSystemConstants.EXTEND_SELECTION_NO); >+ >+ SwtUtils.waitForDisplayIdle(getTree().getDisplay()); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdDropByTextPath(final String pathType, final int preAscend, >+ final String treePath, final String operator, int delayBeforeDrop) { >+ >+ final DragAndDropHelperSwt dndHelper = DragAndDropHelperSwt >+ .getInstance(); >+ final IRobot robot = getRobot(); >+ >+ try { >+ pressOrReleaseModifiers(dndHelper.getModifier(), true); >+ getEventThreadQueuer().invokeAndWait("gdDropByTextPath - perform drag", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() throws StepExecutionException { >+ // drag >+ robot.mousePress(dndHelper.getDragComponent(), null, >+ dndHelper.getMouseButton()); >+ >+ CAPUtil.shakeMouse(); >+ >+ return null; >+ } >+ }); >+ >+ // Post a MouseMove event in order to break the Display out of its >+ // post-drag "freeze". It appears as though the mouse position >+ // change needs to be extreme in order to nudge the Display back >+ // into action (i.e. (<mouse-location> + 1) was insufficient), >+ // so the default Event values (x, y = 0) are used. >+ Event wakeEvent = new Event(); >+ wakeEvent.type = SWT.MouseMove; >+ getTree().getDisplay().post(wakeEvent); >+ >+ waitForDisplayUpdate(); >+ >+ // drop >+ gdSelect(pathType, preAscend, treePath, operator, 0, 1, >+ CompSystemConstants.EXTEND_SELECTION_NO); >+ >+ SwtUtils.waitForDisplayIdle(getTree().getDisplay()); >+ CAPUtil.waitBeforeDrop(delayBeforeDrop); >+ >+ } finally { >+ robot.mouseRelease(null, null, dndHelper.getMouseButton()); >+ pressOrReleaseModifiers( >+ dndHelper.getModifier(), false); >+ SwtUtils.waitForDisplayIdle(getTree().getDisplay()); >+ } >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdDragByIndexPath(int mouseButton, String modifier, >+ String pathType, int preAscend, String indexPath) { >+ >+ final DragAndDropHelperSwt dndHelper = DragAndDropHelperSwt >+ .getInstance(); >+ >+ dndHelper.setMouseButton(mouseButton); >+ dndHelper.setModifier(modifier); >+ dndHelper.setDragComponent(null); >+ >+ SwtUtils.waitForDisplayIdle(getTree().getDisplay()); >+ >+ gdSelectByIndices(pathType, preAscend, indexPath, 0, 1, >+ CompSystemConstants.EXTEND_SELECTION_NO); >+ >+ SwtUtils.waitForDisplayIdle(getTree().getDisplay()); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdDropByIndexPath(final String pathType, final int preAscend, >+ final String indexPath, int delayBeforeDrop) { >+ >+ final DragAndDropHelperSwt dndHelper = DragAndDropHelperSwt >+ .getInstance(); >+ final IRobot robot = getRobot(); >+ try { >+ pressOrReleaseModifiers(dndHelper.getModifier(), true); >+ getEventThreadQueuer().invokeAndWait("gdDropByIndexPath - perform drag", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() throws StepExecutionException { >+ // drag >+ robot.mousePress(dndHelper.getDragComponent(), null, >+ dndHelper.getMouseButton()); >+ >+ CAPUtil.shakeMouse(); >+ >+ return null; >+ } >+ }); >+ >+ // Post a MouseMove event in order to break the Display out of its >+ // post-drag "freeze". It appears as though the mouse position >+ // change needs to be extreme in order to nudge the Display back >+ // into action (i.e. (<mouse-location> + 1) was insufficient), >+ // so the default Event values (x, y = 0) are used. >+ Event wakeEvent = new Event(); >+ wakeEvent.type = SWT.MouseMove; >+ getTree().getDisplay().post(wakeEvent); >+ >+ waitForDisplayUpdate(); >+ >+ // drop >+ gdSelectByIndices(pathType, preAscend, indexPath, 0, 1, >+ CompSystemConstants.EXTEND_SELECTION_NO); >+ >+ SwtUtils.waitForDisplayIdle(getTree().getDisplay()); >+ CAPUtil.waitBeforeDrop(delayBeforeDrop); >+ } finally { >+ robot.mouseRelease(null, null, dndHelper.getMouseButton()); >+ pressOrReleaseModifiers(dndHelper.getModifier(), >+ false); >+ SwtUtils.waitForDisplayIdle(getTree().getDisplay()); >+ } >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ protected Object getNodeAtMousePosition() throws StepExecutionException { >+ return (TreeItem)getEventThreadQueuer().invokeAndWait("getItemAtMousePosition", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() throws StepExecutionException { >+ Point mousePos = SwtUtils.convertToSwtPoint( >+ getRobot().getCurrentMousePosition()); >+ ItemAtPointTreeNodeOperation op = >+ new ItemAtPointTreeNodeOperation( >+ mousePos, SwtUtils.getWidgetBounds(getTree())); >+ >+ TreeItem topItem = getTree().getTopItem(); >+ if (topItem != null) { >+ >+ // FIXME zeb This may be slow for very large trees, as the >+ // search may continue long past the >+ // visible client area of the tree. >+ // It may also cause problems with regard to >+ // lazy/virtual nodes. >+ StandardDepthFirstTraverser traverser = >+ new StandardDepthFirstTraverser( >+ new TreeOperationContext( >+ getEventThreadQueuer(), getRobot(), getTree())); >+ traverser.traversePath(op, topItem); >+ if (op.getItemAtPoint() != null) { >+ return op.getItemAtPoint(); >+ } >+ >+ } >+ >+ throw new StepExecutionException("No tree node found at mouse position.", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.NOT_FOUND)); >+ } >+ }); >+ } >+ >+ /** >+ * @return the column where the mouse pointer currently rests. Returns -1 if >+ * the mouse pointer is currently outside of the TableTree or if the >+ * TableTree has no columns. >+ */ >+ private int getMouseColumn() { >+ final Tree treeTable = getTree(); >+ int column = ((Integer)getEventThreadQueuer().invokeAndWait( >+ "getMouseColumn", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() throws StepExecutionException { >+ Rectangle treeTableBounds = >+ SwtUtils.getWidgetBounds(getTree()); >+ Point cursorPosition = >+ treeTable.getDisplay().getCursorLocation(); >+ boolean isCursorInBounds = >+ treeTableBounds.contains(cursorPosition); >+ if (isCursorInBounds) { >+ int horizontalScrollOffset = 0; >+ ScrollBar horizontalBar = >+ getTree().getHorizontalBar(); >+ if (horizontalBar != null >+ && !horizontalBar.isDisposed()) { >+ horizontalScrollOffset = >+ horizontalBar.getSelection(); >+ } >+ Rectangle columnBounds = new Rectangle( >+ treeTableBounds.x - horizontalScrollOffset, >+ treeTableBounds.y, 0, treeTableBounds.height); >+ for (int i = 0; >+ i < treeTable.getColumnCount(); i++) { >+ >+ columnBounds.x += columnBounds.width; >+ columnBounds.width = >+ treeTable.getColumn(i).getWidth(); >+ if (columnBounds.contains(cursorPosition)) { >+ return new Integer(i); >+ } >+ } >+ } >+ >+ return new Integer(-1); >+ } >+ >+ })).intValue(); >+ >+ return column; >+ } >+ // >+ // Methods for Table Trees following >+ // >+ >+ /** >+ * Selects a node relative to the currently selected node. >+ * @param direction the direction to move. >+ * directions: >+ * UP - Navigates through parents >+ * DOWN - Navigates through children >+ * NEXT - Navigates to next sibling >+ * PREVIOUS - Navigates to previous sibling >+ * @param distance the distance to move >+ * @param clickCount the click count to select the new cell. >+ * @throws StepExecutionException if any error occurs >+ */ >+ public void gdMove(String direction, int distance, int clickCount) >+ throws StepExecutionException { >+ >+ if (getColumnCount() > 0) { >+ TreeOperationContext context; >+ int mouseColumn = getMouseColumn(); >+ >+ if (mouseColumn == -1) { >+ context = >+ new TableTreeOperationContext( >+ getEventThreadQueuer(), getRobot(), getTree()); >+ } else { >+ context = >+ new TableTreeOperationContext( >+ getEventThreadQueuer(), getRobot(), getTree(), >+ mouseColumn); >+ } >+ >+ TreeItem selectedNode = (TreeItem) getSelectedNode(context); >+ >+ TreeNodeOperation selectOp = >+ new SelectTreeNodeOperation( >+ ClickOptions.create().setClickCount(clickCount)); >+ TreeNodeOperationConstraint constraint = >+ new TreeNodeOperationConstraint(); >+ >+ if (CompSystemConstants >+ .TREE_MOVE_UP.equalsIgnoreCase(direction)) { >+ AbstractTreeNodeTraverser traverser = >+ new ParentTraverser(context, distance, constraint); >+ traverser.traversePath(selectOp, selectedNode); >+ } else if (CompSystemConstants >+ .TREE_MOVE_DOWN.equalsIgnoreCase(direction)) { >+ TreeNodeOperation expandOp = >+ new ExpandCollapseTreeNodeOperation(false); >+ AbstractTreeNodeTraverser expandTraverser = >+ new ChildTraverser(context, distance - 1); >+ expandTraverser.traversePath(expandOp, selectedNode); >+ >+ AbstractTreeNodeTraverser selectTraverser = >+ new ChildTraverser(context, distance, constraint); >+ selectTraverser.traversePath(selectOp, selectedNode); >+ >+ } else if (CompSystemConstants >+ .TREE_MOVE_NEXT.equalsIgnoreCase(direction)) { >+ // Look through siblings >+ AbstractTreeNodeTraverser traverser = >+ new SiblingTraverser(context, distance, true, constraint); >+ traverser.traversePath(selectOp, selectedNode); >+ >+ } else if (CompSystemConstants >+ .TREE_MOVE_PREVIOUS.equalsIgnoreCase(direction)) { >+ // Look through siblings >+ AbstractTreeNodeTraverser traverser = >+ new SiblingTraverser(context, distance, false, constraint); >+ traverser.traversePath(selectOp, selectedNode); >+ } >+ } else { >+ super.gdMove(direction, distance, clickCount); >+ } >+ } >+ >+ /** >+ * Runs in the GUI thread. >+ * @return the number of columns in the receivers component. >+ */ >+ private int getColumnCount() { >+ return ((Integer)getEventThreadQueuer().invokeAndWait( >+ "getColumnCount", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() throws StepExecutionException { >+ return new Integer(getTree().getColumnCount()); >+ } >+ >+ })).intValue(); >+ } >+ >+ /** >+ * Selects the item at the end of the <code>treepath</code> at column >+ * <code>column</code>. >+ * >+ * @param pathType whether the path is relative or absolute >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param treePath The tree path. >+ * @param operator >+ * If regular expressions are used to match the tree path >+ * @param clickCount the click count >+ * @param column the column of the item to select >+ * @param button what mouse button should be used >+ * @throws StepExecutionException If the tree path is invalid, if the >+ * double-click to expand the node fails, or if the selection is invalid. >+ */ >+ public void gdSelect(String pathType, int preAscend, String treePath, >+ String operator, int clickCount, int column, >+ int button) >+ throws StepExecutionException { >+ final int implCol = IndexConverter.toImplementationIndex(column); >+ checkColumnIndex(implCol); >+ >+ selectByPath(pathType, preAscend, >+ createStringNodePath(splitTextTreePath(treePath), operator), >+ ClickOptions.create() >+ .setClickCount(clickCount) >+ .setMouseButton(button), implCol); >+ >+ } >+ /** >+ * Selects the last node of the path given by <code>indexPath</code> >+ * at column <code>column</code>. >+ * >+ * @param pathType whether the path is relative or absolute >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param indexPath the index path >+ * @param clickCount the number of times to click >+ * @param column the column of the item to select >+ * @param button what mouse button should be used >+ * @throws StepExecutionException if <code>indexPath</code> is not a valid >+ * path >+ */ >+ public void gdSelectByIndices(String pathType, int preAscend, >+ String indexPath, int clickCount, int column, >+ int button) >+ throws StepExecutionException { >+ final int implCol = IndexConverter.toImplementationIndex(column); >+ checkColumnIndex(implCol); >+ >+ selectByPath(pathType, preAscend, >+ createIndexNodePath(splitIndexTreePath(indexPath)), >+ ClickOptions.create() >+ .setClickCount(clickCount) >+ .setMouseButton(button), implCol); >+ } >+ >+ /** >+ * Verifies whether the first selection in the tree has a rendered text at >+ * column <code>column</code> that is equal to <code>pattern</code>. >+ * >+ * @param pattern The pattern >+ * @param column >+ * The column containing the text to verify >+ * @throws StepExecutionException If no node is selected or the verification fails. >+ */ >+ public void gdVerifySelectedValue(String pattern, int column) >+ throws StepExecutionException { >+ >+ gdVerifySelectedValue(pattern, MatchUtil.DEFAULT_OPERATOR, column); >+ } >+ /** >+ * Verifies if the selected node underneath <code>treePath</code> at column >+ * <code>column</code> has a rendered text which is equal to >+ * <code>selection</code>. >+ * >+ * @param pattern the pattern >+ * @param operator >+ * The operator to use when comparing the expected and >+ * actual values. >+ * @param column >+ * The column containing the text to verify >+ * @throws StepExecutionException If there is no tree node selected, the tree path contains no >+ * selection or the verification fails >+ */ >+ public void gdVerifySelectedValue(String pattern, String operator, >+ int column) throws StepExecutionException { >+ >+ final int implCol = IndexConverter.toImplementationIndex(column); >+ checkColumnIndex(implCol); >+ >+ TableTreeOperationContext context = new TableTreeOperationContext( >+ getEventThreadQueuer(), getRobot(), getTree(), implCol); >+ >+ String text = context.getNodeTextAtColumn(context.getSelectedNode()); >+ >+ Verifier.match(text, pattern, operator); >+ >+ } >+ >+ /** >+ * >+ * @param index The 0-based column index to check. >+ * @throws StepExecutionException if the column index is invalid. >+ */ >+ private void checkColumnIndex(final int index) >+ throws StepExecutionException { >+ >+ int numColumns = ((Integer)getEventThreadQueuer().invokeAndWait( >+ "checkColumnIndex", //$NON-NLS-1$ >+ new IRunnable() { >+ >+ public Object run() { >+ return new Integer(getTree().getColumnCount()); >+ } >+ >+ })).intValue(); >+ >+ if ((index < 0 || index >= numColumns) && index != 0) { >+ throw new StepExecutionException("Invalid column: " //$NON-NLS-1$ >+ + IndexConverter.toUserIndex(index), >+ EventFactory.createActionError( >+ TestErrorEvent.INVALID_INDEX)); >+ } >+ } >+ >+ /** >+ * @param pathType pathType >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param objectPath objectPath >+ * @param co the click options to use >+ * @param column the column >+ */ >+ private void selectByPath(String pathType, int preAscend, >+ INodePath objectPath, ClickOptions co, int column) { >+ >+ TreeNodeOperation expOp = >+ new ExpandCollapseTreeNodeOperation(false); >+ TreeNodeOperation selectOp = >+ new SelectTreeNodeOperation(co); >+ INodePath subPath = objectPath.subPath(0, objectPath.getLength() - 1); >+ >+ traverseTreeByPath(subPath, pathType, preAscend, expOp); >+ traverseLastElementByPath( >+ objectPath, pathType, preAscend, selectOp, column); >+ >+ } >+ >+ /** >+ * Traverses the tree by searching for the nodes in the tree >+ * path entry and calling the given operation on the last element in the path. >+ * @param treePath The tree path. >+ * @param pathType For example, "relative" or "absolute". >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param operation The tree node operation. >+ * @param column The target column for the operation. >+ * @throws StepExecutionException If the path traversion fails. >+ */ >+ private void traverseLastElementByPath(INodePath treePath, >+ String pathType, int preAscend, TreeNodeOperation operation, >+ int column) >+ throws StepExecutionException { >+ >+ Validate.notNull(treePath); >+ Validate.notNull(operation); >+ >+ TableTreeOperationContext context = new TableTreeOperationContext( >+ getEventThreadQueuer(), getRobot(), getTree(), column); >+ TreeItem startNode = (TreeItem) getStartNode(pathType, >+ preAscend, context); >+ >+ AbstractTreeNodeTraverser traverser = new PathBasedTraverser( >+ context, treePath, new TreeNodeOperationConstraint()); >+ traverser.traversePath(operation, startNode); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String gdStoreValueAtMousePosition(String variable) { >+ TreeItem itemAtMousePosition = (TreeItem) getNodeAtMousePosition(); >+ int column = getMouseColumn(); >+ AbstractTreeOperationContext context; >+ >+ if (column != -1) { >+ context = >+ new TableTreeOperationContext( >+ getEventThreadQueuer(), getRobot(), getTree(), column); >+ } else { >+ context = >+ new TableTreeOperationContext( >+ getEventThreadQueuer(), getRobot(), getTree()); >+ } >+ >+ return context.getRenderedText(itemAtMousePosition); >+ } >+ >+ /** >+ * Selects Checkbox of last node of the path given by <code>treepath</code>. >+ * >+ * @param pathType whether the path is relative or absolute >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param treePath The tree path. >+ * @param operator >+ * If regular expressions are used to match the tree path >+ * @throws StepExecutionException If the tree path is invalid, if the >+ * double-click to expand the node fails, or if the selection is invalid. >+ */ >+ public void gdToggleCheckbox(String pathType, int preAscend, String >+ treePath, String operator) >+ throws StepExecutionException { >+ toggleCheckBoxByPath(pathType, preAscend, >+ createStringNodePath(splitTextTreePath(treePath), operator)); >+ } >+ >+ /** >+ * Selects Checkbox of last node of the path given by <code>indexPath</code> >+ * @param pathType whether the path is relative or absolute >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param indexPath the index path >+ * @throws StepExecutionException if <code>indexPath</code> is not a valid >+ * path >+ */ >+ public void gdToggleCheckboxByIndices(String pathType, int preAscend, >+ String indexPath) >+ throws StepExecutionException { >+ >+ toggleCheckBoxByPath(pathType, preAscend, >+ createIndexNodePath(splitIndexTreePath(indexPath))); >+ } >+ >+ /** >+ * Verify Selection of checkbox of the node at the end of the <code>treepath</code>. >+ * >+ * @param pathType whether the path is relative or absolute >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param treePath The tree path. >+ * @param operator >+ * If regular expressions are used to match the tree path >+ * @param checked true if checkbox of tree node is selected, false otherwise >+ * @throws StepExecutionException If the tree path is invalid, if the >+ * double-click to expand the node fails, or if the selection is invalid. >+ */ >+ public void gdVerifyCheckbox(String pathType, int preAscend, String >+ treePath, String operator, boolean checked) >+ throws StepExecutionException { >+ verifyCheckBoxByPath(pathType, preAscend, >+ createStringNodePath(splitTextTreePath(treePath), operator), >+ checked); >+ } >+ >+ /** >+ * Verify Selection of checkbox of last node of the path given by <code>indexPath</code> >+ * @param pathType whether the path is relative or absolute >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param indexPath the index path >+ * @param checked true if checkbox of tree node is selected, false otherwise >+ * @throws StepExecutionException if <code>indexPath</code> is not a valid >+ * path >+ */ >+ public void gdVerifyCheckboxByIndices(String pathType, int preAscend, >+ String indexPath, boolean checked) >+ throws StepExecutionException { >+ >+ verifyCheckBoxByPath(pathType, preAscend, >+ createIndexNodePath(splitIndexTreePath(indexPath)), >+ checked); >+ } >+ >+ /** >+ * Verifies whether the checkbox of the first selection in the tree is checked >+ * >+ * @param checked true if checkbox of node is selected, false otherwise >+ * @throws StepExecutionException If no node is selected or the verification fails. >+ */ >+ public void gdVerifySelectedCheckbox(boolean checked) >+ throws StepExecutionException { >+ Boolean checkSelected = ((Boolean)getEventThreadQueuer().invokeAndWait( >+ "gdVerifyTreeCheckbox", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ TreeItem node = getTree().getSelection()[0]; >+ return new Boolean(node.getChecked()); >+ } >+ })); >+ >+ Verifier.equals(checked, checkSelected.booleanValue()); >+ } >+ >+ /** >+ * @param pathType pathType >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param objectPath objectPath >+ * @param checked true if Checkbox should be enabled, false otherwise >+ */ >+ private void verifyCheckBoxByPath(String pathType, int preAscend, >+ INodePath objectPath, final boolean checked) { >+ >+ TreeNodeOperation expOp = >+ new ExpandCollapseTreeNodeOperation(false); >+ TreeOperationContext context = new TreeOperationContext( >+ getEventThreadQueuer(), getRobot(), getTree()); >+ TreeNodeOperation checkboxOp = new VerifyCheckboxOperation( >+ checked, context); >+ INodePath subPath = objectPath.subPath(0, objectPath.getLength() - 1); >+ >+ traverseTreeByPath(subPath, pathType, preAscend, expOp); >+ traverseLastElementByPath(objectPath, pathType, preAscend, checkboxOp); >+ } >+ >+ /** >+ * @param pathType pathType >+ * @param preAscend >+ * Relative traversals will start this many parent nodes >+ * above the current node. Absolute traversals ignore this >+ * parameter. >+ * @param objectPath objectPath >+ */ >+ private void toggleCheckBoxByPath(String pathType, int preAscend, >+ INodePath objectPath) { >+ >+ TreeNodeOperation expOp = >+ new ExpandCollapseTreeNodeOperation(false); >+ TreeOperationContext context = new TreeOperationContext( >+ getEventThreadQueuer(), getRobot(), getTree()); >+ TreeNodeOperation selCheckboxOp = new ToggleCheckboxOperation(context); >+ INodePath subPath = objectPath.subPath(0, objectPath.getLength() - 1); >+ >+ traverseTreeByPath(subPath, pathType, preAscend, expOp); >+ traverseLastElementByPath(objectPath, pathType, preAscend, >+ selCheckboxOp); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdClick(int count, int button) { >+ super.gdClick(count, button); >+ >+ } >+ >+ >+ >+ /** >+ * Forces all outstanding paint requests for the receiver's component's >+ * display to be processed before this method returns. >+ * >+ * @see Display#update() >+ */ >+ protected void waitForDisplayUpdate() { >+ ((Control)getComponent().getRealComponent()) >+ .getDisplay().syncExec(new Runnable() { >+ public void run() { >+ ((Control)getComponent() >+ .getRealComponent()).getDisplay().update(); >+ } >+ }); >+ } >+ >+ /** >+ * Presses or releases the given modifier. >+ * @param modifier the modifier. >+ * @param press if true, the modifier will be pressed. >+ * if false, the modifier will be released. >+ */ >+ public void pressOrReleaseModifiers(String modifier, boolean press) { >+ final IRobot robot = getRobot(); >+ final StringTokenizer modTok = new StringTokenizer( >+ KeyStrokeUtil.getModifierString(modifier), " "); //$NON-NLS-1$ >+ while (modTok.hasMoreTokens()) { >+ final String mod = modTok.nextToken(); >+ final int keyCode = KeyCodeConverter.getKeyCode(mod); >+ if (press) { >+ robot.keyPress(null, keyCode); >+ } else { >+ robot.keyRelease(null, keyCode); >+ } >+ } >+ } >+ >+} >diff --git a/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/ButtonAdapter.java b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/ButtonAdapter.java >new file mode 100644 >index 0000000..5d9f7ef >--- /dev/null >+++ b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/ButtonAdapter.java >@@ -0,0 +1,70 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swt.uiadapter; >+ >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IButtonAdapter; >+import org.eclipse.swt.widgets.Button; >+/** >+ * Implements the Button interface for adapting a <code>SWT.Button</code> >+ * >+ * @author BREDEX GmbH >+ */ >+public class ButtonAdapter extends WidgetAdapter implements IButtonAdapter { >+ >+ /** the Button from the AUT */ >+ private Button m_button; >+ >+ /** >+ * >+ * @param objectToAdapt graphics component which will be adapted >+ */ >+ public ButtonAdapter(Object objectToAdapt) { >+ super(objectToAdapt); >+ m_button = (Button) objectToAdapt; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String getText() { >+ >+ return (String)getEventThreadQueuer() >+ .invokeAndWait("getText", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return m_button.getText(); // see findBugs; >+ } >+ }); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isSelected() { >+ Boolean actual = (Boolean)getEventThreadQueuer() >+ .invokeAndWait("isSelected", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return m_button.getSelection() >+ ? Boolean.TRUE : Boolean.FALSE; // see findBugs; >+ } >+ }); >+ return actual.booleanValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ * >+ */ >+ public String readValue(String variable) { >+ >+ return getText(); >+ } >+} >\ No newline at end of file >diff --git a/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/MenuAdapter.java b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/MenuAdapter.java >new file mode 100644 >index 0000000..c5daae2 >--- /dev/null >+++ b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/MenuAdapter.java >@@ -0,0 +1,121 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swt.uiadapter; >+ >+import org.eclipse.jubula.rc.common.driver.IEventThreadQueuer; >+import org.eclipse.jubula.rc.common.driver.IRobot; >+import org.eclipse.jubula.rc.common.driver.IRobotFactory; >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.exception.RobotException; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuAdapter; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuItemAdapter; >+import org.eclipse.jubula.rc.swt.driver.RobotFactoryConfig; >+import org.eclipse.swt.widgets.Menu; >+import org.eclipse.swt.widgets.MenuItem; >+ >+/** >+ * Implements the Menu interface for adapting a <code>SWT.Menu</code> >+ * >+ * @author BREDEX GmbH >+ */ >+public class MenuAdapter implements IMenuAdapter { >+ /** the Menu from the AUT */ >+ private Menu m_menu; >+ >+ /** the RobotFactory from the AUT */ >+ private IRobotFactory m_robotFactory; >+ >+ /** >+ * >+ * @param component graphics component which will be adapted >+ */ >+ public MenuAdapter(Object component) { >+ m_menu = (Menu) component; >+ } >+ >+ /** >+ * Gets the Robot factory. The factory is created once per instance. >+ * >+ * @return The Robot factory. >+ */ >+ protected IRobotFactory getRobotFactory() { >+ if (m_robotFactory == null) { >+ m_robotFactory = new RobotFactoryConfig().getRobotFactory(); >+ } >+ return m_robotFactory; >+ } >+ >+ /** >+ * Gets the IEventThreadQueuer. >+ * >+ * @return The Robot >+ * @throws RobotException >+ * If the Robot cannot be created. >+ */ >+ protected IRobot getRobot() throws RobotException { >+ return getRobotFactory().getRobot(); >+ } >+ >+ /** >+ * @return The event thread queuer. >+ */ >+ public IEventThreadQueuer getEventThreadQueuer() { >+ return getRobotFactory().getEventThreadQueuer(); >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public Object getRealComponent() { >+ return m_menu; >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public void setComponent(Object element) { >+ m_menu = (Menu) element; >+ >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public IMenuItemAdapter[] getItems() { >+ >+ MenuItem[] items = >+ (MenuItem[]) getEventThreadQueuer().invokeAndWait( >+ "getItems", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return m_menu.getItems(); >+ } >+ }); >+ IMenuItemAdapter[] adapters = new IMenuItemAdapter[items.length]; >+ for (int i = 0; i < items.length; i++) { >+ IMenuItemAdapter menuItem = new MenuItemAdapter(items[i]); >+ adapters[i] = menuItem; >+ } >+ return adapters; >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public int getItemCount() { >+ Integer itemCount = (Integer) getEventThreadQueuer().invokeAndWait( >+ "getItemCount", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return new Integer(m_menu.getItemCount()); >+ } >+ }); >+ return itemCount.intValue(); >+ } >+ >+ >+ >+ >+} >diff --git a/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/MenuItemAdapter.java b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/MenuItemAdapter.java >new file mode 100644 >index 0000000..d9bc73e >--- /dev/null >+++ b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/MenuItemAdapter.java >@@ -0,0 +1,548 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swt.uiadapter; >+ >+import org.eclipse.jubula.rc.common.driver.ClickOptions; >+import org.eclipse.jubula.rc.common.driver.IEventMatcher; >+import org.eclipse.jubula.rc.common.driver.IEventThreadQueuer; >+import org.eclipse.jubula.rc.common.driver.IRobot; >+import org.eclipse.jubula.rc.common.driver.IRobotEventConfirmer; >+import org.eclipse.jubula.rc.common.driver.IRobotEventInterceptor; >+import org.eclipse.jubula.rc.common.driver.IRobotFactory; >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.driver.InterceptorOptions; >+import org.eclipse.jubula.rc.common.exception.RobotException; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.listener.EventLock; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuAdapter; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IMenuItemAdapter; >+import org.eclipse.jubula.rc.swt.driver.EventThreadQueuerSwtImpl; >+import org.eclipse.jubula.rc.swt.driver.RobotFactoryConfig; >+import org.eclipse.jubula.rc.swt.driver.RobotFactorySwtImpl; >+import org.eclipse.jubula.rc.swt.driver.SelectionSwtEventMatcher; >+import org.eclipse.jubula.rc.swt.driver.ShowSwtEventMatcher; >+import org.eclipse.jubula.rc.swt.implclasses.EventListener; >+import org.eclipse.jubula.rc.swt.implclasses.EventListener.Condition; >+import org.eclipse.jubula.rc.swt.utils.SwtUtils; >+import org.eclipse.jubula.tools.constants.TimeoutConstants; >+import org.eclipse.jubula.tools.i18n.I18n; >+import org.eclipse.jubula.tools.objects.event.EventFactory; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.graphics.Rectangle; >+import org.eclipse.swt.widgets.Display; >+import org.eclipse.swt.widgets.Event; >+import org.eclipse.swt.widgets.Menu; >+import org.eclipse.swt.widgets.MenuItem; >+ >+/** >+ * Implements the MenuItem interface for adapting a <code>SWT.MenuItem</code> >+ * >+ * @author BREDEX GmbH >+ */ >+public class MenuItemAdapter implements IMenuItemAdapter { >+ >+ /** the MenuItem from the AUT*/ >+ private MenuItem m_menuItem; >+ >+ >+ /** the RobotFactory from the AUT */ >+ private IRobotFactory m_robotFactory; >+ >+ /** >+ * >+ * @param component graphics component which will be adapted >+ */ >+ public MenuItemAdapter(Object component) { >+ super(); >+ m_menuItem = (MenuItem) component; >+ } >+ >+ /** >+ * Gets the Robot factory. The factory is created once per instance. >+ * >+ * @return The Robot factory. >+ */ >+ protected IRobotFactory getRobotFactory() { >+ if (m_robotFactory == null) { >+ m_robotFactory = new RobotFactoryConfig().getRobotFactory(); >+ } >+ return m_robotFactory; >+ } >+ >+ /** >+ * Gets the IEventThreadQueuer. >+ * >+ * @return The Robot >+ * @throws RobotException >+ * If the Robot cannot be created. >+ */ >+ protected IRobot getRobot() throws RobotException { >+ return getRobotFactory().getRobot(); >+ } >+ >+ /** >+ * @return The event thread queuer. >+ */ >+ public IEventThreadQueuer getEventThreadQueuer() { >+ return getRobotFactory().getEventThreadQueuer(); >+ } >+ >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public Object getRealComponent() { >+ >+ return m_menuItem; >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public void setComponent(Object element) { >+ m_menuItem = (MenuItem) element; >+ >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public String getText() { >+ return (String) getEventThreadQueuer().invokeAndWait( >+ "getText", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return m_menuItem.getText(); >+ } >+ }); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isEnabled() { >+ final Boolean isEnabled = (Boolean) getEventThreadQueuer() >+ .invokeAndWait("isEnabled", new IRunnable() { //$NON-NLS-1$ >+ public Object run() throws StepExecutionException { >+ return m_menuItem.isEnabled() ? Boolean.TRUE >+ : Boolean.FALSE; >+ } >+ }); >+ return isEnabled.booleanValue(); >+ >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isExisting() { >+ if (m_menuItem != null) { >+ return true; >+ } >+ return false; >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isSelected() { >+ final Boolean isSelected = (Boolean)getEventThreadQueuer() >+ .invokeAndWait("isSelected", new IRunnable() { //$NON-NLS-1$ >+ public Object run() throws StepExecutionException { >+ return m_menuItem.getSelection() >+ ? Boolean.TRUE : Boolean.FALSE; >+ } >+ }); >+ return isSelected.booleanValue(); >+ } >+ >+ /** >+ * @return - >+ */ >+ public boolean isShowing() { >+ >+ return true; //FIXME is here a Showing implementation? >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public IMenuAdapter getMenu() { >+ >+ Menu menu = >+ (Menu) getEventThreadQueuer().invokeAndWait( >+ "getItems", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return m_menuItem.getMenu(); >+ } >+ }); >+ >+ >+ return new MenuAdapter(menu); >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean hasSubMenu() { >+ >+ >+ >+ if (getMenu() != null) { >+ return true; >+ } >+ return false; >+ } >+ >+ >+ /** >+ * Checks whether the given menu item is a separator. >+ * This method runs in the GUI thread. >+ * @return <code>true</code> if <code>menuItem</code> is a separator item. >+ * Otherwise <code>false</code>. >+ */ >+ public boolean isSeparator() { >+ final Boolean isSeparator = (Boolean)getEventThreadQueuer() >+ .invokeAndWait( >+ ".isSeparator", new IRunnable() { //$NON-NLS-1$ >+ public Object run() throws StepExecutionException { >+ return (m_menuItem.getStyle() & SWT.SEPARATOR) != 0 >+ ? Boolean.TRUE : Boolean.FALSE; >+ } >+ }); >+ return isSeparator.booleanValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void selectMenuItem() { >+ Rectangle bounds = getMenuItemBounds(); >+ Rectangle nullBounds = new Rectangle(0, 0, 0, 0); >+ >+ if (bounds.equals(nullBounds)) { >+ selectProgramatically(); >+ } else { >+ clickMenuItem(getRobot(), m_menuItem, 1); >+ } >+ >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public IMenuAdapter openSubMenu() { >+ final MenuItem menuItem = m_menuItem; >+ MenuShownCondition cond = new MenuShownCondition(menuItem); >+ EventLock lock = new EventLock(); >+ final EventListener listener = new EventListener(lock, cond); >+ final Display d = menuItem.getDisplay(); >+ final IEventThreadQueuer queuer = new EventThreadQueuerSwtImpl(); >+ >+ queuer.invokeAndWait("addMenuShownListeners", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ d.addFilter(SWT.Show, listener); >+ >+ return null; >+ } >+ }); >+ try { >+ // Menu bar items require a click in order to open the submenu. >+ // Cascading menus are opened with a mouse-over and >+ // may be closed by a click. >+ int clickCount = isMenuBarItem(menuItem) ? 1 : 0; >+ Menu menu = (Menu)getEventThreadQueuer().invokeAndWait( >+ "openSubMenu", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return menuItem.getMenu(); >+ } >+ }); >+ Rectangle bounds = getMenuItemBounds(); >+ Rectangle nullBounds = new Rectangle(0, 0, 0, 0); >+ if (bounds.equals(nullBounds)) { >+ openSubMenuProgramatically(menu); >+ } else { >+ clickMenuItem(getRobot(), menuItem, clickCount); >+ } >+ synchronized (lock) { >+ long timeout = TimeoutConstants.SERVER_TIMEOUT_WAIT_FOR_POPUP; >+ long done = System.currentTimeMillis() + timeout; >+ long now; >+ while (!lock.isReleased() && timeout > 0) { >+ lock.wait(timeout); >+ now = System.currentTimeMillis(); >+ timeout = done - now; >+ } >+ } >+ } catch (InterruptedException e) { // ignore >+ } finally { >+ queuer.invokeAndWait("removeMenuShownListeners", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ d.removeFilter(SWT.Show, listener); >+ >+ return null; >+ } >+ }); >+ } >+ if (!lock.isReleased()) { >+ String itemText = (String)getEventThreadQueuer().invokeAndWait( >+ "getItemText", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() throws StepExecutionException { >+ if (menuItem != null && !menuItem.isDisposed()) { >+ return menuItem.getText(); >+ } >+ return "unknown menu item"; //$NON-NLS-1$ >+ } >+ >+ }); >+ itemText = SwtUtils.removeMnemonics(itemText); >+ throw new StepExecutionException( >+ I18n.getString("TestErrorEvent.MenuDidNotAppear", //$NON-NLS-1$ >+ new String [] {itemText}), >+ EventFactory.createActionError( >+ "TestErrorEvent.MenuDidNotAppear", //$NON-NLS-1$ >+ new String [] {itemText})); >+ } >+ return new MenuAdapter(cond.getMenu()); >+ } >+ >+ /** >+ * @param menuItem the menu item to check >+ * @return <code>true</code> of the given menu item is part of a menu >+ * bar. Otherwise, <code>false</code>. >+ */ >+ private boolean isMenuBarItem(final MenuItem menuItem) { >+ return ((Boolean)getEventThreadQueuer().invokeAndWait( >+ "isMenuBarItem", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() throws StepExecutionException { >+ if (menuItem != null && !menuItem.isDisposed()) { >+ Menu parent = menuItem.getParent(); >+ if (parent != null && !parent.isDisposed()) { >+ return (parent.getStyle() & SWT.BAR) != 0 >+ ? Boolean.TRUE : Boolean.FALSE; >+ } >+ } >+ return Boolean.FALSE; >+ } >+ >+ })).booleanValue(); >+ } >+ >+ >+ /** >+ * Waits for a submenu to appear. Examples of submenus are cascading menus >+ * and pulldown menus. >+ * >+ * @author BREDEX GmbH >+ * @created Oct 30, 2008 >+ */ >+ public static class MenuShownCondition implements Condition { >+ /** the menu that was shown */ >+ private Menu m_shownMenu = null; >+ >+ /** the parent item of the expected menu */ >+ private MenuItem m_parentItem; >+ >+ /** >+ * Constructor >+ * >+ * @param parentItem The parent item of the expected menu. This >+ * condition only matches if a menu with parent item >+ * <code>parentItem</code> appears. >+ */ >+ MenuShownCondition(MenuItem parentItem) { >+ m_parentItem = parentItem; >+ } >+ >+ /** >+ * >+ * @return the menu that appeared >+ */ >+ public Menu getMenu() { >+ return m_shownMenu; >+ } >+ >+ /** >+ * >+ * {@inheritDoc} >+ */ >+ public boolean isTrue(Event event) { >+ if (event.type == SWT.Show && event.widget instanceof Menu >+ && ((Menu)(event.widget)).getParentItem() == m_parentItem) { >+ m_shownMenu = (Menu)event.widget; >+ return true; >+ } >+ >+ return false; >+ } >+ } >+ >+ /** >+ * Clicks on a menu item >+ * >+ * @param robot the robot >+ * @param item the menu item >+ * @param clickCount the number of times to click the menu item >+ */ >+ public static void clickMenuItem(IRobot robot, final MenuItem item, >+ int clickCount) { >+ // FIXME existiert so schon und kann man benutzen >+// if (!isMenuItemEnabled(item)) { >+// throw new StepExecutionException("menu item not enabled", //$NON-NLS-1$ >+// EventFactory.createActionError( >+// TestErrorEvent.MENU_ITEM_NOT_ENABLED)); >+// } >+ >+ robot.click(item, null, >+ ClickOptions.create() >+ .setClickType(ClickOptions.ClickType.RELEASED) >+ .setStepMovement(false).setClickCount(clickCount)); >+ >+ } >+ /** >+ * >+ * @return bounds of MenuItem >+ */ >+ public Rectangle getMenuItemBounds() { >+ Rectangle bounds = (Rectangle)getEventThreadQueuer().invokeAndWait( >+ "getMenuItemBounds", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return SwtUtils.getBounds(m_menuItem); >+ } >+ }); >+ return bounds; >+ } >+ >+ /** >+ * open SubMenu programatically (for Mac OS) >+ * @param menu the Menu >+ */ >+ public void openSubMenuProgramatically(final Menu menu) { >+// if (!isMenuEnabled(menu)) { >+// throw new StepExecutionException("menu item not enabled", //$NON-NLS-1$ >+// EventFactory.createActionError( >+// TestErrorEvent.MENU_ITEM_NOT_ENABLED)); >+// } >+ >+ final InterceptorOptions options = new InterceptorOptions( >+ new long[]{SWT.Show}); >+ final IEventMatcher matcher = >+ new ShowSwtEventMatcher(); >+ RobotFactorySwtImpl robotSwt = new RobotFactorySwtImpl(); >+ IRobotEventInterceptor interceptor = >+ robotSwt.getRobotEventInterceptor(); >+ final IRobotEventConfirmer confirmer = interceptor >+ .intercept(options); >+ >+ final Event event = new Event(); >+ event.time = (int) System.currentTimeMillis(); >+ event.widget = menu; >+ event.display = menu.getDisplay(); >+ event.type = SWT.Show; >+ >+ getEventThreadQueuer().invokeAndWait( >+ "openSubMenuProgramatically", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ >+ menu.notifyListeners(SWT.Show, event); >+ >+ return null; >+ } >+ }); >+ >+ try { >+ confirmer.waitToConfirm(menu, matcher); >+ } catch (RobotException re) { >+ final StringBuffer sb = new StringBuffer( >+ "Robot exception occurred while clicking...\n"); //$NON-NLS-1$ >+// logRobotException(menuItem, re, sb); >+ sb.append("Component: "); //$NON-NLS-1$ >+ >+ getEventThreadQueuer().invokeAndWait( >+ "getBounds", new IRunnable() { //$NON-NLS-1$ >+ public Object run() >+ throws StepExecutionException { >+ sb.append(menu); >+ // Return value not used >+ return null; >+ } >+ }); >+// log.error(sb.toString(), re); >+ throw re; >+ } >+ } >+ >+ /** >+ * select MenuItem programatically (for Mac OS) >+ */ >+ public void selectProgramatically() { >+// FIXME must implement this check case >+// if (!isMenuItemEnabled(menuItem)) { >+// throw new StepExecutionException("menu item not enabled", //$NON-NLS-1$ >+// EventFactory.createActionError( >+// TestErrorEvent.MENU_ITEM_NOT_ENABLED)); >+// } >+ final MenuItem menuItem = m_menuItem; >+ final InterceptorOptions options = new InterceptorOptions( >+ new long[]{SWT.Selection}); >+ final IEventMatcher matcher = >+ new SelectionSwtEventMatcher(); >+ RobotFactorySwtImpl robotSwt = new RobotFactorySwtImpl(); >+ IRobotEventInterceptor interceptor = >+ robotSwt.getRobotEventInterceptor(); >+ final IRobotEventConfirmer confirmer = interceptor >+ .intercept(options); >+ >+ final Event event = new Event(); >+ event.time = (int) System.currentTimeMillis(); >+ event.widget = menuItem; >+ event.display = menuItem.getDisplay(); >+ event.type = SWT.Selection; >+ >+ getEventThreadQueuer().invokeLater( >+ "selectProgramatically", new Runnable() { //$NON-NLS-1$ >+ public void run() { >+ //if menuitem is checkbox or radiobutton set Selection >+ if ((menuItem.getStyle() & SWT.CHECK) == 0 >+ || (menuItem.getStyle() & SWT.RADIO) == 0) { >+ if (menuItem.getSelection()) { >+ menuItem.setSelection(false); >+ } else { >+ menuItem.setSelection(true); >+ } >+ } >+ >+ menuItem.notifyListeners(SWT.Selection, event); >+ >+ } >+ }); >+ >+ try { >+ confirmer.waitToConfirm(menuItem, matcher); >+ } catch (RobotException re) { >+ final StringBuffer sb = new StringBuffer( >+ "Robot exception occurred while clicking...\n"); //$NON-NLS-1$ >+ //logRobotException(menuItem, re, sb); >+ sb.append("Component: "); //$NON-NLS-1$ >+ >+ getEventThreadQueuer().invokeAndWait( >+ "getBounds", new IRunnable() { //$NON-NLS-1$ >+ public Object run() >+ throws StepExecutionException { >+ sb.append(menuItem); >+ // Return value not used >+ return null; >+ } >+ }); >+// FIXME LOG IS MISSING HERE >+// log.error(sb.toString(), re); >+ throw re; >+ } >+ >+ } >+ >+ >+} >diff --git a/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/TableAdapter.java b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/TableAdapter.java >new file mode 100644 >index 0000000..0db01aa >--- /dev/null >+++ b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/TableAdapter.java >@@ -0,0 +1,526 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swt.uiadapter; >+ >+import java.awt.Rectangle; >+ >+import org.eclipse.jubula.rc.common.driver.ClickOptions; >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.implclasses.IndexConverter; >+import org.eclipse.jubula.rc.common.implclasses.MatchUtil; >+import org.eclipse.jubula.rc.common.implclasses.table.Cell; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.ITableAdapter; >+import org.eclipse.jubula.rc.swt.listener.TableSelectionTracker; >+import org.eclipse.jubula.rc.swt.utils.SwtUtils; >+import org.eclipse.jubula.tools.objects.event.EventFactory; >+import org.eclipse.jubula.tools.objects.event.TestErrorEvent; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.custom.TableCursor; >+import org.eclipse.swt.graphics.FontMetrics; >+import org.eclipse.swt.graphics.GC; >+import org.eclipse.swt.graphics.Image; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Table; >+import org.eclipse.swt.widgets.TableColumn; >+import org.eclipse.swt.widgets.TableItem; >+/** >+ * Implements the Table interface for adapting a <code>SWT.Table</code> >+ * >+ * @author BREDEX GmbH >+ */ >+public class TableAdapter extends WidgetAdapter implements ITableAdapter { >+ /** */ >+ private Table m_table; >+ >+ /** >+ * >+ * @param objectToAdapt graphics component which will be adapted >+ */ >+ public TableAdapter(Object objectToAdapt) { >+ super(objectToAdapt); >+ m_table = (Table) objectToAdapt; >+ } >+ >+ /** {@inheritDoc} */ >+ public int getColumnCount() { >+ Integer returnvalue = (Integer) getEventThreadQueuer().invokeAndWait( >+ "getColumnCount", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return new Integer(m_table.getColumnCount()); >+ } >+ }); >+ return returnvalue.intValue(); >+ } >+ >+ /** {@inheritDoc} */ >+ public int getRowCount() { >+ Integer returnvalue = (Integer) getEventThreadQueuer().invokeAndWait( >+ "getRowCount", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return new Integer(m_table.getItemCount()); >+ } >+ }); >+ return returnvalue.intValue(); >+ } >+ >+ /** {@inheritDoc} */ >+ public String getCellText(final int row, final int column) { >+ String current = (String)getEventThreadQueuer().invokeAndWait("getCellText", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ String value = m_table.getItem(row).getText(column); >+// if (log.isDebugEnabled()) { >+// log.debug("Getting cell text:"); //$NON-NLS-1$ >+// log.debug("Row, col: " + row + ", " + col); //$NON-NLS-1$ //$NON-NLS-2$ >+// log.debug("Value: " + value); //$NON-NLS-1$ >+// } >+ return value; >+ } >+ }); >+ return current; >+ } >+ >+ /** {@inheritDoc} */ >+ public String getColumnName(final int column) { >+ String current = (String)getEventThreadQueuer().invokeAndWait("getColumnName", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ String value = m_table.getColumn(column).getText(); >+ return value; >+ } >+ }); >+ return current; >+ } >+ >+ /** {@inheritDoc} */ >+ public int getColumnFromString(final String col, final String operator) { >+ int column = -2; >+ try { >+ int usrIdxCol = Integer.parseInt(col); >+ if (usrIdxCol == 0) { >+ usrIdxCol = usrIdxCol + 1; >+ } >+ column = IndexConverter.toImplementationIndex( >+ usrIdxCol); >+ } catch (NumberFormatException nfe) { >+ try { >+ Boolean isVisible; >+ isVisible = (Boolean)getEventThreadQueuer().invokeAndWait( >+ "getColumnFromString", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ return new Boolean(m_table.getHeaderVisible()); >+ } >+ }); >+ if (!(isVisible.booleanValue())) { >+ throw new StepExecutionException("No Header", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.NO_HEADER)); >+ } >+ >+ Integer implCol; >+ implCol = (Integer)getEventThreadQueuer().invokeAndWait( >+ "getColumnFromString", new IRunnable() { //$NON-NLS-1$ >+ public Object run() throws StepExecutionException { >+ for (int i = 0; i < m_table.getColumnCount(); i++) { >+ TableColumn tblCol = m_table.getColumn(i); >+ if (MatchUtil.getInstance().match( >+ tblCol.getText(), col, operator)) { >+ return new Integer (i); >+ } >+ } >+ return new Integer (-2); >+ } >+ }); >+ column = implCol.intValue(); >+ } catch (IllegalArgumentException iae) { >+ //do nothing here >+ } >+ } >+ return column; >+ } >+ >+ /** {@inheritDoc} */ >+ public String getRowName(final int row) { >+ String current = (String)getEventThreadQueuer().invokeAndWait("getRowName", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ String value = m_table.getItem(row).getText(); >+ return value; >+ } >+ }); >+ return current; >+ } >+ >+ /** {@inheritDoc} */ >+ public int getRowFromString(final String row, final String operator) { >+ int rowInt = -2; >+ try { >+ rowInt = IndexConverter.toImplementationIndex( >+ Integer.parseInt(row)); >+ if (rowInt == -1) { >+ Boolean isVisible; >+ isVisible = (Boolean)getEventThreadQueuer().invokeAndWait( >+ "getRowFromString", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ return new Boolean(m_table.getHeaderVisible()); >+ } >+ }); >+ if (!(isVisible.booleanValue())) { >+ throw new StepExecutionException("Header not visible", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.NO_HEADER)); >+ } >+ } >+ } catch (NumberFormatException nfe) { >+ Integer implRow; >+ implRow = (Integer)getEventThreadQueuer().invokeAndWait( >+ "getRowFromString", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() throws StepExecutionException { >+ for (int i = 0; i < m_table.getItemCount(); i++) { >+ String cellTxt = getCellText(i, 0); >+ if (MatchUtil.getInstance().match( >+ cellTxt, row, operator)) { >+ return new Integer(i); >+ } >+ } >+ return new Integer(-2); >+ } >+ }); >+ rowInt = implRow.intValue(); >+ } >+ return rowInt; >+ } >+ >+ /** {@inheritDoc} */ >+ public Rectangle getBounds() { >+ Rectangle returnvalue = (Rectangle) getEventThreadQueuer() >+ .invokeAndWait("getBounds", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() throws StepExecutionException { >+ return m_table.getBounds(); >+ } >+ }); >+ >+ return returnvalue; >+ } >+ >+ /** {@inheritDoc} */ >+ public Rectangle getHeaderBounds(final int col) { >+ Rectangle cellBounds; >+ cellBounds = (Rectangle)getEventThreadQueuer().invokeAndWait( >+ "getHeaderBounds", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() throws StepExecutionException { >+ org.eclipse.swt.graphics.Rectangle rect = >+ m_table.getItem(0).getBounds(col); >+ rect.y = m_table.getClientArea().y; >+ return new Rectangle(rect.x, rect.y, rect.width, >+ rect.height); >+ } >+ }); >+ return cellBounds; >+ } >+ >+ /** {@inheritDoc} */ >+ public Cell getSelectedCell() throws StepExecutionException { >+ Cell cell = (Cell) getEventThreadQueuer().invokeAndWait( >+ "getSelectedSell", new IRunnable() { //$NON-NLS-1$ >+ public Object run() throws StepExecutionException { >+ return TableSelectionTracker.getInstance() >+ .getSelectedCell(m_table); >+ } >+ }); >+ return cell; >+ } >+ >+ /** {@inheritDoc} */ >+ public boolean isHeaderVisible() { >+ Boolean isVisible; >+ isVisible = (Boolean)getEventThreadQueuer().invokeAndWait( >+ "isHeaderVisible", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ return new Boolean(m_table.getHeaderVisible()); >+ } >+ }); >+ return isVisible.booleanValue(); >+ } >+ >+ /** {@inheritDoc} */ >+ public boolean isCellEditable(final int row, final int col) { >+ final Control cellEditor = (Control) >+ activateEditor(new Cell(row, col)); >+ boolean isEditable = ((Boolean)getEventThreadQueuer().invokeAndWait( >+ "isCellEditable", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ >+ return isEditable(cellEditor) >+ ? Boolean.TRUE : Boolean.FALSE; >+ } >+ })).booleanValue(); >+ return isEditable; >+ } >+ >+ /** {@inheritDoc} */ >+ public boolean hasCellSelection() { >+ TableItem[] selItems = (TableItem[])getEventThreadQueuer() >+ .invokeAndWait("hasCellSelection", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ return m_table.getSelection(); >+ } >+ }); >+ return selItems.length > 0; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public Rectangle scrollCellToVisible(final int row, final int col) >+ throws StepExecutionException { >+ final Table table = m_table; >+ getEventThreadQueuer().invokeAndWait("scrollCellToVisible", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ if (table.getColumnCount() > 0 || col > 0) { >+ table.showColumn(table.getColumn(col)); >+ } >+ table.showItem(table.getItem(row)); >+ return null; >+ } >+ }); >+ >+ final Rectangle cellBoundsRelativeToParent = getCellBounds(row, col); >+ >+ getEventThreadQueuer().invokeAndWait("getCellBoundsRelativeToParent", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ org.eclipse.swt.graphics.Point cellOriginRelativeToParent = >+ table.getDisplay().map( >+ table, table.getParent(), >+ new org.eclipse.swt.graphics.Point( >+ cellBoundsRelativeToParent.x, >+ cellBoundsRelativeToParent.y)); >+ cellBoundsRelativeToParent.x = >+ cellOriginRelativeToParent.x; >+ cellBoundsRelativeToParent.y = >+ cellOriginRelativeToParent.y; >+ return null; >+ } >+ }); >+ >+ Control parent = (Control)getEventThreadQueuer().invokeAndWait("getParent", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ table.getParent(); >+ return null; >+ } >+ }); >+ >+ >+ getRobot().scrollToVisible( >+ parent, cellBoundsRelativeToParent); >+ >+ return getVisibleBounds(getCellBounds(row, col)); >+ } >+ >+ /** >+ * >+ * @param row The row of the cell >+ * @param col The column of the cell >+ * @return The bounding rectangle for the cell, relative to the table's >+ * location. >+ */ >+ private Rectangle getCellBounds(final int row, final int col) { >+ Rectangle cellBounds = (Rectangle)getEventThreadQueuer().invokeAndWait( >+ "evaluateCellBounds", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ checkRowColBounds(row, col); >+ TableItem ti = m_table.getItem(row); >+ int column = (m_table.getColumnCount() > 0 || col > 0) >+ ? col : 0; >+ org.eclipse.swt.graphics.Rectangle r = >+ ti.getBounds(column); >+ String text = ti.getText(column); >+ Image image = ti.getImage(column); >+ if (text != null && text.length() != 0) { >+ GC gc = new GC(m_table); >+ int charWidth = 0; >+ try { >+ FontMetrics fm = gc.getFontMetrics(); >+ charWidth = fm.getAverageCharWidth(); >+ } finally { >+ gc.dispose(); >+ } >+ r.width = text.length() * charWidth; >+ if (image != null) { >+ r.width += image.getBounds().width; >+ } >+ } else if (image != null) { >+ r.width = image.getBounds().width; >+ } >+ if (column > 0) { >+ TableColumn tc = m_table.getColumn(column); >+ int alignment = tc.getAlignment(); >+ if (alignment == SWT.CENTER) { >+ r.x += ((double)tc.getWidth() / 2) >+ - ((double)r.width / 2); >+ } >+ if (alignment == SWT.RIGHT) { >+ r.x += tc.getWidth() - r.width; >+ } >+ } >+ >+ return new Rectangle(r.x, r.y, r.width, r.height); >+ } >+ }); >+ return cellBounds; >+ } >+ >+ /** >+ * Checks wether <code>0 <= value < count</code>. >+ * @param value The value to check. >+ * @param count The upper bound. >+ */ >+ private void checkBounds(int value, int count) { >+ if (value < 0 || value >= count) { >+ throw new StepExecutionException("Invalid row/column: " + value, //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.INVALID_INDEX_OR_HEADER)); >+ } >+ } >+ >+ /** >+ * Checks if the passed row and column are inside the bounds of the Table. >+ * @param row The row >+ * @param column The column >+ * @throws StepExecutionException If the row or the column is outside of the Table's bounds. >+ */ >+ protected void checkRowColBounds(int row, int column) >+ throws StepExecutionException { >+ checkBounds(row, getRowCount()); >+ >+ // Corner case: Only check the bounds if the table is not being >+ // used as a list or anything other than the first column >+ // is being checked. >+ int colCount = getColumnCount(); >+ if (colCount > 0 || column > 0) { >+ checkBounds(column, colCount); >+ } >+ } >+ >+ /** >+ * Computes the visible cellBounds inside the visible bounds of the table.<br> >+ * The result is the intersection of the visible bounds of the table and the >+ * bounds of the cell. >+ * @param cellBounds the bounds of the cell to click in. These bounds must >+ * be relative to the table's location. >+ * @return the visible cell bounds, relative to the table's location. >+ */ >+ private Rectangle getVisibleBounds(Rectangle cellBounds) { >+ org.eclipse.swt.graphics.Rectangle r = >+ (org.eclipse.swt.graphics.Rectangle) >+ getEventThreadQueuer().invokeAndWait("getVisibleCellBounds: " + cellBounds, //$NON-NLS-1$ >+ new IRunnable() { >+ >+ public Object run() { >+ return m_table.getClientArea(); >+ } >+ }); >+ >+ Rectangle visibleTableBounds = new Rectangle( >+ r.x, r.y, r.width, r.height); >+ Rectangle visibleCellBounds = >+ visibleTableBounds.intersection(cellBounds); >+ return visibleCellBounds; >+ } >+ >+ /** >+ * @param cellEditor The cell editor to check. >+ * @return <code>true</code> if the given cell editor is editable. >+ */ >+ private boolean isEditable(Control cellEditor) { >+ >+ if (cellEditor == null || cellEditor instanceof TableCursor >+ || cellEditor == m_table) { >+ // No actual editor found. >+ return false; >+ } >+ >+ return (cellEditor.getStyle() & SWT.READ_ONLY) == 0; >+ } >+ >+ /** >+ * @param cellEditor The cell editor to check. >+ * @return <code>true</code> if the given editor is editable. Otherwise >+ * <code>false</code>. >+ */ >+ private boolean invokeIsEditable(final Control cellEditor) { >+ >+ boolean isEditable = ((Boolean)getEventThreadQueuer().invokeAndWait( >+ "getSelectedCell", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() { >+ return isEditable(cellEditor) >+ ? Boolean.TRUE : Boolean.FALSE; >+ } >+ })).booleanValue(); >+ return isEditable; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public Object activateEditor(final Cell cell) { >+ >+ Rectangle rect = scrollCellToVisible(cell.getRow(), cell.getCol()); >+ Control editor = getTableCellEditor(cell, rect); >+ // sometimes the editor only appears after doubleclick! >+ >+ if (!invokeIsEditable(editor)) { >+ org.eclipse.swt.graphics.Rectangle cellBounds = >+ new org.eclipse.swt.graphics.Rectangle( >+ rect.x, rect.y, rect.width, rect.height); >+ ClickOptions co = ClickOptions.create().setClickCount(2); >+ Control clickTarget = editor == null >+ || editor instanceof TableCursor ? m_table : editor; >+ getRobot().click(clickTarget, cellBounds, co); >+ editor = getTableCellEditor(cell, rect); >+ } >+ >+ return editor; >+ >+ } >+ /** >+ * Gets the TableCellEditor of the given cell. >+ * The Cell has to be activated before! >+ * @param cell the cell. >+ * @param rect >+ * @return the TableCellEditor >+ */ >+ private Control getTableCellEditor(final Cell cell, Rectangle rect) { >+ org.eclipse.swt.graphics.Rectangle swtRect = >+ new org.eclipse.swt.graphics.Rectangle(rect.x, rect.y, >+ rect.width, rect.height); >+ getRobot().click(m_table, >+ swtRect, >+ ClickOptions.create().setClickCount(1)); >+ >+ >+ return SwtUtils.getCursorControl(); >+ } >+} >diff --git a/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/TreeAdapter.java b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/TreeAdapter.java >new file mode 100644 >index 0000000..7b78f2d >--- /dev/null >+++ b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/TreeAdapter.java >@@ -0,0 +1,66 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swt.uiadapter; >+ >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.implclasses.tree.AbstractTreeOperationContext; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.ITreeAdapter; >+import org.eclipse.jubula.rc.swt.implclasses.TreeOperationContext; >+import org.eclipse.swt.widgets.Tree; >+/** >+ * Implements the Tree interface for adapting a <code>SWT.Tree</code> >+ * >+ * @author BREDEX GmbH >+ */ >+public class TreeAdapter extends WidgetAdapter implements ITreeAdapter { >+ >+ >+ /** >+ * >+ * @param objectToAdapt graphics component which will be adapted >+ */ >+ public TreeAdapter(Object objectToAdapt) { >+ super(objectToAdapt); >+ } >+ /** >+ * >+ * @return the caste object >+ */ >+ private Tree getTree() { >+ return (Tree) getRealComponent(); >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public Object getRootNode() { >+ return getEventThreadQueuer() >+ .invokeAndWait("getRootNode", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return getTree().getItems(); >+ } >+ }); >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public AbstractTreeOperationContext getContext() { >+ return new TreeOperationContext(getEventThreadQueuer(), >+ getRobot(), getTree()); >+ } >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isRootVisible() { >+ >+ return true; >+ } >+ >+} >diff --git a/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/WidgetAdapter.java b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/WidgetAdapter.java >new file mode 100644 >index 0000000..6e52073 >--- /dev/null >+++ b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/WidgetAdapter.java >@@ -0,0 +1,427 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swt.uiadapter; >+ >+import org.eclipse.jubula.rc.common.caps.AbstractMenuCAPs; >+import org.eclipse.jubula.rc.common.driver.ClickOptions; >+import org.eclipse.jubula.rc.common.driver.IEventThreadQueuer; >+import org.eclipse.jubula.rc.common.driver.IRobot; >+import org.eclipse.jubula.rc.common.driver.IRobotFactory; >+import org.eclipse.jubula.rc.common.driver.IRunnable; >+import org.eclipse.jubula.rc.common.driver.RobotTiming; >+import org.eclipse.jubula.rc.common.exception.RobotException; >+import org.eclipse.jubula.rc.common.exception.StepExecutionException; >+import org.eclipse.jubula.rc.common.listener.EventLock; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IWidgetAdapter; >+import org.eclipse.jubula.rc.swt.caps.CAPUtil; >+import org.eclipse.jubula.rc.swt.caps.MenuCAPs; >+import org.eclipse.jubula.rc.swt.driver.DragAndDropHelperSwt; >+import org.eclipse.jubula.rc.swt.driver.EventThreadQueuerSwtImpl; >+import org.eclipse.jubula.rc.swt.driver.RobotFactoryConfig; >+import org.eclipse.jubula.rc.swt.implclasses.EventListener; >+import org.eclipse.jubula.rc.swt.implclasses.SimulatedTooltip; >+import org.eclipse.jubula.rc.swt.utils.SwtUtils; >+import org.eclipse.jubula.tools.constants.TimeoutConstants; >+import org.eclipse.jubula.tools.objects.event.EventFactory; >+import org.eclipse.jubula.tools.objects.event.TestErrorEvent; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.graphics.Rectangle; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Display; >+import org.eclipse.swt.widgets.Event; >+import org.eclipse.swt.widgets.Menu; >+import org.eclipse.swt.widgets.Widget; >+/** >+ * Implements the interface for widgets and supports basic methods >+ * which are needed for nearly a lot of components. >+ * >+ * @author BREDEX GmbH >+ */ >+public abstract class WidgetAdapter implements IWidgetAdapter { >+ >+ /** constants for communication */ >+ protected static final String POS_UNIT_PIXEL = "Pixel"; //$NON-NLS-1$ >+ /** constants for communication */ >+ protected static final String POS_UNI_PERCENT = "Percent"; //$NON-NLS-1$ >+ >+ >+ /** the RobotFactory from the AUT */ >+ private IRobotFactory m_robotFactory; >+ >+ /** */ >+ private Control m_component; >+ >+ /** >+ * Is true, if a popup menu is shown >+ */ >+ protected static class PopupShownCondition implements >+ EventListener.Condition { >+ >+ /** >+ * the popup menu >+ */ >+ private Menu m_popup = null; >+ >+ /** >+ * >+ * @return the popup menu >+ */ >+ public Menu getPopup() { >+ return m_popup; >+ } >+ >+ /** >+ * {@inheritDoc} >+ * @param event event >+ * @return result of the condition >+ */ >+ public boolean isTrue(Event event) { >+ >+ if (event.type == SWT.Show && event.widget instanceof Menu) { >+ m_popup = (Menu)event.widget; >+ return true; >+ } >+ >+ return false; >+ } >+ } >+ >+ /** >+ * >+ * @param objectToAdapt >+ */ >+ protected WidgetAdapter(Object objectToAdapt) { >+ m_component = (Control) objectToAdapt; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public Object getRealComponent() { >+ return m_component; >+ } >+ >+ /** >+ * Gets the Robot factory. The factory is created once per instance. >+ * >+ * @return The Robot factory. >+ */ >+ protected IRobotFactory getRobotFactory() { >+ if (m_robotFactory == null) { >+ m_robotFactory = new RobotFactoryConfig().getRobotFactory(); >+ } >+ return m_robotFactory; >+ } >+ /** >+ * Gets the Robot >+ * >+ * @return The Robot >+ * @throws RobotException >+ * If the Robot cannot be created. >+ */ >+ protected IRobot getRobot() throws RobotException { >+ return getRobotFactory().getRobot(); >+ } >+ /** >+ * @return The event thread queuer. >+ */ >+ public IEventThreadQueuer getEventThreadQueuer() { >+ return getRobotFactory().getEventThreadQueuer(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public String getPropteryValue(final String propertyname) { >+ Object prop = getEventThreadQueuer().invokeAndWait("getProperty", //$NON-NLS-1$ >+ new IRunnable() { >+ public Object run() throws StepExecutionException { >+ try { >+ return getRobot().getPropertyValue( >+ getRealComponent(), propertyname); >+ } catch (RobotException e) { >+ throw new StepExecutionException( >+ e.getMessage(), >+ EventFactory.createActionError( >+ TestErrorEvent.PROPERTY_NOT_ACCESSABLE)); >+ } >+ } >+ }); >+ return String.valueOf(prop); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isShowing() { >+ Boolean actual = (Boolean)getEventThreadQueuer() >+ .invokeAndWait("isShowing", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return m_component.isVisible() >+ ? Boolean.TRUE : Boolean.FALSE; // see findBugs; >+ } >+ }); >+ return actual.booleanValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean isEnabled() { >+ >+ Boolean actual = (Boolean)getEventThreadQueuer() >+ .invokeAndWait("isEnabled", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return m_component.isEnabled() >+ ? Boolean.TRUE : Boolean.FALSE; // see findBugs; >+ } >+ }); >+ return actual.booleanValue(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public boolean hasFocus() { >+ Boolean actual = (Boolean)getEventThreadQueuer() >+ .invokeAndWait("hasFocus", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ return m_component.isFocusControl() >+ ? Boolean.TRUE : Boolean.FALSE; // see findBugs; >+ } >+ }); >+ return actual.booleanValue(); >+ } >+ >+ /** >+ * Shows and returns the popup menu >+ * @param button MouseButton >+ * @return the popup menu >+ */ >+ public AbstractMenuCAPs showPopup( >+ final int button) { >+ final Widget component = m_component; >+ if (SwtUtils.isMouseCursorInWidget(component)) { >+ return showPopup(component, new Runnable() { >+ public void run() { >+ RobotTiming.sleepPreShowPopupDelay(); >+ >+ getRobot().clickAtCurrentPosition(component, 1, >+ button); >+ } >+ }); >+ } >+ return showPopup(50, POS_UNI_PERCENT, 50, >+ POS_UNI_PERCENT, button); >+ } >+ >+ /** >+ * Shows and returns the popup menu >+ * >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @param button MouseButton >+ * @return the popup menu >+ * @throws StepExecutionException error >+ */ >+ public AbstractMenuCAPs showPopup( >+ final int xPos, final String xUnits, >+ final int yPos, final String yUnits, >+ final int button) throws StepExecutionException { >+ final Widget component = m_component; >+ return showPopup(component, new Runnable() { >+ public void run() { >+ RobotTiming.sleepPreShowPopupDelay(); >+ boolean isAbsoluteUnitsX = >+ POS_UNIT_PIXEL.equalsIgnoreCase( >+ xUnits); >+ boolean isAbsoluteUnitsY = >+ POS_UNIT_PIXEL.equalsIgnoreCase( >+ yUnits); >+ getRobot().click(component, null, >+ ClickOptions.create().setClickCount(1) >+ .setMouseButton(button), >+ xPos, isAbsoluteUnitsX, yPos, isAbsoluteUnitsY); >+ } >+ }); >+ } >+ >+ /** >+ * Shows and returns the popup menu >+ * >+ * @param component The component for which to open the popup menu. >+ * @param showPopup A <code>Runnable</code> that, when run, should display >+ * a popup menu for the given component. >+ * @return the popup menu >+ * @throws StepExecutionException error >+ */ >+ private AbstractMenuCAPs showPopup(final Widget component, >+ final Runnable showPopup) throws StepExecutionException { >+ >+ PopupShownCondition cond = new PopupShownCondition(); >+ EventLock lock = new EventLock(); >+ final EventListener listener = new EventListener(lock, cond); >+ final Display d = component.getDisplay(); >+ final IEventThreadQueuer queuer = new EventThreadQueuerSwtImpl(); >+ >+ queuer.invokeAndWait("addPopupShownListeners", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ d.addFilter(SWT.Show, listener); >+ >+ return null; >+ } >+ }); >+ >+ try { >+ // showPopup must run in the current thread in order to >+ // avoid a race condition. >+ showPopup.run(); >+ >+ synchronized (lock) { >+ long timeout = TimeoutConstants.SERVER_TIMEOUT_WAIT_FOR_POPUP; >+ long done = System.currentTimeMillis() + timeout; >+ long now; >+ while (!lock.isReleased() && (timeout > 0)) { >+ lock.wait(timeout); >+ now = System.currentTimeMillis(); >+ timeout = done - now; >+ } >+ } >+ } catch (InterruptedException e) { >+ // ignore >+ } finally { >+ queuer.invokeAndWait("removePopupShownListeners", new IRunnable() { //$NON-NLS-1$ >+ public Object run() { >+ d.removeFilter(SWT.Show, listener); >+ >+ return null; >+ } >+ }); >+ } >+ if (!lock.isReleased()) { >+ throw new StepExecutionException("popup not shown", //$NON-NLS-1$ >+ EventFactory.createActionError( >+ TestErrorEvent.POPUP_NOT_FOUND)); >+ } >+ >+ MenuCAPs contextMenu = new MenuCAPs(); >+ contextMenu.setComponent(cond.getPopup()); >+ contextMenu.setContextMenu(true); >+ return contextMenu; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void showToolTip(final String text, final int textSize, >+ final int timePerWord, final int windowWidth) { >+ >+ final Rectangle bounds = (Rectangle)getEventThreadQueuer() >+ .invokeAndWait("gdShowText.getBounds", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() { >+ return SwtUtils.getWidgetBounds(m_component); >+ } >+ }); >+ >+ SimulatedTooltip sp = (SimulatedTooltip)getEventThreadQueuer() >+ .invokeAndWait("gdShowText.initToolTip", new IRunnable() { //$NON-NLS-1$ >+ >+ public Object run() throws StepExecutionException { >+ return new SimulatedTooltip(timePerWord, text, >+ windowWidth, textSize, bounds); >+ } >+ >+ }); >+ sp.start(); >+ try { >+ sp.join(); >+ } catch (InterruptedException e) { >+ throw new StepExecutionException(e); >+ } >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdDrag(int mouseButton, String modifier, int xPos, >+ String xUnits, int yPos, String yUnits) { >+ // Only store the Drag-Information. Otherwise the GUI-Eventqueue >+ // blocks after performed Drag! >+ final DragAndDropHelperSwt dndHelper = DragAndDropHelperSwt >+ .getInstance(); >+ dndHelper.setMouseButton(mouseButton); >+ dndHelper.setModifier(modifier); >+ dndHelper.setDragComponent(null); >+ clickDirect(0, mouseButton, xPos, xUnits, yPos, yUnits); >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public void gdDrop(final int xPos, final String xUnits, final int yPos, >+ final String yUnits, int delayBeforeDrop) { >+ final DragAndDropHelperSwt dndHelper = DragAndDropHelperSwt >+ .getInstance(); >+ final IRobot robot = getRobot(); >+ final String modifier = dndHelper.getModifier(); >+ final int mouseButton = dndHelper.getMouseButton(); >+ // Note: This method performs the drag AND drop action in one runnable >+ // in the GUI-Eventqueue because after the mousePress, the eventqueue >+ // blocks! >+ try { >+ CAPUtil.pressOrReleaseModifiers(modifier, true); >+ >+ getEventThreadQueuer().invokeAndWait("gdStartDrag", new IRunnable() { //$NON-NLS-1$ >+ public Object run() throws StepExecutionException { >+ // drag >+ robot.mousePress(dndHelper.getDragComponent(), null, >+ mouseButton); >+ >+ CAPUtil.shakeMouse(); >+ >+ // drop >+ clickDirect(0, mouseButton, xPos, xUnits, yPos, yUnits); >+ return null; >+ } >+ }); >+ >+ CAPUtil.waitBeforeDrop(delayBeforeDrop); >+ } finally { >+ getRobot().mouseRelease(null, null, mouseButton); >+ CAPUtil.pressOrReleaseModifiers(modifier, false); >+ } >+ } >+ >+ /** >+ * clicks into a component. >+ * @param count amount of clicks >+ * @param button what button should be clicked >+ * @param xPos what x position >+ * @param xUnits should x position be pixel or percent values >+ * @param yPos what y position >+ * @param yUnits should y position be pixel or percent values >+ * @throws StepExecutionException error >+ */ >+ protected void clickDirect(int count, int button, int xPos, String xUnits, >+ int yPos, String yUnits) >+ throws StepExecutionException { >+ >+ getRobot().click( >+ m_component, >+ null, >+ ClickOptions.create().setClickCount(count).setMouseButton( >+ button), xPos, xUnits.equalsIgnoreCase(POS_UNIT_PIXEL), >+ yPos, yUnits.equalsIgnoreCase(POS_UNIT_PIXEL)); >+ } >+} >\ No newline at end of file >diff --git a/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/factory/SWTAdapterFactory.java b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/factory/SWTAdapterFactory.java >new file mode 100644 >index 0000000..4f9f53f >--- /dev/null >+++ b/org.eclipse.jubula.rc.swt/src/org/eclipse/jubula/rc/swt/uiadapter/factory/SWTAdapterFactory.java >@@ -0,0 +1,67 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 BREDEX GmbH. >+ * 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: >+ * BREDEX GmbH - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jubula.rc.swt.uiadapter.factory; >+ >+import org.eclipse.jubula.rc.common.uiadapter.factory.IUIAdapterFactory; >+import org.eclipse.jubula.rc.common.uiadapter.interfaces.IComponentAdapter; >+import org.eclipse.jubula.rc.swt.uiadapter.ButtonAdapter; >+import org.eclipse.jubula.rc.swt.uiadapter.MenuAdapter; >+import org.eclipse.jubula.rc.swt.uiadapter.MenuItemAdapter; >+import org.eclipse.jubula.rc.swt.uiadapter.TableAdapter; >+import org.eclipse.jubula.rc.swt.uiadapter.TreeAdapter; >+import org.eclipse.swt.widgets.Button; >+import org.eclipse.swt.widgets.Menu; >+import org.eclipse.swt.widgets.MenuItem; >+import org.eclipse.swt.widgets.Table; >+import org.eclipse.swt.widgets.Tree; >+ >+/** >+ * This factory constructs the specific adapter out of the incoming >+ * graphics component from the AUT. >+ * >+ * @author BREDEX GmbH >+ */ >+public class SWTAdapterFactory implements IUIAdapterFactory { >+ /** */ >+ private static final Class[] SUPPORTEDCLASSES = >+ new Class[]{Button.class, Menu.class, MenuItem.class, Tree.class, >+ Table.class}; >+ >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public Class[] getSupportedClasses() { >+ return SUPPORTEDCLASSES; >+ } >+ >+ /** >+ * {@inheritDoc} >+ */ >+ public IComponentAdapter getAdapter(Object objectToAdapt) { >+ IComponentAdapter returnvalue = null; >+ if (objectToAdapt instanceof Button) { >+ returnvalue = new ButtonAdapter(objectToAdapt); >+ } else if (objectToAdapt instanceof Menu) { >+ returnvalue = new MenuAdapter(objectToAdapt); >+ } else if (objectToAdapt instanceof MenuItem) { >+ returnvalue = new MenuItemAdapter(objectToAdapt); >+ } else if (objectToAdapt instanceof Tree) { >+ returnvalue = new TreeAdapter(objectToAdapt); >+ } else if (objectToAdapt instanceof Table) { >+ returnvalue = new TableAdapter(objectToAdapt); >+ } >+ >+ >+ return returnvalue; >+ } >+ >+} >diff --git a/org.eclipse.jubula.toolkit.provider.swing/resources/xml/ComponentConfiguration.xml b/org.eclipse.jubula.toolkit.provider.swing/resources/xml/ComponentConfiguration.xml >index bd116a5..3f49ff8 100644 >--- a/org.eclipse.jubula.toolkit.provider.swing/resources/xml/ComponentConfiguration.xml >+++ b/org.eclipse.jubula.toolkit.provider.swing/resources/xml/ComponentConfiguration.xml >@@ -27,7 +27,7 @@ > > <toolkitComponent type="javax.swing.AbstractButton" visible="false"> > <realizes>guidancer.concrete.Button</realizes> >- <testerClass>org.eclipse.jubula.rc.swing.swing.implclasses.AbstractButtonImplClass</testerClass> >+ <testerClass>org.eclipse.jubula.rc.swing.swing.caps.AbstractButtonCAPs</testerClass> > <componentClass name="javax.swing.AbstractButton" /> > </toolkitComponent> > >@@ -36,13 +36,13 @@ > <typeFactory>org.eclipse.jubula.rc.common.implclasses.DefaultComponentFactory</typeFactory> > </defaultMapping> > <realizes>guidancer.concrete.MenuBar</realizes> >- <testerClass>org.eclipse.jubula.rc.swing.swing.implclasses.JMenuBarImplClass</testerClass> >+ <testerClass>org.eclipse.jubula.rc.swing.swing.caps.JMenuBarCAPs</testerClass> > <componentClass name="com.bredexsw.guidancer.autserver.swing.implclasses.JMenuBarDefaultMapping" /> > </toolkitComponent> > > <toolkitComponent type="javax.swing.JComboBox" visible="false"> > <realizes>guidancer.concrete.ComboBox</realizes> >- <testerClass>org.eclipse.jubula.rc.swing.swing.implclasses.JComboBoxImplClass</testerClass> >+ <testerClass>org.eclipse.jubula.rc.swing.swing.caps.JComboBoxCAPs</testerClass> > <componentClass name="javax.swing.JComboBox" /> > </toolkitComponent> > >@@ -66,7 +66,7 @@ > > <toolkitComponent type="javax.swing.JTable" visible="false"> > <realizes>guidancer.concrete.Table</realizes> >- <testerClass>org.eclipse.jubula.rc.swing.swing.implclasses.JTableImplClass</testerClass> >+ <testerClass>org.eclipse.jubula.rc.swing.swing.caps.JTableCAPs</testerClass> > <componentClass name="javax.swing.JTable" /> > </toolkitComponent> > >@@ -78,7 +78,7 @@ > > <toolkitComponent type="javax.swing.JTree" visible="false"> > <realizes>guidancer.concrete.Tree</realizes> >- <testerClass>org.eclipse.jubula.rc.swing.swing.implclasses.JTreeImplClass</testerClass> >+ <testerClass>org.eclipse.jubula.rc.swing.swing.caps.JTreeCAPs</testerClass> > <componentClass name="javax.swing.JTree" /> > </toolkitComponent> > >diff --git a/org.eclipse.jubula.toolkit.provider.swt/resources/xml/ComponentConfiguration.xml b/org.eclipse.jubula.toolkit.provider.swt/resources/xml/ComponentConfiguration.xml >index 0695724..b55dd5c 100644 >--- a/org.eclipse.jubula.toolkit.provider.swt/resources/xml/ComponentConfiguration.xml >+++ b/org.eclipse.jubula.toolkit.provider.swt/resources/xml/ComponentConfiguration.xml >@@ -184,7 +184,7 @@ > > <toolkitComponent type="org.eclipse.swt.widgets.Button" visible="false"> > <realizes>guidancer.abstract.SwtButton</realizes> >- <testerClass>org.eclipse.jubula.rc.swt.implclasses.ButtonImplClass</testerClass> >+ <testerClass>org.eclipse.jubula.rc.swt.caps.ButtonCAPs</testerClass> > <componentClass name="org.eclipse.swt.widgets.Button" /> > </toolkitComponent> > >@@ -203,7 +203,7 @@ > <typeFactory>org.eclipse.jubula.rc.common.implclasses.DefaultComponentFactory</typeFactory> > </defaultMapping> > <realizes>guidancer.concrete.MenuBar</realizes> >- <testerClass>org.eclipse.jubula.rc.swt.implclasses.MenuImplClass</testerClass> >+ <testerClass>org.eclipse.jubula.rc.swt.caps.MenuCAPs</testerClass> > <componentClass name="com.bredexsw.guidancer.autswtserver.implclasses.MenuDefaultMapping" /> > </toolkitComponent> > >@@ -239,13 +239,13 @@ > > <toolkitComponent type="org.eclipse.swt.widgets.Table" visible="false"> > <realizes>guidancer.concrete.Table</realizes> >- <testerClass>org.eclipse.jubula.rc.swt.implclasses.TableImplClass</testerClass> >+ <testerClass>org.eclipse.jubula.rc.swt.caps.TableCAPs</testerClass> > <componentClass name="org.eclipse.swt.widgets.Table" /> > </toolkitComponent> > > <toolkitComponent type="org.eclipse.swt.widgets.Tree" observable="false"> > <realizes>guidancer.concrete.Tree</realizes> >- <testerClass>org.eclipse.jubula.rc.swt.implclasses.TableTreeImplClass</testerClass> >+ <testerClass>org.eclipse.jubula.rc.swt.caps.TreeCAPs</testerClass> > <componentClass name="org.eclipse.swt.widgets.Tree" /> > <action name="CompSystem.VerifyCheckboxOfSelectedEntry" changed="4.1"> > <method>gdVerifySelectedCheckbox</method> >@@ -370,7 +370,7 @@ > > <toolkitComponent type="org.eclipse.swt.widgets.SwtTree"> > <realizes>org.eclipse.swt.widgets.Tree</realizes> >- <testerClass>org.eclipse.jubula.rc.swt.implclasses.TableTreeImplClass</testerClass> >+ <testerClass>org.eclipse.jubula.rc.swt.caps.TreeCAPs</testerClass> > <componentClass name="org.eclipse.swt.widgets.Tree" /> > <action name="CompSystem.SelectByTextPathAtColumn" changed="1.22"> > <method>gdSelect</method> >-- >1.7.11 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 394179
:
223499
|
223848
|
223948
|
223950
|
224096
|
224662
|
225163