diff src/tools/xml_tools.py @ 968:75f3b3b430ff

tools, frontends, memory: param definition and XMLUI handle multi-selection for list widgets: - we need to update urwid_satext to revision 79 - no more "value" attribute value in the "list" element, use HTML-style "select" attribute in the "option" elements instead - /!\ param saving do not handle multiple values yet!
author souliane <souliane@mailoo.org>
date Tue, 01 Apr 2014 21:21:13 +0200
parents 9754c0ebadba
children 5c7707c958d8
line wrap: on
line diff
--- a/src/tools/xml_tools.py	Tue Apr 01 16:27:59 2014 +0200
+++ b/src/tools/xml_tools.py	Tue Apr 01 21:21:13 2014 +0200
@@ -207,8 +207,9 @@
             callback_id = param.getAttribute('callback_id') or None
 
             if type_ == 'list':
-                options = _getParamListOptions(param)
+                options, selected = _getParamListOptions(param)
                 widget_kwargs['options'] = options
+                widget_kwargs['selected'] = selected
 
             if type_ in ("button", "text"):
                 param_ui.addEmpty()
@@ -230,16 +231,16 @@
 
 
 def _getParamListOptions(param):
-    """Retrieve the options for list element. Allow listing the <option/>
-    tags directly in <param/> or in an intermediate <options/> tag."""
-    elems = param.getElementsByTagName("options")
-    if len(elems) == 0:
-        elems = param.getElementsByTagName("option")
-    else:
-        elems = elems.item(0).getElementsByTagName("option")
+    """Retrieve the options for list element. The <option/> tags
+    must be direct children of <param/>."""
+    if len(param.getElementsByTagName("options")) > 0:
+        raise exceptions.DataError(_("The 'options' tag is not allowed in parameter of type 'list'!"))
+    elems = param.getElementsByTagName("option")
     if len(elems) == 0:
         return []
-    return [elem.getAttribute("value") for elem in elems]
+    options = [elem.getAttribute("value") for elem in elems]
+    selected = [elem.getAttribute("value") for elem in elems if elem.getAttribute("selected") == 'true']
+    return  (options, selected)
 
 
 ## XMLUI Elements
@@ -302,7 +303,13 @@
     """" Used by ListWidget to specify options """
     type = 'option'
 
-    def __init__(self, parent, option):
+    def __init__(self, parent, option, selected=False):
+        """
+
+        @param parent
+        @param option (string, tuple)
+        @param selected (boolean)
+        """
         assert(isinstance(parent, ListWidget))
         super(OptionElement, self).__init__(parent.xmlui, parent)
         if isinstance(option, basestring):
@@ -311,6 +318,8 @@
             value, label = option
         self.elem.setAttribute('value', value)
         self.elem.setAttribute('label', label)
+        if selected:
+            self.elem.setAttribute('selected', 'true')
 
 
 class RowElement(Element):
@@ -609,13 +618,24 @@
         if value:
             self.elem.setAttribute('value', value)
         for field in fields_back:
-            fback_el = FieldBackElement(self, field)
+            FieldBackElement(self, field)
 
 
 class ListWidget(InputWidget):
     type = 'list'
 
-    def __init__(self, xmlui, options, value=None, style=None, name=None, parent=None):
+    def __init__(self, xmlui, options, selected=None, style=None, name=None, parent=None):
+        """
+
+        @param xmlui
+        @param options (list[string, tuple]): each option can be given as:
+                                              - a string if the label and the value are the same
+                                              - a couple if the label and the value differ
+        @param selected (list[string]): list of the selected values
+        @param style (string)
+        @param name (string)
+        @param parent
+        """
         if style is None:
             style = set()
         styles = set(style)
@@ -624,16 +644,19 @@
         if not styles.issubset(['multi']):
             raise exceptions.DataError(_("invalid styles"))
         super(ListWidget, self).__init__(xmlui, name, parent)
-        self.addOptions(options)
-        if value:
-            self.elem.setAttribute('value', value)
+        self.addOptions(options, selected)
         for style in styles:
             self.elem.setAttribute(style, 'yes')
 
-    def addOptions(self, options):
-        """i Add options to a multi-values element (e.g. list) """
+    def addOptions(self, options, selected=None):
+        """Add options to a multi-values element (e.g. list) """
+        if selected:
+            if isinstance(selected, basestring):
+                selected = [selected]
+        else:
+            selected = []
         for option in options:
-            OptionElement(self, option)
+            OptionElement(self, option, option in selected)
 
 
 ## XMLUI main class