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.ArrayList;
  28 import java.util.LinkedList;
  29 import java.util.List;
  30 import org.eclipse.swt.widgets.Tree;
  31 import org.eclipse.swt.widgets.TreeItem;
  32 import org.jemmy.Point;
  33 import org.jemmy.action.GetAction;
  34 import org.jemmy.control.ControlType;
  35 import org.jemmy.control.Property;
  36 import org.jemmy.control.Wrap;
  37 import org.jemmy.env.Environment;
  38 import org.jemmy.input.KeyboardSelectable;
  39 import org.jemmy.input.KeyboardSelector;
  40 import org.jemmy.input.StringTree;
  41 import org.jemmy.interfaces.ControlInterface;
  42 import org.jemmy.interfaces.Focusable;
  43 import org.jemmy.interfaces.Parent;
  44 import org.jemmy.interfaces.Selectable;
  45 import org.jemmy.interfaces.Selector;
  46 import org.jemmy.interfaces.TypeControlInterface;
  47 
  48 /**
  49  *
  50  * @author shura
  51  * @author erikgreijus
  52  */
  53 @ControlType(Tree.class)
  54 public class TreeWrap<T extends Tree> extends ScrollableWrap<T> implements KeyboardSelectable<String>, Focusable {
  55 
  56     private KeyboardSelector<String> selector = null;
  57     private ItemParent<TreeItem> items;
  58     private SWTTree tree = null;
  59 
  60     public TreeWrap(Environment env, T node) {
  61         super(env, node);
  62     }
  63 
  64     private void addItems(TreeItem[] items, LinkedList<TreeItem> list) {
  65         for (TreeItem item : items) {
  66             list.add(item);
  67             if (item.getExpanded()) {
  68                 addItems(item.getItems(), list);
  69             }
  70         }
  71     }
  72 
  73     public List<TreeItem> getItems() {
  74         return new GetAction<List<TreeItem>>() {
  75 
  76             @Override
  77             public void run(Object... parameters) throws Exception {
  78                 LinkedList<TreeItem> res = new LinkedList<>();
  79                 addItems(getControl().getItems(), res);
  80                 setResult(res);
  81             }
  82         }.dispatch(getEnvironment());
  83     }
  84 
  85     public TreeItem getSelectedItem() {
  86         return new GetAction<TreeItem>() {
  87 
  88             @Override
  89             public void run(Object... parameters) throws Exception {
  90                 if (getControl().getSelection().length > 0) {
  91                     setResult(getControl().getSelection()[0]);
  92                 } else {
  93                     setResult(null);
  94                 }
  95             }
  96         }.dispatch(getEnvironment());
  97     }
  98 
  99     @Override
 100     public int selection() {
 101         return new GetAction<Integer>() {
 102 
 103             @Override
 104             public void run(Object... parameters) throws Exception {
 105                 if (getControl().getSelection().length > 0) {
 106                     TreeItem selection = getControl().getSelection()[0];
 107                     setResult(0);
 108                     if (selection != null) {
 109                         List<TreeItem> items = getItems();
 110                         for (int i = 0; i < items.size(); i++) {
 111                             if (items.get(i) == selection) {
 112                                 setResult(i);
 113                             }
 114                         }
 115                     }
 116                 } else {
 117                     setResult(0);
 118                 }
 119 
 120             }
 121         }.dispatch(getEnvironment());
 122     }
 123 
 124     @Override
 125     public boolean isVertical() {
 126         return true;
 127     }
 128 
 129     public int index(TreeItem item) {
 130         return getItems().indexOf(item);
 131     }
 132 
 133     @Override
 134     public Selector<String> selector() {
 135         if (selector == null) {
 136             selector = new KeyboardSelector<>(this, this);
 137         }
 138         return selector;
 139     }
 140 
 141     @Override
 142     public Class<String> getType() {
 143         return String.class;
 144     }
 145 
 146     /**
 147      * Click point for Tree (top of the visible part)
 148      *
 149      * @return The click point of this Tree
 150      */
 151     @Override
 152     @Property(Wrap.CLICKPOINT_PROP_NAME)
 153     public Point getClickPoint() {
 154         return new Point(getScreenBounds().getWidth() / 2, 1);
 155     }
 156 
 157     @Override
 158     public <TYPE, INTERFACE extends TypeControlInterface<TYPE>> INTERFACE as(Class<INTERFACE> interfaceClass, Class<TYPE> type) {
 159         if (interfaceClass.equals(Parent.class) && TreeItem.class.equals(type)) {
 160             if (items == null) {
 161                 items = new ItemParent<TreeItem>(this, TreeItem.class) {
 162 
 163                     @Override
 164                     protected List<TreeItem> getItems() {
 165                         return TreeWrap.this.getItems();
 166                     }
 167                 };
 168             }
 169             return (INTERFACE) items;
 170         }
 171         if (org.jemmy.interfaces.Tree.class.isAssignableFrom(interfaceClass)
 172                 && interfaceClass.isAssignableFrom(StringTree.class) && TreeItem.class.equals(type)) {
 173             if (tree == null) {
 174                 tree = new SWTTree(this);
 175             }
 176             return (INTERFACE) tree;
 177         }
 178         return super.as(interfaceClass, type);
 179     }
 180 
 181     @Override
 182     public <INTERFACE extends ControlInterface> INTERFACE as(Class<INTERFACE> interfaceClass) {
 183         if (org.jemmy.interfaces.Tree.class.isAssignableFrom(interfaceClass)
 184                 && interfaceClass.isAssignableFrom(StringTree.class)) {
 185             if (tree == null) {
 186                 tree = new SWTTree(this);
 187             }
 188             return (INTERFACE) tree;
 189         }
 190         return super.as(interfaceClass);
 191     }
 192 
 193     @Override
 194     public <TYPE, INTERFACE extends TypeControlInterface<TYPE>> boolean is(Class<INTERFACE> interfaceClass, Class<TYPE> type) {
 195         if (interfaceClass.equals(Parent.class) && TreeItem.class.equals(type)) {
 196             return true;
 197         }
 198         if (org.jemmy.interfaces.Tree.class.isAssignableFrom(interfaceClass)
 199                 && interfaceClass.isAssignableFrom(StringTree.class) && TreeItem.class.equals(type)) {
 200             return true;
 201         }
 202         return super.is(interfaceClass, type);
 203     }
 204 
 205     @Override
 206     public <INTERFACE extends ControlInterface> boolean is(Class<INTERFACE> interfaceClass) {
 207         if (org.jemmy.interfaces.Tree.class.isAssignableFrom(interfaceClass)
 208                 && interfaceClass.isAssignableFrom(StringTree.class)) {
 209             return true;
 210         }
 211         return super.is(interfaceClass);
 212     }
 213 
 214     @Override
 215     public int index(String item) {
 216         return getStates().indexOf(item);
 217     }
 218 
 219     @Property(Selectable.STATES_PROP_NAME)
 220     @Override
 221     public List<String> getStates() {
 222         return new GetAction<List<String>>() {
 223 
 224             @Override
 225             public void run(Object... parameters) throws Exception {
 226                 List<TreeItem> itms = getItems();
 227                 List<String> res = new ArrayList<>(itms.size());
 228                 itms.stream().forEach((i) -> {
 229                     res.add(i.getText());
 230                 });
 231                 setResult(res);
 232             }
 233         }.dispatch(getEnvironment());
 234     }
 235 
 236     @Property(Selectable.STATE_PROP_NAME)
 237     @Override
 238     public String getState() {
 239         return new GetAction<String>() {
 240 
 241             @Override
 242             public void run(Object... parameters) throws Exception {
 243                 setResult((getSelectedItem() == null) ? "" : getSelectedItem().getText());
 244             }
 245         }.dispatch(getEnvironment());
 246     }
 247 }