felix@1545: package de.intevation.flys.client.client.ui.chart; felix@1545: felix@1545: import java.util.ArrayList; felix@1545: import java.util.List; felix@1545: import java.util.Map; felix@1545: felix@1545: import com.google.gwt.json.client.JSONArray; felix@1545: import com.google.gwt.json.client.JSONNumber; felix@1545: import com.google.gwt.json.client.JSONParser; felix@1545: import com.google.gwt.core.client.GWT; felix@1545: import com.google.gwt.user.client.rpc.AsyncCallback; felix@1545: felix@1545: import com.smartgwt.client.util.SC; felix@1545: import com.smartgwt.client.widgets.Window; felix@1545: import com.smartgwt.client.widgets.tab.TabSet; felix@1545: import com.smartgwt.client.widgets.tab.Tab; felix@1545: import com.smartgwt.client.widgets.layout.VLayout; felix@1545: import com.smartgwt.client.widgets.layout.HLayout; felix@1545: import com.smartgwt.client.widgets.IButton; felix@1545: import com.smartgwt.client.widgets.Button; felix@1545: import com.smartgwt.client.widgets.Label; felix@1545: import com.smartgwt.client.widgets.Canvas; felix@1545: import com.smartgwt.client.widgets.grid.ListGrid; felix@1545: import com.smartgwt.client.widgets.grid.ListGridField; felix@1545: import com.smartgwt.client.widgets.grid.ListGridRecord; felix@1545: felix@1545: import com.smartgwt.client.widgets.form.DynamicForm; felix@1545: import com.smartgwt.client.widgets.form.fields.FormItem; felix@1545: import com.smartgwt.client.widgets.form.fields.CheckboxItem; felix@1545: import com.smartgwt.client.widgets.form.fields.TextItem; felix@1545: felix@1545: import com.smartgwt.client.widgets.events.ClickEvent; felix@1545: import com.smartgwt.client.widgets.events.ClickHandler; felix@1545: import com.smartgwt.client.widgets.form.fields.events.ChangedHandler; felix@1545: import com.smartgwt.client.widgets.form.fields.events.ChangedEvent; felix@1545: import com.smartgwt.client.widgets.form.fields.events.BlurHandler; felix@1545: import com.smartgwt.client.widgets.form.fields.events.BlurEvent; felix@1545: felix@1545: import com.smartgwt.client.types.Alignment; felix@1545: felix@1545: import de.intevation.flys.client.shared.model.Artifact; felix@1545: felix@1545: import de.intevation.flys.client.client.Config; felix@1545: import de.intevation.flys.client.client.FLYSConstants; felix@1545: import de.intevation.flys.client.shared.model.Property; felix@1545: import de.intevation.flys.client.shared.model.PropertyGroup; felix@1545: import de.intevation.flys.client.shared.model.PropertySetting; felix@1545: import de.intevation.flys.client.shared.model.BooleanProperty; felix@1545: import de.intevation.flys.client.shared.model.DoubleProperty; felix@1545: import de.intevation.flys.client.shared.model.IntegerProperty; felix@1545: import de.intevation.flys.client.shared.model.StringProperty; felix@1545: import de.intevation.flys.client.shared.model.Settings; felix@1545: import de.intevation.flys.client.shared.model.OutputSettings; felix@1545: import de.intevation.flys.client.shared.model.Collection; felix@1545: import de.intevation.flys.client.shared.model.CollectionItem; felix@1545: import de.intevation.flys.client.client.utils.IntegerValidator; felix@1545: import de.intevation.flys.client.client.utils.DoubleValidator; felix@1545: felix@1545: import de.intevation.flys.client.client.services.CollectionAttributeService; felix@1545: import de.intevation.flys.client.client.services.CollectionAttributeServiceAsync; felix@1545: import de.intevation.flys.client.client.services.LoadArtifactService; felix@1545: import de.intevation.flys.client.client.services.LoadArtifactServiceAsync; felix@1545: import de.intevation.flys.client.client.services.FeedService; felix@1545: import de.intevation.flys.client.client.services.FeedServiceAsync; felix@1545: felix@1545: import de.intevation.flys.client.shared.model.Data; felix@1545: import de.intevation.flys.client.shared.model.DefaultArtifact; felix@1545: import de.intevation.flys.client.shared.model.DefaultData; felix@1545: import de.intevation.flys.client.shared.model.Recommendation; felix@1545: import de.intevation.flys.client.shared.model.Recommendation.Facet; felix@1545: import de.intevation.flys.client.shared.model.Recommendation.Filter; felix@1545: felix@1545: felix@1545: /** felix@1545: * UI to enter point data and save it to an PointArtifact. felix@1545: */ felix@1545: public class ManualPointsEditor felix@1545: extends Window felix@1545: implements ClickHandler felix@1545: { felix@1545: /** The interface that provides i18n messages. */ felix@1545: protected FLYSConstants MSG = GWT.create(FLYSConstants.class); felix@1545: felix@1545: /** Name of the main data item to be fed. */ felix@1545: public static final String POINT_DATA = "manualpoints.data"; felix@1545: // TODO with separate point sets in multiple diagrams, we might need felix@1545: // different POINT_DATA-names (e.g. one per diagram). felix@1545: felix@1545: protected CollectionAttributeServiceAsync updater = felix@1545: GWT.create(CollectionAttributeService.class); felix@1545: felix@1545: /** The collection */ felix@1545: protected Collection collection; felix@1545: felix@1545: /** The listGrid showing point entries. */ felix@1545: protected ListGrid listGrid; felix@1545: felix@1545: /** Service handle to clone and add artifacts to collection. */ felix@1545: LoadArtifactServiceAsync loadArtifactService = GWT.create( felix@1545: de.intevation.flys.client.client.services.LoadArtifactService.class); felix@1545: felix@1545: /** Service to feed the artifact with new point-data. */ felix@1545: FeedServiceAsync feedService = GWT.create( felix@1545: de.intevation.flys.client.client.services.FeedService.class); felix@1545: felix@1545: /** UUID of artifact to feed. */ felix@1545: protected String uuid; felix@1545: felix@1545: felix@1545: /** felix@1545: * Setup editor dialog. felix@1545: * @param collection The collection to use. felix@1545: */ felix@1545: public ManualPointsEditor(Collection collection) { felix@1545: this.collection = collection; felix@1545: init(); felix@1545: } felix@1545: felix@1545: felix@1545: /** Searches collection for first artifact to serve (manual) point data. */ felix@1545: public String findManualPointsUUID() { felix@1545: // TODO Need to be more picky (different points in different diagrams) felix@1545: int size = collection.getItemLength(); felix@1545: felix@1545: for (int i = 0; i < size; i++) { felix@1545: CollectionItem item = collection.getItem(i); felix@1545: String dataValue = (String) item.getData().get(POINT_DATA); felix@1545: if (dataValue != null) { felix@1545: // Found it. felix@1545: uuid = item.identifier(); felix@1545: return uuid; felix@1545: } felix@1545: } felix@1545: felix@1545: return null; felix@1545: } felix@1545: felix@1545: felix@1545: /** felix@1545: * Initialize the editor window and its components. felix@1545: */ felix@1545: protected void init() { felix@1545: setTitle("Add Points"); felix@1545: //TODO MSG.properties()); felix@1545: setCanDragReposition(true); felix@1545: setCanDragResize(true); felix@1545: felix@1545: // If no manualpoints artifact found, create it now. felix@1545: if(findManualPointsUUID() == null) { felix@1545: addArtifactCreateUI(); felix@1545: } felix@1545: else { felix@1545: createUI(); felix@1545: } felix@1545: } felix@1545: felix@1547: felix@1545: /** Create and setup/add the ui. */ felix@1545: public void createUI() { felix@1545: Config config = Config.getInstance(); felix@1545: felix@1545: Button accept = new Button(MSG.label_ok()); felix@1545: Button cancel = new Button(MSG.label_cancel()); felix@1545: cancel.addClickHandler(this); felix@1545: accept.addClickHandler(new ClickHandler() { felix@1545: public void onClick(ClickEvent e) { felix@1545: if(isDialogValid()) { felix@1545: // Feed JSON-encoded content of listgrid. felix@1545: String jsonString = ""; felix@1545: int idx = 0; felix@1545: JSONArray list = new JSONArray(); felix@1545: felix@1545: // TODO also need name attribute felix@1545: for(ListGridRecord record : listGrid.getRecords()) { felix@1545: if (record instanceof PointRecord) { felix@1545: JSONArray data = new JSONArray(); felix@1545: felix@1545: PointRecord point = (PointRecord) record; felix@1545: data.set(0, new JSONNumber(point.getX())); felix@1545: data.set(1, new JSONNumber(point.getY())); felix@1545: felix@1545: list.set(idx, data); felix@1545: idx++; felix@1545: } felix@1545: else { felix@1545: JSONArray data = new JSONArray(); felix@1545: felix@1545: // TODO better get double directly (via cell-formatter etc) felix@1545: String xString = record.getAttributeAsString("X"); felix@1545: String yString = record.getAttributeAsString("Y"); felix@1545: felix@1545: data.set(0, new JSONNumber(Double.valueOf(xString))); felix@1545: data.set(1, new JSONNumber(Double.valueOf(yString))); felix@1545: felix@1545: list.set(idx, data); felix@1545: idx++; felix@1545: } felix@1545: } felix@1545: felix@1545: // TODO lock UI until feed succeeded/failed. felix@1545: felix@1545: // Feed list.toString to respective artifact. felix@1545: Data[] feedData = new Data[] { felix@1545: DefaultData.createSimpleStringData(POINT_DATA, felix@1545: list.toString()) felix@1545: }; felix@1545: feedService.feed( felix@1545: Config.getInstance().getLocale(), felix@1545: new DefaultArtifact(uuid, "TODO:hash"), felix@1545: feedData, felix@1545: new AsyncCallback() { felix@1545: public void onFailure(Throwable caught) { felix@1545: GWT.log("Could not feed artifact with points."); felix@1545: SC.warn(MSG.getString(caught.getMessage())); felix@1545: enable(); felix@1545: } felix@1545: public void onSuccess(Artifact fartifact) { felix@1545: GWT.log("Successfully set points "); felix@1545: // TODO refresh view felix@1545: //requestRedraw(); felix@1545: //updateCollection(); felix@1545: //updateGrid(); felix@1545: //enable(); felix@1545: destroy(); felix@1545: } felix@1545: }); felix@1545: } felix@1545: else { felix@1545: GWT.log("Dialog not valid"); felix@1545: SC.warn(MSG.error_dialog_not_valid()); felix@1545: } felix@1545: } felix@1545: }); felix@1545: felix@1545: HLayout buttons = new HLayout(); felix@1545: buttons.addMember(accept); felix@1545: buttons.addMember(cancel); felix@1545: buttons.setAlign(Alignment.CENTER); felix@1545: buttons.setHeight(30); felix@1545: felix@1545: VLayout layout = new VLayout(); felix@1545: listGrid = new ListGrid(); felix@1545: listGrid.setWidth100(); felix@1545: listGrid.setHeight(200); felix@1545: final ListGridField xField = new ListGridField("X", "X"); felix@1545: final ListGridField yField = new ListGridField("Y", "Y"); felix@1545: final ListGridField nameField = new ListGridField("name", "name"); felix@1545: final ListGridField removeField = new ListGridField("remove", "remove"); felix@1545: listGrid.setFields(new ListGridField[] {xField, yField, removeField}); felix@1545: felix@1545: // Find the artifacts uuid. felix@1545: findManualPointsUUID(); felix@1545: CollectionItem item = collection.getItem(uuid); felix@1545: felix@1545: // Add points to grid. felix@1545: if (item != null) { felix@1545: String jsonData = item.getData().get(POINT_DATA); felix@1545: JSONArray jsonArray = (JSONArray) JSONParser.parse(jsonData); felix@1545: for (int i = 0; i < jsonArray.size(); i++) { felix@1545: JSONArray point = (JSONArray) jsonArray.get(i); felix@1545: listGrid.addData(pointRecordFromJSON(point)); felix@1545: } felix@1545: } felix@1545: else { felix@1545: System.out.println("No item found for " + uuid); felix@1545: } felix@1545: felix@1545: layout.addMember(listGrid); felix@1545: felix@1545: addItem(layout); felix@1545: IButton button = new IButton("Edit New"); felix@1545: button.setTop(250); felix@1545: button.addClickHandler(new ClickHandler() { felix@1545: public void onClick(ClickEvent event) { felix@1545: listGrid.startEditingNew(); felix@1545: } felix@1545: }); felix@1545: addItem(button); felix@1545: addItem(buttons); felix@1545: setWidth(380); felix@1545: setHeight(470); felix@1545: centerInPage(); felix@1545: } felix@1545: felix@1545: felix@1545: /** From a JSON-encoded point, create a PointRecord. */ felix@1545: public PointRecord pointRecordFromJSON(JSONArray jsonArray) { felix@1545: JSONNumber x = (JSONNumber) jsonArray.get(0); felix@1545: JSONNumber y = (JSONNumber) jsonArray.get(1); felix@1545: return new PointRecord(x.doubleValue(), y.doubleValue()); felix@1545: } felix@1545: felix@1545: felix@1545: /** Add a ManualPointArtifact to Collection. */ felix@1545: public void addArtifactCreateUI() { felix@1545: // TODO MSG:/i18n felix@1545: final Label standByLabel = new Label("Creating artifact, these are not the droids"); felix@1545: addItem(standByLabel); felix@1545: felix@1545: setWidth(380); felix@1545: setHeight(470); felix@1545: centerInPage(); felix@1545: felix@1545: Config config = Config.getInstance(); felix@1545: String locale = config.getLocale(); felix@1545: felix@1545: loadArtifactService.load( felix@1545: this.collection, felix@1545: new Recommendation("manualpoints", ""), felix@1545: "manualpoints", felix@1545: locale, felix@1545: new AsyncCallback() { felix@1545: public void onFailure(Throwable caught) { felix@1545: GWT.log("Creating manualpoint artifact failed!"); felix@1545: } felix@1545: public void onSuccess(Artifact artifact) { felix@1545: GWT.log("Successfully created artifact."); felix@1545: removeItem(standByLabel); felix@1545: uuid = artifact.getUuid(); felix@1545: createUI(); felix@1545: } felix@1545: }); felix@1545: } felix@1545: felix@1545: felix@1545: /** felix@1545: * This method is called when the user aborts point editing. felix@1545: * @param event The event. felix@1545: */ felix@1545: public void onClick(ClickEvent event) { felix@1545: this.destroy(); felix@1545: } felix@1545: felix@1545: felix@1545: /** Simple record to store points. */ felix@1545: public class PointRecord extends ListGridRecord { felix@1545: protected static final String ATTRIBUTE_X = "X"; felix@1545: protected static final String ATTRIBUTE_Y = "Y"; felix@1545: felix@1545: double x; felix@1545: double y; felix@1545: felix@1545: private PointRecord() {;} felix@1545: felix@1545: public PointRecord(double x, double y) { felix@1545: setX(x); felix@1545: setY(y); felix@1545: } felix@1545: felix@1545: public void setX(double x) { felix@1545: this.x = x; felix@1545: setAttribute(ATTRIBUTE_X, getX()); felix@1545: } felix@1545: felix@1545: public void setY(double y) { felix@1545: this.y = y; felix@1545: setAttribute(ATTRIBUTE_Y, getY()); felix@1545: } felix@1545: felix@1545: public double getX() { felix@1545: return this.x; felix@1545: } felix@1545: felix@1545: public double getY() { felix@1545: return this.y; felix@1545: } felix@1545: } felix@1545: felix@1545: felix@1545: // TODO cleanup. We need code similar to the following. felix@1545: felix@1545: /* felix@1545: protected void updateCollection() { felix@1545: final Config config = Config.getInstance(); felix@1545: final String loc = config.getLocale(); felix@1545: felix@1545: GWT.log("PropertiesEditor.updateCollection via RPC now"); felix@1545: felix@1545: Settings s = settings; felix@1545: collection.addSettings(this.tab.getOutputName(), s); felix@1545: updater.update(collection, loc, new AsyncCallback() { felix@1545: public void onFailure(Throwable caught) { felix@1545: GWT.log("Could not update collection attributes."); felix@1545: SC.warn(MSG.getString(caught.getMessage())); felix@1545: } felix@1545: public void onSuccess(Collection collection) { felix@1545: updateChartTab(); felix@1545: } felix@1545: }); felix@1545: } felix@1545: felix@1545: /* felix@1545: protected void updateChartTab() { felix@1545: this.tab.updateChartInfo(); felix@1545: this.tab.updateChartPanel(); felix@1545: this.destroy(); felix@1545: } felix@1545: */ felix@1545: felix@1545: protected boolean isDialogValid() { felix@1545: boolean valid = true; felix@1545: /* felix@1545: for (int i = 0; i < tabs.getNumTabs(); i++) { felix@1545: Tab t = tabs.getTab(i); felix@1545: Canvas container = t.getPane(); felix@1545: Canvas[] children = container.getChildren(); felix@1545: for (Canvas c: children) { felix@1545: valid = validateCanvas(c); felix@1545: if(!valid) { felix@1545: return valid; felix@1545: } felix@1545: } felix@1545: } felix@1545: */ felix@1545: return valid; felix@1545: } felix@1545: felix@1545: felix@1545: protected boolean validateCanvas(Canvas c) { felix@1545: boolean valid = true; felix@1545: if(c instanceof DynamicForm) { felix@1545: DynamicForm f = (DynamicForm) c; felix@1545: return !f.hasErrors(); felix@1545: } felix@1545: else if(c.getChildren().length > 0) { felix@1545: for (Canvas child: c.getChildren()) { felix@1545: valid = validateCanvas(child); felix@1545: if(!valid) { felix@1545: return valid; felix@1545: } felix@1545: } felix@1545: } felix@1545: return valid; felix@1545: } felix@1545: } felix@1545: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :