teichmann@5861: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
teichmann@5861: * Software engineering by Intevation GmbH
teichmann@5861: *
teichmann@5993: * This file is Free Software under the GNU AGPL (>=v3)
teichmann@5861: * and comes with ABSOLUTELY NO WARRANTY! Check out the
teichmann@5993: * documentation coming with Dive4Elements River for details.
teichmann@5861: */
teichmann@5861:
teichmann@5835: package org.dive4elements.river.client.client.ui;
ingo@30:
gernotbelger@8870: import java.util.Collection;
gernotbelger@8870: import java.util.HashMap;
gernotbelger@8870: import java.util.LinkedHashMap;
gernotbelger@8870: import java.util.LinkedList;
gernotbelger@8870: import java.util.List;
gernotbelger@8870: import java.util.Map;
gernotbelger@8870: import java.util.Map.Entry;
ingo@30:
teichmann@5835: import org.dive4elements.river.client.client.Config;
teichmann@5835: import org.dive4elements.river.client.client.FLYSConstants;
teichmann@5835: import org.dive4elements.river.client.client.services.ModuleService;
teichmann@5835: import org.dive4elements.river.client.client.services.ModuleServiceAsync;
teichmann@5835: import org.dive4elements.river.client.shared.model.Data;
teichmann@5835: import org.dive4elements.river.client.shared.model.DataItem;
teichmann@5835: import org.dive4elements.river.client.shared.model.DataList;
teichmann@5835: import org.dive4elements.river.client.shared.model.DefaultData;
teichmann@5835: import org.dive4elements.river.client.shared.model.DefaultDataItem;
teichmann@5835: import org.dive4elements.river.client.shared.model.Module;
gernotbelger@8870: import org.dive4elements.river.client.shared.model.ModuleGroup;
ingo@30:
gernotbelger@8870: import com.google.gwt.core.client.GWT;
gernotbelger@8870: import com.google.gwt.user.client.rpc.AsyncCallback;
gernotbelger@8870: import com.smartgwt.client.types.VerticalAlignment;
gernotbelger@8870: import com.smartgwt.client.util.SC;
gernotbelger@8870: import com.smartgwt.client.widgets.Canvas;
gernotbelger@8870: import com.smartgwt.client.widgets.Label;
gernotbelger@8870: import com.smartgwt.client.widgets.form.DynamicForm;
gernotbelger@8870: import com.smartgwt.client.widgets.form.fields.RadioGroupItem;
gernotbelger@8870: import com.smartgwt.client.widgets.form.fields.events.ChangeEvent;
gernotbelger@8870: import com.smartgwt.client.widgets.form.fields.events.ChangeHandler;
gernotbelger@8870: import com.smartgwt.client.widgets.layout.HLayout;
gernotbelger@8870: import com.smartgwt.client.widgets.layout.LayoutSpacer;
gernotbelger@8870: import com.smartgwt.client.widgets.layout.VLayout;
ingo@30:
ingo@30: /**
ingo@30: * The ModuleSelection combines the river selection and the module selection in
ingo@30: * one widget. It will display a vertical splitted widget - the upper part will
ingo@30: * render checkboxes for each module, the lower one will display a combobox at
ingo@30: * the left and a map panel on the right to choose the river.
ingo@30: *
ingo@30: * @author Ingo Weinzierl
ingo@30: */
ingo@30: public class ModuleSelection extends MapSelection {
ingo@30:
christian@4131: private static final long serialVersionUID = -5634831815175543328L;
christian@4131:
ingo@30: /** The message class that provides i18n strings.*/
gernotbelger@8870: private FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
bjoern@3518:
bjoern@3518: /** The ModuleService used to retrieve the available modules of a user.*/
gernotbelger@8870: private ModuleServiceAsync moduleService = GWT.create(ModuleService.class);
ingo@30:
gernotbelger@8870: private Map > modulesRiverMap = new LinkedHashMap >();
gernotbelger@8870:
gernotbelger@8870: private Map modulesByName = new HashMap();
gernotbelger@8870:
gernotbelger@8870: private Map> modulesByGroup = new LinkedHashMap>();
gernotbelger@8870:
gernotbelger@8870: private Map groupToRadios = new LinkedHashMap();
gernotbelger@8870:
gernotbelger@8870: private Map groupToCanvas = new LinkedHashMap();
gernotbelger@8870:
gernotbelger@8870: private Map rivers = null;
gernotbelger@8870:
gernotbelger@8870: private VLayout radioPanel;
gernotbelger@8870:
gernotbelger@8872: /* TODO: seems that it needs to be static for the callback, is this really necessary?
gernotbelger@8872: * FIXME: this is (most probable) the reason for the following bug:
gernotbelger@8872: * - open two different new projects
gernotbelger@8872: * - select in both windows two differenz modules (e.g. w-info in the first, m-info in the second)
gernotbelger@8872: * - now click on a river in each window
gernotbelger@8872: * ---> 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).
gernotbelger@8870: * */
gernotbelger@8870: private static Module selectedModule = null;
gernotbelger@8870:
ingo@30: public ModuleSelection() {
bjoern@3518: readModules();
ingo@30: }
ingo@30:
ingo@30: /**
ingo@30: * This method returns a widget that renders the checkboxes for each module
ingo@30: * and the MapSelection that lets the user choose the river.
ingo@30: *
ingo@30: * @param data The provided rivers.
ingo@30: *
ingo@30: * @return the module selection combined with the river selection.
ingo@30: */
christian@4131: @Override
ingo@51: public Canvas create(DataList data) {
bjoern@3518: GWT.log("ModuleSelection - create()");
rrenkert@6133: createCallback();
ingo@30: VLayout newLayout = new VLayout();
ingo@30: newLayout.setMembersMargin(10);
raimund@282: newLayout.setAlign(VerticalAlignment.TOP);
ingo@30: Canvas moduleSelection = createWidget();
ingo@30:
raimund@282: moduleSelection.setHeight(100);
raimund@282: newLayout.setHeight(70);
ingo@30: newLayout.addMember(moduleSelection);
ingo@30:
ingo@30: return newLayout;
ingo@30: }
ingo@30:
bjoern@3518: private void readModules() {
bjoern@3518: Config config = Config.getInstance();
bjoern@3518: String locale = config.getLocale();
bjoern@3518:
bjoern@3518: moduleService.list(locale, new AsyncCallback() {
bjoern@3518: @Override
bjoern@3518: public void onFailure(Throwable caught) {
bjoern@3518: GWT.log("Could not recieve a list of modules.");
bjoern@3518: SC.warn(MSG.getString(caught.getMessage()));
bjoern@3518: }
bjoern@3518:
bjoern@3518: @Override
bjoern@3518: public void onSuccess(Module[] newmodules) {
bjoern@3518: GWT.log("Retrieved " + newmodules.length + " modules.");
gernotbelger@8870: setModules(newmodules);
gernotbelger@8870: updateRadioPanels();
bjoern@3518: }
bjoern@3518: });
bjoern@3518: }
bjoern@3518:
gernotbelger@8870: // TODO: bad. Too much knowledge spread over the application.
gernotbelger@8870: // TODO: instead, e.g. use a controller that knows both (ModuleSelection and LinkSelection) and let him do this kind of things
andre@8528: private void checkRivers(String selected) {
gernotbelger@8870: if (rivers == null || rivers.isEmpty() || /*modules == null || */ selected == null )
gernotbelger@8870: return;
gernotbelger@8870:
gernotbelger@8870: final List allowedRivers = modulesRiverMap.get(selected);
gernotbelger@8870: if ( allowedRivers == null )
gernotbelger@8870: GWT.log("No configured rivers for module: " + selected);
gernotbelger@8870:
gernotbelger@8870: for (final Map.Entry s: rivers.entrySet()) {
gernotbelger@8870: if (allowedRivers == null || !allowedRivers.contains(s.getKey())) {
gernotbelger@8870: s.getValue().hide();
gernotbelger@8870: } else {
gernotbelger@8870: s.getValue().show();
andre@8528: }
andre@8528: }
andre@8528: }
gernotbelger@8870:
gernotbelger@8870: protected final void setModules(Module[] newmodules) {
gernotbelger@8870: modulesRiverMap.clear();
gernotbelger@8874:
gernotbelger@8870: if( newmodules == null )
gernotbelger@8870: return;
gernotbelger@8874:
gernotbelger@8870: for(final Module module : newmodules) {
gernotbelger@8870: final String name = module.getName();
gernotbelger@8874:
gernotbelger@8870: /* remember rivers per module */
gernotbelger@8870: modulesRiverMap.put(name, module.getRivers());
bjoern@3530:
gernotbelger@8870: /* hash by name */
gernotbelger@8870: modulesByName.put(name, module);
gernotbelger@8874:
gernotbelger@8870: /* hash by group */
gernotbelger@8870: final ModuleGroup group = module.getGroup();
gernotbelger@8870: if( !modulesByGroup.containsKey( group ) )
gernotbelger@8870: modulesByGroup.put(group, new LinkedList());
gernotbelger@8874:
gernotbelger@8870: final List modulesGroup = modulesByGroup.get(group);
gernotbelger@8870: modulesGroup.add(module);
bjoern@3518: }
bjoern@3518: }
ingo@30:
ingo@30: /**
ingo@30: * Creates a widget that displays a checkbox for each module.
ingo@30: *
ingo@30: * @return a widget with checkboxes.
ingo@30: */
ingo@30: protected Canvas createWidget() {
gernotbelger@8870:
gernotbelger@8870: final HLayout layout = new HLayout();
gernotbelger@8870:
gernotbelger@8870: radioPanel = new VLayout();
ingo@30:
gernotbelger@8870: final Label label = new Label(MESSAGES.module_selection());
ingo@30: label.setWidth(50);
raimund@282: label.setHeight(25);
ingo@30:
ingo@30: layout.addMember(label);
gernotbelger@8870: layout.addMember(radioPanel);
gernotbelger@8874:
gernotbelger@8870: updateRadioPanels();
gernotbelger@8874:
ingo@30: return layout;
ingo@30: }
ingo@30:
gernotbelger@8870: protected final void updateRadioPanels() {
gernotbelger@8870:
gernotbelger@8870: /* first clear existing panels, if any exist */
gernotbelger@8870: final Collection