# HG changeset patch # User Felix Wolfsteller # Date 1328718279 0 # Node ID 66671b69c7eaec8c1142e63ac060540787627a11 # Parent 87572e476f7a7434dbdebb41a9d04f19a25106da Added new UIProvider to enter mutliple locations (yet only input view textfield possible). flys-client/trunk@3979 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 87572e476f7a -r 66671b69c7ea flys-client/ChangeLog --- a/flys-client/ChangeLog Wed Feb 08 16:20:30 2012 +0000 +++ b/flys-client/ChangeLog Wed Feb 08 16:24:39 2012 +0000 @@ -1,3 +1,24 @@ +2012-02-08 Felix Wolfsteller + + New UIProvider to enter multiple locations (so far only via keyboard). + + * src/main/java/de/intevation/flys/client/client/ui/MultipleLocationPanel.java, + src/main/java/de/intevation/flys/client/client/ui/LocationPanel.java, + src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java: + Refactored. New UIProvider does allow and provide multiple values, + which are whitespace separated in data item. + + * src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java: + Serve the new UIProvider if somebody orders it. + +2012-02-08 Felix Wolfsteller + + * src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSConstants.properties, + src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSConstants.java: Added + missing translation for "waterlevels" used in the datacage window. + 2012-02-08 Felix Wolfsteller * src/main/java/de/intevation/flys/client/server/ChartInfoServiceImpl.java, diff -r 87572e476f7a -r 66671b69c7ea flys-client/src/main/java/de/intevation/flys/client/client/ui/LocationPanel.java --- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/LocationPanel.java Wed Feb 08 16:20:30 2012 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/LocationPanel.java Wed Feb 08 16:24:39 2012 +0000 @@ -255,10 +255,6 @@ double[] good = new double[values.length]; int idx = 0; - if (values.length > 1) { - errors.add(MSG.too_many_values()); - } - for (double value: values) { if (value < min || value > max) { String tmp = MSG.error_validate_range(); diff -r 87572e476f7a -r 66671b69c7ea flys-client/src/main/java/de/intevation/flys/client/client/ui/MultipleLocationPanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/MultipleLocationPanel.java Wed Feb 08 16:24:39 2012 +0000 @@ -0,0 +1,303 @@ +package de.intevation.flys.client.client.ui; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.i18n.client.NumberFormat; + +import com.smartgwt.client.util.SC; +import com.smartgwt.client.widgets.Canvas; +import com.smartgwt.client.widgets.Label; +import com.smartgwt.client.widgets.form.fields.events.BlurHandler; +import com.smartgwt.client.widgets.form.fields.events.BlurEvent; + +import com.smartgwt.client.widgets.layout.HLayout; +import com.smartgwt.client.widgets.layout.VLayout; + +import com.smartgwt.client.widgets.grid.events.RecordClickHandler; +import com.smartgwt.client.widgets.grid.events.RecordClickEvent; + +import com.smartgwt.client.data.Record; + +import de.intevation.flys.client.shared.model.ArtifactDescription; +import de.intevation.flys.client.shared.model.Data; +import de.intevation.flys.client.shared.model.DataItem; +import de.intevation.flys.client.shared.model.DataList; +import de.intevation.flys.client.shared.model.DistanceInfoObject; +import de.intevation.flys.client.shared.model.RangeData; + +import de.intevation.flys.client.client.services.DistanceInfoService; +import de.intevation.flys.client.client.services.DistanceInfoServiceAsync; +import de.intevation.flys.client.client.Config; +import de.intevation.flys.client.client.ui.range.DistanceInfoDataSource; + + +/** + * This UIProvider creates a widget to enter a single location (km). + * + * @author Raimund Renkert + */ +public class MultipleLocationPanel +extends LocationPanel +implements RecordClickHandler +{ + /** The DistanceInfoService used to retrieve locations about rivers. */ + protected DistanceInfoServiceAsync distanceInfoService = + GWT.create(DistanceInfoService.class); + + /** The table data. */ + protected DistanceInfoObject[] tableData; + + /** The input helper (usually right side, table to click on, values are + * then entered in the texfield. */ + protected LocationPicker picker; + + /** + * Creates a new LocationDistancePanel instance. + */ + public MultipleLocationPanel() { + picker = new LocationPicker(this); + } + + + /** + * This method creates a widget that contains a label, a panel with + * checkboxes to switch the input mode between location and distance input, + * and a mode specific panel. + * + * @param data The data that might be inserted. + * + * @return a panel. + */ + @Override + public Canvas create(DataList data) { + findDataItemName(data); + + VLayout layout = new VLayout(); + layout.setMembersMargin(10); + + Label label = new Label(MSG.location ()); + Canvas widget = createWidget(data); + Canvas submit = getNextButton(); + + initDefaults(data); + + picker.createLocationTable(); + + widget.setHeight(50); + label.setHeight(25); + + layout.addMember(label); + layout.addMember(widget); + layout.addMember(submit); + + return layout; + } + + + /** + * This method reads the default values defined in the DataItems of the Data + * objects in list. + * + * @param list The DataList container that stores the Data objects. + */ + protected void initDefaults(DataList list) { + Data data = list.get(0); + + // Compatibility with MinMax- DataItems: + RangeData rangeData = null; + + for (int i = 0, n = list.size(); i < n; i++) { + Data tmp = list.get(i); + + if (tmp instanceof RangeData) { + rangeData = (RangeData) tmp; + } + } + + if (rangeData != null) { + min = Double.parseDouble(rangeData.getDefaultLower().toString()); + max = Double.parseDouble(rangeData.getDefaultUpper().toString()); + // catch ..? + } + else { + DataItem[] items = data.getItems(); + DataItem iMin = getDataItem(items, "min"); + DataItem iMax = getDataItem(items, "max"); + + try { + min = Double.parseDouble(iMin.getStringValue()); + max = Double.parseDouble(iMax.getStringValue()); + } + catch (NumberFormatException nfe) { + SC.warn(MSG.error_read_minmax_values()); + min = -Double.MAX_VALUE; + max = Double.MAX_VALUE; + } + } + + DataItem def = data.getDefault(); + if (def != null) { + String value = def.getStringValue(); + + try { + double d = Double.parseDouble(value); + setLocationValues(new double[] { d } ); + } + catch (NumberFormatException nfe) { + // could not parse, dont know what to do else + } + } + } + + + protected Canvas createWidget(DataList data) { + VLayout layout = new VLayout(); + inputLayout = new HLayout(); + + // The initial view will display the location input mode. + locationPanel = new DoubleArrayPanel( + MSG.unitLocation(), + getLocationValues(), + new BlurHandler(){public void onBlur(BlurEvent be) {}}); + + picker.getLocationTable().setAutoFetchData(true); + + inputLayout.addMember(locationPanel); + + layout.addMember(inputLayout); + + inputLayout.setMembersMargin(30); + + picker.prepareFilter(); + + helperContainer.addMember(picker.getLocationTable()); + helperContainer.addMember(picker.getFilterLayout()); + helperContainer.addMember(picker.getResultCountForm()); + setPickerDataSource(); + return layout; + } + + + /** Overridden to restrict to one entered value. */ + @Override + public List validate() { + List errors = new ArrayList(); + NumberFormat nf = NumberFormat.getDecimalFormat(); + + saveLocationValues(locationPanel); + + if (!locationPanel.validateForm()) { + errors.add(MSG.wrongFormat()); + return errors; + } + + double[] values = getLocationValues(); + double[] good = new double[values.length]; + int idx = 0; + + for (double value: values) { + if (value < min || value > max) { + String tmp = MSG.error_validate_range(); + tmp = tmp.replace("$1", nf.format(value)); + tmp = tmp.replace("$2", nf.format(min)); + tmp = tmp.replace("$3", nf.format(max)); + errors.add(tmp); + } + else { + good[idx++] = value; + } + } + + double[] justGood = new double[idx]; + for (int i = 0; i < justGood.length; i++) { + justGood[i] = good[i]; + } + + if (!errors.isEmpty()) { + locationPanel.setValues(justGood); + } + + return errors; + } + + + /** + * This method returns the selected data. + * + * @return the selected/inserted data. + */ + public Data[] getData() { + saveLocationValues(locationPanel); + double[] values = getLocationValues(); + Data[] data = new Data[2]; + boolean first = true; + String valueString = ""; + + for (int i = 0; i < values.length; i++) { + if (!first) valueString += " "; + else first = false; + valueString += Double.valueOf(values[i]).toString(); + } + + data[0] = createDataArray(getDataItemName(), valueString); + + data[1] = createDataArray("ld_mode", "locations"); + + return data; + } + + + /** Hook service to the listgrid with possible input values. */ + protected void setPickerDataSource() { + Config config = Config.getInstance(); + String url = config.getServerUrl(); + String river = ""; + + ArtifactDescription adescr = artifact.getArtifactDescription(); + DataList[] data = adescr.getOldData(); + + // Try to find a "river" data item to set the source for the + // list grid. + if (data != null && data.length > 0) { + for (int i = 0; i < data.length; i++) { + DataList dl = data[i]; + if (dl.getState().equals("state.winfo.river") || + dl.getState().equals("state.chart.river")) { + for (int j = 0; j < dl.size(); j++) { + Data d = dl.get(j); + DataItem[] di = d.getItems(); + if (di != null && di.length == 1) { + river = d.getItems()[0].getStringValue(); + break; + } + } + } + } + } + + picker.getLocationTable().setDataSource(new DistanceInfoDataSource( + url, river, "locations")); + } + + // TODO allow multiple selections here or in LocationPanel + /** + * Callback when an item from the input helper was clicked. + * Set the respective km-value in the location value field. + * @param e event passed. + */ + public void onRecordClick (RecordClickEvent e) { + Record record = e.getRecord(); + double[] selected = new double[1]; + try { + selected[0] = + Double.parseDouble(record.getAttribute("from")); + } + catch(NumberFormatException nfe) { + // Is there anything else to do here? + } + setLocationValues(selected); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 87572e476f7a -r 66671b69c7ea flys-client/src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java --- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java Wed Feb 08 16:20:30 2012 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java Wed Feb 08 16:24:39 2012 +0000 @@ -1,54 +1,19 @@ package de.intevation.flys.client.client.ui; -import com.google.gwt.core.client.GWT; - -import com.smartgwt.client.util.SC; -import com.smartgwt.client.widgets.Canvas; -import com.smartgwt.client.widgets.Label; -import com.smartgwt.client.widgets.form.fields.events.BlurHandler; -import com.smartgwt.client.widgets.form.fields.events.BlurEvent; - -import com.smartgwt.client.widgets.layout.HLayout; -import com.smartgwt.client.widgets.layout.VLayout; +import java.util.ArrayList; +import java.util.List; -import com.smartgwt.client.widgets.grid.events.RecordClickHandler; -import com.smartgwt.client.widgets.grid.events.RecordClickEvent; +import com.google.gwt.i18n.client.NumberFormat; -import com.smartgwt.client.data.Record; - -import de.intevation.flys.client.shared.model.ArtifactDescription; import de.intevation.flys.client.shared.model.Data; -import de.intevation.flys.client.shared.model.DataItem; -import de.intevation.flys.client.shared.model.DataList; -import de.intevation.flys.client.shared.model.DistanceInfoObject; -import de.intevation.flys.client.shared.model.RangeData; - -import de.intevation.flys.client.client.services.DistanceInfoService; -import de.intevation.flys.client.client.services.DistanceInfoServiceAsync; -import de.intevation.flys.client.client.Config; -import de.intevation.flys.client.client.ui.range.DistanceInfoDataSource; /** * This UIProvider creates a widget to enter a single location (km). - * - * @author Raimund Renkert */ public class SingleLocationPanel -extends LocationPanel -implements RecordClickHandler +extends MultipleLocationPanel { - /** The DistanceInfoService used to retrieve locations about rivers. */ - protected DistanceInfoServiceAsync distanceInfoService = - GWT.create(DistanceInfoService.class); - - /** The table data. */ - protected DistanceInfoObject[] tableData; - - /** The input helper (usually right side, table to click on, values are - * then entered in the texfield. */ - protected LocationPicker picker; - /** * Creates a new LocationDistancePanel instance. */ @@ -57,122 +22,51 @@ } - /** - * This method creates a widget that contains a label, a panel with - * checkboxes to switch the input mode between location and distance input, - * and a mode specific panel. - * - * @param data The data that might be inserted. - * - * @return a panel. - */ + /** Overridden to restrict to one entered value. */ @Override - public Canvas create(DataList data) { - findDataItemName(data); - - VLayout layout = new VLayout(); - layout.setMembersMargin(10); - - Label label = new Label(MSG.location ()); - Canvas widget = createWidget(data); - Canvas submit = getNextButton(); - - initDefaults(data); - - picker.createLocationTable(); + public List validate() { + List errors = new ArrayList(); + NumberFormat nf = NumberFormat.getDecimalFormat(); - widget.setHeight(50); - label.setHeight(25); - - layout.addMember(label); - layout.addMember(widget); - layout.addMember(submit); - - return layout; - } - + saveLocationValues(locationPanel); - /** - * This method reads the default values defined in the DataItems of the Data - * objects in list. - * - * @param list The DataList container that stores the Data objects. - */ - protected void initDefaults(DataList list) { - Data data = list.get(0); + if (!locationPanel.validateForm()) { + errors.add(MSG.wrongFormat()); + return errors; + } - // Compatibility with MinMax- DataItems: - RangeData rangeData = null; + double[] values = getLocationValues(); + double[] good = new double[values.length]; + int idx = 0; - for (int i = 0, n = list.size(); i < n; i++) { - Data tmp = list.get(i); + // We want just one value to be allowed. + if (values.length > 1) { + errors.add(MSG.too_many_values()); + } - if (tmp instanceof RangeData) { - rangeData = (RangeData) tmp; + for (double value: values) { + if (value < min || value > max) { + String tmp = MSG.error_validate_range(); + tmp = tmp.replace("$1", nf.format(value)); + tmp = tmp.replace("$2", nf.format(min)); + tmp = tmp.replace("$3", nf.format(max)); + errors.add(tmp); + } + else { + good[idx++] = value; } } - if (rangeData != null) { - min = Double.parseDouble(rangeData.getDefaultLower().toString()); - max = Double.parseDouble(rangeData.getDefaultUpper().toString()); - // catch ..? - } - else { - DataItem[] items = data.getItems(); - DataItem iMin = getDataItem(items, "min"); - DataItem iMax = getDataItem(items, "max"); - - try { - min = Double.parseDouble(iMin.getStringValue()); - max = Double.parseDouble(iMax.getStringValue()); - } - catch (NumberFormatException nfe) { - SC.warn(MSG.error_read_minmax_values()); - min = -Double.MAX_VALUE; - max = Double.MAX_VALUE; - } + double[] justGood = new double[idx]; + for (int i = 0; i < justGood.length; i++) { + justGood[i] = good[i]; } - DataItem def = data.getDefault(); - if (def != null) { - String value = def.getStringValue(); - - try { - double d = Double.parseDouble(value); - setLocationValues(new double[] { d } ); - } - catch (NumberFormatException nfe) { - // could not parse, dont know what to do else - } + if (!errors.isEmpty()) { + locationPanel.setValues(justGood); } - } - - - protected Canvas createWidget(DataList data) { - VLayout layout = new VLayout(); - inputLayout = new HLayout(); - // The initial view will display the location input mode. - locationPanel = new DoubleArrayPanel( - MSG.unitLocation(), - getLocationValues(), - new BlurHandler(){public void onBlur(BlurEvent be) {}}); - - picker.getLocationTable().setAutoFetchData(true); - - inputLayout.addMember(locationPanel); - - layout.addMember(inputLayout); - - inputLayout.setMembersMargin(30); - - picker.prepareFilter(); - - helperContainer.addMember(picker.getLocationTable()); - helperContainer.addMember(picker.getFilterLayout()); - helperContainer.addMember(picker.getResultCountForm()); - setPickerDataSource(); - return layout; + return errors; } @@ -183,68 +77,17 @@ */ public Data[] getData() { saveLocationValues(locationPanel); - double[] values = getLocationValues(); + double[] values = getLocationValues(); Data[] data = new Data[values.length+1]; for (int i = 0; i < values.length; i++) { data[i] = createDataArray(getDataItemName(), Double.valueOf(values[i]).toString()); } + data[values.length] = createDataArray("ld_mode", "locations"); return data; } - - - /** Hook service to the listgrid with possible input values. */ - protected void setPickerDataSource() { - Config config = Config.getInstance(); - String url = config.getServerUrl(); - String river = ""; - - ArtifactDescription adescr = artifact.getArtifactDescription(); - DataList[] data = adescr.getOldData(); - - // Try to find a "river" data item to set the source for the - // list grid. - if (data != null && data.length > 0) { - for (int i = 0; i < data.length; i++) { - DataList dl = data[i]; - if (dl.getState().equals("state.winfo.river") || - dl.getState().equals("state.chart.river")) { - for (int j = 0; j < dl.size(); j++) { - Data d = dl.get(j); - DataItem[] di = d.getItems(); - if (di != null && di.length == 1) { - river = d.getItems()[0].getStringValue(); - break; - } - } - } - } - } - - picker.getLocationTable().setDataSource(new DistanceInfoDataSource( - url, river, "locations")); - } - - - /** - * Callback when an item from the input helper was clicked. - * Set the respective km-value in the location value field. - * @param e event passed. - */ - public void onRecordClick (RecordClickEvent e) { - Record record = e.getRecord(); - double[] selected = new double[1]; - try { - selected[0] = - Double.parseDouble(record.getAttribute("from")); - } - catch(NumberFormatException nfe) { - // Is there anything else to do here? - } - setLocationValues(selected); - } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 87572e476f7a -r 66671b69c7ea flys-client/src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java --- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java Wed Feb 08 16:20:30 2012 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java Wed Feb 08 16:24:39 2012 +0000 @@ -2,6 +2,13 @@ import de.intevation.flys.client.shared.model.User; + +/** + * Depending on the provider the state declared, return a UIProvider. + * + * A UIProvider provides widgets and input helpers to guide input to an + * artifacts state. + */ public class UIProviderFactory { private UIProviderFactory() { @@ -20,6 +27,9 @@ else if (uiProvider.equals("location_panel")) { return new SingleLocationPanel(); } + else if (uiProvider.equals("multi_location_panel")) { + return new MultipleLocationPanel(); + } else if (uiProvider.equals("distance_panel")) { return new DistancePanel(); }