core, frontends (xmlui): added "hidden" widget, to specify a value to be returned unmodified

This commit is contained in:
Goffi 2018-08-31 15:57:11 +02:00
commit 14fd4252eb
2 changed files with 57 additions and 35 deletions

View file

@ -78,6 +78,8 @@ def _dataFormField2XMLUIData(field, read_only=False):
widget_type = "textbox"
widget_args[0] = u"\n".join(field.values)
widget_kwargs["read_only"] = read_only
elif field.fieldType == "hidden":
widget_type = "hidden"
elif field.fieldType == "text-private":
widget_type = "password"
widget_kwargs["read_only"] = read_only
@ -148,11 +150,12 @@ def dataForm2Widgets(form_ui, form, read_only=False, prepend=None, filters=None)
widget_type, widget_args, widget_kwargs = widget_filter(
form_ui, widget_type, widget_args, widget_kwargs
)
label = field.label or field.var
if label:
form_ui.addLabel(label)
else:
form_ui.addEmpty()
if widget_type != "hidden":
label = field.label or field.var
if label:
form_ui.addLabel(label)
else:
form_ui.addEmpty()
form_ui.addWidget(widget_type, *widget_args, **widget_kwargs)
@ -902,7 +905,6 @@ class LabelWidget(Widget):
used most of time to display the desciption or name of the next widget
"""
type = "label"
def __init__(self, xmlui, label, name=None, parent=None):
@ -910,6 +912,22 @@ class LabelWidget(Widget):
self.elem.setAttribute("value", label)
class HiddenWidget(Widget):
"""Not displayed widget, frontends will just copy the value(s)"""
type = "hidden"
def __init__(self, xmlui, value, name, parent=None):
super(HiddenWidget, self).__init__(xmlui, name, parent)
value_elt = self.xmlui.doc.createElement("value")
text = self.xmlui.doc.createTextNode(value)
value_elt.appendChild(text)
self.elem.appendChild(value_elt)
@property
def value(self):
return self.elem.firstChild.firstChild.wholeText
class JidWidget(Widget):
"""Used to display a Jabber ID, some specific methods can be added"""

View file

@ -29,6 +29,7 @@ class_map = {}
CLASS_PANEL = "panel"
CLASS_DIALOG = "dialog"
CURRENT_LABEL = "current_label"
HIDDEN = "hidden"
class InvalidXMLUI(Exception):
@ -261,15 +262,8 @@ class XMLUIBase(object):
This class must not be instancied directly
"""
def __init__(
self,
host,
parsed_dom,
title=None,
flags=None,
callback=None,
profile=C.PROF_KEY_NONE,
):
def __init__(self, host, parsed_dom, title=None, flags=None, callback=None,
profile=C.PROF_KEY_NONE):
"""Initialise the XMLUI instance
@param host: %(doc_host)s
@ -277,17 +271,22 @@ class XMLUIBase(object):
@param title: force the title, or use XMLUI one if None
@param flags: list of string which can be:
- NO_CANCEL: the UI can't be cancelled
- FROM_BACKEND: the UI come from backend (i.e. it's not the direct result of user operation)
- FROM_BACKEND: the UI come from backend (i.e. it's not the direct result of
user operation)
@param callback(callable, None): if not None, will be used with launchAction:
- if None is used, default behaviour will be used (closing the dialog and calling host.actionManager)
- if None is used, default behaviour will be used (closing the dialog and
calling host.actionManager)
- if a callback is provided, it will be used instead, so you'll have to manage
dialog closing or new xmlui to display, or other action (you can call host.actionManager)
dialog closing or new xmlui to display, or other action (you can call
host.actionManager)
The callback will have data, callback_id and profile as arguments
"""
self.host = host
top = parsed_dom.documentElement
self.session_id = top.getAttribute("session_id") or None
self.submit_id = top.getAttribute("submit") or None
self.xmlui_title = title or top.getAttribute("title") or u""
self.hidden = {}
if flags is None:
flags = []
self.flags = flags
@ -333,7 +332,8 @@ class XMLUIBase(object):
raise ValueError("Can't submit is self.submit_id is not set")
if "session_id" in data:
raise ValueError(
"session_id must no be used in data, it is automaticaly filled with self.session_id if present"
u"session_id must no be used in data, it is automaticaly filled with "
u"self.session_id if present"
)
if self.session_id is not None:
data["session_id"] = self.session_id
@ -379,17 +379,8 @@ class XMLUIPanel(XMLUIBase):
widget_factory = None
def __init__(
self,
host,
parsed_dom,
title=None,
flags=None,
callback=None,
ignore=None,
whitelist=None,
profile=C.PROF_KEY_NONE,
):
def __init__(self, host, parsed_dom, title=None, flags=None, callback=None,
ignore=None, whitelist=None, profile=C.PROF_KEY_NONE):
"""
@param title(unicode, None): title of the
@ -416,7 +407,8 @@ class XMLUIPanel(XMLUIBase):
self._whitelist = None
self.constructUI(parsed_dom)
def escape(self, name):
@staticmethod
def escape(name):
"""Return escaped name for forms"""
return u"%s%s" % (C.SAT_FORM_PREFIX, name)
@ -435,7 +427,8 @@ class XMLUIPanel(XMLUIBase):
@param _xmlui_parent: widget container with '_xmluiAppend' method
@param current_node: element from which childs will be parsed
@param wanted: list of tag names that can be present in the childs to be SàT XMLUI compliant
@param wanted: list of tag names that can be present in the childs to be SàT XMLUI
compliant
@param data(None, dict): additionnal data which are needed in some cases
"""
for node in current_node.childNodes:
@ -447,7 +440,8 @@ class XMLUIPanel(XMLUIBase):
if node.nodeName == "container":
type_ = node.getAttribute("type")
if _xmlui_parent is self and type_ != "vertical":
# main container is not a VerticalContainer and we want one, so we create one to wrap it
# main container is not a VerticalContainer and we want one,
# so we create one to wrap it
_xmlui_parent = self.widget_factory.createVerticalContainer(self)
self.main_cont = _xmlui_parent
if type_ == "tabs":
@ -557,6 +551,12 @@ class XMLUIPanel(XMLUIBase):
elif type_ == "label":
ctrl = self.widget_factory.createLabelWidget(_xmlui_parent, value)
data[CURRENT_LABEL] = ctrl
elif type_ == "hidden":
if name in self.hidden:
raise exceptions.ConflictError(u"Conflict on hidden value with "
u"name {name}".format(name=name))
self.hidden[name] = value
continue
elif type_ == "jid":
ctrl = self.widget_factory.createJidWidget(_xmlui_parent, value)
elif type_ == "divider":
@ -650,7 +650,8 @@ class XMLUIPanel(XMLUIBase):
except (
AttributeError,
TypeError,
): # XXX: TypeError is here because pyjamas raise a TypeError instead of an AttributeError
): # XXX: TypeError is here because pyjamas raise a TypeError instead
# of an AttributeError
if not isinstance(
ctrl, (EmptyWidget, TextWidget, LabelWidget, JidWidget)
):
@ -857,8 +858,11 @@ class XMLUIPanel(XMLUIBase):
)
else:
selected_values.append((escaped, ctrl["control"]._xmluiGetValue()))
data = dict(selected_values)
for key, value in self.hidden.iteritems():
data[self.escape(key)] = value
if self.submit_id is not None:
data = dict(selected_values)
self.submit(data)
else:
log.warning(