# HG changeset patch # User Ingo Weinzierl # Date 1300290733 0 # Node ID ba7df4a24ae0b331daed57c41158531acc432c8f # Parent 87a44f8e25cc1e4acd1b6f55b1ea2f2b14a1ea59 Added a new widget to enter w/Q values in single and range mode. flys-client/trunk@1483 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 87a44f8e25cc -r ba7df4a24ae0 flys-client/ChangeLog --- a/flys-client/ChangeLog Wed Mar 16 09:57:41 2011 +0000 +++ b/flys-client/ChangeLog Wed Mar 16 15:52:13 2011 +0000 @@ -1,3 +1,24 @@ +2011-03-16 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added + i18n strings used in the WQInputPanel. + + * src/main/java/de/intevation/flys/client/client/ui/DoubleRangePanel.java: + New. This panel contains three input fields that enables the user to + enter a start and end value and a step width. Furthermore, there are + methods to validate the fields and to retrieve its values. + + * src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java: + New. This panel contains a single input field that enables the user to + enter a list of double values. There is a method to validate the input + and a method to retrieve the list of entered double values. + + * src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java: + New. This panel allows the user to enter W or Q values for single or + range input in one single state. + 2011-03-16 Ingo Weinzierl * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, diff -r 87a44f8e25cc -r ba7df4a24ae0 flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages.java --- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages.java Wed Mar 16 09:57:41 2011 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages.java Wed Mar 16 15:52:13 2011 +0000 @@ -94,5 +94,44 @@ @DefaultMessage("Wrong format") String wrongFormat(); + + @DefaultMessage("Input for W/Q Data") + String wqTitle(); + + @DefaultMessage("W at gauge [cm]") + String wqW(); + + @DefaultMessage("Q [m³/s]") + String wqQ(); + + @DefaultMessage("Single values") + String wqSingle(); + + @DefaultMessage("Range") + String wqRange(); + + @DefaultMessage("cm") + String unitWSingle(); + + @DefaultMessage("cm -") + String unitWFrom(); + + @DefaultMessage("cm a") + String unitWTo(); + + @DefaultMessage("cm") + String unitWStep(); + + @DefaultMessage("m³/s") + String unitQSingle(); + + @DefaultMessage("m³/s -") + String unitQFrom(); + + @DefaultMessage("m³/s a") + String unitQTo(); + + @DefaultMessage("m³/s") + String unitQStep(); } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 87a44f8e25cc -r ba7df4a24ae0 flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties --- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties Wed Mar 16 09:57:41 2011 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties Wed Mar 16 15:52:13 2011 +0000 @@ -27,3 +27,17 @@ unitWidth = m unitLocation = km wrongFormat = Falsches Format + +wqTitle = Eingabe für W/Q Daten +wqW = W am Pegel [cm] +wqQ = Q [m³/s] +wqSingle = Einzelwerte +wqRange = Wertebereich +unitWSingle = cm +unitWFrom = cm - +unitWTo = cm a +unitWStep = cm +unitQSingle = m³/s +unitQFrom = m³/s - +unitQTo = m³/s a +unitQStep = m³/s diff -r 87a44f8e25cc -r ba7df4a24ae0 flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties --- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties Wed Mar 16 09:57:41 2011 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties Wed Mar 16 15:52:13 2011 +0000 @@ -27,3 +27,9 @@ unitWidth = m unitLocation = km wrongFormat = Wrong format + +wqTitle = Input for W/Q Data +wqW = W at Gauge [cm] +wqQ = Q [m³/s] +wqSingle = Single values +wqRange = Range diff -r 87a44f8e25cc -r ba7df4a24ae0 flys-client/src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java Wed Mar 16 15:52:13 2011 +0000 @@ -0,0 +1,159 @@ +package de.intevation.flys.client.client.ui; + +import java.util.Map; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.i18n.client.NumberFormat; + +import com.smartgwt.client.types.TitleOrientation; +import com.smartgwt.client.widgets.form.DynamicForm; +import com.smartgwt.client.widgets.form.fields.FormItem; +import com.smartgwt.client.widgets.form.fields.StaticTextItem; +import com.smartgwt.client.widgets.form.fields.TextItem; +import com.smartgwt.client.widgets.form.fields.events.BlurHandler; + +import de.intevation.flys.client.client.FLYSMessages; + +public class DoubleArrayPanel +extends DynamicForm +{ + /** The message class that provides i18n strings.*/ + protected FLYSMessages MESSAGES = GWT.create(FLYSMessages.class); + + + /** The constant input field name.*/ + public static final String FIELD_NAME = "doublearray"; + + + /** + * Creates a new form with a single input field that displays an array of + * double values. + * + * @param name The name of the TextItem. + * @param title The title of the TextItem. + * @param values The double values that should be displayed initially. + * @param handler The BlurHandler that is used to valide the input. + */ + public DoubleArrayPanel( + String title, + double[] values, + BlurHandler handler) + { + TextItem ti = new TextItem(FIELD_NAME); + StaticTextItem sti = new StaticTextItem("staticarray"); + + ti.setShowTitle(false); + sti.setShowTitle(false); + sti.setValue(title); + + ti.addBlurHandler(handler); + + setFields(ti, sti); + setTitleOrientation(TitleOrientation.RIGHT); + setNumCols(2); + + if (values == null) { + return; + } + + NumberFormat f = NumberFormat.getDecimalFormat(); + + StringBuilder text = new StringBuilder(); + boolean firstItem = true; + + for (double val: values) { + if (!firstItem) { + text.append(" "); + } + + text.append(f.format(val)); + + firstItem = false; + } + + ti.setValue(text.toString()); + } + + + /** + * This method validates the entered text in the location input field. If + * there are values that doesn't represent a valid location, an error is + * displayed. + * + * @param item The FormItem. + */ + protected boolean validateForm(FormItem item) { + boolean valid = true; + String value = (String) item.getValue(); + + if (value == null) { + return valid; + } + + String[] parts = value.split(" "); + + if (parts == null) { + return valid; + } + + NumberFormat f = NumberFormat.getDecimalFormat(); + Map errors = getErrors(); + + try { + for (String part: parts) { + double location = f.parse(part); + } + + errors.remove(item.getFieldName()); + } + catch (NumberFormatException nfe) { + errors.put(item.getFieldName(), MESSAGES.wrongFormat()); + + valid = false; + } + + setErrors(errors, true); + + return valid; + } + + + /** + * This method returns the double array that has been entered in + * item. + * + * @param item The item that contains the desired values. + * + * @return the values as double array. + */ + public double[] getInputValues(FormItem item) { + String value = (String) item.getValue(); + + if (value == null) { + return null; + } + + String[] parts = value.split(" "); + + if (parts == null) { + return null; + } + + double[] values = new double[parts.length]; + + NumberFormat f = NumberFormat.getDecimalFormat(); + + int i = 0; + for (String part: parts) { + try { + values[i++] = f.parse(part); + } + catch (NumberFormatException nfe) { + // do nothing + } + } + + return values; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 87a44f8e25cc -r ba7df4a24ae0 flys-client/src/main/java/de/intevation/flys/client/client/ui/DoubleRangePanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/DoubleRangePanel.java Wed Mar 16 15:52:13 2011 +0000 @@ -0,0 +1,183 @@ +package de.intevation.flys.client.client.ui; + +import java.util.Map; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.i18n.client.NumberFormat; + +import com.smartgwt.client.types.Alignment; +import com.smartgwt.client.widgets.form.DynamicForm; +import com.smartgwt.client.widgets.form.fields.FloatItem; +import com.smartgwt.client.widgets.form.fields.FormItem; +import com.smartgwt.client.widgets.form.fields.StaticTextItem; +import com.smartgwt.client.widgets.form.fields.events.BlurHandler; + +import de.intevation.flys.client.client.FLYSMessages; + + + +/** + * This class creates a DynamicForm with three input fields. + * + * @author Ingo Weinzierl + */ +public class DoubleRangePanel +extends DynamicForm +{ + /** The message class that provides i18n strings.*/ + protected FLYSMessages MESSAGES = GWT.create(FLYSMessages.class); + + + /** The constant name of the input field to enter the start of a distance.*/ + public static final String FIELD_FROM = "from"; + + /** The constant name of the input field to enter the end of a distance.*/ + public static final String FIELD_TO = "to"; + + /** The constant name of the input field to enter the step width of a + * distance.*/ + public static final String FIELD_WIDTH = "step"; + + + /** + * Creates a new form with a single input field that displays an array of + * double values. + * + * @param name The name of the TextItem. + * @param title The title of the TextItem. + * @param values The double values that should be displayed initially. + * @param handler The BlurHandler that is used to valide the input. + */ + public DoubleRangePanel( + String titleFrom, String titleTo, String titleStep, + double from, double to, double step, + int width, + BlurHandler handler) + { + FloatItem fromItem = new FloatItem(FIELD_FROM); + FloatItem toItem = new FloatItem(FIELD_TO); + FloatItem stepItem = new FloatItem(FIELD_WIDTH); + + fromItem.addBlurHandler(handler); + toItem.addBlurHandler(handler); + stepItem.addBlurHandler(handler); + + NumberFormat f = NumberFormat.getDecimalFormat(); + + fromItem.setValue(f.format(from)); + toItem.setValue(f.format(to)); + stepItem.setValue(f.format(step)); + + StaticTextItem fromText = new StaticTextItem("staticFrom"); + fromText.setValue(titleFrom); + fromText.setShowTitle(false); + fromItem.setShowTitle(false); + + StaticTextItem toText = new StaticTextItem("staticTo"); + toText.setValue(titleTo); + toText.setShowTitle(false); + toItem.setShowTitle(false); + + StaticTextItem stepText = new StaticTextItem("staticStep"); + stepText.setValue(titleStep); + stepText.setShowTitle(false); + stepItem.setShowTitle(false); + + int itemWidth = width / 6; + fromItem.setWidth(itemWidth); + fromText.setWidth(itemWidth); + toItem.setWidth(itemWidth); + toText.setWidth(itemWidth); + stepItem.setWidth(itemWidth); + stepText.setWidth(itemWidth); + + setFields(fromItem, fromText, toItem, toText, stepItem, stepText); + setFixedColWidths(false); + setNumCols(6); + setWidth(width); + setAlign(Alignment.CENTER); + } + + + /** + * This method validates the entered text in the input fields. If + * there are values that doesn't represent a valid float, an error is + * displayed. + * + * @param item The FormItem. + */ + protected boolean validateForm(FormItem item) { + boolean valid = true; + + String v = (String) item.getValue(); + + NumberFormat f = NumberFormat.getDecimalFormat(); + Map errors = getErrors(); + + try { + double value = f.parse(v); + + errors.remove(item.getFieldName()); + } + catch (NumberFormatException nfe) { + errors.put(item.getFieldName(), MESSAGES.wrongFormat()); + + item.focusInItem(); + + valid = false; + } + + setErrors(errors, true); + + return valid; + } + + + /** + * Returns the double value of value. + * + * @return the double value of value. + */ + protected double getDouble(String value) { + NumberFormat f = NumberFormat.getDecimalFormat(); + + return f.parse(value); + } + + + /** + * Returns the start value. + * + * @return the start value. + */ + public double getFrom() { + String v = getValueAsString(FIELD_FROM); + + return getDouble(v); + } + + + /** + * Returns the end value. + * + * @return the end value. + */ + public double getTo() { + String v = getValueAsString(FIELD_TO); + + return getDouble(v); + } + + + /** + * Returns the step width. + * + * @return the step width. + */ + public double getStep() { + String v = getValueAsString(FIELD_WIDTH); + + return getDouble(v); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 87a44f8e25cc -r ba7df4a24ae0 flys-client/src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java Wed Mar 16 15:52:13 2011 +0000 @@ -0,0 +1,404 @@ +package de.intevation.flys.client.client.ui; + +import java.util.LinkedHashMap; + +import com.google.gwt.core.client.GWT; + +import com.smartgwt.client.widgets.Canvas; +import com.smartgwt.client.widgets.IButton; +import com.smartgwt.client.widgets.Label; +import com.smartgwt.client.widgets.form.DynamicForm; +import com.smartgwt.client.widgets.form.fields.FormItem; +import com.smartgwt.client.widgets.form.fields.RadioGroupItem; +import com.smartgwt.client.widgets.form.fields.events.BlurHandler; +import com.smartgwt.client.widgets.form.fields.events.BlurEvent; +import com.smartgwt.client.widgets.form.fields.events.ChangeHandler; +import com.smartgwt.client.widgets.form.fields.events.ChangeEvent; +import com.smartgwt.client.widgets.layout.VLayout; + +import de.intevation.flys.client.shared.model.Data; +import de.intevation.flys.client.client.FLYSMessages; + + +/** + * This UIProvider creates a widget to enter W or Q data. + * + * @author Ingo Weinzierl + */ +public class WQInputPanel +extends AbstractUIProvider +implements ChangeHandler, BlurHandler +{ + /** The message class that provides i18n strings.*/ + protected FLYSMessages MSG = GWT.create(FLYSMessages.class); + + + /** The constant field name for choosing w or q mode.*/ + public static final String FIELD_WQ = "wq"; + + /** The constant field value for W input mode.*/ + public static final String FIELD_WQ_W = "W"; + + /** The constant field value for Q input mode.*/ + public static final String FIELD_WQ_Q = "Q"; + + /** The constant field name for choosing single values or range.*/ + public static final String FIELD_MODE = "mode"; + + /** The constant field value for single input mode.*/ + public static final String FIELD_MODE_SINGLE = "single"; + + /** The constant field value for range input mode.*/ + public static final String FIELD_MODE_RANGE = "range"; + + /** The constant value that determines the width of the left panel.*/ + public static final int WIDTH_LEFT = 200; + + + /** The container that manages the w and q panels.*/ + protected VLayout container; + + /** The RadioGroupItem that determines the w/q input mode.*/ + protected DynamicForm modes; + + /** The 'from' value entered in the range W mode.*/ + protected double fromW; + + /** The 'to' value entered in the range W mode.*/ + protected double toW; + + /** The 'step' value entered in the range W mode.*/ + protected double stepW; + + /** The values entered in the single W mode.*/ + protected double[] valuesW; + + /** The 'from' value entered in the range Q mode.*/ + protected double fromQ; + + /** The 'to' value entered in the range Q mode.*/ + protected double toQ; + + /** The 'step' value entered in the range Q mode.*/ + protected double stepQ; + + /** The values entered in the single Q mode.*/ + protected double[] valuesQ; + + + /** + * Creates a new WQInputPanel instance. + */ + public WQInputPanel() { + } + + + /** + * This method calls createWidget and puts a 'next' button to the bottom. + * + * @param data The data that is displayed. + * + * @return the widget. + */ + public Canvas create(Data data) { + Canvas widget = createWidget(data); + IButton submit = new IButton(MSG.next()); + Label label = new Label(MSG.wqTitle()); + + label.setHeight(25); + + VLayout layout = new VLayout(); + layout.addMember(label); + layout.addMember(widget); + layout.addMember(submit); + + return layout; + } + + + /** + * This method creates the whole widget. There is a panel on the left, that + * allows the user to enter values manually by keyboard. On the right, there + * is a table that allows the user to enter values by mouse click. + * + * @param data The data that is displayed in the table on the right. + * + * @return the widget. + */ + protected Canvas createWidget(Data data) { + VLayout layout = new VLayout(); + container = new VLayout(); + Canvas modeForm = createModePanel(); + + layout.addMember(modeForm); + layout.addMember(container); + + // TODO add a table on the right to select Q values + + return layout; + } + + + /** + * This method creates the mode panel. It contains two radio button panels + * that allows the user to switch the input mode between w/q and + * single/range input. + * + * @return a panel. + */ + protected Canvas createModePanel() { + RadioGroupItem wq = new RadioGroupItem(FIELD_WQ); + wq.setShowTitle(false); + wq.setVertical(false); + wq.setWidth(WIDTH_LEFT); + + RadioGroupItem mode = new RadioGroupItem(FIELD_MODE); + mode.setShowTitle(false); + mode.setVertical(false); + mode.setWidth(WIDTH_LEFT); + + LinkedHashMap wqValues = new LinkedHashMap(); + wqValues.put(FIELD_WQ_W, MSG.wqW()); + wqValues.put(FIELD_WQ_Q, MSG.wqQ()); + + LinkedHashMap modeValues = new LinkedHashMap(); + modeValues.put(FIELD_MODE_SINGLE, MSG.wqSingle()); + modeValues.put(FIELD_MODE_RANGE, MSG.wqRange()); + + wq.setValueMap(wqValues); + mode.setValueMap(modeValues); + + wq.addChangeHandler(this); + mode.addChangeHandler(this); + + modes = new DynamicForm(); + modes.setFields(wq, mode); + modes.setWidth(WIDTH_LEFT); + modes.setNumCols(1); + + LinkedHashMap initial = new LinkedHashMap(); + initial.put(FIELD_WQ, FIELD_WQ_W); + initial.put(FIELD_MODE, FIELD_MODE_SINGLE); + modes.setValues(initial); + + return modes; + } + + + /** + * This method returns the selected data. + * + * @return the selected/inserted data. + */ + public Data[] getData() { + // TODO Implement me + + return null; + } + + + /** + * This method changes the lower panel with the input fields depending on + * the combination of the two radio button panels. + * + * @param event The ChangeEvent. + */ + public void onChange(ChangeEvent event) { + DynamicForm form = event.getForm(); + FormItem item = event.getItem(); + + String wqMode = null; + String inputMode = null; + + if (item.getFieldName().equals(FIELD_MODE)) { + wqMode = form.getValueAsString(FIELD_WQ); + inputMode = (String) event.getValue(); + } + else { + wqMode = (String) event.getValue(); + inputMode = form.getValueAsString(FIELD_MODE); + } + + container.removeMembers(container.getMembers()); + + Canvas newPanel = null; + + if (wqMode.equals(FIELD_WQ_W)) { + if (inputMode.equals(FIELD_MODE_SINGLE)) { + // Single W mode + double[] values = getSingleW(); + + newPanel = new DoubleArrayPanel( + MSG.unitWSingle(), values, this); + } + else { + // Range W mode + double from = getFromW(); + double to = getToW(); + double step = getStepW(); + + newPanel = new DoubleRangePanel( + MSG.unitWFrom(), MSG.unitWTo(), MSG.unitWStep(), + from, to, step, + 250, + this); + } + } + else { + if (inputMode.equals(FIELD_MODE_SINGLE)) { + // Single Q mode + double[] values = getSingleQ(); + + newPanel = new DoubleArrayPanel( + MSG.unitQSingle(), values, this); + } + else { + // Range Q mode + double from = getFromQ(); + double to = getToQ(); + double step = getStepQ(); + + newPanel = new DoubleRangePanel( + MSG.unitQFrom(), MSG.unitQTo(), MSG.unitQStep(), + from, to, step, + 250, + this); + } + } + + container.addMember(newPanel); + } + + + /** + * This method is called if the value of one of the input fields might have + * changed. The entered values are validated and stored. + * + * @param event The BlurEvent. + */ + public void onBlur(BlurEvent event) { + DynamicForm form = event.getForm(); + FormItem item = event.getItem(); + + String wqMode = (String) modes.getValue(FIELD_WQ); + String inputMode = (String) modes.getValue(FIELD_MODE); + + if (wqMode.equals(FIELD_WQ_W)) { + if (inputMode.equals(FIELD_MODE_SINGLE)) { + DoubleArrayPanel p = (DoubleArrayPanel) form; + + if (p.validateForm(item)) { + setSingleW(p.getInputValues(item)); + } + } + else { + DoubleRangePanel p = (DoubleRangePanel) form; + + if (p.validateForm(item)) { + setFromW(p.getFrom()); + setToW(p.getTo()); + setStepW(p.getStep()); + } + } + } + else { + if (inputMode.equals(FIELD_MODE_SINGLE)) { + DoubleArrayPanel p = (DoubleArrayPanel) form; + + if (p.validateForm(item)) { + setSingleQ(p.getInputValues(item)); + } + } + else { + DoubleRangePanel p = (DoubleRangePanel) form; + + if (p.validateForm(item)) { + setFromQ(p.getFrom()); + setToQ(p.getTo()); + setStepQ(p.getStep()); + } + } + } + } + + + protected double[] getSingleQ() { + return valuesQ; + } + + + protected void setSingleQ(double[] values) { + valuesQ = values; + } + + + protected double getFromQ() { + return fromQ; + } + + + protected void setFromQ(double fromQ) { + this.fromQ = fromQ; + } + + + protected double getToQ() { + return toQ; + } + + + protected void setToQ(double toQ) { + this.toQ = toQ; + } + + + protected double getStepQ() { + return stepQ; + } + + + protected void setStepQ(double stepQ) { + this.stepQ = stepQ; + } + + + protected double[] getSingleW() { + return valuesW; + } + + + protected void setSingleW(double[] values) { + valuesW = values; + } + + + protected double getFromW() { + return fromW; + } + + + protected void setFromW(double fromW) { + this.fromW = fromW; + } + + + protected double getToW() { + return toW; + } + + + protected void setToW(double toW) { + this.toW = toW; + } + + + protected double getStepW() { + return stepW; + } + + + protected void setStepW(double stepW) { + this.stepW = stepW; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :