]> git.saurik.com Git - wxWidgets.git/commitdiff
More XRCed updates from Roman
authorRobin Dunn <robin@alldunn.com>
Thu, 7 Mar 2002 21:33:31 +0000 (21:33 +0000)
committerRobin Dunn <robin@alldunn.com>
Thu, 7 Mar 2002 21:33:31 +0000 (21:33 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14484 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

wxPython/CHANGES.txt
wxPython/tools/XRCed/CHANGES
wxPython/tools/XRCed/params.py
wxPython/tools/XRCed/xrced.ico
wxPython/tools/XRCed/xrced.py
wxPython/tools/XRCed/xrced.xrc
wxPython/tools/XRCed/xxx.py

index 5d91cdb7c2c9069dbd2589383b2bbd5ecf6b1f80..6d1f99f7b6b81f371707e1b7484013904f2ac516 100644 (file)
@@ -28,6 +28,8 @@ for each item, as well as optional column or row spanning.  Cells with
 no item assigned to it are just left blank.  Stretchable rows or
 columns are specified and work the same as in wxFlexGridSizer.
 
+Updated XRCed from Roman Rolinsky
+
 
 
 2.3.2.1
index eecd2c0ebef730c074252ebb2086b517202c740a..89b20ff696dd337ac6282757817c5f45db9f1c21 100644 (file)
@@ -39,17 +39,20 @@ Fixed double-clicking problem with tree control on Windows.
 
 Some performance improovements.
 
+
 0.0.5
 -----
 
 Added notebook with properties page and style page. Fixed some problems
 on Windows.
 
+
 0.0.4
 -----
 
 Some fixes suggested by RD
 
+
 0.0.3
 -----
 
index 89513a1fbf9402701808001d9d47076904900dfe..93b8d2fb3e0596020e8e9d18f488e34c1a8ccfde 100644 (file)
@@ -8,6 +8,7 @@ from wxPython.wx import *
 from wxPython.xrc import *
 import string
 import os.path
+from types import *
 
 # Object which is currently processed
 currentXXX = None
@@ -21,6 +22,8 @@ genericStyles = ['wxSIMPLE_BORDER', 'wxDOUBLE_BORDER',
                  'wxTRANSPARENT_WINDOW', 'wxWANTS_CHARS',
                  'wxNO_FULL_REPAINT_ON_RESIZE']
 
+buttonSize = (55,-1)
+
 # Class that can properly disable children
 class PPanel(wxPanel):
     def __init__(self, parent, name):
@@ -43,8 +46,8 @@ class ParamBinaryOr(PPanel):
         self.SetBackgroundColour(panel.GetBackgroundColour())
         sizer = wxBoxSizer()
         self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
-        sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 10)
-        self.button = wxButton(self, self.ID_BUTTON_CHOICES, 'Edit...')
+        sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
+        self.button = wxButton(self, self.ID_BUTTON_CHOICES, 'Edit...', size=buttonSize)
         sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
         self.SetAutoLayout(true)
         self.SetSizer(sizer)
@@ -90,7 +93,7 @@ class ParamBinaryOr(PPanel):
         dlg.SetSizer(topSizer)
         topSizer.Fit(dlg)
         dlg.Center()
-        if dlg.ShowModal() == wxID_OK:
+        if dlg.ShowModal() == wxID_OK: 
             value = []
             for i in range(listBox.Number()):
                 if listBox.IsChecked(i):
@@ -141,8 +144,8 @@ class ParamColour(PPanel):
         self.ID_BUTTON = wxNewId()
         self.SetBackgroundColour(panel.GetBackgroundColour())
         sizer = wxBoxSizer()
-        self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(60,-1))
-        sizer.Add(self.text, 0, wxRIGHT, 10)
+        self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=buttonSize)
+        sizer.Add(self.text, 0, wxRIGHT, 5)
         self.button = wxPanel(self, self.ID_BUTTON, wxDefaultPosition, wxSize(40, -1))
         sizer.Add(self.button, 0, wxGROW)
         self.SetAutoLayout(true)
@@ -207,8 +210,8 @@ class ParamFont(PPanel):
         self.SetBackgroundColour(panel.GetBackgroundColour())
         sizer = wxBoxSizer()
         self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
-        sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 10)
-        self.button = wxButton(self, self.ID_BUTTON_SELECT, 'Select...')
+        sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
+        self.button = wxButton(self, self.ID_BUTTON_SELECT, 'Select...', size=buttonSize)
         sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
         self.SetAutoLayout(true)
         self.SetSizer(sizer)
@@ -353,21 +356,21 @@ class ParamPosSize(ParamText):
 class ContentDialog(wxDialogPtr):
     def __init__(self, parent, value):
         # Is this normal???
-        w = frame.res.LoadDialog(parent, 'ID_DIALOG_CONTENT')
+        w = frame.res.LoadDialog(parent, 'DIALOG_CONTENT')
         wxDialogPtr.__init__(self, w.this)
         self.thisown = 1
         self.Center()
-        self.list = self.FindWindowByName('ID_LIST')
+        self.list = self.FindWindowByName('LIST')
         # Set list items
         for v in value:
             self.list.Append(v)
         self.SetAutoLayout(true)
         self.GetSizer().Fit(self)
         # Callbacks
-        self.ID_BUTTON_APPEND = XMLID('ID_BUTTON_APPEND')
-        self.ID_BUTTON_REMOVE = XMLID('ID_BUTTON_REMOVE')
-        self.ID_BUTTON_UP = XMLID('ID_BUTTON_UP')
-        self.ID_BUTTON_DOWN = XMLID('ID_BUTTON_DOWN')
+        self.ID_BUTTON_APPEND = XMLID('BUTTON_APPEND')
+        self.ID_BUTTON_REMOVE = XMLID('BUTTON_REMOVE')
+        self.ID_BUTTON_UP = XMLID('BUTTON_UP')
+        self.ID_BUTTON_DOWN = XMLID('BUTTON_DOWN')
         EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp)
         EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown)
         EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend)
@@ -404,11 +407,11 @@ class ContentDialog(wxDialogPtr):
 class ContentCheckListDialog(wxDialogPtr):
     def __init__(self, parent, value):
         # Is this normal???
-        w = frame.res.LoadDialog(parent, 'ID_DIALOG_CONTENT_CHECK_LIST')
+        w = frame.res.LoadDialog(parent, 'DIALOG_CONTENT_CHECK_LIST')
         wxDialogPtr.__init__(self, w.this)
         self.thisown = 1
         self.Center()
-        self.list = self.FindWindowByName('ID_CHECK_LIST')
+        self.list = self.FindWindowByName('CHECK_LIST')
         # Set list items
         i = 0
         for v,ch in value:
@@ -418,10 +421,10 @@ class ContentCheckListDialog(wxDialogPtr):
         self.SetAutoLayout(true)
         self.GetSizer().Fit(self)
         # Callbacks
-        self.ID_BUTTON_APPEND = XMLID('ID_BUTTON_APPEND')
-        self.ID_BUTTON_REMOVE = XMLID('ID_BUTTON_REMOVE')
-        self.ID_BUTTON_UP = XMLID('ID_BUTTON_UP')
-        self.ID_BUTTON_DOWN = XMLID('ID_BUTTON_DOWN')
+        self.ID_BUTTON_APPEND = XMLID('BUTTON_APPEND')
+        self.ID_BUTTON_REMOVE = XMLID('BUTTON_REMOVE')
+        self.ID_BUTTON_UP = XMLID('BUTTON_UP')
+        self.ID_BUTTON_DOWN = XMLID('BUTTON_DOWN')
         EVT_CHECKLISTBOX(self, self.list.GetId(), self.OnCheck)
         EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp)
         EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown)
@@ -469,8 +472,8 @@ class ParamContent(PPanel):
         self.SetBackgroundColour(panel.GetBackgroundColour())
         sizer = wxBoxSizer()
         self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
-        sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 10)
-        self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...')
+        sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
+        self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize)
         sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
         self.SetAutoLayout(true)
         self.SetSizer(sizer)
@@ -493,6 +496,7 @@ class ParamContent(PPanel):
         return self.value
     def SetValue(self, value):
         self.freeze = true
+        if not value: value = []
         self.value = value
         self.text.SetValue(str(value))  # update text ctrl
         self.freeze = false
@@ -515,41 +519,78 @@ class ParamContent(PPanel):
         dlg.Destroy()
 
 # CheckList content
-class ParamContentCheckList(PPanel):
+class ParamContentCheckList(ParamContent):
     def __init__(self, parent, name):
-        PPanel.__init__(self, parent, name)
-        self.ID_TEXT_CTRL = wxNewId()
-        self.ID_BUTTON_EDIT = wxNewId()
-        self.SetBackgroundColour(panel.GetBackgroundColour())
-        sizer = wxBoxSizer()
-        self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
-        sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 10)
-        self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...')
-        sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
-        self.SetAutoLayout(true)
-        self.SetSizer(sizer)
-        sizer.Fit(self)
-        self.textModified = false
-        EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit)
-        EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
-    def OnChange(self, evt):
-        if self.freeze: return
-        self.SetModified()
-        self.textModified = true
-        evt.Skip()
-    def GetValue(self):
+        ParamContent.__init__(self, parent, name)
+    def OnButtonEdit(self, evt):
         if self.textModified:           # text has newer value
             try:
-                return eval(self.text.GetValue())
+                self.value = eval(self.text.GetValue())
             except SyntaxError:
                 wxLogError('Syntax error in parameter value: ' + self.GetName())
-                return []
-        return self.value
-    def SetValue(self, value):
-        self.freeze = true
-        self.value = value
-        self.text.SetValue(str(value))  # update text ctrl
-        self.freeze = false
+                self.value = []
+        dlg = ContentCheckListDialog(self, self.value)
+        if dlg.ShowModal() == wxID_OK:
+            value = []
+            for i in range(dlg.list.Number()):
+                value.append((dlg.list.GetString(i), dlg.list.IsChecked(i)))
+            # Add ignored flags
+            self.SetValue(value)
+            self.SetModified()
+            self.textModified = false
+        dlg.Destroy()
+
+class IntListDialog(wxDialogPtr):
+    def __init__(self, parent, value):
+        # Is this normal???
+        w = frame.res.LoadDialog(parent, 'DIALOG_INTLIST')
+        wxDialogPtr.__init__(self, w.this)
+        self.thisown = 1
+        self.Center()
+        self.list = self.FindWindowByName('LIST')
+        # Set list items
+        value.sort()
+        for v in value:
+            if type(v) != IntType:
+                wxLogError('Invalid item type')
+            else:
+                self.list.Append(str(v))
+        self.SetAutoLayout(true)
+        self.GetSizer().Fit(self)
+        # Callbacks
+        self.ID_BUTTON_ADD = XMLID('BUTTON_ADD')
+        self.ID_BUTTON_REMOVE = XMLID('BUTTON_REMOVE')
+        EVT_BUTTON(self, self.ID_BUTTON_ADD, self.OnButtonAppend)
+        EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
+        EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
+    def OnButtonAppend(self, evt):
+        s = wxGetTextFromUser('Enter new number:', 'Add', '', self)
+        # Check that it's unique
+        try:
+            v = int(s)
+            s = str(v)                  # to be sure
+            i = self.list.FindString(s)
+            if i == -1:                 # ignore non-unique
+                # Find place to insert
+                found = false
+                for i in range(self.list.Number()):
+                    if int(self.list.GetString(i)) > v:
+                        found = true
+                        break
+                if found: self.list.InsertItems([s], i)
+                else: self.list.Append(s)
+        except ValueError:
+            wxLogError('List item is not an int!')
+    def OnButtonRemove(self, evt):
+        self.list.Delete(self.list.GetSelection())
+    def OnUpdateUI(self, evt):
+        if evt.GetId() == self.ID_BUTTON_REMOVE:
+            evt.Enable(self.list.GetSelection() != -1)
+
+# For growable list
+class ParamIntList(ParamContent):
+    def __init__(self, parent, name):
+        ParamContent.__init__(self, parent, name)
     def OnButtonEdit(self, evt):
         if self.textModified:           # text has newer value
             try:
@@ -557,18 +598,18 @@ class ParamContentCheckList(PPanel):
             except SyntaxError:
                 wxLogError('Syntax error in parameter value: ' + self.GetName())
                 self.value = []
-        dlg = ContentCheckListDialog(self, self.value)
+        dlg = IntListDialog(self, self.value)
         if dlg.ShowModal() == wxID_OK:
             value = []
             for i in range(dlg.list.Number()):
-                value.append((dlg.list.GetString(i), dlg.list.IsChecked(i)))
+                value.append(int(dlg.list.GetString(i)))
             # Add ignored flags
             self.SetValue(value)
             self.SetModified()
             self.textModified = false
         dlg.Destroy()
 
-# Boxless radiobox
+# Boxless radiobox 
 class RadioBox(PPanel):
     def __init__(self, parent, id, choices,
                  pos=wxDefaultPosition, name='radiobox'):
@@ -620,15 +661,15 @@ class ParamOrient(RadioBox):
         self.SetStringSelection(self.seulav[value])
 
 class ParamFile(PPanel):
-    def __init__(self, parent, name):
+    def __init__(self, parent, name):    
         PPanel.__init__(self, parent, name)
         self.ID_TEXT_CTRL = wxNewId()
         self.ID_BUTTON_BROWSE = wxNewId()
         self.SetBackgroundColour(panel.GetBackgroundColour())
         sizer = wxBoxSizer()
         self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
-        sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 10)
-        self.button = wxButton(self, self.ID_BUTTON_BROWSE, 'Browse...')
+        sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
+        self.button = wxButton(self, self.ID_BUTTON_BROWSE, 'Browse...',size=buttonSize)
         sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
         self.SetAutoLayout(true)
         self.SetSizer(sizer)
@@ -637,7 +678,7 @@ class ParamFile(PPanel):
         EVT_BUTTON(self, self.ID_BUTTON_BROWSE, self.OnButtonBrowse)
         EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
     def OnChange(self, evt):
-        if self.freeze: return
+        if self.freeze: return        
         self.SetModified()
         self.textModified = true
         evt.Skip()
index c1652ba91fd520a805ef342d26c9cea0058551f9..6c9964d2fb0b43ddf412d0a9d288e9838f98eb77 100644 (file)
Binary files a/wxPython/tools/XRCed/xrced.ico and b/wxPython/tools/XRCed/xrced.ico differ
index 175c022f55b2dffd180fe8edc9ab56d5d5f4d568..5b45307ad0854b73167a24ddd80c2b016e2b1d71 100644 (file)
@@ -9,7 +9,6 @@ from wxPython.xrc import *
 from wxPython.html import *
 from xml.dom import minidom
 import os
-import tempfile
 import getopt
 
 # Icons
@@ -17,13 +16,18 @@ import images
 
 # Constants
 
-if wxGetOsVersion()[1] == 1:
+# Return code from wxGetOsVersion
+wxGTK = 9
+
+if wxGetOsVersion()[0] == wxGTK:
     labelFont = wxFont(12, wxDEFAULT, wxNORMAL, wxBOLD)
+    modernFont = wxFont(12, wxMODERN, wxNORMAL, wxNORMAL)
 else:
     labelFont = wxFont(10, wxDEFAULT, wxNORMAL, wxBOLD)
+    modernFont = wxFont(10, wxMODERN, wxNORMAL, wxNORMAL)
 
 progname = 'XRCed'
-version = '0.0.7-1'
+version = '0.0.7-2'
 
 # Local modules
 from xxx import *
@@ -217,7 +221,11 @@ class ParamPage(wxPanel):
             w.SetValue('')              # set empty (default) value
             w.SetModified()             # mark as changed
             elem = tree.dom.createElement(param)
-            xxx.params[param] = xxxParam(elem)
+            # Some classes are special
+            if param == 'font':
+                xxx.params[param] = xxxParamFont(xxx.element, elem)
+            else:
+                xxx.params[param] = xxxParam(elem)
             # Find place to put new element: first present element after param
             found = false
             paramStyles = xxx.allParams + xxx.styles
@@ -275,7 +283,7 @@ class PropPage(ParamPage):
         topSizer = wxStaticBoxSizer(box, wxVERTICAL)
         sizer = wxFlexGridSizer(len(xxx.allParams), 2, 1, 1)
         if xxx.hasName:
-            label = wxStaticText(self, -1, 'XML ID:', size=(80,-1))
+            label = wxStaticText(self, -1, 'XML ID:', size=(100,-1))
             control = ParamText(self, name='XML_name')
             sizer.AddMany([ (label, 0, wxALIGN_CENTER_VERTICAL),
                             (control, 0, wxALIGN_CENTER_VERTICAL) ])
@@ -284,13 +292,13 @@ class PropPage(ParamPage):
             present = param in xxx.params
             if param in xxx.required:
                 label = wxStaticText(self, paramIDs[param], param + ':',
-                                     size = (80,-1), name = param)
+                                     size = (100,-1), name = param)
             else:
                 # Notebook has one very loooooong parameter
                 if param == 'usenotebooksizer': sParam = 'usesizer:'
                 else: sParam = param + ':'
                 label = wxCheckBox(self, paramIDs[param], sParam,
-                                   size = (80,-1), name = param)
+                                   size = (100,-1), name = param)
                 self.checks[param] = label
             try:
                 typeClass = xxx.paramDict[param]
@@ -306,7 +314,7 @@ class PropPage(ParamPage):
             sizer.AddMany([ (label, 0, wxALIGN_CENTER_VERTICAL),
                             (control, 0, wxALIGN_CENTER_VERTICAL) ])
             self.controls[param] = control
-        topSizer.Add(sizer, 1, wxALL | wxEXPAND, 5)
+        topSizer.Add(sizer, 1, wxALL | wxEXPAND, 3)
         self.SetAutoLayout(true)
         self.SetSizer(topSizer)
         topSizer.Fit(self)
@@ -343,7 +351,7 @@ class StylePage(ParamPage):
         for param in xxx.styles:
             present = param in xxx.params.keys()
             check = wxCheckBox(self, paramIDs[param],
-                               param + ':', size = (80,-1), name = param)
+                               param + ':', size = (100,-1), name = param)
             check.SetValue(present)
             control = paramDict[param](self, name = param)
             control.Enable(present)
@@ -351,7 +359,7 @@ class StylePage(ParamPage):
                             (control, 0, wxALIGN_CENTER_VERTICAL) ])
             self.checks[param] = check
             self.controls[param] = control
-        topSizer.Add(sizer, 1, wxALL | wxEXPAND, 5)
+        topSizer.Add(sizer, 1, wxALL | wxEXPAND, 3)
         self.SetAutoLayout(true)
         self.SetSizer(topSizer)
         topSizer.Fit(self)
@@ -422,7 +430,7 @@ class XML_Tree(wxTreeCtrl):
 
         self.needUpdate = false
         self.pendingHighLight = None
-        self.ctrl = false
+        self.ctrl = self.shift = false
         self.dom = None
         # Create image list
         il = wxImageList(16, 16, true)
@@ -542,6 +550,8 @@ class XML_Tree(wxTreeCtrl):
         return node
     # Find position relative to the top-level window
     def FindNodePos(self, item):
+        # Root at (0,0)
+        if item == testWin.item: return wxPoint(0, 0)
         itemParent = self.GetItemParent(item)
         # Select NB page
         obj = self.FindNodeObject(item)
@@ -552,8 +562,6 @@ class XML_Tree(wxTreeCtrl):
                 if notebook.GetPage(i) == obj:
                     if notebook.GetSelection() != i: notebook.SetSelection(i)
                     break
-        # Root at (0,0)
-        if itemParent == self.root: return wxPoint(0, 0)
         # Find first ancestor which is a wxWindow (not a sizer)
         winParent = itemParent
         while self.GetPyData(winParent).isSizer:
@@ -565,9 +573,9 @@ class XML_Tree(wxTreeCtrl):
         return parentPos + pos
     # Find window (or sizer) corresponding to a tree item.
     def FindNodeObject(self, item):
+        if item == testWin.item: return testWin.panel
         itemParent = self.GetItemParent(item)
         # If top-level, return testWin (or panel if wxFrame)
-        if itemParent == self.root: return testWin.panel
         xxx = self.GetPyData(item).treeObject()
         parentWin = self.FindNodeObject(itemParent)
         # Top-level sizer? return window's sizer
@@ -601,7 +609,7 @@ class XML_Tree(wxTreeCtrl):
             if panel.IsModified():
                 self.Apply(xxx, oldItem)
                 #if conf.autoRefresh:
-                if testWin and tree.GetItemAncestor(oldItem) == testWin.item:
+                if testWin and not tree.IsHighlatable(oldItem):
                     if testWin.highLight:
                         testWin.highLight.Remove()
                     self.needUpdate = true
@@ -619,11 +627,13 @@ class XML_Tree(wxTreeCtrl):
         panel.SetModified(false)
         # Hightlighting is done in OnIdle
         tree.pendingHighLight = self.selection
-    # Find top-level parent
-    def GetItemAncestor(self, item):
-        while self.GetItemParent(item) != self.root:
+    # Check if item is in testWin subtree
+    def IsHighlatable(self, item):
+        if item == testWin.item: return false
+        while item != self.root:
             item = self.GetItemParent(item)
-        return item
+            if item == testWin.item: return true
+        return false
     # Highlight selected item
     def HighLight(self, item):
         self.pendingHighLight = None
@@ -635,7 +645,7 @@ class XML_Tree(wxTreeCtrl):
             if testWin.highLight: testWin.highLight.Remove()
             return
         # If a control from another window is selected, remove highlight
-        if self.GetItemAncestor(item) != testWin.item:
+        if not self.IsHighlatable(item):
             if testWin.highLight: testWin.highLight.Remove()
             return
         # Get window/sizer object
@@ -680,6 +690,7 @@ class XML_Tree(wxTreeCtrl):
     # (re)create test window
     def CreateTestWin(self, item):
         global testWin
+        wxBeginBusyCursor()
         # Create a window with this resource
         xxx = self.GetPyData(item).treeObject()
         # Close old window, remember where it was
@@ -691,7 +702,7 @@ class XML_Tree(wxTreeCtrl):
                 if testWin.highLight:
                     highLight = testWin.highLight.item
                 # !!! if 0 is removed, refresh is broken (notebook not deleted?)
-                if 0 and xxx.className == 'wxPanel':
+                if xxx.className == 'wxPanel':
                     if testWin.highLight:
                         testWin.pendingHighLight = highLight
                         testWin.highLight.Remove()
@@ -732,6 +743,8 @@ class XML_Tree(wxTreeCtrl):
             # Create new frame
             testWin = wxPreFrame()
             res.LoadFrame(testWin, frame, xxx.name)
+            # Create status bar
+            testWin.CreateStatusBar()
             testWin.panel = testWin
             testWin.SetPosition(pos)
             testWin.Show(true)
@@ -751,6 +764,7 @@ class XML_Tree(wxTreeCtrl):
             testWin.Show(true)
         elif xxx.className == 'wxMenuBar':
             testWin = wxFrame(frame, -1, 'MenuBar: ' + xxx.name, pos=pos)
+            testWin.panel = None
             # Set status bar to display help
             testWin.CreateStatusBar()
             testWin.menuBar = res.LoadMenuBar(xxx.name)
@@ -758,6 +772,7 @@ class XML_Tree(wxTreeCtrl):
             testWin.Show(true)
         elif xxx.className == 'wxToolBar':
             testWin = wxFrame(frame, -1, 'ToolBar: ' + xxx.name, pos=pos)
+            testWin.panel = None
             # Set status bar to display help
             testWin.CreateStatusBar()
             testWin.toolBar = res.LoadToolBar(testWin, xxx.name)
@@ -765,10 +780,13 @@ class XML_Tree(wxTreeCtrl):
             testWin.Show(true)
         wxMemoryFSHandler_RemoveFile('xxx.xrc')
         testWin.item = item
-        testWin.Connect(testWin.GetId(), -1, wxEVT_CLOSE_WINDOW, self.OnCloseTestWin)
+        EVT_CLOSE(testWin, self.OnCloseTestWin)
+        EVT_BUTTON(testWin, wxID_OK, self.OnCloseTestWin)
+        EVT_BUTTON(testWin, wxID_CANCEL, self.OnCloseTestWin)
         testWin.highLight = None
         if highLight and not tree.pendingHighLight:
             self.HighLight(highLight)
+        wxEndBusyCursor()
 
     def OnCloseTestWin(self, evt):
         global testWin, testWinPos
@@ -776,13 +794,20 @@ class XML_Tree(wxTreeCtrl):
         testWinPos = testWin.GetPosition()
         testWin.Destroy()
         testWin = None
-        evt.Skip()
+
+    # Return item index in parent
+    def ItemIndex(self, parent, item):
+        i = 0
+        it, cookie = self.GetFirstChild(parent, 0)
+        while it != item:
+            i += 1
+            it, cookie = self.GetNextChild(parent, cookie)
+        return i
 
     # True if next item should be inserted after current (vs. appended to it)
     def NeedInsert(self, item):
         xxx = self.GetPyData(item)
         if item == self.root: return false        # root item
-        if self.ctrl: return true       # if Ctrl pressed, always insert
         if xxx.hasChildren and not self.GetChildrenCount(item, false):
             return false
         return not (self.IsExpanded(item) and self.GetChildrenCount(item, false))
@@ -806,10 +831,11 @@ class XML_Tree(wxTreeCtrl):
             self.ctrl = evt.ControlDown() # save Ctrl state
             self.shift = evt.ShiftDown()  # and Shift too
             m = wxMenu()                  # create menu
-            needInsert = false
-            if item != self.root: needInsert = self.NeedInsert(item)
-            if item == self.root or \
-               self.GetItemParent(item) == self.root and needInsert:
+            if self.ctrl:
+                needInsert = true
+            else:
+                needInsert = self.NeedInsert(item)
+            if item == self.root or needInsert and self.GetItemParent(item) == self.root:
                 m.Append(pullDownMenu.ID_NEW_PANEL, 'Panel', 'Create panel')
                 m.Append(pullDownMenu.ID_NEW_DIALOG, 'Dialog', 'Create dialog')
                 m.Append(pullDownMenu.ID_NEW_FRAME, 'Frame', 'Create frame')
@@ -854,7 +880,7 @@ class XML_Tree(wxTreeCtrl):
             menu.Append(wxID_CUT, 'Cut', 'Cut to the clipboard')
             menu.Append(wxID_COPY, 'Copy', 'Copy to the clipboard')
             if self.ctrl and item != tree.root:
-                menu.Append(wxID_PASTE, 'Paste Sibling',
+                menu.Append(pullDownMenu.ID_PASTE_SIBLING, 'Paste Sibling',
                             'Paste from the clipboard as a sibling')
             else:
                 menu.Append(wxID_PASTE, 'Paste', 'Paste from the clipboard')
@@ -929,6 +955,7 @@ class PullDownMenu:
     ID_NEW_LAST = wxNewId()
     ID_EXPAND = wxNewId()
     ID_COLLAPSE = wxNewId()
+    ID_PASTE_SIBLING = wxNewId()
 
     def __init__(self, parent):
         self.ID_DELETE = parent.ID_DELETE
@@ -936,19 +963,38 @@ class PullDownMenu:
                        self.ID_NEW_LAST, parent.OnCreate)
         EVT_MENU(parent, self.ID_COLLAPSE, parent.OnCollapse)
         EVT_MENU(parent, self.ID_EXPAND, parent.OnExpand)
+        EVT_MENU(parent, self.ID_PASTE_SIBLING, parent.OnPaste)
         # We connect to tree, but process in frame
         EVT_MENU_HIGHLIGHT_ALL(tree, parent.OnPullDownHighlight)
 
 ################################################################################
 
+# ScrolledMessageDialog - modified from wxPython lib to set fixed-width font
+class ScrolledMessageDialog(wxDialog):
+    def __init__(self, parent, msg, caption, pos = wxDefaultPosition, size = (500,300)):
+        from wxPython.lib.layoutf import Layoutf
+        wxDialog.__init__(self, parent, -1, caption, pos, size)
+        text = wxTextCtrl(self, -1, msg, wxDefaultPosition,
+                             wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY)
+        text.SetFont(modernFont)
+        dc = wxWindowDC(text)
+        w, h = dc.GetTextExtent(' ')
+        ok = wxButton(self, wxID_OK, "OK")
+        text.SetConstraints(Layoutf('t=t5#1;b=t5#2;l=l5#1;r=r5#1', (self,ok)))
+        text.SetSize((w * 80 + 30, h * 40))
+        ok.SetConstraints(Layoutf('b=b5#1;x%w50#1;w!80;h!25', (self,)))
+        self.SetAutoLayout(TRUE)
+        self.Fit()
+        self.CenterOnScreen(wxBOTH)
+
+################################################################################
+
 class Frame(wxFrame):
     def __init__(self, pos, size):
         global frame
         frame = self
         wxFrame.__init__(self, None, -1, '', pos, size)
         self.CreateStatusBar()
-        #self.SetIcon(wxIconFromXPMData(images.getIconData()))
-        #icon = wxIconFromXPMData(images.getIconData())
         icon = wxIcon(os.path.join(sys.path[0], 'xrced.ico'), wxBITMAP_TYPE_ICO)
         self.SetIcon(icon)
 
@@ -958,6 +1004,9 @@ class Frame(wxFrame):
         self.panelWidth = 300
         self.panelHeight = 200
 
+        # Idle flas
+        self.inIdle = false
+
         # Make menus
         menuBar = wxMenuBar()
 
@@ -1294,6 +1343,7 @@ class Frame(wxFrame):
 
     def OnCut(self, evt):
         selected = tree.selection
+        if not selected: return         # key pressed event
         # Undo info
         self.lastOp = 'CUT'
         self.undo = [tree.GetItemParent(selected), tree.GetPrevSibling(selected)]
@@ -1306,7 +1356,7 @@ class Frame(wxFrame):
                 testWin = None
             else:
                 # Remove highlight, update testWin
-                if tree.GetItemAncestor(selected) == testWin.item:
+                if not tree.IsHighlatable(selected):
                     if testWin.highLight: testWin.highLight.Remove()
                     tree.needUpdate = true
         self.clipboard = tree.RemoveLeaf(selected)
@@ -1318,13 +1368,17 @@ class Frame(wxFrame):
 
     def OnCopy(self, evt):
         selected = tree.selection
+        if not selected: return         # key pressed event
         xxx = tree.GetPyData(selected)
         self.clipboard = xxx.element.cloneNode(true)
         self.SetStatusText('Copied')
 
     def OnPaste(self, evt):
         selected = tree.selection
-        appendChild = not tree.NeedInsert(selected)
+        if not selected: return         # key pressed event
+        # For pasting with Ctrl pressed
+        if evt.GetId() == pullDownMenu.ID_PASTE_SIBLING: appendChild = false
+        else: appendChild = not tree.NeedInsert(selected)
         xxx = tree.GetPyData(selected)
         if not appendChild:
             # If has next item, insert, else append to parent
@@ -1358,6 +1412,8 @@ class Frame(wxFrame):
         x = xxx.treeObject()
         if x.__class__ in [xxxDialog, xxxFrame, xxxMenuBar, xxxToolBar]:
             if parent.__class__ != xxxMainNode: error = true
+        elif x.__class__ == xxxPanel and parent.__class__ == xxxMainNode:
+            pass
         elif x.__class__ == xxxSpacer:
             if not parent.isSizer: error = true
         elif x.__class__ == xxxSeparator:
@@ -1411,8 +1467,12 @@ class Frame(wxFrame):
             node = tree.GetPyData(nextItem).element
             parent.element.insertBefore(elem, node)
             # Inserting before is difficult, se we insert after or first child
-            newItem = tree.InsertItem(parentLeaf, selected, xxx.treeName(),
-                                      image=xxx.treeImage(), data=wxTreeItemData(xxx))
+            index = tree.ItemIndex(parentLeaf, nextItem)
+            newItem = tree.InsertItemBefore(parentLeaf, index,
+                        xxx.treeName(), image=xxx.treeImage())
+            tree.SetPyData(newItem, xxx)
+#            newItem = tree.InsertItem(parentLeaf, selected, xxx.treeName(),
+#                                      image=xxx.treeImage(), data=wxTreeItemData(xxx))
         # Add children items
         if xxx.hasChildren:
             treeObj = xxx.treeObject()
@@ -1426,7 +1486,7 @@ class Frame(wxFrame):
             tree.ScrollTo(newItem)
             tree.Refresh()
         # Update view?
-        if testWin and tree.GetItemAncestor(newItem) == testWin.item:
+        if testWin and tree.IsHighlatable(newItem):
             if conf.autoRefresh:
                 tree.needUpdate = true
                 tree.pendingHighLight = newItem
@@ -1437,6 +1497,7 @@ class Frame(wxFrame):
 
     def OnDelete(self, evt):
         selected = tree.selection
+        if not selected: return         # key pressed event
         # Undo info
         self.lastOp = 'DELETE'
         self.undo = [tree.GetItemParent(selected), tree.GetPrevSibling(selected)]
@@ -1449,7 +1510,7 @@ class Frame(wxFrame):
                 testWin = None
             else:
                 # Remove highlight, update testWin
-                if tree.GetItemAncestor(selected) == testWin.item:
+                if not tree.IsHighlatable(selected):
                     if testWin.highLight: testWin.highLight.Remove()
                     tree.needUpdate = true
         xnode = tree.RemoveLeaf(selected)
@@ -1482,6 +1543,7 @@ class Frame(wxFrame):
             self.miniFrame.SetSize((self.panelWidth, self.panelHeight))
 
     def OnTest(self, evt):
+        if not tree.selection: return   # key pressed event
         tree.ShowTestWindow(tree.selection)
 
     def OnRefresh(self, evt):
@@ -1509,9 +1571,8 @@ class Frame(wxFrame):
         dlg.Destroy()
 
     def OnReadme(self, evt):
-        from wxPython.lib.dialogs import wxScrolledMessageDialog
         text = open(os.path.join(sys.path[0], 'README'), 'r').read()
-        dlg = wxScrolledMessageDialog(self, text, "XRCed README")
+        dlg = ScrolledMessageDialog(self, text, "XRCed README")
         dlg.ShowModal()
         dlg.Destroy()
 
@@ -1534,19 +1595,15 @@ class Frame(wxFrame):
 
     def OnCreate(self, evt):
         selected = tree.selection
-        appendChild = not tree.NeedInsert(selected)
+        if tree.ctrl: appendChild = false
+        else: appendChild = not tree.NeedInsert(selected)
         xxx = tree.GetPyData(selected)
         if not appendChild:
             # If insert before
             if tree.shift:
                 # If has previous item, insert after it, else append to parent
                 nextItem = selected
-                selected = tree.GetPrevSibling(selected)
-                if selected:
-                    # Insert before nextItem
-                    parentLeaf = tree.GetItemParent(selected)
-                else:                   # last child: change selected to parent
-                    parentLeaf = selected = tree.GetItemParent(nextItem)
+                parentLeaf = tree.GetItemParent(selected)
             else:
                 # If has next item, insert, else append to parent
                 nextItem = tree.GetNextSibling(selected)
@@ -1557,13 +1614,11 @@ class Frame(wxFrame):
                     appendChild = true
                     selected = tree.GetItemParent(selected)
         # Expanded container (must have children)
-        else:
-            # Can't use HasChildren because root always has
-            if tree.shift and tree.IsExpanded(selected) \
-               and tree.GetChildrenCount(selected, false):
-                appendChild = false
-                nextItem = tree.GetFirstChild(selected, 0)[0]
-                parentLeaf = selected
+        elif tree.shift and tree.IsExpanded(selected) \
+           and tree.GetChildrenCount(selected, false):
+            appendChild = false
+            nextItem = tree.GetFirstChild(selected, 0)[0]
+            parentLeaf = selected
         # Parent should be tree element or None
         if appendChild:
             parent = tree.GetPyData(selected)
@@ -1592,16 +1647,23 @@ class Frame(wxFrame):
         else:
             node = tree.GetPyData(nextItem).element
             parent.element.insertBefore(elem, node)
-            newItem = tree.InsertItem(parentLeaf, selected,
-                                      xxx.treeName(), image=xxx.treeImage(),
-                                      data=wxTreeItemData(xxx))
+            # !!! There is a different behavious on Win and GTK
+            # !!! On Win InsertItem(parent, parent, ...) inserts at the end.
+            index = tree.ItemIndex(parentLeaf, nextItem)
+            newItem = tree.InsertItemBefore(parentLeaf, index,
+                        xxx.treeName(), image=xxx.treeImage())
+#                       data=wxTreeItemData(xxx)) # does not work
+            tree.SetPyData(newItem, xxx)
+#            newItem = tree.InsertItem(parentLeaf, selected,
+#                                      xxx.treeName(), image=xxx.treeImage(),
+#                                      data=wxTreeItemData(xxx))
         tree.EnsureVisible(newItem)
         tree.SelectItem(newItem)
         if not tree.IsVisible(newItem):
             tree.ScrollTo(newItem)
             tree.Refresh()
         # Update view?
-        if testWin and tree.GetItemAncestor(newItem) == testWin.item:
+        if testWin and tree.IsHighlatable(newItem):
             if conf.autoRefresh:
                 tree.needUpdate = true
                 tree.pendingHighLight = newItem
@@ -1636,16 +1698,22 @@ class Frame(wxFrame):
             evt.Enable(testWin != None)
 
     def OnIdle(self, evt):
+        if self.inIdle: return          # Recursive call protection
+        self.inIdle = true
         if tree.needUpdate:
             if conf.autoRefresh:
                 if testWin:
+                    self.SetStatusText('Refreshing test window...')
                     # (re)create
                     tree.CreateTestWin(testWin.item)
+                    wxYield()
+                    self.SetStatusText('')
                 tree.needUpdate = false
         elif tree.pendingHighLight:
             tree.HighLight(tree.pendingHighLight)
         else:
             evt.Skip()
+        self.inIdle = false
 
     # We don't let close panel window
     def OnCloseMiniFrame(self, evt):
index 1a9be61a7d3a6ab89532911cf1408d4e0c1cc81a..a407461450bd618a1f89f23642f9348161cdfbfb 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" ?>
 <resource>
-  <object class="wxDialog" name="ID_DIALOG_CONTENT">
+  <object class="wxDialog" name="DIALOG_CONTENT">
     <title>Content</title>
     <size>250,300</size>
     <object class="wxBoxSizer">
@@ -9,7 +9,7 @@
         <object class="wxBoxSizer">
           <orient>wxHORIZONTAL</orient>
           <object class="sizeritem">
-            <object class="wxListBox" name="ID_LIST">
+            <object class="wxListBox" name="LIST">
               <content/>
             </object>
             <option>1</option>
             <object class="wxBoxSizer">
               <orient>wxVERTICAL</orient>
               <object class="sizeritem">
-                <object class="wxButton" name="ID_BUTTON_UP">
+                <object class="wxButton" name="BUTTON_UP">
                   <label>Move Up</label>
                 </object>
                 <flag>wxBOTTOM</flag>
                 <border>5</border>
               </object>
               <object class="sizeritem">
-                <object class="wxButton" name="ID_BUTTON_DOWN">
+                <object class="wxButton" name="BUTTON_DOWN">
                   <label>Move Down</label>
                 </object>
               </object>
                 <option>1</option>
               </object>
               <object class="sizeritem">
-                <object class="wxButton" name="ID_BUTTON_APPEND">
+                <object class="wxButton" name="BUTTON_APPEND">
                   <label>Append...</label>
                 </object>
                 <flag>wxBOTTOM</flag>
                 <border>5</border>
               </object>
               <object class="sizeritem">
-                <object class="wxButton" name="ID_BUTTON_REMOVE">
+                <object class="wxButton" name="BUTTON_REMOVE">
                   <label>Remove</label>
                 </object>
               </object>
@@ -82,7 +82,7 @@
     </object>
     <style>wxRESIZE_BORDER</style>
   </object>
-  <object class="wxDialog" name="ID_DIALOG_CONTENT_CHECK_LIST">
+  <object class="wxDialog" name="DIALOG_CONTENT_CHECK_LIST">
     <title>Content</title>
     <size>250,300</size>
     <object class="wxBoxSizer">
@@ -91,7 +91,7 @@
         <object class="wxBoxSizer">
           <orient>wxHORIZONTAL</orient>
           <object class="sizeritem">
-            <object class="wxCheckList" name="ID_CHECK_LIST">
+            <object class="wxCheckList" name="CHECK_LIST">
               <content/>
             </object>
             <option>1</option>
             <object class="wxBoxSizer">
               <orient>wxVERTICAL</orient>
               <object class="sizeritem">
-                <object class="wxButton" name="ID_BUTTON_UP">
+                <object class="wxButton" name="BUTTON_UP">
                   <label>Move Up</label>
                 </object>
                 <flag>wxBOTTOM</flag>
                 <border>5</border>
               </object>
               <object class="sizeritem">
-                <object class="wxButton" name="ID_BUTTON_DOWN">
+                <object class="wxButton" name="BUTTON_DOWN">
                   <label>Move Down</label>
                 </object>
               </object>
                 <option>1</option>
               </object>
               <object class="sizeritem">
-                <object class="wxButton" name="ID_BUTTON_APPEND">
+                <object class="wxButton" name="BUTTON_APPEND">
                   <label>Append...</label>
                 </object>
                 <flag>wxBOTTOM</flag>
                 <border>5</border>
               </object>
               <object class="sizeritem">
-                <object class="wxButton" name="ID_BUTTON_REMOVE">
+                <object class="wxButton" name="BUTTON_REMOVE">
                   <label>Remove</label>
                 </object>
               </object>
     </object>
     <style>wxRESIZE_BORDER</style>
   </object>
+  <object class="wxDialog" name="DIALOG_INTLIST">
+    <title>Numbers</title>
+    <size>100,300</size>
+    <object class="wxBoxSizer">
+      <orient>wxVERTICAL</orient>
+      <object class="sizeritem">
+        <object class="wxBoxSizer">
+          <orient>wxVERTICAL</orient>
+          <object class="sizeritem">
+            <object class="wxListBox" name="LIST">
+              <content/>
+              <size>80,100</size>
+              <style>wxLB_SORT</style>
+            </object>
+            <option>1</option>
+            <flag>wxALL|wxALIGN_CENTRE_HORIZONTAL</flag>
+            <border>10</border>
+          </object>
+          <object class="sizeritem">
+            <object class="wxBoxSizer">
+              <orient>wxVERTICAL</orient>
+              <object class="sizeritem">
+                <object class="wxButton" name="BUTTON_ADD">
+                  <label>Add...</label>
+                </object>
+                <flag>wxBOTTOM</flag>
+                <border>3</border>
+              </object>
+              <object class="sizeritem">
+                <object class="wxButton" name="BUTTON_REMOVE">
+                  <label>Remove</label>
+                </object>
+              </object>
+            </object>
+            <flag>wxALL|wxALIGN_CENTRE_HORIZONTAL</flag>
+            <border>5</border>
+          </object>
+        </object>
+        <option>1</option>
+        <flag>wxEXPAND</flag>
+      </object>
+      <object class="sizeritem">
+        <object class="wxStaticLine"/>
+        <flag>wxEXPAND</flag>
+      </object>
+      <object class="sizeritem">
+        <object class="wxBoxSizer">
+          <orient>wxVERTICAL</orient>
+          <object class="sizeritem">
+            <object class="wxButton" name="wxID_OK">
+              <label>OK</label>
+              <default>1</default>
+            </object>
+            <flag>wxBOTTOM</flag>
+            <border>5</border>
+          </object>
+          <object class="sizeritem">
+            <object class="wxButton" name="wxID_CANCEL">
+              <label>Cancel</label>
+            </object>
+          </object>
+        </object>
+        <flag>wxALL|wxALIGN_CENTRE_HORIZONTAL</flag>
+        <border>10</border>
+      </object>
+    </object>
+    <style>wxRESIZE_BORDER</style>
+  </object>
 </resource>
\ No newline at end of file
index 0435ea573766033c28df2965ce2bad5bedf5f49d..7dfdeb490042b37c7a447395adc3c26982c71b3a 100644 (file)
@@ -26,13 +26,27 @@ class xxxParam:
         self.textNode = text
     # Value returns string
     def value(self):
-        return str(self.textNode.data)
+        return self.textNode.data
     def update(self, value):
         self.textNode.data = value
     def remove(self):
         self.node.parentNode.removeChild(self.node)
         self.node.unlink()
 
+# Integer parameter
+class xxxParamInt(xxxParam):
+    # Standard use: for text nodes
+    def __init__(self, node):
+        xxxParam.__init__(self, node)
+    # Value returns string
+    def value(self):
+        try:
+            return int(self.textNode.data)
+        except ValueError:
+            return -1                   # invalid value
+    def update(self, value):
+        self.textNode.data = str(value)
+
 # Content parameter
 class xxxParamContent:
     def __init__(self, node):
@@ -118,10 +132,10 @@ class xxxParamContentCheckList:
                 self.node.appendChild(itemElem)
                 l.append((itemText, itemElem))
             self.l = l
-#        else:
-#            for i in range(len(value)):
-#                self.l[i][0].data = value[i]
-#                self.l[i][1].setAttributedata = value[i]
+        else:
+            for i in range(len(value)):
+                self.l[i][0].data = value[i][0]
+                self.l[i][1].setAttribute('checked', str(value[i][1]))
         self.data = value
 
 ################################################################################
@@ -176,7 +190,7 @@ class xxxObject:
                     else:
                         self.params[tag] = xxxParamContent(node)
                 elif tag == 'font': # has children
-                    self.params[tag] = xxxParamFont(self, node)
+                    self.params[tag] = xxxParamFont(element, node)
                 else:                   # simple parameter
                     self.params[tag] = xxxParam(node)
             else:
@@ -199,24 +213,26 @@ class xxxObject:
 
 ################################################################################
 
-class xxxParamFont(xxxParam):
+# This is a little special 
+class xxxParamFont(xxxObject):
     allParams = ['size', 'style', 'weight', 'family', 'underlined',
                  'face', 'encoding']
     def __init__(self, parent, element):
         xxxObject.__init__(self, parent, element)
-        self.parentNode = element       # required to behave similar to DOM node
+        self.parentNode = parent       # required to behave similar to DOM node
         v = []
         for p in self.allParams:
             try:
-                v.append(str(self.params[p].data))
+                v.append(str(self.params[p].value()))
             except KeyError:
                 v.append('')
         self.data = v
     def update(self, value):
         # `value' is a list of strings corresponding to all parameters
         elem = self.element
-        for node in elem.childNodes:
-            elem.removeChild(node)
+        # Remove old elements first
+        childNodes = elem.childNodes[:]
+        for node in childNodes: elem.removeChild(node)
         i = 0
         self.params.clear()
         v = []
@@ -230,6 +246,11 @@ class xxxParamFont(xxxParam):
             v.append(value[i])
             i += 1
         self.data = v
+    def value(self):
+        return self.data
+    def remove(self):
+        self.parentNode.removeChild(self.element)
+        self.element.unlink()
 
 ################################################################################
 
@@ -483,20 +504,20 @@ class xxxParamMulti:
 class xxxFlexGridSizer(xxxGridSizer):
     specials = ['growablecols', 'growablerows']
     allParams = ['cols', 'rows', 'vgap', 'hgap'] + specials
-    paramDict = {'growablecols':ParamContent, 'growablerows':ParamContent}
+    paramDict = {'growablecols':ParamIntList, 'growablerows':ParamIntList}
     # Special processing for growable* parameters
     # (they are represented by several nodes)
     def special(self, tag, node):
-        if tag not in self.params.keys():
+        if tag not in self.params:
             self.params[tag] = xxxParamMulti()
-        self.params[tag].append(xxxParam(node))
+        self.params[tag].append(xxxParamInt(node))
     def setSpecial(self, param, value):
         # Straightforward implementation: remove, add again
         self.params[param].remove()
         del self.params[param]
-        for str in value:
+        for i in value:
             node = tree.dom.createElement(param)
-            text = tree.dom.createTextNode(str)
+            text = tree.dom.createTextNode(str(i))
             node.appendChild(text)
             self.element.appendChild(node)
             self.special(param, node)