# HG changeset patch # User souliane # Date 1396380621 -7200 # Node ID 5c7707c958d895cb324113e492d5ce2704b0b1e0 # Parent 75f3b3b430ff3959f541c3f9e5fea24079b4f869 tools, frontends (xmlui): add setter methods for widgets + new widget InternalButton to process UI operations diff -r 75f3b3b430ff -r 5c7707c958d8 frontends/src/primitivus/xmlui.py --- 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): diff -r 75f3b3b430ff -r 5c7707c958d8 frontends/src/tools/xmlui.py --- 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 diff -r 75f3b3b430ff -r 5c7707c958d8 frontends/src/wix/xmlui.py --- 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 diff -r 75f3b3b430ff -r 5c7707c958d8 src/tools/xml_tools.py --- 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'