Mercurial > libervia-web
view src/browser/xmlui.py @ 465:33ec27ef4b6a
server side: adapt passing the async failure from server to browser side, according to the new class BridgeException
author | souliane <souliane@mailoo.org> |
---|---|
date | Sun, 08 Jun 2014 16:59:48 +0200 |
parents | 1a0cec9b0f1e |
children |
line wrap: on
line source
#!/usr/bin/python # -*- coding: utf-8 -*- # Libervia: a Salut à Toi frontend # Copyright (C) 2011, 2012, 2013, 2014 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 Affero 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 Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from sat.core.log import getLogger log = getLogger(__name__) from sat_frontends.tools import xmlui from pyjamas.ui.VerticalPanel import VerticalPanel from pyjamas.ui.HorizontalPanel import HorizontalPanel from pyjamas.ui.TabPanel import TabPanel from pyjamas.ui.Grid import Grid from pyjamas.ui.Label import Label from pyjamas.ui.TextBox import TextBox from pyjamas.ui.PasswordTextBox import PasswordTextBox from pyjamas.ui.TextArea import TextArea from pyjamas.ui.CheckBox import CheckBox from pyjamas.ui.ListBox import ListBox from pyjamas.ui.Button import Button from pyjamas.ui.HTML import HTML from nativedom import NativeDOM class EmptyWidget(xmlui.EmptyWidget, Label): def __init__(self, parent): Label.__init__(self, '') class TextWidget(xmlui.TextWidget, Label): def __init__(self, parent, value): Label.__init__(self, value) class LabelWidget(xmlui.LabelWidget, TextWidget): def __init__(self, parent, value): TextWidget.__init__(self, parent, value + ": ") class JidWidget(xmlui.JidWidget, TextWidget): def __init__(self, parent, value): TextWidget.__init__(self, parent, value) class DividerWidget(xmlui.DividerWidget, HTML): def __init__(self, parent, style='line'): """Add a divider @param parent @param style (string): one of: - line: a simple line - dot: a line of dots - dash: a line of dashes - plain: a full thick line - blank: a blank line/space """ HTML.__init__(self, "<hr/>") self.addStyleName(style) class StringWidget(xmlui.StringWidget, TextBox): def __init__(self, parent, value): TextBox.__init__(self) self.setText(value) def _xmluiSetValue(self, value): self.setText(value) def _xmluiGetValue(self): return self.getText() def _xmluiOnChange(self, callback): self.addChangeListener(callback) class PasswordWidget(xmlui.PasswordWidget, PasswordTextBox): def __init__(self, parent, value): PasswordTextBox.__init__(self) self.setText(value) def _xmluiSetValue(self, value): self.setText(value) def _xmluiGetValue(self): return self.getText() def _xmluiOnChange(self, callback): self.addChangeListener(callback) class TextBoxWidget(xmlui.TextBoxWidget, TextArea): def __init__(self, parent, value): TextArea.__init__(self) self.setText(value) def _xmluiSetValue(self, value): self.setText(value) def _xmluiGetValue(self): return self.getText() def _xmluiOnChange(self, callback): self.addChangeListener(callback) class BoolWidget(xmlui.BoolWidget, CheckBox): def __init__(self, parent, state): CheckBox.__init__(self) self.setChecked(state) def _xmluiSetValue(self, value): self.setChecked(value == "true") def _xmluiGetValue(self): return "true" if self.isChecked() else "false" def _xmluiOnChange(self, callback): self.addClickListener(callback) class ButtonWidget(xmlui.ButtonWidget, Button): def __init__(self, parent, value, click_callback): Button.__init__(self, value, click_callback) def _xmluiOnClick(self, callback): self.addClickListener(callback) class ListWidget(xmlui.ListWidget, ListBox): def __init__(self, parent, options, selected, flags): ListBox.__init__(self) multi_selection = 'single' not in flags self.setMultipleSelect(multi_selection) if multi_selection: self.setVisibleItemCount(5) for option in options: self.addItem(option[1]) self._xmlui_attr_map = {label: value for value, label in options} self._xmluiSelectValues(selected) def _xmluiSelectValue(self, value): """Select a value checking its item""" try: label = [label for label, _value in self._xmlui_attr_map.items() if _value == value][0] except IndexError: log.warning("Can't find value [%s] to select" % value) return self.selectItem(label) def _xmluiSelectValues(self, values): """Select multiple values, ignore the items""" self.setValueSelection(values) def _xmluiGetSelectedValues(self): ret = [] for label in self.getSelectedItemText(): ret.append(self._xmlui_attr_map[label]) return ret def _xmluiOnChange(self, callback): self.addChangeListener(callback) def _xmluiAddValues(self, values, select=True): selected = self._xmluiGetSelectedValues() for value in values: if value not in self._xmlui_attr_map.values(): self.addItem(value) self._xmlui_attr_map[value] = value if value not in selected: selected.append(value) self._xmluiSelectValues(selected) class LiberviaContainer(object): def _xmluiAppend(self, widget): self.append(widget) class AdvancedListContainer(xmlui.AdvancedListContainer, Grid): def __init__(self, parent, columns, selectable='no'): Grid.__init__(self, 0, columns) self.columns = columns self.row = -1 self.col = 0 self._xmlui_rows_idx = [] self._xmlui_selectable = selectable != 'no' self._xmlui_selected_row = None self.addTableListener(self) if self._xmlui_selectable: self.addStyleName('AdvancedListSelectable') def onCellClicked(self, grid, row, col): if not self._xmlui_selectable: return self._xmlui_selected_row = row try: self._xmlui_select_cb(self) except AttributeError: log.warning("no select callback set") def _xmluiAppend(self, widget): self.setWidget(self.row, self.col, widget) self.col += 1 def _xmluiAddRow(self, idx): self.row += 1 self.col = 0 self._xmlui_rows_idx.insert(self.row, idx) self.resizeRows(self.row + 1) def _xmluiGetSelectedWidgets(self): return [self.getWidget(self._xmlui_selected_row, col) for col in range(self.columns)] def _xmluiGetSelectedIndex(self): try: return self._xmlui_rows_idx[self._xmlui_selected_row] except TypeError: return None def _xmluiOnSelect(self, callback): self._xmlui_select_cb = callback class PairsContainer(xmlui.PairsContainer, Grid): def __init__(self, parent): Grid.__init__(self, 0, 0) self.row = 0 self.col = 0 def _xmluiAppend(self, widget): if self.col == 0: self.resize(self.row + 1, 2) self.setWidget(self.row, self.col, widget) self.col += 1 if self.col == 2: self.row += 1 self.col = 0 class TabsContainer(LiberviaContainer, xmlui.TabsContainer, TabPanel): def __init__(self, parent): TabPanel.__init__(self) self.setStyleName('liberviaTabPanel') def _xmluiAddTab(self, label): tab_panel = VerticalContainer(self) self.add(tab_panel, label) if len(self.getChildren()) == 1: self.selectTab(0) return tab_panel class VerticalContainer(LiberviaContainer, xmlui.VerticalContainer, VerticalPanel): __bases__ = (LiberviaContainer, xmlui.VerticalContainer, VerticalPanel) def __init__(self, parent): VerticalPanel.__init__(self) class WidgetFactory(object): # XXX: __getattr__ doesn't work here for an unknown reason def createVerticalContainer(self, *args, **kwargs): instance = VerticalContainer(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance def createPairsContainer(self, *args, **kwargs): instance = PairsContainer(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance def createTabsContainer(self, *args, **kwargs): instance = TabsContainer(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance def createAdvancedListContainer(self, *args, **kwargs): instance = AdvancedListContainer(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance def createEmptyWidget(self, *args, **kwargs): instance = EmptyWidget(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance def createTextWidget(self, *args, **kwargs): instance = TextWidget(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance def createLabelWidget(self, *args, **kwargs): instance = LabelWidget(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance def createJidWidget(self, *args, **kwargs): instance = JidWidget(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance def createDividerWidget(self, *args, **kwargs): instance = DividerWidget(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance def createStringWidget(self, *args, **kwargs): instance = StringWidget(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance def createPasswordWidget(self, *args, **kwargs): instance = PasswordWidget(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance def createTextBoxWidget(self, *args, **kwargs): instance = TextBoxWidget(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance def createBoolWidget(self, *args, **kwargs): instance = BoolWidget(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance def createButtonWidget(self, *args, **kwargs): instance = ButtonWidget(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance def createListWidget(self, *args, **kwargs): instance = ListWidget(*args, **kwargs) instance._xmlui_main = self._xmlui_main return instance # def __getattr__(self, attr): # if attr.startswith("create"): # cls = globals()[attr[6:]] # cls._xmlui_main = self._xmlui_main # return cls class XMLUI(xmlui.XMLUI, VerticalPanel): widget_factory = WidgetFactory() def __init__(self, host, xml_data, title=None, flags=None): self.widget_factory._xmlui_main = self self.dom = NativeDOM() dom_parse = lambda xml_data: self.dom.parseString(xml_data) VerticalPanel.__init__(self) self.setSize('100%', '100%') xmlui.XMLUI.__init__(self, host, xml_data, title, flags, dom_parse) def setCloseCb(self, close_cb): self.close_cb = close_cb def _xmluiClose(self): if self.close_cb: self.close_cb() else: log.warning("no close method defined") def _xmluiLaunchAction(self, action_id, data): self.host.launchAction(action_id, data) def _xmluiSetParam(self, name, value, category): self.host.bridge.call('setParam', None, name, value, category) def constructUI(self, xml_data): super(XMLUI, self).constructUI(xml_data) self.add(self.main_cont) self.setCellHeight(self.main_cont, '100%') if self.type == 'form': hpanel = HorizontalPanel() hpanel.setStyleName('marginAuto') hpanel.add(Button('Submit', self.onFormSubmitted)) if not 'NO_CANCEL' in self.flags: hpanel.add(Button('Cancel', self.onFormCancelled)) self.add(hpanel) elif self.type == 'param': assert(isinstance(self.children[0][0], TabPanel)) hpanel = HorizontalPanel() hpanel.add(Button('Save', self.onSaveParams)) hpanel.add(Button('Cancel', lambda ignore: self._xmluiClose())) self.add(hpanel)