changeset 500:67a4e8383b70

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
author Goffi <goffi@goffi.org>
date Wed, 13 Aug 2014 14:09:09 +0200
parents ec3f30253040
children b483f1c88b7c
files src/browser/libervia_main.py src/browser/sat_browser/card_game.py src/browser/sat_browser/menu.py src/browser/sat_browser/xmlui.py
diffstat 4 files changed, 118 insertions(+), 100 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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 <b>win</b> !"
             else:
                 title = "You <b>loose</b> :("
-        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()
--- 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%')
--- 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)