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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.jemmy.swt;
  24 
  25 import java.util.ArrayList;
  26 import java.util.LinkedList;
  27 import java.util.List;
  28 import org.eclipse.swt.widgets.Tree;
  29 import org.eclipse.swt.widgets.TreeItem;
  30 import org.jemmy.Point;
  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.StringTree;
  39 import org.jemmy.interfaces.ControlInterface;
  40 import org.jemmy.interfaces.Focusable;
  41 import org.jemmy.interfaces.Parent;
  42 import org.jemmy.interfaces.Selectable;
  43 import org.jemmy.interfaces.Selector;
  44 import org.jemmy.interfaces.TypeControlInterface;
  45 
  46 /**
  47  *
  48  * @author shura, erikgreijus
  49  * @param <T>
  50  */
  51 @ControlType(Tree.class)
  52 public class TreeWrap<T extends Tree> extends ScrollableWrap<T> implements KeyboardSelectable<String>, Focusable {
  53 
  54     private KeyboardSelector<String> selector = null;
  55     private ItemParent<TreeItem> items;
  56     private SWTTree tree = null;
  57 
  58     public TreeWrap(Environment env, T node) {
  59         super(env, node);
  60     }
  61 
  62     private void addItems(TreeItem[] items, LinkedList<TreeItem> list) {
  63         for (TreeItem item : items) {
  64             list.add(item);
  65             if (item.getExpanded()) {
  66                 addItems(item.getItems(), list);
  67             }
  68         }
  69     }
  70 
  71     public List<TreeItem> getItems() {
  72         return new GetAction<List<TreeItem>>() {
  73 
  74             @Override
  75             public void run(Object... parameters) throws Exception {
  76                 LinkedList<TreeItem> res = new LinkedList<>();
  77                 addItems(getControl().getItems(), res);
  78                 setResult(res);
  79             }
  80         }.dispatch(getEnvironment());
  81     }
  82 
  83     public TreeItem getSelectedItem() {
  84         return new GetAction<TreeItem>() {
  85 
  86             @Override
  87             public void run(Object... parameters) throws Exception {
  88                 if (getControl().getSelection().length > 0) {
  89                     setResult(getControl().getSelection()[0]);
  90                 } else {
  91                     setResult(null);
  92                 }
  93             }
  94         }.dispatch(getEnvironment());
  95     }
  96 
  97     @Override
  98     public int selection() {
  99         return new GetAction<Integer>() {
 100 
 101             @Override
 102             public void run(Object... parameters) throws Exception {
 103                 if (getControl().getSelection().length > 0) {
 104                     TreeItem selection = getControl().getSelection()[0];
 105                     setResult(0);
 106                     if (selection != null) {
 107                         List<TreeItem> items = getItems();
 108                         for (int i = 0; i < items.size(); i++) {
 109                             if (items.get(i) == selection) {
 110                                 setResult(i);
 111                             }
 112                         }
 113                     }
 114                 } else {
 115                     setResult(0);
 116                 }
 117 
 118             }
 119         }.dispatch(getEnvironment());
 120     }
 121 
 122     @Override
 123     public boolean isVertical() {
 124         return true;
 125     }
 126 
 127     public int index(TreeItem item) {
 128         return getItems().indexOf(item);
 129     }
 130 
 131     @Override
 132     public Selector<String> selector() {
 133         if (selector == null) {
 134             selector = new KeyboardSelector<>(this, this);
 135         }
 136         return selector;
 137     }
 138 
 139     @Override
 140     public Class<String> getType() {
 141         return String.class;
 142     }
 143 
 144     /**
 145      * Click point for Tree (top of the visible part)
 146      *
 147      * @return The click point of this Tree
 148      */
 149     @Override
 150     @Property(Wrap.CLICKPOINT_PROP_NAME)
 151     public Point getClickPoint() {
 152         return new Point(getScreenBounds().getWidth() / 2, 1);
 153     }
 154 
 155     @Override
 156     public <TYPE, INTERFACE extends TypeControlInterface<TYPE>> INTERFACE as(Class<INTERFACE> interfaceClass, Class<TYPE> type) {
 157         if (interfaceClass.equals(Parent.class) && TreeItem.class.equals(type)) {
 158             if (items == null) {
 159                 items = new ItemParent<TreeItem>(this, TreeItem.class) {
 160 
 161                     @Override
 162                     protected List<TreeItem> getItems() {
 163                         return TreeWrap.this.getItems();
 164                     }
 165                 };
 166             }
 167             return (INTERFACE) items;
 168         }
 169         if (org.jemmy.interfaces.Tree.class.isAssignableFrom(interfaceClass)
 170                 && interfaceClass.isAssignableFrom(StringTree.class) && TreeItem.class.equals(type)) {
 171             if (tree == null) {
 172                 tree = new SWTTree(this);
 173             }
 174             return (INTERFACE) tree;
 175         }
 176         return super.as(interfaceClass, type);
 177     }
 178 
 179     @Override
 180     public <INTERFACE extends ControlInterface> INTERFACE as(Class<INTERFACE> interfaceClass) {
 181         if (org.jemmy.interfaces.Tree.class.isAssignableFrom(interfaceClass)
 182                 && interfaceClass.isAssignableFrom(StringTree.class)) {
 183             if (tree == null) {
 184                 tree = new SWTTree(this);
 185             }
 186             return (INTERFACE) tree;
 187         }
 188         return super.as(interfaceClass);
 189     }
 190 
 191     @Override
 192     public <TYPE, INTERFACE extends TypeControlInterface<TYPE>> boolean is(Class<INTERFACE> interfaceClass, Class<TYPE> type) {
 193         if (interfaceClass.equals(Parent.class) && TreeItem.class.equals(type)) {
 194             return true;
 195         }
 196         if (org.jemmy.interfaces.Tree.class.isAssignableFrom(interfaceClass)
 197                 && interfaceClass.isAssignableFrom(StringTree.class) && TreeItem.class.equals(type)) {
 198             return true;
 199         }
 200         return super.is(interfaceClass, type);
 201     }
 202 
 203     @Override
 204     public <INTERFACE extends ControlInterface> boolean is(Class<INTERFACE> interfaceClass) {
 205         if (org.jemmy.interfaces.Tree.class.isAssignableFrom(interfaceClass)
 206                 && interfaceClass.isAssignableFrom(StringTree.class)) {
 207             return true;
 208         }
 209         return super.is(interfaceClass);
 210     }
 211 
 212     @Override
 213     public int index(String item) {
 214         return getStates().indexOf(item);
 215     }
 216 
 217     @Property(Selectable.STATES_PROP_NAME)
 218     @Override
 219     public List<String> getStates() {
 220         return new GetAction<List<String>>() {
 221 
 222             @Override
 223             public void run(Object... parameters) throws Exception {
 224                 List<TreeItem> itms = getItems();
 225                 List<String> res = new ArrayList<>(itms.size());
 226                 itms.stream().forEach((i) -> {
 227                     res.add(i.getText());
 228                 });
 229                 setResult(res);
 230             }
 231         }.dispatch(getEnvironment());
 232     }
 233 
 234     @Property(Selectable.STATE_PROP_NAME)
 235     @Override
 236     public String getState() {
 237         return new GetAction<String>() {
 238 
 239             @Override
 240             public void run(Object... parameters) throws Exception {
 241                 setResult((getSelectedItem() == null) ? "" : getSelectedItem().getText());
 242             }
 243         }.dispatch(getEnvironment());
 244     }
 245 }