Package org.geomajas.gwt.client.widget

Source Code of org.geomajas.gwt.client.widget.AttributeListGrid$ImageCellHandler

/*
* This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
*
* Copyright 2008-2011 Geosparc nv, http://www.geosparc.com/, Belgium.
*
* The program is available in open source according to the GNU Affero
* General Public License. All contributions in this program are covered
* by the Geomajas Contributors License Agreement. For full licensing
* details, see LICENSE.txt in the project root.
*/

package org.geomajas.gwt.client.widget;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.geomajas.configuration.AssociationAttributeInfo;
import org.geomajas.configuration.AttributeInfo;
import org.geomajas.configuration.FeatureInfo;
import org.geomajas.configuration.PrimitiveAttributeInfo;
import org.geomajas.configuration.PrimitiveType;
import org.geomajas.gwt.client.util.StringUtil;
import org.geomajas.layer.feature.Attribute;
import org.geomajas.layer.feature.attribute.AssociationValue;
import org.geomajas.layer.feature.attribute.ManyToOneAttribute;
import org.geomajas.layer.feature.attribute.OneToManyAttribute;

import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.widgets.Img;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridFieldIfFunction;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.CellClickEvent;
import com.smartgwt.client.widgets.grid.events.CellClickHandler;
import com.smartgwt.client.widgets.grid.events.CellOverEvent;
import com.smartgwt.client.widgets.grid.events.CellOverHandler;

/**
* List grid that shows association attributes as records.
*
* @author Jan De Moerloose
*/
public class AttributeListGrid extends ListGrid {

  /**
   * Feature information
   */
  private FeatureInfo featureInfo;

  /**
   * Show all attributes (true) or only the 'identifying' attributes (false)?
   */
  private boolean allAttributesDisplayed;

  /**
   * Show the feature's ID in the table. This is false by default, and should not really be necessary.
   */
  private boolean idInTable;

  /**
   * When hovering over image attributes, should they be shown in floating panels or not?
   */
  private boolean showImageAttributeOnHover;

  /**
   * List of values in the grid
   */
  private Map<AssociationValue, String> idByValue = new HashMap<AssociationValue, String>();
 
  private int newRows;

  private static final String NEW_PREFIX = "_new_";

  private static final String VALUE_HOLDER_RECORD_ATTRIBUTE = "_value_";

  private static final String ID_NAME = "attributeId";

  // -------------------------------------------------------------------------
  // Constructors:
  // -------------------------------------------------------------------------

  public AttributeListGrid(FeatureInfo featureInfo) {
    this.featureInfo = featureInfo;
    setShowEmptyMessage(true);
    setIdInTable(false);
  }

  // -------------------------------------------------------------------------
  // Class specific methods:
  // -------------------------------------------------------------------------

  /**
   * Empty the grid, thereby removing all rows. It does not clear the header though.
   */
  public void clearValues() {
    setData(new ListGridRecord[] {});
    idByValue.clear();
    newRows = 0;
  }

  /**
   * Adds a new value to the list.
   *
   * @param associationValue The value to be added to the list.
   * @return Returns true in case of update, and false if the value is already in the list or the value is null
   */
  public boolean saveOrUpdateValue(AssociationValue associationValue) {
    if (idByValue.containsKey(associationValue)) {
      updateValue(associationValue);
      setData(getRecords());
      return true;
    } else {
      // Calculate id
      Object idObject = associationValue.getId().getValue();
      String id;
      if (idObject != null) {
        id = idObject.toString();
      } else {
        // fake id
        id = NEW_PREFIX + "." + (newRows++);
      }
      // Feature checks out, add it to the grid:
      ListGridRecord record = new ListGridRecord();
      record.setAttribute(ID_NAME, id);
      updateAttributes(associationValue, record);
      idByValue.put(associationValue, id);
      addData(record);
      return false;
    }
  }

  /**
   * Removes a value to the list.
   *
   * @param associationValue The value to be removed from the list.
   * @return Returns true in case of successful removal.
   */
  public boolean deleteValue(AssociationValue associationValue) {
    if (idByValue.containsKey(associationValue)) {
      for (ListGridRecord record : getRecords()) {
        if (record.getAttributeAsObject(VALUE_HOLDER_RECORD_ATTRIBUTE) == associationValue) {
          removeData(record);
          idByValue.remove(associationValue);
          return true;
        }
      }
    }
    return false;
  }
 
  /**
   * Returns true if the specified value has been added to the list.
   *
   * @param associationValue value to check
   * @return true if added, false otherwise.
   */
  public boolean containsValue(AssociationValue associationValue) {
    return idByValue.containsKey(associationValue);
  }
 
  private void updateAttributes(AssociationValue associationValue, ListGridRecord record) {
    for (AttributeInfo attributeInfo : featureInfo.getAttributes()) {
      Attribute<?> attr = associationValue.getAllAttributes().get(attributeInfo.getName());
      if (attr.isPrimitive()) {
        Object value = attr.getValue();
        if (value != null) {
          if (value instanceof Boolean) {
            record.setAttribute(attributeInfo.getName(), (Boolean) value); // "false" != false
          } else {
            record.setAttribute(attributeInfo.getName(), value.toString());
          }
        } else {
          record.setAttribute(attributeInfo.getName(), "");
        }
      } else {
        AssociationAttributeInfo associationAttributeInfo = (AssociationAttributeInfo) attributeInfo;
        String displayName = associationAttributeInfo.getFeature().getDisplayAttributeName();
        Object value = attr.getValue();
        if (value != null) {
          if (displayName == null) {
            displayName = associationAttributeInfo.getFeature().getAttributes().get(0).getName();
          }
          switch (associationAttributeInfo.getType()) {
            case MANY_TO_ONE:
              ManyToOneAttribute manyToOneAttribute = (ManyToOneAttribute) attr;
              Object displayValue = manyToOneAttribute.getValue().getAllAttributes().get(displayName)
                  .getValue();
              if (displayValue != null) {
                record.setAttribute(attributeInfo.getName(), displayValue.toString());
              } else {
                record.setAttribute(attributeInfo.getName(), "");
              }
              break;
            case ONE_TO_MANY:
              OneToManyAttribute oneToManyAttribute = (OneToManyAttribute) attr;
              List<String> values = new ArrayList<String>();
              for (AssociationValue assoc : oneToManyAttribute.getValue()) {
                Object o = assoc.getAllAttributes().get(displayName).getValue();
                if (o != null) {
                  values.add(o.toString());
                }
              }
              record.setAttribute(attributeInfo.getName(), StringUtil.join(values, ","));
              break;
          }
        } else {
          record.setAttribute(attributeInfo.getName(), "");
        }
      }
    }
    record.setAttribute(VALUE_HOLDER_RECORD_ATTRIBUTE, associationValue);
  }

  public AssociationValue getSelectedValue() {
    ListGridRecord record = getSelectedRecord();
    if (record != null) {
      return (AssociationValue) record.getAttributeAsObject(VALUE_HOLDER_RECORD_ATTRIBUTE);
    } else {
      return null;
    }
  }

  public void selectValue(AssociationValue value) {
    for (ListGridRecord record : getRecords()) {
      if (record.getAttributeAsObject(VALUE_HOLDER_RECORD_ATTRIBUTE) == value) {
        selectRecord(record);
      }
    }
  }

  public void updateValue(AssociationValue value) {
    for (ListGridRecord record : getRecords()) {
      if (record.getAttributeAsObject(VALUE_HOLDER_RECORD_ATTRIBUTE) == value) {
        updateAttributes(value, record);
      }
    }
  }

  public List<AssociationValue> getValues() {
    List<AssociationValue> values = new ArrayList<AssociationValue>();
    for (ListGridRecord record : getRecords()) {
      values.add((AssociationValue) record.getAttributeAsObject(VALUE_HOLDER_RECORD_ATTRIBUTE));
    }
    return values;
  }

  /**
   * Is the grid currently displaying all attributes, instead of only the 'identifying' ones?
   *
   * @return are all attributes displayed
   */
  public boolean isAllAttributesDisplayed() {
    return allAttributesDisplayed;
  }

  /**
   * Determine if all attributes of a layer should be shown, or only the 'identifying' ones. Changing this value will
   * not change the layout of the grid. So set this value in advance.
   *
   * @param allAttributesDisplayed should all attributes be displayed
   */
  public void setAllAttributesDisplayed(boolean allAttributesDisplayed) {
    this.allAttributesDisplayed = allAttributesDisplayed;
    updateFields();
  }

  /**
   * Return whether or not the feature's ID's are currently drawn in the grid.
   *
   * @return is feature id displayed
   */
  public boolean isIdInTable() {
    return idInTable;
  }

  /**
   * Determine whether or not the feature's ID should be displayed in the grid. This method will immediately update
   * the entire grid.
   *
   * @param idInTable should id be displayed
   */
  public void setIdInTable(boolean idInTable) {
    this.idInTable = idInTable;
    updateFields();
  }

  public boolean isShowImageAttributeOnHover() {
    return showImageAttributeOnHover;
  }

  public void setShowImageAttributeOnHover(boolean showImageAttributeOnHover) {
    this.showImageAttributeOnHover = showImageAttributeOnHover;
  }

  // -------------------------------------------------------------------------
  // Private methods:
  // -------------------------------------------------------------------------

  /**
   * Actually create or update the fields.
   */
  private void updateFields() {
    if (featureInfo != null) {
      // Create a header field for each attribute definition:
      List<ListGridField> fields = new ArrayList<ListGridField>();
      if (idInTable) {
        ListGridField gridField = new ListGridField(ID_NAME, "ID");
        gridField.setAlign(Alignment.LEFT);
        gridField.setCanEdit(false);
        fields.add(gridField);
      }

      for (AttributeInfo attributeInfo : featureInfo.getAttributes()) {
        if (!attributeInfo.isHidden() && (attributeInfo.isIdentifying() || allAttributesDisplayed)) {
          fields.add(createAttributeGridField(attributeInfo));
        }
      }
      setFields(fields.toArray(new ListGridField[fields.size()]));
      setCanResizeFields(true);
    }
  }

  /**
   * Create a single field definition from a attribute definition.
   *
   * @param attributeInfo attribute info
   * @return field for grid
   */
  private ListGridField createAttributeGridField(final AttributeInfo attributeInfo) {
    ListGridField gridField = new ListGridField(attributeInfo.getName(), attributeInfo.getLabel());
    gridField.setAlign(Alignment.LEFT);
    gridField.setCanEdit(false);
    gridField.setShowIfCondition(new IdentifyingListGridFieldIfFunction(attributeInfo.isIdentifying()));

    if (attributeInfo instanceof PrimitiveAttributeInfo) {
      PrimitiveAttributeInfo info = (PrimitiveAttributeInfo) attributeInfo;
      if (info.getType().equals(PrimitiveType.BOOLEAN)) {
        gridField.setType(ListGridFieldType.BOOLEAN);
      } else if (info.getType().equals(PrimitiveType.STRING)) {
        gridField.setType(ListGridFieldType.TEXT);
      } else if (info.getType().equals(PrimitiveType.DATE)) {
        gridField.setType(ListGridFieldType.DATE);
      } else if (info.getType().equals(PrimitiveType.SHORT)) {
        gridField.setType(ListGridFieldType.INTEGER);
      } else if (info.getType().equals(PrimitiveType.INTEGER)) {
        gridField.setType(ListGridFieldType.INTEGER);
      } else if (info.getType().equals(PrimitiveType.LONG)) {
        gridField.setType(ListGridFieldType.INTEGER);
      } else if (info.getType().equals(PrimitiveType.FLOAT)) {
        gridField.setType(ListGridFieldType.FLOAT);
      } else if (info.getType().equals(PrimitiveType.DOUBLE)) {
        gridField.setType(ListGridFieldType.FLOAT);
      } else if (info.getType().equals(PrimitiveType.IMGURL)) {
        gridField.setType(ListGridFieldType.IMAGE);
        if (showImageAttributeOnHover) {
          addCellOverHandler(new ImageCellHandler(attributeInfo));
        }
      } else if (info.getType().equals(PrimitiveType.CURRENCY)) {
        gridField.setType(ListGridFieldType.TEXT);
      } else if (info.getType().equals(PrimitiveType.URL)) {
        gridField.setType(ListGridFieldType.TEXT);
        gridField.setAttribute("text-decoration", "underline");
        addCellClickHandler(new UrlCellHandler(attributeInfo));
      }
    } else if (attributeInfo instanceof AssociationAttributeInfo) {
      gridField.setType(ListGridFieldType.TEXT);
    }
    return gridField;
  }

  /**
   * Private class, implementing the {@link ListGridFieldIfFunction} interface that determines the visibility of a
   * grid field, based upon the attribute definition's identifying value, and the {@link FeatureListGrid}'s
   * <code>allAttributesDisplayed</code> value.
   *
   * @author Pieter De Graef
   */
  private class IdentifyingListGridFieldIfFunction implements ListGridFieldIfFunction {

    private boolean identifying;

    public IdentifyingListGridFieldIfFunction(boolean identifying) {
      this.identifying = identifying;
    }

    public boolean execute(ListGrid grid, ListGridField field, int fieldNum) {
      if (identifying) {
        return true;
      }
      if (grid instanceof AttributeListGrid) {
        AttributeListGrid table = (AttributeListGrid) grid;
        if (table.isAllAttributesDisplayed()) {
          return true;
        }
      }
      return false;
    }
  }

  /**
   * Display the actual image of an image-cell when the mouse goes over it. The image self-destructs after 3 seconds.
   *
   * @author Pieter De Graef
   */
  private class ImageCellHandler implements CellOverHandler {

    private Timer killTimer;

    private Img img;

    private int row = -1;

    private AttributeInfo attributeInfo;

    ImageCellHandler(AttributeInfo attributeInfo) {
      this.attributeInfo = attributeInfo;
    }

    public void onCellOver(CellOverEvent event) {
      ListGridField gridField = AttributeListGrid.this.getField(event.getColNum());
      if (gridField.getName().equals(attributeInfo.getName())) {
        ListGridRecord record = event.getRecord();
        String value = record.getAttribute(attributeInfo.getName());
        if (event.getRowNum() != row) {
          if (img != null) {
            cleanup();
          }
          img = new Img(value);
          img.setMaxWidth(300);
          img.setMaxHeight(300);
          img.setKeepInParentRect(true);
          img.setShowEdges(true);
          img.setLeft(AttributeListGrid.this.getAbsoluteLeft() + 10);
          img.setTop(AttributeListGrid.this.getAbsoluteTop() + 10);
          img.draw();
          killTimer = new Timer() {

            public void run() {
              img.destroy();
            }
          };
          killTimer.schedule(Math.round(3000));
          row = event.getRowNum();
        }
      }
    }

    private void cleanup() {
      killTimer.cancel();
      img.destroy();
      img = null;
    }
  }

  /**
   * Open the url in a separate browser window
   *
   * @author Jan De Moerloose
   */
  private class UrlCellHandler implements CellClickHandler {

    private AttributeInfo attributeInfo;

    UrlCellHandler(AttributeInfo attributeInfo) {
      this.attributeInfo = attributeInfo;
    }

    public void onCellClick(CellClickEvent event) {
      ListGridField gridField = AttributeListGrid.this.getField(event.getColNum());
      if (gridField.getName().equals(attributeInfo.getName())) {
        ListGridRecord record = event.getRecord();
        String value = record.getAttribute(attributeInfo.getName());
        Window.open(value, "urlWindow", null);
      }
    }

  }
}
TOP

Related Classes of org.geomajas.gwt.client.widget.AttributeListGrid$ImageCellHandler

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.