1 /* 2 * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package org.jemmy.swt; 26 27 import java.util.Arrays; 28 29 import org.eclipse.swt.graphics.Point; 30 import org.eclipse.swt.widgets.Combo; 31 import org.jemmy.action.GetAction; 32 import org.jemmy.control.ControlType; 33 import org.jemmy.control.Property; 34 import org.jemmy.control.Wrap; 35 import org.jemmy.env.Environment; 36 import org.jemmy.input.KeyboardSelectable; 37 import org.jemmy.input.KeyboardSelector; 38 import org.jemmy.input.SelectionText; 39 import org.jemmy.interfaces.ControlInterface; 40 import org.jemmy.interfaces.Focusable; 41 import org.jemmy.interfaces.Keyboard.KeyboardButtons; 42 import org.jemmy.interfaces.Keyboard.KeyboardModifier; 43 import org.jemmy.interfaces.Selector; 44 45 /** 46 * 47 * @author shura, erikgreijus 48 * @param <T> 49 */ 50 @ControlType(Combo.class) 51 public class ComboWrap<T extends Combo> extends ControlWrap<T> implements 52 KeyboardSelectable<String>, Focusable { 53 54 public static final String DISMISSAL_BUTTON_PROP = ComboWrap.class.getName() + ".dismissal.button"; 55 public static final String DISMISSAL_MODIFIER_PROP = ComboWrap.class.getName() + ".dismissal.modifier"; 56 private final KeyboardButtons dismissalButton; 57 private final KeyboardModifier[] dismissalModifier; 58 59 class ComboKeyboardSelector<T> extends KeyboardSelector<T> { 60 61 private final Wrap<?> comboWrap; 62 63 public ComboKeyboardSelector(Wrap<?> wrap, KeyboardSelectable<T> control) { 64 super(wrap, control); 65 comboWrap = wrap; 66 } 67 68 @Override 69 public void select(T state) { 70 super.select(state); 71 comboWrap.keyboard().pushKey(dismissalButton, dismissalModifier); 72 } 73 } 74 75 class FocusableSelectionText extends SelectionText implements Focusable { 76 77 protected ClickFocus focuser; 78 private final ComboWrap<T> comboWrap; 79 80 public FocusableSelectionText(ComboWrap<T> textWrap) { 81 super(textWrap); 82 this.comboWrap = textWrap; 83 } 84 85 @Override 86 public double position() { 87 return comboWrap.position(); 88 } 89 90 @Override 91 public String text() { 92 return comboWrap.text(); 93 } 94 95 @Override 96 public double anchor() { 97 return comboWrap.anchor(); 98 } 99 100 @Override 101 public ClickFocus focuser() { 102 if (focuser == null) { 103 focuser = new ClickFocus(); 104 } 105 return focuser; 106 } 107 } 108 109 FocusableSelectionText text = new FocusableSelectionText(this); 110 private ComboKeyboardSelector<String> selector = null; 111 112 public ComboWrap(Environment env, T node) { 113 super(env, node); 114 KeyboardButtons defaultDismissalButton = System.getProperty("os.name").toLowerCase().contains("windows") ? KeyboardButtons.ESCAPE : KeyboardButtons.SPACE; 115 KeyboardModifier[] defaultDismissalModifiers = new KeyboardModifier[0]; 116 dismissalButton = env.getProperty(KeyboardButtons.class, 117 DISMISSAL_BUTTON_PROP, defaultDismissalButton); 118 dismissalModifier = (KeyboardModifier[]) env.getProperty(KeyboardModifier[].class, 119 DISMISSAL_MODIFIER_PROP, defaultDismissalModifiers); 120 } 121 122 @Override 123 public java.util.List<String> getStates() { 124 return new GetAction<java.util.List<String>>() { 125 126 @Override 127 public void run(Object... parameters) throws Exception { 128 setResult(Arrays.asList(getControl().getItems())); 129 } 130 }.dispatch(getEnvironment()); 131 } 132 133 @Override 134 public String getState() { 135 return new GetAction<String>() { 136 137 @Override 138 public void run(Object... parameters) throws Exception { 139 if (getControl().getSelectionIndex() >= 0) { 140 setResult(getControl().getItem(getControl().getSelectionIndex())); 141 } else { 142 setResult(null); 143 } 144 } 145 }.dispatch(getEnvironment()); 146 } 147 148 @Override 149 public int selection() { 150 return new GetAction<Integer>() { 151 152 @Override 153 public void run(Object... parameters) throws Exception { 154 setResult(getControl().getSelectionIndex()); 155 } 156 }.dispatch(getEnvironment()); 157 } 158 159 @Override 160 public Selector<String> selector() { 161 if (selector == null) { 162 selector = new ComboKeyboardSelector<>(this, this); 163 } 164 return selector; 165 } 166 167 @Override 168 public Class<String> getType() { 169 return String.class; 170 } 171 172 @Override 173 public boolean isVertical() { 174 return true; 175 } 176 177 @Override 178 public int index(String item) { 179 return new GetAction<Integer>() { 180 181 @Override 182 public void run(Object... parameters) throws Exception { 183 setResult(getControl().indexOf(item)); 184 } 185 }.dispatch(getEnvironment()); 186 } 187 188 @Override 189 public ClickFocus focuser() { 190 if (focuser == null) { 191 super.focuser().clickCount = 2; 192 } 193 return focuser; 194 } 195 196 @Override 197 public boolean hasFocus() { 198 GetAction<Boolean> action; 199 action = new GetAction<Boolean>() { 200 201 @Override 202 public void run(Object... parameters) { 203 setResult(getControl().isFocusControl() || getControl().getListVisible()); 204 } 205 206 @Override 207 public String toString() { 208 return "Getting focus state for " + getControl(); 209 } 210 }; 211 getEnvironment().getExecutor().execute(getEnvironment(), true, action); 212 return action.getResult(); 213 } 214 215 @Property(Wrap.POSITION_PROP_NAME) 216 public Integer position() { 217 GetAction<Integer> action = new GetAction<Integer>() { 218 219 @Override 220 public void run(Object... parameters) { 221 setResult(getControl().getSelection().x); 222 } 223 }; 224 getEnvironment().getExecutor().execute(getEnvironment(), true, action); 225 return action.getResult(); 226 } 227 228 @Property(SelectionText.SELECTION_ANCHOR_PROP_NAME) 229 public Integer anchor() { 230 GetAction<Integer> action = new GetAction<Integer>() { 231 232 @Override 233 public void run(Object... parameters) { 234 Point selection = getControl().getSelection(); 235 setResult((selection.x == getControl().getCaretPosition()) 236 ? selection.y : selection.x); 237 } 238 }; 239 getEnvironment().getExecutor().execute(getEnvironment(), true, action); 240 return action.getResult(); 241 } 242 243 @Property(Wrap.TEXT_PROP_NAME) 244 @Override 245 public String text() { 246 GetAction<String> action = new GetAction<String>() { 247 248 @Override 249 public void run(Object... parameters) { 250 setResult(getControl().getText()); 251 } 252 }; 253 getEnvironment().getExecutor().execute(getEnvironment(), true, action); 254 return action.getResult(); 255 } 256 257 @Override 258 public <INTERFACE extends ControlInterface> boolean is(Class<INTERFACE> interfaceClass) { 259 if (interfaceClass.isAssignableFrom(SelectionText.class)) { 260 return true; 261 } 262 if (interfaceClass.equals(Focusable.class)) { 263 return true; 264 } 265 return super.is(interfaceClass); 266 } 267 268 @SuppressWarnings("unchecked") 269 @Override 270 public <INTERFACE extends ControlInterface> INTERFACE as(Class<INTERFACE> interfaceClass) { 271 if (interfaceClass.isAssignableFrom(SelectionText.class)) { 272 return (INTERFACE) text; 273 } 274 if (interfaceClass.isAssignableFrom(Focusable.class)) { 275 return (INTERFACE) text; 276 } 277 return super.as(interfaceClass); 278 } 279 }