comparison src/browser/xmlui.py @ 449:981ed669d3b3

/!\ reorganize all the file hierarchy, move the code and launching script to src: - browser_side --> src/browser - public --> src/browser_side/public - libervia.py --> src/browser/libervia_main.py - libervia_server --> src/server - libervia_server/libervia.sh --> src/libervia.sh - twisted --> src/twisted - new module src/common - split constants.py in 3 files: - src/common/constants.py - src/browser/constants.py - src/server/constants.py - output --> html (generated by pyjsbuild during the installation) - new option/parameter "data_dir" (-d) to indicates the directory containing html and server_css - setup.py installs libervia to the following paths: - src/common --> <LIB>/libervia/common - src/server --> <LIB>/libervia/server - src/twisted --> <LIB>/twisted - html --> <SHARE>/libervia/html - server_side --> <SHARE>libervia/server_side - LIBERVIA_INSTALL environment variable takes 2 new options with prompt confirmation: - clean: remove previous installation directories - purge: remove building and previous installation directories You may need to update your sat.conf and/or launching script to update the following options/parameters: - ssl_certificate - data_dir
author souliane <souliane@mailoo.org>
date Tue, 20 May 2014 06:41:16 +0200
parents browser_side/xmlui.py@d52f529a6d42
children 1a0cec9b0f1e
comparison
equal deleted inserted replaced
448:14c35f7f1ef5 449:981ed669d3b3
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 # Libervia: a Salut à Toi frontend
5 # Copyright (C) 2011, 2012, 2013, 2014 Jérôme Poisson <goffi@goffi.org>
6
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
16
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20 from sat.core.log import getLogger
21 log = getLogger(__name__)
22 from sat_frontends.tools import xmlui
23
24 from pyjamas.ui.VerticalPanel import VerticalPanel
25 from pyjamas.ui.HorizontalPanel import HorizontalPanel
26 from pyjamas.ui.TabPanel import TabPanel
27 from pyjamas.ui.Grid import Grid
28 from pyjamas.ui.Label import Label
29 from pyjamas.ui.TextBox import TextBox
30 from pyjamas.ui.PasswordTextBox import PasswordTextBox
31 from pyjamas.ui.TextArea import TextArea
32 from pyjamas.ui.CheckBox import CheckBox
33 from pyjamas.ui.ListBox import ListBox
34 from pyjamas.ui.Button import Button
35 from pyjamas.ui.HTML import HTML
36
37 from nativedom import NativeDOM
38
39
40 class EmptyWidget(xmlui.EmptyWidget, Label):
41
42 def __init__(self, parent):
43 Label.__init__(self, '')
44
45
46 class TextWidget(xmlui.TextWidget, Label):
47
48 def __init__(self, parent, value):
49 Label.__init__(self, value)
50
51
52 class LabelWidget(xmlui.LabelWidget, TextWidget):
53
54 def __init__(self, parent, value):
55 TextWidget.__init__(self, parent, value+": ")
56
57
58 class JidWidget(xmlui.JidWidget, TextWidget):
59
60 def __init__(self, parent, value):
61 TextWidget.__init__(self, parent, value)
62
63
64 class DividerWidget(xmlui.DividerWidget, HTML):
65
66 def __init__(self, parent, style='line'):
67 """Add a divider
68
69 @param parent
70 @param style (string): one of:
71 - line: a simple line
72 - dot: a line of dots
73 - dash: a line of dashes
74 - plain: a full thick line
75 - blank: a blank line/space
76 """
77 HTML.__init__(self, "<hr/>")
78 self.addStyleName(style)
79
80
81 class StringWidget(xmlui.StringWidget, TextBox):
82
83 def __init__(self, parent, value):
84 TextBox.__init__(self)
85 self.setText(value)
86
87 def _xmluiSetValue(self, value):
88 self.setText(value)
89
90 def _xmluiGetValue(self):
91 return self.getText()
92
93 def _xmluiOnChange(self, callback):
94 self.addChangeListener(callback)
95
96
97 class PasswordWidget(xmlui.PasswordWidget, PasswordTextBox):
98
99 def __init__(self, parent, value):
100 PasswordTextBox.__init__(self)
101 self.setText(value)
102
103 def _xmluiSetValue(self, value):
104 self.setText(value)
105
106 def _xmluiGetValue(self):
107 return self.getText()
108
109 def _xmluiOnChange(self, callback):
110 self.addChangeListener(callback)
111
112
113 class TextBoxWidget(xmlui.TextBoxWidget, TextArea):
114
115 def __init__(self, parent, value):
116 TextArea.__init__(self)
117 self.setText(value)
118
119 def _xmluiSetValue(self, value):
120 self.setText(value)
121
122 def _xmluiGetValue(self):
123 return self.getText()
124
125 def _xmluiOnChange(self, callback):
126 self.addChangeListener(callback)
127
128
129 class BoolWidget(xmlui.BoolWidget, CheckBox):
130
131 def __init__(self, parent, state):
132 CheckBox.__init__(self)
133 self.setChecked(state)
134
135 def _xmluiSetValue(self, value):
136 self.setChecked(value == "true")
137
138 def _xmluiGetValue(self):
139 return "true" if self.isChecked() else "false"
140
141 def _xmluiOnChange(self, callback):
142 self.addClickListener(callback)
143
144
145 class ButtonWidget(xmlui.ButtonWidget, Button):
146
147 def __init__(self, parent, value, click_callback):
148 Button.__init__(self, value, click_callback)
149
150 def _xmluiOnClick(self, callback):
151 self.addClickListener(callback)
152
153
154 class ListWidget(xmlui.ListWidget, ListBox):
155
156 def __init__(self, parent, options, selected, flags):
157 ListBox.__init__(self)
158 multi_selection = 'single' not in flags
159 self.setMultipleSelect(multi_selection)
160 if multi_selection:
161 self.setVisibleItemCount(5)
162 for option in options:
163 self.addItem(option[1])
164 self._xmlui_attr_map = {label: value for value, label in options}
165 self._xmluiSelectValues(selected)
166
167 def _xmluiSelectValue(self, value):
168 """Select a value checking its item"""
169 try:
170 label = [label for label, _value in self._xmlui_attr_map.items() if _value == value][0]
171 except IndexError:
172 log.warning("Can't find value [%s] to select" % value)
173 return
174 self.selectItem(label)
175
176 def _xmluiSelectValues(self, values):
177 """Select multiple values, ignore the items"""
178 self.setValueSelection(values)
179
180 def _xmluiGetSelectedValues(self):
181 ret = []
182 for label in self.getSelectedItemText():
183 ret.append(self._xmlui_attr_map[label])
184 return ret
185
186 def _xmluiOnChange(self, callback):
187 self.addChangeListener(callback)
188
189 def _xmluiAddValues(self, values, select=True):
190 selected = self._xmluiGetSelectedValues()
191 for value in values:
192 if value not in self._xmlui_attr_map.values():
193 self.addItem(value)
194 self._xmlui_attr_map[value] = value
195 if value not in selected:
196 selected.append(value)
197 self._xmluiSelectValues(selected)
198
199
200 class LiberviaContainer(object):
201
202 def _xmluiAppend(self, widget):
203 self.append(widget)
204
205
206 class AdvancedListContainer(xmlui.AdvancedListContainer, Grid):
207
208 def __init__(self, parent, columns, selectable='no'):
209 Grid.__init__(self, 0, columns)
210 self.columns = columns
211 self.row = -1
212 self.col = 0
213 self._xmlui_rows_idx = []
214 self._xmlui_selectable = selectable != 'no'
215 self._xmlui_selected_row = None
216 self.addTableListener(self)
217 if self._xmlui_selectable:
218 self.addStyleName('AdvancedListSelectable')
219
220 def onCellClicked(self, grid, row, col):
221 if not self._xmlui_selectable:
222 return
223 self._xmlui_selected_row = row
224 try:
225 self._xmlui_select_cb(self)
226 except AttributeError:
227 log.warning("no select callback set")
228
229
230 def _xmluiAppend(self, widget):
231 self.setWidget(self.row, self.col, widget)
232 self.col += 1
233
234 def _xmluiAddRow(self, idx):
235 self.row += 1
236 self.col = 0
237 self._xmlui_rows_idx.insert(self.row, idx)
238 self.resizeRows(self.row+1)
239
240 def _xmluiGetSelectedWidgets(self):
241 return [self.getWidget(self._xmlui_selected_row, col) for col in range(self.columns)]
242
243 def _xmluiGetSelectedIndex(self):
244 try:
245 return self._xmlui_rows_idx[self._xmlui_selected_row]
246 except TypeError:
247 return None
248
249 def _xmluiOnSelect(self, callback):
250 self._xmlui_select_cb = callback
251
252
253 class PairsContainer(xmlui.PairsContainer, Grid):
254
255 def __init__(self, parent):
256 Grid.__init__(self, 0, 0)
257 self.row = 0
258 self.col = 0
259
260 def _xmluiAppend(self, widget):
261 if self.col == 0:
262 self.resize(self.row+1, 2)
263 self.setWidget(self.row, self.col, widget)
264 self.col += 1
265 if self.col == 2:
266 self.row +=1
267 self.col = 0
268
269
270
271 class TabsContainer(LiberviaContainer, xmlui.TabsContainer, TabPanel):
272
273 def __init__(self, parent):
274 TabPanel.__init__(self)
275 self.setStyleName('liberviaTabPanel')
276
277 def _xmluiAddTab(self, label):
278 tab_panel = VerticalContainer(self)
279 self.add(tab_panel, label)
280 if len(self.getChildren()) == 1:
281 self.selectTab(0)
282 return tab_panel
283
284
285 class VerticalContainer(LiberviaContainer, xmlui.VerticalContainer, VerticalPanel):
286 __bases__ = (LiberviaContainer, xmlui.VerticalContainer, VerticalPanel)
287
288 def __init__(self, parent):
289 VerticalPanel.__init__(self)
290
291
292 class WidgetFactory(object):
293 # XXX: __getattr__ doesn't work here for an unknown reason
294
295 def createVerticalContainer(self, *args, **kwargs):
296 instance = VerticalContainer(*args, **kwargs)
297 instance._xmlui_main = self._xmlui_main
298 return instance
299
300 def createPairsContainer(self, *args, **kwargs):
301 instance = PairsContainer(*args, **kwargs)
302 instance._xmlui_main = self._xmlui_main
303 return instance
304
305 def createTabsContainer(self, *args, **kwargs):
306 instance = TabsContainer(*args, **kwargs)
307 instance._xmlui_main = self._xmlui_main
308 return instance
309
310 def createAdvancedListContainer(self, *args, **kwargs):
311 instance = AdvancedListContainer(*args, **kwargs)
312 instance._xmlui_main = self._xmlui_main
313 return instance
314
315 def createEmptyWidget(self, *args, **kwargs):
316 instance = EmptyWidget(*args, **kwargs)
317 instance._xmlui_main = self._xmlui_main
318 return instance
319
320 def createTextWidget(self, *args, **kwargs):
321 instance = TextWidget(*args, **kwargs)
322 instance._xmlui_main = self._xmlui_main
323 return instance
324
325 def createLabelWidget(self, *args, **kwargs):
326 instance = LabelWidget(*args, **kwargs)
327 instance._xmlui_main = self._xmlui_main
328 return instance
329
330 def createJidWidget(self, *args, **kwargs):
331 instance = JidWidget(*args, **kwargs)
332 instance._xmlui_main = self._xmlui_main
333 return instance
334
335 def createDividerWidget(self, *args, **kwargs):
336 instance = DividerWidget(*args, **kwargs)
337 instance._xmlui_main = self._xmlui_main
338 return instance
339
340 def createStringWidget(self, *args, **kwargs):
341 instance = StringWidget(*args, **kwargs)
342 instance._xmlui_main = self._xmlui_main
343 return instance
344
345 def createPasswordWidget(self, *args, **kwargs):
346 instance = PasswordWidget(*args, **kwargs)
347 instance._xmlui_main = self._xmlui_main
348 return instance
349
350 def createTextBoxWidget(self, *args, **kwargs):
351 instance = TextBoxWidget(*args, **kwargs)
352 instance._xmlui_main = self._xmlui_main
353 return instance
354
355 def createBoolWidget(self, *args, **kwargs):
356 instance = BoolWidget(*args, **kwargs)
357 instance._xmlui_main = self._xmlui_main
358 return instance
359
360 def createButtonWidget(self, *args, **kwargs):
361 instance = ButtonWidget(*args, **kwargs)
362 instance._xmlui_main = self._xmlui_main
363 return instance
364
365 def createListWidget(self, *args, **kwargs):
366 instance = ListWidget(*args, **kwargs)
367 instance._xmlui_main = self._xmlui_main
368 return instance
369
370
371 # def __getattr__(self, attr):
372 # if attr.startswith("create"):
373 # cls = globals()[attr[6:]]
374 # cls._xmlui_main = self._xmlui_main
375 # return cls
376
377
378 class XMLUI(xmlui.XMLUI, VerticalPanel):
379 widget_factory = WidgetFactory()
380
381 def __init__(self, host, xml_data, title = None, flags = None):
382 self.widget_factory._xmlui_main = self
383 self.dom = NativeDOM()
384 dom_parse = lambda xml_data: self.dom.parseString(xml_data)
385 VerticalPanel.__init__(self)
386 self.setSize('100%', '100%')
387 xmlui.XMLUI.__init__(self, host, xml_data, title, flags, dom_parse)
388
389 def setCloseCb(self, close_cb):
390 self.close_cb = close_cb
391
392 def _xmluiClose(self):
393 if self.close_cb:
394 self.close_cb()
395 else:
396 log.warning("no close method defined")
397
398 def _xmluiLaunchAction(self, action_id, data):
399 self.host.launchAction(action_id, data)
400
401 def _xmluiSetParam(self, name, value, category):
402 self.host.bridge.call('setParam', None, name, value, category)
403
404 def constructUI(self, xml_data):
405 super(XMLUI, self).constructUI(xml_data)
406 self.add(self.main_cont)
407 self.setCellHeight(self.main_cont, '100%')
408 if self.type == 'form':
409 hpanel = HorizontalPanel()
410 hpanel.setStyleName('marginAuto')
411 hpanel.add(Button('Submit',self.onFormSubmitted))
412 if not 'NO_CANCEL' in self.flags:
413 hpanel.add(Button('Cancel',self.onFormCancelled))
414 self.add(hpanel)
415 elif self.type == 'param':
416 assert(isinstance(self.children[0][0],TabPanel))
417 hpanel = HorizontalPanel()
418 hpanel.add(Button('Save', self.onSaveParams))
419 hpanel.add(Button('Cancel', lambda ignore: self._xmluiClose()))
420 self.add(hpanel)