[PATCH] Refaktored the DatacageTwinPanel so it is reusable
Wald Commits
scm-commit at wald.intevation.org
Thu Jan 18 18:32:36 CET 2018
# HG changeset patch
# User gernotbelger
# Date 1516296750 -3600
# Node ID 8f6d6d26e96f0985b95cd99b1616b3a8eb7862c0
# Parent 13650d8a2373b27e49474ca16c3051858bf52714
Refaktored the DatacageTwinPanel so it is reusable.
diff -r 13650d8a2373 -r 8f6d6d26e96f artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelPairSelectState.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelPairSelectState.java Thu Jan 18 18:26:30 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelPairSelectState.java Thu Jan 18 18:32:30 2018 +0100
@@ -48,7 +48,7 @@
/** Specify to display a datacage_twin_panel. */
@Override
protected String getUIProvider() {
- return "datacage_twin_panel";
+ return "waterlevel_twin_panel";
}
diff -r 13650d8a2373 -r 8f6d6d26e96f gwt-client/src/main/java/org/dive4elements/river/client/client/ui/AbstractPairRecommendationPanel.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/AbstractPairRecommendationPanel.java Thu Jan 18 18:32:30 2018 +0100
@@ -0,0 +1,508 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.client.client.ui;
+
+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.events.ClickEvent;
+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.grid.events.RecordClickEvent;
+import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import org.dive4elements.river.client.client.Config;
+import org.dive4elements.river.client.client.FLYSConstants;
+import org.dive4elements.river.client.client.event.StepForwardEvent;
+import org.dive4elements.river.client.client.services.LoadArtifactServiceAsync;
+import org.dive4elements.river.client.client.services.RemoveArtifactServiceAsync;
+import org.dive4elements.river.client.shared.model.Artifact;
+import org.dive4elements.river.client.shared.model.Collection;
+import org.dive4elements.river.client.shared.model.Data;
+import org.dive4elements.river.client.shared.model.DataItem;
+import org.dive4elements.river.client.shared.model.DataList;
+import org.dive4elements.river.client.shared.model.DefaultData;
+import org.dive4elements.river.client.shared.model.DefaultDataItem;
+import org.dive4elements.river.client.shared.model.Recommendation;
+import org.dive4elements.river.client.shared.model.Recommendation.Facet;
+import org.dive4elements.river.client.shared.model.Recommendation.Filter;
+import org.dive4elements.river.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 abstract class AbstractPairRecommendationPanel
+extends TextProvider {
+
+ /**
+ * Allows for abstraction on how to handle/serialize the recommendation and the used factories.
+ * @author Gernot Belger
+ *
+ */
+ public static interface IRecommendationInfo {
+
+ String getFactory();
+
+ /**
+ * Separate factory for the 'createDataString' method, because in the case of waterlevels. See HOTFIX/FIXME there.
+ */
+ String getDataStringFactory();
+
+ /**
+ * Set factory of recommendation such that the correct artifacts will
+ * be cloned for difference calculations.
+ */
+ void adjustRecommendation(Recommendation recommendation);
+ }
+
+ public static interface IValidator
+ {
+ List<String> validate(ListGrid differencesList, FLYSConstants msgProvider);
+ }
+
+ private static final long serialVersionUID = 8906629596491827857L;
+
+ // FIXME: why? we hide the field of the super class with exactly the same thing...
+ private static FLYSConstants MSG_PROVIDER = GWT.create(FLYSConstants.class);
+
+ private String dataName;
+
+ private User user;
+
+ /** ListGrid that displays user-selected pairs to build differences with. */
+ private ListGrid differencesList;
+
+ /**
+ * List to track previously selected but now removed pairs. (Needed to
+ * be able to identify artifacts that can be removed from the collection.
+ */
+ private List<RecommendationPairRecord> removedPairs =
+ new ArrayList<RecommendationPairRecord>();
+
+ /** Service handle to clone and add artifacts to collection. */
+ private LoadArtifactServiceAsync loadArtifactService = GWT.create(
+ org.dive4elements.river.client.client.services.LoadArtifactService.class);
+
+ /** Service to remove artifacts from collection. */
+ private RemoveArtifactServiceAsync removeArtifactService = GWT.create(
+ org.dive4elements.river.client.client.services.RemoveArtifactService.class);
+
+ private IRecommendationInfo leftInfo;
+
+ private IRecommendationInfo rightInfo;
+
+ private IValidator validator;
+
+ /**
+ * @param Validates the content of this form when the user clicks 'apply'
+ * @param leftInfo Delegate for handling the left part of the recommendation-pair
+ * @param rightInfo Delegate for handling the right part of the recommendation-pair
+ */
+ public AbstractPairRecommendationPanel(final User user, IValidator validator, final IRecommendationInfo leftInfo, final IRecommendationInfo rightInfo ) {
+ this.user = user;
+ this.validator = validator;
+ this.leftInfo = leftInfo;
+ this.rightInfo = rightInfo;
+ }
+
+ // FIXME: better than copy/pasting the MSG field into every sub-class but not really nice yet.
+ protected final static FLYSConstants msg() {
+ return MSG_PROVIDER;
+ }
+
+ /**
+ * Remove first occurrence of "[" and "]" (if both do occur).
+ * @param value String to be stripped of [] (might be null).
+ * @return input string but with [ and ] removed, or input string if no
+ * brackets were found.
+ * @see StringUtil.unbracket
+ */
+ // FIXME: check if this is the same as STringUItils#unbracket
+ private static final String unbracket(String value) {
+ // null- guard.
+ if (value == null) return value;
+
+ int start = value.indexOf("[");
+ int end = value.indexOf("]");
+
+ if (start < 0 || end < 0) {
+ return value;
+ }
+
+ return value.substring(start + 1, end);
+ }
+
+ /**
+ * Create a recommendation from a string representation of it.
+ * @param from string in format as shown above.
+ * @param leftInfo2
+ * @return recommendation from input string.
+ */
+ private Recommendation createRecommendationFromString(final String from, final IRecommendationInfo info) {
+ // 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);
+
+ final String factory = info.getFactory( );
+
+ final Recommendation r = new Recommendation(factory, parts[0], this.artifact.getUuid(), filter);
+ r.setDisplayName(parts[3]);
+ return r;
+ }
+
+
+ /**
+ * Add RecomendationPairRecords from input String to the ListGrid.
+ */
+ private void populateGridFromString(String from){
+ // Split this string.
+ // Create according recommendations and display strings.
+ String[] recs = from.split("#");
+ if (recs.length % 2 != 0) return;
+ for (int i = 0; i < recs.length; i+=2) {
+ Recommendation minuend =
+ createRecommendationFromString(recs[i+0], leftInfo);
+ Recommendation subtrahend =
+ createRecommendationFromString(recs[i+1], rightInfo);
+
+ RecommendationPairRecord pr = new RecommendationPairRecord(
+ minuend, subtrahend);
+ // This Recommendation Pair comes from the data string and was thus
+ // already cloned.
+ pr.setIsAlreadyLoaded(true);
+ this.differencesList.addData(pr);
+ }
+ }
+
+ /**
+ * Creates the graphical representation and interaction widgets for the data.
+ * @param dataList the data.
+ * @return graphical representation and interaction widgets for data.
+ */
+ @Override
+ public final Canvas create(DataList dataList) {
+
+ final Canvas widget = createWidget();
+
+ final Canvas canvas = createChooserWidgets(widget, dataList, user, differencesList);
+
+ populateGrid(dataList);
+
+ return canvas;
+ }
+
+ /**
+ * Creates the individual parts of the input-helper area ('Eingabeunterstützung') for choosing the content of this widget.
+ */
+ protected abstract Canvas createChooserWidgets(final Canvas widget, final DataList dataList, final User auser, final ListGrid diffList);
+
+ private void populateGrid(DataList dataList) {
+ Data data = dataList.get(0);
+ this.dataName = data.getLabel();
+ for (int i = 0; i < dataList.size(); i++) {
+ if (dataList.get(i) != null && dataList.get(i).getItems() != null) {
+ if (dataList.get(i).getItems() != null) {
+ populateGridFromString(
+ dataList.get(i).getItems()[0].getStringValue());
+ }
+ }
+ }
+ }
+
+ @Override
+ public final List<String> validate() {
+ return validator.validate(differencesList, MSG_PROVIDER);
+ }
+
+ /**
+ * Creates layout with grid that displays selection inside.
+ */
+ protected final Canvas createWidget() {
+ VLayout layout = new VLayout();
+ differencesList = new ListGrid();
+
+ differencesList.setCanEdit(false);
+ differencesList.setCanSort(false);
+ differencesList.setShowHeaderContextMenu(false);
+ differencesList.setHeight(150);
+ differencesList.setShowAllRecords(true);
+
+ ListGridField nameField = new ListGridField("first", "Minuend");
+ ListGridField capitalField = new ListGridField("second", "Subtrahend");
+ // Track removed rows, therefore more or less reimplement
+ // setCanRecomeRecords.
+ final ListGridField removeField =
+ new ListGridField("_removeRecord", "Remove Record"){{
+ setType(ListGridFieldType.ICON);
+ setIcon(GWT.getHostPageBaseURL() + msg().removeFeature());
+ setCanEdit(false);
+ setCanFilter(false);
+ setCanSort(false);
+ setCanGroupBy(false);
+ setCanFreeze(false);
+ setWidth(25);
+ }};
+
+ differencesList.setFields(new ListGridField[] {nameField,
+ capitalField, removeField});
+
+ differencesList.addRecordClickHandler(new RecordClickHandler() {
+ @Override
+ public void onRecordClick(final RecordClickEvent event) {
+ // Just handle remove-clicks
+ if(!event.getField().getName().equals(removeField.getName())) {
+ return;
+ }
+ trackRemoved(event.getRecord());
+ event.getViewer().removeData(event.getRecord());
+ }
+ });
+ layout.addMember(differencesList);
+
+ return layout;
+ }
+
+
+ /**
+ * Add record to list of removed records.
+ */
+ protected final 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("AbstractPairRecommendationPanel.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();
+ leftInfo.adjustRecommendation(firstR);
+
+ Recommendation secondR = r.getSecond();
+ rightInfo.adjustRecommendation(secondR);
+ 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>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ GWT.log("RemoveArtifact (" + uuid + ") failed.");
+ }
+ @Override
+ public void onSuccess(Collection coll) {
+ GWT.log("RemoveArtifact succeeded");
+ }
+ });
+ }
+
+ // Clone new ones (and spawn statics), go forward.
+ parameterList.lockUI();
+ loadArtifactService.loadMany(
+ this.collection,
+ toClone,
+ //"staticwkms" and "waterlevel"
+ null,
+ locale,
+ new AsyncCallback<Artifact[]>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ caught.printStackTrace();
+ GWT.log("Failure of cloning with factories!");
+ parameterList.unlockUI();
+ }
+ @Override
+ public void onSuccess(Artifact[] artifacts) {
+ GWT.log("Successfully cloned " + toClone.length +
+ " with factories.");
+
+ fireStepForwardEvent(new StepForwardEvent(
+ getData(toClone, artifacts, toUse)));
+ parameterList.unlockUI();
+ }
+ });
+ }
+
+ /**
+ * Create Data and DataItem from selection (a long string with identifiers
+ * to construct diff-pairs).
+ *
+ * @param newRecommendations "new" recommendations (did not survive a
+ * backjump).
+ * @param newArtifacts artifacts cloned from newRecommendations.
+ * @param oldRecommendations old recommendations that survived a backjump.
+ *
+ * @return dataitem with a long string with identifiers to construct
+ * diff-pairs.
+ */
+ protected final Data[] getData(
+ Recommendation[] newRecommendations,
+ Artifact[] newArtifacts,
+ Recommendation[] oldRecommendations)
+ {
+ // Construct string with info about selections.
+ String dataItemString = "";
+ for (int i = 0; i < newRecommendations.length; i++) {
+ Recommendation r = newRecommendations[i];
+ Artifact newArtifact = newArtifacts[i];
+ String uuid = newArtifact.getUuid();
+ r.setMasterArtifact(uuid);
+
+ if (i>0)
+ dataItemString += "#";
+
+ // REMARK: ugly, but we know that the recommandations comes in left/right pairs.
+ final IRecommendationInfo info = i % 2 == 0 ? leftInfo : rightInfo;
+
+ dataItemString += createDataString(uuid, r, info);
+ }
+
+ for (int i = 0; i < oldRecommendations.length; i++) {
+ Recommendation r = oldRecommendations[i];
+ String uuid = r.getIDs();
+
+ if (dataItemString.length() > 0)
+ dataItemString += "#";
+
+ // REMARK: ugly, but we know that the recommandations comes in left/right pairs.
+ final IRecommendationInfo info = i % 2 == 0 ? leftInfo : rightInfo;
+
+ dataItemString += createDataString(uuid, r, info);
+ }
+
+ // TODO some hassle could be resolved by using multiple DataItems
+ // (e.g. one per pair).
+ DataItem item = new DefaultDataItem(dataName, dataName, dataItemString);
+ return new Data[] { new DefaultData(
+ dataName, null, null, new DataItem[] {item}) };
+ }
+
+ /**
+ * Creates part of the String that encodes minuend or subtrahend.
+ * @param recommendation Recommendation to wrap in string.
+ * @param info Provides the factory to encode.
+ */
+ protected static final String createDataString(final String artifactUuid, final Recommendation recommendation, final IRecommendationInfo info) {
+ final String factory = info.getDataStringFactory();
+
+ 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 "[" + artifactUuid + ";"
+ + f.getName()
+ + ";"
+ + f.getIndex()
+ + ";"
+ + recommendation.getDisplayName() + "]";
+ }
+
+ return "["
+ + artifactUuid
+ + ";" + factory + ";0;"
+ + recommendation.getDisplayName() + "]";
+ }
+}
\ No newline at end of file
diff -r 13650d8a2373 -r 8f6d6d26e96f gwt-client/src/main/java/org/dive4elements/river/client/client/ui/AbstractUIProvider.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/AbstractUIProvider.java Thu Jan 18 18:26:30 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/AbstractUIProvider.java Thu Jan 18 18:32:30 2018 +0100
@@ -307,12 +307,14 @@
return null;
}
-
+ /**
+ * Validates the selection.
+ * @return List of internationalized errror messages (if any).
+ */
public List<String> validate() {
return new ArrayList<String>(); // FIXME: What's this?
}
-
/** Create simple DefaultData with single DataItem inside. */
public static DefaultData createDataArray(String name, String value) {
DataItem item = new DefaultDataItem(
diff -r 13650d8a2373 -r 8f6d6d26e96f gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DatacagePairWidget.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DatacagePairWidget.java Thu Jan 18 18:26:30 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DatacagePairWidget.java Thu Jan 18 18:32:30 2018 +0100
@@ -49,12 +49,14 @@
*
* @param artifact Artifact to query datacage with.
* @param user User to query datacage with.
- * @param outs outs to query datacage with.
+ * @param leftOuts outs to query the left datacage with.
+ * @param rightOuts outs to query the right datacage with.
* @param grid Grid into which to insert selection of pairs.
*/
public DatacagePairWidget(Artifact artifact,
User user,
- String outs,
+ String leftOuts,
+ String rightOuts,
ListGrid grid) {
this.grid = grid;
@@ -62,13 +64,13 @@
firstDatacageWidget = new DatacageWidget(
artifact,
user,
- outs,
+ leftOuts,
"load-system:true",
false);
secondDatacageWidget = new DatacageWidget(
artifact,
user,
- outs,
+ rightOuts,
"load-system:true",
false);
firstDatacageWidget.setIsMutliSelectable(false);
diff -r 13650d8a2373 -r 8f6d6d26e96f gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DatacageTwinPanel.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DatacageTwinPanel.java Thu Jan 18 18:26:30 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DatacageTwinPanel.java Thu Jan 18 18:32:30 2018 +0100
@@ -8,511 +8,56 @@
package org.dive4elements.river.client.client.ui;
+import org.dive4elements.river.client.shared.model.DataList;
+import org.dive4elements.river.client.shared.model.User;
+
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.events.ClickEvent;
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.grid.events.RecordClickEvent;
-import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
-import org.dive4elements.river.client.client.Config;
-import org.dive4elements.river.client.client.FLYSConstants;
-import org.dive4elements.river.client.client.event.StepForwardEvent;
-import org.dive4elements.river.client.client.services.LoadArtifactServiceAsync;
-import org.dive4elements.river.client.client.services.RemoveArtifactServiceAsync;
-import org.dive4elements.river.client.shared.model.Artifact;
-import org.dive4elements.river.client.shared.model.Collection;
-import org.dive4elements.river.client.shared.model.Data;
-import org.dive4elements.river.client.shared.model.DataItem;
-import org.dive4elements.river.client.shared.model.DataList;
-import org.dive4elements.river.client.shared.model.DefaultData;
-import org.dive4elements.river.client.shared.model.DefaultDataItem;
-import org.dive4elements.river.client.shared.model.Recommendation;
-import org.dive4elements.river.client.shared.model.Recommendation.Facet;
-import org.dive4elements.river.client.shared.model.Recommendation.Filter;
-import org.dive4elements.river.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
+ * A {@link AbstractPairRecommendationPanel} that uses a 'TwinDatacage' in the help-input area.
* DatacagePairWidget which is put in the input-helper area.
*/
-public class DatacageTwinPanel
-extends TextProvider {
+public abstract class DatacageTwinPanel
+extends AbstractPairRecommendationPanel {
- private static final long serialVersionUID = 8906629596491827857L;
+ private IDatacageTwinPanelInfo leftInfo;
+ private IDatacageTwinPanelInfo rightInfo;
- protected static FLYSConstants MSG = GWT.create(FLYSConstants.class);
+ public static interface IDatacageTwinPanelInfo extends IRecommendationInfo
+ {
+ String getOuts();
+ }
+
+ public DatacageTwinPanel(final User user, IValidator validator, final IDatacageTwinPanelInfo leftInfo, final IDatacageTwinPanelInfo rightInfo ) {
+ super(user, validator, leftInfo, rightInfo);
- protected String dataName;
-
- protected User user;
-
- /** ListGrid that displays user-selected pairs to build differences with. */
- protected ListGrid differencesList;
-
- /**
- * 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(
- org.dive4elements.river.client.client.services.LoadArtifactService.class);
-
- /** Service to remove artifacts from collection. */
- RemoveArtifactServiceAsync removeArtifactService = GWT.create(
- org.dive4elements.river.client.client.services.RemoveArtifactService.class);
-
-
- public DatacageTwinPanel(User user) {
- super();
- this.user = user;
- }
-
-
- /**
- * Remove first occurrence of "[" and "]" (if both do occur).
- * @param value String to be stripped of [] (might be null).
- * @return input string but with [ and ] removed, or input string if no
- * brackets were found.
- * @see StringUtil.unbracket
- */
- public static final String unbracket(String value) {
- // null- guard.
- if (value == null) return value;
-
- int start = value.indexOf("[");
- int end = value.indexOf("]");
-
- if (start < 0 || end < 0) {
- return value;
- }
-
- value = value.substring(start + 1, end);
-
- return value;
- }
-
-
- /**
- * Create a recommendation from a string representation of it.
- * @param from string in format as shown above.
- * @return recommendation from input string.
- */
- public Recommendation createRecommendationFromString(String from, String factory) {
- // 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(factory, parts[0],
- this.artifact.getUuid(), filter);
- r.setDisplayName(parts[3]);
- return r;
- }
-
-
- /**
- * Add RecomendationPairRecords from input String to the ListGrid.
- */
- public void populateGridFromString(String from, String factory){
- // Split this string.
- // Create according recommendations and display strings.
- String[] recs = from.split("#");
- if (recs.length % 2 != 0) return;
- for (int i = 0; i < recs.length; i+=2) {
- Recommendation minuend =
- createRecommendationFromString(recs[i+0], factory);
- Recommendation subtrahend =
- createRecommendationFromString(recs[i+1], factory);
-
- RecommendationPairRecord pr = new RecommendationPairRecord(
- minuend, subtrahend);
- // This Recommendation Pair comes from the data string and was thus
- // already cloned.
- pr.setIsAlreadyLoaded(true);
- this.differencesList.addData(pr);
- }
- }
-
-
- /**
- * Creates the graphical representation and interaction widgets for the data.
- * @param dataList the data.
- * @return graphical representation and interaction widgets for data.
- */
+ this.leftInfo = leftInfo;
+ this.rightInfo = rightInfo;
+ }
+
@Override
- public Canvas create(DataList dataList) {
+ protected final Canvas createChooserWidgets(final Canvas widget, final DataList dataList, final User user, final ListGrid differencesList) {
GWT.log("createData()");
- Canvas widget = createWidget();
Canvas submit = getNextButton();
VLayout layout = new VLayout();
HLayout helperLayout = new HLayout();
- helperLayout.addMember(new DatacagePairWidget(this.artifact,
- user, "winfo_diff_twin_panel", differencesList));
+
+ final String leftOuts = leftInfo.getOuts();
+ final String rightOuts = rightInfo.getOuts();
+
+ helperLayout.addMember(new DatacagePairWidget(this.artifact, user, leftOuts, rightOuts, differencesList));
layout.addMember(widget);
layout.addMember(submit);
layout.setMembersMargin(10);
this.helperContainer.addMember(helperLayout);
- populateGrid(dataList, "waterlevel");
return layout;
}
-
- protected void populateGrid(DataList dataList, String factory) {
- Data data = dataList.get(0);
- this.dataName = data.getLabel();
- for (int i = 0; i < dataList.size(); i++) {
- if (dataList.get(i) != null && dataList.get(i).getItems() != null) {
- if (dataList.get(i).getItems() != null) {
- populateGridFromString(
- dataList.get(i).getItems()[0].getStringValue(),
- factory);
- }
- }
- }
- }
-
-
- /**
- * Validates the selection.
- * @return List of internationalized errror messages (if any).
- */
- @Override
- public List<String> validate() {
- List<String> errors = new ArrayList<String>();
- if (differencesList.getRecords().length == 0) {
- errors.add(MSG.error_no_waterlevel_pair_selected());
- }
- // Check whether minuend and subtrahend are equal.
- for (ListGridRecord record: differencesList.getRecords()) {
- RecommendationPairRecord r = (RecommendationPairRecord) record;
- if (r.getFirst().equals(r.getSecond())) {
- errors.add(MSG.error_same_waterlevels_in_pair());
- }
- }
-
- return errors;
- }
-
-
- /**
- * Creates layout with grid that displays selection inside.
- */
- public Canvas createWidget() {
- VLayout layout = new VLayout();
- differencesList = new ListGrid();
-
- differencesList.setCanEdit(false);
- differencesList.setCanSort(false);
- differencesList.setShowHeaderContextMenu(false);
- differencesList.setHeight(150);
- differencesList.setShowAllRecords(true);
-
- ListGridField nameField = new ListGridField("first", "Minuend");
- ListGridField capitalField = new ListGridField("second", "Subtrahend");
- // Track removed rows, therefore more or less reimplement
- // setCanRecomeRecords.
- final ListGridField removeField =
- new ListGridField("_removeRecord", "Remove Record"){{
- setType(ListGridFieldType.ICON);
- setIcon(GWT.getHostPageBaseURL() + MSG.removeFeature());
- setCanEdit(false);
- setCanFilter(false);
- setCanSort(false);
- setCanGroupBy(false);
- setCanFreeze(false);
- setWidth(25);
- }};
-
- differencesList.setFields(new ListGridField[] {nameField,
- capitalField, removeField});
-
- differencesList.addRecordClickHandler(new RecordClickHandler() {
- @Override
- public void onRecordClick(final RecordClickEvent event) {
- // Just handle remove-clicks
- if(!event.getField().getName().equals(removeField.getName())) {
- return;
- }
- trackRemoved(event.getRecord());
- event.getViewer().removeData(event.getRecord());
- }
- });
- layout.addMember(differencesList);
-
- return layout;
- }
-
-
- /**
- * Add record to list of removed records.
- */
- public void trackRemoved(Record r) {
- RecommendationPairRecord pr = (RecommendationPairRecord) r;
- this.removedPairs.add(pr);
- }
-
- /**
- * Set factory of recommendation such that the correct artifacts will
- * be cloned for difference calculations.
- */
- public void adjustRecommendation(Recommendation recommendation) {
- // XXX: THIS IS AN EVIL HACK TO MAKE W-DIFFERENCES WORK AGAIN!
- // TODO: Throw all this code away and do it with server side recommendations!
- recommendation.setTargetOut("w_differences");
-
- if (recommendation.getIDs() != null) {
- GWT.log("Setting staticwkms factory for rec with ID "
- + recommendation.getIDs());
- recommendation.setFactory("staticwkms");
- }
- /*
- // So far, we do not need to rewrite the factory anymore,
- // except for staticwkms; probably other cases will pop up later.
- else if (recommendation.getFactory().equals("winfo")) {
- GWT.log("Setting waterlevel factory for a winfo rec.");
- recommendation.setFactory("waterlevel");
- }
- */
- else {
- GWT.log("Leave rec. id " + recommendation.getIDs() + ", factory "
- + recommendation.getFactory() + " untouched.");
- }
- }
-
- /**
- * 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();
- adjustRecommendation(firstR);
-
- Recommendation secondR = r.getSecond();
- adjustRecommendation(secondR);
- 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>() {
- @Override
- public void onFailure(Throwable caught) {
- GWT.log("RemoveArtifact (" + uuid + ") failed.");
- }
- @Override
- public void onSuccess(Collection collection) {
- GWT.log("RemoveArtifact succeeded");
- }
- });
- }
-
- // Clone new ones (and spawn statics), go forward.
- parameterList.lockUI();
- loadArtifactService.loadMany(
- this.collection,
- toClone,
- //"staticwkms" and "waterlevel"
- null,
- locale,
- new AsyncCallback<Artifact[]>() {
- @Override
- public void onFailure(Throwable caught) {
- GWT.log("Failure of cloning with factories!");
- parameterList.unlockUI();
- }
- @Override
- public void onSuccess(Artifact[] artifacts) {
- GWT.log("Successfully cloned " + toClone.length +
- " with factories.");
-
- fireStepForwardEvent(new StepForwardEvent(
- getData(toClone, artifacts, toUse)));
- parameterList.unlockUI();
- }
- });
- }
-
-
- /**
- * Create Data and DataItem from selection (a long string with identifiers
- * to construct diff-pairs).
- *
- * @param newRecommendations "new" recommendations (did not survive a
- * backjump).
- * @param newArtifacts artifacts cloned from newRecommendations.
- * @param oldRecommendations old recommendations that survived a backjump.
- *
- * @return dataitem with a long string with identifiers to construct
- * diff-pairs.
- */
- protected Data[] getData(
- Recommendation[] newRecommendations,
- Artifact[] newArtifacts,
- Recommendation[] oldRecommendations)
- {
- // Construct string with info about selections.
- String dataItemString = "";
- for (int i = 0; i < newRecommendations.length; i++) {
- Recommendation r = newRecommendations[i];
- Artifact newArtifact = newArtifacts[i];
- String uuid = newArtifact.getUuid();
- r.setMasterArtifact(uuid);
- if (i>0) dataItemString += "#";
-
- dataItemString += createDataString(uuid, r);
- }
-
- for (int i = 0; i < oldRecommendations.length; i++) {
- Recommendation r = oldRecommendations[i];
- String uuid = r.getIDs();
- if (dataItemString.length() > 0) dataItemString += "#";
-
- dataItemString += createDataString(uuid, r);
- }
-
- // TODO some hassle could be resolved by using multiple DataItems
- // (e.g. one per pair).
- DataItem item = new DefaultDataItem(dataName, dataName, dataItemString);
- return new Data[] { new DefaultData(
- dataName, null, null, new DataItem[] {item}) };
- }
-
-
- protected String createDataString(String artifact, Recommendation recommendation) {
- return createDataString(artifact, recommendation, "staticwkms");
- }
-
- /**
- * Creates part of the String that encodes minuend or subtrahend.
- * @param artifact Artifacts UUID.
- * @param recommendation Recommendation to wrap in string.
- * @param factory The factory to encode.
- */
- protected String createDataString(
- String artifact,
- Recommendation recommendation,
- String factory)
- {
- 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
- + ";" + factory + ";0;"
- + recommendation.getDisplayName() + "]";
- }
- }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+}
\ No newline at end of file
diff -r 13650d8a2373 -r 8f6d6d26e96f gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DefaultDatacageTwinPanelInfo.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DefaultDatacageTwinPanelInfo.java Thu Jan 18 18:32:30 2018 +0100
@@ -0,0 +1,47 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui;
+
+import org.dive4elements.river.client.client.ui.DatacageTwinPanel.IDatacageTwinPanelInfo;
+import org.dive4elements.river.client.shared.model.Recommendation;
+
+/**
+ * @author Gernot Belger
+ */
+public final class DefaultDatacageTwinPanelInfo implements IDatacageTwinPanelInfo {
+
+ private String factory;
+ private String outs;
+
+ public DefaultDatacageTwinPanelInfo(final String factory, final String outs) {
+ this.factory = factory;
+ this.outs = outs;
+ }
+
+ @Override
+ public String getFactory() {
+ return factory;
+ }
+
+ @Override
+ public String getDataStringFactory() {
+ return factory;
+ }
+
+ @Override
+ public void adjustRecommendation(Recommendation recommendation) {
+ recommendation.setFactory(factory);
+ }
+
+ @Override
+ public String getOuts() {
+ return outs;
+ }
+}
\ No newline at end of file
diff -r 13650d8a2373 -r 8f6d6d26e96f gwt-client/src/main/java/org/dive4elements/river/client/client/ui/WaterlevelRecommandationInfo.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/WaterlevelRecommandationInfo.java Thu Jan 18 18:32:30 2018 +0100
@@ -0,0 +1,69 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui;
+
+import org.dive4elements.river.client.client.ui.DatacageTwinPanel.IDatacageTwinPanelInfo;
+import org.dive4elements.river.client.shared.model.Recommendation;
+
+import com.google.gwt.core.client.GWT;
+
+/**
+ * @author Gernot Belger
+ */
+public final class WaterlevelRecommandationInfo implements IDatacageTwinPanelInfo {
+
+ private String outs;
+
+ public WaterlevelRecommandationInfo(String outs ) {
+ this.outs = outs;
+ }
+
+ @Override
+ public String getFactory() {
+ // FIXME: why are the factory here and the one used in createDataString different?
+ // Probably also because of the 'throw all this code away comment'
+ return "waterlevel";
+ }
+
+ @Override
+ public String getDataStringFactory() {
+ return "staticwkms";
+ }
+
+ @Override
+ public void adjustRecommendation(Recommendation recommendation) {
+ // XXX: THIS IS AN EVIL HACK TO MAKE W-DIFFERENCES WORK AGAIN!
+ // TODO: Throw all this code away and do it with server side recommendations!
+ recommendation.setTargetOut("w_differences");
+
+ if (recommendation.getIDs() != null) {
+ GWT.log("Setting staticwkms factory for rec with ID "
+ + recommendation.getIDs());
+ recommendation.setFactory("staticwkms");
+ }
+ /*
+ // So far, we do not need to rewrite the factory anymore,
+ // except for staticwkms; probably other cases will pop up later.
+ else if (recommendation.getFactory().equals("winfo")) {
+ GWT.log("Setting waterlevel factory for a winfo rec.");
+ recommendation.setFactory("waterlevel");
+ }
+ */
+ else {
+ GWT.log("Leave rec. id " + recommendation.getIDs() + ", factory "
+ + recommendation.getFactory() + " untouched.");
+ }
+ }
+
+ @Override
+ public String getOuts() {
+ return outs;
+ }
+}
\ No newline at end of file
diff -r 13650d8a2373 -r 8f6d6d26e96f gwt-client/src/main/java/org/dive4elements/river/client/client/ui/WaterlevelTwinPanel.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/WaterlevelTwinPanel.java Thu Jan 18 18:32:30 2018 +0100
@@ -0,0 +1,25 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui;
+
+import org.dive4elements.river.client.shared.model.User;
+
+/**
+ * A DatacageTwinPanel implementation for W-INFO Differences: choose two waterlevels
+ *
+ * @author Gernot Belger
+ */
+public class WaterlevelTwinPanel
+extends DatacageTwinPanel {
+
+ public WaterlevelTwinPanel(final User user) {
+ super(user, new WaterlevelTwinPanelValidator(), new WaterlevelRecommandationInfo("winfo_diff_twin_panel"), new WaterlevelRecommandationInfo("winfo_diff_twin_panel") );
+ }
+}
\ No newline at end of file
diff -r 13650d8a2373 -r 8f6d6d26e96f gwt-client/src/main/java/org/dive4elements/river/client/client/ui/WaterlevelTwinPanelValidator.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/WaterlevelTwinPanelValidator.java Thu Jan 18 18:32:30 2018 +0100
@@ -0,0 +1,48 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.dive4elements.river.client.client.FLYSConstants;
+import org.dive4elements.river.client.client.ui.AbstractPairRecommendationPanel.IValidator;
+
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+/**
+ * Contains the old code from the validate-method of the DatacageTwinPanel.
+ *
+ * @author Gernot Belger
+ */
+public final class WaterlevelTwinPanelValidator implements IValidator {
+
+ @Override
+ public List<String> validate(final ListGrid differencesList, final FLYSConstants msgProvider) {
+
+ final List<String> errors = new ArrayList<String>();
+ if (differencesList.getRecords().length == 0) {
+ // FIXME: waterlevel dependent! This will lead to a bad error message in English, for M-Info/Bed-Differences calculation
+ errors.add(msgProvider.error_no_waterlevel_pair_selected());
+ }
+ // Check whether minuend and subtrahend are equal.
+ for (ListGridRecord record: differencesList.getRecords()) {
+ RecommendationPairRecord r = (RecommendationPairRecord) record;
+ if (r.getFirst().equals(r.getSecond())) {
+ // FIXME: this is still waterlevel specific!
+ // TODO: delegate validation to specific implementations
+ errors.add(msgProvider.error_same_waterlevels_in_pair());
+ }
+ }
+
+ return errors;
+ }
+}
\ No newline at end of file
diff -r 13650d8a2373 -r 8f6d6d26e96f gwt-client/src/main/java/org/dive4elements/river/client/client/ui/minfo/BedHeightsDatacagePanel.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/minfo/BedHeightsDatacagePanel.java Thu Jan 18 18:26:30 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/minfo/BedHeightsDatacagePanel.java Thu Jan 18 18:32:30 2018 +0100
@@ -8,83 +8,51 @@
package org.dive4elements.river.client.client.ui.minfo;
+import java.util.List;
+
+import org.dive4elements.river.client.client.ui.AbstractPairRecommendationPanel;
+import org.dive4elements.river.client.client.ui.DatacageWidget;
+import org.dive4elements.river.client.client.ui.DefaultDatacageTwinPanelInfo;
+import org.dive4elements.river.client.client.ui.RecommendationPairRecord;
+import org.dive4elements.river.client.client.ui.WaterlevelTwinPanelValidator;
+import org.dive4elements.river.client.shared.model.DataList;
+import org.dive4elements.river.client.shared.model.ToLoad;
+import org.dive4elements.river.client.shared.model.User;
+
import com.google.gwt.core.client.GWT;
-
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Canvas;
-
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
-
+import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tree.TreeNode;
-import org.dive4elements.river.client.client.FLYSConstants;
-
-import org.dive4elements.river.client.client.services.LoadArtifactServiceAsync;
-import org.dive4elements.river.client.client.services.RemoveArtifactServiceAsync;
-
-import org.dive4elements.river.client.client.ui.DatacageTwinPanel;
-import org.dive4elements.river.client.client.ui.DatacageWidget;
-import org.dive4elements.river.client.client.ui.RecommendationPairRecord;
-
-import org.dive4elements.river.client.shared.model.DataList;
-import org.dive4elements.river.client.shared.model.ToLoad;
-
-import org.dive4elements.river.client.shared.model.Recommendation;
-import org.dive4elements.river.client.shared.model.User;
-
-import java.util.ArrayList;
-import java.util.List;
-
-// TODO Probably better to branch off AbstractUIProvider.
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(
- org.dive4elements.river.client.client.services.LoadArtifactService.class);
-
- /** Service to remove artifacts from collection. */
- RemoveArtifactServiceAsync removeArtifactService = GWT.create(
- org.dive4elements.river.client.client.services.RemoveArtifactService.class);
-
- protected DatacageWidget datacage;
+extends AbstractPairRecommendationPanel {
public BedHeightsDatacagePanel(User user) {
- super(user);
+ // FIXME: This will lead to a bad error message in English (i.e. contains something about waterlevels), for M-Info/Bed-Differences calculation
+ // BUT: this is the behavior of 3.2.1 (because of sloppy derivation), so we do not change it now
+ super(user, new WaterlevelTwinPanelValidator(), new DefaultDatacageTwinPanelInfo("bedheight", null), new DefaultDatacageTwinPanelInfo("bedheight", null) );
}
- /**
- * 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) {
+ protected Canvas createChooserWidgets(final Canvas widget, final DataList dataList, final User user, final ListGrid differencesList) {
GWT.log("createData()");
- Canvas widget = createWidget();
Canvas submit = getNextButton();
- datacage = new DatacageWidget(
+
+ final DatacageWidget datacage = new DatacageWidget(
this.artifact, user, "minfo_diff_panel", "load-system:true", false);
- Button plusBtn = new Button(MSG.datacage_add_pair());
+ Button plusBtn = new Button(msg().datacage_add_pair());
plusBtn.setAutoFit(true);
plusBtn.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
- plusClicked();
+ plusClicked(datacage, differencesList);
}
});
@@ -98,29 +66,19 @@
layout.setMembersMargin(10);
this.helperContainer.addMember(helperLayout);
- populateGrid(dataList, "bedheight");
-
return layout;
}
- public void adjustRecommendation(Recommendation recommendation) {
- recommendation.setFactory("bedheight");
- }
-
- @Override
- protected String createDataString(String artifact, Recommendation recommendation) {
- return createDataString(artifact, recommendation, "bedheight");
- }
-
/**
* Callback for add-button.
* Fires to load for every selected element and handler.
+ * @param differencesList
*/
- public void plusClicked() {
+ protected final static void plusClicked( final DatacageWidget datacage, ListGrid differencesList ) {
List<TreeNode> selection = datacage.getPlainSelection();
if (selection == null || selection.isEmpty()) {
- SC.say(MSG.warning());
+ SC.say(msg().warning());
return;
}
More information about the Dive4Elements-commits
mailing list