# HG changeset patch # User Goffi # Date 1407931749 -7200 # Node ID 67a4e8383b7094e124c864e784985ad768f175ab # Parent ec3f30253040590470f4a06f6038414515fd1f20 browser side (XMLUI): XMLUI update to follow core changes: - Dialogs are now managed - FileDialog raise a NotImplementedError, it's not yet possible in Libervia - XMLUIPanel.show is implemented - following core changes, we now create an XMLUI with xmlui.create(...) - WidgetFactory now inherit from GenericFactory - workaround for __getattr__ bug in pyjamas, now createXXX are automaticaly created with inspection diff -r ec3f30253040 -r 67a4e8383b70 src/browser/libervia_main.py --- a/src/browser/libervia_main.py Fri Jul 25 11:43:27 2014 +0200 +++ b/src/browser/libervia_main.py Wed Aug 13 14:09:09 2014 +0200 @@ -407,11 +407,8 @@ # action was a one shot, nothing to do pass elif "xmlui" in data: - ui = xmlui.XMLUI(self, xml_data=data['xmlui']) - options = ['NO_CLOSE'] if ui.type == 'form' else [] - _dialog = dialog.GenericDialog(ui.title, ui, options=options) - ui.setCloseCb(_dialog.close) - _dialog.show() + ui = xmlui.create(self, xml_data=data['xmlui']) + ui.show() elif "public_blog" in data: # TODO: use the bare instead of node when all blogs can be retrieved node = jid.JID(data['public_blog']).node diff -r ec3f30253040 -r 67a4e8383b70 src/browser/sat_browser/card_game.py --- a/src/browser/sat_browser/card_game.py Fri Jul 25 11:43:27 2014 +0200 +++ b/src/browser/sat_browser/card_game.py Wed Aug 13 14:09:09 2014 +0200 @@ -299,7 +299,7 @@ def tarotGameChooseContrat(self, xml_data): """Called when the player has to select his contrat @param xml_data: SàT xml representation of the form""" - body = xmlui.XMLUI(self._parent.host, xml_data, flags=['NO_CANCEL']) + body = xmlui.create(self._parent.host, xml_data, flags=['NO_CANCEL']) _dialog = dialog.GenericDialog(_('Please choose your contrat'), body, options=['NO_CLOSE']) body.setCloseCb(_dialog.close) _dialog.show() @@ -381,7 +381,7 @@ title = "You win !" else: title = "You loose :(" - body = xmlui.XMLUI(self._parent.host, xml_data, title=title, flags=['NO_CANCEL']) + body = xmlui.create(self._parent.host, xml_data, title=title, flags=['NO_CANCEL']) _dialog = dialog.GenericDialog(title, body, options=['NO_CLOSE']) body.setCloseCb(_dialog.close) _dialog.show() diff -r ec3f30253040 -r 67a4e8383b70 src/browser/sat_browser/menu.py --- a/src/browser/sat_browser/menu.py Fri Jul 25 11:43:27 2014 +0200 +++ b/src/browser/sat_browser/menu.py Wed Aug 13 14:09:09 2014 +0200 @@ -173,7 +173,7 @@ def gotUI(xml_ui): if not xml_ui: return - body = xmlui.XMLUI(self.host, xml_ui) + body = xmlui.create(self.host, xml_ui) _dialog = dialog.GenericDialog("Manage your account", body, options=['NO_CLOSE']) body.setCloseCb(_dialog.close) _dialog.show() @@ -183,7 +183,7 @@ def gotParams(xml_ui): if not xml_ui: return - body = xmlui.XMLUI(self.host, xml_ui) + body = xmlui.create(self.host, xml_ui) _dialog = dialog.GenericDialog("Parameters", body, options=['NO_CLOSE']) body.setCloseCb(_dialog.close) _dialog.setSize('80%', '80%') diff -r ec3f30253040 -r 67a4e8383b70 src/browser/sat_browser/xmlui.py --- a/src/browser/sat_browser/xmlui.py Fri Jul 25 11:43:27 2014 +0200 +++ b/src/browser/sat_browser/xmlui.py Wed Aug 13 14:09:09 2014 +0200 @@ -20,6 +20,8 @@ from sat.core.log import getLogger log = getLogger(__name__) from sat_frontends.tools import xmlui +from sat_browser.constants import Const as C +from sat_browser import dialog from pyjamas.ui.VerticalPanel import VerticalPanel from pyjamas.ui.HorizontalPanel import HorizontalPanel @@ -39,34 +41,34 @@ class EmptyWidget(xmlui.EmptyWidget, Label): - def __init__(self, parent): + def __init__(self, _xmlui_parent): Label.__init__(self, '') class TextWidget(xmlui.TextWidget, Label): - def __init__(self, parent, value): + def __init__(self, _xmlui_parent, value): Label.__init__(self, value) class LabelWidget(xmlui.LabelWidget, TextWidget): - def __init__(self, parent, value): - TextWidget.__init__(self, parent, value + ": ") + def __init__(self, _xmlui_parent, value): + TextWidget.__init__(self, _xmlui_parent, value + ": ") class JidWidget(xmlui.JidWidget, TextWidget): - def __init__(self, parent, value): - TextWidget.__init__(self, parent, value) + def __init__(self, _xmlui_parent, value): + TextWidget.__init__(self, _xmlui_parent, value) class DividerWidget(xmlui.DividerWidget, HTML): - def __init__(self, parent, style='line'): + def __init__(self, _xmlui_parent, style='line'): """Add a divider - @param parent + @param _xmlui_parent @param style (string): one of: - line: a simple line - dot: a line of dots @@ -80,7 +82,7 @@ class StringWidget(xmlui.StringWidget, TextBox): - def __init__(self, parent, value, read_only=False): + def __init__(self, _xmlui_parent, value, read_only=False): TextBox.__init__(self) self.setText(value) self.setReadonly(read_only) @@ -97,7 +99,7 @@ class PasswordWidget(xmlui.PasswordWidget, PasswordTextBox): - def __init__(self, parent, value, read_only=False): + def __init__(self, _xmlui_parent, value, read_only=False): PasswordTextBox.__init__(self) self.setText(value) self.setReadonly(read_only) @@ -114,7 +116,7 @@ class TextBoxWidget(xmlui.TextBoxWidget, TextArea): - def __init__(self, parent, value, read_only=False): + def __init__(self, _xmlui_parent, value, read_only=False): TextArea.__init__(self) self.setText(value) self.setReadonly(read_only) @@ -131,7 +133,7 @@ class BoolWidget(xmlui.BoolWidget, CheckBox): - def __init__(self, parent, state, read_only=False): + def __init__(self, _xmlui_parent, state, read_only=False): CheckBox.__init__(self) self.setChecked(state) self.setReadonly(read_only) @@ -148,7 +150,7 @@ class ButtonWidget(xmlui.ButtonWidget, Button): - def __init__(self, parent, value, click_callback): + def __init__(self, _xmlui_parent, value, click_callback): Button.__init__(self, value, click_callback) def _xmluiOnClick(self, callback): @@ -157,7 +159,7 @@ class ListWidget(xmlui.ListWidget, ListBox): - def __init__(self, parent, options, selected, flags): + def __init__(self, _xmlui_parent, options, selected, flags): ListBox.__init__(self) multi_selection = 'single' not in flags self.setMultipleSelect(multi_selection) @@ -209,7 +211,7 @@ class AdvancedListContainer(xmlui.AdvancedListContainer, Grid): - def __init__(self, parent, columns, selectable='no'): + def __init__(self, _xmlui_parent, columns, selectable='no'): Grid.__init__(self, 0, columns) self.columns = columns self.row = -1 @@ -255,7 +257,7 @@ class PairsContainer(xmlui.PairsContainer, Grid): - def __init__(self, parent): + def __init__(self, _xmlui_parent): Grid.__init__(self, 0, 0) self.row = 0 self.col = 0 @@ -272,7 +274,7 @@ class TabsContainer(LiberviaContainer, xmlui.TabsContainer, TabPanel): - def __init__(self, parent): + def __init__(self, _xmlui_parent): TabPanel.__init__(self) self.setStyleName('liberviaTabPanel') @@ -287,89 +289,79 @@ class VerticalContainer(LiberviaContainer, xmlui.VerticalContainer, VerticalPanel): __bases__ = (LiberviaContainer, xmlui.VerticalContainer, VerticalPanel) - def __init__(self, parent): + def __init__(self, _xmlui_parent): VerticalPanel.__init__(self) -class WidgetFactory(object): - # XXX: __getattr__ doesn't work here for an unknown reason +## Dialogs ## - def createVerticalContainer(self, *args, **kwargs): - instance = VerticalContainer(*args, **kwargs) - instance._xmlui_main = self._xmlui_main - return instance + +class Dlg(object): - def createPairsContainer(self, *args, **kwargs): - instance = PairsContainer(*args, **kwargs) - instance._xmlui_main = self._xmlui_main - return instance + def _xmluiShow(self): + self.show() - def createTabsContainer(self, *args, **kwargs): - instance = TabsContainer(*args, **kwargs) - instance._xmlui_main = self._xmlui_main - return instance + def _xmluiClose(self): + pass + + +class MessageDialog(Dlg, xmlui.MessageDialog, dialog.InfoDialog): - def createAdvancedListContainer(self, *args, **kwargs): - instance = AdvancedListContainer(*args, **kwargs) - instance._xmlui_main = self._xmlui_main - return instance + def __init__(self, _xmlui_parent, title, message, level): + #TODO: level is not managed + Dlg.__init__(self) + xmlui.MessageDialog.__init__(self, _xmlui_parent) + dialog.InfoDialog.__init__(self, title, message, self._xmluiValidated()) - 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 +class NoteDialog(xmlui.NoteDialog, MessageDialog): + # TODO: separate NoteDialog - def createLabelWidget(self, *args, **kwargs): - instance = LabelWidget(*args, **kwargs) - instance._xmlui_main = self._xmlui_main - return instance + def __init__(self, _xmlui_parent, title, message, level): + xmlui.NoteDialog.__init__(self, _xmlui_parent) + MessageDialog.__init__(self, _xmlui_parent, title, message, level) + + +class ConfirmDialog(xmlui.ConfirmDialog, Dlg, dialog.ConfirmDialog): - 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 __init__(self, _xmlui_parent, title, message, level): + #TODO: level is not managed + xmlui.ConfirmDialog.__init__(self, _xmlui_parent) + print "self.parent = %s" % self._xmlui_parent + Dlg.__init__(self) + dialog.ConfirmDialog.__init__(self, self.answered, message, title) - def createStringWidget(self, *args, **kwargs): - instance = StringWidget(*args, **kwargs) - instance._xmlui_main = self._xmlui_main - return instance + def answered(self, validated): + if validated: + self._xmluiValidated() + else: + self._xmluiCancelled() - def createPasswordWidget(self, *args, **kwargs): - instance = PasswordWidget(*args, **kwargs) - instance._xmlui_main = self._xmlui_main - return instance + +class FileDialog(xmlui.FileDialog, Dlg): + #TODO: - def createTextBoxWidget(self, *args, **kwargs): - instance = TextBoxWidget(*args, **kwargs) - instance._xmlui_main = self._xmlui_main - return instance + def __init__(self, _xmlui_parent, title, message, level, filetype): + raise NotImplementedError("FileDialog is not implemented in Libervia yet") + - def createBoolWidget(self, *args, **kwargs): - instance = BoolWidget(*args, **kwargs) - instance._xmlui_main = self._xmlui_main - return instance +class GenericFactory(object): + # XXX: __getattr__ doens't work here with pyjamas for an unknown reason + # so an introspection workaround is used + + def __init__(self): - def createButtonWidget(self, *args, **kwargs): - instance = ButtonWidget(*args, **kwargs) - instance._xmlui_main = self._xmlui_main - return instance + for name, cls in globals().items(): + if name.endswith("Widget") or name.endswith("Container") or name.endswith("Dialog"): + log.info("registering: %s" % name) + def createCreater(cls): + return lambda *args, **kwargs: self._genericCreate(cls, *args, **kwargs) + setattr(self, "create%s" % name, createCreater(cls)) - def createListWidget(self, *args, **kwargs): - instance = ListWidget(*args, **kwargs) - instance._xmlui_main = self._xmlui_main + def _genericCreate(self, cls, *args, **kwargs): + instance = cls(*args, **kwargs) return instance - # def __getattr__(self, attr): # if attr.startswith("create"): # cls = globals()[attr[6:]] @@ -377,16 +369,27 @@ # return cls -class XMLUI(xmlui.XMLUI, VerticalPanel): +class WidgetFactory(GenericFactory): + + def _genericCreate(self, cls, *args, **kwargs): + instance = GenericFactory._genericCreate(self, cls, *args, **kwargs) + instance._xmlui_main = self._xmlui_main + return instance + +class LiberviaXMLUIBase(object): + + def _xmluiLaunchAction(self, action_id, data): + self.host.launchAction(action_id, data) + + +class XMLUIPanel(LiberviaXMLUIBase, xmlui.XMLUIPanel, VerticalPanel): widget_factory = WidgetFactory() - def __init__(self, host, xml_data, title=None, flags=None): + def __init__(self, host, parsed_xml, title=None, flags=None): self.widget_factory._xmlui_main = self - self.dom = nativedom.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) + xmlui.XMLUIPanel.__init__(self, host, parsed_xml, title, flags) def setCloseCb(self, close_cb): self.close_cb = close_cb @@ -397,14 +400,11 @@ 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) + def constructUI(self, parsed_dom): + super(XMLUIPanel, self).constructUI(parsed_dom) self.add(self.main_cont) self.setCellHeight(self.main_cont, '100%') if self.type == 'form': @@ -420,3 +420,24 @@ hpanel.add(Button('Save', self.onSaveParams)) hpanel.add(Button('Cancel', lambda ignore: self._xmluiClose())) self.add(hpanel) + + def show(self): + options = ['NO_CLOSE'] if self.type == C.XMLUI_FORM else [] + _dialog = dialog.GenericDialog(self.title, self, options=options) + self.setCloseCb(_dialog.close) + _dialog.show() + + +class XMLUIDialog(LiberviaXMLUIBase, xmlui.XMLUIDialog): + dialog_factory = GenericFactory() + + def __init__(self, host, parsed_dom, title = None, flags = None): + xmlui.XMLUIDialog.__init__(self, host, parsed_dom, title, flags) + +xmlui.registerClass(xmlui.CLASS_PANEL, XMLUIPanel) +xmlui.registerClass(xmlui.CLASS_DIALOG, XMLUIDialog) + +def create(*args, **kwargs): + dom = nativedom.NativeDOM() + kwargs['dom_parse'] = lambda xml_data: dom.parseString(xml_data) + return xmlui.create(*args, **kwargs)