Coverage Report - org.eclipse.swtbot.swt.finder.widgets.SWTBotTree
 
Classes in this File Line Coverage Branch Coverage Complexity
SWTBotTree
87%
67/77
62%
5/8
1.721
SWTBotTree$1
100%
3/3
N/A
1.721
SWTBotTree$10
90%
9/10
83%
5/6
1.721
SWTBotTree$11
100%
12/12
100%
4/4
1.721
SWTBotTree$12
86%
13/15
75%
3/4
1.721
SWTBotTree$13
75%
3/4
50%
1/2
1.721
SWTBotTree$14
85%
6/7
75%
3/4
1.721
SWTBotTree$15
77%
7/9
100%
2/2
1.721
SWTBotTree$16
100%
3/3
50%
1/2
1.721
SWTBotTree$2
100%
3/3
N/A
1.721
SWTBotTree$3
100%
6/6
100%
2/2
1.721
SWTBotTree$4
100%
4/4
N/A
1.721
SWTBotTree$5
100%
3/3
N/A
1.721
SWTBotTree$6
100%
12/12
100%
6/6
1.721
SWTBotTree$7
90%
9/10
50%
3/6
1.721
SWTBotTree$8
0%
0/9
0%
0/6
1.721
SWTBotTree$9
100%
5/5
N/A
1.721
 
 1  8
 /*******************************************************************************
 2  
  * Copyright (c) 2008 Ketan Padegaonkar and others.
 3  
  * All rights reserved. This program and the accompanying materials
 4  
  * are made available under the terms of the Eclipse Public License v1.0
 5  
  * which accompanies this distribution, and is available at
 6  
  * http://www.eclipse.org/legal/epl-v10.html
 7  
  *
 8  
  * Contributors:
 9  
  *     Ketan Padegaonkar - initial API and implementation
 10  
  *******************************************************************************/
 11  
 package org.eclipse.swtbot.swt.finder.widgets;
 12  
 
 13  
 import java.util.ArrayList;
 14  
 import java.util.Arrays;
 15  
 import java.util.List;
 16  
 
 17  
 import org.eclipse.swt.SWT;
 18  
 import org.eclipse.swt.widgets.Tree;
 19  
 import org.eclipse.swt.widgets.TreeItem;
 20  
 import org.eclipse.swtbot.swt.finder.ReferenceBy;
 21  
 import org.eclipse.swtbot.swt.finder.SWTBot;
 22  
 import org.eclipse.swtbot.swt.finder.SWTBotWidget;
 23  
 import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
 24  
 import org.eclipse.swtbot.swt.finder.results.ArrayResult;
 25  
 import org.eclipse.swtbot.swt.finder.results.BoolResult;
 26  
 import org.eclipse.swtbot.swt.finder.results.IntResult;
 27  
 import org.eclipse.swtbot.swt.finder.results.ListResult;
 28  
 import org.eclipse.swtbot.swt.finder.results.Result;
 29  
 import org.eclipse.swtbot.swt.finder.results.StringResult;
 30  
 import org.eclipse.swtbot.swt.finder.results.VoidResult;
 31  
 import org.eclipse.swtbot.swt.finder.results.WidgetResult;
 32  
 import org.eclipse.swtbot.swt.finder.utils.MessageFormat;
 33  
 import org.eclipse.swtbot.swt.finder.utils.StringUtils;
 34  
 import org.eclipse.swtbot.swt.finder.utils.TableCollection;
 35  
 import org.eclipse.swtbot.swt.finder.utils.TableRow;
 36  
 import org.eclipse.swtbot.swt.finder.utils.internal.Assert;
 37  
 import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
 38  
 import org.hamcrest.SelfDescribing;
 39  
 
 40  
 /**
 41  
  * @author Ketan Padegaonkar <KetanPadegaonkar [at] gmail [dot] com>
 42  
  * @author Joshua Gosse <jlgosse [at] ca [dot] ibm [dot] com>
 43  
  * @version $Id$
 44  
  */
 45  
 @SWTBotWidget(clasz = Tree.class, preferredName = "tree", referenceBy = { ReferenceBy.LABEL })
 46  
 public class SWTBotTree extends AbstractSWTBot<Tree> {
 47  
 
 48  
         /**
 49  
          * Constructs an instance of this object with the given tree.
 50  
          *
 51  
          * @param tree the widget.
 52  
          * @param description the description of the widget, this will be reported by {@link #toString()}
 53  
          * @throws WidgetNotFoundException if the widget is <code>null</code> or widget has been disposed.
 54  
          */
 55  
         public SWTBotTree(Tree tree, SelfDescribing description) throws WidgetNotFoundException {
 56  144
                 super(tree, description);
 57  144
         }
 58  
 
 59  
         /**
 60  
          * Constructs an instance of this object with the given tree.
 61  
          *
 62  
          * @param tree the widget.
 63  
          * @throws WidgetNotFoundException if the widget is <code>null</code> or widget has been disposed.
 64  
          */
 65  
         public SWTBotTree(Tree tree) throws WidgetNotFoundException {
 66  79
                 this(tree, null);
 67  79
         }
 68  
 
 69  
         /**
 70  
          * Gets the number of rows in the tree.
 71  
          *
 72  
          * @return the number of rows in the tree
 73  
          */
 74  
         public int rowCount() {
 75  9
                 return syncExec(new IntResult() {
 76  
                         public Integer run() {
 77  9
                                 return widget.getItems().length;
 78  
                         }
 79  
                 });
 80  
         }
 81  
 
 82  
         /**
 83  
          * Gets the column count of this tree.
 84  
          *
 85  
          * @return the number of columns in the tree
 86  
          */
 87  
         public int columnCount() {
 88  28
                 return syncExec(new IntResult() {
 89  
                         public Integer run() {
 90  28
                                 return widget.getColumnCount();
 91  
                         }
 92  
                 });
 93  
         }
 94  
 
 95  
         /**
 96  
          * Gets the columns of this tree.
 97  
          *
 98  
          * @return the list of columns in the tree.
 99  
          */
 100  
         public List<String> columns() {
 101  4
                 final int columnCount = columnCount();
 102  4
                 return syncExec(new ListResult<String>() {
 103  
                         public List<String> run() {
 104  4
                                 String columns[] = new String[columnCount];
 105  20
                                 for (int i = 0; i < columnCount; i++)
 106  16
                                         columns[i] = widget.getColumn(i).getText();
 107  4
                                 return new ArrayList<String>(Arrays.asList(columns));
 108  
                         }
 109  
                 });
 110  
         }
 111  
 
 112  
         /**
 113  
          * Gets the cell data for the given row/column index.
 114  
          *
 115  
          * @param row the row index.
 116  
          * @param column the column index.
 117  
          * @return the cell at the location specified by the row and column
 118  
          */
 119  
         public String cell(final int row, final int column) {
 120  6
                 int rowCount = rowCount();
 121  6
                 int columnCount = columnCount();
 122  
 
 123  6
                 Assert.isLegal(row < rowCount, "The row number (" + row + ") is more than the number of rows(" + rowCount + ") in the tree."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 124  12
                 Assert.isLegal(column < columnCount, "The column number (" + column + ") is more than the number of column(" + columnCount //$NON-NLS-1$ //$NON-NLS-2$
 125  6
                                 + ") in the tree."); //$NON-NLS-1$
 126  
 
 127  6
                 return syncExec(new StringResult() {
 128  
                         public String run() {
 129  6
                                 TreeItem item = widget.getItem(row);
 130  6
                                 return item.getText(column);
 131  
                         }
 132  
                 });
 133  
         }
 134  
 
 135  
         /**
 136  
          * Gets the cell data for the given row/column information.
 137  
          *
 138  
          * @param row the row index.
 139  
          * @param columnName the column name.
 140  
          * @return the cell in the tree at the specified row and column header.
 141  
          */
 142  
         public String cell(int row, String columnName) {
 143  3
                 List<String> columns = columns();
 144  3
                 Assert.isLegal(columns.contains(columnName), "The column `" + columnName + "' is not found."); //$NON-NLS-1$ //$NON-NLS-2$
 145  3
                 int columnIndex = columns.indexOf(columnName);
 146  3
                 if (columnIndex == -1)
 147  0
                         return ""; //$NON-NLS-1$
 148  3
                 return cell(row, columnIndex);
 149  
         }
 150  
 
 151  
         /**
 152  
          * Gets the current selection count.
 153  
          *
 154  
          * @return the number of selected items.
 155  
          */
 156  
         public int selectionCount() {
 157  4
                 return syncExec(new IntResult() {
 158  
                         public Integer run() {
 159  4
                                 return widget.getSelectionCount();
 160  
                         }
 161  
                 });
 162  
         }
 163  
 
 164  
         /**
 165  
          * Gets the table collection representing the selection.
 166  
          *
 167  
          * @return the selection in the tree
 168  
          */
 169  
         public TableCollection selection() {
 170  5
                 final int columnCount = columnCount();
 171  
 
 172  5
                 return syncExec(new Result<TableCollection>() {
 173  
                         public TableCollection run() {
 174  5
                                 final TableCollection selection = new TableCollection();
 175  5
                                 TreeItem[] items = widget.getSelection();
 176  10
                                 for (TreeItem item : items) {
 177  5
                                         TableRow tableRow = new TableRow();
 178  5
                                         if (columnCount == 0)
 179  2
                                                 tableRow.add(item.getText());
 180  
                                         else
 181  15
                                                 for (int j = 0; j < columnCount; j++)
 182  12
                                                         tableRow.add(item.getText(j));
 183  5
                                         selection.add(tableRow);
 184  
                                 }
 185  5
                                 return selection;
 186  
                         }
 187  
                 });
 188  
         }
 189  
 
 190  
         /**
 191  
          * Selects the items matching the array list.
 192  
          *
 193  
          * @param items the items to select.
 194  
          * @return this same instance.
 195  
          */
 196  
         public SWTBotTree select(final String... items) {
 197  1
                 waitForEnabled();
 198  1
                 setFocus();
 199  1
                 asyncExec(new VoidResult() {
 200  
                         public void run() {
 201  1
                                 List<TreeItem> selection = new ArrayList<TreeItem>();
 202  3
                                 for (String item : items) {
 203  2
                                         SWTBotTreeItem si = getTreeItem(item);
 204  2
                                         selection.add(si.widget);
 205  
                                 }
 206  1
                                 if (!hasStyle(widget, SWT.MULTI) && items.length > 1)
 207  0
                                         log.warn("Tree does not support SWT.MULTI, cannot make multiple selections"); //$NON-NLS-1$
 208  1
                                 widget.setSelection(selection.toArray(new TreeItem[] {}));
 209  1
                         }
 210  
                 });
 211  1
                 notifySelect();
 212  1
                 return this;
 213  
         }
 214  
         
 215  
         /**
 216  
          * Selects the items in the array. Useful for cases where you're selecting items whose names are not unique, or
 217  
          * items you've exposed one at a time while traversing the tree.
 218  
          * 
 219  
          * @param items the items to select.
 220  
          * @return this same instance.
 221  
          */
 222  
         public SWTBotTree select(final SWTBotTreeItem... items) {
 223  0
                 assertEnabled();
 224  0
                 setFocus();
 225  0
                 asyncExec(new VoidResult() {
 226  
                         public void run() {
 227  0
                                 List<TreeItem> selection = new ArrayList<TreeItem>();
 228  0
                                 for (SWTBotTreeItem treeItem : items) {
 229  0
                                         selection.add(treeItem.widget);
 230  
                                 }
 231  0
                                 if (!hasStyle(widget, SWT.MULTI) && items.length > 1)
 232  0
                                         log.warn("Tree does not support SWT.MULTI, cannot make multiple selections"); //$NON-NLS-1$
 233  0
                                 widget.setSelection(selection.toArray(new TreeItem[] {}));
 234  0
                         }
 235  
                 });
 236  0
                 notifySelect();
 237  0
                 return this;
 238  
         }
 239  
 
 240  
         /**
 241  
          * Unselects the selection in the tree.
 242  
          *
 243  
          * @return this same instance.
 244  
          */
 245  
         public SWTBotTree unselect() {
 246  1
                 waitForEnabled();
 247  1
                 asyncExec(new VoidResult() {
 248  
                         public void run() {
 249  1
                                 log.debug(MessageFormat.format("Unselecting all in {0}", widget)); //$NON-NLS-1$
 250  1
                                 widget.deselectAll();
 251  1
                         }
 252  
                 });
 253  1
                 notifySelect();
 254  1
                 return this;
 255  
         }
 256  
 
 257  
         /**
 258  
          * Select the indexes provided.
 259  
          *
 260  
          * @param indices the indices to select.
 261  
          * @return this same instance.
 262  
          */
 263  
         public SWTBotTree select(final int... indices) {
 264  3
                 waitForEnabled();
 265  3
                 setFocus();
 266  3
                 asyncExec(new VoidResult() {
 267  
                         public void run() {
 268  3
                                 log.debug(MessageFormat.format("Selecting rows [{0}] in tree{1}", StringUtils.join(indices, ", "), this)); //$NON-NLS-1$ //$NON-NLS-2$
 269  3
                                 if (!hasStyle(widget, SWT.MULTI) && indices.length > 1)
 270  0
                                         log.warn("Tree does not support SWT.MULTI, cannot make multiple selections"); //$NON-NLS-1$
 271  3
                                 TreeItem items[] = new TreeItem[indices.length];
 272  7
                                 for (int i = 0; i < indices.length; i++)
 273  4
                                         items[i] = widget.getItem(indices[i]);
 274  3
                                 widget.setSelection(items);
 275  3
                         }
 276  
                 });
 277  3
                 notifySelect();
 278  3
                 return this;
 279  
         }
 280  
 
 281  
         /**
 282  
          * Notifies the tree widget about selection changes
 283  
          */
 284  
         protected void notifySelect() {
 285  5
                 notify(SWT.MouseEnter);
 286  5
                 notify(SWT.MouseMove);
 287  5
                 notify(SWT.Activate);
 288  5
                 notify(SWT.FocusIn);
 289  5
                 notify(SWT.MouseDown);
 290  5
                 notify(SWT.Selection);
 291  5
                 notify(SWT.MouseUp);
 292  5
                 notify(SWT.MouseHover);
 293  5
                 notify(SWT.MouseMove);
 294  5
                 notify(SWT.MouseExit);
 295  5
                 notify(SWT.Deactivate);
 296  5
                 notify(SWT.FocusOut);
 297  5
         }
 298  
 
 299  
         /**
 300  
          * Attempts to expand all nodes along the path specified by the node array parameter.
 301  
          * 
 302  
          * @param nodes node path to expand
 303  
          * @return the last Tree item that was expanded.
 304  
          * @throws WidgetNotFoundException if any of the nodes on the path do not exist
 305  
          */
 306  
         public SWTBotTreeItem expandNode(String... nodes) throws WidgetNotFoundException {
 307  9
                 Assert.isNotEmpty((Object[])nodes);
 308  
 
 309  8
                 log.debug(MessageFormat.format("Expanding nodes {0} in tree {1}", StringUtils.join(nodes, ">"), this));
 310  
 
 311  8
                 waitForEnabled();
 312  8
                 SWTBotTreeItem item = getTreeItem(nodes[0]).expand();
 313  
                 
 314  8
                 List<String> asList = new ArrayList<String>(Arrays.asList(nodes));
 315  8
                 asList.remove(0);
 316  8
                 if (!asList.isEmpty())
 317  1
                         item = item.expandNode(asList.toArray(new String[0]));
 318  
 
 319  8
                 return item;
 320  
         }
 321  
 
 322  
         /**
 323  
          * Collapses the node matching the node information.
 324  
          *
 325  
          * @param nodeText the text on the node.
 326  
          * @return the Tree item that was expanded.
 327  
          * @throws WidgetNotFoundException if the node is not found.
 328  
          */
 329  
         public SWTBotTreeItem collapseNode(final String nodeText) throws WidgetNotFoundException {
 330  0
                 waitForEnabled();
 331  0
                 return getTreeItem(nodeText).collapse();
 332  
         }
 333  
 
 334  
         /**
 335  
          * Gets the visible row count.
 336  
          *
 337  
          * @return the number of visible rows
 338  
          */
 339  
         public int visibleRowCount() {
 340  4
                 return syncExec(new IntResult() {
 341  
                         public Integer run() {
 342  4
                                 TreeItem[] items = widget.getItems();
 343  4
                                 return getVisibleChildrenCount(items);
 344  
                         }
 345  
 
 346  
                         private int getVisibleChildrenCount(TreeItem item) {
 347  27
                                 if (item.getExpanded())
 348  7
                                         return getVisibleChildrenCount(item.getItems());
 349  20
                                 return 0;
 350  
                         }
 351  
 
 352  
                         private int getVisibleChildrenCount(TreeItem[] items) {
 353  11
                                 int count = 0;
 354  38
                                 for (TreeItem item : items) {
 355  27
                                         int j = getVisibleChildrenCount(item) + 1;
 356  27
                                         count += j;
 357  
                                 }
 358  11
                                 return count;
 359  
                         }
 360  
                 });
 361  
 
 362  
         }
 363  
 
 364  
         /**
 365  
          * Expands the nodes as if the plus sign was clicked.
 366  
          *
 367  
          * @param nodeText the node to be expanded.
 368  
          * @param recursive if the expansion should be recursive.
 369  
          * @return the tree item that was expanded.
 370  
          * @throws WidgetNotFoundException if the node is not found.
 371  
          */
 372  
         public SWTBotTreeItem expandNode(final String nodeText, final boolean recursive) throws WidgetNotFoundException {
 373  2
                 waitForEnabled();
 374  2
                 return syncExec(new Result<SWTBotTreeItem>() {
 375  
                         public SWTBotTreeItem run() {
 376  
                                 SWTBotTreeItem item;
 377  
                                 try {
 378  2
                                         item = getTreeItem(nodeText);
 379  2
                                         expandNode(item);
 380  0
                                 } catch (WidgetNotFoundException e) {
 381  0
                                         throw new RuntimeException(e);
 382  
                                 }
 383  2
                                 return item;
 384  
                         }
 385  
 
 386  
                         private void expandNode(SWTBotTreeItem item) throws WidgetNotFoundException {
 387  8
                                 item.expand();
 388  8
                                 if (recursive)
 389  8
                                         expandTreeItem(item.widget);
 390  8
                         }
 391  
 
 392  
                         private void expandTreeItem(TreeItem node) throws WidgetNotFoundException {
 393  8
                                 TreeItem[] items = node.getItems();
 394  14
                                 for (TreeItem item : items) {
 395  6
                                         expandNode(new SWTBotTreeItem(item));
 396  
                                 }
 397  8
                         }
 398  
                 });
 399  
         }
 400  
 
 401  
         /**
 402  
          * Gets the tree item matching the given name.
 403  
          *
 404  
          * @param nodeText the text on the node.
 405  
          * @return the tree item with the specified text.
 406  
          * @throws WidgetNotFoundException if the node was not found.
 407  
          */
 408  
         public SWTBotTreeItem getTreeItem(final String nodeText) throws WidgetNotFoundException {
 409  
                 try {
 410  30
                         new SWTBot().waitUntil(new DefaultCondition() {
 411  
                                 public String getFailureMessage() {
 412  0
                                         return "Could not find node with text " + nodeText; //$NON-NLS-1$
 413  
                                 }
 414  
 
 415  
                                 public boolean test() throws Exception {
 416  30
                                         return getItem(nodeText) != null;
 417  
                                 }
 418  
                         });
 419  0
                 } catch (TimeoutException e) {
 420  0
                         throw new WidgetNotFoundException("Timed out waiting for tree item " + nodeText, e); //$NON-NLS-1$
 421  
                 }
 422  30
                 return new SWTBotTreeItem(getItem(nodeText));
 423  
         }
 424  
 
 425  
         /**
 426  
          * Gets the item matching the given name.
 427  
          *
 428  
          * @param nodeText the text on the node.
 429  
          * @return the tree item with the specified text.
 430  
          */
 431  30
         private TreeItem getItem(final String nodeText) {
 432  60
                 return syncExec(new WidgetResult<TreeItem>() {
 433  
                         public TreeItem run() {
 434  60
                                 TreeItem[] items = widget.getItems();
 435  130
                                 for (TreeItem item : items) {
 436  130
                                         if (item.getText().equals(nodeText))
 437  60
                                                 return item;
 438  
                                 }
 439  0
                                 return null;
 440  
                         }
 441  
                 });
 442  
         }
 443  
 
 444  
         /**
 445  
          * Gets all the items in the tree.
 446  
          *
 447  
          * @return the list of all tree items in the tree, or an empty list if there are none.
 448  
          * @since 1.0
 449  
          */
 450  
         public SWTBotTreeItem[] getAllItems() {
 451  1
                 return syncExec(new ArrayResult<SWTBotTreeItem>() {
 452  
                         public SWTBotTreeItem[] run() {
 453  1
                                 TreeItem[] items = widget.getItems();
 454  1
                                 SWTBotTreeItem[] result = new SWTBotTreeItem[items.length];
 455  
 
 456  5
                                 for (int i = 0; i < items.length; i++)
 457  
                                         try {
 458  4
                                                 result[i] = new SWTBotTreeItem(items[i]);
 459  0
                                         } catch (WidgetNotFoundException e) {
 460  0
                                                 return new SWTBotTreeItem[0];
 461  
                                         }
 462  1
                                 return result;
 463  
                         }
 464  
                 });
 465  
         }
 466  
 
 467  
         /**
 468  
          * Gets if this tree has items within it.
 469  
          *
 470  
          * @return <code>true</code> if the tree has any items, <code>false</code> otherwise.
 471  
          * @since 1.0
 472  
          */
 473  
         public boolean hasItems() {
 474  2
                 return syncExec(new BoolResult() {
 475  
                         public Boolean run() {
 476  2
                                 return widget.getItemCount() > 0;
 477  
                         }
 478  
                 });
 479  
         }
 480  
 
 481  
 }