comparison src/tools/xml_tools.py @ 2397:7fff98d64ab5

core (XMLUI), template(XMLUI): added flags to ListWidget: following flags have been added: - noselect: list selection is not allowed (options are the important data) - extensible: user can add elements to the list - reducible: user can remove elements from the list - inline: presentation hint: the list should be displayed horizontally
author Goffi <goffi@goffi.org>
date Fri, 27 Oct 2017 18:03:35 +0200
parents 2e05921df16a
children 3ff9d7a7fe71
comparison
equal deleted inserted replaced
2396:66baa687c682 2397:7fff98d64ab5
348 348
349 if type_ == 'list': 349 if type_ == 'list':
350 options, selected = _paramsGetListOptions(param) 350 options, selected = _paramsGetListOptions(param)
351 widget_kwargs['options'] = options 351 widget_kwargs['options'] = options
352 widget_kwargs['selected'] = selected 352 widget_kwargs['selected'] = selected
353 widget_kwargs['styles'] = ['extensible']
353 elif type_ == 'jids_list': 354 elif type_ == 'jids_list':
354 widget_kwargs['jids'] = _paramsGetListJids(param) 355 widget_kwargs['jids'] = _paramsGetListJids(param)
355 356
356 if type_ in ("button", "text"): 357 if type_ in ("button", "text"):
357 param_ui.addEmpty() 358 param_ui.addEmpty()
937 FieldBackElement(self, field) 938 FieldBackElement(self, field)
938 939
939 940
940 class ListWidget(InputWidget): 941 class ListWidget(InputWidget):
941 type = 'list' 942 type = 'list'
943 STYLES = (u'multi', u'noselect', u'extensible', u'reducible', u'inline')
942 944
943 def __init__(self, xmlui, options, selected=None, styles=None, name=None, parent=None): 945 def __init__(self, xmlui, options, selected=None, styles=None, name=None, parent=None):
944 """ 946 """
945 947
946 @param xmlui 948 @param xmlui
948 - a single string if the label and the value are the same 950 - a single string if the label and the value are the same
949 - a tuple with a couple of string (value,label) if the label and the value differ 951 - a tuple with a couple of string (value,label) if the label and the value differ
950 @param selected (list[string]): list of the selected values 952 @param selected (list[string]): list of the selected values
951 @param styles (iterable[string]): flags to set the behaviour of the list 953 @param styles (iterable[string]): flags to set the behaviour of the list
952 can be: 954 can be:
953 - multi: mutliple selection is allowed 955 - multi: multiple selection is allowed
956 - noselect: no selection is allowed
957 useful when only the list itself is needed
958 - extensible: can be extended by user (i.e. new options can be added)
959 - reducible: can be reduced by user (i.e. options can be removed)
960 - inline: hint that this list should be displayed on a single line (e.g. list of labels)
954 @param name (string) 961 @param name (string)
955 @param parent 962 @param parent
956 """ 963 """
957 styles = set() if styles is None else set(styles) 964 styles = set() if styles is None else set(styles)
958 if styles is None: 965 if styles is None:
959 styles = set() 966 styles = set()
960 else: 967 else:
961 styles = set(styles) 968 styles = set(styles)
969 if u'noselect' in styles and (u'multi' in styles or selected):
970 raise exceptions.DataError(_(u'"multi" flag and "selected" option are not compatible with "noselect" flag'))
962 if not options: 971 if not options:
963 # we can have no options if we get a submitted data form 972 # we can have no options if we get a submitted data form
964 # but we can't use submitted values directly, 973 # but we can't use submitted values directly,
965 # because we would not have the labels 974 # because we would not have the labels
966 log.warning(_('empty "options" list')) 975 log.warning(_('empty "options" list'))
967 if not styles.issubset(['multi']):
968 raise exceptions.DataError(_("invalid styles"))
969 super(ListWidget, self).__init__(xmlui, name, parent) 976 super(ListWidget, self).__init__(xmlui, name, parent)
970 self.addOptions(options, selected) 977 self.addOptions(options, selected)
971 for style in styles: 978 self.setStyles(styles)
972 self.elem.setAttribute(style, 'yes')
973 979
974 def addOptions(self, options, selected=None): 980 def addOptions(self, options, selected=None):
975 """Add options to a multi-values element (e.g. list) """ 981 """Add options to a multi-values element (e.g. list) """
976 if selected: 982 if selected:
977 if isinstance(selected, basestring): 983 if isinstance(selected, basestring):
980 selected = [] 986 selected = []
981 for option in options: 987 for option in options:
982 assert isinstance(option, basestring) or isinstance(option, tuple) 988 assert isinstance(option, basestring) or isinstance(option, tuple)
983 value = option if isinstance(option, basestring) else option[0] 989 value = option if isinstance(option, basestring) else option[0]
984 OptionElement(self, option, value in selected) 990 OptionElement(self, option, value in selected)
991
992 def setStyles(self, styles):
993 if not styles.issubset(self.STYLES):
994 raise exceptions.DataError(_(u"invalid styles"))
995 for style in styles:
996 self.elem.setAttribute(style, 'yes')
997 # TODO: check flags incompatibily (noselect and multi) like in __init__
998
999 def setStyle(self, style):
1000 self.setStyles([style])
1001
985 1002
986 class JidsListWidget(InputWidget): 1003 class JidsListWidget(InputWidget):
987 """A list of text or jids where elements can be added/removed or modified""" 1004 """A list of text or jids where elements can be added/removed or modified"""
988 type = 'jids_list' 1005 type = 'jids_list'
989 1006