Mercurial > dive4elements > river
comparison gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/ManualPointsEditor.java @ 5838:5aa05a7a34b7
Rename modules to more fitting names.
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Thu, 25 Apr 2013 15:23:37 +0200 |
parents | flys-client/src/main/java/org/dive4elements/river/client/client/ui/chart/ManualPointsEditor.java@821a02bbfb4e |
children | 172338b1407f |
comparison
equal
deleted
inserted
replaced
5837:d9901a08d0a6 | 5838:5aa05a7a34b7 |
---|---|
1 package org.dive4elements.river.client.client.ui.chart; | |
2 | |
3 import com.google.gwt.core.client.GWT; | |
4 import com.google.gwt.i18n.client.DateTimeFormat; | |
5 import com.google.gwt.i18n.client.NumberFormat; | |
6 import com.google.gwt.json.client.JSONArray; | |
7 import com.google.gwt.json.client.JSONBoolean; | |
8 import com.google.gwt.json.client.JSONNumber; | |
9 import com.google.gwt.json.client.JSONParser; | |
10 import com.google.gwt.json.client.JSONString; | |
11 import com.google.gwt.user.client.rpc.AsyncCallback; | |
12 | |
13 import com.smartgwt.client.types.Alignment; | |
14 import com.smartgwt.client.types.ListGridFieldType; | |
15 import com.smartgwt.client.util.SC; | |
16 import com.smartgwt.client.widgets.Button; | |
17 import com.smartgwt.client.widgets.IButton; | |
18 import com.smartgwt.client.widgets.Label; | |
19 import com.smartgwt.client.widgets.Window; | |
20 import com.smartgwt.client.widgets.events.ClickEvent; | |
21 import com.smartgwt.client.widgets.events.ClickHandler; | |
22 import com.smartgwt.client.widgets.grid.CellEditValueFormatter; | |
23 import com.smartgwt.client.widgets.grid.CellEditValueParser; | |
24 import com.smartgwt.client.widgets.grid.CellFormatter; | |
25 import com.smartgwt.client.widgets.grid.ListGrid; | |
26 import com.smartgwt.client.widgets.grid.ListGridField; | |
27 import com.smartgwt.client.widgets.grid.ListGridRecord; | |
28 import com.smartgwt.client.widgets.grid.events.RecordClickEvent; | |
29 import com.smartgwt.client.widgets.grid.events.RecordClickHandler; | |
30 import com.smartgwt.client.widgets.layout.HLayout; | |
31 import com.smartgwt.client.widgets.layout.VLayout; | |
32 | |
33 import org.dive4elements.river.client.client.Config; | |
34 import org.dive4elements.river.client.client.FLYSConstants; | |
35 import org.dive4elements.river.client.client.event.RedrawRequestEvent; | |
36 import org.dive4elements.river.client.client.event.RedrawRequestHandler; | |
37 import org.dive4elements.river.client.client.services.FeedServiceAsync; | |
38 import org.dive4elements.river.client.client.services.LoadArtifactServiceAsync; | |
39 import org.dive4elements.river.client.shared.model.Artifact; | |
40 import org.dive4elements.river.client.shared.model.Collection; | |
41 import org.dive4elements.river.client.shared.model.CollectionItem; | |
42 import org.dive4elements.river.client.shared.model.Data; | |
43 import org.dive4elements.river.client.shared.model.DefaultArtifact; | |
44 import org.dive4elements.river.client.shared.model.DefaultData; | |
45 import org.dive4elements.river.client.shared.model.Property; | |
46 import org.dive4elements.river.client.shared.model.PropertyGroup; | |
47 import org.dive4elements.river.client.shared.model.Recommendation; | |
48 import org.dive4elements.river.client.shared.model.Settings; | |
49 import org.dive4elements.river.client.shared.model.StringProperty; | |
50 | |
51 import java.util.Date; | |
52 import java.util.List; | |
53 | |
54 | |
55 /** | |
56 * UI to enter point data and save it to an PointArtifact. | |
57 */ | |
58 public class ManualPointsEditor | |
59 extends Window | |
60 implements ClickHandler | |
61 { | |
62 /** The interface that provides i18n messages. */ | |
63 protected FLYSConstants MSG = GWT.create(FLYSConstants.class); | |
64 | |
65 /** Part of name of the main data item to be fed. */ | |
66 public static final String POINT_DATA = "manualpoints.data"; | |
67 | |
68 /** When we chaged something, we need a RedrawRequest(Handler). */ | |
69 protected RedrawRequestHandler redrawRequestHandler; | |
70 | |
71 /** The collection */ | |
72 protected Collection collection; | |
73 | |
74 /** The listGrid showing point entries. */ | |
75 protected ListGrid listGrid; | |
76 | |
77 protected ListGridFieldType fieldTypeX = ListGridFieldType.FLOAT; | |
78 | |
79 /** Service handle to clone and add artifacts to collection. */ | |
80 LoadArtifactServiceAsync loadArtifactService = GWT.create( | |
81 org.dive4elements.river.client.client.services.LoadArtifactService.class); | |
82 | |
83 /** Service to feed the artifact with new point-data. */ | |
84 FeedServiceAsync feedService = GWT.create( | |
85 org.dive4elements.river.client.client.services.FeedService.class); | |
86 | |
87 /** UUID of artifact to feed. */ | |
88 protected String uuid; | |
89 | |
90 /** Name of the outputmode, important when feeding data. */ | |
91 protected String outputModeName; | |
92 | |
93 /** Name of the point data item. */ | |
94 protected String pointDataItemName; | |
95 | |
96 | |
97 /** | |
98 * Setup editor dialog. | |
99 * @param collection The collection to use. | |
100 */ | |
101 public ManualPointsEditor(Collection collection, | |
102 RedrawRequestHandler handler, String outputModeName | |
103 ) { | |
104 this.collection = collection; | |
105 this.redrawRequestHandler = handler; | |
106 this.outputModeName = outputModeName; | |
107 this.pointDataItemName = outputModeName + "." + POINT_DATA; | |
108 init(); | |
109 } | |
110 | |
111 | |
112 /** Searches collection for first artifact to serve (manual) point data. */ | |
113 public String findManualPointsUUID() { | |
114 // TODO Need to be more picky (different points in different diagrams) | |
115 int size = collection.getItemLength(); | |
116 | |
117 for (int i = 0; i < size; i++) { | |
118 CollectionItem item = collection.getItem(i); | |
119 String dataValue = item.getData().get(pointDataItemName); | |
120 if (dataValue != null) { | |
121 // Found it. | |
122 uuid = item.identifier(); | |
123 return uuid; | |
124 } | |
125 } | |
126 | |
127 return null; | |
128 } | |
129 | |
130 | |
131 /** | |
132 * Initialize the editor window and its components. | |
133 */ | |
134 protected void init() { | |
135 setTitle(MSG.addpoints()); | |
136 setCanDragReposition(true); | |
137 setCanDragResize(true); | |
138 | |
139 // If no manualpoints artifact found, create it now. | |
140 if(findManualPointsUUID() == null) { | |
141 addArtifactCreateUI(); | |
142 } | |
143 else { | |
144 createUI(); | |
145 } | |
146 } | |
147 | |
148 | |
149 /** Create and setup/add the ui. */ | |
150 public void createUI() { | |
151 Button accept = new Button(MSG.label_ok()); | |
152 Button cancel = new Button(MSG.label_cancel()); | |
153 cancel.addClickHandler(this); | |
154 | |
155 accept.addClickHandler(new ClickHandler() { | |
156 @Override | |
157 public void onClick(ClickEvent e) { | |
158 okClicked(); | |
159 } | |
160 }); | |
161 | |
162 HLayout buttons = new HLayout(); | |
163 buttons.addMember(accept); | |
164 buttons.addMember(cancel); | |
165 buttons.setAlign(Alignment.CENTER); | |
166 buttons.setHeight(30); | |
167 | |
168 VLayout layout = new VLayout(); | |
169 listGrid = new ListGrid(); | |
170 listGrid.setWidth100(); | |
171 listGrid.setHeight("*"); | |
172 listGrid.setCanSort(false); | |
173 listGrid.setCanEdit(true); | |
174 listGrid.setShowHeaderContextMenu(false); | |
175 | |
176 // Use X and Y as default fallback. | |
177 String xAxis = "X"; | |
178 String yAxis = "Y"; | |
179 | |
180 // Get header text from collection settings | |
181 Settings settings = this.collection.getSettings(outputModeName); | |
182 List<Property> axes = settings.getSettings("axes"); | |
183 if(axes != null) { | |
184 for (Property p: axes) { | |
185 PropertyGroup pg = (PropertyGroup)p; | |
186 GWT.log(pg.toString()); | |
187 StringProperty id = | |
188 (StringProperty)pg.getPropertyByName("id"); | |
189 if(id.getValue().equals("X")) { | |
190 StringProperty name = | |
191 (StringProperty)pg.getPropertyByName("label"); | |
192 xAxis = name.getValue(); | |
193 } | |
194 else if (yAxis.equals("Y")) { | |
195 StringProperty name = | |
196 (StringProperty)pg.getPropertyByName("label"); | |
197 yAxis = name.getValue(); | |
198 } | |
199 } | |
200 } | |
201 | |
202 CellFormatter format = createCellFormatter(); | |
203 CellEditValueParser cevp = createCellEditValueParser(); | |
204 CellEditValueFormatter cevf = createCellEditValueFormatter(); | |
205 | |
206 ListGridField xField = | |
207 new ListGridField(PointRecord.ATTRIBUTE_X, xAxis); | |
208 if(xAxis.equalsIgnoreCase("date") || xAxis.equalsIgnoreCase("Datum")) { | |
209 // FIXME: This is a hack for Timeseries charts with Date types on the x axis | |
210 xField.setType(ListGridFieldType.DATE); | |
211 this.fieldTypeX = ListGridFieldType.DATE; | |
212 } | |
213 else { | |
214 xField.setType(ListGridFieldType.FLOAT); | |
215 xField.setCellFormatter(format); | |
216 xField.setEditValueParser(cevp); | |
217 xField.setEditValueFormatter(cevf); | |
218 } | |
219 | |
220 ListGridField yField = | |
221 new ListGridField(PointRecord.ATTRIBUTE_Y, yAxis); | |
222 yField.setType(ListGridFieldType.FLOAT); | |
223 yField.setCellFormatter(format); | |
224 yField.setEditValueParser(cevp); | |
225 yField.setEditValueFormatter(cevf); | |
226 | |
227 ListGridField nameField = new ListGridField(PointRecord.ATTRIBUTE_NAME, | |
228 MSG.pointname()); | |
229 final ListGridField removeField = | |
230 new ListGridField("_removeRecord", MSG.removepoint()){{ | |
231 setType(ListGridFieldType.ICON); | |
232 setIcon(GWT.getHostPageBaseURL() + MSG.removeFeature()); | |
233 setCanEdit(false); | |
234 setCanFilter(false); | |
235 setCanSort(false); | |
236 setCanGroupBy(false); | |
237 setCanFreeze(false); | |
238 setWidth(25); | |
239 }}; | |
240 | |
241 ListGridField activeField = new ListGridField( | |
242 PointRecord.ATTRIBUTE_ACTIVE, MSG.selection()); | |
243 activeField.setType(ListGridFieldType.BOOLEAN); | |
244 activeField.setDefaultValue(true); | |
245 | |
246 listGrid.setFields(new ListGridField[] {activeField, xField, yField, | |
247 nameField, removeField}); | |
248 | |
249 listGrid.addRecordClickHandler(new RecordClickHandler() { | |
250 @Override | |
251 public void onRecordClick(final RecordClickEvent event) { | |
252 // Just handle remove-clicks | |
253 if(!event.getField().getName().equals(removeField.getName())) { | |
254 return; | |
255 } | |
256 event.getViewer().removeData(event.getRecord()); | |
257 } | |
258 }); | |
259 | |
260 // Find the artifacts uuid | |
261 findManualPointsUUID(); | |
262 CollectionItem item = collection.getItem(uuid); | |
263 | |
264 // Add points to grid | |
265 if (item != null) { | |
266 // TODO store this from findPointUUID instead (we touched these). | |
267 String jsonData = item.getData().get(pointDataItemName); | |
268 JSONArray jsonArray = (JSONArray) JSONParser.parse(jsonData); | |
269 for (int i = 0; i < jsonArray.size(); i++) { | |
270 JSONArray point = (JSONArray) jsonArray.get(i); | |
271 listGrid.addData(PointRecord.fromJSON(point)); | |
272 } | |
273 } | |
274 else { | |
275 GWT.log("ManualPointsEditor: No item found for " + uuid); | |
276 } | |
277 | |
278 IButton button = new IButton(MSG.newpoint()); | |
279 button.setTop(250); | |
280 button.addClickHandler(new ClickHandler() { | |
281 @Override | |
282 public void onClick(ClickEvent event) { | |
283 listGrid.startEditingNew(); | |
284 } | |
285 }); | |
286 | |
287 layout.addMember(listGrid); | |
288 layout.addMember(button); | |
289 | |
290 addItem(layout); | |
291 | |
292 addItem(buttons); | |
293 setWidth(380); | |
294 setHeight(470); | |
295 centerInPage(); | |
296 } | |
297 | |
298 | |
299 protected CellFormatter createCellFormatter() { | |
300 return new CellFormatter() { | |
301 @Override | |
302 public String format(Object value, ListGridRecord record, int rowNum, int colNum) { | |
303 if(value != null) { | |
304 NumberFormat nf = NumberFormat.getDecimalFormat(); | |
305 try { | |
306 double d = Double.valueOf(value.toString()).doubleValue(); | |
307 return nf.format(d); | |
308 } catch (Exception e) { | |
309 return value.toString(); | |
310 } | |
311 } else { | |
312 return null; | |
313 } | |
314 }}; | |
315 } | |
316 | |
317 | |
318 protected CellEditValueParser createCellEditValueParser() { | |
319 return new CellEditValueParser() { | |
320 @Override | |
321 public Object parse(Object value, ListGridRecord record, int rowNum, int colNum) { | |
322 if (value == null) | |
323 return null; | |
324 try { | |
325 NumberFormat nf = NumberFormat.getDecimalFormat(); | |
326 double d = nf.parse(value.toString()); | |
327 return (new Double(d)).toString(); | |
328 } | |
329 catch(NumberFormatException nfe) { | |
330 return value; | |
331 } | |
332 } | |
333 }; | |
334 } | |
335 | |
336 | |
337 protected CellEditValueFormatter createCellEditValueFormatter() { | |
338 return new CellEditValueFormatter() { | |
339 @Override | |
340 public Object format(Object value, ListGridRecord record, int rowNum, int colNum) { | |
341 if (value == null) { | |
342 return ""; | |
343 } | |
344 NumberFormat nf = NumberFormat.getDecimalFormat(); | |
345 try { | |
346 double d = Double.valueOf(value.toString()).doubleValue(); | |
347 return nf.format(d); | |
348 } | |
349 catch(NumberFormatException nfe) { | |
350 return value; | |
351 } | |
352 } | |
353 }; | |
354 } | |
355 | |
356 protected String getLocaleDateFormat() { | |
357 String loc = Config.getInstance().getLocale(); | |
358 if ("de".equals(loc)) { | |
359 return "yy.MM.yyyy"; | |
360 } | |
361 else { | |
362 return "MM/dd/yyyy"; | |
363 } | |
364 } | |
365 | |
366 protected String formatDate(Date date) { | |
367 DateTimeFormat dtf = DateTimeFormat.getFormat(getLocaleDateFormat()); | |
368 return dtf.format(date); | |
369 } | |
370 | |
371 /** Create JSON representation of the points present in the list grid. */ | |
372 protected JSONArray jsonArrayFromListGrid() { | |
373 JSONArray list = new JSONArray(); | |
374 int idx = 0; | |
375 | |
376 for(ListGridRecord record : listGrid.getRecords()) { | |
377 if (record instanceof PointRecord) { | |
378 JSONArray data = new JSONArray(); | |
379 | |
380 PointRecord point = (PointRecord) record; | |
381 if(point.isTimeseriesPoint()) { | |
382 data.set(0, new JSONString(point.getXAsDate())); | |
383 GWT.log("Date: " + point.getXAsDate()); | |
384 } | |
385 else { | |
386 data.set(0, new JSONNumber(point.getX())); | |
387 } | |
388 data.set(1, new JSONNumber(point.getY())); | |
389 data.set(2, new JSONString(point.getName())); | |
390 data.set(3, JSONBoolean.getInstance(point.isActive())); | |
391 | |
392 list.set(idx, data); | |
393 idx++; | |
394 } | |
395 else { | |
396 JSONArray data = new JSONArray(); | |
397 | |
398 String nameString = record.getAttributeAsString(PointRecord.ATTRIBUTE_NAME); | |
399 // Apply default name if none set. | |
400 if (nameString == null || nameString.equals("")) { | |
401 String xString = record.getAttributeAsString( | |
402 PointRecord.ATTRIBUTE_X); | |
403 String yString = record.getAttributeAsString( | |
404 PointRecord.ATTRIBUTE_Y); | |
405 nameString = xString + "/" + yString; | |
406 } | |
407 | |
408 if(fieldTypeX.equals(ListGridFieldType.DATE)) { | |
409 Date date = record.getAttributeAsDate(PointRecord.ATTRIBUTE_X); | |
410 data.set(0, new JSONString(formatDate(date))); | |
411 GWT.log("Date: " + formatDate(date)); | |
412 } | |
413 else { | |
414 data.set(0, new JSONNumber(record. | |
415 getAttributeAsDouble(PointRecord.ATTRIBUTE_X))); | |
416 } | |
417 data.set(1, new JSONNumber(record. | |
418 getAttributeAsDouble(PointRecord.ATTRIBUTE_Y))); | |
419 data.set(2, new JSONString(nameString)); | |
420 data.set(3, JSONBoolean.getInstance(record.getAttributeAsBoolean( | |
421 PointRecord.ATTRIBUTE_ACTIVE))); | |
422 | |
423 list.set(idx, data); | |
424 idx++; | |
425 } | |
426 } | |
427 return list; | |
428 } | |
429 | |
430 | |
431 /** | |
432 * Called when OK Button was clicked. Then, if entered values are valid, | |
433 * fire a RedrawRequest and destroy. | |
434 */ | |
435 protected void okClicked() { | |
436 if(isDialogValid()) { | |
437 // Feed JSON-encoded content of listgrid. | |
438 JSONArray list = jsonArrayFromListGrid(); | |
439 | |
440 Data[] feedData = new Data[] { | |
441 DefaultData.createSimpleStringData(pointDataItemName, | |
442 list.toString()) | |
443 }; | |
444 | |
445 feedService.feed( | |
446 Config.getInstance().getLocale(), | |
447 new DefaultArtifact(uuid, "TODO:hash"), | |
448 feedData, | |
449 new AsyncCallback<Artifact>() { | |
450 @Override | |
451 public void onFailure(Throwable caught) { | |
452 GWT.log("Could not feed artifact with points."); | |
453 SC.warn(MSG.getString(caught.getMessage())); | |
454 enable(); | |
455 } | |
456 @Override | |
457 public void onSuccess(Artifact fartifact) { | |
458 GWT.log("Successfully set points"); | |
459 redrawRequestHandler.onRedrawRequest( | |
460 new RedrawRequestEvent()); | |
461 destroy(); | |
462 } | |
463 }); | |
464 } | |
465 else { | |
466 GWT.log("Dialog not valid"); | |
467 SC.warn(MSG.error_dialog_not_valid()); | |
468 } | |
469 } | |
470 | |
471 | |
472 /** Add a ManualPointArtifact to Collection. */ | |
473 public void addArtifactCreateUI() { | |
474 final Label standByLabel = new Label(MSG.standby()); | |
475 addItem(standByLabel); | |
476 | |
477 setWidth(380); | |
478 setHeight(470); | |
479 centerInPage(); | |
480 | |
481 Config config = Config.getInstance(); | |
482 String locale = config.getLocale(); | |
483 | |
484 loadArtifactService.load( | |
485 this.collection, | |
486 new Recommendation("manualpoints", ""), | |
487 "manualpoints", | |
488 locale, | |
489 new AsyncCallback<Artifact>() { | |
490 @Override | |
491 public void onFailure(Throwable caught) { | |
492 GWT.log("Creating manualpoint artifact failed!"); | |
493 } | |
494 @Override | |
495 public void onSuccess(Artifact artifact) { | |
496 GWT.log("Successfully created artifact."); | |
497 removeItem(standByLabel); | |
498 uuid = artifact.getUuid(); | |
499 createUI(); | |
500 } | |
501 }); | |
502 } | |
503 | |
504 | |
505 /** | |
506 * This method is called when the user aborts point editing. | |
507 * @param event The event. | |
508 */ | |
509 @Override | |
510 public void onClick(ClickEvent event) { | |
511 this.destroy(); | |
512 } | |
513 | |
514 | |
515 /** Return false if x or y attribute is missing. */ | |
516 protected boolean isDialogValid() { | |
517 boolean valid = true; | |
518 for (ListGridRecord record : listGrid.getRecords()) { | |
519 try { | |
520 if (record.getAttribute(PointRecord.ATTRIBUTE_X) == null | |
521 || record.getAttribute(PointRecord.ATTRIBUTE_Y) == null) { | |
522 return false; | |
523 } | |
524 } | |
525 catch(IllegalArgumentException ex) { | |
526 | |
527 } | |
528 } | |
529 if (listGrid.hasErrors()) { | |
530 valid = false; | |
531 } | |
532 return valid; | |
533 } | |
534 } | |
535 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |