core (XMLUI): filters can now be used when converting data form to XMLUI:

they can be used to modify created widgets, this is specially useful to customise well known field.
This commit is contained in:
Goffi 2017-10-27 18:06:58 +02:00
commit 0a33ab2d1d

View file

@ -102,7 +102,7 @@ def _dataFormField2XMLUIData(field, read_only=False):
return widget_type, widget_args, widget_kwargs
def dataForm2Widgets(form_ui, form, read_only=False, prepend=None):
def dataForm2Widgets(form_ui, form, read_only=False, prepend=None, filters=None):
"""Complete an existing XMLUI with widget converted from XEP-0004 data forms.
@param form_ui (XMLUI): XMLUI instance
@ -111,6 +111,11 @@ def dataForm2Widgets(form_ui, form, read_only=False, prepend=None):
@param prepend(iterable, None): widgets to prepend to main LabelContainer
if not None, must be an iterable of *args for addWidget. Those widgets will
be added first to the container.
@param filters(dict, None): if not None, a dictionary of callable:
key is the name of the widget to filter
the value is a callable, it will get widget's type, args and kwargs
and must return the same variable, which it can modify
This is especially useful to modify well known fields
@return: the completed XMLUI instance
"""
if form.instructions:
@ -124,6 +129,12 @@ def dataForm2Widgets(form_ui, form, read_only=False, prepend=None):
for field in form.fieldList:
widget_type, widget_args, widget_kwargs = _dataFormField2XMLUIData(field, read_only)
try:
widget_filter = filters[widget_kwargs['name']]
except KeyError:
pass
else:
widget_type, widget_args, widget_kwargs = widget_filter(widget_type, widget_args, widget_kwargs)
label = field.label or field.var
if label:
form_ui.addLabel(label)
@ -235,7 +246,7 @@ def dataFormEltResult2XMLUI(form_elt, session_id=None):
dataForm2Widgets(xml_ui, parsed_form, read_only=True)
return xml_ui
def dataFormResult2XMLUI(result_form, base_form, session_id=None, prepend=None):
def dataFormResult2XMLUI(result_form, base_form, session_id=None, prepend=None, filters=None):
"""Convert data form result to SàT XMLUI.
@param result_form (data_form.Form): result form to convert
@ -243,6 +254,7 @@ def dataFormResult2XMLUI(result_form, base_form, session_id=None, prepend=None):
this one is necessary to reconstruct options when needed (e.g. list elements)
@param session_id (unicode): session id to return with the data
@param prepend: same as for [dataForm2Widgets]
@param filters: same as for [dataForm2Widgets]
@return: XMLUI instance
"""
form = deepcopy(result_form)
@ -253,7 +265,7 @@ def dataFormResult2XMLUI(result_form, base_form, session_id=None, prepend=None):
continue
field.options = base_field.options[:]
xml_ui = XMLUI("window", "vertical", session_id=session_id)
dataForm2Widgets(xml_ui, form, read_only=True, prepend=prepend)
dataForm2Widgets(xml_ui, form, read_only=True, prepend=prepend, filters=filters)
return xml_ui
@ -760,6 +772,9 @@ class Widget(Element):
super(Widget, self).__init__(xmlui, parent)
if name:
self.elem.setAttribute('name', name)
if name in xmlui.named_widgets:
raise exceptions.ConflictError(_(u'A widget with the name "{name}" already exists.').format(name=name))
xmlui.named_widgets[name] = self
self.elem.setAttribute('type', self.type)
def setInternalCallback(self, callback, fields, data_elts=None):
@ -1128,6 +1143,7 @@ class XMLUI(object):
@param title: title or default if None
@param submit_id: callback id to call for panel_type we can submit (form, param, dialog)
@param session_id: use to keep a session attached to the dialog, must be returned by frontends
@attribute named_widgets(dict): map from name to widget
"""
self._introspect() # FIXME: why doing that on each XMLUI ? should be done once
if panel_type not in [C.XMLUI_WINDOW, C.XMLUI_FORM, C.XMLUI_PARAM, C.XMLUI_POPUP, C.XMLUI_DIALOG]:
@ -1155,6 +1171,7 @@ class XMLUI(object):
return
self.main_container = self._createContainer(container, TopElement(self))
self.current_container = self.main_container
self.named_widgets = {}
def _introspect(self):
""" Introspect module to find Widgets and Containers """