Mercurial > libervia-web
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) |