changeset 9076:22d8928895a1

dynamic input table epochSelect
author gernotbelger
date Tue, 22 May 2018 11:58:30 +0200
parents 89740fe82196
children 2b13de1b0897
files artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/LoadMultipleEpochSelectState.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/LoadMultipleYearSelectState.java artifacts/src/main/resources/messages.properties artifacts/src/main/resources/messages_de.properties gwt-client/src/main/java/org/dive4elements/river/client/client/ui/FromToTableHelperPanel.java gwt-client/src/main/java/org/dive4elements/river/client/client/ui/TableHelper.java gwt-client/src/main/java/org/dive4elements/river/client/client/ui/UIProviderFactory.java gwt-client/src/main/java/org/dive4elements/river/client/client/ui/sinfo/CollisionLoadEpochPanel.java gwt-client/src/main/java/org/dive4elements/river/client/client/ui/sinfo/CollisionLoadYearPanel.java
diffstat 9 files changed, 280 insertions(+), 318 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/LoadMultipleEpochSelectState.java	Fri May 18 17:42:34 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/LoadMultipleEpochSelectState.java	Tue May 22 11:58:30 2018 +0200
@@ -8,8 +8,20 @@
 
 package org.dive4elements.river.artifacts.sinfo.collision;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.log4j.Logger;
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.artifacts.common.utils.XMLUtils.ElementCreator;
+import org.dive4elements.river.artifacts.model.CollisionHibernateFactory;
+import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
+import org.dive4elements.river.artifacts.states.AddTableDataHelper;
 import org.dive4elements.river.artifacts.states.DefaultState;
+import org.dive4elements.river.model.sinfo.Collision;
+import org.w3c.dom.Element;
 
 public class LoadMultipleEpochSelectState extends DefaultState {
     /** The log used in this class. */
@@ -25,4 +37,38 @@
     protected String getUIProvider() {
         return "sinfo.collision.load_epoch_select";
     }
+
+    @Override
+    protected void appendItems(final Artifact artifact, final ElementCreator creator, final String name, final CallContext context, final Element select) {
+
+        try {
+            if ("epochs".equals(name)) {
+
+                final AddTableDataHelper helper = new AddTableDataHelper(creator, select, "year", context.getMeta());
+
+                helper.addColumn(0, "pinfrom", "40", "common.client.ui.from", "ICON", "CENTER", "from");
+                helper.addColumn(1, "pinto", "40", "common.client.ui.to", "ICON", "CENTER", "to");
+                helper.addColumn(2, "year", "60", "year", "INTEGER", "LEFT", null);
+
+                final CollisionAccess access = new CollisionAccess((SINFOArtifact) artifact); // Der River wurde im vorigen State bereits gesetzt
+
+                final List<Collision> collisions = CollisionHibernateFactory.getCollisionsByRiver(access.getRiver());
+                for (final Collision coll : collisions) { // TODO: Filter on Range (?)
+                    final Integer year = coll.getYear();
+                    final Map<String, String> row = new HashMap<>();
+                    row.put("year", year.toString()); // Nullpointer?
+                    try {
+                        helper.addRow(row);
+                    }
+                    catch (final Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+                helper.submitMapToXml();
+            }
+        }
+        catch (final IllegalArgumentException iae) {
+            iae.printStackTrace();
+        }
+    }
 }
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/LoadMultipleYearSelectState.java	Fri May 18 17:42:34 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/LoadMultipleYearSelectState.java	Tue May 22 11:58:30 2018 +0200
@@ -50,7 +50,7 @@
                 final AddTableDataHelper helper = new AddTableDataHelper(creator, select, "year", context.getMeta());
 
                 helper.addColumn(0, "pinfrom", "60", "common.client.ui.selection", "ICON", "CENTER", "from");
-                helper.addColumn(1, "year", "80", "year", "INTEGER", "RIGHT", null);
+                helper.addColumn(1, "year", "60", "year", "INTEGER", "LEFT", null);
 
                 final CollisionAccess access = new CollisionAccess((SINFOArtifact) artifact); // Der River wurde im vorigen State bereits gesetzt
 
--- a/artifacts/src/main/resources/messages.properties	Fri May 18 17:42:34 2018 +0200
+++ b/artifacts/src/main/resources/messages.properties	Tue May 22 11:58:30 2018 +0200
@@ -1120,4 +1120,6 @@
 help.state.bundu.vollmer.qs=${help.url}/OnlineHilfe/bunduierungsanalyse#help.state.bundu.vollmer.qs
 help.state.bundu.vollmer.compute=${help.url}/OnlineHilfe/bunduierungsanalyse#help.state.bundu.vollmer.compute
 
-common.client.ui.selection = Selection
\ No newline at end of file
+common.client.ui.selection = Selection
+common.client.ui.from = from
+common.client.ui.to = to
\ No newline at end of file
--- a/artifacts/src/main/resources/messages_de.properties	Fri May 18 17:42:34 2018 +0200
+++ b/artifacts/src/main/resources/messages_de.properties	Tue May 22 11:58:30 2018 +0200
@@ -1120,4 +1120,6 @@
 help.state.bundu.vollmer.qs=${help.url}/OnlineHilfe/bunduierungsanalyse#help.state.bundu.vollmer.qs
 help.state.bundu.vollmer.compute=${help.url}/OnlineHilfe/bunduierungsanalyse#help.state.bundu.vollmer.compute
 
-common.client.ui.selection = Auswahl
\ No newline at end of file
+common.client.ui.selection = Auswahl
+common.client.ui.from = von
+common.client.ui.to = bis
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/FromToTableHelperPanel.java	Tue May 22 11:58:30 2018 +0200
@@ -0,0 +1,205 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.dive4elements.river.client.client.FLYSConstants;
+import org.dive4elements.river.client.shared.model.Data;
+import org.dive4elements.river.client.shared.model.DataItem;
+import org.dive4elements.river.client.shared.model.DataList;
+import org.dive4elements.river.client.shared.model.MultiAttributeData;
+import org.dive4elements.river.client.shared.model.MultiDataItem;
+
+import com.google.gwt.core.client.GWT;
+import com.smartgwt.client.data.Record;
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
+import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+public class FromToTableHelperPanel {
+
+    public interface IColumnClickHandler {
+        void columnClicked(String value);
+    }
+
+    private enum PinType {
+        none, from, to
+    }
+
+    private final ListGrid table;
+
+    private final DataList dataList;
+
+    private final FLYSConstants flys;
+
+    private final List<String> keyColEntries = new ArrayList<String>();
+
+    public FromToTableHelperPanel(final DataList dataList, final String definitionStr, final FLYSConstants flys, final IColumnClickHandler fromHandler,
+            final IColumnClickHandler toHandler) {
+        this.flys = flys;
+        this.dataList = dataList;
+        this.table = new ListGrid();
+        this.table.setShowHeaderContextMenu(false);
+        this.table.setWidth100();
+        this.table.setShowRecordComponents(true);
+        this.table.setShowRecordComponentsByCell(true);
+        this.table.setHeight100();
+        this.table.setEmptyMessage(flys.empty_table());
+        this.table.setCanReorderFields(false);
+
+        final MultiAttributeData mData = findDefinition(definitionStr);
+        final Map<String, Map<String, String>> meta = mData.getMeta();
+
+        final Map<String, String> tableInfo = meta.get("meta_tableinfo");
+        final String keyColumnName = tableInfo.get("keycol");
+
+        final SortedMap<Integer, ListGridField> fields = new TreeMap<Integer, ListGridField>();
+
+        for (final Entry<String, Map<String, String>> entry : meta.entrySet()) {
+
+            final String colName = entry.getKey();
+            if (colName.startsWith("meta_"))
+                continue;
+
+            final Map<String, String> values = entry.getValue();
+
+            final int order = Integer.parseInt(values.get("order"));
+
+            final ListGridField field = createField(colName, keyColumnName, values, fromHandler, toHandler);
+
+            fields.put(order, field);
+        }
+
+        for (final DataItem dataItem : mData.opts) {
+            final MultiDataItem item = (MultiDataItem) dataItem;
+
+            final Map<String, String> valueMap = item.getValue();
+
+            final Record newRecord = new Record();
+            for (final Entry<String, String> entry : valueMap.entrySet()) {
+                final String key = entry.getKey();
+                final String value = entry.getValue();
+                newRecord.setAttribute(key, value);
+
+                if (key.equals(keyColumnName))
+                    this.keyColEntries.add(value);
+            }
+
+            this.table.addData(newRecord);
+        }
+
+        this.table.setFields(fields.values().toArray(new ListGridField[fields.size()]));
+    }
+
+    public Canvas getTable() {
+        return this.table;
+    }
+
+    private MultiAttributeData findDefinition(final String paranemterName) {
+
+        for (final Data data : this.dataList.getAll()) {
+
+            final String label = data.getLabel();
+            if (label.equals(paranemterName) && data instanceof MultiAttributeData)
+                return (MultiAttributeData) data;
+        }
+
+        return null;
+    }
+
+    private ListGridField createField(final String colName, final String keyColumnName, final Map<String, String> values, final IColumnClickHandler fromHandler,
+            final IColumnClickHandler toHandler) {
+
+        final String translation = getMeta(values, "translation", colName);
+
+        final ListGridField field = new ListGridField(colName, translation);
+
+        final String width = getMeta(values, "colwidth", "99");
+        field.setWidth(width);
+
+        final ListGridFieldType type = getMeta(values, "type", ListGridFieldType.TEXT, ListGridFieldType.class);
+        field.setType(type);
+
+        final Alignment alignment = getMeta(values, "alignment", Alignment.LEFT, Alignment.class);
+        field.setAlign(alignment);
+
+        final PinType pinType = getMeta(values, "pin", PinType.none, PinType.class);
+        switch (pinType) {
+        case from: {
+            makePin(keyColumnName, fromHandler, field, this.flys.markerGreen());
+        }
+            break;
+
+        case to: {
+            makePin(keyColumnName, toHandler, field, this.flys.markerRed());
+        }
+            break;
+        case none:
+        default:
+            break;
+        }
+
+        return field;
+    }
+
+    private void makePin(final String keyColumnName, final IColumnClickHandler handler, final ListGridField field, final String markerStr) {
+        final String baseUrl = GWT.getHostPageBaseURL();
+        field.setCellIcon(baseUrl + markerStr);
+        field.addRecordClickHandler(new RecordClickHandler() {
+            @Override
+            public void onRecordClick(final RecordClickEvent e) {
+                final Record r = e.getRecord();
+                handler.columnClicked(r.getAttribute(keyColumnName));
+            }
+        });
+    }
+
+    private String getMeta(final Map<String, String> values, final String key, final String defaultValue) {
+
+        final String value = values.get(key);
+        if (value == null || value.isEmpty())
+            return defaultValue;
+
+        return value;
+    }
+
+    private <TYPE extends Enum<TYPE>> TYPE getMeta(final Map<String, String> values, final String key, final TYPE defaultValue, final Class<TYPE> enumType) {
+
+        final String value = values.get(key);
+        if (value == null || value.isEmpty())
+            return defaultValue;
+
+        try {
+            return Enum.valueOf(enumType, value);
+        }
+        catch (final Exception e) {
+            e.printStackTrace();
+            return defaultValue;
+        }
+    }
+
+    public List<String> getKeycolEntries() {
+        return this.keyColEntries;
+    }
+}
\ No newline at end of file
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/TableHelper.java	Fri May 18 17:42:34 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,199 +0,0 @@
-/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
- * Software engineering by
- *  Björnsen Beratende Ingenieure GmbH
- *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-package org.dive4elements.river.client.client.ui;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import org.dive4elements.river.client.client.FLYSConstants;
-import org.dive4elements.river.client.shared.model.Data;
-import org.dive4elements.river.client.shared.model.DataItem;
-import org.dive4elements.river.client.shared.model.DataList;
-import org.dive4elements.river.client.shared.model.MultiAttributeData;
-import org.dive4elements.river.client.shared.model.MultiDataItem;
-
-import com.google.gwt.core.client.GWT;
-import com.smartgwt.client.data.Record;
-import com.smartgwt.client.types.Alignment;
-import com.smartgwt.client.types.ListGridFieldType;
-import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.grid.ListGrid;
-import com.smartgwt.client.widgets.grid.ListGridField;
-import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
-import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
-
-/**
- * @author Domenico Nardi Tironi
- *
- */
-public class TableHelper {
-
-    public interface IColumnClickHandler {
-        void columnClicked(String value);
-    }
-
-    private enum PinType {
-        none, from, to
-    }
-
-    private final ListGrid table;
-    private final DataList dataList;
-    final FLYSConstants flys;
-    private final List<String> keyColEntries = new ArrayList<String>();
-
-    public TableHelper(final DataList dataList, final String definitionStr, final FLYSConstants flys, final IColumnClickHandler fromHandler) {
-        this.flys = flys;
-        this.dataList = dataList;
-        this.table = new ListGrid();
-        this.table.setShowHeaderContextMenu(false);
-        this.table.setWidth100();
-        this.table.setShowRecordComponents(true);
-        this.table.setShowRecordComponentsByCell(true);
-        this.table.setHeight100();
-        this.table.setEmptyMessage(flys.empty_table());
-        this.table.setCanReorderFields(false);
-
-        final MultiAttributeData mData = findDefinition(definitionStr);
-        final Map<String, Map<String, String>> meta = mData.getMeta();
-
-        final Map<String, String> tableInfo = meta.get("meta_tableinfo");
-        final String keyColumnName = tableInfo.get("keycol");
-
-        final SortedMap<Integer, ListGridField> fields = new TreeMap<Integer, ListGridField>();
-
-        for (final Entry<String, Map<String, String>> entry : meta.entrySet()) {
-
-            final String colName = entry.getKey();
-            if (colName.startsWith("meta_"))
-                continue;
-
-            final Map<String, String> values = entry.getValue();
-
-            final int order = Integer.parseInt(values.get("order"));
-
-            final ListGridField field = createField(colName, keyColumnName, values, fromHandler);
-
-            fields.put(order, field);
-        }
-
-        for (final DataItem dataItem : mData.opts) {
-            final MultiDataItem item = (MultiDataItem) dataItem;
-
-            final Map<String, String> valueMap = item.getValue();
-            // final String columnName = mData.getLabel();
-            final Record newRecord = new Record();
-            for (final Entry<String, String> entry : valueMap.entrySet()) {
-                final String key = entry.getKey();
-                final String value = entry.getValue();
-                newRecord.setAttribute(key, value);
-
-                if (key.equals(keyColumnName))
-                    this.keyColEntries.add(value);
-            }
-
-            this.table.addData(newRecord);
-        }
-
-        this.table.setFields(fields.values().toArray(new ListGridField[fields.size()]));
-
-    }
-
-    public Canvas getTable() {
-        return this.table;
-    }
-
-    private MultiAttributeData findDefinition(final String paranemterName) {
-
-        for (final Data data : this.dataList.getAll()) {
-
-            final String label = data.getLabel();
-            if (label.equals(paranemterName) && data instanceof MultiAttributeData)
-                return (MultiAttributeData) data;
-        }
-
-        return null;
-    }
-
-    private ListGridField createField(final String colName, final String keyColumnName, final Map<String, String> values,
-            final IColumnClickHandler fromHandler) {
-
-        final String translation = getMeta(values, "translation", colName);
-
-        final ListGridField field = new ListGridField(colName, translation);
-
-        final String width = getMeta(values, "width", "99");
-        field.setWidth(width);
-
-        final ListGridFieldType type = getMeta(values, "type", ListGridFieldType.TEXT, ListGridFieldType.class);
-        field.setType(type);
-
-        final Alignment alignment = getMeta(values, "alignment", Alignment.LEFT, Alignment.class);
-        field.setAlign(alignment);
-
-        final PinType pinType = getMeta(values, "pin", PinType.none, PinType.class);
-        switch (pinType) {
-        case from: {
-            final String baseUrl = GWT.getHostPageBaseURL();
-            field.setCellIcon(baseUrl + this.flys.markerGreen());
-            field.addRecordClickHandler(new RecordClickHandler() {
-                @Override
-                public void onRecordClick(final RecordClickEvent e) {
-                    final Record r = e.getRecord();
-                    fromHandler.columnClicked(r.getAttribute(keyColumnName));
-                }
-            });
-        }
-            break;
-
-        case to:
-            break;
-
-        case none:
-        default:
-            break;
-        }
-
-        return field;
-    }
-
-    private String getMeta(final Map<String, String> values, final String key, final String defaultValue) {
-
-        final String value = values.get(key);
-        if (value == null || value.isEmpty())
-            return defaultValue;
-
-        return value;
-    }
-
-    private <TYPE extends Enum<TYPE>> TYPE getMeta(final Map<String, String> values, final String key, final TYPE defaultValue, final Class<TYPE> enumType) {
-
-        final String value = values.get(key);
-        if (value == null || value.isEmpty())
-            return defaultValue;
-
-        try {
-            return Enum.valueOf(enumType, value);
-        }
-        catch (final Exception e) {
-            e.printStackTrace();
-            return defaultValue;
-        }
-    }
-
-    public List<String> getKeycolEntries() {
-
-        return this.keyColEntries;
-    }
-
-}
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/UIProviderFactory.java	Fri May 18 17:42:34 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/UIProviderFactory.java	Tue May 22 11:58:30 2018 +0200
@@ -135,8 +135,8 @@
             return new DoubleInputPanel("percent");
         } else if (uiProvider.equals("parameter-matrix")) {
             return new ParameterMatrixPanel();
-        } else if (uiProvider.equals("minfo.bed.year_epoch")) {
-            return new RadioPanel(); // legacy
+        } else if (uiProvider.equals("minfo.bed.year_epoch")) {// legacy
+            return new RadioPanel();
         } else if (uiProvider.equals("radio_panel")) {
             return new RadioPanel();
         } else if (uiProvider.equals("bedquality_periods_select")) {
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/sinfo/CollisionLoadEpochPanel.java	Fri May 18 17:42:34 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/sinfo/CollisionLoadEpochPanel.java	Tue May 22 11:58:30 2018 +0200
@@ -11,25 +11,21 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.dive4elements.river.client.client.Config;
 import org.dive4elements.river.client.client.FLYSConstants;
 import org.dive4elements.river.client.client.services.SedimentLoadInfoService;
 import org.dive4elements.river.client.client.services.SedimentLoadInfoServiceAsync;
 import org.dive4elements.river.client.client.ui.AbstractUIProvider;
-import org.dive4elements.river.client.shared.model.ArtifactDescription;
+import org.dive4elements.river.client.client.ui.FromToTableHelperPanel;
+import org.dive4elements.river.client.client.ui.FromToTableHelperPanel.IColumnClickHandler;
 import org.dive4elements.river.client.shared.model.Data;
 import org.dive4elements.river.client.shared.model.DataItem;
 import org.dive4elements.river.client.shared.model.DataList;
 import org.dive4elements.river.client.shared.model.DefaultData;
 import org.dive4elements.river.client.shared.model.DefaultDataItem;
-import org.dive4elements.river.client.shared.model.SedimentLoadInfoObject;
-import org.dive4elements.river.client.shared.model.SedimentLoadInfoRecord;
 
 import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.smartgwt.client.data.Record;
 import com.smartgwt.client.types.ListGridFieldType;
-import com.smartgwt.client.util.SC;
 import com.smartgwt.client.widgets.Button;
 import com.smartgwt.client.widgets.Canvas;
 import com.smartgwt.client.widgets.Label;
@@ -55,9 +51,8 @@
     protected ListGrid elements;
     private TextItem start;
     private TextItem end;
-    private ListGrid sedLoadTable; // TODO: Datenquelle für Collision richtig wählen! Sediment komplett eliminieren
 
-    protected List<String> validYears;
+    protected List<String> validYears = new ArrayList<String>();
 
     public Canvas createWidget(final DataList data) {
         final HLayout input = new HLayout();
@@ -180,68 +175,33 @@
     @Override
     public Canvas create(final DataList data) {
         final VLayout layout = new VLayout();
-        final Canvas helper = createHelper();
-        this.helperContainer.addMember(helper);
-
         final Canvas submit = getNextButton();
         final Canvas widget = createWidget(data);
 
         layout.addMember(widget);
         layout.addMember(submit);
 
-        fetchSedimentLoadData();
+        final IColumnClickHandler fromHandler = createHandler(this.start);
+        final IColumnClickHandler toHandler = createHandler(this.end);
 
+        final FromToTableHelperPanel helper = new FromToTableHelperPanel(data, "epochs", this.MSG, fromHandler, toHandler);
+        this.validYears = helper.getKeycolEntries();
+        final Canvas table = helper.getTable();
+
+        this.helperContainer.addMember(table);
         return layout;
     }
 
-    private Canvas createHelper() {
-        this.sedLoadTable = new ListGrid();
-        this.sedLoadTable.setShowHeaderContextMenu(false);
-        this.sedLoadTable.setWidth100();
-        this.sedLoadTable.setShowRecordComponents(true);
-        this.sedLoadTable.setShowRecordComponentsByCell(true);
-        this.sedLoadTable.setHeight100();
-        this.sedLoadTable.setEmptyMessage(this.MSG.empty_table());
-        this.sedLoadTable.setCanReorderFields(false);
+    private IColumnClickHandler createHandler(final TextItem field) {
+        final IColumnClickHandler handler = new IColumnClickHandler() {
 
-        /* Input support pins */
-        final String baseUrl = GWT.getHostPageBaseURL();
-        final ListGridField pinFrom = new ListGridField("fromIcon", this.MESSAGES.from());
-        pinFrom.setWidth(30);
-        pinFrom.setType(ListGridFieldType.ICON);
-        pinFrom.setCellIcon(baseUrl + this.MESSAGES.markerGreen());
-
-        final ListGridField pinTo = new ListGridField("toIcon", this.MESSAGES.to());
-        pinTo.setType(ListGridFieldType.ICON);
-        pinTo.setWidth(30);
-        pinTo.setCellIcon(baseUrl + this.MESSAGES.markerRed());
-
-        pinFrom.addRecordClickHandler(new RecordClickHandler() {
             @Override
-            public void onRecordClick(final RecordClickEvent e) {
-                final Record r = e.getRecord();
-                CollisionLoadEpochPanel.this.start.setValue(r.getAttribute("date"));
-            }
-        });
-
-        pinTo.addRecordClickHandler(new RecordClickHandler() {
-            @Override
-            public void onRecordClick(final RecordClickEvent e) {
-                final Record r = e.getRecord();
-                CollisionLoadEpochPanel.this.end.setValue(r.getAttribute("date"));
+            public void columnClicked(final String value) {
+                field.setValue(value);
             }
-        });
-
-        final ListGridField date = new ListGridField("date", this.MSG.year());
-        date.setType(ListGridFieldType.TEXT);
-        date.setWidth(100);
+        };
 
-        final ListGridField descr = new ListGridField("description", this.MSG.description());
-        descr.setType(ListGridFieldType.TEXT);
-        descr.setWidth("*");
-
-        this.sedLoadTable.setFields(pinFrom, pinTo, date, descr);
-        return this.sedLoadTable;
+        return handler;
     }
 
     @Override
@@ -264,60 +224,6 @@
         return data.toArray(new Data[data.size()]);
     }
 
-    protected void fetchSedimentLoadData() {
-        final Config config = Config.getInstance();
-        final String locale = config.getLocale();
-
-        final ArtifactDescription adescr = this.artifact.getArtifactDescription();
-        final DataList[] data = adescr.getOldData();
-
-        final double[] km = this.artifact.getArtifactDescription().getKMRange();
-        final String river = this.artifact.getArtifactDescription().getRiver();
-
-        String sq_ti_id = "";
-        this.validYears = new ArrayList<String>(data.length);
-        for (final DataList element : data) {
-            final Data str = getData(element.getAll(), "sq_ti_id");
-            if (str != null) {
-                final DataItem[] strItems = str.getItems();
-                sq_ti_id = strItems[0].getStringValue();
-                break;
-            }
-        }
-
-        if (sq_ti_id.isEmpty()) {
-            GWT.log("Failed to find sq time interval id in data.");
-        }
-
-        this.sedLoadInfoService.getSedimentLoadInfo(locale, river, "single", km[0], km[1], sq_ti_id, new AsyncCallback<SedimentLoadInfoObject[]>() {
-            @Override
-            public void onFailure(final Throwable caught) {
-                GWT.log("Could not recieve sediment load informations.");
-                SC.warn(CollisionLoadEpochPanel.this.MSG.getString(caught.getMessage()));
-            }
-
-            @Override
-            public void onSuccess(final SedimentLoadInfoObject[] sedLoad) {
-                final int num = sedLoad != null ? sedLoad.length : 0;
-                GWT.log("Recieved " + num + " sediment load informations.");
-
-                if (num == 0) {
-                    return;
-                }
-
-                addSedimentLoadInfo(sedLoad);
-            }
-        });
-    }
-
-    protected void addSedimentLoadInfo(final SedimentLoadInfoObject[] sedLoad) {
-        for (final SedimentLoadInfoObject sl : sedLoad) {
-            final SedimentLoadInfoRecord rec = new SedimentLoadInfoRecord(sl);
-            this.sedLoadTable.addData(rec);
-            this.validYears.add(rec.getDate());
-        }
-    }
-
     /*
      * Validate the epoch input. We do this here and not in an overridden
      * validate method as we want to validate before an epoch is added
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/sinfo/CollisionLoadYearPanel.java	Fri May 18 17:42:34 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/sinfo/CollisionLoadYearPanel.java	Tue May 22 11:58:30 2018 +0200
@@ -13,8 +13,8 @@
 
 import org.dive4elements.river.client.client.FLYSConstants;
 import org.dive4elements.river.client.client.ui.AbstractUIProvider;
-import org.dive4elements.river.client.client.ui.TableHelper;
-import org.dive4elements.river.client.client.ui.TableHelper.IColumnClickHandler;
+import org.dive4elements.river.client.client.ui.FromToTableHelperPanel;
+import org.dive4elements.river.client.client.ui.FromToTableHelperPanel.IColumnClickHandler;
 import org.dive4elements.river.client.shared.model.Data;
 import org.dive4elements.river.client.shared.model.DataItem;
 import org.dive4elements.river.client.shared.model.DataList;
@@ -85,7 +85,7 @@
             }
         };
 
-        final TableHelper helper = new TableHelper(data, "years", this.MSG, fromHandler);
+        final FromToTableHelperPanel helper = new FromToTableHelperPanel(data, "years", this.MSG, fromHandler, null);
         final Canvas table = helper.getTable();
         this.validYears = helper.getKeycolEntries();
 
@@ -110,7 +110,7 @@
         form.setNumCols(4);
         this.yearsItem = new TextItem(this.MSG.years());
         this.yearsItem.setValidators(new IsIntegerValidator());
-        form.setFields(this.yearsItem);
+        form.setFields(this.yearsItem); // TODO: move to helper
 
         layout.addMember(title);
         layout.addMember(form);

http://dive4elements.wald.intevation.org