Mercurial > dive4elements > river
view gwt-client/src/main/java/org/dive4elements/river/client/client/ui/AbstractWQAdaptedInputPanel.java @ 9289:fe207a8699f7
Changed optics of groups in module selection
author | gernotbelger |
---|---|
date | Tue, 24 Jul 2018 10:51:09 +0200 |
parents | 82c67b859aa7 |
children | 6174daaf5e56 |
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde * Software engineering by Intevation GmbH * * 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.HashMap; import java.util.List; import java.util.Map; import org.dive4elements.river.client.client.Config; import org.dive4elements.river.client.client.FLYSConstants; import org.dive4elements.river.client.client.ui.wq.QDTable; import org.dive4elements.river.client.client.ui.wq.WTable; import org.dive4elements.river.client.shared.model.ArtifactDescription; 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.WQDataItem; import org.dive4elements.river.client.shared.model.WQInfoObject; import org.dive4elements.river.client.shared.model.WQInfoRecord; 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.util.SC; import com.smartgwt.client.widgets.Canvas; import com.smartgwt.client.widgets.Label; import com.smartgwt.client.widgets.form.DynamicForm; import com.smartgwt.client.widgets.form.fields.events.BlurEvent; import com.smartgwt.client.widgets.form.fields.events.BlurHandler; import com.smartgwt.client.widgets.form.fields.events.ChangeEvent; import com.smartgwt.client.widgets.form.fields.events.ChangeHandler; import com.smartgwt.client.widgets.grid.events.CellClickEvent; import com.smartgwt.client.widgets.grid.events.CellClickHandler; import com.smartgwt.client.widgets.layout.HLayout; import com.smartgwt.client.widgets.layout.VLayout; import com.smartgwt.client.widgets.tab.TabSet; /** * This UIProvider creates a widget to enter W or Q data for discharge * longitudinal section computations. * * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> */ abstract public class AbstractWQAdaptedInputPanel extends AbstractUIProvider implements ChangeHandler, BlurHandler { private static final long serialVersionUID = -3218827566805476423L; /** The message class that provides i18n strings. */ protected FLYSConstants MSG = GWT.create(FLYSConstants.class); protected static final int ROW_HEIGHT = 20; /** List of QDTables in inputhelper section. */ protected List<QDTable> qdTables; private static final String GAUGE_SEPARATOR = ":"; private static final String GAUGE_PART_SEPARATOR = ";"; private static final String VALUE_SEPARATOR = ","; /** Stores the input panels related to their keys. */ protected Map<String, DoubleArrayPanel> wqranges; /** [startkm,endkm] per gauge in selected range. */ protected List<Double[]> gaugeRanges; /** Stores the min/max values for each q range (gauge). */ protected Map<String, double[]> qranges; /** The RadioGroupItem that determines the w/q input mode. */ protected DynamicForm modes; /** List of doubleArrayPanels shown. */ protected final ArrayList<DoubleArrayPanel> doubleArrayPanels = new ArrayList<DoubleArrayPanel>(); /** List of wTables in inputhelper section. */ protected List<WTable> wTables; /** Tabs in inputhelper area. */ protected TabSet tabs; public AbstractWQAdaptedInputPanel() { this.wqranges = new HashMap<String, DoubleArrayPanel>(); this.qranges = new HashMap<String, double[]>(); this.wTables = new ArrayList<WTable>(); this.qdTables = new ArrayList<QDTable>(); } /** Inits the helper panel. */ // TODO duplicate in WQInputPanel protected void initHelperPanel() { this.tabs = new TabSet(); this.tabs.setWidth100(); this.tabs.setHeight100(); // For each gauge, add two tabs with helper tables. createTabs(); this.helperContainer.addMember(this.tabs); } /** Create labels, canvasses, layouts. */ @Override public Canvas create(final DataList data) { beforeCreate(data); readGaugeRanges(data); initHelperPanel(); final Canvas submit = getNextButton(); final Canvas widget = createWidget(data); final Label label = new Label(this.MSG.wqadaptedTitle()); label.setHeight(25); final VLayout layout = new VLayout(); layout.setMembersMargin(10); layout.setWidth(350); layout.addMember(label); layout.addMember(widget); layout.addMember(submit); fetchWQData(); initTableListeners(); afterCreate(); return layout; } protected abstract void createTabs(); protected abstract void beforeCreate(final DataList data); protected abstract void afterCreate(); /** * Initializes the listeners of the WQD tables. */ // TODO dupe from WQInputPanel protected void initTableListeners() { int i = 0; for (final QDTable qdTable : this.qdTables) { // Register listener such that values are filled in on click. final QDTable table = qdTable; final int fi = i; final CellClickHandler handler = new CellClickHandler() { @Override public void onCellClick(final CellClickEvent e) { if (table.isDisabled() || table.isLocked()) { return; } final Record r = e.getRecord(); final double val = r.getAttributeAsDouble("value"); AbstractWQAdaptedInputPanel.this.doubleArrayPanels.get(fi).setValues(new double[] { val }); // If a named value for first gauge is chosen, // try to find and set // the values to the other panels too. if (fi == 0) { final String valueName = r.getAttribute("name"); int oi = 0; // TODO instead of oi use random access. for (final QDTable otherQDTable : AbstractWQAdaptedInputPanel.this.qdTables) { if (oi == 0) { oi++; continue; } final Double value = otherQDTable.findRecordValue(valueName); if (value == null) { SC.warn(AbstractWQAdaptedInputPanel.this.MSG.noMainValueAtGauge()); } else { AbstractWQAdaptedInputPanel.this.doubleArrayPanels.get(oi).setValues(new double[] { value }); } oi++; } } else { // Focus next. if (fi != AbstractWQAdaptedInputPanel.this.doubleArrayPanels.size() - 1) { AbstractWQAdaptedInputPanel.this.doubleArrayPanels.get(fi + 1).focusInItem(1); } } } }; qdTable.addCellClickHandler(handler); i++; } i = 0; for (final WTable wTable : this.wTables) { // Register listener such that values are filled in on click. final WTable table = wTable; final int fi = i; final CellClickHandler handler = new CellClickHandler() { @Override public void onCellClick(final CellClickEvent e) { if (table.isDisabled()) { return; } final Record r = e.getRecord(); final double val = r.getAttributeAsDouble("value"); AbstractWQAdaptedInputPanel.this.doubleArrayPanels.get(fi).setValues(new double[] { val }); // If a named value for first gauge is chosen, // try to find and set // the values to the other panels too. if (fi == 0) { final String valueName = r.getAttribute("name"); int oi = 0; // TODO instead of oi use random access. for (final WTable otherWTable : AbstractWQAdaptedInputPanel.this.wTables) { if (oi == 0) { oi++; continue; } final Double value = otherWTable.findRecordValue(valueName); if (value == null) { // TODO: afterwards it freaks out SC.warn(AbstractWQAdaptedInputPanel.this.MSG.noMainValueAtGauge()); } else { AbstractWQAdaptedInputPanel.this.doubleArrayPanels.get(oi).setValues(new double[] { value }); } oi++; } } else { // Focus next. if (fi != AbstractWQAdaptedInputPanel.this.doubleArrayPanels.size() - 1) { AbstractWQAdaptedInputPanel.this.doubleArrayPanels.get(fi + 1).focusInItem(1); } } } }; wTable.addCellClickHandler(handler); i++; } } /** Create area showing previously entered w or q data. */ protected final Canvas createOldWQValues(final Data wqData, final boolean isQ) { final VLayout layout = new VLayout(); if (wqData != null) { final DataItem item = wqData.getItems()[0]; final String value = item.getStringValue(); final String[] gauges = value.split(GAUGE_SEPARATOR); final String unit = isQ ? "m³/s" : "cm"; for (final String gauge : gauges) { final HLayout h = new HLayout(); final String[] parts = gauge.split(GAUGE_PART_SEPARATOR); final String[] values = parts[3].split(VALUE_SEPARATOR); final Label l = new Label(parts[2] + ": "); final StringBuilder sb = new StringBuilder(); boolean first = true; for (final String v : values) { if (!first) { sb.append(", "); } sb.append(v); sb.append(" "); sb.append(unit); first = false; } final Label v = new Label(sb.toString()); l.setWidth(65); v.setWidth(65); h.addMember(l); h.addMember(v); layout.addMember(h); } } return layout; } protected void initUserWQValues(final DataList dataList) { final List<Data> allData = dataList.getAll(); final Data dDef = getData(allData, "wq_values"); final DataItem def = dDef != null ? dDef.getDefault() : null; final String value = def != null ? def.getStringValue() : null; if (value == null || value.length() == 0) { return; } final String[] lines = value.split(GAUGE_SEPARATOR); if (lines == null || lines.length == 0) { return; } for (final String line : lines) { final String[] cols = line.split(GAUGE_PART_SEPARATOR); // final String title = createLineTitle(line); if (cols == null || cols.length < 3) { continue; } final String[] strValues = cols[2].split(VALUE_SEPARATOR); final double[] values = new double[strValues.length]; int idx = 0; for (final String strValue : strValues) { try { values[idx++] = Double.valueOf(strValue); } catch (final NumberFormatException nfe) { // do nothing } } final String key = cols[0] + GAUGE_PART_SEPARATOR + cols[1]; final DoubleArrayPanel dap = this.wqranges.get(key); if (dap == null) { continue; } dap.setValues(values); } } /** Populate Gauge Ranges array. */ protected final void readGaugeRanges(final DataList dataList) { final List<WQDataItem> items = getWQItems(dataList); this.gaugeRanges = new ArrayList<Double[]>(); for (final DataItem item : items) { if (item instanceof WQDataItem) { final String[] startEndKm = item.getLabel().split(";"); final Double[] kvp = new Double[] { Double.parseDouble(startEndKm[0]), Double.parseDouble(startEndKm[1]) }; this.gaugeRanges.add(kvp); } } } /** Get items which are not WQ_MODE. */ protected List<WQDataItem> getWQItems(final DataList dataList) { final List<Data> data = dataList.getAll(); final List<WQDataItem> results = new ArrayList<WQDataItem>(); for (final Data d : data) { final DataItem[] items = d.getItems(); if (items != null) { for (final Object item : items) { if (item instanceof WQDataItem) results.add((WQDataItem) item); } } } return results; } protected final Data getWQValues(final String dataKey) { String wqvalue = null; for (final Map.Entry<String, DoubleArrayPanel> entry : this.wqranges.entrySet()) { final String key = entry.getKey(); final DoubleArrayPanel dap = entry.getValue(); final String label = dap.getItemTitle(); final double[] values = dap.getInputValues(); if (wqvalue == null) { wqvalue = createValueString(key + ";" + label, values); } else { wqvalue += GAUGE_SEPARATOR + createValueString(key + ";" + label, values); } } final DataItem valueItem = new DefaultDataItem(dataKey, dataKey, wqvalue); final Data values = new DefaultData(dataKey, null, null, new DataItem[] { valueItem }); return values; } protected String createValueString(final String key, final double[] values) { final StringBuilder sb = new StringBuilder(); boolean first = true; for (final double value : values) { if (!first) { sb.append(","); } sb.append(Double.toString(value)); first = false; } return key + ";" + sb.toString(); } @Override public void onChange(final ChangeEvent event) { // TODO IMPLEMENT ME } /** Store the currently focussed DoubleArrayPanel and focus helper tab. */ @Override public final void onBlur(final BlurEvent event) { final DoubleArrayPanel dap = (DoubleArrayPanel) event.getForm(); dap.validateForm(event.getItem()); } /** Get the WQD data from service and stuck them up that tables. */ protected void fetchWQData() { final Config config = Config.getInstance(); final String locale = config.getLocale(); final ArtifactDescription adescr = this.artifact.getArtifactDescription(); final DataList[] data = adescr.getOldData(); final String river = getRiverName(data); int i = 0; // Get Data for respective gauge. for (final Double[] range : this.gaugeRanges) { // Gauge ranges overlap, move start and end a bit closer // to each other. final double rDiff = (range[1] - range[0]) / 10d; final int fi = i; final AsyncCallback<WQInfoObject[]> cb = new AsyncCallback<WQInfoObject[]>() { @Override public void onFailure(final Throwable caught) { GWT.log("Could not recieve wq informations."); SC.warn(caught.getMessage()); } @Override public void onSuccess(final WQInfoObject[] wqi) { final int num = wqi != null ? wqi.length : 0; GWT.log("Received " + num + " wq informations (" + fi + "."); if (num == 0) { return; } addWQInfo(wqi, fi); } }; callMainValuesService(locale, river, range[0] + rDiff, range[1] - rDiff, cb); i++; } } protected abstract void callMainValuesService(String locale, String river, double start, double end, AsyncCallback<WQInfoObject[]> cb); /** Add Info to helper table for gauge at index gaugeIdx. */ private void addWQInfo(final WQInfoObject[] wqi, final int gaugeIdx) { for (final WQInfoObject wi : wqi) { final WQInfoRecord rec = new WQInfoRecord(wi); if (wi.getType().equals("W")) { if (gaugeIdx < this.wTables.size()) this.wTables.get(gaugeIdx).addData(rec); } else if (wi.getType().equals("Q")) { if (gaugeIdx < this.qdTables.size()) this.qdTables.get(gaugeIdx).addData(rec); } } } /** * Returns the name of the selected river. * * @param data * The DataList with all data. * * @return the name of the current river. */ protected String getRiverName(final DataList[] data) { final ArtifactDescription adesc = this.artifact.getArtifactDescription(); return adesc.getRiver(); } abstract protected Canvas createWidget(final DataList dataList); }