changeset 104:5458ac1380cc

XMLUI: added tabs layout xmltools: tabs layout are added, and a new addCategory method is used to add tabs wix: tabs layout are managed with notebook
author Goffi <goffi@goffi.org>
date Wed, 23 Jun 2010 14:55:04 +0800
parents 6be927a465ed
children d2630fba8dfd
files frontends/wix/xmlui.py tools/xml_tools.py
diffstat 2 files changed, 75 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/wix/xmlui.py	Wed Jun 23 00:23:26 2010 +0800
+++ b/frontends/wix/xmlui.py	Wed Jun 23 14:55:04 2010 +0800
@@ -54,9 +54,9 @@
 
         self.Show()
 
-    def __parse_elems(self, childs, parent, sizer):
-        """Parse elements inside a <layout> tags, and add them to the sizer"""
-        for elem in childs:
+    def __parseElems(self, node, parent):
+        """Parse elements inside a <layout> tags, and add them to the parent sizer"""
+        for elem in node.childNodes:
             if elem.nodeName != "elem":
                 message=_("Unmanaged tag")
                 error(message)
@@ -90,40 +90,67 @@
             else:
                 error(_("FIXME FIXME FIXME: type [%s] is not implemented") % type)  #FIXME !
                 raise NotImplementedError
-            sizer.Add(ctrl, _proportion, flag=wx.EXPAND)
+            parent.sizer.Add(ctrl, _proportion, flag=wx.EXPAND)
 
+    def __parseChilds(self, parent, current_param, elem, wanted = ['layout']):
+        """Recursively parse childNodes of an elemen
+        @param parent: parent wx.Window
+        @param current_param: current wx.Window (often wx.Panel) or None if we must create one
+        @param elem: element from which childs will be parsed
+        @param wanted: list of tag names that can be present in the childs to be SàT XMLUI compliant"""
+        for node in elem.childNodes:
+            if wanted and not node.nodeName in wanted:
+                raise Exception("Invalid XMLUI") #TODO: make a custom exception
+            if node.nodeName == "layout":
+                type = node.getAttribute('type')
+                if type == "tabs":
+                    current = wx.Notebook(parent, -1, style=wx.NB_LEFT if self.type=='param' else 0)
+                    self.__parseChilds(current, None, node, ['category'])
+                else:
+                    if current_param == None:
+                        current = wx.Panel(parent, -1)
+                    else:
+                        current = current_param
+                    if type == "vertical":
+                        current.sizer = wx.BoxSizer(wx.VERTICAL)
+                    elif type == "pairs":
+                        current.sizer = wx.FlexGridSizer(cols=2)
+                        current.sizer.AddGrowableCol(1) #The growable column need most of time to be the right one in pairs
+                    else:
+                        warning(_("Unknown layout, using default one"))
+                        current.sizer = wx.BoxSizer(wx.VERTICAL)
+                    current.SetSizer(current.sizer)
+                    self.__parseElems(node, current)
+                if parent:
+                    parent.sizer.Add(current, flag=wx.EXPAND)
+            elif node.nodeName == "category":
+                name = node.getAttribute('name') 
+                if not node.nodeName in wanted or not name or not isinstance(parent,wx.Notebook):
+                    raise Exception("Invalid XMLUI") #TODO: make a custom exception
+                notebook = parent
+                tab_panel = wx.Panel(notebook, -1) 
+                tab_panel.sizer = wx.BoxSizer(wx.VERTICAL)
+                tab_panel.SetSizer(tab_panel.sizer)
+                notebook.AddPage(tab_panel, name)
+                self.__parseChilds(tab_panel, None, node, ['layout'])
+
+            else:
+                message=_("Unknown tag")
+                error(message)
+                raise Exception(message) #TODO: raise a custom exception here
 
 
     def constructUI(self, xml_data):
         panel=wx.Panel(self)
         panel.sizer = wx.BoxSizer(wx.VERTICAL)
-
+        
         cat_dom = minidom.parseString(xml_data.encode('utf-8'))
         top= cat_dom.documentElement
         self.type = top.getAttribute("type")
         if top.nodeName != "sat_xmlui" or not self.type in ['form', 'param', 'window']:
-            message = _("XML UI received is invalid")
-            error(message)
-            raise Exception(message)
+            raise Exception("Invalid XMLUI") #TODO: make a custom exception
 
-        for node in cat_dom.documentElement.childNodes:
-            if node.nodeName == "layout":
-                layout_panel = wx.Panel(panel, -1)
-                if node.getAttribute('type') == "vertical":
-                    current_sizer = wx.BoxSizer(wx.VERTICAL)
-                elif node.getAttribute('type') == "pairs":
-                    current_sizer = wx.FlexGridSizer(cols=2)
-                    current_sizer.AddGrowableCol(1) #The growable column need most of time to be the right one in pairs
-                else:
-                    warning(_("Unknown layout, using default one"))
-                    current_sizer = wx.BoxSizer(wx.VERTICAL)
-                layout_panel.SetSizer(current_sizer)
-                self.__parse_elems(node.childNodes, layout_panel, current_sizer)
-                panel.sizer.Add(layout_panel, flag=wx.EXPAND)
-            else:
-                message=_("Unknown tag")
-                error(message)
-                raise Exception(message) #TODO: raise a custom exception here
+        self.__parseChilds(panel, None, cat_dom.documentElement)
 
         if self.type == 'form':
             dialogButtons = wx.StdDialogButtonSizer()
--- a/tools/xml_tools.py	Wed Jun 23 00:23:26 2010 +0800
+++ b/tools/xml_tools.py	Wed Jun 23 14:55:04 2010 +0800
@@ -32,6 +32,7 @@
     
     form_panel = XMLUI("form", "vertical")
     
+
     if form.instructions:
         form_panel.addText('\n'.join(form.instructions), 'instructions')
     
@@ -91,7 +92,9 @@
         self.doc = impl.createDocument(None, "sat_xmlui", None)
         top_element = self.doc.documentElement
         top_element.setAttribute("type", panel_type)
-        self.currentLayout = self.__createLayout(layout, top_element)
+        self.parentTabsLayout = None #used only we have 'tabs' layout
+        self.currentCategory = None #used only we have 'tabs' layout
+        self.changeLayout(layout)
 
     def __del__(self):
         self.doc.unlink() 
@@ -101,7 +104,7 @@
         @param type: layout type (cf init doc)
         @parent: parent element or None
         """
-        if not layout in ['vertical', 'horizontal', 'pairs']:
+        if not layout in ['vertical', 'horizontal', 'pairs', 'tabs']:
             error (_("Unknown layout type [%s]") % layout)
             assert (False)
         layout_elt = self.doc.createElement('layout')
@@ -128,7 +131,9 @@
 
     def changeLayout(self, layout):
         """Change the current layout"""
-        self.currentLayout = self.__createLayout(layout, self.doc.documentElement)
+        self.currentLayout = self.__createLayout(layout, self.currentCategory if self.currentCategory else self.doc.documentElement)
+        if layout == "tabs":
+            self.parentTabsLayout = self.currentLayout
 
 
     def addEmpty(self, name=None):
@@ -190,6 +195,20 @@
             opt.setAttribute('value', option)
             parent.appendChild(opt)
 
+    def addCategory(self, name, layout):
+        """Add a category to current layout (must be a tabs layout)"""
+        assert(layout != 'tabs')
+        if not self.parentTabsLayout:
+            error(_("Trying to add a category without parent tabs layout"))
+            assert(False)
+        if self.parentTabsLayout.getAttribute('type') != 'tabs':
+            error(_("parent layout of a category is not tabs"))
+            assert(False)
+        self.currentCategory = cat = self.doc.createElement('category')
+        cat.setAttribute('name', name)
+        self.changeLayout(layout)
+        self.parentTabsLayout.appendChild(cat)
+
     def toXml(self):
         """return the XML representation of the panel""" 
         return self.doc.toxml()