Mercurial > dive4elements > river
view flys-client/src/main/java/de/intevation/flys/client/client/ui/DatacageWidget.java @ 4269:0c766c475805
Add Panel and Tree UI classes for dispayling the measurement station info
The new ui classes are using the new extracted base class InfoPanel and InfoTree
which are in common with the gauge info.
author | Björn Ricks <bjoern.ricks@intevation.de> |
---|---|
date | Fri, 26 Oct 2012 12:22:06 +0200 |
parents | 360e22afb98b |
children | 7558a18ceb23 |
line wrap: on
line source
package de.intevation.flys.client.client.ui; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.rpc.AsyncCallback; import com.smartgwt.client.types.SelectionStyle; import com.smartgwt.client.types.TreeModelType; import com.smartgwt.client.util.SC; import com.smartgwt.client.widgets.Button; import com.smartgwt.client.widgets.events.ClickEvent; import com.smartgwt.client.widgets.events.ClickHandler; import com.smartgwt.client.widgets.grid.HoverCustomizer; import com.smartgwt.client.widgets.grid.ListGridRecord; import com.smartgwt.client.widgets.grid.events.RecordDoubleClickEvent; import com.smartgwt.client.widgets.grid.events.RecordDoubleClickHandler; import com.smartgwt.client.widgets.layout.VLayout; import com.smartgwt.client.widgets.tree.Tree; import com.smartgwt.client.widgets.tree.TreeGrid; import com.smartgwt.client.widgets.tree.TreeNode; import de.intevation.flys.client.client.Config; import de.intevation.flys.client.client.FLYSConstants; import de.intevation.flys.client.client.event.DatacageDoubleClickHandler; import de.intevation.flys.client.client.event.DatacageHandler; import de.intevation.flys.client.client.services.MetaDataService; import de.intevation.flys.client.client.services.MetaDataServiceAsync; import de.intevation.flys.client.shared.model.Artifact; import de.intevation.flys.client.shared.model.AttrList; import de.intevation.flys.client.shared.model.DataCageNode; import de.intevation.flys.client.shared.model.DataCageTree; import de.intevation.flys.client.shared.model.ToLoad; import de.intevation.flys.client.shared.model.User; import java.util.ArrayList; import java.util.List; import java.util.MissingResourceException; import java.util.Stack; // TODO: refactor, extract ~DataCageGrid /** * Display tree of, for example, previous calculations and allows * selection in order to access/clone these. */ public class DatacageWidget extends VLayout { public static final int MAX_OPEN = 30; protected MetaDataServiceAsync metaDataService = GWT.create(MetaDataService.class); protected FLYSConstants messages = GWT.create(FLYSConstants.class); protected Artifact artifact; protected User user; protected String outs; protected String parameters; protected TreeGrid treeGrid; protected Tree tree; protected ToLoad toLoad; protected List<DatacageHandler> handlers; protected List<DatacageDoubleClickHandler> doubleHandlers; public DatacageWidget() { handlers = new ArrayList<DatacageHandler>(); doubleHandlers = new ArrayList<DatacageDoubleClickHandler>(); } public DatacageWidget(Artifact artifact, User user) { this(artifact, user, null); } public DatacageWidget(Artifact artifact, User user, String outs) { this(artifact, user, outs, true); } public DatacageWidget( Artifact artifact, User user, String outs, boolean showButton ) { this(artifact, user, outs, null, showButton); } public DatacageWidget( Artifact artifact, User user, String outs, String parameters, boolean showButton ) { this(); this.artifact = artifact; this.user = user; this.outs = outs; this.parameters = parameters; toLoad = new ToLoad(); setWidth100(); tree = new Tree(); tree.setModelType(TreeModelType.CHILDREN); tree.setNameProperty("name"); tree.setIdField("id"); tree.setChildrenProperty("children-nodes"); tree.setShowRoot(false); treeGrid = new TreeGrid(); treeGrid.setLoadDataOnDemand(false); treeGrid.setWidth100(); treeGrid.setHeight100(); treeGrid.setShowRoot(false); treeGrid.setNodeIcon("[SKIN]/../blank.gif"); treeGrid.setShowConnectors(true); treeGrid.setLoadingMessage(messages.databasket_loading()); treeGrid.setEmptyMessage(messages.databasket_loading()); treeGrid.setLoadingDataMessage(messages.databasket_loading()); treeGrid.setHoverMoveWithMouse(true); treeGrid.setCanHover(true); treeGrid.setShowHover(true); treeGrid.setHoverOpacity(75); treeGrid.setHoverCustomizer(new HoverCustomizer() { @Override public String hoverHTML(Object value, ListGridRecord record, int rowNum, int colNum ) { if(record instanceof TreeNode) { TreeNode hoveredTreeNode = (TreeNode)record; String info = hoveredTreeNode.getAttribute("info"); if (info == null) { info = hoveredTreeNode.getName(); } return info; } else { return "";// should not happen } } }); treeGrid.addRecordDoubleClickHandler(new RecordDoubleClickHandler() { @Override public void onRecordDoubleClick(RecordDoubleClickEvent event) { doubleClickedOnTree(event); } }); addMember(treeGrid); if (showButton) { addMember(createPlusButton()); } triggerTreeBuilding(); } /** * @param handler Handler to be added (notified on add-action). */ public DatacageWidget(Artifact artifact, User user, String outs, DatacageHandler handler) { this(artifact, user, outs); this.addDatacageHandler(handler); } public DatacageWidget( Artifact artifact, User user, String outs, DatacageHandler handler, String parameters ) { this(artifact, user, outs, handler); this.parameters = parameters; } /** * Sets whether more than one item can be selected. * @param multi if true, allow mutliple selections. */ public void setIsMutliSelectable(boolean multi) { if (multi) { treeGrid.setSelectionType(SelectionStyle.MULTIPLE); } else { treeGrid.setSelectionType(SelectionStyle.SINGLE); } } /** * @param handler Handler to be added (notified on add-action). */ public void addDatacageHandler(DatacageHandler handler) { if (!handlers.contains(handler)) { handlers.add(handler); } } /** * @param h Handler to be added (notified on Double click on node). */ public void addDatacageDoubleClickHandler(DatacageDoubleClickHandler h) { if (!doubleHandlers.contains(h)) { doubleHandlers.add(h); } } /** * @param handler Handler to remove from list. */ public void removeDatacageHandler(DatacageHandler handler) { handlers.remove(handler); } public ToLoad getToLoad() { return toLoad; } public ToLoad getSelection() { // Reset content of toLoads. toLoad = new ToLoad(); if (treeGrid == null) { return toLoad; } ListGridRecord [] selection = treeGrid.getSelectedRecords(); if (selection != null) { for (ListGridRecord record: selection) { if (record instanceof TreeNode) { collectToLoads((TreeNode)record); } } } return toLoad; } /** * Returns the titles of selected items (if any). */ public String[] getSelectionTitles() { if (treeGrid == null) { return new String[] {}; } ListGridRecord [] selection = treeGrid.getSelectedRecords(); if (selection == null) { return new String[] {}; } List<String> titleList = new ArrayList<String>(); for (ListGridRecord record: selection) { if (record instanceof TreeNode) { titleList.add(((TreeNode)record).getAttribute("name")); } } return titleList.toArray(new String[titleList.size()]); } /** * Callback for add-button. * Fires to load for every selected element and handler. */ public void plusClicked() { if (!getSelection().isEmpty()) { fireToLoad(); } } protected Button createPlusButton() { Button plusBtn = new Button(messages.datacageAdd()); plusBtn.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { plusClicked(); } }); return plusBtn; } protected void fireToLoad() { for (DatacageHandler handler: handlers) { handler.toLoad(toLoad); } } /** Notify DatacageDoubleClickHandlers that a doubleclick happened. */ protected void fireOnDoubleClick() { for (DatacageDoubleClickHandler handler: doubleHandlers) { handler.onDoubleClick(toLoad); } } protected void doubleClickedOnTree(RecordDoubleClickEvent event) { TreeNode node = (TreeNode)event.getRecord(); collectToLoads(node); fireOnDoubleClick(); } /** * Adds to toLoad, from info in node. * Afterwards, add all children of node to stack to parse (next time * collectToLoads is called). */ protected void collectToLoads(TreeNode node) { Stack<TreeNode> stack = new Stack<TreeNode>(); stack.push(node); while (!stack.isEmpty()) { node = stack.pop(); String factory = node.getAttribute("factory"); if (factory != null) { // we need at least a factory String artifact = node.getAttribute("artifact-id"); String out = node.getAttribute("out"); String name = node.getAttribute("facet"); String ids = node.getAttribute("ids"); String debugAttributeValues = ""; for (String attr: node.getAttributes()) { debugAttributeValues += ("[" + attr +": " + node.getAttributeAsString(attr) + "] "); } GWT.log("DatacageWidget.collectToLoad, attributes are " + debugAttributeValues); toLoad.add(artifact, factory, out, name, ids, node.getAttribute("name")); } TreeNode [] children = tree.getChildren(node); if (children != null) { for (TreeNode child: children) { stack.push(child); } } } } /** Get meta-data and populate tree with it. */ protected void triggerTreeBuilding() { Config config = Config.getInstance(); String locale = config.getLocale(); String artifactId = artifact.getUuid(); String userId = (user != null) ? user.identifier() : null; metaDataService.getMetaData( locale, artifactId, userId, outs, parameters, new AsyncCallback<DataCageTree>() { @Override public void onFailure(Throwable caught) { GWT.log("Could not load meta data."); SC.warn(caught.getMessage()); } @Override public void onSuccess(DataCageTree dcTree) { GWT.log("Successfully loaded meta data."); IdGenerator idGenerator = new IdGenerator(); DataCageNode dcRoot = dcTree.getRoot(); TreeNode root = buildRecursiveChildren( dcRoot, idGenerator); tree.setRoot(root); TreeNode[] nodes = tree.getChildren(root); for (int i = 0; i < nodes.length; i++) { if(!tree.hasChildren(nodes[i])) { nodes[i].setIsFolder(true); } } if (idGenerator.current() < MAX_OPEN) { tree.openAll(); } treeGrid.setData(tree); } }); } private static final class IdGenerator { protected int current; public IdGenerator() { } public int next() { return current++; } public int current() { return current; } } // class IdGenerator private String i18n(String s) { if (!(s.startsWith("${") && s.endsWith("}"))) { return s; } s = s.substring(2, s.length()-1); try { return messages.getString(s); } catch (MissingResourceException mre) { GWT.log("cannot find i18n for + '" + s + "'"); return s; } } protected TreeNode buildRecursiveChildren( DataCageNode node, IdGenerator idGenerator ) { TreeNode tn = new TreeNode(); tn.setAttribute("id", idGenerator.next()); List<DataCageNode> children = node.getChildren(); if (children != null) { TreeNode [] tns = new TreeNode[children.size()]; for (int i = 0; i < tns.length; ++i) { DataCageNode child = children.get(i); tns[i] = buildRecursiveChildren(child, idGenerator); } tn.setAttribute("children-nodes", tns); } tn.setAttribute("name", i18n(node.getDescription())); tn.setAttribute("facet", node.getName()); AttrList attrs = node.getAttributes(); if (attrs != null) { for (int i = 0, N = attrs.size(); i < N; ++i) { String key = attrs.getKey(i); String value = attrs.getValue(i); tn.setAttribute(key, value); } } return tn; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :