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 :

http://dive4elements.wald.intevation.org