comparison frontends/src/tools/xmlui.py @ 2377:e50aee5caf33

frontends (xmlui): new _xmlui_for_name attribute: _xmlui_for_name is an attribute which can be set to Label widgets to indicate the name of the linked widget. This attribute is set automatically for LabelContainer. data argument in _parseChilds is now a dict (or None)
author Goffi <goffi@goffi.org>
date Mon, 16 Oct 2017 07:21:44 +0200
parents 825608d4eaf8
children a59f2abd970e
comparison
equal deleted inserted replaced
2376:825608d4eaf8 2377:e50aee5caf33
366 """Recursively parse childNodes of an element 366 """Recursively parse childNodes of an element
367 367
368 @param _xmlui_parent: widget container with '_xmluiAppend' method 368 @param _xmlui_parent: widget container with '_xmluiAppend' method
369 @param current_node: element from which childs will be parsed 369 @param current_node: element from which childs will be parsed
370 @param wanted: list of tag names that can be present in the childs to be SàT XMLUI compliant 370 @param wanted: list of tag names that can be present in the childs to be SàT XMLUI compliant
371 @param data: additionnal data which are needed in some cases 371 @param data(None, dict): additionnal data which are needed in some cases
372 """ 372 """
373 if data is None:
374 data = {}
373 for node in current_node.childNodes: 375 for node in current_node.childNodes:
374 if wanted and not node.nodeName in wanted: 376 if wanted and not node.nodeName in wanted:
375 raise InvalidXMLUI('Unexpected node: [%s]' % node.nodeName) 377 raise InvalidXMLUI('Unexpected node: [%s]' % node.nodeName)
376 378
377 if node.nodeName == "container": 379 if node.nodeName == "container":
380 # main container is not a VerticalContainer and we want one, so we create one to wrap it 382 # main container is not a VerticalContainer and we want one, so we create one to wrap it
381 _xmlui_parent = self.widget_factory.createVerticalContainer(self) 383 _xmlui_parent = self.widget_factory.createVerticalContainer(self)
382 self.main_cont = _xmlui_parent 384 self.main_cont = _xmlui_parent
383 if type_ == "tabs": 385 if type_ == "tabs":
384 cont = self.widget_factory.createTabsContainer(_xmlui_parent) 386 cont = self.widget_factory.createTabsContainer(_xmlui_parent)
385 self._parseChilds(_xmlui_parent, node, ('tab',), cont) 387 self._parseChilds(_xmlui_parent, node, ('tab',), {'tabs_cont': cont})
386 elif type_ == "vertical": 388 elif type_ == "vertical":
387 cont = self.widget_factory.createVerticalContainer(_xmlui_parent) 389 cont = self.widget_factory.createVerticalContainer(_xmlui_parent)
388 self._parseChilds(cont, node, ('widget', 'container')) 390 self._parseChilds(cont, node, ('widget', 'container'))
389 elif type_ == "pairs": 391 elif type_ == "pairs":
390 cont = self.widget_factory.createPairsContainer(_xmlui_parent) 392 cont = self.widget_factory.createPairsContainer(_xmlui_parent)
391 self._parseChilds(cont, node, ('widget', 'container')) 393 self._parseChilds(cont, node, ('widget', 'container'))
392 elif type_ == "label": 394 elif type_ == "label":
393 cont = self.widget_factory.createLabelContainer(_xmlui_parent) 395 cont = self.widget_factory.createLabelContainer(_xmlui_parent)
394 self._parseChilds(cont, node, ('widget', 'container')) 396 self._parseChilds(cont, node, ('widget', 'container'), {'current_label': None})
395 elif type_ == "advanced_list": 397 elif type_ == "advanced_list":
396 try: 398 try:
397 columns = int(node.getAttribute('columns')) 399 columns = int(node.getAttribute('columns'))
398 except (TypeError, ValueError): 400 except (TypeError, ValueError):
399 raise DataError("Invalid columns") 401 raise DataError("Invalid columns")
425 427
426 elif node.nodeName == 'tab': 428 elif node.nodeName == 'tab':
427 name = node.getAttribute('name') 429 name = node.getAttribute('name')
428 label = node.getAttribute('label') 430 label = node.getAttribute('label')
429 selected = C.bool(node.getAttribute('selected') or C.BOOL_FALSE) 431 selected = C.bool(node.getAttribute('selected') or C.BOOL_FALSE)
430 if not name or not isinstance(data, TabsContainer): 432 if not name or not 'tabs_cont' in data:
431 raise InvalidXMLUI 433 raise InvalidXMLUI
432 if self.type == 'param': 434 if self.type == 'param':
433 self._current_category = name #XXX: awful hack because params need category and we don't keep parent 435 self._current_category = name #XXX: awful hack because params need category and we don't keep parent
434 tab_cont = data 436 tab_cont = data['tabs_cont']
435 new_tab = tab_cont._xmluiAddTab(label or name, selected) 437 new_tab = tab_cont._xmluiAddTab(label or name, selected)
436 self._parseChilds(new_tab, node, ('widget', 'container')) 438 self._parseChilds(new_tab, node, ('widget', 'container'))
437 439
438 elif node.nodeName == 'row': 440 elif node.nodeName == 'row':
439 try: 441 try:
440 index = str(data['index']) 442 index = str(data['index'])
443 except KeyError:
444 index = node.getAttribute('index') or None
445 else:
441 data['index'] += 1 446 data['index'] += 1
442 except TypeError:
443 index = node.getAttribute('index') or None
444 _xmlui_parent._xmluiAddRow(index) 447 _xmlui_parent._xmluiAddRow(index)
445 self._parseChilds(_xmlui_parent, node, ('widget', 'container')) 448 self._parseChilds(_xmlui_parent, node, ('widget', 'container'))
446 449
447 elif node.nodeName == "widget": 450 elif node.nodeName == "widget":
448 name = node.getAttribute("name") 451 name = node.getAttribute("name")
452 value = getText(value_elt) 455 value = getText(value_elt)
453 else: 456 else:
454 value = node.getAttribute("value") if node.hasAttribute('value') else u'' 457 value = node.getAttribute("value") if node.hasAttribute('value') else u''
455 if type_=="empty": 458 if type_=="empty":
456 ctrl = self.widget_factory.createEmptyWidget(_xmlui_parent) 459 ctrl = self.widget_factory.createEmptyWidget(_xmlui_parent)
460 if 'current_label' in data:
461 data['current_label'] = None
457 elif type_=="text": 462 elif type_=="text":
458 ctrl = self.widget_factory.createTextWidget(_xmlui_parent, value) 463 ctrl = self.widget_factory.createTextWidget(_xmlui_parent, value)
459 elif type_=="label": 464 elif type_=="label":
460 ctrl = self.widget_factory.createLabelWidget(_xmlui_parent, value) 465 ctrl = self.widget_factory.createLabelWidget(_xmlui_parent, value)
466 if 'current_label' in data:
467 data['current_label'] = ctrl
461 elif type_=="jid": 468 elif type_=="jid":
462 ctrl = self.widget_factory.createJidWidget(_xmlui_parent, value) 469 ctrl = self.widget_factory.createJidWidget(_xmlui_parent, value)
463 elif type_=="divider": 470 elif type_=="divider":
464 style = node.getAttribute("style") or 'line' 471 style = node.getAttribute("style") or 'line'
465 ctrl = self.widget_factory.createDividerWidget(_xmlui_parent, style) 472 ctrl = self.widget_factory.createDividerWidget(_xmlui_parent, style)
513 520
514 elif type_ != 'text': 521 elif type_ != 'text':
515 callback = node.getAttribute("internal_callback") or None 522 callback = node.getAttribute("internal_callback") or None
516 if callback: 523 if callback:
517 fields = [field.getAttribute('name') for field in node.getElementsByTagName("internal_field")] 524 fields = [field.getAttribute('name') for field in node.getElementsByTagName("internal_field")]
518 data = self.getInternalCallbackData(callback, node) 525 cb_data = self.getInternalCallbackData(callback, node)
519 ctrl._xmlui_param_internal = (callback, fields, data) 526 ctrl._xmlui_param_internal = (callback, fields, cb_data)
520 if type_ == 'button': 527 if type_ == 'button':
521 ctrl._xmluiOnClick(self.onChangeInternal) 528 ctrl._xmluiOnClick(self.onChangeInternal)
522 else: 529 else:
523 ctrl._xmluiOnChange(self.onChangeInternal) 530 ctrl._xmluiOnChange(self.onChangeInternal)
524 531
525 ctrl._xmlui_name = name 532 ctrl._xmlui_name = name
526 _xmlui_parent._xmluiAppend(ctrl) 533 _xmlui_parent._xmluiAppend(ctrl)
534 if 'current_label' in data and not isinstance(ctrl, LabelWidget):
535 # this key is set in LabelContainer, when present
536 # we can associate the label with the widget it is labelling
537 data['current_label']._xmlui_for_name = name
527 538
528 else: 539 else:
529 raise NotImplementedError(_('Unknown tag [%s]') % node.nodeName) 540 raise NotImplementedError(_('Unknown tag [%s]') % node.nodeName)
530 541
531 def constructUI(self, parsed_dom, post_treat=None): 542 def constructUI(self, parsed_dom, post_treat=None):