changeset 969:5c7707c958d8

tools, frontends (xmlui): add setter methods for widgets + new widget InternalButton to process UI operations
author souliane <souliane@mailoo.org>
date Tue, 01 Apr 2014 21:30:21 +0200 (2014-04-01)
parents 75f3b3b430ff
children 2e052998c7eb
files frontends/src/primitivus/xmlui.py frontends/src/tools/xmlui.py frontends/src/wix/xmlui.py src/tools/xml_tools.py
diffstat 4 files changed, 119 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/src/primitivus/xmlui.py	Tue Apr 01 21:21:13 2014 +0200
+++ b/frontends/src/primitivus/xmlui.py	Tue Apr 01 21:30:21 2014 +0200
@@ -19,6 +19,7 @@
 
 from sat.core.i18n import _
 import urwid
+import copy
 from urwid_satext import sat_widgets
 from logging import debug, info, warning, error
 from xml.dom import minidom
@@ -78,11 +79,15 @@
 
         urwid.Divider.__init__(self, div_char)
 
+
 class PrimitivusStringWidget(xmlui.StringWidget, sat_widgets.AdvancedEdit, PrimitivusEvents):
 
     def __init__(self, parent, value):
         sat_widgets.AdvancedEdit.__init__(self, edit_text=value)
 
+    def _xmluiSetValue(self, value):
+        self.set_edit_text(value)
+
     def _xmluiGetValue(self):
         return self.get_edit_text()
 
@@ -92,6 +97,9 @@
     def __init__(self, parent, value):
         sat_widgets.Password.__init__(self, edit_text=value)
 
+    def _xmluiSetValue(self, value):
+        self.set_edit_text(value)
+
     def _xmluiGetValue(self):
         return self.get_edit_text()
 
@@ -101,6 +109,9 @@
     def __init__(self, parent, value):
         sat_widgets.AdvancedEdit.__init__(self, edit_text=value, multiline=True)
 
+    def _xmluiSetValue(self, value):
+        self.set_edit_text(value)
+
     def _xmluiGetValue(self):
         return self.get_edit_text()
 
@@ -110,6 +121,9 @@
     def __init__(self, parent, state):
         urwid.CheckBox.__init__(self, '', state=state)
 
+    def _xmluiSetValue(self, value):
+        self.set_state(value == "true")
+
     def _xmluiGetValue(self):
         return "true" if self.get_state() else "false"
 
@@ -135,6 +149,21 @@
     def _xmluiGetSelectedValues(self):
         return [option.value for option in self.getSelectedValues()]
 
+    def _xmluiAddValues(self, values, select=True):
+        current_values = self.getAllValues()
+        new_values = copy.deepcopy(current_values)
+        for value in values:
+            if value not in current_values:
+                new_values.append(value)
+        if select:
+            selected = self._xmluiGetSelectedValues()
+        self.changeValues(new_values)
+        if select:
+            for value in values:
+                if value not in selected:
+                    selected.append(value)
+            self._xmluiSelectValues(selected)
+
 
 class PrimitivusAdvancedListContainer(xmlui.AdvancedListContainer, sat_widgets.TableContainer, PrimitivusEvents):
 
--- a/frontends/src/tools/xmlui.py	Tue Apr 01 21:21:13 2014 +0200
+++ b/frontends/src/tools/xmlui.py	Tue Apr 01 21:30:21 2014 +0200
@@ -311,6 +311,10 @@
                     callback_id = node.getAttribute("callback")
                     ctrl = self.widget_factory.createButtonWidget(parent, value, self.onButtonPress)
                     ctrl._xmlui_param_id = (callback_id, [field.getAttribute('name') for field in node.getElementsByTagName("field_back")])
+                elif type_ == "internal_button":
+                    action = node.getAttribute("action")
+                    ctrl = self.widget_factory.createButtonWidget(parent, value, self.onInternalButtonPress)
+                    ctrl._xmlui_param_id = (action, [field.getAttribute('name') for field in node.getElementsByTagName("internal_field")])
                 else:
                     print(_("FIXME FIXME FIXME: widget type [%s] is not implemented") % type_)
                     raise NotImplementedError(_("FIXME FIXME FIXME: type [%s] is not implemented") % type_)
@@ -413,6 +417,39 @@
                 data[escaped] = ctrl['control']._xmluiGetValue()
         self._xmluiLaunchAction(callback_id, data)
 
+    def onInternalButtonPress(self, button):
+        """ Called when an internal XMLUI button is clicked
+        Do the processing associated to the button
+        @param button: the button clicked
+
+        """
+        action, fields = button._xmlui_param_id
+        if action not in ('copy', 'move'):
+            raise NotImplementedError(_("FIXME: XMLUI internal action [%s] is not implemented") % action)
+        source = None
+        for field in fields:
+            widget = self.ctrl_list[field]['control']
+            if not source:
+                source = widget
+                continue
+            if isinstance(widget, ListWidget):
+                if isinstance(source, ListWidget):
+                    values = source._xmluiGetSelectedValues()
+                else:
+                    values = [source._xmluiGetValue()]
+                    if action == 'move':
+                        source._xmluiSetValue('')
+                widget._xmluiAddValues(values, select=True)
+            else:
+                if isinstance(source, ListWidget):
+                    value = u', '.join(source._xmluiGetSelectedValues())
+                else:
+                    value = source._xmluiGetValue()
+                    if action == 'move':
+                        source._xmluiSetValue('')
+                widget._xmluiSetValue(value)
+            source = None
+
     def onFormSubmitted(self, ignore=None):
         """ An XMLUI form has been submited
         call the submit action associated with this form
--- a/frontends/src/wix/xmlui.py	Tue Apr 01 21:21:13 2014 +0200
+++ b/frontends/src/wix/xmlui.py	Tue Apr 01 21:30:21 2014 +0200
@@ -42,6 +42,10 @@
 
 
 class ValueWidget(WixWidget):
+
+    def _xmluiSetValue(self, value):
+        self.SetValue(value)
+
     def _xmluiGetValue(self):
         return self.GetValue()
 
@@ -106,6 +110,9 @@
         self.SetValue(state)
         self._xmlui_proportion = 1
 
+    def _xmluiSetValue(self, value):
+        self.SetValue(value == 'true')
+
     def _xmluiGetValue(self):
         return "true" if self.GetValue() else "false"
 
@@ -153,6 +160,11 @@
             ret.append(self._xmlui_attr_map[label])
         return ret
 
+    def _xmluiAddValues(self, values, select=True):
+        wx.ListBox.AppendItems(values)
+        if select:
+            self._xmluiSelectValues(values)
+
 
 class WixContainer(object):
     _xmlui_proportion = 1
--- a/src/tools/xml_tools.py	Tue Apr 01 21:21:13 2014 +0200
+++ b/src/tools/xml_tools.py	Tue Apr 01 21:30:21 2014 +0200
@@ -299,6 +299,16 @@
         self.elem.setAttribute('name', name)
 
 
+class InternalFieldElement(Element):
+    """ Used by InternalButtonWidget to indicate which field are manipulated by internal action """
+    type = 'internal_field'
+
+    def __init__(self, parent, name):
+        assert(isinstance(parent, InternalButtonWidget))
+        super(InternalFieldElement, self).__init__(parent.xmlui, parent)
+        self.elem.setAttribute('name', name)
+
+
 class OptionElement(Element):
     """" Used by ListWidget to specify options """
     type = 'option'
@@ -621,6 +631,37 @@
             FieldBackElement(self, field)
 
 
+class InternalButtonWidget(Widget):
+    type = 'internal_button'
+
+    def __init__(self, xmlui, action='copy', value=None, fields=None, name=None, parent=None):
+        """Add an button to process internal UI operations.
+
+        The internal button is not associated to any callback id because it is
+        not using the bridge (no communication with the backend).
+
+        @param action (string): a value from:
+                                - 'copy': process the widgets given in 'fields'
+                                  two by two, by copying the values of one widget
+                                  to the other.
+                                - 'move': same than copy but moves the values
+                                          if the source widget is not a List.
+                                - more operation to be added when necessary...
+        @param value (string): label of the button
+        @param fields (list): a list of widget name (string)
+        @param name: name
+        @param parent: parent container
+        """
+        if fields is None:
+            fields = []
+        super(InternalButtonWidget, self).__init__(xmlui, name, parent)
+        self.elem.setAttribute('action', action)
+        if value:
+            self.elem.setAttribute('value', value)
+        for field in fields:
+            InternalFieldElement(self, field)
+
+
 class ListWidget(InputWidget):
     type = 'list'