Allowing user to type formulas
authorlbessard
Tue, 02 Oct 2007 14:06:30 +0200
changeset 299 506f9700b9fb
parent 298 dba062c5c3c1
child 300 b83d063c4dc4
Allowing user to type formulas
Node ID selection disabled
Adding possibility to reset values to default
objdictgen/commondialogs.py
objdictgen/eds_utils.py
objdictgen/networkedit.py
objdictgen/node.py
objdictgen/nodemanager.py
objdictgen/objdictedit.py
objdictgen/subindextable.py
--- a/objdictgen/commondialogs.py	Tue Oct 02 10:32:11 2007 +0200
+++ b/objdictgen/commondialogs.py	Tue Oct 02 14:06:30 2007 +0200
@@ -728,6 +728,9 @@
     def __init__(self, parent):
         self._init_ctrls(parent)
         
+        self.staticText2.Hide()
+        self.NodeID.Hide()
+        
         self.Type.Append("master")
         self.Type.Append("slave")
 
@@ -984,6 +987,9 @@
     def __init__(self, parent):
         self._init_ctrls(parent)
         
+        self.staticText3.Hide()
+        self.NodeID.Hide()
+        
         self.NodeID.SetValue("0x00")
         self.Type.Append("master")
         self.Type.Append("slave")
--- a/objdictgen/eds_utils.py	Tue Oct 02 10:32:11 2007 +0200
+++ b/objdictgen/eds_utils.py	Tue Oct 02 14:06:30 2007 +0200
@@ -308,7 +308,7 @@
                     if value.startswith("$NODEID"):
                         try:
                             test = int(value.replace("$NODEID+", ""), 16)
-                            computed_value = value.replace("$NODEID", "self.ID")
+                            computed_value = "\"%s\""%value
                         except:
                             raise SyntaxError, "\"%s\" is not a valid formula for attribute \"%s\" of section \"[%s]\""%(value, keyname, section_name)
                     # Second case, value starts with "0x", then it's an hexadecimal value
@@ -387,7 +387,7 @@
                     elif values["DATATYPE"] == 0x01:
                         values["DEFAULTVALUE"] = {0 : True, 1 : False}[values["DEFAULTVALUE"]]
                     else:
-                        if type(values["DEFAULTVALUE"]) != IntType and values["DEFAULTVALUE"].find("self.ID") == -1:
+                        if type(values["DEFAULTVALUE"]) != IntType and values["DEFAULTVALUE"].find("$NODEID") == -1:
                             raise
                 except:
                     raise SyntaxError, "Error on section \"[%s]\":\nDefaultValue incompatible with DataType"%section_name
@@ -496,7 +496,7 @@
     for entry in entries:
         # Extract infos and values for the entry
         entry_infos = Manager.GetEntryInfos(entry)
-        values = Manager.GetCurrentEntry(entry)
+        values = Manager.GetCurrentEntry(entry, compute = False)
         # Define section name
         text = "\n[%X]\n"%entry
         # If there is only one value, it's a VAR entry
@@ -726,6 +726,7 @@
                             max_subindex = values["subindexes"][0]["DEFAULTVALUE"]
                         except:
                             raise SyntaxError, "Error on entry 0x%4.4X:\nSubindex 0 must be defined for an ARRAY or a RECORD entry"%entry
+                        Node.AddEntry(entry, value = [])
                         # Define value for all subindexes except the first 
                         for subindex in xrange(1, int(max_subindex) + 1):
                             # Take default value if it is defined and entry is defined
--- a/objdictgen/networkedit.py	Tue Oct 02 10:32:11 2007 +0200
+++ b/objdictgen/networkedit.py	Tue Oct 02 14:06:30 2007 +0200
@@ -362,9 +362,6 @@
             self._onsave()
         event.Skip()
 
-    def GetNoteBook(self):
-        return self.NetworkNodes
-
     def OnQuitMenu(self, event):
         self.Close()
         event.Skip()
@@ -516,7 +513,7 @@
             values = dialog.GetValues()
             result = self.NodeList.AddSlaveNode(values["slaveName"], values["slaveNodeID"], values["edsFile"])
             if not result:
-                new_editingpanel = EditingPanel(self, self.NodeList, False)
+                new_editingpanel = EditingPanel(self.NetworkNodes, self, self.NodeList, False)
                 new_editingpanel.SetIndex(values["slaveNodeID"])
                 idx = self.NodeList.GetOrderNumber(values["slaveNodeID"])
                 self.NetworkNodes.InsertPage(idx, new_editingpanel, "")
@@ -579,11 +576,11 @@
         if self.NetworkNodes.GetPageCount() > 0:
             self.NetworkNodes.DeleteAllPages()
         if self.NodeList:
-            new_editingpanel = EditingPanel(self, self.Manager)
+            new_editingpanel = EditingPanel(self.NetworkNodes, self, self.Manager)
             new_editingpanel.SetIndex(0)
             self.NetworkNodes.AddPage(new_editingpanel, "")
             for idx in self.NodeList.GetSlaveIDs():
-                new_editingpanel = EditingPanel(self, self.NodeList, False)
+                new_editingpanel = EditingPanel(self.NetworkNodes, self, self.NodeList, False)
                 new_editingpanel.SetIndex(idx)
                 self.NetworkNodes.AddPage(new_editingpanel, "")
 
--- a/objdictgen/node.py	Tue Oct 02 10:32:11 2007 +0200
+++ b/objdictgen/node.py	Tue Oct 02 14:06:30 2007 +0200
@@ -145,7 +145,7 @@
                 [{"name" : "Inhibit Time Emergency", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
     0x1016 : {"name" : "Consumer Heartbeat Time", "struct" : rec, "need" : False, "values" :
                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
-                 {"name" : "Consumer Heartbeat Time", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7F}]},
+                 {"name" : "Consumer Heartbeat Time", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmin" : 1, "nbmax" : 0x7F}]},
     0x1017 : {"name" : "Producer Heartbeat Time", "struct" : var, "need" : False, "callback" : True, "values" :
                 [{"name" : "Producer Heartbeat Time", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
     0x1018 : {"name" : "Identity", "struct" : array, "need" : True, "values" :
@@ -181,18 +181,18 @@
                  {"name" : "StdErr", "type" : 0x05, "access" : 'ro', "pdo" : True}]},
     0x1027 : {"name" : "Module List", "struct" : rec, "need" : False, "values" :
                 [{"name" : "Number of Connected Modules", "type" : 0x05, "access" : 'ro', "pdo" : False},
-                 {"name" : "Module %d[(sub)]", "type" : 0x06, "access" : 'ro', "pdo" : False, "nbmax" : 0xFE}]},
+                 {"name" : "Module %d[(sub)]", "type" : 0x06, "access" : 'ro', "pdo" : False, "nbmin" : 1, "nbmax" : 0xFE}]},
     0x1028 : {"name" : "Emergency Consumer", "struct" : rec, "need" : False, "values" :
                 [{"name" : "Number of Consumed Emergency Objects", "type" : 0x05, "access" : 'ro', "pdo" : False},
-                 {"name" : "Emergency Consumer", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7E}]},
+                 {"name" : "Emergency Consumer", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmin" : 1, "nbmax" : 0x7E}]},
     0x1029 : {"name" : "Error Behavior", "struct" : array, "need" : False, "values" :
                 [{"name" : "Number of Error Classes", "type" : 0x05, "access" : 'ro', "pdo" : False},
                  {"name" : "Communication Error", "type" : 0x05, "access" : 'rw', "pdo" : False},
                  {"name" : "Device Profile", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]},
     0x1200 : {"name" : "Server SDO Parameter", "struct" : array, "need" : False, "values" :
                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
-                 {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False},
-                 {"name" : "COB ID Server to Client (Transmit SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False}]},
+                 {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False, "default" : "\"$NODEID+0x600\""},
+                 {"name" : "COB ID Server to Client (Transmit SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False, "default" : "\"$NODEID+0x580\""}]},
     0x1201 : {"name" : "Additional Server SDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x7F, "need" : False, "values" :
                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
                  {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False},
@@ -205,24 +205,24 @@
                  {"name" : "Node ID of the SDO Server", "type" : 0x05, "access" : 'rw', "pdo" : False}]},
     0x1400 : {"name" : "Receive PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
                 [{"name" : "Highest SubIndex Supported", "type" : 0x05, "access" : 'ro', "pdo" : False},
-                 {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False, "default" : "{True:self.ID+(base+2)*0x100,False:0}[base<4]"},
+                 {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False, "default" : "{True:\"$NODEID+0x%X00\"%(base+2),False:0}[base<4]"},
                  {"name" : "Transmission Type", "type" : 0x05, "access" : 'rw', "pdo" : False},
                  {"name" : "Inhibit Time", "type" : 0x06, "access" : 'rw', "pdo" : False},
                  {"name" : "Compatibility Entry", "type" : 0x05, "access" : 'rw', "pdo" : False},
                  {"name" : "Event Timer", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
     0x1600 : {"name" : "Receive PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'rw', "pdo" : False},
-                 {"name" : "PDO %d Mapping for an application object %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x40}]},
+                 {"name" : "PDO %d Mapping for an application object %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmin" : 0, "nbmax" : 0x40}]},
     0x1800 : {"name" : "Transmit PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "callback" : True, "values" :
                 [{"name" : "Highest SubIndex Supported", "type" : 0x05, "access" : 'ro', "pdo" : False},
-                 {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False, "default" : "{True:self.ID+(base+1)*0x100+0x80,False:0}[base<4]"},
+                 {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False, "default" : "{True:\"$NODEID+0x%X80\"%(base+1),False:0}[base<4]"},
                  {"name" : "Transmission Type", "type" : 0x05, "access" : 'rw', "pdo" : False},
                  {"name" : "Inhibit Time", "type" : 0x06, "access" : 'rw', "pdo" : False},
                  {"name" : "Compatibility Entry", "type" : 0x05, "access" : 'rw', "pdo" : False},
                  {"name" : "Event Timer", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
     0x1A00 : {"name" : "Transmit PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'rw', "pdo" : False},
-                 {"name" : "PDO %d Mapping for a process data variable %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x40}]},
+                 {"name" : "PDO %d Mapping for a process data variable %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmin" : 0, "nbmax" : 0x40}]},
 }
 
 #-------------------------------------------------------------------------------
@@ -530,7 +530,7 @@
             elif subIndex == 1:
                 self.Dictionary[index] = [value]
                 return True
-        elif subIndex > 1 and type(self.Dictionary[index]) == ListType and subIndex == len(self.Dictionary[index]) + 1:
+        elif subIndex > 0 and type(self.Dictionary[index]) == ListType and subIndex == len(self.Dictionary[index]) + 1:
             self.Dictionary[index].append(value)
             return True
         return False
@@ -616,23 +616,23 @@
     Returns the value of the entry asked. If the entry has the value "count", it
     returns the number of subIndex in the entry except the first.
     """
-    def GetEntry(self, index, subIndex = None):
+    def GetEntry(self, index, subIndex = None, compute = True):
         if index in self.Dictionary:
             if subIndex == None:
                 if type(self.Dictionary[index]) == ListType:
                     values = [len(self.Dictionary[index])]
                     for value in self.Dictionary[index]:
-                        values.append(self.CompileValue(value, index))
+                        values.append(self.CompileValue(value, index, compute))
                     return values
                 else:
-                    return self.CompileValue(self.Dictionary[index], index)
+                    return self.CompileValue(self.Dictionary[index], index, compute)
             elif subIndex == 0:
                 if type(self.Dictionary[index]) == ListType:
                     return len(self.Dictionary[index])
                 else:
-                    return self.CompileValue(self.Dictionary[index], index)
+                    return self.CompileValue(self.Dictionary[index], index, compute)
             elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]):
-                return self.CompileValue(self.Dictionary[index][subIndex - 1], index)
+                return self.CompileValue(self.Dictionary[index][subIndex - 1], index, compute)
         return None
 
     """
@@ -767,7 +767,7 @@
         mask = 0xFFFF << 16
         if subIndex:
             model += subIndex << 8
-            mask = 0xFF << 8
+            mask += 0xFF << 8
         for i in self.Dictionary.iterkeys():
             if 0x1600 <= i <= 0x17FF or 0x1A00 <= i <= 0x1BFF:
                 for j,value in enumerate(self.Dictionary[i]):
@@ -857,11 +857,14 @@
                 result += "%04X (%s): %s\n"%(index, name, values)
         return result
             
-    def CompileValue(self, value, index):
-        if type(value) == StringType and value.find("self.ID") != -1:
+    def CompileValue(self, value, index, compute = True):
+        if type(value) == StringType:
             base = self.GetBaseIndex(index)
             try:
-                return eval(value)
+                raw = eval(value)
+                if compute:
+                    return eval(raw.replace("$NODEID","self.ID"))
+                return raw
             except:
                 return 0
         else:
--- a/objdictgen/nodemanager.py	Tue Oct 02 10:32:11 2007 +0200
+++ b/objdictgen/nodemanager.py	Tue Oct 02 14:06:30 2007 +0200
@@ -265,6 +265,7 @@
             node = load(file)
             file.close()
             self.CurrentNode = node
+            self.CurrentNode.SetNodeID(0)
             # Add a new buffer and defining current state
             index = self.AddNodeBuffer(self.CurrentNode.Copy(), True)
             self.SetCurrentFilePath(filepath)
@@ -297,6 +298,19 @@
         # Verify if it's not forced that the current node is saved before closing it
         if self.UndoBuffers[self.NodeIndex].IsCurrentSaved() or ignore:
             self.RemoveNodeBuffer(self.NodeIndex)
+            if len(self.UndoBuffers) > 0:
+                previousindexes = [idx for idx in self.UndoBuffers.keys() if idx < self.NodeIndex]
+                nextindexes = [idx for idx in self.UndoBuffers.keys() if idx > self.NodeIndex]
+                if len(previousindexes) > 0:
+                    previousindexes.sort()
+                    self.NodeIndex = previousindexes[-1]
+                elif len(nextindexes) > 0:
+                    nextindexes.sort()
+                    self.NodeIndex = nextindexes[0]
+                else:
+                    self.NodeIndex = None
+            else:
+                self.NodeIndex = None
             return True
         return False
 
@@ -374,9 +388,13 @@
         # Informations about entry
         infos = self.GetEntryInfos(index)
         length = self.CurrentNode.GetEntry(index, 0)
+        if "nbmin" in infos:
+            nbmin = infos["nbmin"]
+        else:
+            nbmin = 1
         # Entry is a record, or is an array of manufacturer specific
         if infos["struct"] & OD_IdenticalSubindexes or 0x2000 <= index <= 0x5FFF and infos["struct"] & OD_IdenticalSubindexes:
-            for i in xrange(min(number, length - 1)):
+            for i in xrange(min(number, length - nbmin)):
                 self.RemoveCurrentVariable(index, length - i)
             self.BufferCurrentNode()
 
@@ -463,7 +481,12 @@
                         default = subentry_infos["default"]
                     else:
                         default = self.GetTypeDefaultValue(subentry_infos["type"])
-                    node.AddEntry(index, 1, default)
+                    node.AddEntry(index, value = [])
+                    if "nbmin" in subentry_infos:
+                        for i in xrange(subentry_infos["nbmin"]):
+                            node.AddEntry(index, i + 1, default)
+                    else:
+                        node.AddEntry(index, 1, default)
                 # Second case entry is a record
                 else:
                     i = 1
@@ -493,6 +516,23 @@
 
 
     """
+    Reset an subentry from current node to its default value
+    """
+    def SetCurrentEntryToDefault(self, index, subindex, node = None):
+        disable_buffer = node != None
+        if node == None:
+            node = self.CurrentNode
+        if node.IsEntry(index, subindex):
+            subentry_infos = self.GetSubentryInfos(index, subindex)
+            if "default" in subentry_infos:
+                default = subentry_infos["default"]
+            else:
+                default = self.GetTypeDefaultValue(subentry_infos["type"])
+            node.SetEntry(index, subindex, default)
+            if not disable_buffer:
+                self.BufferCurrentNode()
+
+    """
     Remove an entry from current node. Analize the index to perform the correct
     method
     """
@@ -653,7 +693,9 @@
                         type = node.GetEntry(type)[1]
                     if dic[type] == 0:
                         try:
-                            if value.startswith("0x"):
+                            if value.startswith("$NODEID"):
+                                value = "\"%s\""%value
+                            elif value.startswith("0x"):
                                 value = int(value, 16)
                             else:
                                 value = int(value)
@@ -896,9 +938,9 @@
             return self.CurrentNode.IsEntry(index)
         return False
     
-    def GetCurrentEntry(self, index, subIndex = None):
-        if self.CurrentNode:
-            return self.CurrentNode.GetEntry(index, subIndex)
+    def GetCurrentEntry(self, index, subIndex = None, compute = True):
+        if self.CurrentNode:
+            return self.CurrentNode.GetEntry(index, subIndex, compute)
         return None
     
     def GetCurrentParamsEntry(self, index, subIndex = None):
@@ -947,7 +989,7 @@
             entry_infos = node.GetEntryInfos(index)
             data = []
             editors = []
-            values = node.GetEntry(index)
+            values = node.GetEntry(index, compute = False)
             params = node.GetParamsEntry(index)
             if type(values) == ListType:
                 for i, value in enumerate(values):
@@ -1015,8 +1057,11 @@
                         if result:
                             values = result.groups()
                             if values[0] == "UNSIGNED":
-                                format = "0x%0" + str(int(values[1])/4) + "X"
-                                dic["value"] = format%dic["value"]
+                                try:
+                                    format = "0x%0" + str(int(values[1])/4) + "X"
+                                    dic["value"] = format%dic["value"]
+                                except:
+                                    pass
                                 editor["value"] = "string"
                             if values[0] == "INTEGER":
                                 editor["value"] = "number"
--- a/objdictgen/objdictedit.py	Tue Oct 02 10:32:11 2007 +0200
+++ b/objdictgen/objdictedit.py	Tue Oct 02 14:06:30 2007 +0200
@@ -306,7 +306,7 @@
         for filepath in filesOpen:
             result = self.Manager.OpenFileInCurrent(filepath)
             if type(result) == IntType:
-                new_editingpanel = EditingPanel(self, self.Manager)
+                new_editingpanel = EditingPanel(self.FileOpened, self, self.Manager)
                 new_editingpanel.SetIndex(result)
                 self.FileOpened.AddPage(new_editingpanel, "")
             window = self.FileOpened.GetPage(0)
@@ -323,9 +323,6 @@
         self.RefreshTitle()
         self.RefreshMainMenu()
 
-    def GetNoteBook(self):
-        return self.FileOpened
-
     def OnAddSDOServerMenu(self, event):
         self.Manager.AddSDOServerToCurrent()
         self.RefreshBufferState()
@@ -579,7 +576,7 @@
             options = dialog.GetOptions()
             result = self.Manager.CreateNewNode(name, id, nodetype, description, profile, filepath, NMT, options)
             if type(result) == IntType:
-                new_editingpanel = EditingPanel(self, self.Manager)
+                new_editingpanel = EditingPanel(self.FileOpened, self, self.Manager)
                 new_editingpanel.SetIndex(result)
                 self.FileOpened.AddPage(new_editingpanel, "")
                 self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
@@ -593,6 +590,7 @@
                 message = wx.MessageDialog(self, result, "ERROR", wx.OK|wx.ICON_ERROR)
                 message.ShowModal()
                 message.Destroy()
+        dialog.Destroy()
         event.Skip()
 
     def OnOpenMenu(self, event):
@@ -607,7 +605,7 @@
             if os.path.isfile(filepath):
                 result = self.Manager.OpenFileInCurrent(filepath)
                 if type(result) == IntType:
-                    new_editingpanel = EditingPanel(self, self.Manager)
+                    new_editingpanel = EditingPanel(self.FileOpened, self, self.Manager)
                     new_editingpanel.SetIndex(result)
                     self.FileOpened.AddPage(new_editingpanel, "")
                     self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
@@ -702,7 +700,7 @@
             if os.path.isfile(filepath):
                 result = self.Manager.ImportCurrentFromEDSFile(filepath)
                 if type(result) == IntType:
-                    new_editingpanel = EditingPanel(self, self.Manager)
+                    new_editingpanel = EditingPanel(self.FileOpened, self, self.Manager)
                     new_editingpanel.SetIndex(result)
                     self.FileOpened.AddPage(new_editingpanel, "")
                     self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
--- a/objdictgen/subindextable.py	Tue Oct 02 10:32:11 2007 +0200
+++ b/objdictgen/subindextable.py	Tue Oct 02 14:06:30 2007 +0200
@@ -247,7 +247,8 @@
 ] = [wx.NewId() for _init_coll_IndexListMenu_Items in range(3)]
 
 [ID_EDITINGPANELMENU1ITEMS0, ID_EDITINGPANELMENU1ITEMS1, 
-] = [wx.NewId() for _init_coll_SubindexGridMenu_Items in range(2)]
+ ID_EDITINGPANELMENU1ITEMS3, 
+] = [wx.NewId() for _init_coll_SubindexGridMenu_Items in range(3)]
 
 class EditingPanel(wx.SplitterWindow):
     def _init_coll_AddToListSizer_Items(self, parent):
@@ -275,13 +276,18 @@
 
     def _init_coll_SubindexGridMenu_Items(self, parent):
         parent.Append(help='', id=ID_EDITINGPANELMENU1ITEMS0,
-              kind=wx.ITEM_NORMAL, text='Add')
+              kind=wx.ITEM_NORMAL, text='Add subindexes')
         parent.Append(help='', id=ID_EDITINGPANELMENU1ITEMS1,
-              kind=wx.ITEM_NORMAL, text='Delete')
+              kind=wx.ITEM_NORMAL, text='Delete subindexes')
+        parent.AppendSeparator()
+        parent.Append(help='', id=ID_EDITINGPANELMENU1ITEMS3,
+              kind=wx.ITEM_NORMAL, text='Default value')
         self.Bind(wx.EVT_MENU, self.OnAddSubindexMenu,
               id=ID_EDITINGPANELMENU1ITEMS0)
         self.Bind(wx.EVT_MENU, self.OnDeleteSubindexMenu,
               id=ID_EDITINGPANELMENU1ITEMS1)
+        self.Bind(wx.EVT_MENU, self.OnDefaultValueSubindexMenu,
+              id=ID_EDITINGPANELMENU1ITEMS3)
 
     def _init_coll_IndexListMenu_Items(self, parent):
         parent.Append(help='', id=ID_EDITINGPANELINDEXLISTMENUITEMS0,
@@ -391,9 +397,9 @@
 
         self._init_sizers()
 
-    def __init__(self, parent, manager, editable = True):
-        self._init_ctrls(parent.GetNoteBook())
-        self.ParentWindow = parent
+    def __init__(self, parent, window, manager, editable = True):
+        self._init_ctrls(parent)
+        self.ParentWindow = window
         self.Manager = manager
         self.ListIndex = []
         self.ChoiceIndex = []
@@ -402,7 +408,7 @@
         self.Index = None
         
         for values in DictionaryOrganisation:
-            text = "   0x%04X-0x%04X      %s"%(values["minIndex"],values["maxIndex"],values["name"])
+            text = "   0x%04X-0x%04X      %s"%(values["minIndex"], values["maxIndex"], values["name"])
             self.PartList.Append(text)
         self.Table = SubindexTable(self, [], [], ["subindex", "name", "type", "value", "access", "save", "comment"])
         self.SubindexGrid.SetTable(self.Table)
@@ -630,13 +636,27 @@
         event.Skip()
 
     def OnSubindexGridRightClick(self, event):
+        self.SubindexGrid.SetGridCursor(event.GetRow(), event.GetCol())
         if self.Editable:
             selected = self.IndexList.GetSelection()
             if selected != wx.NOT_FOUND:
                 index = self.ListIndex[selected]
                 if self.Manager.IsCurrentEntry(index):
+                    showpopup = False
                     infos = self.Manager.GetEntryInfos(index)
                     if index >= 0x2000 and infos["struct"] & OD_MultipleSubindexes or infos["struct"] & OD_IdenticalSubindexes:
+                        showpopup = True
+                        self.SubindexGridMenu.FindItemByPosition(0).Enable(True)
+                        self.SubindexGridMenu.FindItemByPosition(1).Enable(True)
+                    else:
+                        self.SubindexGridMenu.FindItemByPosition(0).Enable(False)
+                        self.SubindexGridMenu.FindItemByPosition(1).Enable(False)
+                    if self.Table.GetColLabelValue(event.GetCol()) == "value":
+                        showpopup = True
+                        self.SubindexGridMenu.FindItemByPosition(3).Enable(True)
+                    else:
+                        self.SubindexGridMenu.FindItemByPosition(3).Enable(False)
+                    if showpopup:
                         self.PopupMenu(self.SubindexGridMenu)
         event.Skip()
 
@@ -729,3 +749,14 @@
                     dialog.Destroy()
         event.Skip()
 
+    def OnDefaultValueSubindexMenu(self, event):
+        if self.Editable:
+            selected = self.IndexList.GetSelection()
+            if selected != wx.NOT_FOUND:
+                index = self.ListIndex[selected]
+                if self.Manager.IsCurrentEntry(index):
+                    row = self.SubindexGrid.GetGridCursorRow()
+                    self.Manager.SetCurrentEntryToDefault(index, row)
+                    self.ParentWindow.RefreshBufferState()
+                    self.RefreshIndexList()
+        event.Skip()
\ No newline at end of file