/*
* OneCMDB, an open source configuration management project.
* Copyright 2007, Lokomo Systems AB, and individual contributors
* as indicated by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.onecmdb.ui.gwt.toolkit.client.view.tree;
import org.onecmdb.ui.gwt.toolkit.client.control.tree.ITreeControl;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.TreeListener;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
public class CITreeWidget extends Composite implements TreeListener {
protected ITreeControl control;
protected Tree tree;
private TreeItem currentItem;
private QueryCriteriaWidget search;
public CITreeWidget(final ITreeControl control) {
this.control = control;
tree = new Tree();
tree.addTreeListener(this);
TreeItem item = new TreeItem("Populating....");
//tree.addItem(item);
control.getRootObject(new AsyncCallback() {
public void onFailure(Throwable caught) {
tree.addItem(new TreeItem(new Label("ERROR: " + caught.getMessage())));
}
public void onSuccess(Object result) {
tree.clear();
if (control.isHideRoot()) {
if (result instanceof Object[]) {
Object objects[] = (Object[])result;
for (int i = 0; i < objects.length; i++) {
control.getChildren(objects[i], null, new AsyncCallback() {
public void onFailure(Throwable caught) {
tree.addItem(new TreeItem(new Label("ERROR: " + caught.getMessage())));
}
public void onSuccess(Object result) {
addRootObject(result);
}
});
}
} else {
control.getChildren(result, null, new AsyncCallback() {
public void onFailure(Throwable caught) {
tree.addItem(new TreeItem(new Label("ERROR: " + caught.getMessage())));
}
public void onSuccess(Object result) {
addRootObject(result);
}
});
}
} else {
addRootObject(result);
}
}
});
VerticalPanel vPanel = new VerticalPanel();
vPanel.setVerticalAlignment(vPanel.ALIGN_TOP);
search = new QueryCriteriaWidget(this);
vPanel.add(search);
vPanel.setCellWidth(search, "100%");
if (!control.showSearch()) {
search.setVisible(false);
}
vPanel.add(tree);
vPanel.setCellWidth(tree, "100%");
vPanel.setCellHeight(tree, "100%");
vPanel.setCellVerticalAlignment(tree, VerticalPanel.ALIGN_TOP);
initWidget(vPanel);
}
protected void addRootObject(Object result) {
if (result instanceof Object[]) {
Object objects[] = (Object[])result;
for (int i = 0; i < objects.length; i++) {
TreeItem item = newTreeItem(objects[i], true);
//tree.addItem(item);
}
} else {
TreeItem item = newTreeItem(result, true);
//tree.addItem(item);
}
}
protected CITreeWidget() {
}
public ITreeControl getTreeControl() {
return(this.control);
}
public void reload() {
if (currentItem == null) {
currentItem = tree.getItem(0);
}
// Reload root.
currentItem.setState(false, true);
currentItem.setState(true, true);
}
protected TreeItem newTreeItem(Object data, final boolean root) {
Widget w = this.control.getWidget(data);
final TreeItem item = new TreeItem();
item.setUserObject(data);
item.setWidget(w);
// Need to this here since we call the auto open and that
// need to have the tree callback setup.
if (root) {
tree.addItem(item);
}
this.control.getChildCount(data, new AsyncCallback() {
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
public void onSuccess(Object result) {
if (result instanceof Integer) {
int value = ((Integer)result).intValue();
if (value > 0) {
TreeItem countItem = new TreeItem("Populating....");
countItem.setUserObject(result);
item.addItem(countItem);
// Always open root item.
if (root && control.isRootState()) {
System.out.println("Default open root Tree Item! '" + item.getUserObject() +"'");
item.setState(true, true);
}
}
}
}
});
return(item);
}
public void onTreeItemSelected(TreeItem item) {
if (CITreeWidget.this.control.getTreeListener() != null) {
CITreeWidget.this.control.getTreeListener().onTreeItemSelected(item);
}
}
public void onTreeItemStateChanged(final TreeItem item) {
final long start = System.currentTimeMillis();
if (item.getState()) {
if (item.getUserObject() instanceof GroupData) {
GroupData gData = (GroupData)item.getUserObject();
updateChildren(item, gData.getUserData(), gData.getFirstItem());
return;
}
currentItem = item;
// Open start populate with entries.
this.control.getChildCount(item.getUserObject(), new AsyncCallback() {
public void onFailure(Throwable caught) {
item.removeItems();
item.addItem(new TreeItem(new Label("ERROR: " + caught.getMessage())));
}
public void onSuccess(Object result) {
if (result instanceof Integer) {
Integer totalCount = (Integer)result;
Integer maxResult = CITreeWidget.this.control.getMaxResult();
if (maxResult != null && (totalCount.intValue() > maxResult.intValue())) {
// Start adding groups...
int groups = totalCount.intValue() / maxResult.intValue();
int rest = totalCount.intValue() % maxResult.intValue();
if (rest > 0) {
groups++;
}
item.removeItems();
for (int i = 0; i < groups; i++) {
TreeItem groupItem = new TreeItem();
int start = 1;
int stop = maxResult.intValue();
if (i > 0) {
start = (i*maxResult.intValue()) + 1;
stop = ((i+1)*maxResult.intValue());
if (stop > totalCount.intValue()) {
stop = totalCount.intValue();
}
}
groupItem.setText("[" + start + ".." + stop +"]");
groupItem.setUserObject(new GroupData(item.getUserObject(), new Integer(start-1)));
groupItem.addItem(new TreeItem("Loading..."));
item.addItem(groupItem);
}
} else {
updateChildren(item, item.getUserObject(), null);
}
}
}
});
} else {
//item.removeItems();
//updateCountItem(item);
}
if (CITreeWidget.this.control.getTreeListener() != null) {
CITreeWidget.this.control.getTreeListener().onTreeItemStateChanged(item);
}
}
protected void updateChildren(final TreeItem item, Object data, final Integer firstItem) {
CITreeWidget.this.control.getChildren(data, firstItem, new AsyncCallback() {
public void onFailure(Throwable caught) {
item.removeItems();
item.addItem(new TreeItem(new Label("ERROR: " + caught.getMessage())));
}
public void onSuccess(Object result) {
long stopCall = System.currentTimeMillis();
if (result instanceof Object[]) {
/*
boolean useSearch = false;
Integer totalCount = new Integer(0);
if (count instanceof Integer) {
totalCount = (Integer)count;
}
if (totalCount.intValue() > control.getMaxResult().intValue()) {
showSearch(true);
useSearch = true;
}
*/
item.removeItems();
/*
if (useSearch) {
TreeItem searchItem = new TreeItem();
searchItem.setHTML("<font size=\"xx-small\"><b>NOTE: Showing " + control.getMaxResult() + " of " + totalCount +", use search!</b></font>");
searchItem.setUserObject(totalCount);
item.addItem(searchItem);
}
*/
int resultSize = 0;
Object children[] = (Object[])result;
resultSize = children.length;
for (int i = 0; i < resultSize; i++) {
item.addItem(newTreeItem(children[i], false));
}
long stopUI = System.currentTimeMillis();
//OneCMDBSession.addCallStat("Tree.getChildren()", resultSize, start, stopCall, stopUI);
}
}
});
}
protected void updateCountItem(final TreeItem parent) {
this.control.getChildCount(parent.getUserObject(), new AsyncCallback() {
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
public void onSuccess(Object result) {
if (result instanceof Integer) {
int value = ((Integer)result).intValue();
if (value > 0) {
TreeItem countItem = new TreeItem("Populating....");
countItem.setUserObject(result);
parent.addItem(countItem);
}
}
}
});
}
protected void showSearch(boolean b) {
search.setVisible(true);
}
class GroupData {
private Object data;
private Integer firstResult;
public GroupData(Object data, Integer firstResult) {
this.data = data;
this.firstResult = firstResult;
}
public Object getUserData() {
return(this.data);
}
public Integer getFirstItem() {
return(this.firstResult);
}
}
}