package com.xxx.pkgtool.view;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import com.hundsun.pkgtool.cache.PropFileCache;
import com.hundsun.pkgtool.provider.FileTreeContentProvider;
/**
* CheckboxTreeViewer with special behaviour of the checked / gray state on
* container (non-leaf) nodes:
* The grayed state is used to visualize the checked state of its children.
* Containers are checked and non-gary if all contained leafs are checked. The
* container is grayed if some but not all leafs are checked.
*/
public class ContainerCheckedTreeViewer extends CheckboxTreeViewer {
/**
* Constructor for ContainerCheckedTreeViewer.
* @see CheckboxTreeViewer#CheckboxTreeViewer(Composite)
*/
public ContainerCheckedTreeViewer(Composite parent) {
super(parent);
initViewer();
}
/**
* Constructor for ContainerCheckedTreeViewer.
* @see CheckboxTreeViewer#CheckboxTreeViewer(Composite,int)
*/
public ContainerCheckedTreeViewer(Composite parent, int style) {
super(parent, style);
initViewer();
}
/**
* Constructor for ContainerCheckedTreeViewer.
* @see CheckboxTreeViewer#CheckboxTreeViewer(Tree)
*/
public ContainerCheckedTreeViewer(Tree tree) {
super(tree);
initViewer();
}
private void initViewer() {
setUseHashlookup(true);
addCheckStateListener(new ICheckStateListener() {
public void checkStateChanged(CheckStateChangedEvent event) {
doCheckStateChanged(event.getElement());
}
});
addTreeListener(new ITreeViewerListener() {
public void treeCollapsed(TreeExpansionEvent event) {}
public void treeExpanded(TreeExpansionEvent event) {
Widget item = findItem(event.getElement());
if (item instanceof TreeItem) {
initializeItem((TreeItem) item);
}
}
});
}
protected void doCheckStateChanged(Object element) {
Widget item = findItem(element);
if (item instanceof TreeItem) {
TreeItem treeItem = (TreeItem) item;
treeItem.setGrayed(false);
updateChildrenItems(treeItem);
updateParentItems(treeItem.getParentItem());
}
}
/**
* The item has expanded. Updates the checked state of its children.
*/
private void initializeItem(TreeItem item) {
if (item.getChecked() && !item.getGrayed()) {
updateChildrenItems(item);
}
}
/**
* Updates the check state of all created children
*/
private void updateChildrenItems(TreeItem parent) {
Item[] children = getChildren(parent);
boolean state = parent.getChecked();
for (int i = 0; i < children.length; i++) {
TreeItem curr = (TreeItem) children[i];
if (curr.getData() != null && ((curr.getChecked() != state) || curr.getGrayed())) {
curr.setChecked(state);
curr.setGrayed(false);
updateChildrenItems(curr);
}
}
}
/**
* Updates the check / gray state of all parent items
*/
private void updateParentItems(TreeItem item) {
if (item != null) {
Item[] children = getChildren(item);
boolean containsChecked = false;
boolean containsUnchecked = false;
for (int i = 0; i < children.length; i++) {
TreeItem curr = (TreeItem) children[i];
containsChecked |= curr.getChecked();
containsUnchecked |= (!curr.getChecked() || curr.getGrayed());
}
item.setChecked(containsChecked);
item.setGrayed(containsChecked && containsUnchecked);
updateParentItems(item.getParentItem());
}
}
public boolean setChecked(Object element, boolean state) {
if (super.setChecked(element, state)) {
doCheckStateChanged(element);
return true;
}
return false;
}
public void setCheckedElements(Object[] elements) {
super.setCheckedElements(elements);
for (int i = 0; i < elements.length; i++) {
doCheckStateChanged(elements[i]);
}
}
protected void setExpanded(Item item, boolean expand) {
super.setExpanded(item, expand);
if (expand && item instanceof TreeItem) {
initializeItem((TreeItem) item);
}
}
public Object[] getUnCheckedElements(){
ArrayList<Object> result = new ArrayList<Object>();
List<TreeItem> allItems = new ArrayList<TreeItem>();
getAllItems(super.getTree(),allItems);
for(TreeItem element:allItems){
if(!element.getChecked() && !element.getGrayed()){
if(element.getData()!=null && !element.getData().toString().contains(":\\")){
result.add(PropFileCache.propCache.get(FileTreeContentProvider.tempMap.get(element.getData())));
}else{
result.add(element.getData());
}
}
}
return result.toArray();
}
public Object[] getCheckedElements() {
Object[] checked = super.getCheckedElements();
// add all items that are children of a checked node but not created yet
ArrayList<Object> result = new ArrayList<Object>();
for (int i = 0; i < checked.length; i++) {
Object curr = checked[i];
result.add(curr);
Widget item = findItem(curr);
if (item != null) {
Item[] children = getChildren(item);
// check if contains the dummy node
if (children.length == 1 && children[0].getData() == null) {
// not yet created
collectChildren(curr, result);
}
}
}
return result.toArray();
}
private void collectChildren(Object element, ArrayList<Object> result) {
Object[] filteredChildren = getFilteredChildren(element);
for (int i = 0; i < filteredChildren.length; i++) {
Object curr = filteredChildren[i];
result.add(curr);
collectChildren(curr, result);
}
}
private static void getAllItems(Tree tree, List<TreeItem> allItems){
for(TreeItem item : tree.getItems()){
allItems.add(item);
getAllItems(item, allItems);
}
}
private static void getAllItems(TreeItem currentItem, List<TreeItem> allItems){
TreeItem[] children = currentItem.getItems();
for(int i = 0; i < children.length; i++){
allItems.add(children[i]);
getAllItems(children[i], allItems);
}
}
}
09-13
116