comparison tools/xml_tools.py @ 103:6be927a465ed

XMLUI refactoring, step 1
author Goffi <goffi@goffi.org>
date Wed, 23 Jun 2010 00:23:26 +0800
parents 94011f553cd0
children 5458ac1380cc
comparison
equal deleted inserted replaced
102:94011f553cd0 103:6be927a465ed
28 28
29 29
30 def dataForm2xml(form): 30 def dataForm2xml(form):
31 """Take a data form (xep-0004, Wokkel's implementation) and convert it to a SàT xml""" 31 """Take a data form (xep-0004, Wokkel's implementation) and convert it to a SàT xml"""
32 32
33 impl = minidom.getDOMImplementation() 33 form_panel = XMLUI("form", "vertical")
34
35 doc = impl.createDocument(None, "form", None)
36 top_element = doc.documentElement
37 34
38 #result_xml = ["<form>", "</form>"]
39 if form.instructions: 35 if form.instructions:
40 elem = doc.createElement('elem') 36 form_panel.addText('\n'.join(form.instructions), 'instructions')
41 elem.setAttribute('name','instructions') 37
42 elem.setAttribute('type','text') 38 form_panel.changeLayout("pairs")
43 text = doc.createTextNode('\n'.join(form.instructions)) 39
44 elem.appendChild(text)
45 top_element.appendChild(elem)
46 for field in form.fieldList: 40 for field in form.fieldList:
47 if field.fieldType == 'fixed': 41 if field.fieldType == 'fixed':
48 __field_type = 'text' 42 __field_type = 'text'
49 elif field.fieldType == 'text-single': 43 elif field.fieldType == 'text-single':
50 __field_type = "string" 44 __field_type = "string"
54 __field_type = "list" 48 __field_type = "list"
55 else: 49 else:
56 error (u"FIXME FIXME FIXME: Type [%s] is not managed yet by SàT" % field.fieldType) 50 error (u"FIXME FIXME FIXME: Type [%s] is not managed yet by SàT" % field.fieldType)
57 __field_type = "string" 51 __field_type = "string"
58 52
59 elem = doc.createElement('elem') 53 if field.label:
60 if field.var: 54 form_panel.addLabel(field.label)
61 elem.setAttribute('name', field.var) 55 else:
62 elem.setAttribute('type', __field_type) 56 form_panel.addEmpty()
63 elem.setAttribute('label', field.label or "") 57
64 if field.value: 58 elem = form_panel.addElement(__field_type, field.var, None, field.value, [option.value for option in field.options])
65 elem.setAttribute('value', field.value) 59 return form_panel.toXml()
66 top_element.appendChild(elem)
67 for option in field.options:
68 opt = doc.createElement('option')
69 opt.setAttribute('value', option.value)
70 elem.appendChild(opt)
71 result = doc.toxml()
72 doc.unlink()
73 return result
74 60
75 def tupleList2dataForm(values): 61 def tupleList2dataForm(values):
76 """convert a list of tuples (name,value) to a wokkel submit data form""" 62 """convert a list of tuples (name,value) to a wokkel submit data form"""
77 form = data_form.Form('submit') 63 form = data_form.Form('submit')
78 for value in values: 64 for value in values:
79 field = data_form.Field(var=value[0], value=value[1]) 65 field = data_form.Field(var=value[0], value=value[1])
80 form.addField(field) 66 form.addField(field)
81 67
82 return form 68 return form
83 69
70 class XMLUI:
71 """This class is used to create a user interface (form/window/parameters/etc) using SàT XML"""
72
73 def __init__(self, panel_type, layout="vertical"):
74 """Init SàT XML Panel
75 @param panel_type: one of
76 - window (new window)
77 - form (formulaire, depend of the frontend, usually a panel with cancel/submit buttons)
78 - param (parameters, presentatio depend of the frontend)
79 @param layout: disposition of elements, one of:
80 - VERTICAL: elements are disposed up to bottom
81 - HORIZONTAL: elements are disposed left to right
82 - PAIRS: elements come on two aligned columns
83 (usually one for a label, the next for the element)
84 """
85 if not panel_type in ['window', 'form', 'param']:
86 error(_("Unknown panel type [%s]") % panel_type)
87 assert(False)
88 self.type = panel_type
89 impl = minidom.getDOMImplementation()
90
91 self.doc = impl.createDocument(None, "sat_xmlui", None)
92 top_element = self.doc.documentElement
93 top_element.setAttribute("type", panel_type)
94 self.currentLayout = self.__createLayout(layout, top_element)
95
96 def __del__(self):
97 self.doc.unlink()
84 98
99 def __createLayout(self, layout, parent=None):
100 """Create a layout element
101 @param type: layout type (cf init doc)
102 @parent: parent element or None
103 """
104 if not layout in ['vertical', 'horizontal', 'pairs']:
105 error (_("Unknown layout type [%s]") % layout)
106 assert (False)
107 layout_elt = self.doc.createElement('layout')
108 layout_elt.setAttribute('type',layout)
109 if parent != None:
110 parent.appendChild(layout_elt)
111 return layout_elt
85 112
113 def __createElem(self, type, name=None, parent = None):
114 """Create an element
115 @param type: one of
116 - empty: empty element (usefull to skip something in a layout, e.g. skip first element in a PAIRS layout)
117 - text: text to be displayed in an multi-line area, e.g. instructions
118 @param name: name of the element or None
119 @param parent: parent element or None
120 """
121 elem = self.doc.createElement('elem')
122 if name:
123 elem.setAttribute('name', name)
124 elem.setAttribute('type', type)
125 if parent != None:
126 parent.appendChild(elem)
127 return elem
128
129 def changeLayout(self, layout):
130 """Change the current layout"""
131 self.currentLayout = self.__createLayout(layout, self.doc.documentElement)
132
133
134 def addEmpty(self, name=None):
135 """Add a multi-lines text"""
136 elem = self.__createElem('empty', name, self.currentLayout)
137
138 def addText(self, text, name=None):
139 """Add a multi-lines text"""
140 elem = self.__createElem('text', name, self.currentLayout)
141 text = self.doc.createTextNode(text)
142 elem.appendChild(text)
143
144 def addLabel(self, text, name=None):
145 """Add a single line text, mainly useful as label before element"""
146 elem = self.__createElem('label', name, self.currentLayout)
147 elem.setAttribute('value', text)
148
149 def addString(self, name=None, value=None):
150 """Add a string box"""
151 elem = self.__createElem('string', name, self.currentLayout)
152 if value:
153 elem.setAttribute('value', value)
154
155 def addPassword(self, name=None, value=None):
156 """Add a password box"""
157 elem = self.__createElem('password', name, self.currentLayout)
158 if value:
159 elem.setAttribute('value', value)
160
161 def addList(self, options, name=None, value=None):
162 """Add a list of choices"""
163 assert (options)
164 elem = self.__createElem('list', name, self.currentLayout)
165 self.addOptions(options, elem)
166 if value:
167 elem.setAttribute('value', value)
168
169 def addElement(self, type, name = None, content = None, value = None, options = None):
170 """Convenience method to add element, the params correspond to the ones in addSomething methods"""
171 if type == 'empty':
172 self.addEmpty(name)
173 elif type == 'text':
174 assert(content)
175 self.addText(content, name)
176 elif type == 'label':
177 assert(value)
178 elif type == 'string':
179 self.addString(name, value)
180 elif type == 'password':
181 self.addPassword(name, value)
182 elif type == 'list':
183 self.addList(options, name, value)
184
185 def addOptions(self, options, parent):
186 """Add options to a multi-values element (e.g. list)
187 @param parent: multi-values element"""
188 for option in options:
189 opt = self.doc.createElement('option')
190 opt.setAttribute('value', option)
191 parent.appendChild(opt)
192
193 def toXml(self):
194 """return the XML representation of the panel"""
195 return self.doc.toxml()