view flys-client/src/main/java/de/intevation/flys/client/client/ui/WQAdaptedInputPanel.java @ 4205:0dd8963cec9c

Set also the width of the GaugeTree when resizing the GaugePanel GWT is no longer able to calculate and set the correct width of the GaugeTree since the GaugeTree is added via a Canvas wrapper. Therefore set the width manually when resizing the GaugeTree.
author Björn Ricks <bjoern.ricks@intevation.de>
date Mon, 22 Oct 2012 15:33:16 +0200
parents 8490faba00e7
children bbd82bd8e541
line wrap: on
line source
package de.intevation.flys.client.client.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

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.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.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.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tab.TabSet;
import com.smartgwt.client.widgets.tab.Tab;

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.DefaultData;
import de.intevation.flys.client.shared.model.DefaultDataItem;
import de.intevation.flys.client.shared.model.WQDataItem;
import de.intevation.flys.client.shared.model.WQInfoObject;
import de.intevation.flys.client.shared.model.WQInfoRecord;
import de.intevation.flys.client.shared.model.ArtifactDescription;


import de.intevation.flys.client.client.FLYSConstants;
import de.intevation.flys.client.client.Config;
import de.intevation.flys.client.client.services.WQInfoService;
import de.intevation.flys.client.client.services.WQInfoServiceAsync;
import de.intevation.flys.client.client.ui.wq.WTable;
import de.intevation.flys.client.client.ui.wq.QDTable;


/**
 * This UIProvider creates a widget to enter W or Q data for discharge
 * longitudinal section computations.
 *
 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
 */
public class WQAdaptedInputPanel
extends      AbstractUIProvider
implements   ChangeHandler, BlurHandler
{
    public static final String FIELD_WQ_MODE = "wq_isq";
    public static final String FIELD_WQ_W    = "W";
    public static final String FIELD_WQ_Q    = "Q";

    public static final String GAUGE_SEPARATOR = ":";

    public static final String GAUGE_PART_SEPARATOR = ";";

    public static final String VALUE_SEPARATOR = ",";

    public static final int ROW_HEIGHT = 20;

    /** The constant field name for choosing w or q mode.*/
    public static final String FIELD_WQ = "wq";

    /** The constant field name for choosing single values or range.*/
    public static final String FIELD_MODE = "mode";

    /** The constant field value for range input mode.*/
    public static final String FIELD_MODE_RANGE = "range";

    protected WQInfoServiceAsync wqInfoService =
        GWT.create(WQInfoService.class);

    /** The message class that provides i18n strings.*/
    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);

    /** Stores the input panels related to their keys.*/
    protected Map<String, DoubleArrayPanel> wqranges;

    /** Stores the min/max values for each q range.*/
    protected Map<String, double[]> qranges;

    /** Stores the min/max values for each w range.*/
    protected Map<String, double[]> wranges;

    /** The RadioGroupItem that determines the w/q input mode.*/
    protected DynamicForm modes;

    protected QDTable qdTable;

    protected WTable wTable;

    protected TabSet tabs;


    public WQAdaptedInputPanel() {
        wqranges = new HashMap<String, DoubleArrayPanel>();
        qranges  = new HashMap<String, double[]>();
        wranges  = new HashMap<String, double[]>();
        qdTable  = new QDTable();
        wTable   = new WTable();
    }


    public Canvas create(DataList data) {
        initHelperPanel();

        Canvas submit = getNextButton();
        Canvas widget = createWidget(data);
        Label  label  = new Label(MSG.wqadaptedTitle());

        label.setHeight(25);

        VLayout layout = new VLayout();
        layout.setMembersMargin(10);
        layout.setWidth(350);

        layout.addMember(label);
        layout.addMember(widget);
        layout.addMember(submit);


        return layout;
    }


    protected void initHelperPanel() {
        tabs = new TabSet();
        tabs.setWidth100();
        tabs.setHeight100();

        // TODO i18n
        Tab wTab = new Tab("W");
        Tab qTab = new Tab("Q / D");

        wTab.setPane(wTable);
        qTab.setPane(qdTable);
        qdTable.hideIconFields();

        tabs.addTab(wTab, 0);
        tabs.addTab(qTab, 1);

        helperContainer.addMember(tabs);

        fetchWQData();
    }


    public Canvas createOld(DataList dataList) {
        List<Data> all = dataList.getAll();
        Data    wqData = getData(all, "wq_values");
        Data    wqMode = getData(all, "wq_isq");

        Canvas back = getBackButton(dataList.getState());

        HLayout valLayout  = new HLayout();
        HLayout modeLayout = new HLayout();
        VLayout vlayout    = new VLayout();

        Label wqLabel   = new Label(dataList.getLabel());
        Label modeLabel = new Label("");

        wqLabel.setValign(VerticalAlignment.TOP);

        wqLabel.setWidth(200);
        wqLabel.setHeight(25);
        modeLabel.setHeight(25);
        modeLabel.setWidth(200);

        valLayout.addMember(wqLabel);
        valLayout.addMember(createOldWQValues(wqData));
        valLayout.addMember(back);
        modeLayout.addMember(modeLabel);

        vlayout.addMember(valLayout);
        vlayout.addMember(modeLayout);

        return vlayout;
    }


    protected Canvas createOldWQValues(Data wqData) {
        VLayout layout = new VLayout();

        DataItem item  = wqData.getItems()[0];
        String   value = item.getStringValue();

        String[] gauges = value.split(GAUGE_SEPARATOR);

        for (String gauge: gauges) {
            HLayout h = new HLayout();

            String[] parts  = gauge.split(GAUGE_PART_SEPARATOR);
            String[] values = parts[2].split(VALUE_SEPARATOR);

            Label l = new Label(parts[0] + " - " + parts[1] + ": ");

            StringBuilder sb = new StringBuilder();
            boolean    first = true;

            for (String v: values) {
                if (!first) {
                    sb.append(", ");
                }

                sb.append(v);

                first = false;
            }

            Label v = new Label(sb.toString());

            l.setWidth(65);
            v.setWidth(65);

            h.addMember(l);
            h.addMember(v);

            layout.addMember(h);
        }

        return layout;
    }


    protected Canvas createWidget(DataList dataList) {
        VLayout layout = new VLayout();

        Canvas mode = createMode(dataList);
        Canvas list = createList(dataList);

        DataItem[] items = getWQItems(dataList);
        int listHeight   = ROW_HEIGHT * items.length;

        mode.setHeight(25);
        mode.setWidth(200);

        layout.addMember(mode);
        layout.addMember(list);

        layout.setHeight(25 + listHeight);
        layout.setWidth(350);

        initUserDefaults(dataList);

        return layout;
    }


    @Override
    public List<String> validate() {
        if (isWMode()) {
            return validateW();
        }
        else {
            return validateQ();
        }
    }


    protected List<String> validateW() {
        List<String> errors = new ArrayList<String>();
        NumberFormat nf     = NumberFormat.getDecimalFormat();

        Iterator<String> iter = wqranges.keySet().iterator();

        while (iter.hasNext()) {
            List<String> tmpErrors = new ArrayList<String>();

            String           key = iter.next();
            DoubleArrayPanel dap = wqranges.get(key);

            if (!dap.validateForm()) {
                errors.add(MSG.error_invalid_double_value());
                return errors;
            }

            double[] mm  = wranges.get(key);
            if (mm == null) {
                SC.warn(MSG.error_read_minmax_values());
                continue;
            }

            double[] values = dap.getInputValues();
            double[] good   = new double[values.length];

            int idx = 0;

            for (double value: values) {
                if (value < mm[0] || value > mm[1]) {
                    String tmp = MSG.error_validate_range();
                    tmp = tmp.replace("$1", nf.format(value));
                    tmp = tmp.replace("$2", nf.format(mm[0]));
                    tmp = tmp.replace("$3", nf.format(mm[1]));
                    tmpErrors.add(tmp);
                }
                else {
                    good[idx++] = value;
                }
            }

            double[] justGood = new double[idx];
            for (int i = 0; i < justGood.length; i++) {
                justGood[i] = good[i];
            }

            if (!tmpErrors.isEmpty()) {
                dap.setValues(justGood);

                errors.addAll(tmpErrors);
            }
        }

        return errors;
    }


    protected List<String> validateQ() {
        List<String> errors = new ArrayList<String>();
        NumberFormat nf     = NumberFormat.getDecimalFormat();

        Iterator<String> iter = wqranges.keySet().iterator();

        while (iter.hasNext()) {
            List<String> tmpErrors = new ArrayList<String>();

            String           key = iter.next();
            DoubleArrayPanel dap = wqranges.get(key);

            if (!dap.validateForm()) {
                errors.add(MSG.error_invalid_double_value());
                return errors;
            }

            double[] mm = qranges.get(key);
            if (mm == null) {
                SC.warn(MSG.error_read_minmax_values());
                continue;
            }

            double[] values = dap.getInputValues();
            double[] good   = new double[values.length];

            int idx = 0;

            for (double value: values) {
                if (value < mm[0] || value > mm[1]) {
                    String tmp = MSG.error_validate_range();
                    tmp = tmp.replace("$1", nf.format(value));
                    tmp = tmp.replace("$2", nf.format(mm[0]));
                    tmp = tmp.replace("$3", nf.format(mm[1]));
                    tmpErrors.add(tmp);
                }
                else {
                    good[idx++] = value;
                }
            }

            double[] justGood = new double[idx];
            for (int i = 0; i < justGood.length; i++) {
                justGood[i] = good[i];
            }

            if (!tmpErrors.isEmpty()) {
                dap.setValues(justGood);

                errors.addAll(tmpErrors);
            }
        }

        return errors;
    }


    protected void initUserDefaults(DataList dataList) {

        initUserWQValues(dataList);
        initUserWQMode(dataList);
    }


    protected void initUserWQMode(DataList dataList) {
        List<Data> allData = dataList.getAll();

        Data     dDef  = getData(allData, "wq_mode");
        DataItem def   = dDef != null ? dDef.getDefault() : null;
        String   value = def != null ? def.getStringValue() : null;

        if (value != null && value.equals(FIELD_WQ_W)) {
            modes.setValue(FIELD_WQ_MODE, FIELD_WQ_W);
        }
        else {
            modes.setValue(FIELD_WQ_MODE, FIELD_WQ_Q);
        }
    }


    protected void initUserWQValues(DataList dataList) {
        List<Data> allData = dataList.getAll();

        Data     dDef  = getData(allData, "wq_values");
        DataItem def   = dDef != null ? dDef.getDefault() : null;
        String   value = def != null ? def.getStringValue() : null;

        if (value == null || value.length() == 0) {
            return;
        }

        String[] lines = value.split(GAUGE_SEPARATOR);

        if (lines == null || lines.length == 0) {
            return;
        }

        for (String line: lines) {
            String[] cols  = line.split(GAUGE_PART_SEPARATOR);
            String   title = createLineTitle(line);

            if (cols == null || cols.length < 3) {
                continue;
            }

            String[] strValues = cols[2].split(VALUE_SEPARATOR);
            double[] values    = new double[strValues.length];

            int idx = 0;

            for (String strValue: strValues) {
                try {
                    values[idx++] = Double.valueOf(strValue);
                }
                catch (NumberFormatException nfe) {
                    // do nothing
                }
            }

            String           key = cols[0] + GAUGE_PART_SEPARATOR + cols[1];
            DoubleArrayPanel dap = wqranges.get(key);

            if (dap == null) {
                continue;
            }

            dap.setValues(values);
        }
    }


    protected Canvas createList(DataList dataList) {
        VLayout layout = new VLayout();

        DataItem[] items = getWQItems(dataList);

        for (DataItem item: items) {
            String title = item.getLabel();

            DoubleArrayPanel dap = new DoubleArrayPanel(
                createLineTitle(title), null, this, TitleOrientation.LEFT);

            wqranges.put(title, dap);

            if (item instanceof WQDataItem) {
                WQDataItem wq = (WQDataItem) item;
                double[] mmQ = wq.getQRange();
                double[] mmW = wq.getWRange();

                qranges.put(title, mmQ);
                wranges.put(title, mmW);
            }

            layout.addMember(dap);
        }

        layout.setHeight(items.length * ROW_HEIGHT);

        return layout;
    }


    protected DataItem[] getWQItems(DataList dataList) {
        List<Data> data = dataList.getAll();

        for (Data d: data) {
            String name = d.getLabel();

            if (name.equals(FIELD_WQ_MODE)) {
                continue;
            }

            return d.getItems();
        }

        return null;
    }


    protected Canvas createMode(DataList dataList) {
        RadioGroupItem wq = new RadioGroupItem(FIELD_WQ_MODE);
        wq.setShowTitle(false);
        wq.setVertical(false);
        wq.setWidth(200);

        LinkedHashMap wqValues = new LinkedHashMap();
        wqValues.put(FIELD_WQ_W, MSG.wqW());
        wqValues.put(FIELD_WQ_Q, MSG.wqQ());

        wq.setValueMap(wqValues);

        modes = new DynamicForm();
        modes.setFields(wq);
        modes.setWidth(200);
        wq.addChangeHandler(new ChangeHandler() {
            public void onChange(ChangeEvent e) {
                DynamicForm form = e.getForm();

                if(form.getValueAsString(FIELD_WQ_MODE).contains("Q")) {
                    tabs.selectTab(0);
                }
                else {
                    tabs.selectTab(1);
                }
            }
        });


        LinkedHashMap initial = new LinkedHashMap();
        initial.put(FIELD_WQ_MODE, FIELD_WQ_Q);
        modes.setValues(initial);
        tabs.selectTab(1);
        return modes;
    }


    public String createLineTitle(String key) {
        String[] splitted = key.split(";");

        return splitted[0] + " - " + splitted[1];
    }


    public Data[] getData() {
        Data mode   = getWQMode();
        Data values = getWQValues();

        return new Data[] { mode, values };
    }


    public boolean isWMode() {
        String mode = (String) modes.getValue(FIELD_WQ_MODE);

        return FIELD_WQ_W.equals(mode);
    }


    protected Data getWQMode() {
        String wqMode = modes.getValueAsString(FIELD_WQ_MODE);
        String value = "false";
        if (wqMode.equals("Q")) {
            value = "true";
        }
        DataItem item = new DefaultDataItem("wq_isq", "wq_isq", value);
        Data mode = new DefaultData(
            "wq_isq", null, null, new DataItem[] { item });

        return mode;
    }


    protected Data getWQValues() {
        String wqvalue = null;

        Iterator<String> iter = wqranges.keySet().iterator();
        while (iter.hasNext()) {
            String           key = iter.next();
            DoubleArrayPanel dap = wqranges.get(key);

            double[] values = dap.getInputValues();
            if (wqvalue == null) {
                wqvalue = createValueString(key, values);
            }
            else {
                wqvalue += GAUGE_SEPARATOR + createValueString(key, values);
            }
        }

        DataItem valueItem = new DefaultDataItem(
            "wq_values", "wq_values", wqvalue);
        Data values = new DefaultData(
            "wq_values", null, null, new DataItem[] { valueItem });

        return values;
    }


    protected String createValueString(String key, double[] values) {
        StringBuilder sb = new StringBuilder();

        boolean first = true;

        for (double value: values) {
            if (!first) {
                sb.append(",");
            }

            sb.append(Double.toString(value));

            first = false;
        }

        return key + ";" + sb.toString();
    }


    public void onChange(ChangeEvent event) {
        // TODO IMPLEMENT ME
    }


    public void onBlur(BlurEvent event) {
        DoubleArrayPanel dap = (DoubleArrayPanel) event.getForm();
        dap.validateForm(event.getItem());
    }


    protected void fetchWQData() {
        Config config    = Config.getInstance();
        String locale    = config.getLocale ();

        ArtifactDescription adescr = artifact.getArtifactDescription();
        DataList[] data = adescr.getOldData();

        double[]  mm = getMinMaxKM(data);
        String river = getRiverName(data);

        wqInfoService.getWQInfo(locale, river, mm[0], mm[0],
            new AsyncCallback<WQInfoObject[]>() {
                public void onFailure(Throwable caught) {
                    GWT.log("Could not recieve wq informations.");
                    SC.warn(caught.getMessage());
                }

                public void onSuccess(WQInfoObject[] wqi) {
                    int num = wqi != null ? wqi.length :0;
                    GWT.log("Recieved " + num + " wq informations.");

                    if (num == 0) {
                        return;
                    }

                    addWQInfo(wqi);

                }
            }
        );
    }


    protected void addWQInfo (WQInfoObject[] wqi) {
        for(WQInfoObject wi: wqi) {
            WQInfoRecord rec = new WQInfoRecord(wi);

            if (wi.getType().equals("W")) {
                wTable.addData(rec);
            }
            else {
                qdTable.addData(rec);
            }
        }
    }


    /**
     * Determines the min and max kilometer value selected in a former state. A
     * bit silly, but we need to run over each value of the "old data" to find
     * such values because it is not available here.
     *
     * @param data The DataList which contains the whole data inserted for the
     * current artifact.
     *
     * @return a double array with [min, max].
     */
    protected double[] getMinMaxKM(DataList[] data) {
        ArtifactDescription adesc = artifact.getArtifactDescription();
        return adesc.getKMRange();
    }


    /**
     * Returns the name of the selected river.
     *
     * @param data The DataList with all data.
     *
     * @return the name of the current river.
     */
    protected String getRiverName(DataList[] data) {
        ArtifactDescription adesc = artifact.getArtifactDescription();
        return adesc.getRiver();
    }


    protected void updatePanels(boolean isQ) {

    }


}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org