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
This commit is contained in:
parent
31582c98f9
commit
8e37cf55ed
1 changed files with 81 additions and 8 deletions
|
|
@ -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 <option/> tags must be direct children of <param/>.
|
||||
|
|
@ -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 <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 @@ 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 ##
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue