Mercurial > libervia-backend
diff src/tools/xml_tools.py @ 1476:48706f4ff19c
core (xmlui): added JidsListWidget to manage editable list of jids:
- can be used to manage XEP-0004's jid-multi
- can be used in the future for search result to display found entities (need a read-only style)
- generaly usefull to manage list of entites
- implemented in params too
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 20 Aug 2015 18:33:52 +0200 |
parents | 7ac073d2e7e0 |
children | a77217511afd |
line wrap: on
line diff
--- a/src/tools/xml_tools.py Tue Aug 18 10:52:18 2015 +0200 +++ b/src/tools/xml_tools.py Thu Aug 20 18:33:52 2015 +0200 @@ -25,6 +25,7 @@ from xml.dom import minidom, NotFoundErr from wokkel import data_form from twisted.words.xish import domish +from twisted.words.protocols.jabber import jid from sat.core import exceptions @@ -254,6 +255,7 @@ @param xml (unicode) @return: XMLUI """ + # TODO: refactor params and use Twisted directly to parse XML params_doc = minidom.parseString(xml.encode('utf-8')) top = params_doc.documentElement if top.nodeName != 'params': @@ -281,9 +283,11 @@ callback_id = param.getAttribute('callback_id') or None if type_ == 'list': - options, selected = _getParamListOptions(param) + options, selected = _paramsGetListOptions(param) widget_kwargs['options'] = options widget_kwargs['selected'] = selected + elif type_ == 'jids_list': + widget_kwargs['jids'] = _paramsGetListJids(param) if type_ in ("button", "text"): param_ui.addEmpty() @@ -308,7 +312,7 @@ return param_ui.toXml() -def _getParamListOptions(param): +def _paramsGetListOptions(param): """Retrieve the options for list element. The <option/> tags must be direct children of <param/>. @@ -324,8 +328,21 @@ selected = [elem.getAttribute("value") for elem in elems if elem.getAttribute("selected") == 'true'] return (options, selected) +def _paramsGetListJids(param): + """Retrive jids from a jids_list element. -## XMLUI Elements + the <jid/> tags must be direct children of <param/> + @param param (domish.Element): element + @return: a list of jids + """ + elems = param.getElementsByTagName("jid") + jids = [elem.firstChild.data for elem in elems + if elem.firstChild is not None + and elem.firstChild.nodeType == elem.TEXT_NODE] + return jids + + +### XMLUI Elements ### class Element(object): @@ -427,6 +444,26 @@ self.elem.setAttribute('selected', 'true') +class JidElement(Element): + """" Used by JidsListWidget to specify jids""" + type = 'jid' + + def __init__(self, parent, jid_): + """ + @param jid_(jid.JID, unicode): jid to append + """ + assert isinstance(parent, JidsListWidget) + super(JidElement, self).__init__(parent.xmlui, parent) + if isinstance(jid_, jid.JID): + value = jid.full + elif isinstance(jid_, basestring): + value = unicode(jid_) + else: + raise NotImplementedError + jid_txt = self.xmlui.doc.createTextNode(value) + self.elem.appendChild(jid_txt) + + class RowElement(Element): """" Used by AdvancedListContainer """ type = 'row' @@ -462,6 +499,9 @@ self.elem.setAttribute('description', description) +## Containers ## + + class Container(Element): """ And Element which contains other ones and has a layout """ type = None @@ -603,6 +643,9 @@ self.xmlui.changeContainer(parent_container) +## Widgets ## + + class Widget(Element): type = None @@ -798,7 +841,7 @@ class ListWidget(InputWidget): type = 'list' - def __init__(self, xmlui, options, selected=None, style=None, name=None, parent=None): + def __init__(self, xmlui, options, selected=None, styles=None, name=None, parent=None): """ @param xmlui @@ -806,13 +849,15 @@ - a single string if the label and the value are the same - a tuple with a couple of string (value,label) if the label and the value differ @param selected (list[string]): list of the selected values - @param style (string) + @param styles (iterable[string]): flags to set the behaviour of the list @param name (string) @param parent """ - if style is None: - style = set() - styles = set(style) + styles = set() if styles is None else set(styles) + if styles is None: + styles = set() + else: + styles = set(styles) if not options: log.warning(_('empty "options" list')) if not styles.issubset(['multi']): @@ -834,6 +879,34 @@ value = option if isinstance(option, basestring) else option[0] OptionElement(self, option, value in selected) +class JidsListWidget(InputWidget): + """A list of text or jids where elements can be added/removed or modified""" + type = 'jids_list' + + def __init__(self, xmlui, jids, styles=None, name=None, parent=None): + """ + + @param xmlui + @param jids (list[jid.JID]): base jids + @param styles (iterable[string]): flags to set the behaviour of the list + @param name (string) + @param parent + """ + super(JidsListWidget, self).__init__(xmlui, name, parent) + styles = set() if styles is None else set(styles) + if not styles.issubset([]): # TODO + raise exceptions.DataError(_("invalid styles")) + for style in styles: + self.elem.setAttribute(style, 'yes') + if not jids: + log.debug('empty jids list') + else: + self.addJids(jids) + + def addJids(self, jids): + for jid_ in jids: + JidElement(self, jid_) + ## Dialog Elements ##