Mercurial > dive4elements > river
comparison flys-client/src/main/java/org/dive4elements/river/client/client/ui/DatacageWidget.java @ 5834:f507086aa94b
Repaired internal references.
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Thu, 25 Apr 2013 12:31:32 +0200 |
parents | flys-client/src/main/java/de/intevation/flys/client/client/ui/DatacageWidget.java@6958479ec92d |
children | 821a02bbfb4e |
comparison
equal
deleted
inserted
replaced
5833:a2bdc0f524e8 | 5834:f507086aa94b |
---|---|
1 package de.intevation.flys.client.client.ui; | |
2 | |
3 import com.google.gwt.core.client.GWT; | |
4 import com.google.gwt.user.client.rpc.AsyncCallback; | |
5 | |
6 import com.smartgwt.client.types.SelectionStyle; | |
7 import com.smartgwt.client.types.TreeModelType; | |
8 import com.smartgwt.client.util.SC; | |
9 import com.smartgwt.client.widgets.Button; | |
10 import com.smartgwt.client.widgets.events.ClickEvent; | |
11 import com.smartgwt.client.widgets.events.ClickHandler; | |
12 import com.smartgwt.client.widgets.grid.HoverCustomizer; | |
13 import com.smartgwt.client.widgets.grid.ListGridRecord; | |
14 import com.smartgwt.client.widgets.grid.events.RecordDoubleClickEvent; | |
15 import com.smartgwt.client.widgets.grid.events.RecordDoubleClickHandler; | |
16 import com.smartgwt.client.widgets.layout.VLayout; | |
17 import com.smartgwt.client.widgets.tree.Tree; | |
18 import com.smartgwt.client.widgets.tree.TreeGrid; | |
19 import com.smartgwt.client.widgets.tree.TreeNode; | |
20 | |
21 import de.intevation.flys.client.client.Config; | |
22 import de.intevation.flys.client.client.FLYSConstants; | |
23 import de.intevation.flys.client.client.event.DatacageDoubleClickHandler; | |
24 import de.intevation.flys.client.client.event.DatacageHandler; | |
25 import de.intevation.flys.client.client.services.MetaDataService; | |
26 import de.intevation.flys.client.client.services.MetaDataServiceAsync; | |
27 import de.intevation.flys.client.client.ui.ScreenLock; | |
28 import de.intevation.flys.client.shared.model.Artifact; | |
29 import de.intevation.flys.client.shared.model.AttrList; | |
30 import de.intevation.flys.client.shared.model.DataCageNode; | |
31 import de.intevation.flys.client.shared.model.DataCageTree; | |
32 import de.intevation.flys.client.shared.model.ToLoad; | |
33 import de.intevation.flys.client.shared.model.User; | |
34 | |
35 import java.util.ArrayList; | |
36 import java.util.List; | |
37 import java.util.MissingResourceException; | |
38 import java.util.Stack; | |
39 | |
40 // TODO: refactor, extract ~DataCageGrid | |
41 /** | |
42 * Display tree of, for example, previous calculations and allows | |
43 * selection in order to access/clone these. | |
44 */ | |
45 public class DatacageWidget | |
46 extends VLayout | |
47 { | |
48 public static final int MAX_OPEN = 30; | |
49 | |
50 protected MetaDataServiceAsync metaDataService = | |
51 GWT.create(MetaDataService.class); | |
52 | |
53 protected FLYSConstants messages = | |
54 GWT.create(FLYSConstants.class); | |
55 | |
56 protected Artifact artifact; | |
57 protected User user; | |
58 protected String outs; | |
59 protected String parameters; | |
60 | |
61 protected TreeGrid treeGrid; | |
62 protected Tree tree; | |
63 | |
64 protected ToLoad toLoad; | |
65 | |
66 protected List<DatacageHandler> handlers; | |
67 protected List<DatacageDoubleClickHandler> doubleHandlers; | |
68 | |
69 /** Layout to show spinning wheel of joy. */ | |
70 protected VLayout lockScreen; | |
71 | |
72 | |
73 public DatacageWidget() { | |
74 handlers = new ArrayList<DatacageHandler>(); | |
75 doubleHandlers = new ArrayList<DatacageDoubleClickHandler>(); | |
76 } | |
77 | |
78 | |
79 public DatacageWidget(Artifact artifact, User user) { | |
80 this(artifact, user, null); | |
81 } | |
82 | |
83 public DatacageWidget(Artifact artifact, User user, String outs) { | |
84 this(artifact, user, outs, true); | |
85 } | |
86 | |
87 public DatacageWidget( | |
88 Artifact artifact, | |
89 User user, | |
90 String outs, | |
91 boolean showButton | |
92 ) { | |
93 this(artifact, user, outs, null, showButton); | |
94 } | |
95 | |
96 | |
97 public DatacageWidget( | |
98 Artifact artifact, | |
99 User user, | |
100 String outs, | |
101 String parameters, | |
102 boolean showButton | |
103 ) { | |
104 this(); | |
105 | |
106 this.artifact = artifact; | |
107 this.user = user; | |
108 this.outs = outs; | |
109 this.parameters = parameters; | |
110 | |
111 toLoad = new ToLoad(); | |
112 | |
113 setWidth100(); | |
114 | |
115 tree = new Tree(); | |
116 tree.setModelType(TreeModelType.CHILDREN); | |
117 tree.setNameProperty("name"); | |
118 tree.setIdField("id"); | |
119 tree.setChildrenProperty("children-nodes"); | |
120 tree.setShowRoot(false); | |
121 | |
122 treeGrid = new TreeGrid(); | |
123 treeGrid.setLoadDataOnDemand(false); | |
124 treeGrid.setWidth100(); | |
125 treeGrid.setHeight100(); | |
126 treeGrid.setShowRoot(false); | |
127 treeGrid.setNodeIcon("[SKIN]/../blank.gif"); | |
128 treeGrid.setShowConnectors(true); | |
129 treeGrid.setLoadingMessage(messages.databasket_loading()); | |
130 treeGrid.setEmptyMessage(messages.databasket_loading()); | |
131 treeGrid.setLoadingDataMessage(messages.databasket_loading()); | |
132 | |
133 treeGrid.setHoverMoveWithMouse(true); | |
134 treeGrid.setCanHover(true); | |
135 treeGrid.setShowHover(true); | |
136 treeGrid.setHoverOpacity(75); | |
137 treeGrid.setHoverWidth(120); | |
138 | |
139 treeGrid.setHoverCustomizer(new HoverCustomizer() { | |
140 @Override | |
141 public String hoverHTML(Object value, | |
142 ListGridRecord record, | |
143 int rowNum, | |
144 int colNum | |
145 ) { | |
146 if(record instanceof TreeNode) { | |
147 TreeNode hoveredTreeNode = (TreeNode)record; | |
148 String info = hoveredTreeNode.getAttribute("info"); | |
149 if (info == null) { | |
150 info = hoveredTreeNode.getName(); | |
151 } | |
152 return info; | |
153 } | |
154 else { | |
155 return "";// should not happen | |
156 } | |
157 } | |
158 }); | |
159 | |
160 treeGrid.addRecordDoubleClickHandler(new RecordDoubleClickHandler() { | |
161 @Override | |
162 public void onRecordDoubleClick(RecordDoubleClickEvent event) { | |
163 doubleClickedOnTree(event); | |
164 } | |
165 }); | |
166 | |
167 addMember(treeGrid); | |
168 | |
169 if (showButton) { | |
170 addMember(createPlusButton()); | |
171 } | |
172 | |
173 triggerTreeBuilding(); | |
174 } | |
175 | |
176 public void lockUI() { | |
177 lockScreen = ScreenLock.lockUI(this, lockScreen); | |
178 } | |
179 | |
180 /** Enable input, remove grey, remove spinning wheel of joy. */ | |
181 public void unlockUI() { | |
182 ScreenLock.unlockUI(this, lockScreen); | |
183 } | |
184 | |
185 /** | |
186 * @param handler Handler to be added (notified on add-action). | |
187 */ | |
188 public DatacageWidget(Artifact artifact, User user, String outs, | |
189 DatacageHandler handler) { | |
190 this(artifact, user, outs); | |
191 this.addDatacageHandler(handler); | |
192 } | |
193 | |
194 | |
195 public DatacageWidget( | |
196 Artifact artifact, | |
197 User user, | |
198 String outs, | |
199 DatacageHandler handler, | |
200 String parameters | |
201 ) { | |
202 this(artifact, user, outs, handler); | |
203 this.parameters = parameters; | |
204 } | |
205 | |
206 | |
207 /** | |
208 * Sets whether more than one item can be selected. | |
209 * @param multi if true, allow mutliple selections. | |
210 */ | |
211 public void setIsMutliSelectable(boolean multi) { | |
212 if (multi) { | |
213 treeGrid.setSelectionType(SelectionStyle.MULTIPLE); | |
214 } | |
215 else { | |
216 treeGrid.setSelectionType(SelectionStyle.SINGLE); | |
217 } | |
218 } | |
219 | |
220 | |
221 /** | |
222 * @param handler Handler to be added (notified on add-action). | |
223 */ | |
224 public void addDatacageHandler(DatacageHandler handler) { | |
225 if (!handlers.contains(handler)) { | |
226 handlers.add(handler); | |
227 } | |
228 } | |
229 | |
230 | |
231 /** | |
232 * @param h Handler to be added (notified on Double click on node). | |
233 */ | |
234 public void addDatacageDoubleClickHandler(DatacageDoubleClickHandler h) { | |
235 if (!doubleHandlers.contains(h)) { | |
236 doubleHandlers.add(h); | |
237 } | |
238 } | |
239 | |
240 | |
241 /** | |
242 * @param handler Handler to remove from list. | |
243 */ | |
244 public void removeDatacageHandler(DatacageHandler handler) { | |
245 handlers.remove(handler); | |
246 } | |
247 | |
248 | |
249 public ToLoad getToLoad() { | |
250 return toLoad; | |
251 } | |
252 | |
253 | |
254 public ToLoad getSelection() { | |
255 // Reset content of toLoads. | |
256 toLoad = new ToLoad(); | |
257 | |
258 if (treeGrid == null) { | |
259 return toLoad; | |
260 } | |
261 | |
262 ListGridRecord [] selection = treeGrid.getSelectedRecords(); | |
263 | |
264 if (selection != null) { | |
265 for (ListGridRecord record: selection) { | |
266 if (record instanceof TreeNode) { | |
267 collectToLoads((TreeNode)record); | |
268 } | |
269 } | |
270 } | |
271 | |
272 return toLoad; | |
273 } | |
274 | |
275 | |
276 /** | |
277 * Returns the titles of selected items (if any). | |
278 */ | |
279 public String[] getSelectionTitles() { | |
280 if (treeGrid == null) { | |
281 return new String[] {}; | |
282 } | |
283 | |
284 ListGridRecord [] selection = treeGrid.getSelectedRecords(); | |
285 | |
286 if (selection == null) { | |
287 return new String[] {}; | |
288 } | |
289 | |
290 List<String> titleList = new ArrayList<String>(); | |
291 for (ListGridRecord record: selection) { | |
292 if (record instanceof TreeNode) { | |
293 titleList.add(((TreeNode)record).getAttribute("name")); | |
294 } | |
295 } | |
296 | |
297 return titleList.toArray(new String[titleList.size()]); | |
298 } | |
299 | |
300 | |
301 /** | |
302 * Callback for add-button. | |
303 * Fires to load for every selected element and handler. | |
304 */ | |
305 public void plusClicked() { | |
306 if (!getSelection().isEmpty()) { | |
307 fireToLoad(); | |
308 } | |
309 } | |
310 | |
311 | |
312 protected Button createPlusButton() { | |
313 Button plusBtn = new Button(messages.datacageAdd()); | |
314 plusBtn.addClickHandler(new ClickHandler() { | |
315 @Override | |
316 public void onClick(ClickEvent event) { | |
317 plusClicked(); | |
318 } | |
319 }); | |
320 return plusBtn; | |
321 } | |
322 | |
323 | |
324 protected void fireToLoad() { | |
325 for (DatacageHandler handler: handlers) { | |
326 handler.toLoad(toLoad); | |
327 } | |
328 } | |
329 | |
330 | |
331 /** Notify DatacageDoubleClickHandlers that a doubleclick happened. */ | |
332 protected void fireOnDoubleClick() { | |
333 for (DatacageDoubleClickHandler handler: doubleHandlers) { | |
334 handler.onDoubleClick(toLoad); | |
335 } | |
336 } | |
337 | |
338 | |
339 protected void doubleClickedOnTree(RecordDoubleClickEvent event) { | |
340 TreeNode node = (TreeNode)event.getRecord(); | |
341 collectToLoads(node); | |
342 fireOnDoubleClick(); | |
343 } | |
344 | |
345 | |
346 /** | |
347 * Adds to toLoad, from info in node. | |
348 * Afterwards, add all children of node to stack to parse (next time | |
349 * collectToLoads is called). | |
350 */ | |
351 protected void collectToLoads(TreeNode node) { | |
352 Stack<TreeNode> stack = new Stack<TreeNode>(); | |
353 | |
354 stack.push(node); | |
355 | |
356 while (!stack.isEmpty()) { | |
357 node = stack.pop(); | |
358 String factory = node.getAttribute("factory"); | |
359 if (factory != null) { // we need at least a factory | |
360 String artifact = node.getAttribute("artifact-id"); | |
361 String out = node.getAttribute("out"); | |
362 String name = node.getAttribute("facet"); | |
363 String ids = node.getAttribute("ids"); | |
364 String displayname = node.getAttribute("name"); | |
365 String debugAttributeValues = ""; | |
366 for (String attr: node.getAttributes()) { | |
367 debugAttributeValues += ("[" + attr +": " | |
368 + node.getAttributeAsString(attr) + "] "); | |
369 } | |
370 GWT.log("DatacageWidget.collectToLoad, attributes are " | |
371 + debugAttributeValues); | |
372 | |
373 toLoad.add(artifact, | |
374 factory, | |
375 out, | |
376 name, | |
377 ids, | |
378 displayname); | |
379 } | |
380 TreeNode [] children = tree.getChildren(node); | |
381 if (children != null) { | |
382 for (TreeNode child: children) { | |
383 stack.push(child); | |
384 } | |
385 } | |
386 } | |
387 } | |
388 | |
389 | |
390 /** Get meta-data and populate tree with it. */ | |
391 protected void triggerTreeBuilding() { | |
392 Config config = Config.getInstance(); | |
393 String locale = config.getLocale(); | |
394 | |
395 String artifactId = artifact.getUuid(); | |
396 String userId = (user != null) ? user.identifier() : null; | |
397 | |
398 lockUI(); | |
399 | |
400 metaDataService.getMetaData( | |
401 locale, | |
402 artifactId, | |
403 userId, | |
404 outs, | |
405 parameters, | |
406 new AsyncCallback<DataCageTree>() { | |
407 @Override | |
408 public void onFailure(Throwable caught) { | |
409 GWT.log("Could not load meta data."); | |
410 SC.warn(caught.getMessage()); | |
411 unlockUI(); | |
412 } | |
413 | |
414 @Override | |
415 public void onSuccess(DataCageTree dcTree) { | |
416 GWT.log("Successfully loaded meta data."); | |
417 IdGenerator idGenerator = new IdGenerator(); | |
418 DataCageNode dcRoot = dcTree.getRoot(); | |
419 TreeNode root = buildRecursiveChildren( | |
420 dcRoot, idGenerator); | |
421 tree.setRoot(root); | |
422 | |
423 TreeNode[] nodes = tree.getChildren(root); | |
424 for (TreeNode node: nodes) { | |
425 if (node.getAttribute("factory") == null && | |
426 !tree.hasChildren(node)) { | |
427 node.setIsFolder(true); | |
428 } | |
429 } | |
430 | |
431 if (idGenerator.current() < MAX_OPEN) { | |
432 tree.openAll(); | |
433 } | |
434 treeGrid.setData(tree); | |
435 unlockUI(); | |
436 } | |
437 }); | |
438 } | |
439 | |
440 private static final class IdGenerator { | |
441 protected int current; | |
442 | |
443 public IdGenerator() { | |
444 } | |
445 | |
446 public int next() { | |
447 return current++; | |
448 } | |
449 | |
450 public int current() { | |
451 return current; | |
452 } | |
453 } // class IdGenerator | |
454 | |
455 private String i18n(String s) { | |
456 if (!(s.startsWith("${") && s.endsWith("}"))) { | |
457 return s; | |
458 } | |
459 | |
460 s = s.substring(2, s.length()-1); | |
461 | |
462 try { | |
463 return messages.getString(s); | |
464 } | |
465 catch (MissingResourceException mre) { | |
466 GWT.log("cannot find i18n for + '" + s + "'"); | |
467 return s; | |
468 } | |
469 } | |
470 | |
471 protected TreeNode buildRecursiveChildren( | |
472 DataCageNode node, | |
473 IdGenerator idGenerator | |
474 ) { | |
475 TreeNode tn = new TreeNode(); | |
476 tn.setAttribute("id", idGenerator.next()); | |
477 | |
478 List<DataCageNode> children = node.getChildren(); | |
479 | |
480 if (children != null) { | |
481 TreeNode [] tns = new TreeNode[children.size()]; | |
482 for (int i = 0; i < tns.length; ++i) { | |
483 DataCageNode child = children.get(i); | |
484 tns[i] = buildRecursiveChildren(child, idGenerator); | |
485 } | |
486 tn.setAttribute("children-nodes", tns); | |
487 } | |
488 | |
489 tn.setAttribute("name", i18n(node.getDescription())); | |
490 tn.setAttribute("facet", node.getName()); | |
491 | |
492 AttrList attrs = node.getAttributes(); | |
493 if (attrs != null) { | |
494 for (int i = 0, N = attrs.size(); i < N; ++i) { | |
495 String key = attrs.getKey(i); | |
496 String value = attrs.getValue(i); | |
497 tn.setAttribute(key, value); | |
498 } | |
499 } | |
500 | |
501 return tn; | |
502 } | |
503 } | |
504 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |