DataTypeEditor.py
changeset 125 394d9f168258
child 130 38421cd7c8ff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DataTypeEditor.py	Thu Dec 06 18:05:29 2007 +0100
@@ -0,0 +1,488 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
+#based on the plcopen standard. 
+#
+#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
+#
+#See COPYING file for copyrights details.
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#General Public License for more details.
+#
+#You should have received a copy of the GNU General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+import wx
+import wx.grid
+import wx.gizmos
+from plcopen.structures import GetDataTypeRange, IEC_KEYWORDS
+
+if wx.VERSION >= (2, 8, 0):
+    import wx.aui
+
+    class MDIDataTypeEditor(wx.aui.AuiMDIChildFrame):
+        def __init__(self, parent, tagname, window, controler):
+            wx.aui.AuiMDIChildFrame.__init__(self, parent, -1, title = "")
+            
+            sizer = wx.BoxSizer(wx.HORIZONTAL)
+            
+            self.Viewer = DataTypeEditor(self, tagname, window, controler)
+            
+            sizer.AddWindow(self.Viewer, 1, border=0, flag=wx.GROW)
+            
+            self.SetSizer(sizer)
+        
+        def GetViewer(self):
+            return self.Viewer
+
+#-------------------------------------------------------------------------------
+#                          Configuration Editor class
+#-------------------------------------------------------------------------------
+
+[ID_DATATYPEEDITOR, ID_DATATYPEEDITORSTATICBOX,
+ ID_DATATYPEEDITORDERIVATIONTYPE, ID_DATATYPEEDITORDIRECTLYPANEL,
+ ID_DATATYPEEDITORSUBRANGEPANEL, ID_DATATYPEEDITORDIRECTLYBASETYPE, 
+ ID_DATATYPEEDITORSUBRANGEBASETYPE, ID_DATATYPEEDITORSUBRANGEMINIMUM, 
+ ID_DATATYPEEDITORSUBRANGEMAXIMUM, ID_DATATYPEEDITORDIRECTLYINITIALVALUE, 
+ ID_DATATYPEEDITORSUBRANGEINITIALVALUE, ID_DATATYPEEDITORENUMERATEDPANEL,
+ ID_DATATYPEEDITORENUMERATEDVALUES, ID_DATATYPEEDITORENUMERATEDINITIALVALUE,
+ ID_DATATYPEEDITORARRAYPANEL, ID_DATATYPEEDITORARRAYBASETYPE, 
+ ID_DATATYPEEDITORARRAYDIMENSIONS, ID_DATATYPEEDITORARRAYINITIALVALUE, 
+ ID_DATATYPEEDITORSTATICTEXT1, ID_DATATYPEEDITORSTATICTEXT2, 
+ ID_DATATYPEEDITORSTATICTEXT3, ID_DATATYPEEDITORSTATICTEXT4, 
+ ID_DATATYPEEDITORSTATICTEXT5, ID_DATATYPEEDITORSTATICTEXT6, 
+ ID_DATATYPEEDITORSTATICTEXT7, ID_DATATYPEEDITORSTATICTEXT8,
+ ID_DATATYPEEDITORSTATICTEXT9, ID_DATATYPEEDITORSTATICTEXT10, 
+] = [wx.NewId() for _init_ctrls in range(28)]
+
+class DataTypeEditor(wx.Panel):
+    
+    def _init_coll_MainSizer_Items(self, parent):
+        parent.AddSizer(self.TopSizer, 0, border=5, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
+        parent.AddSizer(self.TypeInfosSizer, 0, border=5, flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT)
+
+    def _init_coll_MainSizer_Growables(self, parent):
+        parent.AddGrowableCol(0)
+        parent.AddGrowableRow(1)
+
+    def _init_coll_TopSizer_Items(self, parent):
+        parent.AddWindow(self.staticText1, 0, border=5, flag=wx.GROW|wx.LEFT)
+        parent.AddWindow(self.DerivationType, 0, border=0, flag=wx.GROW)
+
+    def _init_coll_TypeInfosSizer_Items(self, parent):
+        parent.AddWindow(self.DirectlyPanel, 1, border=0, flag=wx.ALL)
+        parent.AddWindow(self.SubrangePanel, 1, border=0, flag=wx.ALL)
+        parent.AddWindow(self.EnumeratedPanel, 1, border=0, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.ArrayPanel, 1, border=0, flag=wx.ALL)
+
+    def _init_coll_DirectlyPanelSizer_Items(self, parent):
+        parent.AddWindow(self.staticText2, 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.DirectlyBaseType, 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.staticText3, 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.DirectlyInitialValue, 1, border=5, flag=wx.GROW|wx.ALL)
+
+    def _init_coll_SubrangePanelSizer_Items(self, parent):
+        parent.AddWindow(self.staticText4, 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.SubrangeBaseType, 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.staticText5, 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.SubrangeInitialValue, 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.staticText6, 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.SubrangeMinimum, 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(wx.Size(0, 0), 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(wx.Size(0, 0), 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.staticText7, 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.SubrangeMaximum, 1, border=5, flag=wx.GROW|wx.ALL)
+        
+    def _init_coll_EnumeratedPanelSizer_Items(self, parent):
+        parent.AddWindow(self.EnumeratedValues, 2, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.staticText8, 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.EnumeratedInitialValue, 1, border=5, flag=wx.ALL)
+
+    def _init_coll_ArrayPanelSizer_Items(self, parent):
+        parent.AddSizer(self.ArrayPanelLeftSizer, 0, border=0, flag=wx.GROW)
+        parent.AddSizer(self.ArrayPanelRightSizer, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.ArrayDimensions, 0, border=5, flag=wx.GROW|wx.ALL)
+        
+    def _init_coll_ArrayPanelSizer_Growables(self, parent):
+        parent.AddGrowableCol(0)
+        parent.AddGrowableCol(1)
+        parent.AddGrowableRow(1)
+
+    def _init_coll_ArrayPanelLeftSizer_Items(self, parent):
+        parent.AddWindow(self.staticText9, 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.ArrayBaseType, 1, border=5, flag=wx.GROW|wx.ALL)
+    
+    def _init_coll_ArrayPanelRightSizer_Items(self, parent):
+        parent.AddWindow(self.staticText10, 1, border=5, flag=wx.GROW|wx.ALL)
+        parent.AddWindow(self.ArrayInitialValue, 1, border=5, flag=wx.GROW|wx.ALL)    
+
+    def _init_sizers(self):
+        self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
+        self.TopSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.TypeInfosSizer = wx.StaticBoxSizer(self.staticbox, wx.HORIZONTAL)
+        self.DirectlyPanelSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.SubrangePanelSizer = wx.GridSizer(cols=4, hgap=0, rows=3, vgap=0)
+        self.EnumeratedPanelSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.ArrayPanelSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=2, vgap=0)
+        self.ArrayPanelLeftSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.ArrayPanelRightSizer = wx.BoxSizer(wx.HORIZONTAL)
+        
+        self._init_coll_MainSizer_Items(self.MainSizer)
+        self._init_coll_MainSizer_Growables(self.MainSizer)
+        self._init_coll_TopSizer_Items(self.TopSizer)
+        self._init_coll_TypeInfosSizer_Items(self.TypeInfosSizer)
+        self._init_coll_DirectlyPanelSizer_Items(self.DirectlyPanelSizer)
+        self._init_coll_SubrangePanelSizer_Items(self.SubrangePanelSizer)
+        self._init_coll_EnumeratedPanelSizer_Items(self.EnumeratedPanelSizer)
+        self._init_coll_ArrayPanelSizer_Items(self.ArrayPanelSizer)
+        self._init_coll_ArrayPanelSizer_Growables(self.ArrayPanelSizer)
+        self._init_coll_ArrayPanelLeftSizer_Items(self.ArrayPanelLeftSizer)
+        self._init_coll_ArrayPanelRightSizer_Items(self.ArrayPanelRightSizer)
+        
+        self.SetSizer(self.MainSizer)
+        self.DirectlyPanel.SetSizer(self.DirectlyPanelSizer)
+        self.SubrangePanel.SetSizer(self.SubrangePanelSizer)
+        self.EnumeratedPanel.SetSizer(self.EnumeratedPanelSizer)
+        self.ArrayPanel.SetSizer(self.ArrayPanelSizer)
+    
+    def _init_ctrls(self, prnt):
+        wx.Panel.__init__(self, id=ID_DATATYPEEDITOR, name='', parent=prnt,
+              size=wx.Size(0, 0), style=wx.SUNKEN_BORDER)
+
+        self.staticbox = wx.StaticBox(id=ID_DATATYPEEDITORSTATICBOX,
+              label='Type infos:', name='staticBox1', parent=self,
+              pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0)
+
+        self.staticText1 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT1,
+              label='Derivation Type:', name='staticText1', parent=self,
+              pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0)
+
+        self.DerivationType = wx.Choice(id=ID_DATATYPEEDITORDERIVATIONTYPE,
+              name='DerivationType', parent=self, pos=wx.Point(0, 0),
+              size=wx.Size(200, 24), style=0)
+        self.Bind(wx.EVT_CHOICE, self.OnDerivationTypeChanged, id=ID_DATATYPEEDITORDERIVATIONTYPE)
+
+        # Panel for Directly derived data types
+
+        self.DirectlyPanel = wx.Panel(id=ID_DATATYPEEDITORDIRECTLYPANEL,
+              name='DirectlyPanel', parent=self, pos=wx.Point(0, 0),
+              size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
+
+        self.staticText2 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT2,
+              label='Base Type:', name='staticText2', parent=self.DirectlyPanel,
+              pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0)
+
+        self.DirectlyBaseType = wx.Choice(id=ID_DATATYPEEDITORDIRECTLYBASETYPE, 
+              name='DirectlyBaseType', parent=self.DirectlyPanel, pos=wx.Point(0, 0),
+              size=wx.Size(0, 24), style=wx.TAB_TRAVERSAL)
+        self.Bind(wx.EVT_CHOICE, self.OnInfosChanged, id=ID_DATATYPEEDITORDIRECTLYBASETYPE)
+
+        self.staticText3 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT3,
+              label='Initial Value:', name='staticText3', parent=self.DirectlyPanel,
+              pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0)
+
+        self.DirectlyInitialValue = wx.TextCtrl(id=ID_DATATYPEEDITORDIRECTLYINITIALVALUE, 
+              name='DirectlyInitialValue', parent=self.DirectlyPanel, pos=wx.Point(0, 0),
+              size=wx.Size(0, 24), style=wx.TAB_TRAVERSAL|wx.TE_PROCESS_ENTER)
+        self.Bind(wx.EVT_TEXT_ENTER, self.OnInfosChanged, id=ID_DATATYPEEDITORDIRECTLYINITIALVALUE)
+
+        # Panel for Subrange data types
+
+        self.SubrangePanel = wx.Panel(id=ID_DATATYPEEDITORSUBRANGEPANEL,
+              name='SubrangePanel', parent=self, pos=wx.Point(0, 0),
+              size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
+
+        self.staticText4 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT4,
+              label='Base Type:', name='staticText4', parent=self.SubrangePanel,
+              pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0)
+
+        self.SubrangeBaseType = wx.Choice(id=ID_DATATYPEEDITORSUBRANGEBASETYPE, 
+              name='SubrangeBaseType', parent=self.SubrangePanel, pos=wx.Point(0, 0),
+              size=wx.Size(0, 24), style=wx.TAB_TRAVERSAL)
+        self.Bind(wx.EVT_CHOICE, self.OnSubrangeBaseTypeChanged, id=ID_DATATYPEEDITORSUBRANGEBASETYPE)
+
+        self.staticText5 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT5,
+              label='Initial Value:', name='staticText5', parent=self.SubrangePanel,
+              pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0)
+
+        self.SubrangeInitialValue = wx.SpinCtrl(id=ID_DATATYPEEDITORSUBRANGEINITIALVALUE, 
+              name='SubrangeInitialValue', parent=self.SubrangePanel, pos=wx.Point(0, 0),
+              size=wx.Size(0, 24), style=wx.TAB_TRAVERSAL)
+        self.Bind(wx.EVT_SPINCTRL, self.OnInfosChanged, id=ID_DATATYPEEDITORSUBRANGEINITIALVALUE)
+
+        self.staticText6 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT6,
+              label='Minimum:', name='staticText6', parent=self.SubrangePanel,
+              pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0)
+
+        self.SubrangeMinimum = wx.SpinCtrl(id=ID_DATATYPEEDITORSUBRANGEMINIMUM, 
+              name='SubrangeMinimum', parent=self.SubrangePanel, pos=wx.Point(0, 0),
+              size=wx.Size(0, 24), style=wx.TAB_TRAVERSAL)
+        self.Bind(wx.EVT_SPINCTRL, self.OnSubrangeMinimumChanged, id=ID_DATATYPEEDITORSUBRANGEMINIMUM)
+
+        self.staticText7 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT7,
+              label='Maximum:', name='staticText7', parent=self.SubrangePanel,
+              pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0)
+
+        self.SubrangeMaximum = wx.SpinCtrl(id=ID_DATATYPEEDITORSUBRANGEMAXIMUM, 
+              name='SubrangeMaximum', parent=self.SubrangePanel, pos=wx.Point(0, 0),
+              size=wx.Size(0, 24), style=wx.TAB_TRAVERSAL)
+        self.Bind(wx.EVT_SPINCTRL, self.OnSubrangeMaximumChanged, id=ID_DATATYPEEDITORSUBRANGEMAXIMUM)
+
+        # Panel for Enumerated data types
+
+        self.EnumeratedPanel = wx.Panel(id=ID_DATATYPEEDITORENUMERATEDPANEL,
+              name='EnumeratedPanel', parent=self, pos=wx.Point(0, 0),
+              size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
+
+        self.EnumeratedValues = wx.gizmos.EditableListBox(id=ID_DATATYPEEDITORENUMERATEDVALUES, 
+              name='EnumeratedValues', parent=self.EnumeratedPanel, label="Values:", pos=wx.Point(0, 0),
+              size=wx.Size(0, 0), style=wx.gizmos.EL_ALLOW_NEW | wx.gizmos.EL_ALLOW_EDIT | wx.gizmos.EL_ALLOW_DELETE)
+        self.EnumeratedValues.GetListCtrl().Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEnumeratedValueEndEdit)
+        self.EnumeratedValues.GetNewButton().Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged)
+        self.EnumeratedValues.GetDelButton().Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged)
+        self.EnumeratedValues.GetUpButton().Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged)
+        self.EnumeratedValues.GetDownButton().Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged)
+        
+        self.staticText8 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT8,
+              label='Initial Value:', name='staticText8', parent=self.EnumeratedPanel,
+              pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0)
+
+        self.EnumeratedInitialValue = wx.Choice(id=ID_DATATYPEEDITORENUMERATEDINITIALVALUE, 
+              name='EnumeratedInitialValue', parent=self.EnumeratedPanel, pos=wx.Point(0, 0),
+              size=wx.Size(0, 24), style=wx.TAB_TRAVERSAL|wx.TE_PROCESS_ENTER)
+        self.Bind(wx.EVT_CHOICE, self.OnInfosChanged, id=ID_DATATYPEEDITORENUMERATEDINITIALVALUE)
+        
+        # Panel for Array data types
+
+        self.ArrayPanel = wx.Panel(id=ID_DATATYPEEDITORARRAYPANEL,
+              name='ArrayPanel', parent=self, pos=wx.Point(0, 0),
+              size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
+
+        self.staticText9 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT9,
+              label='Base Type:', name='staticText9', parent=self.ArrayPanel,
+              pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0)
+
+        self.ArrayBaseType = wx.Choice(id=ID_DATATYPEEDITORARRAYBASETYPE, 
+              name='SubrangeBaseType', parent=self.ArrayPanel, pos=wx.Point(0, 0),
+              size=wx.Size(0, 24), style=wx.TAB_TRAVERSAL)
+        self.Bind(wx.EVT_CHOICE, self.OnInfosChanged, id=ID_DATATYPEEDITORARRAYBASETYPE)
+
+        self.ArrayDimensions = wx.gizmos.EditableListBox(id=ID_DATATYPEEDITORARRAYDIMENSIONS, 
+              name='ArrayDimensions', parent=self.ArrayPanel, label="Dimensions:", pos=wx.Point(0, 0),
+              size=wx.Size(0, 24), style=wx.gizmos.EL_ALLOW_NEW | wx.gizmos.EL_ALLOW_EDIT | wx.gizmos.EL_ALLOW_DELETE)
+        self.ArrayDimensions.GetListCtrl().Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnDimensionsChanged)
+        self.ArrayDimensions.GetNewButton().Bind(wx.EVT_BUTTON, self.OnDimensionsChanged)
+        self.ArrayDimensions.GetDelButton().Bind(wx.EVT_BUTTON, self.OnDimensionsChanged)
+        self.ArrayDimensions.GetUpButton().Bind(wx.EVT_BUTTON, self.OnDimensionsChanged)
+        self.ArrayDimensions.GetDownButton().Bind(wx.EVT_BUTTON, self.OnDimensionsChanged)
+
+        self.staticText10 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT10,
+              label='Initial Value:', name='staticText10', parent=self.ArrayPanel,
+              pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0)
+
+        self.ArrayInitialValue = wx.TextCtrl(id=ID_DATATYPEEDITORARRAYINITIALVALUE, 
+              name='ArrayInitialValue', parent=self.ArrayPanel, pos=wx.Point(0, 0),
+              size=wx.Size(0, 24), style=wx.TAB_TRAVERSAL|wx.TE_PROCESS_ENTER)
+        self.Bind(wx.EVT_TEXT_ENTER, self.OnInfosChanged, id=ID_DATATYPEEDITORARRAYINITIALVALUE)
+        
+        self._init_sizers()
+
+    def __init__(self, parent, tagname, window, controler):
+        self._init_ctrls(parent)
+        
+        self.DerivationType.Append("Directly")
+        self.DerivationType.Append("Subrange")
+        self.DerivationType.Append("Enumerated")
+        self.DerivationType.Append("Array")
+        self.SubrangePanel.Hide()
+        self.EnumeratedPanel.Hide()
+        self.ArrayPanel.Hide()
+        self.CurrentPanel = "Directly"
+        
+        self.ParentWindow = window
+        self.Controler = controler
+        self.TagName = tagname
+    
+    def OnEnumeratedValueEndEdit(self, event):
+        text = event.GetText()
+        if text.upper() in [string.upper() for string in self.EnumeratedValues.GetStrings()]:
+            message = wx.MessageDialog(self, "\"%s\" value already defined!"%text, "Error", wx.OK|wx.ICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+            event.Veto()
+        elif text.upper() in IEC_KEYWORDS:
+            message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%text, "Error", wx.OK|wx.ICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        else:
+            wx.CallAfter(self.RefreshEnumeratedValues)
+            wx.CallAfter(self.RefreshTypeInfos)
+            event.Skip()
+    
+    def OnEnumeratedValuesChanged(self, event):
+        wx.CallAfter(self.RefreshEnumeratedValues)
+        wx.CallAfter(self.RefreshTypeInfos)
+        event.Skip()
+    
+    def SetTagName(self, tagname):
+        self.TagName = tagname
+        
+    def GetTagName(self):
+        return self.TagName
+    
+    def IsViewing(self, tagname):
+        return self.TagName == tagname
+
+    def SetMode(self, mode):
+        pass
+
+    def ResetBuffer(self):
+        pass
+
+    def RefreshView(self):
+        self.DirectlyBaseType.Clear()
+        self.ArrayBaseType.Clear()
+        for datatype in self.Controler.GetDataTypes(self.TagName):
+            self.DirectlyBaseType.Append(datatype)
+            self.ArrayBaseType.Append(datatype)
+        self.DirectlyBaseType.SetSelection(0)
+        self.SubrangeBaseType.Clear()
+        words = self.TagName.split("::")
+        for base_type in self.Controler.GetSubrangeTypes():
+            self.SubrangeBaseType.Append(base_type)
+        self.SubrangeBaseType.SetSelection(0)
+        self.RefreshBoundsRange()
+        type_infos = self.Controler.GetDataTypeInfos(self.TagName)
+        if type_infos is not None:
+            self.DerivationType.SetStringSelection(type_infos["type"])
+            if type_infos["type"] == "Directly":
+                self.DirectlyBaseType.SetStringSelection(type_infos["base_type"])
+                self.DirectlyInitialValue.SetValue(type_infos["initial"])
+            elif type_infos["type"] == "Subrange":
+                self.SubrangeBaseType.SetStringSelection(type_infos["base_type"])
+                self.RefreshBoundsRange()
+                self.SubrangeMinimum.SetValue(type_infos["min"])
+                self.SubrangeMaximum.SetValue(type_infos["max"])
+                self.RefreshSubrangeInitialValueRange()
+                if type_infos["initial"] != "":
+                    self.SubrangeInitialValue.SetValue(int(type_infos["initial"]))
+                else:
+                    self.SubrangeInitialValue.SetValue(type_infos["min"])
+            elif type_infos["type"] == "Enumerated":
+                self.EnumeratedValues.SetStrings(type_infos["values"])
+                self.RefreshEnumeratedValues()
+                self.EnumeratedInitialValue.SetStringSelection(type_infos["initial"])
+            elif type_infos["type"] == "Array":
+                self.ArrayBaseType.SetStringSelection(type_infos["base_type"])
+                self.ArrayDimensions.SetStrings(type_infos["dimensions"])
+                self.ArrayInitialValue.SetValue(type_infos["initial"])
+            self.RefreshDisplayedInfos()
+
+    def OnDerivationTypeChanged(self, event):
+        self.RefreshDisplayedInfos()
+        self.RefreshTypeInfos()
+        event.Skip()
+
+    def OnInfosChanged(self, event):
+        self.RefreshTypeInfos()
+        event.Skip()
+
+    def OnSubrangeBaseTypeChanged(self, event):
+        self.RefreshBoundsRange()
+        self.RefreshTypeInfos()
+        event.Skip()
+
+    def OnSubrangeMinimumChanged(self, event):
+        wx.CallAfter(self.SubrangeMinimum.SetValue, min(self.SubrangeMaximum.GetValue(), self.SubrangeMinimum.GetValue()))
+        wx.CallAfter(self.RefreshSubrangeInitialValueRange)
+        wx.CallAfter(self.RefreshTypeInfos)
+        event.Skip()
+
+    def OnSubrangeMaximumChanged(self, event):
+        wx.CallAfter(self.SubrangeMaximum.SetValue, max(self.SubrangeMinimum.GetValue(), self.SubrangeMaximum.GetValue()))
+        wx.CallAfter(self.RefreshSubrangeInitialValueRange)
+        wx.CallAfter(self.RefreshTypeInfos)
+        event.Skip()
+
+    def OnDimensionsChanged(self, event):
+        wx.CallAfter(self.RefreshTypeInfos)
+        event.Skip()
+
+    def RefreshDisplayedInfos(self):
+        selected = self.DerivationType.GetStringSelection()
+        if selected != self.CurrentPanel:
+            if self.CurrentPanel == "Directly":
+                self.DirectlyPanel.Hide()
+            elif self.CurrentPanel == "Subrange":
+                self.SubrangePanel.Hide()
+            elif self.CurrentPanel == "Enumerated":
+                self.EnumeratedPanel.Hide()
+            elif self.CurrentPanel == "Array":
+                self.ArrayPanel.Hide()
+            self.CurrentPanel = selected
+            if selected == "Directly":
+                self.DirectlyPanel.Show()
+            elif selected == "Subrange":
+                self.SubrangePanel.Show()
+            elif selected == "Enumerated":
+                self.EnumeratedPanel.Show()
+            elif selected == "Array":
+                self.ArrayPanel.Show()
+            self.MainSizer.Layout()
+
+    def RefreshEnumeratedValues(self):
+        selected = self.EnumeratedInitialValue.GetStringSelection()
+        self.EnumeratedInitialValue.Clear()
+        self.EnumeratedInitialValue.Append("")
+        for value in self.EnumeratedValues.GetStrings():
+            self.EnumeratedInitialValue.Append(value)
+        self.EnumeratedInitialValue.SetStringSelection(selected)
+
+    def RefreshBoundsRange(self):
+        range = GetDataTypeRange(self.SubrangeBaseType.GetStringSelection())
+        if range is not None:
+            min_value, max_value = range
+            self.SubrangeMinimum.SetRange(min_value, max_value)
+            self.SubrangeMinimum.SetValue(min(max(min_value, self.SubrangeMinimum.GetValue()), max_value))
+            self.SubrangeMaximum.SetRange(min_value, max_value)
+            self.SubrangeMaximum.SetValue(min(max(min_value, self.SubrangeMaximum.GetValue()), max_value))
+
+    def RefreshSubrangeInitialValueRange(self):
+        self.SubrangeInitialValue.SetRange(self.SubrangeMinimum.GetValue(), self.SubrangeMaximum.GetValue())
+
+    def RefreshTypeInfos(self):
+        selected = self.DerivationType.GetStringSelection()
+        infos = {"type" : selected}
+        if selected == "Directly":
+            infos["base_type"] = self.DirectlyBaseType.GetStringSelection()
+            infos["initial"] = self.DirectlyInitialValue.GetValue()
+        elif selected == "Subrange":
+            infos["base_type"] = self.SubrangeBaseType.GetStringSelection()
+            infos["min"] = self.SubrangeMinimum.GetValue()
+            infos["max"] = self.SubrangeMaximum.GetValue()
+            initial_value = self.SubrangeInitialValue.GetValue()
+            if initial_value == infos["min"]:
+                infos["initial"] = ""
+            else:
+                infos["initial"] = str(initial_value)
+        elif selected == "Enumerated":
+            infos["values"] = self.EnumeratedValues.GetStrings()
+            infos["initial"] = self.EnumeratedInitialValue.GetStringSelection()
+        elif selected == "Array":
+            infos["base_type"] = self.ArrayBaseType.GetStringSelection()
+            infos["dimensions"] = self.ArrayDimensions.GetStrings()
+            infos["initial"] = self.ArrayInitialValue.GetValue()
+        self.Controler.SetDataTypeInfos(self.TagName, infos)
+        self.ParentWindow.RefreshTitle()
+        self.ParentWindow.RefreshEditMenu()
+