Mercurial > dive4elements > river
view gwt-client/src/main/java/org/dive4elements/river/client/client/ui/bundu/BunduWstWQPanel.java @ 9709:b74f817435fe
comment removed
author | dnt_bjoernsen <d.tironi@bjoernsen.de> |
---|---|
date | Wed, 27 Jan 2021 11:47:38 +0100 |
parents | 7369d6ae3f87 |
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.bundu; import java.util.ArrayList; import java.util.Date; 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.DynamicMainValuesService; import org.dive4elements.river.client.client.services.DynamicMainValuesServiceAsync; import org.dive4elements.river.client.client.services.DynamicMainValuesTimeRangeDeterminationService; import org.dive4elements.river.client.client.services.DynamicMainValuesTimeRangeDeterminationServiceAsync; import org.dive4elements.river.client.client.ui.AbstractWQAdaptedInputPanel; import org.dive4elements.river.client.client.ui.DoubleArrayPanel; import org.dive4elements.river.client.client.ui.wq.QDTable; 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.GaugeInfoObject; import org.dive4elements.river.client.shared.model.GaugeInfoResult; 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.types.Visibility; 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.TextItem; 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.form.validator.IntegerRangeValidator; 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 * Fixation analysis * * @author <a href="mailto:aheinecke@intevation.de">Andre Heinecke</a> */ public class BunduWstWQPanel extends AbstractWQAdaptedInputPanel implements FocusHandler { private static final long serialVersionUID = -1L; private static enum mode { Q, UD } /** The currently focussed Input element. */ private DoubleArrayPanel itemWithFocus; /** Service to fetch W/Q MainValues. */ private final DynamicMainValuesServiceAsync mainValueService = GWT.create(DynamicMainValuesService.class); private final DynamicMainValuesTimeRangeDeterminationServiceAsync serviceForTime = GWT.create(DynamicMainValuesTimeRangeDeterminationService.class); private final RadioGroupItem radiogroup = new RadioGroupItem(); private int bezugsjahr = 0; private int qSeriesLength = 0; private Canvas list; private final DynamicForm udForm = new DynamicForm(); private final TextItem udInputItem = new TextItem(); @Override protected void beforeCreate(final DataList data) { for (final Data container : data.getAll()) { final DataItem[] items = container.getItems(); if (items != null) { for (final DataItem item : items) { if ("ignore_bezugsjahr".equals(item.getLabel())) { this.bezugsjahr = Integer.valueOf(item.getStringValue()); } else if ("ignore_q_series_length".equals(item.getLabel())) { this.qSeriesLength = Integer.valueOf(item.getStringValue()); } } } } } @Override protected void afterCreate() { } @Override protected Canvas createWidget(final DataList dataList) { final VLayout layout = new VLayout(); final Canvas mode = createMode(dataList); this.list = createList(dataList); this.udInputItem.setShowTitle(false); this.udInputItem.setWidth(120); final IntegerRangeValidator validator = new IntegerRangeValidator(); validator.setMax(364); validator.setMin(0); validator.setErrorMessage(this.MSG.bundu_bezugswst_validation_range()); this.udInputItem.setRequiredMessage(this.MSG.bundu_bezugswst_validation_range()); this.udInputItem.setValidators(validator); this.udInputItem.setValidateOnChange(true); this.udForm.setFields(this.udInputItem); final List<WQDataItem> items = getWQItems(dataList); final int listHeight = ROW_HEIGHT * items.size(); mode.setHeight(25); mode.setWidth(200); layout.addMember(mode); layout.addMember(this.list); layout.addMember(this.udForm); layout.setHeight(25 + listHeight); layout.setWidth(350); enableQ(); return layout; } /** * Create radio button for switching * Radiobutton-change also triggers helper panel tab selection. */ private Canvas createMode(final DataList dataList) { this.radiogroup.setShowTitle(false); this.radiogroup.setVertical(false); this.radiogroup.setWidth(200); final LinkedHashMap<String, String> wqValues = new LinkedHashMap<String, String>(); wqValues.put(String.valueOf(mode.Q), this.MSG.wqQatGauge()); wqValues.put(String.valueOf(mode.UD), this.MSG.bundu_bezugswst_mode_ud()); this.radiogroup.setValueMap(wqValues); this.radiogroup.setValue(String.valueOf(mode.Q)); this.modes = new DynamicForm(); this.modes.setFields(this.radiogroup); this.modes.setWidth(200); this.radiogroup.addChangeHandler(new ChangeHandler() { @Override public void onChange(final ChangeEvent e) { final String value = e.getValue().toString(); if (value.equals(String.valueOf(mode.UD))) { enableUD(); } else if (value.equals(String.valueOf(mode.Q))) { enableQ(); } } }); this.radiogroup.setCanEdit(false); return this.modes; } private void enableUD() { BunduWstWQPanel.this.list.setVisibility(Visibility.HIDDEN); BunduWstWQPanel.this.udForm.setVisibility(Visibility.VISIBLE); BunduWstWQPanel.this.tabs.disable(); } private void enableQ() { BunduWstWQPanel.this.list.setVisibility(Visibility.VISIBLE); BunduWstWQPanel.this.udForm.setVisibility(Visibility.HIDDEN); BunduWstWQPanel.this.tabs.enable(); } private final String getMode() { return (String) this.radiogroup.getValue(); } @Override public Data[] getData() { final List<Data> dataList = new ArrayList<Data>(); final String modeStr = getMode(); final DataItem item = new DefaultDataItem("bundu.wst.mode", "bundu.wst.mode", modeStr); final Data modeData = new DefaultData("bundu.wst.mode", null, null, new DataItem[] { item }); dataList.add(modeData); if (modeStr.equals(mode.Q.toString())) { dataList.add(getWQValues("wq_values")); } else if (modeStr.equals(mode.UD.toString())) { final String udValue = this.udInputItem.getValueAsString(); // in validate findet der int-check statt; er verhindert ein weitergehen, falls der Wert // nicht int-kompatibel ist final DataItem itemV = new DefaultDataItem("bundu.wst.ud_value", "bundu.wst.ud_value", udValue); dataList.add(new DefaultData("bundu.wst.ud_value", null, null, new DataItem[] { itemV })); dataList.add(getWQValuesForUD("wq_values", udValue)); } return dataList.toArray(new Data[dataList.size()]); } @Override protected void createTabs() { for (int i = 0; i < this.gaugeRanges.size(); i++) { final Tab qTab = new Tab(this.MSG.wq_table_q()); qTab.setPaneMargin(0); final QDTable qdTable = new QDTable(); this.qdTables.add(qdTable); qdTable.showSelect(); qTab.setPane(qdTable); this.tabs.addTab(qTab, i); } this.tabs.setSelectedTab(0); } 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(); final String label = item.getStringValue(); this.tabs.getTab(i).setTitle(this.tabs.getTab(i).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(); this.qranges.put(title, mmQ); } layout.addMember(dap); i++; } } layout.setHeight(items.size() * ROW_HEIGHT); return layout; } @Override public List<String> validate() { final List<String> errors = new ArrayList<String>(); if (getMode().equals(mode.Q.toString())) { errors.addAll(this.validateRange(this.qranges)); } else if (getMode().equals(mode.UD.toString())) { try { if (!this.udInputItem.validate()) { errors.add(this.udInputItem.getRequiredMessage()); } final String value = this.udInputItem.getValueAsString(); if (value == null || value.isEmpty()) { errors.add(this.MSG.missingInput()); return errors; } Integer.valueOf(value);// irgendwie klappt die validator-validierung nur bei der eingabe von // ganzzahlen :-( } catch (final NumberFormatException e) { errors.add(this.MSG.error_invalid_integer()); } } return errors; } private List<String> validateRange(final Map<String, double[]> ranges) { final List<String> errors = new ArrayList<String>(); final NumberFormat nf = NumberFormat.getDecimalFormat(); for (final DoubleArrayPanel dap : this.wqranges.values()) { if (!dap.validateForm()) { errors.add(this.MSG.error_invalid_double_value()); return errors; } int idx = 0; final double[] values = dap.getInputValues(); if (values == null) { errors.add(this.MSG.missingInputs()); return errors; } final double[] good = new double[values.length]; for (final double value : values) { if (value <= 0) { String tmp = this.MSG.error_validate_positive(); tmp = tmp.replace("$1", nf.format(value)); errors.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 (!errors.isEmpty()) { dap.setValues(justGood); } } return errors; } @Override public Canvas createOld(final DataList dataList) { final List<Data> all = dataList.getAll(); final Data wqData = getData(all, "wq_values"); final Data wqMode = getData(all, "bundu.wst.mode"); final Data udValue = getData(all, "bundu.wst.ud_value"); final boolean isQ = wqMode.getItems()[0].getStringValue().equals(String.valueOf(mode.Q)); 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); if (isQ) { valLayout.addMember(createOldWQValues(wqData, true)); } else { valLayout.addMember(new Label(udValue.getItems()[0].getStringValue() + " [d/a]")); } valLayout.addMember(back); modeLayout.addMember(modeLabel); vlayout.addMember(valLayout); vlayout.addMember(modeLayout); return vlayout; } protected void callMainValuesService(final String locale, final String river, final double start, final double end, final Date startDate, final Date endDate, final AsyncCallback<WQInfoObject[]> cb) { this.mainValueService.getWQInfo(locale, river, start, end, startDate, endDate, cb); } @Override public void onFocus(final FocusEvent event) { this.itemWithFocus = (DoubleArrayPanel) event.getForm(); // Switch to respective tab. if (getMode().equals(mode.Q.toString())) { final int inputIndex = this.doubleArrayPanels.indexOf(this.itemWithFocus); this.tabs.selectTab(inputIndex); } } @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); final int startYear = this.bezugsjahr - this.qSeriesLength + 1; final int endYear = this.bezugsjahr; // Gauge ranges overlap, move start and end a bit closer // to each other. final AsyncCallback<GaugeInfoResult> cb = new AsyncCallback<GaugeInfoResult>() { @Override public void onFailure(final Throwable caught) { GWT.log("Could not recieve wq informations."); final String msg = caught.getMessage(); resetLoadingMessageOfQTable(msg); SC.warn(msg); } @Override public void onSuccess(final GaugeInfoResult result) { // TODO Auto-generated method stub final String globalErrorMsg = result.getGlobalErrorMsg(); if (!globalErrorMsg.equals("")) { resetLoadingMessageOfQTable(""); SC.warn(globalErrorMsg); } final GaugeInfoObject[] gauges = result.getGaugeInfoObjects(); final int num = gauges != null ? gauges.length : 0; GWT.log("Received timeranges for gauges"); if (num == 0) { return; } for (int i = 0; i < gauges.length; i++) { final GaugeInfoObject gauge = gauges[i]; // Gauge ranges overlap, move start and end a bit closer // to each other. final Double[] range = getGaugeNamesRange().get(gauge.getName()); 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."); addWQInfo(null, fi, gauge); if (fi == gauges.length - 1) getSubmitBtn().enable(); // always enable on success (globalerrorMsg is also success) } @Override public void onSuccess(final WQInfoObject[] wqi) { final int num = wqi != null ? wqi.length : 0; GWT.log("Received " + num + " wq informations (" + fi + "."); addWQInfo(wqi, fi, gauge); if (fi == gauges.length - 1) { getSubmitBtn().enable(); // always enable on success (globalerrorMsg is also success) if (globalErrorMsg.equals("")) BunduWstWQPanel.this.radiogroup.setCanEdit(true); } } }; callMainValuesService(locale, river, range[0] + rDiff, range[1] - rDiff, gauge.getStartdate(), gauge.getEnddate(), cb); } } }; this.serviceForTime.getGaugeInfo(locale, river, getGaugeNames(), startYear, endYear, cb); getSubmitBtn().disable(); } } @Override protected String getWQInfoMsg() { return this.MSG.bundu_ws_wq_info(); } }