Mercurial > dive4elements > river
comparison gwt-client/src/main/java/org/dive4elements/river/client/client/ui/ThemePanel.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/ThemePanel.java@821a02bbfb4e |
children | 172338b1407f |
comparison
equal
deleted
inserted
replaced
5837:d9901a08d0a6 | 5838:5aa05a7a34b7 |
---|---|
1 package org.dive4elements.river.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.util.BooleanCallback; | |
7 import com.smartgwt.client.util.SC; | |
8 import com.smartgwt.client.widgets.Canvas; | |
9 import com.smartgwt.client.widgets.grid.ListGrid; | |
10 import com.smartgwt.client.widgets.grid.ListGridRecord; | |
11 import com.smartgwt.client.widgets.grid.events.EditCompleteEvent; | |
12 import com.smartgwt.client.widgets.grid.events.EditCompleteHandler; | |
13 import com.smartgwt.client.widgets.grid.events.RowContextClickEvent; | |
14 import com.smartgwt.client.widgets.grid.events.RowContextClickHandler; | |
15 import com.smartgwt.client.widgets.menu.Menu; | |
16 import com.smartgwt.client.widgets.menu.MenuItem; | |
17 import com.smartgwt.client.widgets.menu.events.ClickHandler; | |
18 import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent; | |
19 | |
20 import org.dive4elements.river.client.client.Config; | |
21 import org.dive4elements.river.client.client.FLYSConstants; | |
22 import org.dive4elements.river.client.client.event.HasOutputParameterChangeHandlers; | |
23 import org.dive4elements.river.client.client.event.HasRedrawRequestHandlers; | |
24 import org.dive4elements.river.client.client.event.OnMoveEvent; | |
25 import org.dive4elements.river.client.client.event.OnMoveHandler; | |
26 import org.dive4elements.river.client.client.event.OutputParameterChangeEvent; | |
27 import org.dive4elements.river.client.client.event.OutputParameterChangeHandler; | |
28 import org.dive4elements.river.client.client.event.RedrawRequestEvent; | |
29 import org.dive4elements.river.client.client.event.RedrawRequestEvent.Type; | |
30 import org.dive4elements.river.client.client.event.RedrawRequestHandler; | |
31 import org.dive4elements.river.client.client.services.CollectionAttributeService; | |
32 import org.dive4elements.river.client.client.services.CollectionAttributeServiceAsync; | |
33 import org.dive4elements.river.client.client.services.CollectionItemAttributeService; | |
34 import org.dive4elements.river.client.client.services.CollectionItemAttributeServiceAsync; | |
35 import org.dive4elements.river.client.shared.model.Collection; | |
36 import org.dive4elements.river.client.shared.model.CollectionItemAttribute; | |
37 import org.dive4elements.river.client.shared.model.FacetRecord; | |
38 import org.dive4elements.river.client.shared.model.OutputMode; | |
39 import org.dive4elements.river.client.shared.model.Theme; | |
40 import org.dive4elements.river.client.shared.model.ThemeList; | |
41 | |
42 import java.util.ArrayList; | |
43 import java.util.List; | |
44 | |
45 /** | |
46 * ThemePanel on the left in CollectionView. | |
47 * Contains control widgets for "themes", which are plotted in a diagram (chart). | |
48 * | |
49 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> | |
50 */ | |
51 public abstract class ThemePanel | |
52 extends Canvas | |
53 implements OnMoveHandler, | |
54 EditCompleteHandler, | |
55 HasOutputParameterChangeHandlers, | |
56 HasRedrawRequestHandlers | |
57 { | |
58 protected CollectionAttributeServiceAsync updater = | |
59 GWT.create(CollectionAttributeService.class); | |
60 | |
61 /** The service used to get collection item attributes. */ | |
62 protected CollectionItemAttributeServiceAsync itemAttributeService = | |
63 GWT.create(CollectionItemAttributeService.class); | |
64 | |
65 /** i18ner. */ | |
66 protected FLYSConstants MSG = GWT.create(FLYSConstants.class); | |
67 | |
68 /** List of OutParameterChangedHandler. */ | |
69 protected List<OutputParameterChangeHandler> outHandlers; | |
70 | |
71 /** List of ChartShallRedrawHandler. */ | |
72 protected List<RedrawRequestHandler> redrawRequestHandlers; | |
73 | |
74 protected OutputMode mode; | |
75 | |
76 protected ThemeNavigationPanel navigation; | |
77 protected ListGrid list; | |
78 | |
79 /** The collection view*/ | |
80 protected CollectionView view; | |
81 | |
82 /** | |
83 * Setup Grid, navigation bar. | |
84 * @param collection Collection for which to show themes. | |
85 */ | |
86 public ThemePanel( | |
87 OutputMode mode, | |
88 CollectionView view | |
89 ) { | |
90 this.mode = mode; | |
91 this.list = createGrid(); | |
92 this.view = view; | |
93 list.addRowContextClickHandler(new RowContextClickHandler() { | |
94 @Override | |
95 public void onRowContextClick(RowContextClickEvent event) { | |
96 ListGridRecord[] records = list.getSelectedRecords(); | |
97 | |
98 Menu menu = null; | |
99 | |
100 if (records == null || records.length == 0) { | |
101 return; | |
102 } | |
103 else if (records.length == 1) { | |
104 menu = getSingleContextMenu(records); | |
105 } | |
106 else if (records.length > 1) { | |
107 menu = getMultiContextMenu(records); | |
108 } | |
109 | |
110 if (menu != null) { | |
111 list.setContextMenu(menu); | |
112 menu.showContextMenu(); | |
113 | |
114 event.cancel(); | |
115 } | |
116 } | |
117 }); | |
118 | |
119 this.redrawRequestHandlers = new ArrayList<RedrawRequestHandler>(); | |
120 this.outHandlers = new ArrayList<OutputParameterChangeHandler>(); | |
121 this.navigation = new ThemeNavigationPanel(); | |
122 this.navigation.addOnMoveHandler(this); | |
123 | |
124 this.setShowResizeBar(true); | |
125 } | |
126 | |
127 | |
128 public abstract void activateTheme(Theme theme, boolean active); | |
129 | |
130 | |
131 /** | |
132 * Replace the current collection with a new one. <b>NOTE: this operation | |
133 * triggers updateGrid() which modifies the themes in the grid.</b> | |
134 * | |
135 * @param collection The new collection object. | |
136 */ | |
137 protected void setCollection(Collection collection) { | |
138 // Set collection of view, but do not trigger event shooting. | |
139 this.view.setCollection(collection, true); | |
140 | |
141 updateGrid(); | |
142 } | |
143 | |
144 | |
145 /** Get Collection. */ | |
146 public Collection getCollection() { | |
147 return view.getCollection(); | |
148 } | |
149 | |
150 | |
151 /** | |
152 * Returns the ThemeList of the current collection and output mode. | |
153 * | |
154 * @return the current ThemeList. | |
155 */ | |
156 public ThemeList getThemeList() { | |
157 return getCollection().getThemeList(mode.getName()); | |
158 } | |
159 | |
160 public ListGridRecord[] getSelectedRecords() { | |
161 return list.getSelectedRecords(); | |
162 } | |
163 | |
164 /** | |
165 * Registers a new OutputParameterChangeHandler. | |
166 * | |
167 * @param h The new handler. | |
168 */ | |
169 @Override | |
170 public void addOutputParameterChangeHandler(OutputParameterChangeHandler h){ | |
171 if (h != null) { | |
172 outHandlers.add(h); | |
173 } | |
174 } | |
175 | |
176 | |
177 /** | |
178 * Registers a RedrawRequestHandler. | |
179 * | |
180 * @param h The new handler. | |
181 */ | |
182 @Override | |
183 public void addRedrawRequestHandler(RedrawRequestHandler h){ | |
184 if (h != null) { | |
185 redrawRequestHandlers.add(h); | |
186 } | |
187 } | |
188 | |
189 | |
190 /** | |
191 * Request a redraw of e.g. a Chart. | |
192 */ | |
193 final public void requestRedraw() { | |
194 for (RedrawRequestHandler handler: redrawRequestHandlers) { | |
195 handler.onRedrawRequest(new RedrawRequestEvent(Type.DEFAULT)); | |
196 } | |
197 } | |
198 | |
199 | |
200 /** | |
201 * Called when the attribution of an output changed. It informs the | |
202 * registered handlers about the changes. | |
203 */ | |
204 protected void fireOutputParameterChanged() { | |
205 OutputParameterChangeEvent evt = new OutputParameterChangeEvent(); | |
206 | |
207 for (OutputParameterChangeHandler handler: outHandlers) { | |
208 handler.onOutputParameterChanged(evt); | |
209 } | |
210 } | |
211 | |
212 | |
213 /** Registers the CollectionView associated to this ThemePanel. */ | |
214 public void setCollectionView(CollectionView view) { | |
215 this.view = view; | |
216 } | |
217 | |
218 | |
219 /** | |
220 * This method is used to clear the current theme grid and add new updated | |
221 * data. | |
222 */ | |
223 protected void updateGrid() { | |
224 GWT.log("ThemePanel.updateGrid"); | |
225 | |
226 ListGridRecord[] selected = list.getSelectedRecords(); | |
227 | |
228 clearGrid(); | |
229 | |
230 ThemeList themeList = getThemeList(); | |
231 | |
232 if (themeList == null) { | |
233 GWT.log("ERROR: No theme list."); | |
234 return; | |
235 } | |
236 | |
237 int count = themeList.getThemeCount(); | |
238 | |
239 for (int i = 1; i <= count; i++) { | |
240 Theme theme = themeList.getThemeAt(i); | |
241 | |
242 if (theme == null) { | |
243 continue; | |
244 } | |
245 | |
246 if (theme.getFacet().equals("empty.facet")) { | |
247 theme.setVisible(0); | |
248 } | |
249 | |
250 if (theme.getVisible() == 0) { | |
251 continue; | |
252 } | |
253 | |
254 FacetRecord newRecord = createRecord(theme); | |
255 addFacetRecord(newRecord); | |
256 | |
257 String newArtifact = theme.getArtifact(); | |
258 String newFacet = theme.getFacet(); | |
259 int newIndex = theme.getIndex(); | |
260 | |
261 for (ListGridRecord r: selected) { | |
262 FacetRecord sel = (FacetRecord) r; | |
263 Theme oldTheme = sel.getTheme(); | |
264 | |
265 if (oldTheme.getArtifact().equals(newArtifact) | |
266 && oldTheme.getFacet().equals(newFacet) | |
267 && oldTheme.getIndex() == newIndex) { | |
268 list.selectRecord(newRecord); | |
269 } | |
270 } | |
271 } | |
272 | |
273 fireOutputParameterChanged(); | |
274 } | |
275 | |
276 | |
277 /** Adds given Record to the list (table). */ | |
278 protected void addFacetRecord(FacetRecord rec) { | |
279 list.addData(rec); | |
280 } | |
281 | |
282 | |
283 /** Create a FacetRecord that wraps given theme. */ | |
284 protected FacetRecord createRecord(Theme theme) { | |
285 return new FacetRecord(theme); | |
286 } | |
287 | |
288 | |
289 /** | |
290 * This method triggers the CollectionAttributeService. Based on the current | |
291 * collectin settings, the attribute of the collection is modified or not. | |
292 * But in every case, we will get a new collection object - which might be | |
293 * the same as the current one. | |
294 */ | |
295 public void updateCollection() { | |
296 final Config config = Config.getInstance(); | |
297 final String loc = config.getLocale(); | |
298 | |
299 GWT.log("ThemePanel.updateCollection via RPC now"); | |
300 | |
301 // Don't forget to enable the panel after the request has finished! | |
302 disable(); | |
303 | |
304 updater.update(getCollection(), loc, new AsyncCallback<Collection>() { | |
305 @Override | |
306 public void onFailure(Throwable caught) { | |
307 GWT.log("Could not update collection attributes."); | |
308 SC.warn(MSG.getString(caught.getMessage())); | |
309 | |
310 enable(); | |
311 } | |
312 | |
313 | |
314 @Override | |
315 public void onSuccess(Collection collection) { | |
316 setCollection(collection); | |
317 | |
318 enable(); | |
319 } | |
320 }); | |
321 } | |
322 | |
323 | |
324 /** | |
325 * Create and configure the Grid to display. | |
326 */ | |
327 protected ListGrid createGrid() { | |
328 ListGrid grid = createNewGrid(); | |
329 grid.setLeaveScrollbarGap(false); | |
330 | |
331 return grid; | |
332 } | |
333 | |
334 | |
335 protected ListGrid createNewGrid() { | |
336 return new ListGrid(); | |
337 } | |
338 | |
339 | |
340 /** | |
341 * A method that removes all records from theme grid. | |
342 */ | |
343 protected void clearGrid() { | |
344 ListGridRecord[] records = list.getRecords(); | |
345 | |
346 if (records == null || records.length == 0) { | |
347 return; | |
348 } | |
349 | |
350 for (ListGridRecord record: records) { | |
351 list.removeData(record); | |
352 } | |
353 } | |
354 | |
355 /** Return 'separator'- menu-item. */ | |
356 protected MenuItem createSeparator() { | |
357 MenuItem separator = new MenuItem(); | |
358 separator.setIsSeparator(true); | |
359 return separator; | |
360 } | |
361 | |
362 | |
363 /** | |
364 * Get the context menu for a (right mouse button)click on a single item. | |
365 */ | |
366 protected Menu getSingleContextMenu(final ListGridRecord[] records) { | |
367 Menu menu = new Menu(); | |
368 | |
369 menu.addItem(createActivateItem(records)); | |
370 menu.addItem(createDeactivateItem(records)); | |
371 menu.addItem(createRemoveItem(records)); | |
372 menu.addItem(createSeparator()); | |
373 menu.addItem(createPropertiesItem(records)); | |
374 | |
375 return menu; | |
376 } | |
377 | |
378 | |
379 protected Menu getMultiContextMenu(final ListGridRecord[] records) { | |
380 Menu menu = new Menu(); | |
381 | |
382 menu.addItem(createActivateItem(records)); | |
383 menu.addItem(createDeactivateItem(records)); | |
384 menu.addItem(createRemoveItem(records)); | |
385 | |
386 return menu; | |
387 } | |
388 | |
389 | |
390 /** The properties menu item (opens style editor on click). */ | |
391 protected MenuItem createPropertiesItem(final ListGridRecord[] records) { | |
392 MenuItem properties = new MenuItem(MSG.properties()); | |
393 | |
394 properties.addClickHandler(new ClickHandler() { | |
395 @Override | |
396 public void onClick(MenuItemClickEvent evt) { | |
397 GWT.log("clicked properties"); | |
398 for (ListGridRecord record: records) { | |
399 openStyleEditor((FacetRecord) record); | |
400 } | |
401 } | |
402 }); | |
403 | |
404 return properties; | |
405 } | |
406 | |
407 | |
408 protected MenuItem createActivateItem(final ListGridRecord[] records) { | |
409 MenuItem activate = new MenuItem(MSG.activateTheme()); | |
410 | |
411 activate.addClickHandler(new ClickHandler() { | |
412 @Override | |
413 public void onClick(MenuItemClickEvent evt) { | |
414 for (ListGridRecord record: records) { | |
415 FacetRecord facet = (FacetRecord) record; | |
416 activateTheme(facet.getTheme(), true); | |
417 } | |
418 | |
419 updateCollection(); | |
420 } | |
421 }); | |
422 | |
423 return activate; | |
424 } | |
425 | |
426 | |
427 protected MenuItem createDeactivateItem(final ListGridRecord[] records) { | |
428 MenuItem deactivate = new MenuItem(MSG.deactivateTheme()); | |
429 | |
430 deactivate.addClickHandler(new ClickHandler() { | |
431 @Override | |
432 public void onClick(MenuItemClickEvent evt) { | |
433 for (ListGridRecord record: records) { | |
434 FacetRecord facet = (FacetRecord) record; | |
435 activateTheme(facet.getTheme(), false); | |
436 } | |
437 | |
438 updateCollection(); | |
439 } | |
440 }); | |
441 | |
442 return deactivate; | |
443 } | |
444 | |
445 | |
446 /** Remove given themes (not asking for confirmation). */ | |
447 protected void removeThemes(final ListGridRecord[] records) { | |
448 for (ListGridRecord record: records) { | |
449 FacetRecord facet = (FacetRecord) record; | |
450 Theme theme = facet.getTheme(); | |
451 theme.setVisible(0); | |
452 theme.setActive(0); | |
453 updateCollection(); | |
454 } | |
455 } | |
456 | |
457 | |
458 /** Create menu item for removing theme(s). Will ask for confirmation. */ | |
459 protected MenuItem createRemoveItem(final ListGridRecord[] records) { | |
460 MenuItem remove = new MenuItem(MSG.removeTheme()); | |
461 | |
462 remove.addClickHandler(new ClickHandler() { | |
463 @Override | |
464 public void onClick(MenuItemClickEvent evt) { | |
465 SC.ask(MSG.askThemeRemove(), new BooleanCallback() { | |
466 @Override | |
467 public void execute(Boolean value) { | |
468 if (value) { | |
469 removeThemes(records); | |
470 } | |
471 } | |
472 }); | |
473 } | |
474 }); | |
475 | |
476 return remove; | |
477 } | |
478 | |
479 | |
480 /** | |
481 * This method is called after a cell in the theme grid has been modified. | |
482 * | |
483 * @param event The event that stores information about the modified record. | |
484 */ | |
485 @Override | |
486 public void onEditComplete(EditCompleteEvent event) { | |
487 GWT.log("Edited record."); | |
488 | |
489 int row = event.getRowNum(); | |
490 FacetRecord rec = (FacetRecord) list.getRecord(row); | |
491 | |
492 Theme theme = rec.getTheme(); | |
493 | |
494 theme.setDescription(rec.getName()); | |
495 activateTheme(theme, rec.getActive()); | |
496 | |
497 updateCollection(); | |
498 } | |
499 | |
500 | |
501 /** | |
502 * This method should be defined in subclasses that wants to listen to this | |
503 * event. | |
504 * | |
505 * @param theme The theme that is moved. | |
506 * @param oldIdx The index of the theme before it was moved. | |
507 * @param newIdx The index of the theme after it was moved. | |
508 */ | |
509 protected void fireThemeMoved(Theme theme, int oldIdx, int newIdx) { | |
510 // Do nothing | |
511 } | |
512 | |
513 | |
514 @Override | |
515 public void onMove(OnMoveEvent event) { | |
516 int type = event.getType(); | |
517 | |
518 GWT.log("ThemePanel.onMove: " + type); | |
519 | |
520 ListGridRecord[] records = list.getSelectedRecords(); | |
521 | |
522 if (records == null || records.length == 0) { | |
523 GWT.log("ThemePanel.onMove: No records selected."); | |
524 return; | |
525 } | |
526 | |
527 switch (type) { | |
528 case 0: moveRecordsTop(records); break; | |
529 case 1: moveRecordsUp(records); break; | |
530 case 2: moveRecordsDown(records); break; | |
531 case 3: moveRecordsBottom(records); break; | |
532 } | |
533 | |
534 updateCollection(); | |
535 } | |
536 | |
537 | |
538 /** | |
539 * Moves the selected grid records (themes) to the top of the grid. | |
540 * | |
541 * @param records The selected themes in the list. Null not permitted. | |
542 */ | |
543 protected void moveRecordsTop(ListGridRecord[] records) { | |
544 ThemeList themeList = getThemeList(); | |
545 | |
546 int idx = 1; | |
547 | |
548 for (ListGridRecord record: records) { | |
549 Theme theme = ((FacetRecord) record).getTheme(); | |
550 fireThemeMoved(theme, theme.getPosition(), idx); | |
551 themeList.setThemePosition(theme, idx++); | |
552 } | |
553 | |
554 updateGrid(); | |
555 } | |
556 | |
557 | |
558 /** | |
559 * Moves the selected grid records (themes) one step up. | |
560 * | |
561 * @param records The selected themes in the list. Null not permitted. | |
562 */ | |
563 protected void moveRecordsUp(ListGridRecord[] records) { | |
564 ThemeList themeList = getThemeList(); | |
565 | |
566 int[] newPos = new int[records.length]; | |
567 | |
568 for (int i = 0; i < records.length ; i++) { | |
569 Theme theme = ((FacetRecord) records[i]).getTheme(); | |
570 newPos[i] = theme.getPosition() - 1; | |
571 } | |
572 | |
573 for (int i = 0; i < records.length ; i++) { | |
574 Theme theme = ((FacetRecord) records[i]).getTheme(); | |
575 fireThemeMoved(theme, theme.getPosition(), newPos[i]); | |
576 themeList.setThemePosition(theme, newPos[i]); | |
577 } | |
578 | |
579 updateGrid(); | |
580 } | |
581 | |
582 | |
583 /** | |
584 * Moves the selected grid records (themes) one step down. | |
585 * | |
586 * @param records The selected themes in the list. Null not permitted. | |
587 */ | |
588 protected void moveRecordsDown(ListGridRecord[] records) { | |
589 ThemeList themeList = getThemeList(); | |
590 | |
591 int[] newPos = new int[records.length]; | |
592 | |
593 for (int i = records.length-1; i >= 0; i--) { | |
594 Theme theme = ((FacetRecord) records[i]).getTheme(); | |
595 newPos[i] = theme.getPosition()+1; | |
596 } | |
597 | |
598 for (int i = records.length-1; i >= 0; i--) { | |
599 Theme theme = ((FacetRecord) records[i]).getTheme(); | |
600 fireThemeMoved(theme, theme.getPosition(), newPos[i]); | |
601 themeList.setThemePosition(theme, newPos[i]); | |
602 } | |
603 | |
604 updateGrid(); | |
605 } | |
606 | |
607 | |
608 /** | |
609 * Moves the selected grid records (themes) to the bottom of the grid. | |
610 * | |
611 * @param records The selected themes in the list. Null not permitted. | |
612 */ | |
613 protected void moveRecordsBottom(ListGridRecord[] records) { | |
614 ThemeList themeList = getThemeList(); | |
615 | |
616 int idx = themeList.getThemeCount(); | |
617 | |
618 for (int i = records.length-1; i >= 0; i--) { | |
619 Theme theme = ((FacetRecord) records[i]).getTheme(); | |
620 fireThemeMoved(theme, theme.getPosition(), idx); | |
621 themeList.setThemePosition(theme, idx--); | |
622 } | |
623 | |
624 updateGrid(); | |
625 } | |
626 | |
627 | |
628 protected void openStyleEditor(final FacetRecord record) { | |
629 Config config = Config.getInstance(); | |
630 String locale = config.getLocale(); | |
631 | |
632 String artifact = record.getTheme().getArtifact(); | |
633 | |
634 itemAttributeService.getCollectionItemAttribute( | |
635 this.getCollection(), | |
636 artifact, | |
637 locale, | |
638 new AsyncCallback<CollectionItemAttribute>() { | |
639 @Override | |
640 public void onFailure (Throwable caught) { | |
641 SC.warn(MSG.getString(caught.getMessage())); | |
642 } | |
643 @Override | |
644 public void onSuccess(CollectionItemAttribute cia) { | |
645 GWT.log("Successfully loaded collectionitem attributes."); | |
646 showStyleEditor(cia, record); | |
647 } | |
648 }); | |
649 } | |
650 | |
651 | |
652 protected void showStyleEditor( | |
653 CollectionItemAttribute cia, | |
654 FacetRecord record) | |
655 { | |
656 StyleEditorWindow win = new StyleEditorWindow( | |
657 getCollection(), | |
658 cia, | |
659 record); | |
660 win.setThemePanel(this); | |
661 win.centerInPage(); | |
662 win.show(); | |
663 } | |
664 | |
665 | |
666 /** Get OutputMode of this Panel. */ | |
667 public OutputMode getMode() { | |
668 return this.mode; | |
669 } | |
670 } | |
671 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |