felix@1612: package de.intevation.flys.client.client.ui;
felix@1612:
felix@1612: import java.util.ArrayList;
felix@1612: import java.util.List;
felix@1612:
felix@1612: import com.google.gwt.core.client.GWT;
felix@1612: import com.google.gwt.i18n.client.NumberFormat;
felix@1612:
felix@1612: import com.smartgwt.client.util.SC;
felix@1612: import com.smartgwt.client.widgets.Canvas;
felix@1612: import com.smartgwt.client.widgets.Label;
felix@1612: import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
felix@1612: import com.smartgwt.client.widgets.form.fields.events.BlurEvent;
felix@1612:
felix@1612: import com.smartgwt.client.widgets.layout.HLayout;
felix@1612: import com.smartgwt.client.widgets.layout.VLayout;
felix@1612:
felix@1612: import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
felix@1612: import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
felix@1612:
felix@1612: import com.smartgwt.client.data.Record;
felix@1612:
felix@1612: import de.intevation.flys.client.shared.model.ArtifactDescription;
felix@1612: import de.intevation.flys.client.shared.model.Data;
felix@1612: import de.intevation.flys.client.shared.model.DataItem;
felix@1612: import de.intevation.flys.client.shared.model.DataList;
felix@1612: import de.intevation.flys.client.shared.model.DistanceInfoObject;
felix@1617: import de.intevation.flys.client.shared.DoubleUtils;
felix@1612: import de.intevation.flys.client.shared.model.RangeData;
felix@1612:
felix@1612: import de.intevation.flys.client.client.services.DistanceInfoService;
felix@1612: import de.intevation.flys.client.client.services.DistanceInfoServiceAsync;
felix@1612: import de.intevation.flys.client.client.Config;
felix@1612: import de.intevation.flys.client.client.ui.range.DistanceInfoDataSource;
felix@1612:
felix@1612:
felix@1612: /**
felix@1612: * This UIProvider creates a widget to enter a single location (km).
felix@1612: *
felix@1612: * @author Raimund Renkert
felix@1612: */
felix@1612: public class MultipleLocationPanel
felix@1612: extends LocationPanel
felix@1612: implements RecordClickHandler
felix@1612: {
felix@1612: /** The DistanceInfoService used to retrieve locations about rivers. */
felix@1612: protected DistanceInfoServiceAsync distanceInfoService =
felix@1612: GWT.create(DistanceInfoService.class);
felix@1612:
felix@1612: /** The table data. */
felix@1612: protected DistanceInfoObject[] tableData;
felix@1612:
felix@1612: /** The input helper (usually right side, table to click on, values are
felix@1612: * then entered in the texfield. */
felix@1612: protected LocationPicker picker;
felix@1612:
felix@1615:
felix@1612: /**
felix@1612: * Creates a new LocationDistancePanel instance.
felix@1612: */
felix@1612: public MultipleLocationPanel() {
felix@1612: picker = new LocationPicker(this);
felix@1612: }
felix@1612:
felix@1612:
felix@1612: /**
felix@1612: * This method creates a widget that contains a label, a panel with
felix@1612: * checkboxes to switch the input mode between location and distance input,
felix@1612: * and a mode specific panel.
felix@1612: *
felix@1612: * @param data The data that might be inserted.
felix@1612: *
felix@1612: * @return a panel.
felix@1612: */
felix@1612: @Override
felix@1612: public Canvas create(DataList data) {
felix@1612: findDataItemName(data);
felix@1612:
felix@1612: VLayout layout = new VLayout();
felix@1612: layout.setMembersMargin(10);
felix@1612:
felix@1615: // Take translated data item name as label, if translation available.
felix@1615: String labelString;
felix@1615: try {
felix@1615: labelString = MSG.getString(getDataItemName());
felix@1615: }
felix@1615: catch(java.util.MissingResourceException mre) {
felix@1615: GWT.log("Cannot find translation for data item name : " + getDataItemName());
raimund@3493: labelString = getLabelString();
felix@1615: }
felix@1615: Label label = new Label(labelString);
felix@1612: Canvas widget = createWidget(data);
felix@1612: Canvas submit = getNextButton();
felix@1612:
felix@1612: initDefaults(data);
felix@1612:
felix@1612: picker.createLocationTable();
felix@1612:
felix@1612: widget.setHeight(50);
felix@1612: label.setHeight(25);
felix@1612:
felix@1612: layout.addMember(label);
felix@1612: layout.addMember(widget);
felix@1612: layout.addMember(submit);
felix@1612:
felix@1612: return layout;
felix@1612: }
felix@1612:
felix@1612:
felix@1612: /**
felix@1612: * This method reads the default values defined in the DataItems of the Data
felix@1612: * objects in list.
felix@1612: *
felix@1612: * @param list The DataList container that stores the Data objects.
felix@1612: */
felix@1612: protected void initDefaults(DataList list) {
felix@1612: Data data = list.get(0);
felix@1612:
felix@1612: // Compatibility with MinMax- DataItems:
felix@1612: RangeData rangeData = null;
felix@1612:
felix@1612: for (int i = 0, n = list.size(); i < n; i++) {
felix@1612: Data tmp = list.get(i);
felix@1612:
felix@1612: if (tmp instanceof RangeData) {
felix@1612: rangeData = (RangeData) tmp;
felix@1612: }
felix@1612: }
felix@1612:
felix@1612: if (rangeData != null) {
felix@1612: min = Double.parseDouble(rangeData.getDefaultLower().toString());
felix@1612: max = Double.parseDouble(rangeData.getDefaultUpper().toString());
felix@1612: // catch ..?
felix@1612: }
felix@1612: else {
felix@1612: DataItem[] items = data.getItems();
felix@1612: DataItem iMin = getDataItem(items, "min");
felix@1612: DataItem iMax = getDataItem(items, "max");
sascha@2905:
felix@1612: try {
felix@1612: min = Double.parseDouble(iMin.getStringValue());
felix@1612: max = Double.parseDouble(iMax.getStringValue());
felix@1612: }
felix@1612: catch (NumberFormatException nfe) {
felix@1612: SC.warn(MSG.error_read_minmax_values());
felix@1612: min = -Double.MAX_VALUE;
felix@1612: max = Double.MAX_VALUE;
felix@1612: }
felix@1612: }
felix@1612:
felix@1612: DataItem def = data.getDefault();
felix@1612: if (def != null) {
felix@1612: String value = def.getStringValue();
felix@1612:
felix@1612: try {
felix@1612: double d = Double.parseDouble(value);
felix@1612: setLocationValues(new double[] { d } );
felix@1612: }
felix@1612: catch (NumberFormatException nfe) {
felix@1612: // could not parse, dont know what to do else
felix@1612: }
felix@1612: }
felix@1612: }
felix@1612:
felix@1612:
felix@1612: protected Canvas createWidget(DataList data) {
felix@1612: VLayout layout = new VLayout();
felix@1612: inputLayout = new HLayout();
felix@1612:
felix@1612: // The initial view will display the location input mode.
felix@1612: locationPanel = new DoubleArrayPanel(
felix@1612: MSG.unitLocation(),
felix@1612: getLocationValues(),
raimund@3539: new BlurHandler(){public void onBlur(BlurEvent be) {validate();}});
felix@1612:
felix@1612: picker.getLocationTable().setAutoFetchData(true);
felix@1612:
felix@1612: inputLayout.addMember(locationPanel);
felix@1612:
felix@1612: layout.addMember(inputLayout);
felix@1612:
felix@1612: inputLayout.setMembersMargin(30);
felix@1612:
felix@1612: picker.prepareFilter();
felix@1612:
felix@1612: helperContainer.addMember(picker.getLocationTable());
felix@1612: helperContainer.addMember(picker.getFilterLayout());
felix@1612: helperContainer.addMember(picker.getResultCountForm());
felix@1612: setPickerDataSource();
felix@1612: return layout;
felix@1612: }
felix@1612:
felix@1612:
felix@1612: /** Overridden to restrict to one entered value. */
felix@1612: @Override
felix@1612: public List validate() {
felix@1612: List errors = new ArrayList();
felix@1612: NumberFormat nf = NumberFormat.getDecimalFormat();
felix@1612:
raimund@3539: DataList[] ref = artifact.getArtifactDescription().getOldData();
raimund@3539: String mode = ref[1].get(0).getStringValue();
raimund@3539:
felix@1612: saveLocationValues(locationPanel);
felix@1612:
felix@1612: if (!locationPanel.validateForm()) {
felix@1612: errors.add(MSG.wrongFormat());
felix@1612: return errors;
felix@1612: }
felix@1612:
felix@1618: double[] lValues = getLocationValues();
felix@1618: double[] good = new double[lValues.length];
felix@1612: int idx = 0;
felix@1612:
raimund@3539: double reference =
raimund@3539: Double.valueOf(ref[2].get(0).getStringValue()).doubleValue();
felix@1618: for (double value: lValues) {
raimund@3539: if (mode.equals("calc.reference.curve") &&
raimund@3539: value == reference) {
raimund@3539: errors.add(MSG.error_contains_same_location());
raimund@3539: return errors;
raimund@3539: }
felix@1612: if (value < min || value > max) {
felix@1612: String tmp = MSG.error_validate_range();
felix@1612: tmp = tmp.replace("$1", nf.format(value));
felix@1612: tmp = tmp.replace("$2", nf.format(min));
felix@1612: tmp = tmp.replace("$3", nf.format(max));
felix@1612: errors.add(tmp);
felix@1612: }
felix@1612: else {
felix@1612: good[idx++] = value;
felix@1612: }
felix@1612: }
felix@1612:
felix@1612: double[] justGood = new double[idx];
felix@1612: for (int i = 0; i < justGood.length; i++) {
felix@1612: justGood[i] = good[i];
felix@1612: }
felix@1612:
felix@1612: if (!errors.isEmpty()) {
felix@1612: locationPanel.setValues(justGood);
felix@1612: }
felix@1612:
felix@1612: return errors;
felix@1612: }
felix@1612:
felix@1612:
felix@1612: /**
felix@1615: * This method returns the selected data (to feed).
felix@1612: *
felix@1615: * @return the selected/inserted data in feedable form.
felix@1612: */
felix@1612: public Data[] getData() {
felix@1612: saveLocationValues(locationPanel);
felix@1618: double[] lValues = getLocationValues();
felix@1612: Data[] data = new Data[2];
felix@1612: boolean first = true;
felix@1612: String valueString = "";
felix@1612:
felix@1618: for (int i = 0; i < lValues.length; i++) {
felix@1612: if (!first) valueString += " ";
felix@1612: else first = false;
felix@1618: valueString += Double.valueOf(lValues[i]).toString();
felix@1612: }
felix@1612:
felix@1612: data[0] = createDataArray(getDataItemName(), valueString);
felix@1612:
felix@1612: data[1] = createDataArray("ld_mode", "locations");
felix@1612:
felix@1612: return data;
felix@1612: }
felix@1612:
felix@1612:
felix@1612: /** Hook service to the listgrid with possible input values. */
felix@1612: protected void setPickerDataSource() {
felix@1612: Config config = Config.getInstance();
felix@1612: String url = config.getServerUrl();
felix@1612: String river = "";
felix@1612:
felix@1612: ArtifactDescription adescr = artifact.getArtifactDescription();
felix@1612: DataList[] data = adescr.getOldData();
felix@1612:
felix@1612: // Try to find a "river" data item to set the source for the
felix@1612: // list grid.
raimund@2898: String dataFilter = "locations";
felix@1612: if (data != null && data.length > 0) {
felix@1612: for (int i = 0; i < data.length; i++) {
felix@1612: DataList dl = data[i];
raimund@2898: if (dl.getState().equals("state.minfo.river")) {
raimund@2898: dataFilter = "measuringpoint";
raimund@2898: }
felix@1612: if (dl.getState().equals("state.winfo.river") ||
raimund@2898: dl.getState().equals("state.chart.river") ||
raimund@2898: dl.getState().equals("state.minfo.river")) {
felix@1612: for (int j = 0; j < dl.size(); j++) {
felix@1612: Data d = dl.get(j);
felix@1612: DataItem[] di = d.getItems();
felix@1612: if (di != null && di.length == 1) {
felix@1612: river = d.getItems()[0].getStringValue();
felix@1612: break;
felix@1612: }
felix@1612: }
felix@1612: }
felix@1612: }
felix@1612: }
felix@1612:
felix@1612: picker.getLocationTable().setDataSource(new DistanceInfoDataSource(
raimund@2898: url, river, dataFilter));
felix@1612: }
felix@1612:
felix@1615:
felix@1612: // TODO allow multiple selections here or in LocationPanel
felix@1612: /**
felix@1612: * Callback when an item from the input helper was clicked.
felix@1612: * Set the respective km-value in the location value field.
felix@1612: * @param e event passed.
felix@1612: */
felix@1612: public void onRecordClick (RecordClickEvent e) {
felix@1617: Record record = e.getRecord();
felix@1617: double[] old = getLocationValues();
felix@1617: double[] selected = DoubleUtils.copyOf(old, old.length + 1);
felix@1612: try {
felix@1617: selected[old.length] =
felix@1612: Double.parseDouble(record.getAttribute("from"));
felix@1612: }
felix@1612: catch(NumberFormatException nfe) {
felix@1612: // Is there anything else to do here?
felix@1612: }
raimund@3539:
raimund@3539: // compare reference location and target location.
raimund@3539: DataList[] ref = artifact.getArtifactDescription().getOldData();
raimund@3539: String mode = ref[1].get(0).getStringValue();
raimund@3539: if (mode.equals("calc.reference.curve") &&
raimund@3539: ref[2].get(0).getStringValue().equals(record.getAttribute("from")))
raimund@3539: {
raimund@3539: SC.warn(MSG.error_same_location());
raimund@3539: return;
raimund@3539: }
raimund@3539:
felix@1612: setLocationValues(selected);
felix@1612: }
raimund@3493:
raimund@3493: /**
raimund@3493: * Returns the label string for the input panel.
raimund@3493: */
raimund@3493: protected String getLabelString() {
raimund@3493: return MSG.location();
raimund@3493: }
raimund@3493:
felix@1612: }
felix@1612: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :