Mercurial > dive4elements > river
view gwt-client/src/main/java/org/dive4elements/river/client/client/ui/WQAdaptedInputPanel.java @ 9698:812a6a3eaaf5
another try
author | dnt_bjoernsen <d.tironi@bjoernsen.de> |
---|---|
date | Wed, 20 Jan 2021 17:19:59 +0100 |
parents | 43c975f8ab92 |
children |
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.LinkedHashMap; import java.util.List; import java.util.Map; import org.dive4elements.river.client.client.Config; import org.dive4elements.river.client.client.services.WQInfoService; import org.dive4elements.river.client.client.services.WQInfoServiceAsync; 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 com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.NumberFormat; import com.google.gwt.user.client.rpc.AsyncCallback; import com.smartgwt.client.types.TitleOrientation; import com.smartgwt.client.types.VerticalAlignment; 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.RadioGroupItem; import com.smartgwt.client.widgets.form.fields.events.ChangeEvent; import com.smartgwt.client.widgets.form.fields.events.ChangeHandler; import com.smartgwt.client.widgets.form.fields.events.FocusEvent; import com.smartgwt.client.widgets.form.fields.events.FocusHandler; import com.smartgwt.client.widgets.layout.HLayout; import com.smartgwt.client.widgets.layout.VLayout; import com.smartgwt.client.widgets.tab.Tab; /** * 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> */ public class WQAdaptedInputPanel extends AbstractWQAdaptedInputPanel implements FocusHandler { private static final long serialVersionUID = -3218827566805476423L; private static final String FIELD_WQ_MODE = "wq_isq"; private static final String FIELD_WQ_W = "W"; private static final String FIELD_WQ_Q = "Q"; /** Stores the min/max values for each w range (gauge). */ private final Map<String, double[]> wranges = new HashMap<String, double[]>(); /** Service to fetch W/Q MainValues. */ private final WQInfoServiceAsync wqInfoService = GWT.create(WQInfoService.class); /** The currently focussed Input element. */ private DoubleArrayPanel itemWithFocus; private void enableWTabs() { for (int i = 0; i < this.doubleArrayPanels.size(); i++) { this.tabs.disableTab(2 * i); this.tabs.enableTab(2 * i + 1); } } private void enableQTabs() { for (int i = 0; i < this.doubleArrayPanels.size(); i++) { this.tabs.enableTab(2 * i); this.tabs.disableTab(2 * i + 1); } } /** * Create radio button for switching w and q input. * Radiobutton-change also triggers helper panel tab selection. */ private final Canvas createMode(final DataList dataList) { final RadioGroupItem wq = new RadioGroupItem(FIELD_WQ_MODE); wq.setShowTitle(false); wq.setVertical(false); wq.setWidth(200); final LinkedHashMap<String, String> wqValues = new LinkedHashMap<String, String>(); wqValues.put(FIELD_WQ_W, this.MSG.wqW()); wqValues.put(WQAdaptedInputPanel.FIELD_WQ_Q, this.MSG.wqQatGauge()); wq.setValueMap(wqValues); this.modes = new DynamicForm(); this.modes.setFields(wq); this.modes.setWidth(200); wq.addChangeHandler(new ChangeHandler() { @Override public void onChange(final ChangeEvent e) { final DynamicForm form = e.getForm(); if (form.getValueAsString(FIELD_WQ_MODE).contains("Q")) { WQAdaptedInputPanel.this.tabs.selectTab(0); enableQTabs(); } else { WQAdaptedInputPanel.this.tabs.selectTab(1); enableWTabs(); } } }); final LinkedHashMap<String, String> initial = new LinkedHashMap<String, String>(); initial.put(FIELD_WQ_MODE, this.FIELD_WQ_Q); this.modes.setValues(initial); this.tabs.selectTab(1); return this.modes; } @Override protected void createTabs() { for (int i = 0; i < this.gaugeRanges.size(); i++) { // Later the tabs title will get adjusted to include gauges name. // TODO the tabs title becomes rather long through that (i18n). final Tab wTab = new Tab(this.MSG.wq_table_w()); final WTable wTable = new WTable(); this.wTables.add(wTable); wTable.showSelect(); wTab.setPane(wTable); final Tab qTab = new Tab(this.MSG.wq_table_q()); final QDTable qdTable = new QDTable(); this.qdTables.add(qdTable); qTab.setPane(qdTable); qdTable.showSelect(); this.tabs.addTab(wTab, i * 2 + 0); this.tabs.addTab(qTab, i * 2 + 1); } // Defaults at "Q", first input field. this.tabs.selectTab(0); enableQTabs(); } @Override protected void beforeCreate(final DataList data) { } @Override protected void afterCreate() { // We actually want the first Q tab to be selected and all // Q tabs to be enabled. I sense a bug in TabSet here, as // the code in the W/Q radiogroup-changehandler behaves // exactly vice versa (enabling Q, selecting tab 0). enableWTabs(); this.tabs.selectTab(1); } @Override protected Canvas createWidget(final DataList dataList) { final VLayout layout = new VLayout(); final Canvas mode = createMode(dataList); final Canvas list = createList(dataList); final List<WQDataItem> items = getWQItems(dataList); final int listHeight = ROW_HEIGHT * items.size(); mode.setHeight(25); mode.setWidth(200); layout.addMember(mode); layout.addMember(list); layout.setHeight(25 + listHeight); layout.setWidth(350); initUserDefaults(dataList); return layout; } private void initUserDefaults(final DataList dataList) { initUserWQValues(dataList); initUserWQMode(dataList); } private void initUserWQMode(final DataList dataList) { final List<Data> allData = dataList.getAll(); final Data dDef = getData(allData, "wq_mode"); final DataItem def = dDef != null ? dDef.getDefault() : null; final String value = def != null ? def.getStringValue() : null; if (value != null && value.equals(FIELD_WQ_W)) { this.modes.setValue(FIELD_WQ_MODE, FIELD_WQ_W); } else { this.modes.setValue(FIELD_WQ_MODE, FIELD_WQ_Q); } } private Canvas createList(final DataList dataList) { final VLayout layout = new VLayout(); final List<WQDataItem> items = getWQItems(dataList); int i = 0; for (final DataItem item : items) { if (item instanceof WQDataItem) { final String title = item.getLabel(); // of form: 70.5;112.0 final String label = item.getStringValue(); // Rename W and Q tab to include gauges name. this.tabs.getTab(i * 2).setTitle(this.tabs.getTab(i * 2).getTitle() + " (" + label + ")"); this.tabs.getTab(i * 2 + 1).setTitle(this.tabs.getTab(i * 2 + 1).getTitle() + " (" + label + ")"); final DoubleArrayPanel dap = new DoubleArrayPanel(label, null, this, this, TitleOrientation.LEFT); this.wqranges.put(title, dap); this.doubleArrayPanels.add(dap); if (item instanceof WQDataItem) { final WQDataItem wq = (WQDataItem) item; final double[] mmQ = wq.getQRange(); final double[] mmW = wq.getWRange(); this.qranges.put(title, mmQ); this.wranges.put(title, mmW); } layout.addMember(dap); i++; } } layout.setHeight(items.size() * ROW_HEIGHT); return layout; } @Override public Canvas createOld(final DataList dataList) { // TODO: OVERRIDE final List<Data> all = dataList.getAll(); final Data wqData = getData(all, "wq_values"); final Data wqMode = getData(all, "wq_isq"); final boolean isQ = wqMode.getItems()[0].getStringValue().equals("true"); final Canvas back = getBackButton(dataList.getState()); final HLayout valLayout = new HLayout(); final HLayout modeLayout = new HLayout(); final VLayout vlayout = new VLayout(); final Label wqLabel = new Label(dataList.getLabel()); final Label modeLabel = new Label(""); wqLabel.setValign(VerticalAlignment.TOP); wqLabel.setWidth(200); wqLabel.setHeight(25); modeLabel.setHeight(25); modeLabel.setWidth(200); valLayout.addMember(wqLabel); valLayout.addMember(createOldWQValues(wqData, isQ)); valLayout.addMember(back); modeLayout.addMember(modeLabel); vlayout.addMember(valLayout); vlayout.addMember(modeLayout); return vlayout; } @Override public List<String> validate() { if (isWMode()) { return validateW(); } else { return validateQ(); } } private boolean isWMode() { final String mode = (String) this.modes.getValue(FIELD_WQ_MODE); return FIELD_WQ_W.equals(mode); } protected List<String> validateRange(final Map<String, double[]> ranges) { final List<String> errors = new ArrayList<String>(); final NumberFormat nf = NumberFormat.getDecimalFormat(); for (final Map.Entry<String, DoubleArrayPanel> entry : this.wqranges.entrySet()) { final String key = entry.getKey(); final DoubleArrayPanel dap = entry.getValue(); if (!dap.validateForm()) { errors.add(this.MSG.error_invalid_double_value()); return errors; } final double[] mm = ranges.get(key); if (mm == null) { SC.warn(this.MSG.error_read_minmax_values()); continue; } final double[] values = dap.getInputValues(); final double[] good = new double[values.length]; int idx = 0; final List<String> tmpErrors = new ArrayList<String>(); for (final double value : values) { if (value < mm[0] || value > mm[1]) { String tmp = this.MSG.error_validate_range(); tmp = tmp.replace("$1", nf.format(value)); tmp = tmp.replace("$2", nf.format(mm[0])); tmp = tmp.replace("$3", nf.format(mm[1])); tmpErrors.add(tmp); } else { good[idx++] = value; } } final double[] justGood = new double[idx]; for (int i = 0; i < justGood.length; i++) { justGood[i] = good[i]; } if (!tmpErrors.isEmpty()) { dap.setValues(justGood); errors.addAll(tmpErrors); } } return errors; } private Data getWQMode() { final String wqMode = this.modes.getValueAsString(FIELD_WQ_MODE); String value = "false"; if (wqMode.equals("Q")) { value = "true"; } final DataItem item = new DefaultDataItem("wq_isq", "wq_isq", value); final Data mode = new DefaultData("wq_isq", null, null, new DataItem[] { item }); return mode; } @Override public Data[] getData() { final Data mode = getWQMode(); final Data values = getWQValues("wq_values"); return new Data[] { mode, values }; } private List<String> validateW() { return validateRange(this.wranges); } private List<String> validateQ() { return validateRange(this.qranges); } @Override public void onFocus(final FocusEvent event) { this.itemWithFocus = (DoubleArrayPanel) event.getForm(); // Switch to respective tab. // TODO which makes a focus loss final int inputIndex = this.doubleArrayPanels.indexOf(this.itemWithFocus); this.tabs.selectTab(inputIndex * 2 + (isWMode() ? 0 : 1)); } protected void callMainValuesService(final String locale, final String river, final double start, final double end, final AsyncCallback<WQInfoObject[]> cb) { this.wqInfoService.getWQInfo(locale, river, start, end, cb); } @Override 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; // TODO: HIER MÜSSTE EIN SERVICE HIN, der den größten gemeinsamen zeitlichen Bereich der daily_discharge_values aller // Pegel ermittelt 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, null); } }; callMainValuesService(locale, river, range[0] + rDiff, range[1] - rDiff, cb); i++; } } } @Override protected String getWQInfoMsg() { return null; } }