view flys-client/src/main/java/de/intevation/flys/client/client/ui/minfo/BedHeightsDatacagePanel.java @ 4198:1cdbd8a0c994

Added two new tables ClickableQDTable and ClickableWTable and made Ws and Qs clickable in historical discharge calculation. The new tables define listener interfaces (clicked lower or upper icon) to listen to user clicks. In addition to this, there is an enum ClickMode with NONE, SINGLE and RANGE options, which allows to specifiy, which icons are displayed in the tables. NONE means no icon for user clicks, SINGLE has 1 icon, RANGE 2 icons for lower and upper.
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Mon, 22 Oct 2012 13:31:25 +0200
parents 1755a1bfe5ce
children
line wrap: on
line source
package de.intevation.flys.client.client.ui.minfo;

import com.google.gwt.core.client.GWT;

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

import com.smartgwt.client.data.Record;

import com.smartgwt.client.widgets.Canvas;

import com.smartgwt.client.widgets.events.ClickEvent;

import com.smartgwt.client.widgets.grid.ListGridRecord;

import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;

import de.intevation.flys.client.client.Config;
import de.intevation.flys.client.client.FLYSConstants;

import de.intevation.flys.client.client.event.StepForwardEvent;

import de.intevation.flys.client.client.services.LoadArtifactService;
import de.intevation.flys.client.client.services.LoadArtifactServiceAsync;
import de.intevation.flys.client.client.services.RemoveArtifactService;
import de.intevation.flys.client.client.services.RemoveArtifactServiceAsync;

import de.intevation.flys.client.client.ui.DatacagePairWidget;
import de.intevation.flys.client.client.ui.DatacageTwinPanel;
import de.intevation.flys.client.client.ui.RecommendationPairRecord;

import de.intevation.flys.client.shared.model.Artifact;
import de.intevation.flys.client.shared.model.Collection;
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.Recommendation.Facet;
import de.intevation.flys.client.shared.model.Recommendation.Filter;

import de.intevation.flys.client.shared.model.Recommendation;
import de.intevation.flys.client.shared.model.User;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

// TODO Probably better to branch off AbstractUIProvider.
// TODO Merge with other datacage-widget impls.
/**
 * Panel containing a Grid and a "next" button. The Grid is fed by a
 * DatacagePairWidget which is put in the input-helper area.
 */
public class BedHeightsDatacagePanel
extends      DatacageTwinPanel {

    protected static FLYSConstants MSG = GWT.create(FLYSConstants.class);

    /**
     * List to track previously selected but now removed pairs. (Needed to
     * be able to identify artifacts that can be removed from the collection.
     */
    protected List<RecommendationPairRecord> removedPairs =
        new ArrayList<RecommendationPairRecord>();

    /** Service handle to clone and add artifacts to collection. */
    LoadArtifactServiceAsync loadArtifactService = GWT.create(
            de.intevation.flys.client.client.services.LoadArtifactService.class);

    /** Service to remove artifacts from collection. */
    RemoveArtifactServiceAsync removeArtifactService = GWT.create(
            de.intevation.flys.client.client.services.RemoveArtifactService.class);


    public BedHeightsDatacagePanel(User user) {
        super(user);
    }


    /**
     * Create a recommendation from a string representation of it.
     * @TODO describe format of input string
     * @param from string in format as shown above.
     * @return recommendation from input string.
     */
    public Recommendation createRecommendationFromString(String from) {
        // TODO Construct "real" filter.
        String[] parts = unbracket(from).split(";");
        Recommendation.Filter filter = new Recommendation.Filter();
        Recommendation.Facet  facet  = new Recommendation.Facet(
                parts[1],
                parts[2]);

        List<Recommendation.Facet> facets = new ArrayList<Recommendation.Facet>
            ();
        facets.add(facet);
        filter.add("longitudinal_section", facets);
        Recommendation r = new Recommendation("bedheight", parts[0],
            this.artifact.getUuid(), filter);
        r.setDisplayName(parts[3]);
        return r;
    }


    /**
     * Creates the graphical representation and interaction widgets for the data.
     * @param dataList the data.
     * @return graphical representation and interaction widgets for data.
     */
    @Override
    public Canvas create(DataList dataList) {
        GWT.log("createData()");

        Data       data  = dataList.get(0);
        DataItem[] items = data.getItems();

        String value = items[0].getStringValue();

        String filter = "minfo-heights";
        if (value.equals("epoch")) {
            filter = "minfo-heights-epoch";
        }
        Canvas widget = createWidget();
        Canvas submit = getNextButton();

        VLayout layout       = new VLayout();
        HLayout helperLayout = new HLayout();
        helperLayout.addMember(new DatacagePairWidget(this.artifact,
            user, filter, differencesList));

        layout.addMember(widget);
        layout.addMember(submit);
        layout.setMembersMargin(10);
        this.helperContainer.addMember(helperLayout);

        this.dataName = "diffids";

        return layout;
    }


    /**
     * Add record to list of removed records.
     */
    public void trackRemoved(Record r) {
        RecommendationPairRecord pr = (RecommendationPairRecord) r;
        this.removedPairs.add(pr);
    }


    /**
     * Validates data, does nothing if invalid, otherwise clones new selected
     * waterlevels and add them to collection, forward the artifact.
     */
    @Override
    public void onClick(ClickEvent e) {
        GWT.log("DatacageTwinPanel.onClick");

        List<String> errors = validate();
        if (errors != null && !errors.isEmpty()) {
            showErrors(errors);
            return;
        }

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

        ListGridRecord[] records = differencesList.getRecords();

        List<Recommendation> ar  = new ArrayList<Recommendation>();
        List<Recommendation> all = new ArrayList<Recommendation>();

        for (ListGridRecord record : records) {
            RecommendationPairRecord r =
                (RecommendationPairRecord) record;
            // Do not add "old" recommendations.
            if (!r.isAlreadyLoaded()) {
                // Check whether one of those is a dike or similar.
                // TODO differentiate and merge: new clones, new, old.
                Recommendation firstR = r.getFirst();
                if(firstR.getIDs() != null) {
                    GWT.log("First IDs: " + firstR.getIDs() + " factory: "
                            + firstR.getFactory());
                }
                firstR.setFactory("bedheight");
                Recommendation secondR = r.getSecond();
                if(secondR.getIDs() != null) {
                    GWT.log("Second IDs: " + secondR.getIDs() + " factory: "
                            + secondR.getFactory());
                }
                secondR.setFactory("bedheight");

                ar.add(firstR);
                ar.add(secondR);
            }
            else {
                all.add(r.getFirst());
                all.add(r.getSecond());
            }
        }

        final Recommendation[] toClone = ar.toArray(new Recommendation[ar.size()]);
        final Recommendation[] toUse   = all.toArray(new Recommendation[all.size()]);

        // Find out whether "old" artifacts have to be removed.
        List<String> artifactIdsToRemove = new ArrayList<String>();
        for (RecommendationPairRecord rp: this.removedPairs) {
            Recommendation first  = rp.getFirst();
            Recommendation second = rp.getSecond();

            for (Recommendation recommendation: toUse) {
                if (first != null && first.getIDs().equals(recommendation.getIDs())) {
                    first = null;
                }
                if (second != null && second.getIDs().equals(recommendation.getIDs())) {
                    second = null;
                }

                if (first == null && second == null) {
                    break;
                }
            }
            if (first != null) {
                artifactIdsToRemove.add(first.getIDs());
            }
            if (second != null) {
                artifactIdsToRemove.add(second.getIDs());
            }
        }

        // Remove old artifacts, if any. Do this asychronously without much
        // feedback.
        for(final String uuid: artifactIdsToRemove) {
            removeArtifactService.remove(this.collection,
                uuid,
                locale,
                new AsyncCallback<Collection>() {
                    public void onFailure(Throwable caught) {
                        GWT.log("RemoveArtifact (" + uuid + ") failed.");
                    }
                    public void onSuccess(Collection collection) {
                        GWT.log("RemoveArtifact succeeded");
                    }
                });
        }

        // Clone new ones (and spawn statics), go forward.
        loadArtifactService.loadMany(
            this.collection,
            toClone,
            //"staticwkms" and "waterlevel"
            null,
            locale,
            new AsyncCallback<Artifact[]>() {
                public void onFailure(Throwable caught) {
                    GWT.log("Failure of cloning with factories!");
                }
                public void onSuccess(Artifact[] artifacts) {
                    GWT.log("Successfully cloned " + toClone.length +
                        " with factories.");

                    fireStepForwardEvent(new StepForwardEvent(
                        getData(toClone, artifacts, toUse)));
                }
            });
    }


    /**
     * Creates part of the String that encodes minuend or subtrahend.
     * @param artifact Artifacts UUID.
     * @param recommendation Recommendation to wrap in string.
     */
    protected String createDataString(
        String artifact,
        Recommendation recommendation)
    {
        Filter filter = recommendation.getFilter();
        Facet  f      = null;

        if(filter != null) {
            Map<String, List<Facet>>               outs = filter.getOuts();
            Set<Map.Entry<String, List<Facet>>> entries = outs.entrySet();

            for (Map.Entry<String, List<Facet>> entry: entries) {
                List<Facet> fs = entry.getValue();

                f = fs.get(0);
                if (f != null) {
                    break;
                }
            }

            return "[" + artifact + ";"
                + f.getName()
                + ";"
                + f.getIndex()
                + ";"
                + recommendation.getDisplayName() + "]";
        }
        else {
            return "["
                + artifact
                + ";bedheight;0;"
                + recommendation.getDisplayName() + "]";
        }
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org