/******************************************************************************
* Product: Posterita Ajax UI *
* Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program 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 General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
* For the text or an alternative of this public license, you may reach us *
* Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
* or via info@posterita.org or http://www.posterita.org/ *
*****************************************************************************/
package org.adempiere.webui.panel;
import java.util.TreeMap;
import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.component.AutoComplete;
import org.adempiere.webui.component.Label;
import org.adempiere.webui.component.Panel;
import org.adempiere.webui.util.DocumentSearch;
import org.adempiere.webui.util.TreeItemAction;
import org.adempiere.webui.util.TreeNodeAction;
import org.adempiere.webui.util.TreeUtils;
import org.compiere.model.MTreeNode;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Div;
import org.zkoss.zul.SimpleTreeNode;
import org.zkoss.zul.Tree;
import org.zkoss.zul.Treeitem;
import org.zkoss.zul.event.TreeDataEvent;
import org.zkoss.zul.event.TreeDataListener;
/**
*
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
* @date Mar 3, 2007
* @version $Revision: 0.10 $
*/
public class TreeSearchPanel extends Panel implements EventListener, TreeDataListener
{
/**
*
*/
private static final long serialVersionUID = -1788127438140771622L;
private TreeMap<String, Object> treeNodeItemMap = new TreeMap<String, Object>();
private String[] treeValues;
private String[] treeDescription;
private Label lblSearch;
private AutoComplete cmbSearch;
private Tree tree;
private String eventToFire;
private static final String PREFIX_DOCUMENT_SEARCH = "/";
/**
* @param tree
*/
public TreeSearchPanel(Tree tree)
{
this(tree, Events.ON_CLICK);
}
/**
* @param tree
* @param event
*/
public TreeSearchPanel(Tree tree, String event)
{
super();
this.tree = tree;
this.eventToFire = event;
init();
}
private void init()
{
Div div = new Div();
lblSearch = new Label();
lblSearch.setValue(Msg.getMsg(Env.getCtx(),"TreeSearch").replaceAll("&", "") + ":");
lblSearch.setTooltiptext(Msg.getMsg(Env.getCtx(),"TreeSearchText"));
div.appendChild(lblSearch);
String divStyle = "height: 20px; vertical-align: middle;";
if (!AEnv.isInternetExplorer())
{
divStyle += "margin-bottom: 10px; display: inline-block;";
}
div.setStyle(divStyle);
cmbSearch = new AutoComplete();
cmbSearch.setAutodrop(true);
cmbSearch.addEventListener(Events.ON_CHANGE, this);
if (AEnv.isInternetExplorer())
{
cmbSearch.setWidth("200px");
}
this.appendChild(div);
this.appendChild(cmbSearch);
if (!AEnv.isInternetExplorer())
{
this.setStyle("height: 20px;");
}
}
private void addTreeItem(Treeitem treeItem)
{
String key = treeItem.getLabel();
treeNodeItemMap.put(key, treeItem);
}
private void addTreeItem(SimpleTreeNode node) {
Object data = node.getData();
if (data instanceof MTreeNode) {
MTreeNode mNode = (MTreeNode) data;
treeNodeItemMap.put(mNode.getName(), node);
}
}
/**
* populate the searchable list
*/
public void initialise()
{
refreshSearchList();
if (tree.getModel() != null)
{
tree.getModel().addTreeDataListener(this);
}
}
private void refreshSearchList() {
treeNodeItemMap.clear();
if (tree.getModel() == null) {
TreeUtils.traverse(tree, new TreeItemAction() {
public void run(Treeitem treeItem) {
addTreeItem(treeItem);
}
});
} else {
TreeUtils.traverse(tree.getModel(), new TreeNodeAction() {
public void run(SimpleTreeNode treeNode) {
addTreeItem(treeNode);
}
});
}
treeValues = new String[treeNodeItemMap.size()];
treeDescription = new String[treeNodeItemMap.size()];
int i = -1;
for (Object value : treeNodeItemMap.values())
{
i++;
if (value instanceof Treeitem)
{
Treeitem treeItem = (Treeitem) value;
treeValues[i] = treeItem.getLabel();
treeDescription[i] = treeItem.getTooltiptext();
}
else if (value instanceof SimpleTreeNode)
{
SimpleTreeNode sNode = (SimpleTreeNode) value;
MTreeNode mNode = (MTreeNode) sNode.getData();
treeValues[i] = mNode.getName();
treeDescription[i] = mNode.getDescription();
}
}
cmbSearch.setDescription(treeDescription);
cmbSearch.setDict(treeValues);
}
/**
* @param event
* @see EventListener#onEvent(Event)
*/
public void onEvent(Event event)
{
if (cmbSearch.equals(event.getTarget()) && (event.getName().equals(Events.ON_CHANGE)))
{
String value = cmbSearch.getValue();
if (value != null && value.trim().length() > 0
&& value.substring(0, 1).equals(PREFIX_DOCUMENT_SEARCH))
{
DocumentSearch search = new DocumentSearch();
if (search.openDocumentsByDocumentNo(value.substring(1)))
cmbSearch.setText(null);
return;
}
Object node = treeNodeItemMap.get(value);
Treeitem treeItem = null;
if (node == null) {
return;
} else if (node instanceof Treeitem) {
treeItem = (Treeitem) node;
} else {
SimpleTreeNode sNode = (SimpleTreeNode) node;
int[] path = tree.getModel().getPath(tree.getModel().getRoot(), sNode);
treeItem = tree.renderItemByPath(path);
tree.setSelectedItem(treeItem);
}
if (treeItem != null)
{
select(treeItem);
Clients.showBusy(Msg.getMsg(Env.getCtx(), "Loading"), true);
Events.echoEvent("onPostSelect", this, null);
}
}
}
/**
* don't call this directly, use internally for post selection event
*/
public void onPostSelect() {
Clients.showBusy(null, false);
Event event = null;
if (eventToFire.equals(Events.ON_CLICK))
event = new Event(Events.ON_CLICK, tree.getSelectedItem().getTreerow());
else
event = new Event(eventToFire, tree);
Events.postEvent(event);
}
private void select(Treeitem selectedItem) {
Treeitem parent = selectedItem.getParentItem();
while (parent != null) {
if (!parent.isOpen())
parent.setOpen(true);
parent = parent.getParentItem();
}
selectedItem.getTree().setSelectedItem(selectedItem);
}
/**
* @param event
* @see TreeDataListener#onChange(TreeDataEvent)
*/
public void onChange(TreeDataEvent event) {
refreshSearchList();
}
}