Mercurial > dive4elements > river
view gwt-client/src/main/java/org/dive4elements/river/client/client/ui/ModuleSelection.java @ 9466:a41f5f7c0b4a
Reihenfolge fix
author | gernotbelger |
---|---|
date | Thu, 30 Aug 2018 12:11:08 +0200 |
parents | fe207a8699f7 |
children |
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde * Software engineering by Intevation GmbH * * This file is Free Software under the GNU AGPL (>=v3) * and comes with ABSOLUTELY NO WARRANTY! Check out the * documentation coming with Dive4Elements River for details. */ package org.dive4elements.river.client.client.ui; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.dive4elements.river.client.client.Config; import org.dive4elements.river.client.client.FLYSConstants; import org.dive4elements.river.client.client.services.ModuleService; import org.dive4elements.river.client.client.services.ModuleServiceAsync; import org.dive4elements.river.client.shared.model.Data; import org.dive4elements.river.client.shared.model.DataItem; import org.dive4elements.river.client.shared.model.DataList; import org.dive4elements.river.client.shared.model.DefaultData; import org.dive4elements.river.client.shared.model.DefaultDataItem; import org.dive4elements.river.client.shared.model.Module; import org.dive4elements.river.client.shared.model.ModuleGroup; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.rpc.AsyncCallback; import com.smartgwt.client.types.VerticalAlignment; import com.smartgwt.client.util.SC; import com.smartgwt.client.widgets.Canvas; import com.smartgwt.client.widgets.Label; import com.smartgwt.client.widgets.form.DynamicForm; import com.smartgwt.client.widgets.form.fields.RadioGroupItem; import com.smartgwt.client.widgets.form.fields.events.ChangeEvent; import com.smartgwt.client.widgets.form.fields.events.ChangeHandler; import com.smartgwt.client.widgets.layout.HLayout; import com.smartgwt.client.widgets.layout.LayoutSpacer; import com.smartgwt.client.widgets.layout.VLayout; /** * The ModuleSelection combines the river selection and the module selection in * one widget. It will display a vertical splitted widget - the upper part will * render checkboxes for each module, the lower one will display a combobox at * the left and a map panel on the right to choose the river. * * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> */ public class ModuleSelection extends MapSelection { private static final long serialVersionUID = -5634831815175543328L; /** The message class that provides i18n strings.*/ private FLYSConstants MESSAGES = GWT.create(FLYSConstants.class); /** The ModuleService used to retrieve the available modules of a user.*/ private ModuleServiceAsync moduleService = GWT.create(ModuleService.class); private Map<String, List<String> > modulesRiverMap = new LinkedHashMap<String, List<String> >(); private Map<String, Module> modulesByName = new HashMap<String, Module>(); private Map<ModuleGroup, List<Module>> modulesByGroup = new LinkedHashMap<ModuleGroup, List<Module>>(); private Map<ModuleGroup, RadioGroupItem> groupToRadios = new LinkedHashMap<ModuleGroup, RadioGroupItem>(); private Map<ModuleGroup, Canvas> groupToCanvas = new LinkedHashMap<ModuleGroup, Canvas>(); private Map<String, HLayout> rivers = null; private VLayout radioPanel; /* TODO: seems that it needs to be static for the callback, is this really necessary? * FIXME: this is (most probable) the reason for the following bug: * - open two different new projects * - select in both windows two differenz modules (e.g. w-info in the first, m-info in the second) * - now click on a river in each window * ---> both windows will now show the calculations of the same module (i.e. either both m-info, or both w-info; not one m-info the the other w-info as it should). * */ private static Module selectedModule = null; public ModuleSelection() { readModules(); } /** * This method returns a widget that renders the checkboxes for each module * and the MapSelection that lets the user choose the river. * * @param data The provided rivers. * * @return the module selection combined with the river selection. */ @Override public Canvas create(DataList data) { GWT.log("ModuleSelection - create()"); createCallback(); VLayout newLayout = new VLayout(); newLayout.setMembersMargin(10); newLayout.setAlign(VerticalAlignment.TOP); Canvas moduleSelection = createWidget(); moduleSelection.setHeight(100); newLayout.setHeight(70); newLayout.addMember(moduleSelection); return newLayout; } private void readModules() { Config config = Config.getInstance(); String locale = config.getLocale(); moduleService.list(locale, new AsyncCallback<Module[]>() { @Override public void onFailure(Throwable caught) { GWT.log("Could not recieve a list of modules."); SC.warn(MSG.getString(caught.getMessage())); } @Override public void onSuccess(Module[] newmodules) { GWT.log("Retrieved " + newmodules.length + " modules."); setModules(newmodules); updateRadioPanels(); } }); } // TODO: bad. Too much knowledge spread over the application. // TODO: instead, e.g. use a controller that knows both (ModuleSelection and LinkSelection) and let him do this kind of things private void checkRivers(String selected) { if (rivers == null || rivers.isEmpty() || /*modules == null || */ selected == null ) return; final List<String> allowedRivers = modulesRiverMap.get(selected); if ( allowedRivers == null ) GWT.log("No configured rivers for module: " + selected); for (final Map.Entry<String, HLayout> s: rivers.entrySet()) { if (allowedRivers == null || !allowedRivers.contains(s.getKey())) { s.getValue().hide(); } else { s.getValue().show(); } } } protected final void setModules(Module[] newmodules) { modulesRiverMap.clear(); if( newmodules == null ) return; for(final Module module : newmodules) { final String name = module.getName(); /* remember rivers per module */ modulesRiverMap.put(name, module.getRivers()); /* hash by name */ modulesByName.put(name, module); /* hash by group */ final ModuleGroup group = module.getGroup(); if( !modulesByGroup.containsKey( group ) ) modulesByGroup.put(group, new LinkedList<Module>()); final List<Module> modulesGroup = modulesByGroup.get(group); modulesGroup.add(module); } } /** * Creates a widget that displays a checkbox for each module. * * @return a widget with checkboxes. */ protected Canvas createWidget() { final HLayout layout = new HLayout(); radioPanel = new VLayout(); final Label label = new Label(MESSAGES.module_selection()); label.setWidth(50); label.setHeight(25); layout.addMember(label); layout.addMember(radioPanel); updateRadioPanels(); return layout; } protected final void updateRadioPanels() { /* first clear existing panels, if any exist */ final Collection<Canvas> oldforms = groupToCanvas.values(); for (Canvas oldCanvas : oldforms) { radioPanel.removeMember(oldCanvas); oldCanvas.destroy(); } groupToCanvas.clear(); groupToRadios.clear(); selectedModule = null; if( radioPanel == null ) return; /* now create radio items per group */ int count = 0; for (final Entry<ModuleGroup, List<Module>> groupEntry : modulesByGroup.entrySet()) { final ModuleGroup group = groupEntry.getKey(); final List<Module> groupModule = groupEntry.getValue(); final RadioGroupItem moduleRadio = new RadioGroupItem("modulegroup" + count++); moduleRadio.setShowTitle(false); moduleRadio.setWrap(false); moduleRadio.addChangeHandler(new ChangeHandler() { @Override public void onChange(ChangeEvent event) { final String selectedModuleName = (String) event.getValue(); handleModuleSelected(selectedModuleName); } }); Module selected = null; final LinkedHashMap<String, String> values = new LinkedHashMap<String, String>(); for(final Module module : groupModule) { values.put(module.getName(), module.getLocalizedName()); if (module.isSelected()) { GWT.log("Module " + module.getName() + " is selected."); selectedModule = module; selected = module; } } moduleRadio.setValueMap(values); final DynamicForm groupForm = new DynamicForm(); groupForm.setItems(moduleRadio); groupForm.setColWidths(60,"*"); final Canvas groupPanel; if( group.showGroupFrame() ) { final HLayout layout = new HLayout(); layout.setIsGroup(true); layout.setGroupTitle(group.toString()); layout.setWidth("250"); /* push elements to right */ final LayoutSpacer spacer = new LayoutSpacer(); spacer.setWidth("*"); layout.addMember(spacer); layout.addMember(groupForm); /* put leave a bit space on the right side */ final LayoutSpacer spacer2 = new LayoutSpacer(); spacer2.setWidth("15"); layout.addMember(spacer2); groupPanel = layout; } else groupPanel = groupForm; this.groupToRadios.put( group, moduleRadio ); this.groupToCanvas.put( group, groupPanel ); /* selection must be done after value-map was set; and, only if the selection holds for this group */ if( selected != null ) moduleRadio.setValue(selected.getName()); radioPanel.addMember(groupPanel); } checkRivers(getSelectedModule()); } protected void handleModuleSelected(final String selectedModuleName) { /* remember selected module for later */ selectedModule = modulesByName.get(selectedModuleName); /* because radios might in different radio-groups, we need to de-select them manually */ final ModuleGroup group = selectedModule.getGroup(); for (final Entry<ModuleGroup, RadioGroupItem> entry : groupToRadios.entrySet()) { final ModuleGroup radioGroup = entry.getKey(); if( !group.equals(radioGroup)) { final RadioGroupItem groupRadio = entry.getValue(); groupRadio.setValue((String)null); } } checkRivers(selectedModuleName); } /** * This method prepares the data of two widgets - the module selection and * the river selection. The returning field will contain the Data that * represents the module selection at first position, the second position * stores the Data object that represents the river selection. * * @return the Data that was chosen in this widget. */ @Override protected Data[] getData() { final Module module = selectedModule; final DataItem[] items = new DefaultDataItem[] { new DefaultDataItem(module.getLocalizedName(), module.getLocalizedName(), module.getName()) }; final Data data = new DefaultData("module", null, null, items); return new Data[] {data}; } public void setRivers(Map<String, HLayout> rivers) { this.rivers = rivers; } private native void createCallback() /*-{ $wnd.getModule = @org.dive4elements.river.client.client.ui.ModuleSelection::getSelectedModule(); }-*/; private static String getSelectedModule() { if (selectedModule == null) { return null; } return selectedModule.getName(); } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :