comparison frontends/primitivus/xmlui.py @ 152:b1f1955d96b3

Primitivus: XMLUI: tabs layout management + CustomButton now used instead of urwid's buttons
author Goffi <goffi@goffi.org>
date Sat, 31 Jul 2010 00:32:51 +0800
parents 3c3f70c01333
children 13888bdb72b6
comparison
equal deleted inserted replaced
151:7fcb4f083686 152:b1f1955d96b3
33 #XXX: empty Text hack needed because Pile doesn't support empty list 33 #XXX: empty Text hack needed because Pile doesn't support empty list
34 urwid.WidgetWrap.__init__(self,columns) 34 urwid.WidgetWrap.__init__(self,columns)
35 35
36 def append(self, widget): 36 def append(self, widget):
37 pile = self._w.widget_list[self.idx] 37 pile = self._w.widget_list[self.idx]
38 if pile.__class__ == urwid.Text: 38 if isinstance(pile, urwid.Text):
39 self._w.widget_list[self.idx] = urwid.Pile([widget]) 39 self._w.widget_list[self.idx] = urwid.Pile([widget])
40 if self.idx == 1: 40 if self.idx == 1:
41 self._w.set_focus(1) 41 self._w.set_focus(1)
42 else: 42 else:
43 pile.widget_list.append(widget) 43 pile.widget_list.append(widget)
44 pile.item_types.append(('weight',getattr(self,'weight_'+str(self.idx)))) 44 pile.item_types.append(('weight',getattr(self,'weight_'+str(self.idx))))
45 self.idx = (self.idx + 1) % 2 45 self.idx = (self.idx + 1) % 2
46 46
47 class InvalidXMLUI(Exception):
48 pass
47 49
48 class XMLUI(urwid.WidgetWrap): 50 class XMLUI(urwid.WidgetWrap):
49 51
50 def __init__(self, host, xml_data, title = None, options = [], misc={}): 52 def __init__(self, host, xml_data, title = None, options = [], misc={}):
51 self.host = host 53 self.host = host
76 warning (_("text node has no child !")) 78 warning (_("text node has no child !"))
77 ctrl = urwid.Text(value) 79 ctrl = urwid.Text(value)
78 elif type=="label": 80 elif type=="label":
79 ctrl = urwid.Text(value+": ") 81 ctrl = urwid.Text(value+": ")
80 elif type=="string": 82 elif type=="string":
81 ctrl = urwid.Edit(edit_text = value) 83 ctrl = custom_widgets.AdvancedEdit(edit_text = value)
82 self.ctrl_list[name] = ({'type':type, 'control':ctrl}) 84 self.ctrl_list[name] = ({'type':type, 'control':ctrl})
83 elif type=="password": 85 elif type=="password":
84 ctrl = custom_widgets.Password(edit_text = value) 86 ctrl = custom_widgets.Password(edit_text = value)
85 self.ctrl_list[name] = ({'type':type, 'control':ctrl}) 87 self.ctrl_list[name] = ({'type':type, 'control':ctrl})
86 elif type=="textbox": 88 elif type=="textbox":
87 ctrl = urwid.Edit(edit_text = value, multiline=True) 89 ctrl = custom_widgets.AdvancedEdit(edit_text = value, multiline=True)
88 self.ctrl_list[name] = ({'type':type, 'control':ctrl}) 90 self.ctrl_list[name] = ({'type':type, 'control':ctrl})
89 elif type=="list": 91 elif type=="list":
90 style=[] if elem.getAttribute("multi")=='yes' else ['single'] 92 style=[] if elem.getAttribute("multi")=='yes' else ['single']
91 ctrl = custom_widgets.List(options=[option.getAttribute("value") for option in elem.getElementsByTagName("option")], style=style) 93 ctrl = custom_widgets.List(options=[option.getAttribute("value") for option in elem.getElementsByTagName("option")], style=style)
92 self.ctrl_list[name] = ({'type':type, 'control':ctrl}) 94 self.ctrl_list[name] = ({'type':type, 'control':ctrl})
93 elif type=="button": 95 elif type=="button":
94 callback_id = elem.getAttribute("callback_id") 96 callback_id = elem.getAttribute("callback_id")
95 ctrl = urwid.Button(value, on_press=self.onButtonPress) 97 ctrl = custom_widgets.CustomButton(value, on_press=self.onButtonPress)
96 ctrl.param_id = (callback_id,[field.getAttribute('name') for field in elem.getElementsByTagName("field_back")]) 98 ctrl.param_id = (callback_id,[field.getAttribute('name') for field in elem.getElementsByTagName("field_back")])
97 else: 99 else:
98 error(_("FIXME FIXME FIXME: type [%s] is not implemented") % type) #FIXME ! 100 error(_("FIXME FIXME FIXME: type [%s] is not implemented") % type) #FIXME !
99 raise NotImplementedError 101 raise NotImplementedError
100 parent.append(ctrl) 102 parent.append(ctrl)
101 103
102 def __parseChilds(self, current, elem, wanted = ['layout']): 104 def __parseChilds(self, current, elem, wanted = ['layout'], data = None):
103 """Recursively parse childNodes of an elemen 105 """Recursively parse childNodes of an elemen
104 @param current: widget container with 'append' method 106 @param current: widget container with 'append' method
105 @param elem: element from which childs will be parsed 107 @param elem: element from which childs will be parsed
106 @param wanted: list of tag names that can be present in the childs to be SàT XMLUI compliant""" 108 @param wanted: list of tag names that can be present in the childs to be SàT XMLUI compliant"""
107 for node in elem.childNodes: 109 for node in elem.childNodes:
108 if wanted and not node.nodeName in wanted: 110 if wanted and not node.nodeName in wanted:
109 raise Exception("Invalid XMLUI") #TODO: make a custom exception 111 raise InvalidXMLUI
110 if node.nodeName == "layout": 112 if node.nodeName == "layout":
111 type = node.getAttribute('type') 113 type = node.getAttribute('type')
112 if type == "tabs": 114 if type == "tabs":
113 raise NotImplementedError 115 tab_cont = custom_widgets.TabsContainer()
114 self.__parseChilds(current, None, node, ['category']) 116 self.__parseChilds(current, node, ['category'], tab_cont)
117 current.append(tab_cont)
118 elif type == "vertical":
119 self.__parseElems(node, current)
120 elif type == "pairs":
121 pairs = Pairs()
122 self.__parseElems(node, pairs)
123 current.append(pairs)
115 else: 124 else:
116 if type == "vertical": 125 warning(_("Unknown layout, using default one"))
117 pass
118 elif type == "pairs":
119 pairs = Pairs()
120 current.append(pairs)
121 current = pairs
122 else:
123 warning(_("Unknown layout, using default one"))
124 self.__parseElems(node, current) 126 self.__parseElems(node, current)
125 elif node.nodeName == "category": 127 elif node.nodeName == "category":
126 raise NotImplementedError 128 name = node.getAttribute('name')
127 """name = node.getAttribute('name') 129 if not name or not isinstance(data,custom_widgets.TabsContainer):
128 if not node.nodeName in wanted or not name or not isinstance(parent,wx.Notebook): 130 raise InvalidXMLUI
129 raise Exception("Invalid XMLUI") #TODO: make a custom exception 131 tab_cont = data
130 notebook = parent 132 listbox = tab_cont.addTab(name)
131 tab_panel = wx.Panel(notebook, -1) 133 self.__parseChilds(listbox.body, node, ['layout'])
132 tab_panel.sizer = wx.BoxSizer(wx.VERTICAL)
133 tab_panel.SetSizer(tab_panel.sizer)
134 notebook.AddPage(tab_panel, name)
135 self.__parseChilds(tab_panel, None, node, ['layout'])"""
136
137 else: 134 else:
138 message=_("Unknown tag") 135 message=_("Unknown tag")
139 error(message) 136 error(message)
140 raise Exception(message) #TODO: raise a custom exception here 137 raise NotImplementedError
141 138
142 def constructUI(self, xml_data): 139 def constructUI(self, xml_data):
143 140
144 list_box = urwid.ListBox(urwid.SimpleListWalker([])) 141 list_box = urwid.ListBox(urwid.SimpleListWalker([]))
145 142
146 cat_dom = minidom.parseString(xml_data.encode('utf-8')) 143 cat_dom = minidom.parseString(xml_data.encode('utf-8'))
147 top= cat_dom.documentElement 144 top=cat_dom.documentElement
148 self.type = top.getAttribute("type") 145 self.type = top.getAttribute("type")
149 if not self.title: 146 if not self.title:
150 self.title = top.getAttribute("title") #TODO: manage title 147 self.title = top.getAttribute("title") #TODO: manage title
151 if top.nodeName != "sat_xmlui" or not self.type in ['form', 'param', 'window']: 148 if top.nodeName != "sat_xmlui" or not self.type in ['form', 'param', 'window']:
152 raise Exception("Invalid XMLUI") #TODO: make a custom exception 149 raise InvalidXMLUI
153 150
154 self.__parseChilds(list_box.body, cat_dom.documentElement) 151 self.__parseChilds(list_box.body, cat_dom.documentElement)
152
153 assert list_box.body
154 if isinstance(list_box.body[0],custom_widgets.TabsContainer):
155 return list_box.body[0] #xxx: awfull hack cause TabsContainer is a BoxWidget, can't be inside a ListBox
155 156
156 if self.type == 'form': 157 if self.type == 'form':
157 buttons = [] 158 buttons = []
158 buttons.append(urwid.Button(_('Submit'),self.onFormSubmitted)) 159 buttons.append(urwid.Button(_('Submit'),self.onFormSubmitted))
159 if not 'NO_CANCEL' in self.options: 160 if not 'NO_CANCEL' in self.options:
160 buttons.append(urwid.Button(_('Cancel'),self.onFormCancelled)) 161 buttons.append(urwid.Button(_('Cancel'),self.onFormCancelled))
161 max_len = max([len(button.get_label()) for button in buttons]) 162 max_len = max([len(button.get_label()) for button in buttons])
162 grid_wid = urwid.GridFlow(buttons,max_len+4,1,0,'center') 163 grid_wid = urwid.GridFlow(buttons,max_len+4,1,0,'center')
163 list_box.body.append(grid_wid) 164 list_box.body.append(grid_wid)
164
165 165
166 return list_box 166 return list_box
167 167
168 def show(self): 168 def show(self):
169 """Show the constructed UI""" 169 """Show the constructed UI"""