diff --git a/src/tools/xml_tools.py b/src/tools/xml_tools.py
index ac03cf1f..d02aacf8 100644
--- a/src/tools/xml_tools.py
+++ b/src/tools/xml_tools.py
@@ -25,6 +25,7 @@ log = getLogger(__name__)
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 @@ def paramsXML2XMLUI(xml):
@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 @@ def paramsXML2XMLUI(xml):
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 @@ def paramsXML2XMLUI(xml):
return param_ui.toXml()
-def _getParamListOptions(param):
+def _paramsGetListOptions(param):
"""Retrieve the options for list element.
The tags must be direct children of .
@@ -324,8 +328,21 @@ def _getParamListOptions(param):
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 tags must be direct children of
+ @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 @@ class OptionElement(Element):
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 @@ class HeaderElement(Element):
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 @@ class AdvancedListContainer(Container):
self.xmlui.changeContainer(parent_container)
+## Widgets ##
+
+
class Widget(Element):
type = None
@@ -798,7 +841,7 @@ class ButtonWidget(Widget):
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 @@ class ListWidget(InputWidget):
- 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 @@ class ListWidget(InputWidget):
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 ##