view flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartPropertiesEditor.java @ 1507:c21d14e48040

Improved validation and property handling. flys-client/trunk@3645 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Raimund Renkert <raimund.renkert@intevation.de>
date Wed, 11 Jan 2012 10:21:22 +0000
parents 339f8aa641b5
children 8ac57bbc270c
line wrap: on
line source
package de.intevation.flys.client.client.ui.chart;

import java.util.List;
import java.util.Map;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;

import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.tab.TabSet;
import com.smartgwt.client.widgets.tab.Tab;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.Canvas;

import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.CheckboxItem;
import com.smartgwt.client.widgets.form.fields.TextItem;

import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
import com.smartgwt.client.widgets.form.fields.events.BlurEvent;

import com.smartgwt.client.types.Alignment;

import de.intevation.flys.client.client.Config;
import de.intevation.flys.client.client.FLYSConstants;
import de.intevation.flys.client.shared.model.Property;
import de.intevation.flys.client.shared.model.PropertyGroup;
import de.intevation.flys.client.shared.model.PropertySetting;
import de.intevation.flys.client.shared.model.BooleanProperty;
import de.intevation.flys.client.shared.model.DoubleProperty;
import de.intevation.flys.client.shared.model.IntegerProperty;
import de.intevation.flys.client.shared.model.StringProperty;
import de.intevation.flys.client.shared.model.Settings;
import de.intevation.flys.client.shared.model.OutputSettings;
import de.intevation.flys.client.shared.model.Collection;
import de.intevation.flys.client.client.utils.IntegerValidator;
import de.intevation.flys.client.client.utils.DoubleValidator;

import de.intevation.flys.client.client.services.CollectionAttributeService;
import de.intevation.flys.client.client.services.CollectionAttributeServiceAsync;

/**
 * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
 */
public class ChartPropertiesEditor
extends Window
implements ClickHandler
{
    /** The interface that provides i18n messages. */
    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);

    protected CollectionAttributeServiceAsync updater =
        GWT.create(CollectionAttributeService.class);

    /** The tab called the editor window. */
    protected ChartOutputTab tab;

    /** The tabset for chart properties */
    protected TabSet tabs;

    /** The collection */
    protected Collection collection;

    /** The cloned output settings */
    protected OutputSettings settings;

    /** The original output settings */
    protected OutputSettings origSettings;


    /**
     * Setup editor dialog.
     * @param callerTab      The tab called the editor window.
     */
    public ChartPropertiesEditor(ChartOutputTab callerTab) {
        this.tab = callerTab;
        this.tabs = new TabSet();

        init();
    }

    /**
     * Initialize the editor window and its components.
     */
    protected void init() {
        setTitle(MSG.properties());
        setCanDragReposition(true);
        setCanDragResize(true);

        Config config = Config.getInstance();
        collection = tab.getCollectionView().getCollection();
        String outputName = tab.getOutputName();
        origSettings = (OutputSettings)collection.getSettings(outputName);

        settings = (OutputSettings)origSettings.clone();
        if (settings == null) {
            return;
        }
        List<String> list = settings.getCategories();

        for (int i = 0; i < list.size(); i++) {
            Tab t = new Tab(MSG.getString(list.get(i)));
            List<Property> props = settings.getSettings(list.get(i));
            List<Property> origProps = origSettings.getSettings(list.get(i));
            VLayout layout = new VLayout();
            for (int j = 0; j < props.size(); j++) {
                if (props.get(j) instanceof PropertyGroup) {
                    layout.addMember(generatePropertyGroup(props.get(j),
                                                           origProps.get(j)));
                }
                else if (props.get(j) instanceof PropertySetting) {
                    PropertySetting p = (PropertySetting)props.get(j);
                    if (p.getAttribute("display").equals("false")) {
                        continue;
                    }
                    layout.addMember(generatePropertySetting(props.get(j),
                                                             origProps.get(j)));
                }
            }
            t.setPane(layout);
            tabs.addTab(t);
        }

        Button accept = new Button(MSG.label_ok());
        Button cancel = new Button(MSG.label_cancel());
        cancel.addClickHandler(this);
        accept.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent e) {
                if(isDialogValid()) {
                    updateCollection();
                }
                else {
                    GWT.log("Dialog not valid");
                    SC.warn(MSG.error_dialog_not_valid());
                }
            }
        });

        HLayout buttons = new HLayout();
        buttons.addMember(accept);
        buttons.addMember(cancel);
        buttons.setAlign(Alignment.CENTER);
        buttons.setHeight(30);

        addItem(tabs);
        addItem(buttons);
        setWidth(380);
        setHeight(470);
        centerInPage();
    }

    /**
     * This method is called when the user aborts theming.
     * @param event The event.
     */
    public void onClick(ClickEvent event) {
        this.destroy();
    }


    /**
     *
     */
    protected Canvas generatePropertyGroup(Property group, Property orig) {
        Config config = Config.getInstance();
        String locale = config.getLocale();
        PropertyGroup pg = (PropertyGroup)group;
        PropertyGroup origPg = (PropertyGroup)orig;

        if (pg.getName().equals("axis")) {
            Label scale = new Label(MSG.scale() + " :");
            scale.setHeight(25);
            scale.setMargin(2);

            DynamicForm form1 = new DynamicForm();
            DynamicForm form2 = new DynamicForm();
            form2.setNumCols(6);

            StringProperty label =
                (StringProperty)pg.getPropertyByName("label");
            FormItem title = createStringProperty(label);
            title.setValue(
                ((StringProperty)origPg.getPropertyByName("label")).getValue());

            IntegerProperty fontsize =
                (IntegerProperty)pg.getPropertyByName("font-size");
            FormItem fs = createIntegerProperty(fontsize);
            fs.setValue(
                ((IntegerProperty)
                    origPg.getPropertyByName("font-size")).getValue());

            DoubleProperty upper =
                (DoubleProperty)pg.getPropertyByName("upper");
            final FormItem range1 = createDoubleProperty(upper);
            range1.setWidth(70);
            range1.setValue(
                ((DoubleProperty)
                    origPg.getPropertyByName("upper")).toUIString());

            DoubleProperty lower =
                (DoubleProperty)pg.getPropertyByName("lower");
            final FormItem range2 = createDoubleProperty(lower);
            range2.setWidth(70);
            range2.setValue(
                ((DoubleProperty)
                    origPg.getPropertyByName("lower")).toUIString());

            BooleanProperty fixation =
                (BooleanProperty)pg.getPropertyByName("fixation");
            FormItem fix = createBooleanProperty(fixation);
            fix.setValue(((BooleanProperty)
                origPg.getPropertyByName("fixation")).getValue().booleanValue());

            fix.addChangedHandler(new ChangedHandler() {
                public void onChanged(ChangedEvent e) {
                    if ((Boolean)e.getValue()) {
                        range1.enable();
                        range2.enable();
                    }
                    else {
                        range1.disable();
                        range2.disable();
                    }
                }
            });
            if (fix.getValue().toString().equals("true")) {
                range1.enable();
                range2.enable();
            }
            else {
                range1.disable();
                range2.disable();
            }

            form1.setFields(title, fs);
            form2.setFields(fix, range2, range1);

            HLayout scaleLayout = new HLayout();
            scaleLayout.setHeight(30);
            scaleLayout.addMember(scale);
            scaleLayout.addMember(form2);
            scaleLayout.setStyleName("property-dialog-axis");

            VLayout root = new VLayout();
            root.addMember(form1);
            root.addMember(scaleLayout);
            root.setHeight(90);

            return root;
        }
        return null;
    }


    /**
     *
     */
    protected DynamicForm generatePropertySetting(
        Property setting,
        Property orig)
    {
        PropertySetting s = (PropertySetting)setting;
        DynamicForm form = new DynamicForm();
        FormItem item = new FormItem();
        if (setting instanceof BooleanProperty) {
            item = createBooleanProperty((BooleanProperty)setting);
            item.setValue(((BooleanProperty)orig).getValue().toString());
        }
        else if (setting instanceof DoubleProperty) {
            item = createDoubleProperty((DoubleProperty)setting);
            item.setValue(((DoubleProperty)orig).toUIString());
        }
        else if (setting instanceof IntegerProperty) {
            item = createIntegerProperty((IntegerProperty)setting);
            item.setValue(((IntegerProperty)orig).getValue());
        }
        else if (setting instanceof StringProperty) {
            item = createStringProperty((StringProperty)setting);
            item.setValue(((StringProperty)orig).getValue());
        }
        form.setFields(item);
        return form;
    }


    /**
     *
     */
    protected FormItem createStringProperty(final StringProperty sp) {
        String name = sp.getName();
        if (name.contains("-")) {
            name = name.replace("-", "_");
        }
        TextItem item = new TextItem();
        item.setTitle(MSG.getString(name));
        item.setTitleAlign(Alignment.LEFT);
        item.addBlurHandler(new BlurHandler() {
            public void onBlur(BlurEvent e) {
                String val;
                if (e.getItem().getValue() == null) {
                    val = "";
                }
                else {
                    val = e.getItem().getValue().toString();
                }
                sp.setValue(val);
            }
        });
        return item;
    }


    /**
     *
     */
    protected FormItem createBooleanProperty(final BooleanProperty bp) {
        String name = bp.getName();
        if (name.contains("-")) {
            name = name.replace("-", "_");
        }

        CheckboxItem item = new CheckboxItem("item", MSG.getString(name));
        item.setLabelAsTitle(true);
        item.setTitleStyle("color:#000;");
        item.setTitleAlign(Alignment.LEFT);
        item.addBlurHandler(new BlurHandler() {
            public void onBlur(BlurEvent e) {
                String val;
                if (e.getItem().getValue() == null) {
                    val = "";
                }
                else {
                    val = e.getItem().getValue().toString();
                }
                bp.setValue(val);
            }
        });
        return item;
    }


    /**
     *
     */
    protected FormItem createDoubleProperty(final DoubleProperty dp) {
        String name = dp.getName();
        if (name.contains("-")) {
            name = name.replace("-", "_");
        }

        TextItem item = new TextItem();
        item.setTitle(MSG.getString(name));
        item.setTitleAlign(Alignment.LEFT);
        item.addBlurHandler(new BlurHandler() {
            public void onBlur(BlurEvent e) {
                 DoubleValidator validator = new DoubleValidator();
                 Map errors = e.getForm().getErrors();
                 if(validator.validate(e.getItem(), errors)) {
                     dp.setValueFromUI(e.getItem().getValue().toString());
                     e.getForm().setErrors(errors, true);
                 }
                 else {
                     e.getForm().setErrors(errors, true);
                 }
            }
        });
        return item;
    }


    /**
     *
     */
    protected FormItem createIntegerProperty(final IntegerProperty ip) {
        String name = ip.getName();
        if (name.contains("-")) {
            name = name.replace("-", "_");
        }

        TextItem item = new TextItem();
        item.setTitle(MSG.getString(name));
        item.setTitleAlign(Alignment.LEFT);
        item.addBlurHandler(new BlurHandler() {
            public void onBlur(BlurEvent e) {
                IntegerValidator validator = new IntegerValidator();
                Map errors = e.getForm().getErrors();
                if(validator.validate(e.getItem(), errors)) {
                    ip.setValue(e.getItem().getValue().toString());
                    e.getForm().setErrors(errors, true);
                }
                else {
                    e.getForm().setErrors(errors, true);
                }
            }
        });
        return item;
    }


    protected void updateCollection() {
        final Config config = Config.getInstance();
        final String loc    = config.getLocale();

        GWT.log("PropertiesEditor.updateCollection via RPC now");

        Settings s = settings;
        collection.addSettings(this.tab.getOutputName(), s);
        updater.update(collection, loc, new AsyncCallback<Collection>() {
            public void onFailure(Throwable caught) {
                GWT.log("Could not update collection attributes.");
                SC.warn(MSG.getString(caught.getMessage()));
            }
            public void onSuccess(Collection collection) {
                updateChartTab();
            }
        });
    }

    protected void updateChartTab() {
        this.tab.updateChartInfo();
        this.tab.updateChartPanel();
        this.destroy();
    }


    protected boolean isDialogValid() {
        boolean valid = true;
        for (int i = 0; i < tabs.getNumTabs(); i++) {
            Tab t = tabs.getTab(i);
            Canvas container = t.getPane();
            Canvas[] children = container.getChildren();
            for (Canvas c: children) {
                valid = validateCanvas(c);
                if(!valid) {
                    return valid;
                }
            }
        }
        return valid;
    }


    protected boolean validateCanvas(Canvas c) {
        boolean valid = true;
        if(c instanceof DynamicForm) {
            DynamicForm f = (DynamicForm) c;
            return !f.hasErrors();
        }
        else if(c.getChildren().length > 0) {
            for (Canvas child: c.getChildren()) {
                valid = validateCanvas(child);
                if(!valid) {
                    return valid;
                }
            }
        }
        return valid;
    }
}

http://dive4elements.wald.intevation.org