Mercurial > libervia-backend
view frontends/primitivus/xmlui.py @ 149:3c3f70c01333
Primitivus: wix: xmlui misc fixes
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 28 Jul 2010 19:56:56 +0800 |
parents | 80661755ea8d |
children | b1f1955d96b3 |
line wrap: on
line source
#!/usr/bin/python # -*- coding: utf-8 -*- """ Primitivus: a SAT frontend Copyright (C) 2009, 2010 Jérôme Poisson (goffi@goffi.org) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. """ import urwid import custom_widgets from xml.dom import minidom class Pairs(urwid.WidgetWrap): def __init__(self, weight_0='1', weight_1='1'): self.idx = 0 self.weight_0 = weight_0 self.weight_1 = weight_1 columns = urwid.Columns([urwid.Text(''), urwid.Text('')]) #XXX: empty Text hack needed because Pile doesn't support empty list urwid.WidgetWrap.__init__(self,columns) def append(self, widget): pile = self._w.widget_list[self.idx] if pile.__class__ == urwid.Text: self._w.widget_list[self.idx] = urwid.Pile([widget]) if self.idx == 1: self._w.set_focus(1) else: pile.widget_list.append(widget) pile.item_types.append(('weight',getattr(self,'weight_'+str(self.idx)))) self.idx = (self.idx + 1) % 2 class XMLUI(urwid.WidgetWrap): def __init__(self, host, xml_data, title = None, options = [], misc={}): self.host = host self.title = title self.options = options self.misc = misc self.ctrl_list = {} # usefull to access ctrl widget = self.constructUI(xml_data) urwid.WidgetWrap.__init__(self,widget) def __parseElems(self, node, parent): """Parse elements inside a <layout> tags, and add them to the parent""" for elem in node.childNodes: if elem.nodeName != "elem": message=_("Unmanaged tag") error(message) raise Exception(message) id = elem.getAttribute("id") name = elem.getAttribute("name") type = elem.getAttribute("type") value = elem.getAttribute("value") if elem.hasAttribute('value') else u'' if type=="empty": ctrl = urwid.Text('') elif type=="text": try: value = elem.childNodes[0].wholeText except IndexError: warning (_("text node has no child !")) ctrl = urwid.Text(value) elif type=="label": ctrl = urwid.Text(value+": ") elif type=="string": ctrl = urwid.Edit(edit_text = value) self.ctrl_list[name] = ({'type':type, 'control':ctrl}) elif type=="password": ctrl = custom_widgets.Password(edit_text = value) self.ctrl_list[name] = ({'type':type, 'control':ctrl}) elif type=="textbox": ctrl = urwid.Edit(edit_text = value, multiline=True) self.ctrl_list[name] = ({'type':type, 'control':ctrl}) elif type=="list": style=[] if elem.getAttribute("multi")=='yes' else ['single'] ctrl = custom_widgets.List(options=[option.getAttribute("value") for option in elem.getElementsByTagName("option")], style=style) self.ctrl_list[name] = ({'type':type, 'control':ctrl}) elif type=="button": callback_id = elem.getAttribute("callback_id") ctrl = urwid.Button(value, on_press=self.onButtonPress) ctrl.param_id = (callback_id,[field.getAttribute('name') for field in elem.getElementsByTagName("field_back")]) else: error(_("FIXME FIXME FIXME: type [%s] is not implemented") % type) #FIXME ! raise NotImplementedError parent.append(ctrl) def __parseChilds(self, current, elem, wanted = ['layout']): """Recursively parse childNodes of an elemen @param current: widget container with 'append' method @param elem: element from which childs will be parsed @param wanted: list of tag names that can be present in the childs to be SàT XMLUI compliant""" for node in elem.childNodes: if wanted and not node.nodeName in wanted: raise Exception("Invalid XMLUI") #TODO: make a custom exception if node.nodeName == "layout": type = node.getAttribute('type') if type == "tabs": raise NotImplementedError self.__parseChilds(current, None, node, ['category']) else: if type == "vertical": pass elif type == "pairs": pairs = Pairs() current.append(pairs) current = pairs else: warning(_("Unknown layout, using default one")) self.__parseElems(node, current) elif node.nodeName == "category": raise NotImplementedError """name = node.getAttribute('name') if not node.nodeName in wanted or not name or not isinstance(parent,wx.Notebook): raise Exception("Invalid XMLUI") #TODO: make a custom exception notebook = parent tab_panel = wx.Panel(notebook, -1) tab_panel.sizer = wx.BoxSizer(wx.VERTICAL) tab_panel.SetSizer(tab_panel.sizer) notebook.AddPage(tab_panel, name) self.__parseChilds(tab_panel, None, node, ['layout'])""" else: message=_("Unknown tag") error(message) raise Exception(message) #TODO: raise a custom exception here def constructUI(self, xml_data): list_box = urwid.ListBox(urwid.SimpleListWalker([])) cat_dom = minidom.parseString(xml_data.encode('utf-8')) top= cat_dom.documentElement self.type = top.getAttribute("type") if not self.title: self.title = top.getAttribute("title") #TODO: manage title if top.nodeName != "sat_xmlui" or not self.type in ['form', 'param', 'window']: raise Exception("Invalid XMLUI") #TODO: make a custom exception self.__parseChilds(list_box.body, cat_dom.documentElement) if self.type == 'form': buttons = [] buttons.append(urwid.Button(_('Submit'),self.onFormSubmitted)) if not 'NO_CANCEL' in self.options: buttons.append(urwid.Button(_('Cancel'),self.onFormCancelled)) max_len = max([len(button.get_label()) for button in buttons]) grid_wid = urwid.GridFlow(buttons,max_len+4,1,0,'center') list_box.body.append(grid_wid) return list_box def show(self): """Show the constructed UI""" decorated = custom_widgets.LabelLine(self, custom_widgets.SurroundedText(self.title or '')) self.host.showPopUp(decorated) self.host.redraw() ##EVENTS## def onButtonPress(self, button): self.host.debug() def onFormSubmitted(self, button): data = [] for ctrl_name in self.ctrl_list: ctrl = self.ctrl_list[ctrl_name] if isinstance(ctrl['control'], custom_widgets.List): data.append((ctrl_name, ctrl['control'].getSelectedValue())) else: data.append((ctrl_name, ctrl['control'].get_edit_text())) if self.misc.has_key('action_back'): #FIXME FIXME FIXME: WTF ! Must be cleaned raise NotImplementedError self.host.debug() elif self.misc.has_key('callback'): self.misc['callback'](data) else: warning (_("The form data is not sent back, the type is not managed properly")) self.host.removePopUp() def onFormCancelled(self, button): self.host.removePopUp()