# HG changeset patch # User Felix Wolfsteller # Date 1327584439 0 # Node ID 2f0150f21e776ee6069bf1b49622bde0e8b1f5b6 # Parent 2b3d02626823bbb17747fa11da1eb4215ed34c37 Added basic UI to enter manual points. flys-client/trunk@3773 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 2b3d02626823 -r 2f0150f21e77 flys-client/ChangeLog --- a/flys-client/ChangeLog Thu Jan 26 13:24:17 2012 +0000 +++ b/flys-client/ChangeLog Thu Jan 26 13:27:19 2012 +0000 @@ -1,3 +1,18 @@ +2012-01-26 Felix Wolfsteller + + Added basic UI to enter 'manual points'. + + * src/main/java/de/intevation/flys/client/client/ui/chart/ManualPointsEditor.java: + New. UI to enter and modify manual points. + + * src/main/java/de/intevation/flys/client/client/ui/chart/ChartToolbar.java: + Modified constructor to avoid passing unused parameters, instantiate + ManualPointsEditor on users command. + + * src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java: + Reflect change in ChartToolbars constructor. + (getView): New. + 2012-01-26 Felix Wolfsteller In preparation of 'manual points' feature, opened Collection diff -r 2b3d02626823 -r 2f0150f21e77 flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java --- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java Thu Jan 26 13:24:17 2012 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java Thu Jan 26 13:27:19 2012 +0000 @@ -42,6 +42,8 @@ /** + * Tab representing and showing one Chart-output. + * * @author Ingo Weinzierl */ public class ChartOutputTab @@ -149,7 +151,7 @@ //right.addChild(createChartPanel()); left.addChild(ctp); - tbarPanel = new ChartToolbar(collectionView, this); + tbarPanel = new ChartToolbar(this); vLayout.addMember(tbarPanel); vLayout.addMember(hLayout); @@ -626,5 +628,11 @@ protected double[] getZoomValues() { return zoom; } + + + /** Return the 'parent' CollectionView. */ + public CollectionView getView() { + return this.view; + } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 2b3d02626823 -r 2f0150f21e77 flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartToolbar.java --- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartToolbar.java Thu Jan 26 13:24:17 2012 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartToolbar.java Thu Jan 26 13:27:19 2012 +0000 @@ -54,7 +54,8 @@ protected PanControl panControl; - public ChartToolbar(CollectionView view, ChartOutputTab chartTab) { + /** @param chartTab Output-Tab on which this toolbar is located. */ + public ChartToolbar(ChartOutputTab chartTab) { super(chartTab); this.chartTab = chartTab; @@ -208,8 +209,7 @@ /** Open editor for custom points. */ protected void openPointWindow() { - - // TBD + new ManualPointsEditor(chartTab.getView().getCollection()).show(); } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 2b3d02626823 -r 2f0150f21e77 flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ManualPointsEditor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ManualPointsEditor.java Thu Jan 26 13:27:19 2012 +0000 @@ -0,0 +1,439 @@ +package de.intevation.flys.client.client.ui.chart; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import com.google.gwt.json.client.JSONArray; +import com.google.gwt.json.client.JSONNumber; +import com.google.gwt.json.client.JSONParser; +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.rpc.AsyncCallback; + +import com.smartgwt.client.util.SC; +import com.smartgwt.client.widgets.Window; +import com.smartgwt.client.widgets.tab.TabSet; +import com.smartgwt.client.widgets.tab.Tab; +import com.smartgwt.client.widgets.layout.VLayout; +import com.smartgwt.client.widgets.layout.HLayout; +import com.smartgwt.client.widgets.IButton; +import com.smartgwt.client.widgets.Button; +import com.smartgwt.client.widgets.Label; +import com.smartgwt.client.widgets.Canvas; +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.form.DynamicForm; +import com.smartgwt.client.widgets.form.fields.FormItem; +import com.smartgwt.client.widgets.form.fields.CheckboxItem; +import com.smartgwt.client.widgets.form.fields.TextItem; + +import com.smartgwt.client.widgets.events.ClickEvent; +import com.smartgwt.client.widgets.events.ClickHandler; +import com.smartgwt.client.widgets.form.fields.events.ChangedHandler; +import com.smartgwt.client.widgets.form.fields.events.ChangedEvent; +import com.smartgwt.client.widgets.form.fields.events.BlurHandler; +import com.smartgwt.client.widgets.form.fields.events.BlurEvent; + +import com.smartgwt.client.types.Alignment; + +import de.intevation.flys.client.shared.model.Artifact; + +import de.intevation.flys.client.client.Config; +import de.intevation.flys.client.client.FLYSConstants; +import de.intevation.flys.client.shared.model.Property; +import de.intevation.flys.client.shared.model.PropertyGroup; +import de.intevation.flys.client.shared.model.PropertySetting; +import de.intevation.flys.client.shared.model.BooleanProperty; +import de.intevation.flys.client.shared.model.DoubleProperty; +import de.intevation.flys.client.shared.model.IntegerProperty; +import de.intevation.flys.client.shared.model.StringProperty; +import de.intevation.flys.client.shared.model.Settings; +import de.intevation.flys.client.shared.model.OutputSettings; +import de.intevation.flys.client.shared.model.Collection; +import de.intevation.flys.client.shared.model.CollectionItem; +import de.intevation.flys.client.client.utils.IntegerValidator; +import de.intevation.flys.client.client.utils.DoubleValidator; + +import de.intevation.flys.client.client.services.CollectionAttributeService; +import de.intevation.flys.client.client.services.CollectionAttributeServiceAsync; +import de.intevation.flys.client.client.services.LoadArtifactService; +import de.intevation.flys.client.client.services.LoadArtifactServiceAsync; +import de.intevation.flys.client.client.services.FeedService; +import de.intevation.flys.client.client.services.FeedServiceAsync; + +import de.intevation.flys.client.shared.model.Data; +import de.intevation.flys.client.shared.model.DefaultArtifact; +import de.intevation.flys.client.shared.model.DefaultData; +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; + + +/** + * UI to enter point data and save it to an PointArtifact. + */ +public class ManualPointsEditor +extends Window +implements ClickHandler +{ + /** The interface that provides i18n messages. */ + protected FLYSConstants MSG = GWT.create(FLYSConstants.class); + + /** Name of the main data item to be fed. */ + public static final String POINT_DATA = "manualpoints.data"; + // TODO with separate point sets in multiple diagrams, we might need + // different POINT_DATA-names (e.g. one per diagram). + + protected CollectionAttributeServiceAsync updater = + GWT.create(CollectionAttributeService.class); + + /** The collection */ + protected Collection collection; + + /** The listGrid showing point entries. */ + protected ListGrid listGrid; + + /** Service handle to clone and add artifacts to collection. */ + LoadArtifactServiceAsync loadArtifactService = GWT.create( + de.intevation.flys.client.client.services.LoadArtifactService.class); + + /** Service to feed the artifact with new point-data. */ + FeedServiceAsync feedService = GWT.create( + de.intevation.flys.client.client.services.FeedService.class); + + /** UUID of artifact to feed. */ + protected String uuid; + + + /** + * Setup editor dialog. + * @param collection The collection to use. + */ + public ManualPointsEditor(Collection collection) { + this.collection = collection; + init(); + } + + + /** Searches collection for first artifact to serve (manual) point data. */ + public String findManualPointsUUID() { + // TODO Need to be more picky (different points in different diagrams) + int size = collection.getItemLength(); + + for (int i = 0; i < size; i++) { + CollectionItem item = collection.getItem(i); + String dataValue = (String) item.getData().get(POINT_DATA); + if (dataValue != null) { + // Found it. + uuid = item.identifier(); + return uuid; + } + } + + return null; + } + + + /** + * Initialize the editor window and its components. + */ + protected void init() { + setTitle("Add Points"); + //TODO MSG.properties()); + setCanDragReposition(true); + setCanDragResize(true); + + // If no manualpoints artifact found, create it now. + if(findManualPointsUUID() == null) { + addArtifactCreateUI(); + } + else { + createUI(); + } + } + + /** Create and setup/add the ui. */ + public void createUI() { + Config config = Config.getInstance(); + + Button accept = new Button(MSG.label_ok()); + Button cancel = new Button(MSG.label_cancel()); + cancel.addClickHandler(this); + accept.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent e) { + if(isDialogValid()) { + // Feed JSON-encoded content of listgrid. + String jsonString = ""; + int idx = 0; + JSONArray list = new JSONArray(); + + // TODO also need name attribute + for(ListGridRecord record : listGrid.getRecords()) { + if (record instanceof PointRecord) { + JSONArray data = new JSONArray(); + + PointRecord point = (PointRecord) record; + data.set(0, new JSONNumber(point.getX())); + data.set(1, new JSONNumber(point.getY())); + + list.set(idx, data); + idx++; + } + else { + JSONArray data = new JSONArray(); + + // TODO better get double directly (via cell-formatter etc) + String xString = record.getAttributeAsString("X"); + String yString = record.getAttributeAsString("Y"); + + data.set(0, new JSONNumber(Double.valueOf(xString))); + data.set(1, new JSONNumber(Double.valueOf(yString))); + + list.set(idx, data); + idx++; + } + } + + // TODO lock UI until feed succeeded/failed. + + // Feed list.toString to respective artifact. + Data[] feedData = new Data[] { + DefaultData.createSimpleStringData(POINT_DATA, + list.toString()) + }; + feedService.feed( + Config.getInstance().getLocale(), + new DefaultArtifact(uuid, "TODO:hash"), + feedData, + new AsyncCallback() { + public void onFailure(Throwable caught) { + GWT.log("Could not feed artifact with points."); + SC.warn(MSG.getString(caught.getMessage())); + enable(); + } + public void onSuccess(Artifact fartifact) { + GWT.log("Successfully set points "); + // TODO refresh view + //requestRedraw(); + //updateCollection(); + //updateGrid(); + //enable(); + destroy(); + } + }); + } + else { + GWT.log("Dialog not valid"); + SC.warn(MSG.error_dialog_not_valid()); + } + } + }); + + HLayout buttons = new HLayout(); + buttons.addMember(accept); + buttons.addMember(cancel); + buttons.setAlign(Alignment.CENTER); + buttons.setHeight(30); + + HLayout newPointLayout = new HLayout(); + DynamicForm newPointForm = createNewPointForm(); + newPointLayout.addMember(newPointForm); + + VLayout layout = new VLayout(); + listGrid = new ListGrid(); + listGrid.setWidth100(); + listGrid.setHeight(200); + final ListGridField xField = new ListGridField("X", "X"); + final ListGridField yField = new ListGridField("Y", "Y"); + final ListGridField nameField = new ListGridField("name", "name"); + final ListGridField removeField = new ListGridField("remove", "remove"); + listGrid.setFields(new ListGridField[] {xField, yField, removeField}); + + // Find the artifacts uuid. + findManualPointsUUID(); + CollectionItem item = collection.getItem(uuid); + + // Add points to grid. + if (item != null) { + String jsonData = item.getData().get(POINT_DATA); + JSONArray jsonArray = (JSONArray) JSONParser.parse(jsonData); + for (int i = 0; i < jsonArray.size(); i++) { + JSONArray point = (JSONArray) jsonArray.get(i); + listGrid.addData(pointRecordFromJSON(point)); + } + } + else { + System.out.println("No item found for " + uuid); + } + + layout.addMember(listGrid); + + addItem(layout); + IButton button = new IButton("Edit New"); + button.setTop(250); + button.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + listGrid.startEditingNew(); + } + }); + addItem(button); + addItem(buttons); + setWidth(380); + setHeight(470); + centerInPage(); + } + + + /** From a JSON-encoded point, create a PointRecord. */ + public PointRecord pointRecordFromJSON(JSONArray jsonArray) { + JSONNumber x = (JSONNumber) jsonArray.get(0); + JSONNumber y = (JSONNumber) jsonArray.get(1); + return new PointRecord(x.doubleValue(), y.doubleValue()); + } + + + /** Add a ManualPointArtifact to Collection. */ + public void addArtifactCreateUI() { + // TODO MSG:/i18n + final Label standByLabel = new Label("Creating artifact, these are not the droids"); + addItem(standByLabel); + + setWidth(380); + setHeight(470); + centerInPage(); + + Config config = Config.getInstance(); + String locale = config.getLocale(); + + loadArtifactService.load( + this.collection, + new Recommendation("manualpoints", ""), + "manualpoints", + locale, + new AsyncCallback() { + public void onFailure(Throwable caught) { + GWT.log("Creating manualpoint artifact failed!"); + } + public void onSuccess(Artifact artifact) { + GWT.log("Successfully created artifact."); + removeItem(standByLabel); + uuid = artifact.getUuid(); + createUI(); + } + }); + } + + + /** + * This method is called when the user aborts point editing. + * @param event The event. + */ + public void onClick(ClickEvent event) { + this.destroy(); + } + + + /** Simple record to store points. */ + public class PointRecord extends ListGridRecord { + protected static final String ATTRIBUTE_X = "X"; + protected static final String ATTRIBUTE_Y = "Y"; + + double x; + double y; + + private PointRecord() {;} + + public PointRecord(double x, double y) { + setX(x); + setY(y); + } + + public void setX(double x) { + this.x = x; + setAttribute(ATTRIBUTE_X, getX()); + } + + public void setY(double y) { + this.y = y; + setAttribute(ATTRIBUTE_Y, getY()); + } + + public double getX() { + return this.x; + } + + public double getY() { + return this.y; + } + } + + + // TODO cleanup. We need code similar to the following. + + /* + protected void updateCollection() { + final Config config = Config.getInstance(); + final String loc = config.getLocale(); + + GWT.log("PropertiesEditor.updateCollection via RPC now"); + + Settings s = settings; + collection.addSettings(this.tab.getOutputName(), s); + updater.update(collection, loc, new AsyncCallback() { + public void onFailure(Throwable caught) { + GWT.log("Could not update collection attributes."); + SC.warn(MSG.getString(caught.getMessage())); + } + public void onSuccess(Collection collection) { + updateChartTab(); + } + }); + } + +/* + protected void updateChartTab() { + this.tab.updateChartInfo(); + this.tab.updateChartPanel(); + this.destroy(); + } +*/ + + protected boolean isDialogValid() { + boolean valid = true; + /* + for (int i = 0; i < tabs.getNumTabs(); i++) { + Tab t = tabs.getTab(i); + Canvas container = t.getPane(); + Canvas[] children = container.getChildren(); + for (Canvas c: children) { + valid = validateCanvas(c); + if(!valid) { + return valid; + } + } + } + */ + return valid; + } + + + protected boolean validateCanvas(Canvas c) { + boolean valid = true; + if(c instanceof DynamicForm) { + DynamicForm f = (DynamicForm) c; + return !f.hasErrors(); + } + else if(c.getChildren().length > 0) { + for (Canvas child: c.getChildren()) { + valid = validateCanvas(child); + if(!valid) { + return valid; + } + } + } + return valid; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :