teichmann@5861: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5861: * Software engineering by Intevation GmbH teichmann@5861: * teichmann@5993: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5861: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5993: * documentation coming with Dive4Elements River for details. teichmann@5861: */ teichmann@5861: teichmann@5835: package org.dive4elements.river.client.client.ui; ingo@2521: gernotbelger@9390: import java.io.Serializable; gernotbelger@9390: import java.util.ArrayList; gernotbelger@9390: import java.util.HashMap; gernotbelger@9390: import java.util.List; gernotbelger@9390: import java.util.Map; ingo@2521: teichmann@5835: import org.dive4elements.river.client.client.FLYSConstants; teichmann@5835: import org.dive4elements.river.client.shared.model.DataItem; teichmann@5835: import org.dive4elements.river.client.shared.model.IntegerOptionsData; rrenkert@7826: import org.dive4elements.river.client.shared.model.MultiAttributeData; rrenkert@7826: import org.dive4elements.river.client.shared.model.MultiDataItem; teichmann@5835: import org.dive4elements.river.client.shared.model.StringOptionsData; ingo@2521: gernotbelger@9390: import com.google.gwt.core.client.GWT; gernotbelger@9390: import com.google.gwt.event.dom.client.ClickEvent; gernotbelger@9390: import com.google.gwt.event.dom.client.ClickHandler; gernotbelger@9390: import com.google.gwt.user.client.ui.CheckBox; gernotbelger@9390: import com.google.gwt.user.client.ui.Grid; gernotbelger@9390: import com.google.gwt.user.client.ui.Widget; gernotbelger@9390: import com.smartgwt.client.types.ListGridFieldType; gernotbelger@9390: import com.smartgwt.client.widgets.Canvas; gernotbelger@9390: import com.smartgwt.client.widgets.Label; gernotbelger@9390: import com.smartgwt.client.widgets.grid.ListGrid; gernotbelger@9390: import com.smartgwt.client.widgets.grid.ListGridField; gernotbelger@9390: import com.smartgwt.client.widgets.grid.ListGridRecord; ingo@2521: felix@3854: /** felix@3854: * Some parameters take the form of on/off options that can also be seen felix@3854: * as a matrix. felix@3854: * felix@3854: * This class helps to survive the underlying objects and create a visual felix@3854: * representation of this matrix. Later can happen in two ways to overcome felix@3854: * shortcomings of GWT/SmartGWT combination. felix@3854: */ ingo@2521: public class ParameterMatrix { ingo@2521: felix@3982: protected ListGrid listGrid = null; felix@3982: ingo@2521: public static class Column implements Serializable { christian@4184: christian@4184: private static final long serialVersionUID = -3493426383086860118L; christian@4184: gernotbelger@9390: protected String name; ingo@2521: protected Map values; ingo@2521: ingo@2521: private Column() { ingo@2521: this.values = new HashMap(); ingo@2521: } ingo@2521: gernotbelger@9390: public Column(final String name) { ingo@2521: this(); ingo@2521: this.name = name; ingo@2521: } ingo@2521: gernotbelger@9390: public void addValue(final String label, final String value) { gernotbelger@9390: this.values.put(label, value); ingo@2521: } ingo@2521: gernotbelger@9390: public String getValue(final String label) { gernotbelger@9390: return this.values.get(label); ingo@2521: } ingo@2521: } // end of class Column ingo@2521: gernotbelger@9390: /** The message class that provides i18n strings. */ raimund@3705: protected FLYSConstants MESSAGE = GWT.create(FLYSConstants.class); ingo@2521: ingo@2521: public static final int CELL_HEIGHT = 25; ingo@2521: gernotbelger@9390: private final Map columns; gernotbelger@9390: private final List columnNames; gernotbelger@9390: private final List valueNames; gernotbelger@9390: private final Map> attributes; ingo@2521: felix@3993: /** Maps column names to list of rows' first fields. */ gernotbelger@9390: private final Map> selected; gernotbelger@9390: private final String itemname; ingo@2521: gernotbelger@9390: public ParameterMatrix(final String itemnameColTitle) { ingo@2521: super(); gernotbelger@9390: this.itemname = itemnameColTitle; gernotbelger@9390: this.columns = new HashMap(); ingo@2521: this.columnNames = new ArrayList(); gernotbelger@9390: this.valueNames = new ArrayList(); gernotbelger@9390: this.selected = new HashMap>(); gernotbelger@9390: this.attributes = new HashMap>(); ingo@2521: } ingo@2521: gernotbelger@9390: public void addColumn(final IntegerOptionsData group) { gernotbelger@9390: final String groupTitle = group.getLabel(); ingo@2521: gernotbelger@9390: final Column col = new Column(groupTitle); gernotbelger@9390: final DataItem[] items = group.getItems(); ingo@2532: ingo@2532: if (items == null) { ingo@2532: GWT.log("No items found in StringOptionsData '" + groupTitle + "'"); ingo@2532: return; ingo@2532: } ingo@2532: gernotbelger@9390: for (final DataItem item : items) { gernotbelger@9390: final String title = item.getLabel(); ingo@2532: gernotbelger@9390: if (this.valueNames.indexOf(title) < 0) { gernotbelger@9390: this.valueNames.add(title); ingo@2532: } ingo@2532: ingo@2532: col.addValue(item.getLabel(), item.getStringValue()); ingo@2532: } ingo@2532: gernotbelger@9390: this.columnNames.add(groupTitle); gernotbelger@9390: this.columns.put(groupTitle, col); felix@7579: } felix@7579: gernotbelger@9390: public List getColumnNames() { gernotbelger@9390: return this.columnNames; gernotbelger@9390: } felix@7579: gernotbelger@9390: public void addColumn(final StringOptionsData options) { gernotbelger@9390: final String groupTitle = options.getLabel(); ingo@2532: gernotbelger@9390: final Column col = new Column(groupTitle); gernotbelger@9390: final DataItem[] items = options.getItems(); ingo@2532: ingo@2532: if (items == null) { gernotbelger@9390: GWT.log("No items found in StringOptionsData '" + groupTitle + "'"); ingo@2532: return; ingo@2532: } ingo@2532: gernotbelger@9390: for (final DataItem item : items) { gernotbelger@9390: final String title = item.getLabel(); ingo@2521: gernotbelger@9390: if (this.valueNames.indexOf(title) < 0) { gernotbelger@9390: this.valueNames.add(title); ingo@2521: } ingo@2521: ingo@2521: col.addValue(item.getLabel(), item.getStringValue()); ingo@2521: } ingo@2521: gernotbelger@9390: this.columnNames.add(groupTitle); gernotbelger@9390: this.columns.put(groupTitle, col); ingo@2521: } ingo@2521: gernotbelger@9390: public void addColumn(final MultiAttributeData options) { rrenkert@7826: GWT.log("Add Columns for MultiAttribute data"); gernotbelger@9390: final String groupTitle = options.getLabel(); rrenkert@7826: gernotbelger@9390: final Column col = new Column(groupTitle); gernotbelger@9390: final DataItem[] items = options.getItems(); rrenkert@7826: rrenkert@7826: if (items == null) { gernotbelger@9390: GWT.log("No items found in StringOptionsData '" + groupTitle + "'"); rrenkert@7826: return; rrenkert@7826: } rrenkert@7826: gernotbelger@9390: final MultiDataItem mItem = (MultiDataItem) items[0]; gernotbelger@9390: for (final Map.Entry entry : mItem.getValue().entrySet()) { gernotbelger@9390: if (entry.getKey().equals("art:value") || entry.getKey().equals("art:label")) { rrenkert@7826: continue; rrenkert@7826: } gernotbelger@9390: this.attributes.put(entry.getKey(), new ArrayList()); rrenkert@7826: } gernotbelger@9390: for (final DataItem item : items) { rrenkert@7826: GWT.log("multidataitem: " + item.getLabel()); gernotbelger@9390: final String title = item.getLabel(); rrenkert@7826: gernotbelger@9390: if (this.valueNames.indexOf(title) < 0) { gernotbelger@9390: this.valueNames.add(title); rrenkert@7826: } gernotbelger@9390: final MultiDataItem mi = (MultiDataItem) item; gernotbelger@9390: final Map vs = mi.getValue(); gernotbelger@9390: for (final Map.Entry e : vs.entrySet()) { gernotbelger@9390: if (e.getKey().equals("art:value") || e.getKey().equals("art:label")) { rrenkert@7826: continue; rrenkert@7826: } gernotbelger@9390: final List data = this.attributes.get(e.getKey()); rrenkert@7826: data.add(e.getValue()); rrenkert@7826: } rrenkert@7826: col.addValue(item.getLabel(), mi.getValue().get("art:value")); rrenkert@7826: } rrenkert@7826: gernotbelger@9390: this.columnNames.add(groupTitle); gernotbelger@9390: this.columns.put(groupTitle, col); rrenkert@7826: } ingo@2521: felix@3982: public Widget createParameterGrid() { gernotbelger@9390: this.listGrid = new ListGrid(); gernotbelger@9390: this.listGrid.setShowAllRecords(true); gernotbelger@9390: this.listGrid.setWrapCells(true); gernotbelger@9390: this.listGrid.setShowHeaderContextMenu(false); gernotbelger@9390: this.listGrid.setCanReorderFields(false); gernotbelger@9390: // listGrid.setCanSort(false); gernotbelger@9390: // listGrid.setAutoFitData(Autofit.VERTICAL); gernotbelger@9390: this.listGrid.setFixedRecordHeights(false); felix@3982: // TODO: Then also need "autofit" (when wrapping) felix@3854: gernotbelger@9390: final ListGridField itemNameField = new ListGridField("itemname", this.itemname); gernotbelger@9390: final ArrayList fields = new ArrayList(); felix@3982: fields.add(itemNameField); felix@3982: gernotbelger@9390: for (final Map.Entry> entry : this.attributes.entrySet()) { gernotbelger@9390: final ListGridField attrField = new ListGridField(entry.getKey(), this.MESSAGE.getString(entry.getKey())); rrenkert@7826: fields.add(attrField); rrenkert@7826: } rrenkert@7826: gernotbelger@9390: for (int i = 0, n = this.columnNames.size(); i < n; i++) { gernotbelger@9390: final ListGridField field = new ListGridField(this.columnNames.get(i), this.MESSAGE.getString(this.columnNames.get(i))); felix@3982: field.setType(ListGridFieldType.BOOLEAN); felix@3982: field.setCanEdit(true); felix@3982: fields.add(field); gernotbelger@9390: this.selected.put(this.columnNames.get(i), new ArrayList()); felix@3982: } felix@3854: gernotbelger@9390: final ListGridField[] fieldsArray = fields.toArray(new ListGridField[fields.size()]); gernotbelger@9390: this.listGrid.setFields(fieldsArray); felix@3854: gernotbelger@9390: final int nVals = this.valueNames.size(); sascha@3858: gernotbelger@9390: final ArrayList records = new ArrayList(); felix@3854: for (int j = 0; j < nVals; j++) { gernotbelger@9390: final String valueName = this.valueNames.get(j); gernotbelger@9390: final ListGridRecord record = new ListGridRecord(); felix@3982: record.setAttribute("itemname", valueName); gernotbelger@9390: for (int i = 0, n = this.columnNames.size(); i < n; i++) { gernotbelger@9390: final String columnName = this.columnNames.get(i); gernotbelger@9390: final Column col = this.columns.get(columnName); gernotbelger@9390: final String value = col.getValue(valueName); felix@3982: record.setAttribute(columnName, false); gernotbelger@9390: record.setAttribute(columnName + "-value", value); felix@3854: } gernotbelger@9390: for (final Map.Entry> entry : this.attributes.entrySet()) { rrenkert@7826: record.setAttribute(entry.getKey(), entry.getValue().get(j)); rrenkert@7826: } felix@3982: records.add(record); felix@3854: } felix@3854: gernotbelger@9390: this.listGrid.setData(records.toArray(new ListGridRecord[records.size()])); felix@3982: gernotbelger@9390: return this.listGrid; felix@3982: felix@3854: } felix@3854: felix@3854: /** felix@3854: * Returns a widget with matrix of checkboxes and labels. gernotbelger@9390: * gernotbelger@9390: * @param asListGrid gernotbelger@9390: * if true, use a ListGrid (for inclusion in SmartGWT gernotbelger@9390: * containers, avoiding scrollbar-issues. felix@3854: */ gernotbelger@9390: public Widget create(final boolean asListGrid) { felix@3982: if (asListGrid) { felix@3982: return createParameterGrid(); felix@3854: } gernotbelger@9390: final Grid grid = new Grid(this.valueNames.size() + 1, this.columnNames.size() + 1); ingo@2521: gernotbelger@9390: for (int i = 0, n = this.columnNames.size(); i < n; i++) { gernotbelger@9390: final String columnName = this.columnNames.get(i); gernotbelger@9390: final Column col = this.columns.get(columnName); ingo@2521: gernotbelger@9390: this.selected.put(columnName, new ArrayList()); ingo@2521: gernotbelger@9390: grid.setWidget(0, i + 1, createLabel(this.MESSAGE.getString(columnName))); gernotbelger@9390: gernotbelger@9390: for (int j = 0, o = this.valueNames.size(); j < o; j++) { gernotbelger@9390: final String valueName = this.valueNames.get(j); gernotbelger@9390: final String value = col.getValue(valueName); ingo@2521: ingo@2521: if (i == 0) { gernotbelger@9390: grid.setWidget(j + 1, 0, createLabel(valueName)); ingo@2521: } ingo@2521: ingo@2521: if (value != null && value.length() > 0) { gernotbelger@9390: grid.setWidget(j + 1, i + 1, createCheckBox(columnName, value)); ingo@2521: } ingo@2521: } ingo@2521: } ingo@2521: ingo@2521: return grid; ingo@2521: } ingo@2521: felix@3854: /** Creates label with given text. */ gernotbelger@9390: protected Label createLabel(final String text) { gernotbelger@9390: final Label label = new Label(text); ingo@2521: label.setHeight(CELL_HEIGHT); ingo@2521: ingo@2521: return label; ingo@2521: } ingo@2521: felix@3854: /** Create Checkbox for column/value. */ felix@3854: protected Canvas createCheckBox(final String colName, final String value) { gernotbelger@9390: final CheckBox box = new CheckBox(); christian@4184: box.addClickHandler(new ClickHandler() { christian@4184: ingo@2521: @Override gernotbelger@9390: public void onClick(final ClickEvent event) { gernotbelger@9390: final Map> selection = getSelection(); ingo@2521: gernotbelger@9390: final List values = selection.get(colName); ingo@2521: if (values.indexOf(value) >= 0) { ingo@2521: values.remove(value); gernotbelger@9390: } else { ingo@2521: values.add(value); ingo@2521: } ingo@2521: } ingo@2521: }); ingo@2521: gernotbelger@9390: final Canvas c = new Canvas(); felix@3854: c.addChild(box); felix@3854: return c; ingo@2521: } ingo@2521: ingo@2521: public Map> getSelection() { gernotbelger@9390: if (this.listGrid == null) { gernotbelger@9390: return this.selected; felix@3982: } christian@4184: gernotbelger@9390: final ListGridRecord[] records = this.listGrid.getRecords(); gernotbelger@9390: final Map> result = new HashMap>(); gernotbelger@9390: for (final ListGridRecord record : records) { gernotbelger@9390: for (int i = 0, n = this.columnNames.size(); i < n; i++) { gernotbelger@9390: final String columnName = this.columnNames.get(i); felix@3982: if (Boolean.valueOf(record.getAttribute(columnName)) == true) { rrenkert@4627: if (result.containsKey(columnName)) { gernotbelger@9390: result.get(columnName).add(record.getAttribute(columnName + "-value")); gernotbelger@9390: } else { gernotbelger@9390: final List items = new ArrayList(); rrenkert@4627: items.add(record.getAttribute(columnName + "-value")); rrenkert@4627: result.put(columnName, items); rrenkert@4627: } felix@3982: } felix@3982: } felix@3982: } rrenkert@4627: return result; ingo@2521: } ingo@2521: } ingo@2521: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :