teichmann@5861: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5861: * Software engineering by Intevation GmbH teichmann@5861: * teichmann@5861: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5861: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5861: * documentation coming with Dive4Elements River for details. teichmann@5861: */ teichmann@5861: teichmann@5835: package org.dive4elements.river.client.client.ui; ingo@243: ingo@243: import com.google.gwt.core.client.GWT; ingo@565: import com.google.gwt.i18n.client.NumberFormat; raimund@2456: import com.google.gwt.user.client.rpc.AsyncCallback; ingo@243: felix@5195: import com.smartgwt.client.data.Record; ingo@246: import com.smartgwt.client.types.TitleOrientation; ingo@247: import com.smartgwt.client.types.VerticalAlignment; ingo@602: import com.smartgwt.client.util.SC; ingo@243: import com.smartgwt.client.widgets.Canvas; ingo@243: import com.smartgwt.client.widgets.Label; ingo@255: import com.smartgwt.client.widgets.form.DynamicForm; ingo@255: import com.smartgwt.client.widgets.form.fields.RadioGroupItem; ingo@243: import com.smartgwt.client.widgets.form.fields.events.BlurEvent; christian@4568: import com.smartgwt.client.widgets.form.fields.events.BlurHandler; christian@4568: import com.smartgwt.client.widgets.form.fields.events.ChangeEvent; ingo@243: import com.smartgwt.client.widgets.form.fields.events.ChangeHandler; felix@5195: import com.smartgwt.client.widgets.form.fields.events.FocusEvent; felix@5195: import com.smartgwt.client.widgets.form.fields.events.FocusHandler; felix@5195: import com.smartgwt.client.widgets.grid.events.CellClickEvent; felix@5195: import com.smartgwt.client.widgets.grid.events.CellClickHandler; ingo@247: import com.smartgwt.client.widgets.layout.HLayout; ingo@243: import com.smartgwt.client.widgets.layout.VLayout; christian@4568: import com.smartgwt.client.widgets.tab.Tab; raimund@2456: import com.smartgwt.client.widgets.tab.TabSet; ingo@243: teichmann@5835: import org.dive4elements.river.client.client.Config; teichmann@5835: import org.dive4elements.river.client.client.FLYSConstants; teichmann@5835: import org.dive4elements.river.client.client.services.WQInfoService; teichmann@5835: import org.dive4elements.river.client.client.services.WQInfoServiceAsync; teichmann@5835: import org.dive4elements.river.client.client.ui.wq.QDTable; teichmann@5835: import org.dive4elements.river.client.client.ui.wq.WTable; teichmann@5835: import org.dive4elements.river.client.shared.model.ArtifactDescription; teichmann@5835: import org.dive4elements.river.client.shared.model.Data; teichmann@5835: import org.dive4elements.river.client.shared.model.DataItem; teichmann@5835: import org.dive4elements.river.client.shared.model.DataList; teichmann@5835: import org.dive4elements.river.client.shared.model.DefaultData; teichmann@5835: import org.dive4elements.river.client.shared.model.DefaultDataItem; teichmann@5835: import org.dive4elements.river.client.shared.model.WQDataItem; teichmann@5835: import org.dive4elements.river.client.shared.model.WQInfoObject; teichmann@5835: import org.dive4elements.river.client.shared.model.WQInfoRecord; ingo@243: christian@4568: import java.util.ArrayList; christian@4568: import java.util.HashMap; christian@4568: import java.util.Iterator; christian@4568: import java.util.LinkedHashMap; christian@4568: import java.util.List; christian@4568: import java.util.Map; ingo@246: ingo@243: ingo@243: /** ingo@243: * This UIProvider creates a widget to enter W or Q data for discharge ingo@243: * longitudinal section computations. ingo@243: * ingo@243: * @author Ingo Weinzierl ingo@243: */ ingo@243: public class WQAdaptedInputPanel ingo@243: extends AbstractUIProvider felix@5195: implements ChangeHandler, BlurHandler, FocusHandler ingo@243: { christian@4568: private static final long serialVersionUID = -3218827566805476423L; christian@4568: felix@5635: /** The message class that provides i18n strings. */ felix@5190: protected FLYSConstants MESSAGE = GWT.create(FLYSConstants.class); felix@5190: ingo@2392: public static final String FIELD_WQ_MODE = "wq_isq"; ingo@255: public static final String FIELD_WQ_W = "W"; ingo@255: public static final String FIELD_WQ_Q = "Q"; ingo@246: ingo@247: public static final String GAUGE_SEPARATOR = ":"; ingo@247: ingo@247: public static final String GAUGE_PART_SEPARATOR = ";"; ingo@247: ingo@247: public static final String VALUE_SEPARATOR = ","; ingo@247: ingo@255: public static final int ROW_HEIGHT = 20; ingo@255: felix@5635: /** The constant field name for choosing w or q mode. */ raimund@2456: public static final String FIELD_WQ = "wq"; raimund@2456: felix@5635: /** The constant field name for choosing single values or range. */ raimund@2456: public static final String FIELD_MODE = "mode"; raimund@2456: felix@5635: /** The constant field value for range input mode. */ raimund@2456: public static final String FIELD_MODE_RANGE = "range"; raimund@2456: felix@5640: /** Service to fetch W/Q MainValues. */ raimund@2456: protected WQInfoServiceAsync wqInfoService = raimund@2456: GWT.create(WQInfoService.class); ingo@246: felix@5635: /** The message class that provides i18n strings. */ ingo@246: protected FLYSConstants MSG = GWT.create(FLYSConstants.class); ingo@246: felix@5635: /** Stores the input panels related to their keys. */ ingo@246: protected Map wqranges; ingo@246: felix@5527: /** List of doubleArrayPanels shown. */ felix@5526: protected ArrayList doubleArrayPanels; felix@5526: felix@5773: /** [startkm,endkm] per gauge in selected range. */ felix@5773: protected double[][] gaugeRanges; felix@5773: felix@5773: /** Stores the min/max values for each q range (gauge). */ ingo@565: protected Map qranges; ingo@565: felix@5773: /** Stores the min/max values for each w range (gauge). */ ingo@565: protected Map wranges; ingo@565: felix@5635: /** The RadioGroupItem that determines the w/q input mode. */ ingo@255: protected DynamicForm modes; ingo@255: felix@5773: /** List of wTables in inputhelper section. */ felix@5773: protected List wTables; raimund@2456: felix@5773: /** List of QDTables in inputhelper section. */ felix@5773: protected List qdTables; raimund@2456: felix@5196: /** Tabs in inputhelper area. */ raimund@2456: protected TabSet tabs; ingo@246: felix@5195: /** The currently focussed Input element. */ felix@5195: protected DoubleArrayPanel itemWithFocus; felix@5195: ingo@246: ingo@243: public WQAdaptedInputPanel() { ingo@246: wqranges = new HashMap(); felix@5526: doubleArrayPanels = new ArrayList(); ingo@565: qranges = new HashMap(); ingo@565: wranges = new HashMap(); felix@5773: wTables = new ArrayList(); felix@5773: qdTables = new ArrayList(); ingo@243: } ingo@243: ingo@243: christian@4568: @Override ingo@243: public Canvas create(DataList data) { felix@5773: readGaugeRanges(data); raimund@2456: initHelperPanel(); raimund@2456: ingo@243: Canvas submit = getNextButton(); ingo@246: Canvas widget = createWidget(data); ingo@246: Label label = new Label(MSG.wqadaptedTitle()); ingo@246: ingo@246: label.setHeight(25); ingo@243: ingo@243: VLayout layout = new VLayout(); ingo@243: layout.setMembersMargin(10); ingo@255: layout.setWidth(350); ingo@243: ingo@246: layout.addMember(label); ingo@246: layout.addMember(widget); ingo@243: layout.addMember(submit); ingo@243: felix@5773: fetchWQData(); felix@5773: felix@5773: initTableListeners(); felix@5773: ingo@243: return layout; ingo@243: } ingo@243: ingo@243: felix@5190: /** Inits the helper panel. */ felix@5190: // TODO duplicate in WQInputPanel raimund@2456: protected void initHelperPanel() { raimund@2456: tabs = new TabSet(); raimund@2456: tabs.setWidth100(); raimund@2456: tabs.setHeight100(); raimund@2456: felix@5773: // For each gauge, add two tabs with helper tables. raimund@2456: felix@5773: for (int i = 0; i< gaugeRanges.length; i++) { felix@5773: // Later the tabs title will get adjusted to include gauges name. felix@5773: // TODO the tabs title becomes rather long through that (i18n). felix@5773: Tab wTab = new Tab(MESSAGE.wq_table_w()); felix@5773: Tab qTab = new Tab(MESSAGE.wq_table_q()); raimund@2456: felix@5773: QDTable qdTable = new QDTable(); felix@5773: WTable wTable = new WTable(); felix@5773: felix@5773: wTables.add(wTable); felix@5773: qdTables.add(qdTable); felix@5773: felix@5773: qdTable.showSelect(); felix@5773: //wTable.showSelect(); felix@5773: wTab.setPane(wTable); felix@5773: qTab.setPane(qdTable); felix@5773: felix@5773: tabs.addTab(wTab, i*2+0); felix@5773: tabs.addTab(qTab, i*2+1); felix@5773: } raimund@2456: raimund@2456: helperContainer.addMember(tabs); raimund@2456: } raimund@2456: raimund@2456: felix@5195: /** felix@5195: * Initializes the listeners of the WQD tables. felix@5195: */ felix@5195: // TODO dupe from WQInputPanel felix@5195: protected void initTableListeners() { felix@5773: int i = 0; felix@5773: for (QDTable qdTable: qdTables) { felix@5773: // Register listener such that values are filled in on click. felix@5773: final QDTable table = qdTable; felix@5773: final int fi = i; felix@5773: CellClickHandler handler = new CellClickHandler() { felix@5773: @Override felix@5773: public void onCellClick(CellClickEvent e) { felix@5773: if (isWMode() || table.isLocked()) { felix@5773: return; felix@5773: } felix@5195: felix@5773: int idx = e.getColNum(); felix@5773: Record r = e.getRecord(); felix@5773: double val = r.getAttributeAsDouble("value"); felix@5773: felix@5773: doubleArrayPanels.get(fi).setValues(new double[]{val}); felix@5774: // If a named value for first gauge is chosen, try to find and set felix@5774: // the values to the other panels too. felix@5774: if (fi == 0) { felix@5774: String valueName = r.getAttribute("name"); felix@5774: int oi = 0; felix@5774: // TODO instead of oi use random access. felix@5774: for (QDTable otherQDTable: qdTables) { felix@5774: if (oi == 0) { felix@5774: oi++; felix@5774: continue; felix@5774: } felix@5774: Double value = otherQDTable.findRecordValue(valueName); felix@5774: if (value == null) { felix@5774: // TODO i18n felix@5774: SC.warn("No Value for at "); felix@5774: } felix@5774: else { felix@5774: doubleArrayPanels.get(oi).setValues(new double[]{value}); felix@5774: } felix@5774: oi++; felix@5774: } felix@5526: } felix@5774: else { felix@5774: // Focus next. felix@5774: if (fi != doubleArrayPanels.size()-1) { felix@5774: doubleArrayPanels.get(fi+1).focusInItem(1); felix@5773: } felix@5774: } felix@5195: } felix@5773: }; felix@5195: felix@5773: qdTable.addCellClickHandler(handler); felix@5773: i++; felix@5773: } felix@5195: } felix@5195: felix@5527: christian@4568: @Override ingo@243: public Canvas createOld(DataList dataList) { ingo@247: List all = dataList.getAll(); ingo@247: Data wqData = getData(all, "wq_values"); ingo@2392: Data wqMode = getData(all, "wq_isq"); felix@5154: boolean isQ = wqMode.getItems()[0].getStringValue().equals("true"); ingo@247: Canvas back = getBackButton(dataList.getState()); ingo@247: ingo@247: HLayout valLayout = new HLayout(); ingo@247: HLayout modeLayout = new HLayout(); ingo@247: VLayout vlayout = new VLayout(); ingo@247: ingo@247: Label wqLabel = new Label(dataList.getLabel()); ingo@247: Label modeLabel = new Label(""); ingo@247: ingo@247: wqLabel.setValign(VerticalAlignment.TOP); ingo@247: ingo@247: wqLabel.setWidth(200); ingo@247: wqLabel.setHeight(25); ingo@247: modeLabel.setHeight(25); ingo@247: modeLabel.setWidth(200); ingo@247: ingo@247: valLayout.addMember(wqLabel); felix@5154: valLayout.addMember(createOldWQValues(wqData, isQ)); felix@5154: ingo@247: valLayout.addMember(back); ingo@247: modeLayout.addMember(modeLabel); ingo@247: ingo@247: vlayout.addMember(valLayout); ingo@247: vlayout.addMember(modeLayout); ingo@247: ingo@247: return vlayout; ingo@247: } ingo@247: ingo@247: felix@5124: /** Create area showing previously entered w or q data. */ felix@5154: protected Canvas createOldWQValues(Data wqData, boolean isQ) { ingo@247: VLayout layout = new VLayout(); ingo@247: ingo@247: DataItem item = wqData.getItems()[0]; ingo@247: String value = item.getStringValue(); ingo@247: ingo@247: String[] gauges = value.split(GAUGE_SEPARATOR); ingo@247: felix@5154: String unit = isQ ? "m³/s" : "cm"; felix@5154: ingo@247: for (String gauge: gauges) { ingo@247: HLayout h = new HLayout(); ingo@247: ingo@247: String[] parts = gauge.split(GAUGE_PART_SEPARATOR); rrenkert@5104: String[] values = parts[3].split(VALUE_SEPARATOR); ingo@247: rrenkert@5104: Label l = new Label(parts[2] + ": "); ingo@247: ingo@247: StringBuilder sb = new StringBuilder(); ingo@247: boolean first = true; ingo@247: ingo@247: for (String v: values) { ingo@247: if (!first) { ingo@247: sb.append(", "); ingo@247: } ingo@247: ingo@247: sb.append(v); felix@5154: sb.append(" "); felix@5154: sb.append(unit); ingo@247: ingo@247: first = false; ingo@247: } ingo@247: ingo@247: Label v = new Label(sb.toString()); ingo@247: ingo@247: l.setWidth(65); ingo@247: v.setWidth(65); ingo@247: ingo@247: h.addMember(l); ingo@247: h.addMember(v); ingo@247: ingo@247: layout.addMember(h); ingo@247: } ingo@247: ingo@247: return layout; ingo@243: } ingo@243: ingo@243: felix@5773: /** Create non-input helper part of the UI. */ ingo@246: protected Canvas createWidget(DataList dataList) { ingo@246: VLayout layout = new VLayout(); ingo@246: ingo@255: Canvas mode = createMode(dataList); ingo@255: Canvas list = createList(dataList); ingo@255: ingo@255: DataItem[] items = getWQItems(dataList); ingo@255: int listHeight = ROW_HEIGHT * items.length; ingo@255: ingo@255: mode.setHeight(25); ingo@255: mode.setWidth(200); ingo@255: ingo@255: layout.addMember(mode); ingo@255: layout.addMember(list); ingo@255: ingo@255: layout.setHeight(25 + listHeight); ingo@255: layout.setWidth(350); ingo@255: ingo@519: initUserDefaults(dataList); ingo@519: ingo@255: return layout; ingo@255: } ingo@255: ingo@255: ingo@565: @Override ingo@565: public List validate() { ingo@565: if (isWMode()) { ingo@565: return validateW(); ingo@565: } ingo@565: else { ingo@565: return validateQ(); ingo@565: } ingo@565: } ingo@565: felix@5527: felix@5123: protected List validateRange(Map ranges) { ingo@565: List errors = new ArrayList(); ingo@565: NumberFormat nf = NumberFormat.getDecimalFormat(); ingo@565: ingo@565: Iterator iter = wqranges.keySet().iterator(); ingo@565: ingo@565: while (iter.hasNext()) { ingo@565: List tmpErrors = new ArrayList(); ingo@565: ingo@565: String key = iter.next(); ingo@565: DoubleArrayPanel dap = wqranges.get(key); ingo@602: ingo@602: if (!dap.validateForm()) { ingo@602: errors.add(MSG.error_invalid_double_value()); ingo@602: return errors; ingo@602: } ingo@602: felix@5123: double[] mm = ranges.get(key); ingo@602: if (mm == null) { ingo@602: SC.warn(MSG.error_read_minmax_values()); ingo@602: continue; ingo@602: } ingo@565: ingo@565: double[] values = dap.getInputValues(); ingo@565: double[] good = new double[values.length]; ingo@565: ingo@565: int idx = 0; ingo@565: ingo@565: for (double value: values) { ingo@565: if (value < mm[0] || value > mm[1]) { ingo@565: String tmp = MSG.error_validate_range(); ingo@565: tmp = tmp.replace("$1", nf.format(value)); ingo@565: tmp = tmp.replace("$2", nf.format(mm[0])); ingo@565: tmp = tmp.replace("$3", nf.format(mm[1])); ingo@565: tmpErrors.add(tmp); ingo@565: } ingo@565: else { ingo@565: good[idx++] = value; ingo@565: } ingo@565: } ingo@565: ingo@565: double[] justGood = new double[idx]; ingo@565: for (int i = 0; i < justGood.length; i++) { ingo@565: justGood[i] = good[i]; ingo@565: } ingo@565: ingo@565: if (!tmpErrors.isEmpty()) { ingo@565: dap.setValues(justGood); ingo@565: ingo@565: errors.addAll(tmpErrors); ingo@565: } ingo@565: } ingo@565: ingo@565: return errors; ingo@565: } ingo@565: ingo@565: felix@5123: protected List validateW() { felix@5123: return validateRange(wranges); felix@5123: } ingo@565: ingo@565: felix@5123: protected List validateQ() { felix@5123: return validateRange(qranges); ingo@565: } ingo@565: ingo@565: ingo@519: protected void initUserDefaults(DataList dataList) { ingo@519: initUserWQValues(dataList); ingo@519: initUserWQMode(dataList); ingo@519: } ingo@519: ingo@519: ingo@519: protected void initUserWQMode(DataList dataList) { ingo@519: List allData = dataList.getAll(); ingo@519: ingo@519: Data dDef = getData(allData, "wq_mode"); ingo@519: DataItem def = dDef != null ? dDef.getDefault() : null; ingo@519: String value = def != null ? def.getStringValue() : null; ingo@519: ingo@617: if (value != null && value.equals(FIELD_WQ_W)) { ingo@617: modes.setValue(FIELD_WQ_MODE, FIELD_WQ_W); ingo@519: } ingo@519: else { ingo@617: modes.setValue(FIELD_WQ_MODE, FIELD_WQ_Q); ingo@519: } ingo@519: } ingo@519: ingo@519: ingo@519: protected void initUserWQValues(DataList dataList) { ingo@519: List allData = dataList.getAll(); ingo@519: ingo@519: Data dDef = getData(allData, "wq_values"); ingo@519: DataItem def = dDef != null ? dDef.getDefault() : null; ingo@519: String value = def != null ? def.getStringValue() : null; ingo@519: ingo@519: if (value == null || value.length() == 0) { ingo@519: return; ingo@519: } ingo@519: ingo@519: String[] lines = value.split(GAUGE_SEPARATOR); ingo@519: ingo@519: if (lines == null || lines.length == 0) { ingo@519: return; ingo@519: } ingo@519: ingo@519: for (String line: lines) { ingo@519: String[] cols = line.split(GAUGE_PART_SEPARATOR); ingo@519: String title = createLineTitle(line); ingo@519: ingo@519: if (cols == null || cols.length < 3) { ingo@519: continue; ingo@519: } ingo@519: ingo@519: String[] strValues = cols[2].split(VALUE_SEPARATOR); ingo@519: double[] values = new double[strValues.length]; ingo@519: ingo@519: int idx = 0; ingo@519: ingo@519: for (String strValue: strValues) { ingo@519: try { ingo@519: values[idx++] = Double.valueOf(strValue); ingo@519: } ingo@519: catch (NumberFormatException nfe) { ingo@519: // do nothing ingo@519: } ingo@519: } ingo@519: ingo@519: String key = cols[0] + GAUGE_PART_SEPARATOR + cols[1]; ingo@519: DoubleArrayPanel dap = wqranges.get(key); ingo@560: ingo@560: if (dap == null) { ingo@560: continue; ingo@560: } ingo@560: ingo@519: dap.setValues(values); ingo@519: } ingo@519: } ingo@519: felix@5773: /** Populate Gauge Ranges array. */ felix@5773: private void readGaugeRanges(DataList dataList) { felix@5773: DataItem[] items = getWQItems(dataList); felix@5773: gaugeRanges = new double[items.length][2]; felix@5773: felix@5773: int i = 0; felix@5773: felix@5773: for (DataItem item: items) { felix@5773: String[] startEndKm = item.getLabel().split(";"); felix@5773: felix@5773: gaugeRanges[i][0] = Double.parseDouble(startEndKm[0]); felix@5773: gaugeRanges[i][1] = Double.parseDouble(startEndKm[1]); felix@5773: i++; felix@5773: } felix@5773: } felix@5773: ingo@519: ingo@255: protected Canvas createList(DataList dataList) { ingo@255: VLayout layout = new VLayout(); ingo@255: ingo@255: DataItem[] items = getWQItems(dataList); ingo@255: felix@5773: int i = 0; felix@5773: ingo@255: for (DataItem item: items) { felix@5773: String title = item.getLabel(); // of form: 70.5;112.0 rrenkert@5104: String label = item.getStringValue(); felix@5773: felix@5773: // Rename W and Q tab to include gauges name. felix@5773: tabs.getTab(i*2).setTitle(tabs.getTab(i*2).getTitle() felix@5773: + " (" + label + ")"); felix@5773: tabs.getTab(i*2+1).setTitle(tabs.getTab(i*2+1).getTitle() felix@5773: + " (" + label + ")"); felix@5773: ingo@255: DoubleArrayPanel dap = new DoubleArrayPanel( felix@5195: label, null, this, this, TitleOrientation.LEFT); ingo@255: ingo@255: wqranges.put(title, dap); felix@5526: doubleArrayPanels.add(dap); ingo@565: ingo@565: if (item instanceof WQDataItem) { ingo@565: WQDataItem wq = (WQDataItem) item; ingo@565: double[] mmQ = wq.getQRange(); ingo@565: double[] mmW = wq.getWRange(); ingo@565: ingo@565: qranges.put(title, mmQ); ingo@565: wranges.put(title, mmW); ingo@565: } ingo@565: ingo@255: layout.addMember(dap); felix@5773: i++; ingo@255: } ingo@255: ingo@255: layout.setHeight(items.length * ROW_HEIGHT); ingo@255: ingo@255: return layout; ingo@255: } ingo@255: ingo@255: felix@5154: /** Get items which are not WQ_MODE. */ ingo@255: protected DataItem[] getWQItems(DataList dataList) { ingo@246: List data = dataList.getAll(); ingo@246: ingo@246: for (Data d: data) { ingo@246: String name = d.getLabel(); ingo@246: ingo@246: if (name.equals(FIELD_WQ_MODE)) { ingo@246: continue; ingo@246: } ingo@246: ingo@255: return d.getItems(); ingo@246: } ingo@246: ingo@255: return null; ingo@255: } ingo@255: ingo@255: felix@5154: /** felix@5154: * Create radio button for switching w and q input. felix@5154: * Radiobutton-change also triggers helper panel tab selection. felix@5154: */ ingo@255: protected Canvas createMode(DataList dataList) { ingo@255: RadioGroupItem wq = new RadioGroupItem(FIELD_WQ_MODE); ingo@255: wq.setShowTitle(false); ingo@255: wq.setVertical(false); ingo@255: wq.setWidth(200); ingo@255: ingo@255: LinkedHashMap wqValues = new LinkedHashMap(); ingo@255: wqValues.put(FIELD_WQ_W, MSG.wqW()); rrenkert@5104: wqValues.put(FIELD_WQ_Q, MSG.wqQatGauge()); ingo@255: ingo@255: wq.setValueMap(wqValues); ingo@255: ingo@255: modes = new DynamicForm(); ingo@255: modes.setFields(wq); ingo@255: modes.setWidth(200); raimund@2456: wq.addChangeHandler(new ChangeHandler() { christian@4568: @Override raimund@2456: public void onChange(ChangeEvent e) { raimund@2456: DynamicForm form = e.getForm(); raimund@2456: raimund@2456: if(form.getValueAsString(FIELD_WQ_MODE).contains("Q")) { raimund@2456: tabs.selectTab(0); felix@5921: enableQTabs(); raimund@2456: } raimund@2456: else { raimund@2456: tabs.selectTab(1); felix@5921: enableWTabs(); raimund@2456: } raimund@2456: } raimund@2456: }); raimund@2456: ingo@255: ingo@255: LinkedHashMap initial = new LinkedHashMap(); ingo@617: initial.put(FIELD_WQ_MODE, FIELD_WQ_Q); ingo@255: modes.setValues(initial); raimund@2456: tabs.selectTab(1); ingo@255: return modes; ingo@246: } ingo@246: ingo@246: felix@5921: public void enableWTabs() { felix@5921: for (int i = 0; i < doubleArrayPanels.size(); i++) { felix@5921: tabs.disableTab(2*i); felix@5921: tabs.enableTab(2*i+1); felix@5921: } felix@5921: } felix@5921: felix@5921: felix@5921: public void enableQTabs() { felix@5921: for (int i = 0; i < doubleArrayPanels.size(); i++) { felix@5921: tabs.enableTab(2*i); felix@5921: tabs.disableTab(2*i+1); felix@5921: } felix@5921: } felix@5921: felix@5921: ingo@246: public String createLineTitle(String key) { ingo@246: String[] splitted = key.split(";"); ingo@246: ingo@246: return splitted[0] + " - " + splitted[1]; ingo@246: } ingo@246: ingo@246: christian@4568: @Override ingo@243: public Data[] getData() { ingo@246: Data mode = getWQMode(); ingo@246: Data values = getWQValues(); ingo@243: ingo@246: return new Data[] { mode, values }; ingo@246: } ingo@246: ingo@246: ingo@565: public boolean isWMode() { ingo@565: String mode = (String) modes.getValue(FIELD_WQ_MODE); ingo@565: ingo@565: return FIELD_WQ_W.equals(mode); ingo@565: } ingo@565: ingo@565: ingo@246: protected Data getWQMode() { ingo@255: String wqMode = modes.getValueAsString(FIELD_WQ_MODE); ingo@2392: String value = "false"; ingo@2392: if (wqMode.equals("Q")) { ingo@2392: value = "true"; ingo@2392: } ingo@2392: DataItem item = new DefaultDataItem("wq_isq", "wq_isq", value); ingo@243: Data mode = new DefaultData( ingo@2392: "wq_isq", null, null, new DataItem[] { item }); ingo@243: ingo@246: return mode; ingo@246: } ingo@246: ingo@246: ingo@246: protected Data getWQValues() { ingo@246: String wqvalue = null; ingo@246: ingo@246: Iterator iter = wqranges.keySet().iterator(); ingo@246: while (iter.hasNext()) { ingo@246: String key = iter.next(); ingo@246: DoubleArrayPanel dap = wqranges.get(key); rrenkert@5104: String label = dap.getItemTitle(); ingo@246: ingo@246: double[] values = dap.getInputValues(); ingo@246: if (wqvalue == null) { rrenkert@5104: wqvalue = createValueString(key + ";" + label, values); ingo@246: } ingo@246: else { rrenkert@5104: wqvalue += GAUGE_SEPARATOR + createValueString(key + ";" + label, values); ingo@246: } ingo@246: } ingo@246: ingo@243: DataItem valueItem = new DefaultDataItem( ingo@246: "wq_values", "wq_values", wqvalue); ingo@243: Data values = new DefaultData( ingo@243: "wq_values", null, null, new DataItem[] { valueItem }); ingo@243: ingo@246: return values; ingo@246: } ingo@246: ingo@246: ingo@246: protected String createValueString(String key, double[] values) { ingo@246: StringBuilder sb = new StringBuilder(); ingo@246: ingo@246: boolean first = true; ingo@246: ingo@246: for (double value: values) { ingo@246: if (!first) { ingo@246: sb.append(","); ingo@246: } ingo@246: ingo@246: sb.append(Double.toString(value)); ingo@246: ingo@246: first = false; ingo@246: } ingo@246: ingo@246: return key + ";" + sb.toString(); ingo@243: } ingo@243: ingo@243: christian@4568: @Override ingo@243: public void onChange(ChangeEvent event) { ingo@243: // TODO IMPLEMENT ME ingo@243: } ingo@243: ingo@243: felix@5773: /** Store the currently focussed DoubleArrayPanel and focus helper tab. */ felix@5195: @Override felix@5195: public void onFocus(FocusEvent event) { felix@5195: itemWithFocus = (DoubleArrayPanel) event.getForm(); felix@5773: // Switch to respective tab. felix@5773: // TODO which makes a focus loss felix@5773: int inputIndex = doubleArrayPanels.indexOf(itemWithFocus); felix@5773: tabs.selectTab(inputIndex*2 + (isWMode() ? 0 : 1)); felix@5195: } felix@5195: felix@5195: christian@4568: @Override ingo@243: public void onBlur(BlurEvent event) { ingo@246: DoubleArrayPanel dap = (DoubleArrayPanel) event.getForm(); ingo@246: dap.validateForm(event.getItem()); ingo@243: } raimund@2456: raimund@2456: felix@5773: /** Get the WQD data from service and stuck them up that tables. */ raimund@2456: protected void fetchWQData() { raimund@2456: Config config = Config.getInstance(); raimund@2456: String locale = config.getLocale (); raimund@2456: raimund@2456: ArtifactDescription adescr = artifact.getArtifactDescription(); raimund@2456: DataList[] data = adescr.getOldData(); raimund@2456: raimund@2456: double[] mm = getMinMaxKM(data); raimund@2456: String river = getRiverName(data); raimund@2456: felix@5773: int i = 0; raimund@2456: felix@5773: // Get Data for respective gauge. felix@5773: for (double[] range : gaugeRanges){ felix@5773: // Gauge ranges overlap, move start and end a bit closer to each other. felix@5773: final double rDiff = (range[1] - range[0]) / 10d; felix@5773: final int fi = i; felix@5773: wqInfoService.getWQInfo(locale, river, range[0]+rDiff, range[1]-rDiff, felix@5773: new AsyncCallback() { felix@5773: @Override felix@5773: public void onFailure(Throwable caught) { felix@5773: GWT.log("Could not recieve wq informations."); felix@5773: SC.warn(caught.getMessage()); raimund@2456: } raimund@2456: felix@5773: @Override felix@5773: public void onSuccess(WQInfoObject[] wqi) { felix@5773: int num = wqi != null ? wqi.length :0; felix@5773: GWT.log("Received " + num + " wq informations (" + fi + "."); felix@5773: felix@5773: if (num == 0) { felix@5773: return; felix@5773: } felix@5773: felix@5773: addWQInfo(wqi, fi); felix@5773: } raimund@2456: } felix@5773: ); felix@5773: i++; felix@5773: } raimund@2456: } raimund@2456: raimund@2456: felix@5773: /** Add Info to helper table for gauge at index gaugeIdx. */ felix@5773: protected void addWQInfo (WQInfoObject[] wqi, int gaugeIdx) { raimund@2456: for(WQInfoObject wi: wqi) { raimund@2456: WQInfoRecord rec = new WQInfoRecord(wi); raimund@2456: raimund@2456: if (wi.getType().equals("W")) { felix@5773: wTables.get(gaugeIdx).addData(rec); raimund@2456: } raimund@2456: else { felix@5773: qdTables.get(gaugeIdx).addData(rec); raimund@2456: } raimund@2456: } raimund@2456: } raimund@2456: raimund@2456: raimund@2456: /** raimund@2456: * Determines the min and max kilometer value selected in a former state. A raimund@2456: * bit silly, but we need to run over each value of the "old data" to find raimund@2456: * such values because it is not available here. raimund@2456: * raimund@2456: * @param data The DataList which contains the whole data inserted for the raimund@2456: * current artifact. raimund@2456: * raimund@2456: * @return a double array with [min, max]. raimund@2456: */ raimund@2456: protected double[] getMinMaxKM(DataList[] data) { raimund@2456: ArtifactDescription adesc = artifact.getArtifactDescription(); raimund@2456: return adesc.getKMRange(); raimund@2456: } raimund@2456: raimund@2456: raimund@2456: /** raimund@2456: * Returns the name of the selected river. raimund@2456: * raimund@2456: * @param data The DataList with all data. raimund@2456: * raimund@2456: * @return the name of the current river. raimund@2456: */ raimund@2456: protected String getRiverName(DataList[] data) { raimund@2456: ArtifactDescription adesc = artifact.getArtifactDescription(); raimund@2456: return adesc.getRiver(); raimund@2456: } ingo@243: } ingo@243: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :