view flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterList.java @ 260:dd1dad2ff94e

Remove the data table on step back. flys-client/trunk@1875 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Raimund Renkert <raimund.renkert@intevation.de>
date Tue, 10 May 2011 10:57:57 +0000
parents 5e1c1b7d6516
children eb3c16df59db
line wrap: on
line source
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.user.client.rpc.AsyncCallback;

import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tab.Tab;

import de.intevation.flys.client.shared.model.Artifact;
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.DefaultData;
import de.intevation.flys.client.shared.model.DefaultDataItem;
import de.intevation.flys.client.shared.model.River;
import de.intevation.flys.client.client.Config;
import de.intevation.flys.client.client.FLYS;
import de.intevation.flys.client.client.FLYSConstants;
import de.intevation.flys.client.client.event.HasParameterChangeHandler;
import de.intevation.flys.client.client.event.HasStepBackHandlers;
import de.intevation.flys.client.client.event.HasStepForwardHandlers;
import de.intevation.flys.client.client.event.ParameterChangeEvent;
import de.intevation.flys.client.client.event.ParameterChangeHandler;
import de.intevation.flys.client.client.event.StepBackEvent;
import de.intevation.flys.client.client.event.StepBackHandler;
import de.intevation.flys.client.client.event.StepForwardEvent;
import de.intevation.flys.client.client.event.StepForwardHandler;
import de.intevation.flys.client.client.services.AdvanceService;
import de.intevation.flys.client.client.services.AdvanceServiceAsync;
import de.intevation.flys.client.client.services.ArtifactService;
import de.intevation.flys.client.client.services.ArtifactServiceAsync;
import de.intevation.flys.client.client.services.StepForwardService;
import de.intevation.flys.client.client.services.StepForwardServiceAsync;


public class ParameterList
extends      Tab
implements   StepBackHandler, StepForwardHandler, ParameterChangeHandler,
             HasParameterChangeHandler
{
    /** The message class that provides i18n strings.*/
    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);

    /** The ArtifactService used to communicate with the Artifact server. */
    protected ArtifactServiceAsync artifactService =
        GWT.create(ArtifactService.class);

    /** The StepForwardService used to put data into an existing artifact. */
    protected StepForwardServiceAsync forwardService =
        GWT.create(StepForwardService.class);

    /** The StepForwardService used to put data into an existing artifact. */
    protected AdvanceServiceAsync advanceService =
        GWT.create(AdvanceService.class);


    /** The list of ParameterizationChangeHandler.*/
    protected List<ParameterChangeHandler> parameterHandlers;

    protected FLYS flys;

    protected CollectionView cView;

    protected Artifact artifact;

    protected List<DataList> old;
    protected DataList   current;

    protected UIProvider uiProvider;

    protected VLayout topLayout;
    protected VLayout oldItems;
    protected VLayout currentItems;
    protected Canvas  helperPanel;
    protected Canvas  tablePanel;

    public ParameterList(FLYS flys, CollectionView cView, String title) {
        super(title);

        this.cView = cView;
        this.flys  = flys;

        parameterHandlers = new ArrayList<ParameterChangeHandler>();
        old               = new ArrayList<DataList>();
        topLayout         = new VLayout();
        oldItems          = new VLayout();
        currentItems      = new VLayout();

        addParameterChangeHandler(this);

        init();
    }


    public ParameterList(
        FLYS           flys,
        CollectionView cView,
        String         title,
        Artifact       artifact)
    {
        super(title);

        this.cView    = cView;
        this.flys     = flys;
        this.artifact = artifact;

        parameterHandlers = new ArrayList<ParameterChangeHandler>();
        old               = new ArrayList<DataList>();
        topLayout         = new VLayout();
        oldItems          = new VLayout();
        currentItems      = new VLayout();

        init();

        addParameterChangeHandler(this);

        setArtifact(artifact);
    }


    protected void init() {
        HLayout rootLayout = new HLayout();
        tablePanel = new Canvas();
        rootLayout.setMembersMargin(20);

        VLayout left = new VLayout();

        if (old == null || old.size() == 0) {
            oldItems.setHeight(0);
        }

        oldItems.setMembersMargin(10);
        currentItems.setAlign(VerticalAlignment.TOP);

        left.setMembersMargin(20);
        left.setWidth(300);

        left.addMember(oldItems);
        left.addMember(currentItems);

        // This canvas is used to render helper widgets
        helperPanel = new Canvas();

        rootLayout.addMember(left);
        rootLayout.addMember(helperPanel);

        topLayout.addMember(rootLayout);
        if (artifact == null) {
            Canvas moduleSelection = renderNew();
            moduleSelection.setLayoutAlign(VerticalAlignment.TOP);
            currentItems.addMember(moduleSelection);
        }

        setPane(topLayout);
    }


    protected void setArtifact(Artifact artifact) {
        Artifact tmp  = this.artifact;
        this.artifact = artifact;

        fireParameterChangeEvent(tmp, this.artifact);
    }


    /**
     * This method registers a new ParameterChangeHandler.
     *
     * @param handler The new ParameterChangeHandler.
     */
    public void addParameterChangeHandler(ParameterChangeHandler handler) {
        if (handler != null) {
            parameterHandlers.add(handler);
        }
    }


    /**
     * This method calls the <code>onParameterChange()</code> method of all
     * registered ParameterChangeHandler.
     */
    protected void fireParameterChangeEvent(Artifact old, Artifact newArt) {
        for (ParameterChangeHandler handler: parameterHandlers) {
            handler.onParameterChange(new ParameterChangeEvent(old, newArt));
        }
    }


    /**
     * This method creates a Canvas displaying the plugins of FLYS combined with
     * a widget to select a river.
     *
     * @return a Canvas that displays the supported plugins and rivers of FLYS.
     */
    protected Canvas renderNew() {
        River[] rivers   = flys.getRivers();
        DataItem[] items = new DataItem[rivers.length];

        int i = 0;
        for (River river: rivers) {
            String name = river.getName();
            items[i++]  = new DefaultDataItem(name, null, name);
        }

        Data data = new DefaultData(
            "river",
            MSG.river_selection(),
            null,
            items);

        ModuleSelection widget         = new ModuleSelection();
        HasStepForwardHandlers handler = (HasStepForwardHandlers) widget;

        widget.setContainer(helperPanel);

        handler.addStepForwardHandler(new StepForwardHandler() {
            public void onStepForward(StepForwardEvent event) {
                Data[] data = event.getData();

                DataItem[] moduleItems = data[0].getItems();
                DataItem[] riversItems = data[1].getItems();

                String module = moduleItems[0].getStringValue();
                String river  = riversItems[0].getStringValue();

                if (module == null) {
                    // TODO throw / show error!
                    return;
                }

                String newTitle = MSG.getString(module);
                setTitle(newTitle);

                Config config       = Config.getInstance();
                final String url    = config.getServerUrl();
                final String locale = config.getLocale();

                final Data[] feedData  = new Data[] { data[1] };

                artifactService.create(
                    url, locale, module.toLowerCase(),
                    new AsyncCallback<Artifact>() {
                        public void onFailure(Throwable caught) {
                            GWT.log("Could not create the new artifact.");
                            SC.warn(MSG.getString(caught.getMessage()));
                        }

                        public void onSuccess(Artifact artifact) {
                            GWT.log("Successfully created a new artifact.");

                            forwardService.go(url, locale, artifact, feedData,
                            new AsyncCallback<Artifact>() {
                                public void onFailure(Throwable caught) {
                                    GWT.log("Could not feed the artifact.");
                                    SC.warn(caught.getMessage());
                                }

                                public void onSuccess(Artifact artifact) {
                                    GWT.log("Successfully feed the artifact.");
                                    setArtifact(artifact);
                                }
                            });
                        }
                });
            }
        });

        DataList list = new DataList();
        list.add(data);

        return widget.create(list);
    }


    protected void clearOldData() {
        old.clear();
    }


    public void addOldData(DataList old) {
        if (old != null) {
            this.old.add(old);
        }

        refreshOld();
    }


    public void addOldDatas(DataList[] old) {
        if (old != null && old.length > 0) {
            for (DataList o: old) {
                if (!exists(o)) {
                    GWT.log("Data '" + o.getLabel() + "' is new.");
                    addOldData(o);
                }
            }

            return;
        }

        addOldData(null);
    }


    public boolean exists(DataList data) {
        String stateName = data.getState();

        for (DataList o: old) {
            if (stateName.equals(o.getState())) {
                return true;
            }
        }

        return false;
    }


    public void setCurrentData(DataList current, UIProvider uiProvider) {
        this.current    = current;
        this.uiProvider = uiProvider;

        refreshCurrent();
    }


    public void refreshOld() {
        // XXX maybe we should not remove all items but just add the newest item
        // to the list.
        oldItems.removeMembers(oldItems.getMembers());

        for (DataList dataList: old) {
            HLayout h = new HLayout();
            h.setAlign(VerticalAlignment.TOP);
            h.setHeight(20);

            String     provider   = dataList.getUIProvider();
            UIProvider uiprovider = UIProviderFactory.getProvider(provider);
            ((HasStepBackHandlers) uiprovider).addStepBackHandler(this);

            oldItems.addMember(uiprovider.createOld(dataList));
        }

        int minHeight = oldItems.getMinHeight();
        if (minHeight <= 20) {
            oldItems.setHeight(20);
        }
        else {
            oldItems.setHeight(minHeight);
        }
    }


    /**
     * This method refreshes the part displaying the data of the current state.
     * The UI is created using the UIProvider stored in the Data object.
     */
    public void refreshCurrent() {
        currentItems.removeMembers(currentItems.getMembers());

        if (current != null && uiProvider != null) {
            Canvas c = uiProvider.create(current);
            c.setLayoutAlign(VerticalAlignment.TOP);

            currentItems.addMember(c);
        }
    }


    /**
     * This method is called if the user clicks on the 'next' button to advance
     * to the next state.
     *
     * @param event The StepForwardEvent.
     */
    public void onStepForward(StepForwardEvent event) {
        GWT.log("CollectionView - onStepForward()");

        Config config    = Config.getInstance();
        String serverUrl = config.getServerUrl();
        String locale    = config.getLocale();

        forwardService.go(serverUrl, locale, artifact, event.getData(),
            new AsyncCallback<Artifact>() {
                public void onFailure(Throwable caught) {
                    GWT.log("Could not feed the artifact.");
                    SC.warn(MSG.getString(caught.getMessage()));
                }

                public void onSuccess(Artifact artifact) {
                    GWT.log("Successfully feed the artifact.");
                    setArtifact(artifact);
                }
        });
    }


    /**
     * This method is used to remove all old items from this list after the user
     * has clicked the step back button.
     *
     * @param e The StepBackEvent that holds the identifier of the target state.
     */
    public void onStepBack(StepBackEvent e) {
        final String target    = e.getTarget();

        Config config          = Config.getInstance();
        final String serverUrl = config.getServerUrl();
        final String locale    = config.getLocale();

        advanceService.advance(serverUrl, locale, artifact, target,
            new AsyncCallback<Artifact>() {
                public void onFailure(Throwable caught) {
                    GWT.log("Could not go back to '" + target + "'");
                    SC.warn(MSG.getString(caught.getMessage()));
                }

                public void onSuccess(Artifact artifact) {
                    GWT.log("Successfully step back to '" + target + "'");

                    old.clear();
                    oldItems.removeMembers(oldItems.getMembers());

                    setArtifact(artifact);
                }
            }
        );
    }


    /**
     * Implements the onCollectionChange() method to do update the GUI after the
     * parameterization has changed.
     *
     * @param event The ParameterChangeEvent.
     */
    public void onParameterChange(ParameterChangeEvent event) {
        GWT.log("ParameterList.onParameterChange");

        for (Canvas c: helperPanel.getChildren()) {
            helperPanel.removeChild(c);
        }

        Artifact art             = event.getNewValue();
        ArtifactDescription desc = art.getArtifactDescription();

        DataList currentData = desc.getCurrentData();
        if (currentData != null) {
            // the user has to enter some attributes
            String uiProvider   = currentData.getUIProvider();
            UIProvider provider = UIProviderFactory.getProvider(uiProvider);

            provider.setContainer(helperPanel);
            provider.setArtifact(art);

            ((HasStepForwardHandlers) provider).addStepForwardHandler(this);
            ((HasStepBackHandlers) provider).addStepBackHandler(this);

            setCurrentData(currentData, provider);
        }
        else {
            // we have reached a final state with no more user input
            setCurrentData(null, null);
        }

        addOldDatas(desc.getOldData());
    }

    /**
     * Adds a table to the parameterlist to show calculated data.
     *
     * @param table The table data panel.
     */
    public void setPanel (TableDataPanel table) {
        tablePanel = table.create();
        tablePanel.setHeight(400);
        topLayout.addMember(tablePanel);
    }


    /**
     * Removes the table from the parameter list.
     */
    public void removePanel() {
        topLayout.removeMember(tablePanel);
    }


    public boolean hasPanel() {
        return topLayout.hasMember(tablePanel);
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org