1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems, Inc. and others.
* 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.viewsupport;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
/**
* Utility to perform next/previous navigation on a tree.
* @author markus.schorn@windriver.com
*/
public class TreeNavigator {
private Tree fTree;
private Class<?> fDataClass;
/**
* Creates a tree navigator for the given tree. It allows for finding tree items.
* In case you supply a dataClass only nodes with data of this class are considered.
* @param tree the tree to operate on
* @param dataClass the required class for the data of the tree nodes, or <code>null</code>.
*/
public TreeNavigator(Tree tree, Class<?> dataClass) {
fTree= tree;
fDataClass= dataClass;
}
/**
* Find the first valid item of the selection.
* @return the first valid item in the selection or <code>null</code>
*/
public TreeItem getSelectedItem() {
return getItemOfClass(fTree.getSelection(), true);
}
private TreeItem getItemOfClass(TreeItem[] items, boolean fwd) {
for (int i = 0; i < items.length; i++) {
TreeItem item = items[fwd ? i : items.length-1-i];
if (fDataClass==null || fDataClass.isInstance(item.getData())) {
return item;
}
}
return null;
}
/**
* Find the first valid item on the given level. All parents have to be valid also.
* @param level the level to search, use <code>0</code> for the root nodes of the tree.
* @param fwd if set to false the tree is searched reverse from the buttom.
* @return the first item on the given level, or <code>null</code>
*/
public TreeItem getFirstItemOnLevel(int level, boolean fwd) {
return getFirstOnLevel(fTree.getItems(), level, fwd);
}
private TreeItem getFirstOnLevel(TreeItem[] items, int level, boolean fwd) {
TreeItem item= getItemOfClass(items, fwd);
if (level <= 0 || item == null) {
return item;
}
return getFirstOnLevel(item.getItems(), level-1, fwd);
}
/**
* Combines the methods {@link TreeNavigator#getSelectedItem()} and
* {@link TreeNavigator#getFirstItemOnLevel(int, boolean)}.
* @param level the level to search, use <code>0</code> for the root nodes of the tree.
* @param fwd if set to false the tree is searched reverse from the buttom.
* @return the first valid item of the selection or the first item on the given level, or <code>null</code>
*/
public TreeItem getSelectedItemOrFirstOnLevel(int level, boolean fwd) {
TreeItem result= getSelectedItem();
if (result == null) {
result= getFirstItemOnLevel(level, fwd);
}
return result;
}
/**
* Searches for the next valid sibbling of the given item.
* @param current a tree item to start the search
* @param forward if false the previous sibbling is returned
* @return the next sibbling after the given one, or <code>null</code>
*/
public TreeItem getNextSibbling(TreeItem current, boolean forward) {
TreeItem parentItem= current.getParentItem();
if (parentItem == null) {
Tree tree= current.getParent();
int itemCount = tree.getItemCount();
if (itemCount > 0) {
int index= tree.indexOf(current);
index = (index + (forward ? 1 : itemCount-1)) % itemCount;
return tree.getItem(index);
}
}
else {
int itemCount = parentItem.getItemCount();
if (itemCount > 0) {
int index= parentItem.indexOf(current);
index = (index + (forward ? 1 : itemCount-1)) % itemCount;
return parentItem.getItem(index);
}
}
return null;
}
}
|