# HG changeset patch # User Raimund Renkert # Date 1346154672 0 # Node ID 60984be9bcfa2f4ed156735cf63c0c9a9cae6848 # Parent 59c77a9551c8f801c6cb64603f8727e23eaca116 MINFO: Added UI for minfo differences calculation. flys-client/trunk@5277 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 59c77a9551c8 -r 60984be9bcfa flys-client/ChangeLog --- a/flys-client/ChangeLog Fri Aug 24 14:14:30 2012 +0000 +++ b/flys-client/ChangeLog Tue Aug 28 11:51:12 2012 +0000 @@ -1,3 +1,21 @@ +2012-08-17 Raimund Renkert + + MINFO: Added UI for minfo differences calculation. + + * src/main/java/de/intevation/flys/client/client/ui/minfo, + src/main/java/de/intevation/flys/client/client/ui/minfo/BedHeightsDatacagePanel.java, + src/main/java/de/intevation/flys/client/client/ui/RadioPanel.java: + New. UI provider for states in minfo differences calculation. + + * src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java: + Added new UI provider. + + * src/main/java/de/intevation/flys/client/client/FLYSConstants.java, + src/main/java/de/intevation/flys/client/client/FLYSConstants.properties, + src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties: + Added i18n strings. + 2012-08-24 Björn Ricks * src/main/java/de/intevation/flys/client/server/auth/UserClient.java: diff -r 59c77a9551c8 -r 60984be9bcfa flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.java --- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.java Fri Aug 24 14:14:30 2012 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.java Tue Aug 28 11:51:12 2012 +0000 @@ -779,6 +779,14 @@ String gaugelocations(); + String single(); + + String epoch(); + + String bedheights(); + + String datacage(); + // Capabilities Information Panel String addwmsInputTitle(); diff -r 59c77a9551c8 -r 60984be9bcfa flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.properties --- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.properties Fri Aug 24 14:14:30 2012 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.properties Tue Aug 28 11:51:12 2012 +0000 @@ -395,6 +395,10 @@ dems = Digital Elevation Models hydrboundaries = Hydrological Boundaries gaugelocations = Location of Gauges +single = Year +epoch = Epoch +bedheights = Bedheights +datacage = Datacage # capabilities information panel addwmsInputTitle = Base URL of WMS service diff -r 59c77a9551c8 -r 60984be9bcfa flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties --- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties Fri Aug 24 14:14:30 2012 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties Tue Aug 28 11:51:12 2012 +0000 @@ -395,6 +395,10 @@ dems = Digitale Gel\u00e4ndemodelle hydrboundaries = Hydrologische Grenzen gaugelocations = Pegellagen +single = Jahr +epoch = Epoche +bedheights = Sohlh\u00f6hen +datacage = Datenkorb # capabilities information panel addwmsInputTitle = Basis URL des WMS Dienstes diff -r 59c77a9551c8 -r 60984be9bcfa flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties --- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties Fri Aug 24 14:14:30 2012 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties Tue Aug 28 11:51:12 2012 +0000 @@ -396,6 +396,10 @@ dems = Digital Elevation Models hydrboundaries = Hydrological Boundaries gaugelocations = Location of Gauges +single = Year +epoch = Epoch +bedheights = Bedheights +datacage = Datacage # capabilities information panel addwmsInputTitle = Base URL of WMS service diff -r 59c77a9551c8 -r 60984be9bcfa flys-client/src/main/java/de/intevation/flys/client/client/ui/RadioPanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/RadioPanel.java Tue Aug 28 11:51:12 2012 +0000 @@ -0,0 +1,93 @@ +package de.intevation.flys.client.client.ui; + +import java.util.LinkedHashMap; +import java.util.Map; + +import com.google.gwt.core.client.GWT; +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.layout.HLayout; +import com.smartgwt.client.widgets.layout.VLayout; + +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; + +public class RadioPanel extends AbstractUIProvider { + + protected String dataName; + protected DynamicForm form; + + @Override + public Canvas createOld(DataList dataList) { + // TODO Auto-generated method stub + Data data = dataList.get(0); + DataItem[] items = data.getItems(); + + HLayout layout = new HLayout(); + Label label = new Label(dataList.getLabel()); + Label value = new Label(items[0].getLabel()); + + layout.setHeight(35); + layout.setWidth(400); + label.setWidth(200); + + layout.addMember(label); + layout.addMember(value); + layout.addMember(getBackButton(dataList.getState())); + + return layout; + } + + @Override + public Canvas create(DataList dataList) { + Data data = dataList.get(0); + DataItem[] items = data.getItems(); + + this.dataName = data.getLabel(); + + VLayout layout = new VLayout(); + Label label = new Label(data.getDescription()); + RadioGroupItem rgi = new RadioGroupItem("selection"); + rgi.setShowTitle(false); + GWT.log("items: " + items.length); + LinkedHashMap elems = new LinkedHashMap(); + for (int i = 0; i < items.length; i++) { + GWT.log(items[i].getStringValue() + "; " + items[i].getLabel()); + elems.put(items[i].getStringValue(), items[i].getLabel()); + } + rgi.setValueMap(elems); + rgi.setDefaultValue(items[0].getStringValue()); + + form = new DynamicForm(); + form.setFields(rgi); + layout.setMembersMargin(10); + layout.setHeight(35); + label.setHeight(35); + + layout.addMember(label); + layout.addMember(form); + layout.addMember(getNextButton()); + layout.setMembersMargin(10); + + //initDefaultValues(dataList); + + return layout; + } + + @Override + protected Data[] getData() { + String value = form.getValueAsString("selection"); + DataItem item = new DefaultDataItem("ye_select", "ye_select", value); + return new Data[] { new DefaultData( + "ye_select", null, null, new DataItem[]{item})}; + } + + protected String getTitle(DataItem item) { + return item.getLabel(); + } +} diff -r 59c77a9551c8 -r 60984be9bcfa flys-client/src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java --- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java Fri Aug 24 14:14:30 2012 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java Tue Aug 28 11:51:12 2012 +0000 @@ -9,6 +9,7 @@ import de.intevation.flys.client.client.ui.fixation.FixQSelectPanel; import de.intevation.flys.client.client.ui.sq.SQMultiPeriodPanel; import de.intevation.flys.client.client.ui.sq.SQPeriodPanel; +import de.intevation.flys.client.client.ui.minfo.BedHeightsDatacagePanel; import de.intevation.flys.client.shared.model.User; /** @@ -132,6 +133,12 @@ else if (uiProvider.equals("parameter-matrix")) { return new ParameterMatrixPanel(); } + else if (uiProvider.equals("minfo.bed.year_epoch")) { + return new RadioPanel(); + } + else if (uiProvider.equals("bedheights_twin_panel")) { + return new BedHeightsDatacagePanel(user); + } else { //GWT.log("Picked default provider."); return new SelectProvider(); diff -r 59c77a9551c8 -r 60984be9bcfa flys-client/src/main/java/de/intevation/flys/client/client/ui/minfo/BedHeightsDatacagePanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/minfo/BedHeightsDatacagePanel.java Tue Aug 28 11:51:12 2012 +0000 @@ -0,0 +1,310 @@ +package de.intevation.flys.client.client.ui.minfo; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +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.types.ListGridFieldType; +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.grid.ListGrid; +import com.smartgwt.client.widgets.grid.ListGridField; +import com.smartgwt.client.widgets.grid.ListGridRecord; +import com.smartgwt.client.widgets.events.ClickEvent; +import com.smartgwt.client.widgets.grid.events.RecordClickEvent; +import com.smartgwt.client.widgets.grid.events.RecordClickHandler; + +import de.intevation.flys.client.client.ui.DatacageTwinPanel; + +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.DefaultData; +import de.intevation.flys.client.shared.model.DefaultDataItem; +import de.intevation.flys.client.shared.model.DataList; +import de.intevation.flys.client.shared.model.User; + +import de.intevation.flys.client.client.FLYSConstants; +import de.intevation.flys.client.client.event.StepForwardEvent; +import de.intevation.flys.client.shared.model.Recommendation; +import de.intevation.flys.client.shared.model.Recommendation.Facet; +import de.intevation.flys.client.shared.model.Recommendation.Filter; + +import de.intevation.flys.client.client.Config; +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.RecommendationPairRecord; +import de.intevation.flys.client.client.ui.DatacagePairWidget; + +// 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 removedPairs = + new ArrayList(); + + /** 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 facets = new ArrayList + (); + 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 errors = validate(); + if (errors != null && !errors.isEmpty()) { + showErrors(errors); + return; + } + + Config config = Config.getInstance(); + String locale = config.getLocale(); + + ListGridRecord[] records = differencesList.getRecords(); + + List ar = new ArrayList(); + List all = new ArrayList(); + + 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 artifactIdsToRemove = new ArrayList(); + 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() { + 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() { + 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> outs = filter.getOuts(); + Set>> entries = outs.entrySet(); + + for (Map.Entry> entry: entries) { + List 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 :