Package com.sencha.gxt.widget.core.client.treegrid

Source Code of com.sencha.gxt.widget.core.client.treegrid.TreeGridView

/**
* Sencha GXT 3.1.0-beta - Sencha for GWT
* Copyright(c) 2007-2014, Sencha, Inc.
* licensing@sencha.com
*
* http://www.sencha.com/products/gxt/license/
*/
package com.sencha.gxt.widget.core.client.treegrid;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.client.DOM;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.core.client.dom.XElement;
import com.sencha.gxt.core.client.util.IconHelper;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.data.shared.SortDir;
import com.sencha.gxt.data.shared.Store.StoreSortInfo;
import com.sencha.gxt.data.shared.TreeStore;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
import com.sencha.gxt.widget.core.client.grid.ColumnData;
import com.sencha.gxt.widget.core.client.grid.ColumnModel;
import com.sencha.gxt.widget.core.client.grid.Grid;
import com.sencha.gxt.widget.core.client.grid.GridView;
import com.sencha.gxt.widget.core.client.tree.Tree.CheckState;
import com.sencha.gxt.widget.core.client.tree.Tree.Joint;
import com.sencha.gxt.widget.core.client.tree.Tree.TreeNode;
import com.sencha.gxt.widget.core.client.tree.TreeView.TreeViewRenderMode;

/**
* A {@code GridView} subclass that adds tree related view features.
*/
public class TreeGridView<M> extends GridView<M> {

  protected TreeGrid<M> tree;
  protected TreeStore<M> treeStore;

  /**
   * Creates a new view instance.
   */
  public TreeGridView() {
    this(GWT.<GridAppearance> create(GridAppearance.class));
  }

  /**
   * Creates a new view instance with the given grid appearance.
   *
   * @param appearance the grid appearance
   */
  public TreeGridView(GridAppearance appearance) {
    super(appearance);
  }

  /**
   * Collapses the given node.
   *
   * @param node the node to be collapsed
   */
  public void collapse(TreeNode<M> node) {
    M p = node.getModel();
    M lc = treeStore.getLastChild(p);
    // make sure there is a last child (i.e. at least one child) before trying to thin the liststore
    if (lc != null) {
      int start = ds.indexOf(p);
      if (start != -1) {
        // ensure the node is visible
        int end = tree.findLastOpenChildIndex(lc);
        for (int i = end; i > start; i--) {
          ds.remove(i);
        }
      }
    }
    // regardless, refresh the parent icon
    tree.refresh(p);
  }

  /**
   * Expands the given node.
   *
   * @param node the node to be expanded
   */
  public void expand(TreeNode<M> node) {
    M p = node.getModel();
    List<M> children = treeStore.getChildren(p);
    if (children.size() > 0) {
      int idx = ds.indexOf(p);

      ds.addAll(idx + 1, children);

      for (M child : children) {
        TreeNode<M> cn = findNode(child);
        if (cn != null && cn.isExpanded()) {
          expand(cn);
        }
      }
    }
    tree.refresh(p);
  }

  /**
   * Gets the rendered element, if any, for the given tree node object. This method will look up the dom element if it
   * has not yet been seen. The getElement() method for the node will return the same value as this method does after it
   * has been cached.
   *
   * @param node the tree node to find an element for
   * @return the element that the node represents, or null if not yet rendered
   */
  public XElement getElement(TreeNode<M> node) {
    XElement elt = node.getElement().cast();
    if (elt == null) {
      if (tree.isAttached() && tree.getElement().getOffsetParent() != null) {
        elt = Document.get().getElementById(node.getDomId()).cast();
      } else {
        elt = tree.getElement().child("*#" + node.getDomId());
      }
      node.setElement(elt);
    }
    return elt;
  }

  /**
   * Returns the element which wraps the children of the given node. This is the element that is displayed / hidden when
   * a node is expanded / collapsed.
   *
   * @param node the target node
   * @return the element
   */
  public XElement getElementContainer(TreeNode<M> node) {
    if (node.getElementContainer() == null) {
      node.setElContainer(getElement(node) != null ? tree.getTreeAppearance().getContainerElement(getElement(node))
          : null);
    }
    return node.getElementContainer().cast();
  }

  /**
   * Returns the element in which the nodes icon is rendered.
   *
   * @param node the target node
   * @return the icon elmeent
   */
  public Element getIconElement(TreeNode<M> node) {
    if (node.getIconElement() == null) {
      Element row = getRowElement(node);
      if (row != null) {
        XElement r = row.cast();
        XElement icon = tree.getTreeAppearance().findIconElement(r);
        node.setIconElement(icon);
      }
    }
    return node.getIconElement();
  }

  /**
   * Returns the element in which the nodes joint (expand / collapse) icon is rendered.
   *
   * @param node the target node
   * @return the joint element
   */
  public Element getJointElement(TreeNode<M> node) {
    if (node.getJointElement() == null) {
      Element row = getRowElement(node);
      if (row != null) {
        XElement r = row.cast();
        XElement joint = tree.getTreeAppearance().findJointElement(r);
        node.setJointElement(joint);
      }
    }
    return node.getJointElement();
  }

  /**
   * Returns the markup that is used to render a node.
   *
   * @param m the model
   * @param id the id of the node (store model key provider)
   * @param text the node text
   * @param icon the node icon or null
   * @param checkable true if the node is checked
   * @param joint the joint state
   * @param level the tree depth
   * @return the markup as safe html
   */
  public SafeHtml getTemplate(M m, String id, SafeHtml text, ImageResource icon, boolean checkable, Joint joint,
      int level) {
    SafeHtmlBuilder sb = new SafeHtmlBuilder();
    tree.getTreeAppearance().renderNode(sb, id, text, tree.getStyle(), icon, checkable, CheckState.UNCHECKED, joint,
        level - 1, TreeViewRenderMode.ALL);
    return sb.toSafeHtml();
  }

  /**
   * Returns the element in which the node's text is rendered.
   *
   * @param node the target node
   * @return the text element
   */
  public Element getTextElement(TreeNode<M> node) {
    if (node == null) {
      return null;
    }
    if (node.getTextElement() == null) {
      Element row = getRowElement(node);
      if (row != null) {
        XElement t = row.<XElement> cast().selectNode(tree.getTreeAppearance().textSelector());
        node.setTextElement(t);
      }
    }
    return node.getTextElement();
  }

  @Override
  public boolean isSelectableTarget(Element target) {
    boolean b = super.isSelectableTarget(target);
    if (!b) {
      return false;
    }

    TreeNode<M> node = tree.findNode(target);
    if (node != null) {
      Element j = getJointElement(node);
      if (j != null && j.isOrHasChild(target)) {
        return false;
      }
    }
    return true;
  }

  public void onDropChange(Element e, boolean drop) {
    tree.getTreeAppearance().onDropOver(XElement.as(e), drop);
  }

  public void onIconStyleChange(TreeNode<M> node, ImageResource icon) {
    Element iconEl = getIconElement(node);
    if (iconEl != null) {
      Element e;
      if (icon != null) {
        e = (Element) IconHelper.getElement(icon);
      } else {
        e = DOM.createSpan();
      }
      node.setIconElement((Element) iconEl.getParentElement().insertBefore(e, iconEl));
      iconEl.removeFromParent();
    }
  }

  public void onJointChange(TreeNode<M> node, Joint joint) {
    Element jointEl = getJointElement(node);
    if (jointEl != null) {
      XElement elem = getElement(node);
      node.setJointElement(tree.getTreeAppearance().onJointChange(elem, jointEl.<XElement> cast(), joint,
          tree.getStyle()));
    }
  }

  public void onLoading(TreeNode<M> node) {
    onIconStyleChange(node, tree.getTreeAppearance().loadingIcon());
  }

  @Override
  public void refresh(boolean headerToo) {
    if (grid != null && grid.isViewReady()) {
      for (TreeNode<M> node : tree.nodes.values()) {
        node.clearElements();

      }
    }
    super.refresh(headerToo);
  }

  @Override
  protected void doSort(int colIndex, SortDir sortDir) {
    ColumnConfig<M, ?> column = cm.getColumn(colIndex);
    if (!isRemoteSort()) {
      treeStore.clearSortInfo();

      // These casts can fail, but in dev mode the exception will be caught by the
      // try/catch, unless there are no items in the Store
      @SuppressWarnings({"unchecked", "rawtypes"})
      ValueProvider<? super M, Comparable> vp = (ValueProvider) column.getValueProvider();
      @SuppressWarnings("unchecked")
      StoreSortInfo<M> s = new StoreSortInfo<M>(vp, sortDir);

      if (sortDir == null && storeSortInfo != null && storeSortInfo.getValueProvider().getPath().equals(vp.getPath())) {
        s.setDirection(storeSortInfo.getDirection() == SortDir.ASC ? SortDir.DESC : SortDir.ASC);
      } else if (sortDir == null) {
        s.setDirection(SortDir.ASC);
      }

      if (GWT.isProdMode()) {
        treeStore.addSortInfo(s);
      } else {
        try {
          // addSortInfo will apply its sort when called, which might trigger an
          // exception if the column passed in's data isn't Comparable
          treeStore.addSortInfo(s);
        } catch (ClassCastException ex) {
          GWT.log("Column can't be sorted " + column.getValueProvider().getPath() + " is not Comparable. ", ex);
          throw ex;
        }
      }

    } else {
      // not supported
    }

  }

  protected TreeNode<M> findNode(M m) {
    return tree.findNode(m);
  }

  @Override
  protected List<ColumnData> getColumnData() {
    List<ColumnData> data = super.getColumnData();

    for (int i = 0; i < data.size(); i++) {
      if (cm.indexOf(tree.getTreeColumn()) == i) {
        ColumnData cd = data.get(i);
        cd.setClassNames(cd.getClassNames() + " x-treegrid-column");
      }
    }

    return data;
  }

  protected int getIndenting(TreeNode<M> node) {
    return 18;
  }

  @Override
  protected <N> SafeHtml getRenderedValue(int rowIndex, int colIndex, M m, ListStore<M>.Record record) {
    ColumnConfig<M, N> cc = cm.getColumn(colIndex);
    SafeHtml s = super.getRenderedValue(rowIndex, colIndex, m, record);
    TreeNode<M> node = findNode(m);
    if (node != null && cc == tree.getTreeColumn()) {
      return getTemplate(m, node.getDomId(), s, tree.calculateIconStyle(m), false, tree.calculateJoint(m),
          treeStore.getDepth(m));
    }
    return s;
  }

  protected Element getRowElement(TreeNode<M> node) {
    return (Element) getRow(ds.indexOf(node.getModel()));
  }

  @Override
  public StoreSortInfo<M> getSortState() {
    if (treeStore.getSortInfo().size() > 0) {
      return treeStore.getSortInfo().get(0);
    }
    return null;
  }

  @Override
  protected void init(Grid<M> grid) {
    tree = (TreeGrid<M>) grid;
    super.init(grid);
  }

  @Override
  protected void initData(ListStore<M> ds, ColumnModel<M> cm) {
    super.initData(ds, cm);
    treeStore = tree.getTreeStore();
  }

  @Override
  protected void onRemove(M m, int index, boolean isUpdate) {
    super.onRemove(m, index, isUpdate);
    TreeNode<M> node = findNode(m);
    if (node != null) {
      node.clearElements();
    }
  }
}
TOP

Related Classes of com.sencha.gxt.widget.core.client.treegrid.TreeGridView

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.