changeset 804:5174657b3378

XMLUI (core, frontends): added JidWidget and DividerWidget + popup type + some bugfixes: - JidWidget is a text container a Jabber ID, this can be used by frontends for special treatment (e.g.: possibility to click on it) - DividerWidget is a separator, like a blank or dashed line - popup type is similar to normal window, but designed for a smaller popping window
author Goffi <goffi@goffi.org>
date Tue, 04 Feb 2014 18:19:32 +0100
parents f100fd8d279f
children 7c05c39156a2
files frontends/src/primitivus/primitivus frontends/src/primitivus/xmlui.py frontends/src/tools/xmlui.py frontends/src/wix/xmlui.py src/tools/xml_tools.py
diffstat 5 files changed, 122 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/src/primitivus/primitivus	Tue Feb 04 18:19:29 2014 +0100
+++ b/frontends/src/primitivus/primitivus	Tue Feb 04 18:19:32 2014 +0100
@@ -455,7 +455,7 @@
                 pass
             elif "xmlui" in data:
                 ui = XMLUI(self, xml_data = data['xmlui'])
-                ui.show('popup')
+                ui.show()
             else:
                 self.showPopUp(sat_widgets.Alert(_("Error"), _(u"Unmanaged action result"), ok_cb=self.removePopUp))
         def action_eb(failure):
--- a/frontends/src/primitivus/xmlui.py	Tue Feb 04 18:19:29 2014 +0100
+++ b/frontends/src/primitivus/xmlui.py	Tue Feb 04 18:19:32 2014 +0100
@@ -49,6 +49,35 @@
         urwid.Text.__init__(self, value)
 
 
+class PrimitivusLabelWidget(xmlui.LabelWidget, PrimitivusTextWidget):
+
+    def __init__(self, parent, value):
+        super(PrimitivusLabelWidget, self).__init__(parent, value+": ")
+
+
+class PrimitivusJidWidget(xmlui.JidWidget, PrimitivusTextWidget):
+    pass
+
+
+class PrimitivusDividerWidget(xmlui.DividerWidget, urwid.Divider):
+
+    def __init__(self, parent, style='line'):
+        if style == 'line':
+            div_char = u'─'
+        elif style == 'dot':
+            div_char = u'·'
+        elif style == 'dash':
+            div_char = u'-'
+        elif style == 'plain':
+            div_char = u'█'
+        elif style == 'blank':
+            div_char = ' '
+        else:
+            warning(_("Unknown div_char"))
+            div_char = u'─'
+
+        urwid.Divider.__init__(self, div_char)
+
 class PrimitivusStringWidget(xmlui.StringWidget, sat_widgets.AdvancedEdit, PrimitivusEvents):
 
     def __init__(self, parent, value):
@@ -168,7 +197,7 @@
 
     def __init__(self, host, xml_data, title = None, flags = None):
         self.widget_factory._xmlui_main = self
-        self._dest = "window"
+        self._dest = None
         xmlui.XMLUI.__init__(self, host, xml_data, title, flags)
         urwid.WidgetWrap.__init__(self, self.main_cont)
 
@@ -199,23 +228,32 @@
         super(XMLUI, self).constructUI(xml_data, postTreat)
         urwid.WidgetWrap.__init__(self, self.main_cont)
 
-    def show(self, show_type='popup', valign='middle'):
+    def show(self, show_type=None, valign='middle'):
         """Show the constructed UI
         @param show_type: how to show the UI:
-            - popup
-            - window
+            - None (follow XMLUI's recommendation)
+            - 'popup'
+            - 'window'
         @param valign: vertical alignment when show_type is 'popup'.
                        Ignored when show_type is 'window'.
 
         """
-        self._dest = "popup"
+        if show_type is None:
+            if self.type in ('window', 'param'):
+                show_type = 'window'
+            elif self.type in ('popup', 'form'):
+                show_type = 'popup'
+
+        if show_type not in ('popup', 'window'):
+            raise ValueError('Invalid show_type [%s]' % show_type)
+
+        self._dest = show_type
         decorated = sat_widgets.LabelLine(self, sat_widgets.SurroundedText(self.title or ''))
         if show_type == 'popup':
             self.host.showPopUp(decorated, valign=valign)
         elif show_type == 'window':
             self.host.addWindow(decorated)
         else:
-            error(_('INTERNAL ERROR: Unmanaged show_type (%s)') % show_type)
             assert(False)
         self.host.redraw()
 
--- a/frontends/src/tools/xmlui.py	Tue Feb 04 18:19:29 2014 +0100
+++ b/frontends/src/tools/xmlui.py	Tue Feb 04 18:19:32 2014 +0100
@@ -54,6 +54,21 @@
     pass
 
 
+class LabelWidget(Widget):
+    """ Non interactive text """
+    pass
+
+
+class JidWidget(Widget):
+    """ Jabber ID """
+    pass
+
+
+class DividerWidget(Widget):
+    """ Separator """
+    pass
+
+
 class StringWidget(Widget):
     """ Input widget with require a string
     often called Edit in toolkits
@@ -124,6 +139,7 @@
     """ Widgets are disposed in rows with advaned features """
     pass
 
+
 class XMLUI(object):
     """ Base class to construct SàT XML User Interface
     New frontends can inherite this class to easily implement XMLUI
@@ -247,7 +263,12 @@
                         warning (_("text node has no child !"))
                     ctrl = self.widget_factory.createTextWidget(parent, value)
                 elif type_=="label":
-                    ctrl = self.widget_factory.createTextWidget(parent, value+": ")
+                    ctrl = self.widget_factory.createLabelWidget(parent, value)
+                elif type_=="jid":
+                    ctrl = self.widget_factory.createJidWidget(parent, value)
+                elif type_=="divider":
+                    style = node.getAttribute("style") or 'line'
+                    ctrl = self.widget_factory.createDividerWidget(parent, style)
                 elif type_=="string":
                     ctrl = self.widget_factory.createStringWidget(parent, value)
                     self.ctrl_list[name] = ({'type':type_, 'control':ctrl})
@@ -300,7 +321,7 @@
         self.title = self.title or top.getAttribute("title") or u""
         self.session_id = top.getAttribute("session_id") or None
         self.submit_id = top.getAttribute("submit") or None
-        if top.nodeName != "sat_xmlui" or not self.type in ['form', 'param', 'window']:
+        if top.nodeName != "sat_xmlui" or not self.type in ['form', 'param', 'window', 'popup']:
             raise InvalidXMLUI
 
         if self.type == 'param':
--- a/frontends/src/wix/xmlui.py	Tue Feb 04 18:19:29 2014 +0100
+++ b/frontends/src/wix/xmlui.py	Tue Feb 04 18:19:32 2014 +0100
@@ -57,6 +57,22 @@
         wx.StaticText.__init__(self, parent, -1, value)
 
 
+class LabelWidget(xmlui.LabelWidget, TextWidget):
+
+    def __init__(self, parent, value):
+        super(LabelWidget, self).__init__(parent, value+": ")
+
+
+class JidWidget(xmlui.JidWidget, TextWidget):
+    pass
+
+
+class DividerWidget(WixWidget, xmlui.DividerWidget, wx.StaticLine):
+
+    def __init__(self, parent, style='line'):
+        wx.StaticLine.__init__(self, parent, -1)
+
+
 class StringWidget(EventWidget, ValueWidget, xmlui.StringWidget, wx.TextCtrl):
     _xmlui_change_event = wx.EVT_TEXT
 
--- a/src/tools/xml_tools.py	Tue Feb 04 18:19:29 2014 +0100
+++ b/src/tools/xml_tools.py	Tue Feb 04 18:19:32 2014 +0100
@@ -424,6 +424,7 @@
             self.addHeader(header)
 
     def addHeader(self, header):
+
         pass # TODO
 
     def addItems(self, items):
@@ -443,7 +444,7 @@
         change current container to first container parent
 
         """
-        if self._current_colum % self._columns != 0:
+        if self._item_idx % self._columns != 0:
             raise exceptions.DataError(_("Incorrect number of items in list"))
         parent_container = self.getParentContainer()
         self.xmlui.changeContainer(parent_container)
@@ -490,6 +491,37 @@
         self.elem.setAttribute('value', label)
 
 
+class JidWidget(Widget):
+    type='jid'
+
+    def __init__(self, xmlui, jid, name=None, parent=None):
+        super(JidWidget, self).__init__(xmlui, name, parent)
+        try:
+            self.elem.setAttribute('value', jid.full())
+        except AttributeError:
+            self.elem.setAttribute('value', unicode(jid))
+
+
+class DividerWidget(Widget):
+    type = 'divider'
+
+    def __init__(self, xmlui, style='line', name=None, parent=None):
+        """ Create a divider
+        @param xmlui: XMLUI instance
+        @param style: 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
+        @param name: name of the widget
+        @param parent: parent container
+
+        """
+        super(DividerWidget, self).__init__(xmlui, name, parent)
+        self.elem.setAttribute('style', style)
+
+
 class StringWidget(InputWidget):
     type = 'string'
 
@@ -521,7 +553,7 @@
         self.elem.setAttribute('value', value)
 
 
-class ButtonWidget(InputWidget):
+class ButtonWidget(Widget):
     type = 'button'
 
     def __init__(self, xmlui, callback_id, value=None, fields_back=None, name=None, parent=None):
@@ -571,10 +603,11 @@
 class XMLUI(object):
     """This class is used to create a user interface (form/window/parameters/etc) using SàT XML"""
 
-    def __init__(self, panel_type, container="vertical", title=None, submit_id=None, session_id=None):
+    def __init__(self, panel_type="window", container="vertical", title=None, submit_id=None, session_id=None):
         """Init SàT XML Panel
         @param panel_type: one of
             - window (new window)
+            - popup
             - form (formulaire, depend of the frontend, usually a panel with cancel/submit buttons)
             - param (parameters, presentation depend of the frontend)
         @param container: disposition of elements, one of:
@@ -587,7 +620,7 @@
         @param submit_id: callback id to call for panel_type we can submit (form, param)
         """
         self._introspect()
-        if panel_type not in ['window', 'form', 'param']:
+        if panel_type not in ['window', 'form', 'param', 'popup']:
             raise exceptions.DataError(_("Unknown panel type [%s]") % panel_type)
         if panel_type == 'form' and submit_id is None:
             raise exceptions.DataError(_("form XMLUI need a submit_id"))
@@ -686,7 +719,7 @@
         if container not in self._containers:
             raise exceptions.DataError(_("Unknown container type [%s]") % container)
         cls = self._containers[container]
-        new_container = cls(self, parent, **kwargs)
+        new_container = cls(self, parent=parent, **kwargs)
         return new_container
 
     def changeContainer(self, container, **kwargs):