diff gwt-client/src/main/java/org/dive4elements/river/client/client/ui/ModuleSelection.java @ 8870:c26fb37899ca

Introduced groups for modules. Modules marked with the same group-id, will be put together in the ui. Also using now the localization info from the server instead of localizing the modules again on the client side.
author gernotbelger
date Wed, 07 Feb 2018 11:59:13 +0100
parents 5e38e2924c07
children 60278b5fe4d9
line wrap: on
line diff
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/ModuleSelection.java	Wed Feb 07 11:52:04 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/ModuleSelection.java	Wed Feb 07 11:59:13 2018 +0100
@@ -8,19 +8,13 @@
 
 package org.dive4elements.river.client.client.ui;
 
-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.VLayout;
+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;
@@ -32,10 +26,21 @@
 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 java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+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
@@ -50,32 +55,34 @@
     private static final long serialVersionUID = -5634831815175543328L;
 
     /** The message class that provides i18n strings.*/
-    protected FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
-
-    /** The module checkboxes.*/
-    protected static RadioGroupItem radio;
-
-    /** */
-    protected Module[] modules;
+    private FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
 
     /** The ModuleService used to retrieve the available modules of a user.*/
-    protected ModuleServiceAsync moduleService = GWT.create(
-        ModuleService.class);
-
-    private Map<String, List<String> > modulesRiverMap;
-    protected Map<String, HLayout> rivers;
+    private ModuleServiceAsync moduleService = GWT.create(ModuleService.class);
 
-    /**
-     * The default constructor.
-     */
+    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? 
+     * TODO: what happens if we have several 'new project' windows open in parallel?
+     * */
+    private static Module selectedModule = null;
+
     public ModuleSelection() {
-        rivers = null;
-        modulesRiverMap = new LinkedHashMap<String, List<String> >();
-
         readModules();
     }
 
-
     /**
      * This method returns a widget that renders the checkboxes for each module
      * and the MapSelection that lets the user choose the river.
@@ -114,59 +121,54 @@
             @Override
             public void onSuccess(Module[] newmodules) {
                 GWT.log("Retrieved " + newmodules.length + " modules.");
-                modules = newmodules;
-                setModules();
+                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 (selected == null) {
-            selected = getSelectedModule();
-        }
-        if (rivers != null
-            && !rivers.isEmpty()
-            && modules != null
-            && selected != null
-        ) {
-            List<String> allowedRivers = modulesRiverMap.get(selected);
-            if ( allowedRivers == null ) {
-                GWT.log("No configured rivers for module: " + selected);
-            }
-            for (Map.Entry<String, HLayout> s: rivers.entrySet()) {
-                if ( allowedRivers == null ) {
-                    s.getValue().hide();
-                    continue;
-                }
-                if (!allowedRivers.contains(s.getKey())) {
-                    s.getValue().hide();
-                } else {
-                    s.getValue().show();
-                }
+        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();
             }
         }
     }
-
-    private void setModules() {
-        LinkedHashMap<String, String> values =
-            new LinkedHashMap<String, String>();
+    
+    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());
 
-        if (this.modules!= null) {
-            for(Module module : this.modules) {
-                values.put(module.getName(), module.getLocalizedName());
-                if (module.isSelected()) {
-                    GWT.log("Module " + module.getName() + " is selected.");
-                    if (radio != null) {
-                        radio.setDefaultValue(module.getName());
-                    }
-                }
-                modulesRiverMap.put(module.getName(), 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);
         }
-        if (radio != null) {
-            radio.setValueMap(values);
-        }
-        checkRivers(null);
     }
 
     /**
@@ -175,36 +177,119 @@
      * @return a widget with checkboxes.
      */
     protected Canvas createWidget() {
-        HLayout layout = new HLayout();
-
-        Label      label = new Label(MESSAGES.module_selection());
-        DynamicForm form = new DynamicForm();
+        
+        final HLayout layout = new HLayout();
+        
+        radioPanel = new VLayout();
 
-        radio = new RadioGroupItem("plugin");
-        radio.addChangeHandler(new ChangeHandler() {
-            @Override
-            public void onChange(ChangeEvent event) {
-                checkRivers((String)event.getValue());
-            }
-        });
-
+        final Label label = new Label(MESSAGES.module_selection());
         label.setWidth(50);
         label.setHeight(25);
 
-
-        radio.setShowTitle(false);
-        radio.setVertical(true);
-
-        setModules();
-
-        form.setFields(radio);
-
         layout.addMember(label);
-        layout.addMember(form);
-
+        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 HLayout groupPanel = new HLayout();
+
+            if( group.showGroupFrame() )
+            {
+                final LayoutSpacer spacer = new LayoutSpacer();
+                spacer.setWidth(25);
+                groupPanel.addMember(spacer);
+
+                final Label label = new Label(group.toString());
+                label.setWidth(25);
+                label.setHeight(25);
+                groupPanel.addMember(label);
+            }
+            
+            final DynamicForm groupForm = new DynamicForm();
+
+            final RadioGroupItem moduleRadio = new RadioGroupItem("modulegroup" + count++);
+            moduleRadio.setShowTitle(false);
+            moduleRadio.setVertical(true);
+
+            moduleRadio.addChangeHandler(new ChangeHandler() {
+                @Override
+                public void onChange(ChangeEvent event) {
+                    final String selectedModuleName = (String) event.getValue();
+                    handleModuleSelected(selectedModuleName);
+                }
+            });
+            
+            groupForm.setItems(moduleRadio);
+            groupPanel.addMember(groupForm);
+
+            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;
+                    moduleRadio.setValue(module.getName());
+                }
+            }
+            
+            this.groupToRadios.put( group, moduleRadio );
+            this.groupToCanvas.put( group, groupPanel );
+
+            moduleRadio.setValueMap(values);
+            
+            
+            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
@@ -217,13 +302,11 @@
     @Override
     protected Data[] getData() {
 
-        String module = radio.getValueAsString();
+        final Module module = selectedModule;
 
-        DataItem[] items = new DefaultDataItem[1];
-        items[0]         = new DefaultDataItem(module, module, module);
+        final DataItem[] items = new DefaultDataItem[] { new DefaultDataItem(module.getLocalizedName(), module.getLocalizedName(), module.getName()) };
 
-        Data       data  = new DefaultData("module", null, null, items);
-
+        final Data data  = new DefaultData("module", null, null, items);
         return new Data[] {data};
     }
 
@@ -236,10 +319,10 @@
     }-*/;
 
     private static String getSelectedModule() {
-        if (radio == null) {
+        if (selectedModule == null) {
             return null;
         }
-        return radio.getValueAsString();
+        return selectedModule.getName();
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org