comparison frontends/src/tools/xmlui.py @ 2540:3e03de7691ce

frontends (xmlui): added whitelist argument: when set whitelist indicate that only widgets (and their eventual labels) with names in this list are to be kept. This option is mutually exclusive with ignore.
author Goffi <goffi@goffi.org>
date Thu, 29 Mar 2018 09:03:19 +0200
parents 0046283a285d
children
comparison
equal deleted inserted replaced
2539:dcc77f23e370 2540:3e03de7691ce
19 19
20 from sat.core.i18n import _ 20 from sat.core.i18n import _
21 from sat.core.log import getLogger 21 from sat.core.log import getLogger
22 log = getLogger(__name__) 22 log = getLogger(__name__)
23 from sat_frontends.quick_frontend.constants import Const as C 23 from sat_frontends.quick_frontend.constants import Const as C
24 from sat.core.exceptions import DataError 24 from sat.core import exceptions
25 25
26 26
27 class_map = {} 27 class_map = {}
28 CLASS_PANEL = 'panel' 28 CLASS_PANEL = 'panel'
29 CLASS_DIALOG = 'dialog' 29 CLASS_DIALOG = 'dialog'
269 # must be called only if there is not update 269 # must be called only if there is not update
270 self._xmluiClose() 270 self._xmluiClose()
271 self.host.actionManager(data, profile=profile) 271 self.host.actionManager(data, profile=profile)
272 272
273 def _isAttrSet(self, name, node): 273 def _isAttrSet(self, name, node):
274 """Returnw widget boolean attribute status 274 """Return widget boolean attribute status
275 275
276 @param name: name of the attribute (e.g. "read_only") 276 @param name: name of the attribute (e.g. "read_only")
277 @param node: Node instance 277 @param node: Node instance
278 @return (bool): True if widget's attribute is set (C.BOOL_TRUE) 278 @return (bool): True if widget's attribute is set (C.BOOL_TRUE)
279 """ 279 """
332 332
333 333
334 class XMLUIPanel(XMLUIBase): 334 class XMLUIPanel(XMLUIBase):
335 """XMLUI Panel 335 """XMLUI Panel
336 336
337 New frontends can inherite this class to easily implement XMLUI 337 New frontends can inherit this class to easily implement XMLUI
338 @property widget_factory: factory to create frontend-specific widgets 338 @property widget_factory: factory to create frontend-specific widgets
339 @property dialog_factory: factory to create frontend-specific dialogs 339 @property dialog_factory: factory to create frontend-specific dialogs
340 """ 340 """
341 widget_factory = None 341 widget_factory = None
342 342
343 def __init__(self, host, parsed_dom, title=None, flags=None, callback=None, ignore=None, profile=C.PROF_KEY_NONE): 343 def __init__(self, host, parsed_dom, title=None, flags=None, callback=None, ignore=None, whitelist=None, profile=C.PROF_KEY_NONE):
344 """ 344 """
345
346 @param title(unicode, None): title of the
345 @property widgets(dict): widget name => widget map 347 @property widgets(dict): widget name => widget map
346 @property widget_value(ValueGetter): retrieve widget value from it's name 348 @property widget_value(ValueGetter): retrieve widget value from it's name
347 """ 349 """
348 super(XMLUIPanel, self).__init__(host, parsed_dom, title=title, flags=flags, callback=callback, profile=profile) 350 super(XMLUIPanel, self).__init__(host, parsed_dom, title=title, flags=flags, callback=callback, profile=profile)
349 self.ctrl_list = {} # input widget, used mainly for forms 351 self.ctrl_list = {} # input widget, used mainly for forms
351 self.widget_value = ValueGetter(self.widgets) 353 self.widget_value = ValueGetter(self.widgets)
352 self._main_cont = None 354 self._main_cont = None
353 if ignore is None: 355 if ignore is None:
354 ignore = [] 356 ignore = []
355 self._ignore = ignore 357 self._ignore = ignore
358 if whitelist is not None:
359 if ignore:
360 raise exceptions.InternalError('ignore and whitelist must not be used at the same time')
361 self._whitelist = whitelist
362 else:
363 self._whitelist = None
356 self.constructUI(parsed_dom) 364 self.constructUI(parsed_dom)
357 365
358 def escape(self, name): 366 def escape(self, name):
359 """Return escaped name for forms""" 367 """Return escaped name for forms"""
360 return u"%s%s" % (C.SAT_FORM_PREFIX, name) 368 return u"%s%s" % (C.SAT_FORM_PREFIX, name)
403 self._parseChilds(cont, node, ('widget', 'container'), {CURRENT_LABEL: None}) 411 self._parseChilds(cont, node, ('widget', 'container'), {CURRENT_LABEL: None})
404 elif type_ == "advanced_list": 412 elif type_ == "advanced_list":
405 try: 413 try:
406 columns = int(node.getAttribute('columns')) 414 columns = int(node.getAttribute('columns'))
407 except (TypeError, ValueError): 415 except (TypeError, ValueError):
408 raise DataError("Invalid columns") 416 raise exceptions.DataError("Invalid columns")
409 selectable = node.getAttribute('selectable') or 'no' 417 selectable = node.getAttribute('selectable') or 'no'
410 auto_index = node.getAttribute('auto_index') == C.BOOL_TRUE 418 auto_index = node.getAttribute('auto_index') == C.BOOL_TRUE
411 data = {'index': 0} if auto_index else None 419 data = {'index': 0} if auto_index else None
412 cont = self.widget_factory.createAdvancedListContainer(_xmlui_parent, columns, selectable) 420 cont = self.widget_factory.createAdvancedListContainer(_xmlui_parent, columns, selectable)
413 callback_id = node.getAttribute("callback") or None 421 callback_id = node.getAttribute("callback") or None
454 _xmlui_parent._xmluiAddRow(index) 462 _xmlui_parent._xmluiAddRow(index)
455 self._parseChilds(_xmlui_parent, node, ('widget', 'container')) 463 self._parseChilds(_xmlui_parent, node, ('widget', 'container'))
456 464
457 elif node.nodeName == "widget": 465 elif node.nodeName == "widget":
458 name = node.getAttribute("name") 466 name = node.getAttribute("name")
459 if name in self._ignore: 467 if name and (name in self._ignore or self._whitelist is not None and name not in self._whitelist):
460 # current widget is ignored, but there may be already a label 468 # current widget is ignored, but there may be already a label
461 if CURRENT_LABEL in data: 469 if CURRENT_LABEL in data:
462 # if so, we remove it from parent 470 # if so, we remove it from parent
463 _xmlui_parent._xmluiRemove(data.pop(CURRENT_LABEL)) 471 _xmlui_parent._xmluiRemove(data.pop(CURRENT_LABEL))
464 continue 472 continue
809 """ 817 """
810 assert type_ in (CLASS_PANEL, CLASS_DIALOG) 818 assert type_ in (CLASS_PANEL, CLASS_DIALOG)
811 class_map[type_] = class_ 819 class_map[type_] = class_
812 820
813 821
814 def create(host, xml_data, title=None, flags=None, dom_parse=None, dom_free=None, callback=None, ignore=None, profile=C.PROF_KEY_NONE): 822 def create(host, xml_data, title=None, flags=None, dom_parse=None, dom_free=None, callback=None, ignore=None, whitelist=None, profile=C.PROF_KEY_NONE):
815 """ 823 """
816 @param dom_parse: methode equivalent to minidom.parseString (but which must manage unicode), or None to use default one 824 @param dom_parse: methode equivalent to minidom.parseString (but which must manage unicode), or None to use default one
817 @param dom_free: method used to free the parsed DOM 825 @param dom_free: method used to free the parsed DOM
818 @param ignore(list[unicode], None): name of widgets to ignore 826 @param ignore(list[unicode], None): name of widgets to ignore
819 widgets with name in this list and their label will be ignored 827 widgets with name in this list and their label will be ignored
828 @param whitelist(list[unicode], None): name of widgets to keep
829 when not None, only widgets in this list and their label will be kept
830 mutually exclusive with ignore
820 """ 831 """
821 if dom_parse is None: 832 if dom_parse is None:
822 from xml.dom import minidom 833 from xml.dom import minidom
823 dom_parse = lambda xml_data: minidom.parseString(xml_data.encode('utf-8')) 834 dom_parse = lambda xml_data: minidom.parseString(xml_data.encode('utf-8'))
824 dom_free = lambda parsed_dom: parsed_dom.unlink() 835 dom_free = lambda parsed_dom: parsed_dom.unlink()
839 xmlui = cls(host, parsed_dom, 850 xmlui = cls(host, parsed_dom,
840 title = title, 851 title = title,
841 flags = flags, 852 flags = flags,
842 callback = callback, 853 callback = callback,
843 ignore = ignore, 854 ignore = ignore,
855 whitelist = whitelist,
844 profile = profile) 856 profile = profile)
845 dom_free(parsed_dom) 857 dom_free(parsed_dom)
846 return xmlui 858 return xmlui