Package com.google.devtools.depan.eclipse.views.tools

Source Code of com.google.devtools.depan.eclipse.views.tools.NodeEditorTool

/*
* Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.devtools.depan.eclipse.views.tools;

import com.google.devtools.depan.eclipse.editors.HierarchyCache;
import com.google.devtools.depan.eclipse.editors.NodeWrapperTreeSorter;
import com.google.devtools.depan.eclipse.editors.ViewEditor;
import com.google.devtools.depan.eclipse.trees.GraphData;
import com.google.devtools.depan.eclipse.trees.NodeTreeProvider;
import com.google.devtools.depan.eclipse.trees.NodeTreeView;
import com.google.devtools.depan.eclipse.trees.NodeTreeView.NodeWrapper;
import com.google.devtools.depan.eclipse.utils.EditColTableDef;
import com.google.devtools.depan.eclipse.utils.HierarchyViewer;
import com.google.devtools.depan.eclipse.utils.HierarchyViewer.HierarchyChangeListener;
import com.google.devtools.depan.eclipse.utils.Resources;
import com.google.devtools.depan.eclipse.utils.Tools;
import com.google.devtools.depan.eclipse.utils.relsets.RelSetDescriptor;
import com.google.devtools.depan.eclipse.views.NodeEditorLabelProvider;
import com.google.devtools.depan.eclipse.views.ViewSelectionListenerTool;
import com.google.devtools.depan.model.GraphNode;
import com.google.devtools.depan.model.RelationshipSet;
import com.google.devtools.depan.util.StringUtils;
import com.google.devtools.depan.view.NodeDisplayProperty;
import com.google.devtools.depan.view.NodeDisplayProperty.Size;

import com.google.common.collect.Lists;

import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;

import java.awt.Color;
import java.util.Collection;
import java.util.List;

/**
* Tool for Node edition. Associate to each node a {@link NodeDisplayProperty}
* and provide a GUI to edit them.
*
* @author ycoppel@google.com (Yohann Coppel)
*
*/
public class NodeEditorTool extends ViewSelectionListenerTool
    implements ICellModifier, NodeTreeProvider<NodeDisplayProperty>,
    HierarchyChangeListener {

  /**
   * Node Tree View handling the TreeViewer, and the data inside.
   */
  private NodeTreeView<NodeDisplayProperty> nodeTreeView = null;

  /**
   * Selector for named relationships sets.
   */
  private HierarchyViewer<NodeDisplayProperty> hierarchyPicker = null;

  protected static final String COL_NAME = "Name";
  protected static final String COL_XPOS = "X";
  protected static final String COL_YPOS = "Y";
  protected static final String COL_VISIBLE = "Visible";
  protected static final String COL_SELECTED = "Selected";
  protected static final String COL_SIZE = "Size";
  protected static final String COL_COLOR = "Color (R,G,B - empty = default)";

  public static final int INDEX_NAME = 0;
  public static final int INDEX_XPOS = 1;
  public static final int INDEX_YPOS = 2;
  public static final int INDEX_VISIBLE = 3;
  public static final int INDEX_SELECTED = 4;
  public static final int INDEX_SIZE = 5;
  public static final int INDEX_COLOR = 6;

  private static final EditColTableDef[] TABLE_DEF = new EditColTableDef[] {
    new EditColTableDef(COL_NAME, false, COL_NAME, 180),
    new EditColTableDef(COL_XPOS, false, COL_XPOS, 50),
    new EditColTableDef(COL_YPOS, false, COL_YPOS, 50),
    new EditColTableDef(COL_VISIBLE, true, COL_VISIBLE, 20),
    new EditColTableDef(COL_SELECTED, true, COL_SELECTED, 20),
    new EditColTableDef(COL_SIZE, true, COL_SIZE, 80),
    new EditColTableDef(COL_COLOR, true, COL_COLOR, 40)
  };

  @Override
  public Image getIcon() {
    return Resources.IMAGE_NODEEDITOR;
  }

  @Override
  public String getName() {
    return Resources.NAME_NODEEDITOR;
  }

  @Override
  public Control setupComposite(Composite parent) {
    Composite baseComposite = new Composite(parent, SWT.NONE);
    GridLayout grid = new GridLayout(1, false);
    baseComposite.setLayout(grid);

    hierarchyPicker = createHierarchyPicker(baseComposite);
    hierarchyPicker.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

    nodeTreeView = new NodeTreeView<NodeDisplayProperty>(baseComposite,
        SWT.VIRTUAL | SWT.FULL_SELECTION | SWT.BORDER);
    nodeTreeView.getTreeViewer().getControl().setLayoutData(
        new GridData(SWT.FILL, SWT.FILL, true, true));

    Tree tree = nodeTreeView.getTreeViewer().getTree();
    tree.setHeaderVisible(true);

    for (EditColTableDef d : TABLE_DEF) {
      TreeColumn col = new TreeColumn(tree, SWT.LEFT);
      col.setText(d.getLabel());
      col.setWidth(d.getWidth());
    }

    CellEditor[] cellA = new CellEditor[TABLE_DEF.length];
    cellA[INDEX_NAME] = null;
    cellA[INDEX_XPOS] = null;
    cellA[INDEX_YPOS] = null;
    cellA[INDEX_VISIBLE] = new CheckboxCellEditor(tree);
    cellA[INDEX_SELECTED] = new CheckboxCellEditor(tree);
    cellA[INDEX_SIZE] = new ComboBoxCellEditor(tree,
        Tools.toString(Size.values(), true));
    cellA[INDEX_COLOR] = new TextCellEditor(tree);

    nodeTreeView.getTreeViewer().setCellEditors(cellA);
    nodeTreeView.getTreeViewer().setColumnProperties(
        EditColTableDef.getProperties(TABLE_DEF));

    // (re) set the label provider, for one which can handle multiple
    // columns.
    nodeTreeView.getTreeViewer().setLabelProvider(
        new NodeEditorLabelProvider(this));

    // set a cell modifier
    nodeTreeView.getTreeViewer().setCellModifier(this);
    nodeTreeView.getTreeViewer().setSorter(new NodeWrapperTreeSorter());

    return baseComposite;
  }

  private HierarchyViewer<NodeDisplayProperty> createHierarchyPicker(
      Composite parent) {

    HierarchyViewer<NodeDisplayProperty> result =
        new HierarchyViewer<NodeDisplayProperty>(parent, false);
    result.addChangeListener(this);

    return result;
  }

  /////////////////////////////////////
  // Tool life-cycle methods

  @Override
  protected void acquireResources() {
    super.acquireResources();

    GraphData<NodeDisplayProperty> hierarchy = getDisplayHierarchy();
    nodeTreeView.updateData(hierarchy);
  }

  @Override
  protected void updateControls() {
    super.updateControls();

    // Update the hierarchy picker for the new editor.
    HierarchyCache<NodeDisplayProperty> hierarchies = getEditor().getHierarchies();
    RelationshipSet selectedRelSet = getEditor().getContainerRelSet();
    List<RelSetDescriptor> choices = getEditor().getRelSetChoices();
    hierarchyPicker.setInput(hierarchies, selectedRelSet, choices );
  }

  @Override
  public void editorClosed(ViewEditor viewEditor) {
    if (hasEditor()) {
      GraphData<NodeDisplayProperty> hierarchy = getDisplayHierarchy();
      hierarchy.saveExpandState(
          nodeTreeView.getTreeViewer().getExpandedTreePaths());
    }
    super.editorClosed(viewEditor);
  }

  @Override
  public void emptySelection() {
    if (!hasEditor()) {
      return;
    }

    GraphData<NodeDisplayProperty> hierarchy = getDisplayHierarchy();
    nodeTreeView.updateData(hierarchy);
  }

  private GraphData<NodeDisplayProperty> getDisplayHierarchy() {
    return hierarchyPicker.getGraphData();
  }

  /////////////////////////////////////
  // Node selection methods

  @Override
  public boolean canModify(Object element, String property) {
    return EditColTableDef.get(TABLE_DEF, property).isEditable();
  }

  @Override
  @SuppressWarnings("rawtypes") // NodeWrapper
  public Object getValue(Object element, String property) {
    if (element instanceof NodeWrapper) {
      NodeWrapper wrapper = (NodeWrapper) element;
      if (COL_XPOS.equals(property)) {
        return getEditor().getXPos(wrapper.getNode());
      }
      if (COL_XPOS.equals(property)) {
        return getEditor().getYPos(wrapper.getNode());
      }
      if (property.equals(COL_SELECTED)) {
        return getEditor().isSelected(wrapper.getNode());
      }

      NodeDisplayProperty p = getProp(wrapper);
      if (property.equals(COL_VISIBLE)) {
        return p.isVisible();
      }
      if (property.equals(COL_SIZE)) {
        return p.getSize().ordinal();
      }
      if (property.equals(COL_COLOR)) {
        return p.getColor() == null ? "" : p.getColor().toString();
      }
    }
    return null;
  }

  /**
   * return the {@link NodeDisplayProperty} associated with the given element.
   *
   * @param element
   * @return the property associated with the given {@link NodeWrapper}.
   */
  @SuppressWarnings({ "rawtypes", "unchecked" })
  private NodeDisplayProperty getProp(NodeWrapper element) {
    return ((NodeWrapper<NodeDisplayProperty>) element).getContent();
  }

  /**
   * Change the element property to the given value.
   */
  // suppressWarning: we cast an Object to NodeWrapper, the parameter type is
  // unchecked.
  @Override
  @SuppressWarnings("unchecked")
  public void modify(Object element, String property, Object value) {
    if (!(element instanceof TreeItem)) {
      return;
    }
    Object o = ((TreeItem) element).getData();
    if (!(o instanceof NodeWrapper)) {
      return;
    }
    NodeWrapper<NodeDisplayProperty> prop =
        (NodeWrapper<NodeDisplayProperty>) o;
    NodeDisplayProperty p = prop.getContent();
    GraphNode node = prop.getNode();

//    System.out.println("" + p + " " + property + " - " + value);
    if (property.equals(COL_VISIBLE) && (value instanceof Boolean)) {
      p.setVisible((Boolean) value);
    } else if (property.equals(COL_SELECTED) && (value instanceof Boolean)) {
      selectNode(node, (Boolean) value);
    } else if (property.equals(COL_SIZE) && (value instanceof Integer)) {
      p.setSize(Size.values()[(Integer) value]);
    } else if (property.equals(COL_COLOR) && (value instanceof String)) {
      Color newColor = StringUtils.stringToColor((String) value);
      p.setColor(newColor);
    }
    // notify the listeners about this change
    getEditor().setNodeProperty(node, p);
    // update the column / line we just modified
    nodeTreeView.getTreeViewer().update(o, new String[] {property});
  }

  private void selectNode(GraphNode node, boolean extend) {
    Collection<GraphNode> selectGroup = Lists.newArrayList(node);
    if (extend) {
      getEditor().extendSelection(selectGroup, this);
      return;
    }
    getEditor().reduceSelection(selectGroup, this);
  }

  @Override
  public NodeDisplayProperty getObject(GraphNode node) {
    return getEditor().getNodeProperty(node);
  }

  /**
   * Change the selection state of the given node to the new value, in the list
   * of nodes properties.
   * @param node the node to change.
   * @param value the selection value.
   */
  private void setSelectedState(GraphNode node, boolean value) {
    NodeDisplayProperty prop = getEditor().getNodeProperty(node);
    if (null == prop) {
      return;
    }

    NodeWrapper<NodeDisplayProperty> nodeWrapper =
        nodeTreeView.getNodeWrapper(node);
    if (null == nodeWrapper) {
      return;
    }

    // update the value in the table. this might be faster than updating
    // all the list at the end. because a selection generally doesn't
    // change a lot.
    nodeTreeView.getTreeViewer().update(
        nodeWrapper, new String[] { COL_SELECTED });
  }

  /**
   * Set the given set of nodes as selected in the list.
   * @param selection set of nodes
   */
  @Override
  public void updateSelectedExtend(Collection<GraphNode> extension) {
    for (GraphNode node : extension) {
      setSelectedState(node, true);
    }
  }

  /**
   * Set the given set of nodes as unselected in the list.
   *
   * @param selection set of nodes
   * @see com.google.devtools.depan.eclipse.views.ViewSelectionListenerTool
   *      #updateSelectedRemove(com.google.devtools.depan.model.GraphNode[])
   */
  @Override
  public void updateSelectedReduce(Collection<GraphNode> reduction) {
    for (GraphNode node : reduction) {
      setSelectedState(node, false);
    }
  }

  /**
   * Set the nodes in the given set as the only ones selected. Which means
   * that the previously selected are first unselected, then nodes in the
   * <code>selection</code> argument are added.
   */
  @Override
  public void updateSelectionTo(Collection<GraphNode> selection) {
    for (GraphNode node : getEditor().getViewGraph().getNodes()) {
      NodeWrapper<NodeDisplayProperty> nodeWrapper =
          nodeTreeView.getNodeWrapper(node);
      if (null != nodeWrapper) {
        // update the value in the table. this might be faster than updating
        // all the list at the end. because a selection generally doesn't
        // change a lot.
        nodeTreeView.getTreeViewer().update(
            nodeWrapper, new String[] { COL_SELECTED });
      }
    }
    updateSelectedExtend(selection);
  }

  @Override
  public void hierarchyChanged() {
    if (!hasEditor()) {
      return;
    }

    GraphData<NodeDisplayProperty> hierarchy = getDisplayHierarchy();
    nodeTreeView.updateData(hierarchy);
  }
}
TOP

Related Classes of com.google.devtools.depan.eclipse.views.tools.NodeEditorTool

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.