/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.ui.common.tree;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
/**
* TreeViewerUtil is a set of static utility methods for operating on TreeViewer.
*
* @since 8.0
*/
abstract public class TreeViewerUtil {
/**
* Returns an ordered list of the descendants of a node in a tree. Assumes that
* the tree has a content provider, returns null otherwise.
*
* @param viewer the TreeViewer for the tree
* @param node Object contained as a node in the tree, the root of this query
* @param includeNode true if node itself is to be included at start of the list
* @return ordered list of descendants of the given node in the tree
*/
public static List getDescendantsOfNode(TreeViewer viewer, Object node,
boolean includeNode) {
List result = null;
ITreeContentProvider provider = (ITreeContentProvider)viewer.getContentProvider();
if (provider != null) {
result = new ArrayList();
if (includeNode) {
result.add(node);
}
Object[] children = provider.getChildren(node);
for (int i = 0; i < children.length; i++) {
result.add(children[i]);
List childsChildren = TreeViewerUtil.getDescendantsOfNode(viewer,
children[i], false);
result.addAll(childsChildren);
}
}
return result;
}
/** Gets a List of all root nodes present in the specified tree.
*
* @param viewer The Tree we are working with.
* @return empty list if the content provider is null,
* the children of viewer.getInput() otherwise.
*/
public static List getRootNodes(TreeViewer viewer) {
List result = Collections.EMPTY_LIST;
ITreeContentProvider provider = (ITreeContentProvider)viewer.getContentProvider();
if (provider != null) {
Object[] children = provider.getChildren(viewer.getInput());
result = Arrays.asList(children);
}
return result;
}
/** Set the checked status of an entire tree. This method uses
* viewer.setChecked(), which has some performance issues in large trees.
*
* @param viewer The viewer we are using.
* @param checkedState The new checked state of each node.
*/
public static void setAllChecked(CheckboxTreeViewer viewer, boolean checkedState) {
setSubtreeChecked(viewer, viewer.getInput(), checkedState);
}
/** Set the checked status of all children of the specified node. This method uses
* viewer.setChecked(), which has some performance issues in large trees.
*
* @param viewer The viewer we are using.
* @param node The node whose subtree to check.
* @param checkedState The new checked state of each node.
*/
public static void setSubtreeChecked(CheckboxTreeViewer viewer, Object node, boolean checkedState) {
// get children:
ITreeContentProvider provider = (ITreeContentProvider)viewer.getContentProvider();
if (provider == null) {
// no provider; can't proceed.
return;
} // endif
Object[] children = provider.getChildren(node);
// set checked on each child:
for (int i = 0; i < children.length; i++) {
Object child = children[i];
viewer.setChecked(child, checkedState);
viewer.setSubtreeChecked(node, checkedState);
} // endfor
}
/** Scans the tree, starting at the specified node, to see if all children of that
* node have a checked status of checkedState. There are performance implications to
* this method. Specifically, it uses the content provider to obtain children, and
* then the viewer to get the checked state. This method will get the most accurate
* results, at a cost of speed. Using TreeItems directly would work to a point, but
* would only work if the entire tree had been expanded.
*
* @param viewer The tree we are looking at.
* @param node The starting node.
* @param checkedState the state to compare to.
* @return true if all descendants of node are checked.
*/
public static boolean allDescendantsHaveState(CheckboxTreeViewer viewer, Object node, boolean checkedState) {
ITreeContentProvider contentProvider = (ITreeContentProvider)viewer.getContentProvider();
boolean mismatchFound = false;
Object[] children = contentProvider.getChildren(node);
int i = 0;
while ((i < children.length) && (!mismatchFound)) {
if (viewer.getChecked(children[i]) != checkedState) {
mismatchFound = true;
} else {
if (!allDescendantsHaveState(viewer, children[i], checkedState)) {
mismatchFound = true;
} else {
i++;
}
}
}
return (!mismatchFound);
}
/** Scans the tree, starting at the specified node, to see if all children of that
* node are checked. There are performance implications to this method; see
* allDescendantsHaveState for more information.
*
* @param viewer The tree we are looking at.
* @param node The starting node.
* @see #allDescendantsHaveState(CheckboxTreeViewer, Object, boolean)
* @return true if all descendants of node are checked.
*/
public static boolean allDescendantsChecked(CheckboxTreeViewer viewer, Object node) {
boolean allChecked = allDescendantsHaveState(viewer, node, true);
return allChecked;
}
/** Scans the tree, starting at the specified node, to see if any children of that
* node are checked. There are performance implications to this method; see
* allDescendantsHaveState for more information.
*
* @param viewer The tree we are looking at.
* @param node The starting node.
* @see #allDescendantsHaveState(CheckboxTreeViewer, Object, boolean)
* @return true if any descendants of node are checked.
*/
public static boolean anyDescendantChecked(CheckboxTreeViewer viewer, Object node) {
boolean anyChecked = (!allDescendantsHaveState(viewer, node, false));
return anyChecked;
}
}