comparison frontends/src/tools/xmlui.py @ 1367:f71a0fc26886

merged branch frontends_multi_profiles
author Goffi <goffi@goffi.org>
date Wed, 18 Mar 2015 10:52:28 +0100
parents 35f99c90b736
children 069ad98b360d
comparison
equal deleted inserted replaced
1295:1e3b1f9ad6e2 1367:f71a0fc26886
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
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.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.exceptions import DataError
25 25
26 26
27 class_map = {} 27 class_map = {}
28 CLASS_PANEL = 'panel' 28 CLASS_PANEL = 'panel'
200 """Base class to construct SàT XML User Interface 200 """Base class to construct SàT XML User Interface
201 201
202 This class must not be instancied directly 202 This class must not be instancied directly
203 """ 203 """
204 204
205 def __init__(self, host, parsed_dom, title = None, flags = None): 205 def __init__(self, host, parsed_dom, title=None, flags=None, callback=None, profile=C.PROF_KEY_NONE):
206 """Initialise the XMLUI instance 206 """Initialise the XMLUI instance
207 207
208 @param host: %(doc_host)s 208 @param host: %(doc_host)s
209 @param parsed_dom: main parsed dom 209 @param parsed_dom: main parsed dom
210 @param title: force the title, or use XMLUI one if None 210 @param title: force the title, or use XMLUI one if None
211 @param flags: list of string which can be: 211 @param flags: list of string which can be:
212 - NO_CANCEL: the UI can't be cancelled 212 - NO_CANCEL: the UI can't be cancelled
213 @param callback: if present, will be used with launchAction
213 """ 214 """
214 self.host = host 215 self.host = host
215 top=parsed_dom.documentElement 216 top=parsed_dom.documentElement
216 self.session_id = top.getAttribute("session_id") or None 217 self.session_id = top.getAttribute("session_id") or None
217 self.submit_id = top.getAttribute("submit") or None 218 self.submit_id = top.getAttribute("submit") or None
218 self.title = title or top.getAttribute("title") or u"" 219 self.xmlui_title = title or top.getAttribute("title") or u""
219 if flags is None: 220 if flags is None:
220 flags = [] 221 flags = []
221 self.flags = flags 222 self.flags = flags
223 self.callback = callback
224 self.profile = profile
222 225
223 def _isAttrSet(self, name, node): 226 def _isAttrSet(self, name, node):
224 """Returnw widget boolean attribute status 227 """Returnw widget boolean attribute status
225 228
226 @param name: name of the attribute (e.g. "read_only") 229 @param name: name of the attribute (e.g. "read_only")
251 if self.session_id is not None: 254 if self.session_id is not None:
252 data["session_id"] = self.session_id 255 data["session_id"] = self.session_id
253 self._xmluiLaunchAction(self.submit_id, data) 256 self._xmluiLaunchAction(self.submit_id, data)
254 257
255 def _xmluiLaunchAction(self, action_id, data): 258 def _xmluiLaunchAction(self, action_id, data):
256 self.host.launchAction(action_id, data, profile_key = self.host.profile) 259 self.host.launchAction(action_id, data, callback=self.callback, profile=self.profile)
257 260
258 261
259 class XMLUIPanel(XMLUIBase): 262 class XMLUIPanel(XMLUIBase):
260 """XMLUI Panel 263 """XMLUI Panel
261 264
263 @property widget_factory: factory to create frontend-specific widgets 266 @property widget_factory: factory to create frontend-specific widgets
264 @proporety dialog_factory: factory to create frontend-specific dialogs 267 @proporety dialog_factory: factory to create frontend-specific dialogs
265 """ 268 """
266 widget_factory = None 269 widget_factory = None
267 270
268 def __init__(self, host, parsed_dom, title = None, flags = None): 271 def __init__(self, host, parsed_dom, title=None, flags=None, callback=None, profile=C.PROF_KEY_NONE):
269 super(XMLUIPanel, self).__init__(host, parsed_dom, title = None, flags = None) 272 super(XMLUIPanel, self).__init__(host, parsed_dom, title=title, flags=flags, callback=callback, profile=profile)
270 self.ctrl_list = {} # usefull to access ctrl 273 self.ctrl_list = {} # usefull to access ctrl
271 self._main_cont = None 274 self._main_cont = None
272 self.constructUI(parsed_dom) 275 self.constructUI(parsed_dom)
273 276
274 def escape(self, name): 277 def escape(self, name):
284 if self._main_cont is not None: 287 if self._main_cont is not None:
285 raise ValueError(_("XMLUI can have only one main container")) 288 raise ValueError(_("XMLUI can have only one main container"))
286 self._main_cont = value 289 self._main_cont = value
287 290
288 def _parseChilds(self, _xmlui_parent, current_node, wanted = ('container',), data = None): 291 def _parseChilds(self, _xmlui_parent, current_node, wanted = ('container',), data = None):
289 """Recursively parse childNodes of an elemen 292 """Recursively parse childNodes of an element
290 293
291 @param _xmlui_parent: widget container with '_xmluiAppend' method 294 @param _xmlui_parent: widget container with '_xmluiAppend' method
292 @param current_node: element from which childs will be parsed 295 @param current_node: element from which childs will be parsed
293 @param wanted: list of tag names that can be present in the childs to be SàT XMLUI compliant 296 @param wanted: list of tag names that can be present in the childs to be SàT XMLUI compliant
294 @param data: additionnal data which are needed in some cases 297 @param data: additionnal data which are needed in some cases
460 this method must be overrided 463 this method must be overrided
461 """ 464 """
462 raise NotImplementedError 465 raise NotImplementedError
463 466
464 def _xmluiSetParam(self, name, value, category): 467 def _xmluiSetParam(self, name, value, category):
465 self.host.bridge.setParam(name, value, category, profile_key=self.host.profile) 468 self.host.bridge.setParam(name, value, category, profile_key=self.profile)
466 469
467 ##EVENTS## 470 ##EVENTS##
468 471
469 def onParamChange(self, ctrl): 472 def onParamChange(self, ctrl):
470 """Called when type is param and a widget to save is modified 473 """Called when type is param and a widget to save is modified
637 640
638 641
639 class XMLUIDialog(XMLUIBase): 642 class XMLUIDialog(XMLUIBase):
640 dialog_factory = None 643 dialog_factory = None
641 644
642 def __init__(self, host, parsed_dom, title = None, flags = None): 645 def __init__(self, host, parsed_dom, title=None, flags=None, callback=None, profile=C.PROF_KEY_NONE):
643 super(XMLUIDialog, self).__init__(host, parsed_dom, title = None, flags = None) 646 super(XMLUIDialog, self).__init__(host, parsed_dom, title=None, flags=None, callback=callback, profile=C.PROF_KEY_NONE)
644 top=parsed_dom.documentElement 647 top=parsed_dom.documentElement
645 dlg_elt = self._getChildNode(top, "dialog") 648 dlg_elt = self._getChildNode(top, "dialog")
646 if dlg_elt is None: 649 if dlg_elt is None:
647 raise ValueError("Invalid XMLUI: no Dialog element found !") 650 raise ValueError("Invalid XMLUI: no Dialog element found !")
648 dlg_type = dlg_elt.getAttribute("type") or C.XMLUI_DIALOG_MESSAGE 651 dlg_type = dlg_elt.getAttribute("type") or C.XMLUI_DIALOG_MESSAGE
652 except (TypeError, AttributeError): # XXX: TypeError is here because pyjamas raise a TypeError instead of an AttributeError 655 except (TypeError, AttributeError): # XXX: TypeError is here because pyjamas raise a TypeError instead of an AttributeError
653 message = "" 656 message = ""
654 level = dlg_elt.getAttribute(C.XMLUI_DATA_LVL) or C.XMLUI_DATA_LVL_INFO 657 level = dlg_elt.getAttribute(C.XMLUI_DATA_LVL) or C.XMLUI_DATA_LVL_INFO
655 658
656 if dlg_type == C.XMLUI_DIALOG_MESSAGE: 659 if dlg_type == C.XMLUI_DIALOG_MESSAGE:
657 self.dlg = self.dialog_factory.createMessageDialog(self, self.title, message, level) 660 self.dlg = self.dialog_factory.createMessageDialog(self, self.xmlui_title, message, level)
658 elif dlg_type == C.XMLUI_DIALOG_NOTE: 661 elif dlg_type == C.XMLUI_DIALOG_NOTE:
659 self.dlg = self.dialog_factory.createNoteDialog(self, self.title, message, level) 662 self.dlg = self.dialog_factory.createNoteDialog(self, self.xmlui_title, message, level)
660 elif dlg_type == C.XMLUI_DIALOG_CONFIRM: 663 elif dlg_type == C.XMLUI_DIALOG_CONFIRM:
661 try: 664 try:
662 buttons_elt = self._getChildNode(dlg_elt, "buttons") 665 buttons_elt = self._getChildNode(dlg_elt, "buttons")
663 buttons_set = buttons_elt.getAttribute("set") or C.XMLUI_DATA_BTNS_SET_DEFAULT 666 buttons_set = buttons_elt.getAttribute("set") or C.XMLUI_DATA_BTNS_SET_DEFAULT
664 except (TypeError, AttributeError): # XXX: TypeError is here because pyjamas raise a TypeError instead of an AttributeError 667 except (TypeError, AttributeError): # XXX: TypeError is here because pyjamas raise a TypeError instead of an AttributeError
665 buttons_set = C.XMLUI_DATA_BTNS_SET_DEFAULT 668 buttons_set = C.XMLUI_DATA_BTNS_SET_DEFAULT
666 self.dlg = self.dialog_factory.createConfirmDialog(self, self.title, message, level, buttons_set) 669 self.dlg = self.dialog_factory.createConfirmDialog(self, self.xmlui_title, message, level, buttons_set)
667 elif dlg_type == C.XMLUI_DIALOG_FILE: 670 elif dlg_type == C.XMLUI_DIALOG_FILE:
668 try: 671 try:
669 file_elt = self._getChildNode(dlg_elt, "file") 672 file_elt = self._getChildNode(dlg_elt, "file")
670 filetype = file_elt.getAttribute("type") or C.XMLUI_DATA_FILETYPE_DEFAULT 673 filetype = file_elt.getAttribute("type") or C.XMLUI_DATA_FILETYPE_DEFAULT
671 except (TypeError, AttributeError): # XXX: TypeError is here because pyjamas raise a TypeError instead of an AttributeError 674 except (TypeError, AttributeError): # XXX: TypeError is here because pyjamas raise a TypeError instead of an AttributeError
672 filetype = C.XMLUI_DATA_FILETYPE_DEFAULT 675 filetype = C.XMLUI_DATA_FILETYPE_DEFAULT
673 self.dlg = self.dialog_factory.createFileDialog(self, self.title, message, level, filetype) 676 self.dlg = self.dialog_factory.createFileDialog(self, self.xmlui_title, message, level, filetype)
674 else: 677 else:
675 raise ValueError("Unknown dialog type [%s]" % dlg_type) 678 raise ValueError("Unknown dialog type [%s]" % dlg_type)
676 679
677 def show(self): 680 def show(self):
678 self.dlg._xmluiShow() 681 self.dlg._xmluiShow()
688 """ 691 """
689 assert type_ in (CLASS_PANEL, CLASS_DIALOG) 692 assert type_ in (CLASS_PANEL, CLASS_DIALOG)
690 class_map[type_] = class_ 693 class_map[type_] = class_
691 694
692 695
693 def create(host, xml_data, title = None, flags = None, dom_parse=None, dom_free=None): 696 def create(host, xml_data, title=None, flags=None, dom_parse=None, dom_free=None, callback=None, profile=C.PROF_KEY_NONE):
694 """ 697 """
695 @param dom_parse: methode equivalent to minidom.parseString (but which must manage unicode), or None to use default one 698 @param dom_parse: methode equivalent to minidom.parseString (but which must manage unicode), or None to use default one
696 @param dom_free: method used to free the parsed DOM 699 @param dom_free: method used to free the parsed DOM
697 """ 700 """
698 if dom_parse is None: 701 if dom_parse is None:
699 from xml.dom import minidom 702 from xml.dom import minidom
700 dom_parse = lambda xml_data: minidom.parseString(xml_data.encode('utf-8')) 703 dom_parse = lambda xml_data: minidom.parseString(xml_data.encode('utf-8'))
711 else: 714 else:
712 cls = class_map[CLASS_DIALOG] 715 cls = class_map[CLASS_DIALOG]
713 except KeyError: 716 except KeyError:
714 raise ClassNotRegistedError(_("You must register classes with registerClass before creating a XMLUI")) 717 raise ClassNotRegistedError(_("You must register classes with registerClass before creating a XMLUI"))
715 718
716 xmlui = cls(host, parsed_dom, title, flags) 719 xmlui = cls(host, parsed_dom, title, flags, callback, profile)
717 dom_free(parsed_dom) 720 dom_free(parsed_dom)
718 return xmlui 721 return xmlui