# HG changeset patch # User Goffi # Date 1535723831 -7200 # Node ID c274201cea940e09f3ba105a321648187e3cdb90 # Parent 8dd9db785ac81166b3e06f61ed942dbb7f9197ac core, frontends (xmlui): added "hidden" widget, to specify a value to be returned unmodified diff -r 8dd9db785ac8 -r c274201cea94 sat/tools/xml_tools.py --- a/sat/tools/xml_tools.py Fri Aug 31 15:47:00 2018 +0200 +++ b/sat/tools/xml_tools.py Fri Aug 31 15:57:11 2018 +0200 @@ -78,6 +78,8 @@ 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 @@ 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 @@ 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 @@ 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""" diff -r 8dd9db785ac8 -r c274201cea94 sat_frontends/tools/xmlui.py --- a/sat_frontends/tools/xmlui.py Fri Aug 31 15:47:00 2018 +0200 +++ b/sat_frontends/tools/xmlui.py Fri Aug 31 15:57:11 2018 +0200 @@ -29,6 +29,7 @@ CLASS_PANEL = "panel" CLASS_DIALOG = "dialog" CURRENT_LABEL = "current_label" +HIDDEN = "hidden" class InvalidXMLUI(Exception): @@ -261,15 +262,8 @@ 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 @@ @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 @@ 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 @@ 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 @@ 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 @@ @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 @@ 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 @@ 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 @@ 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 @@ ) 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(