Changes in networkedit for integration with beremiz
authorlbessard
Sat, 21 Jul 2007 10:39:25 +0200
changeset 242 4864f7f01e1d
parent 241 4ecc2f3690f4
child 243 7fcc129a06ce
Changes in networkedit for integration with beremiz
drivers/can_peak/.cvsignore
drivers/generic/.cvsignore
examples/AppliMaster_Linux/.cvsignore
examples/AppliSlave_Linux/.cvsignore
objdictgen/networkedit.py
objdictgen/nodelist.py
objdictgen/nodemanager.py
objdictgen/subindextable.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_peak/.cvsignore	Sat Jul 21 10:39:25 2007 +0200
@@ -0,0 +1,1 @@
+Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/generic/.cvsignore	Sat Jul 21 10:39:25 2007 +0200
@@ -0,0 +1,1 @@
+Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/AppliMaster_Linux/.cvsignore	Sat Jul 21 10:39:25 2007 +0200
@@ -0,0 +1,1 @@
+Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/AppliSlave_Linux/.cvsignore	Sat Jul 21 10:39:25 2007 +0200
@@ -0,0 +1,1 @@
+Makefile
--- a/objdictgen/networkedit.py	Tue Jul 17 18:20:50 2007 +0200
+++ b/objdictgen/networkedit.py	Sat Jul 21 10:39:25 2007 +0200
@@ -37,7 +37,6 @@
 from subindextable import *
 from commondialogs import *
 from doc_index.DS301_index import *
-from config_utils import *
 
 def create(parent):
     return networkedit(parent)
@@ -65,8 +64,10 @@
 else:
     usage()
     sys.exit(2)
-
-ScriptDirectory = sys.path[0]
+ScriptDirectory = ""
+for path in sys.path:
+    if os.path.isfile(os.path.join(path, "networkedit.py")):
+        ScriptDirectory = path
 
 try:
     from wxPython.html import *
@@ -170,7 +171,7 @@
     def _init_coll_menuBar1_Menus(self, parent):
         # generated method, don't edit
 
-        if self.Mode == "solo":
+        if self.ModeSolo:
             parent.Append(menu=self.FileMenu, title='File')
         parent.Append(menu=self.NetworkMenu, title='Network')
         parent.Append(menu=self.EditMenu, title='Edit')
@@ -222,7 +223,7 @@
               kind=wx.ITEM_NORMAL, text='CAN Festival Docs\tF2')
         self.Bind(wx.EVT_MENU, self.OnHelpCANFestivalMenu,
               id=wxID_NETWORKEDITHELPMENUITEMS1)
-        if Html_Window and self.Mode == "solo":
+        if Html_Window and self.ModeSolo:
             parent.Append(help='', id=wxID_NETWORKEDITHELPMENUITEMS2,
                   kind=wx.ITEM_NORMAL, text='About')
             self.Bind(wx.EVT_MENU, self.OnAboutMenu,
@@ -246,8 +247,8 @@
               id=wxID_NETWORKEDITFILEMENUITEMS0)
         self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu,
               id=wxID_NETWORKEDITFILEMENUITEMS1)
-##        self.Bind(wx.EVT_MENU, self.OnCloseProjectMenu,
-##              id=wxID_NETWORKEDITFILEMENUITEMS2)
+        self.Bind(wx.EVT_MENU, self.OnCloseProjectMenu,
+              id=wxID_NETWORKEDITFILEMENUITEMS2)
         self.Bind(wx.EVT_MENU, self.OnQuitMenu,
               id=wxID_NETWORKEDITFILEMENUITEMS4)
         self.Bind(wx.EVT_MENU, self.OnNewProjectMenu,
@@ -267,8 +268,8 @@
               id=wxID_NETWORKEDITNETWORKMENUITEMS0)
         self.Bind(wx.EVT_MENU, self.OnRemoveSlaveMenu,
               id=wxID_NETWORKEDITNETWORKMENUITEMS1)
-        self.Bind(wx.EVT_MENU, self.OnBuildMasterMenu,
-              id=wxID_NETWORKEDITNETWORKMENUITEMS3)
+##        self.Bind(wx.EVT_MENU, self.OnBuildMasterMenu,
+##              id=wxID_NETWORKEDITNETWORKMENUITEMS3)
     
     def _init_coll_AddMenu_Items(self, parent):
         # generated method, don't edit
@@ -313,7 +314,7 @@
         self.menuBar1 = wx.MenuBar()
         self.menuBar1.SetEvtHandlerEnabled(True)
         
-        if self.Mode == "solo":
+        if self.ModeSolo:
             self.FileMenu = wx.Menu(title='')
         
         self.NetworkMenu = wx.Menu(title='')
@@ -325,7 +326,7 @@
         self.HelpMenu = wx.Menu(title='')
 
         self._init_coll_menuBar1_Menus(self.menuBar1)
-        if self.Mode == "solo":
+        if self.ModeSolo:
             self._init_coll_FileMenu_Items(self.FileMenu)
         self._init_coll_NetworkMenu_Items(self.NetworkMenu)
         self._init_coll_EditMenu_Items(self.EditMenu)
@@ -340,7 +341,7 @@
         self._init_utils()
         self.SetClientSize(wx.Size(1000, 700))
         self.SetMenuBar(self.menuBar1)
-##        self.Bind(wx.EVT_CLOSE, self.OnCloseFrame, id=wxID_NETWORKEDIT)
+        self.Bind(wx.EVT_CLOSE, self.OnCloseFrame, id=wxID_NETWORKEDIT)
 
         self.NetworkNodes = wx.Notebook(id=wxID_NETWORKEDITNETWORKNODES,
               name='NetworkNodes', parent=self, pos=wx.Point(0, 0),
@@ -353,12 +354,14 @@
         self._init_coll_HelpBar_Fields(self.HelpBar)
         self.SetStatusBar(self.HelpBar)
 
-    def __init__(self, parent, mode = "solo", nodelist = None):
-        self.Mode = mode
+    def __init__(self, parent, nodelist = None):
+        self.ModeSolo = nodelist == None
         self._init_ctrls(parent)
+        self.Parent = parent
         self.HtmlFrameOpened = []
+        self.BusId = None
         
-        if self.Mode == "solo":
+        if self.ModeSolo:
             self.Manager = NodeManager(ScriptDirectory)
             if projectOpen:
                 self.NodeList = NodeList(self.Manager)
@@ -370,11 +373,34 @@
         else:
             self.NodeList = nodelist
             self.Manager = self.NodeList.GetManager()
+            self.NodeList.SetCurrentSelected(0)
+            self.RefreshNetworkNodes()
+            self.RefreshProfileMenu()
         
         self.RefreshBufferState()
         self.RefreshTitle()
         self.RefreshMainMenu()
 
+    def SetBusId(self, bus_id):
+        self.BusId = bus_id
+
+    def GetBusId(self):
+        return self.BusId
+
+    def GetCurrentNodeId(self):
+        selected = self.NetworkNodes.GetSelection()
+        # At init selected = -1
+        if selected > 0:
+            window = self.NetworkNodes.GetPage(selected)
+            return window.GetIndex()
+        else:
+            return 0
+
+    def OnCloseFrame(self, event):
+        if not self.ModeSolo:
+            self.Parent.CloseEditor(self.BusId)
+        event.Skip()
+
     def GetNoteBook(self):
         return self.NetworkNodes
 
@@ -437,6 +463,7 @@
         if dialog.ShowModal() == wxID_OK:
             projectpath = dialog.GetPath()
             if os.path.isdir(projectpath) and len(os.listdir(projectpath)) == 0:
+                os.mkdir(os.path.join(projectpath, "eds"))
                 manager = NodeManager(ScriptDirectory)
                 nodelist = NodeList(manager)
                 result = nodelist.LoadProject(projectpath)
@@ -493,37 +520,27 @@
             message.Destroy()
         event.Skip()
 
-    def OnBuildMasterMenu(self, event):
+    def OnCloseProjectMenu(self, event):
         if self.NodeList:
-            dialog = wxFileDialog(self, "Choose a locations file", os.getcwd(), "",  "text files (*.txt)|*.od|All files|*.*", wxOPEN|wxCHANGE_DIR)
-            if dialog.ShowModal() == wxID_OK:
-                filepath = dialog.GetPath()
+            if self.NodeList.HasChanged():
+                dialog = wxMessageDialog(self, "There are changes, do you want to save?",  "Close Project", wxYES_NO|wxCANCEL|wxICON_QUESTION)
+                answer = dialog.ShowModal()
                 dialog.Destroy()
-                if os.path.isfile(filepath):
-                    dialog = wxTextEntryDialog(self, "Busname selection", "Please enter the bus number", "", wxOK|wxCANCEL)
-                    if dialog.ShowModal() == wxID_OK:
-                        busname = None
-                        try:
-                            busname = int(dialog.GetValue())
-                        except:
-                            pass
-                        if busname:
-                            file = open(filepath, "r")
-                            locations = [(elements[0], elements[1]) for elements in [line.strip().split(" ") for line in file.readlines()]]
-                            GenerateConciseDCF(locations, busname, self.NodeList)
-                            message = wxMessageDialog(self, "Master node generation successful!", "Error", wxOK|wxICON_ERROR)
-                            message.ShowModal()
-                            message.Destroy()
-                        else:
-                            message = wxMessageDialog(self, "Busname must be a number!", "Error", wxOK|wxICON_ERROR)
-                            message.ShowModal()
-                            message.Destroy()
-                else:
-                    message = wxMessageDialog(self, "\"%s\" isn't a valid file!"%filepath, "Error", wxOK|wxICON_ERROR)
-                    message.ShowModal()
-                    message.Destroy()
-        event.Skip()
-        
+                if answer == wxID_YES:
+                    result = self.NodeList.SaveProject()
+                    if result:
+                        message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
+                        message.ShowModal()
+                        message.Destroy()
+                elif answer == wxID_NO:
+                    self.NodeList.ForceChanged(False)
+            if not self.NodeList.HasChanged():
+                self.Manager = None
+                self.NodeList = None
+                self.RefreshNetworkNodes()
+                self.RefreshTitle()
+                self.RefreshMainMenu()
+        event.Skip()
 
 #-------------------------------------------------------------------------------
 #                             Slave Nodes Management
@@ -640,9 +657,9 @@
 
     def RefreshMainMenu(self):
         if self.menuBar1:
+            self.NetworkMenu.Enable(wxID_NETWORKEDITNETWORKMENUITEMS3, False)
             if self.NodeList == None:
-                self.NetworkMenu.Enable(wxID_NETWORKEDITNETWORKMENUITEMS3, False)
-                if self.Mode == "solo":
+                if self.ModeSolo:
                     self.menuBar1.EnableTop(1, False)
                     self.menuBar1.EnableTop(2, False)
                     self.menuBar1.EnableTop(3, False)
@@ -654,8 +671,7 @@
                     self.menuBar1.EnableTop(1, False)
                     self.menuBar1.EnableTop(2, False)
             else:
-                self.NetworkMenu.Enable(wxID_NETWORKEDITNETWORKMENUITEMS3, True)
-                if self.Mode == "solo":
+                if self.ModeSolo:
                     self.menuBar1.EnableTop(1, True)
                     if self.FileMenu:
                         self.FileMenu.Enable(wxID_NETWORKEDITFILEMENUITEMS1, True)
@@ -696,14 +712,6 @@
                     edititem.SetText("Other Profile")
                     edititem.Enable(False)
 
-    def GetProfileCallBack(self, text):
-        def ProfileCallBack(event):
-            self.Manager.AddSpecificEntryToCurrent(text)
-            self.RefreshBufferState()
-            self.RefreshCurrentIndexList()
-            event.Skip()
-        return ProfileCallBack
-
 #-------------------------------------------------------------------------------
 #                              Buffer Functions
 #-------------------------------------------------------------------------------
--- a/objdictgen/nodelist.py	Tue Jul 17 18:20:50 2007 +0200
+++ b/objdictgen/nodelist.py	Sat Jul 21 10:39:25 2007 +0200
@@ -29,25 +29,30 @@
 import eds_utils
 import os, shutil
 
-
 #-------------------------------------------------------------------------------
 #                          Definition of NodeList Object
 #-------------------------------------------------------------------------------
 
-
 """
 Class recording a node list for a CANOpen network.
 """
 
 class NodeList:
     
-    def __init__(self, manager):
+    def __init__(self, manager, netname = ""):
         self.Root = ""
         self.Manager = manager
-        self.NetworkName = ""
+        self.NetworkName = netname
         self.SlaveNodes = {}
         self.EDSNodes = {}
         self.CurrentSelected = None
+        self.Changed = False
+    
+    def HasChanged(self):
+        return self.Changed or not self.Manager.CurrentIsSaved()
+    
+    def ForceChanged(self, changed):
+        self.Changed = changed
     
     def GetNetworkName(self):
         return self.NetworkName
@@ -80,7 +85,7 @@
     def GetCurrentSelected(self):
         return self.CurrentSelected
             
-    def LoadProject(self, root):
+    def LoadProject(self, root, netname = None):
         self.SlaveNodes = {}
         self.EDSNodes = {}
         
@@ -98,20 +103,22 @@
             if result != None:
                 return result
                 
-        result = self.LoadMasterNode()
+        result = self.LoadMasterNode(netname)
         if result != None:
             return result
             
-        result = self.LoadSlaveNodes()
+        result = self.LoadSlaveNodes(netname)
         if result != None:
             return result
-    
-    def SaveProject(self):
-        result = self.SaveMasterNode()
+        
+        self.NetworkName = netname
+    
+    def SaveProject(self, netname = None):
+        result = self.SaveMasterNode(netname)
         if result != None:
             return result
             
-        result = self.SaveNodeList()
+        result = self.SaveNodeList(netname)
         if result != None:
             return result
     
@@ -137,6 +144,7 @@
         if eds in self.EDSNodes.keys():
             slave = {"Name" : nodeName, "EDS" : eds, "Node" : self.EDSNodes[eds]}
             self.SlaveNodes[nodeID] = slave
+            self.Changed = True
             return None
         else:
             return "\"%s\" EDS file is not available"%eds
@@ -144,47 +152,71 @@
     def RemoveSlaveNode(self, index):
         if index in self.SlaveNodes.keys():
             self.SlaveNodes.pop(index)
+            OnCloseProjectMenu
             return None
         else:
             return "Node with \"0x%2.2X\" ID doesn't exist"
     
-    def LoadMasterNode(self):
-        masterpath = os.path.join(self.Root, "master.od")
+    def LoadMasterNode(self, netname = None):
+        if netname:
+            masterpath = os.path.join(self.Root, "%s_master.od"%netname)
+        else:
+            masterpath = os.path.join(self.Root, "master.od")
         if os.path.isfile(masterpath):
             self.Manager.OpenFileInCurrent(masterpath)
         else:
             self.Manager.CreateNewNode("MasterNode", 0x00, "master", "", "None", "", "heartbeat", ["DS302"])
         return None
     
-    def SaveMasterNode(self):
-        masterpath = os.path.join(self.Root, "master.od")
+    def SaveMasterNode(self, netname = None):
+        if netname:
+            masterpath = os.path.join(self.Root, "%s_master.od"%netname)
+        else:
+            masterpath = os.path.join(self.Root, "master.od")
         if self.Manager.SaveCurrentInFile(masterpath):
             return None
         else:
             return "Fail to save Master Node"
     
-    def LoadSlaveNodes(self):
+    def LoadSlaveNodes(self, netname = None):
         cpjpath = os.path.join(self.Root, "nodelist.cpj")
         if os.path.isfile(cpjpath):
             try:
                 networks = eds_utils.ParseCPJFile(cpjpath)
-                if len(networks) > 0:
-                    self.NetworkName = networks[0]["Name"]
-                    for nodeid, node in networks[0]["Nodes"].items():
+                network = None
+                if netname:
+                    for net in networks:
+                        if net["Name"] == netname:
+                            network = net
+                    self.NetworkName = netname
+                elif len(networks) > 0:
+                    network = networks[0]
+                    self.NetworkName = network["Name"]
+                if network:
+                    for nodeid, node in network["Nodes"].items():
                         if node["Present"] == 1:
                             result = self.AddSlaveNode(node["Name"], nodeid, node["DCFName"])
                             if result != None:
-                                return result
+                                return result        
+                self.Changed = False
             except SyntaxError, message:
                 return "Unable to load CPJ file\n%s"%message
         return None
     
-    def SaveNodeList(self):
-        cpjpath = os.path.join(self.Root, "nodelist.cpj")
-        content = eds_utils.GenerateCPJContent(self)
-        file = open(cpjpath, "w")
-        file.write(content)
-        file.close()
+    def SaveNodeList(self, netname = None):
+        try:
+            cpjpath = os.path.join(self.Root, "nodelist.cpj")
+            content = eds_utils.GenerateCPJContent(self)
+            if netname:
+                file = open(cpjpath, "a")
+            else:
+                file = open(cpjpath, "w")
+            file.write(content)
+            file.close()
+            self.Changed = False
+            return None
+        except:
+            return "Fail to save node list"
     
     def GetSlaveNodeEntry(self, nodeid, index, subindex = None):
         if nodeid in self.SlaveNodes.keys():
@@ -233,6 +265,16 @@
                     return node.GetEntryInfos(index)
         return None
 
+    def GetSubentryInfos(self, index, subindex):
+        if self.CurrentSelected != None:
+            if self.CurrentSelected == 0:
+                return self.Manager.GetSubentryInfos(index, subindex)
+            else:
+                node = self.SlaveNodes[self.CurrentSelected]["Node"]
+                if node:
+                    return node.GetSubentryInfos(index, subindex)
+        return None
+
     def GetCurrentValidIndexes(self, min, max):
         if self.CurrentSelected != None:
             if self.CurrentSelected == 0:
@@ -252,27 +294,29 @@
     def GetCurrentEntryValues(self, index):
         if self.CurrentSelected != None:
             node = self.SlaveNodes[self.CurrentSelected]["Node"]
-            node.SetNodeID(self.CurrentSelected)
             if node:
                 return self.Manager.GetNodeEntryValues(node, index)
             else:
                 print "Can't find node"
         return [], []
-
+    
 if __name__ == "__main__":
     from nodemanager import *
     import os, sys, shutil
     
     manager = NodeManager(sys.path[0])
+    
     nodelist = NodeList(manager)
-    #result = nodelist.LoadProject("/home/deobox/beremiz/test_nodelist")
-    result = nodelist.LoadProject("/home/deobox/Desktop/TestMapping")
+    
+    result = nodelist.LoadProject("/home/laurent/test_nodelist")
     if result != None:
         print result
     else:
         print "MasterNode :"
         manager.CurrentNode.Print()
+        print 
         for nodeid, node in nodelist.SlaveNodes.items():
             print "SlaveNode name=%s id=0x%2.2X :"%(node["Name"], nodeid)
             node["Node"].Print()
-
+            print
+
--- a/objdictgen/nodemanager.py	Tue Jul 17 18:20:50 2007 +0200
+++ b/objdictgen/nodemanager.py	Sat Jul 21 10:39:25 2007 +0200
@@ -227,7 +227,7 @@
                 elif option == "StoreEDS":
                     AddIndexList.extend([0x1021, 0x1022])
             # Add a new buffer 
-            index = self.AddNodeBuffer()
+            index = self.AddNodeBuffer(self.CurrentNode.Copy(), False)
             self.SetCurrentFilePath("")
             # Add Mandatory indexes
             self.ManageEntriesOfCurrent(AddIndexList, [])
@@ -306,9 +306,8 @@
         result = eds_utils.GenerateNode(filepath, self.ScriptDirectory)
         if isinstance(result, Node):
             self.CurrentNode = result
-            index = self.AddNodeBuffer()
+            index = self.AddNodeBuffer(self.CurrentNode.Copy(), False)
             self.SetCurrentFilePath("")
-            self.BufferCurrentNode()
             return index
         else:
             return result
@@ -596,21 +595,10 @@
                 self.CurrentNode.SetParamsEntry(index, None, callback = value)
                 self.BufferCurrentNode()
 
-    def ResetCurrentDefaultValue(self, index, subIndex):
-        subentry_infos = self.GetSubentryInfos(index, subIndex)
-        if "default" in subentry_infos:
-            default = subentry_infos["default"]
-        else:
-            default = self.GetTypeDefaultValue(subentry_infos["type"])
-        self.CurrentNode.SetEntry(index, subIndex, default)
-        
-
     def SetCurrentEntry(self, index, subIndex, value, name, editor):
         if self.CurrentNode and self.CurrentNode.IsEntry(index):
             if name == "value":
-                if editor == None:
-                    self.CurrentNode.SetEntry(index, subIndex, value)
-                elif editor == "map":
+                if editor == "map":
                     value = self.CurrentNode.GetMapValue(value)
                     if value:
                         self.CurrentNode.SetEntry(index, subIndex, value)
@@ -753,11 +741,6 @@
     def GetCurrentNodeIndex(self):
         return self.NodeIndex
     
-    def GetCurrentNode(self):
-        if self.NodeIndex:
-            return self.CurrentNode
-        return None
-    
     def GetCurrentFilename(self):
         return self.GetFilename(self.NodeIndex)
     
--- a/objdictgen/subindextable.py	Tue Jul 17 18:20:50 2007 +0200
+++ b/objdictgen/subindextable.py	Sat Jul 21 10:39:25 2007 +0200
@@ -50,6 +50,8 @@
     {"minIndex" : 0x6000, "maxIndex" : 0x9FFF, "name" : "Standardized Device Profile"},
     {"minIndex" : 0xA000, "maxIndex" : 0xBFFF, "name" : "Standardized Interface Profile"}]
 
+SizeConversion = {1 : "X", 8 : "B", 16 : "W", 24 : "D", 32 : "D", 40 : "L", 48 : "L", 56 : "L", 64 : "L"}
+
 class SubindexTable(wxPyGridTableBase):
     
     """
@@ -249,8 +251,8 @@
  wxID_EDITINGPANELINDEXLISTMENUITEMS2, 
 ] = [wx.NewId() for _init_coll_IndexListMenu_Items in range(3)]
 
-[wxID_EDITINGPANELMENU1ITEMS0, wxID_EDITINGPANELMENU1ITEMS1, wxID_EDITINGPANELMENU1ITEMS2,
-] = [wx.NewId() for _init_coll_SubindexGridMenu_Items in range(3)]
+[wxID_EDITINGPANELMENU1ITEMS0, wxID_EDITINGPANELMENU1ITEMS1, 
+] = [wx.NewId() for _init_coll_SubindexGridMenu_Items in range(2)]
 
 class EditingPanel(wx.SplitterWindow):
     def _init_coll_AddToListSizer_Items(self, parent):
@@ -295,14 +297,10 @@
               kind=wx.ITEM_NORMAL, text='Add')
         parent.Append(help='', id=wxID_EDITINGPANELMENU1ITEMS1,
               kind=wx.ITEM_NORMAL, text='Delete')
-        parent.Append(help='', id=wxID_EDITINGPANELMENU1ITEMS2,
-              kind=wx.ITEM_NORMAL, text='Default Value')
         self.Bind(wx.EVT_MENU, self.OnAddSubindexMenu,
               id=wxID_EDITINGPANELMENU1ITEMS0)
         self.Bind(wx.EVT_MENU, self.OnDeleteSubindexMenu,
               id=wxID_EDITINGPANELMENU1ITEMS1)
-        self.Bind(wx.EVT_MENU, self.OnDefaultValueSubindexMenu,
-              id=wxID_EDITINGPANELMENU1ITEMS2)
 
     def _init_coll_IndexListMenu_Items(self, parent):
         # generated method, don't edit
@@ -391,6 +389,7 @@
               self.OnSubindexGridRightClick)
         self.SubindexGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL,
               self.OnSubindexGridSelectCell)
+        self.SubindexGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnSubindexGridCellLeftClick)
 
         self.CallbackCheck = wx.CheckBox(id=wxID_EDITINGPANELCALLBACKCHECK,
               label='Have Callbacks', name='CallbackCheck',
@@ -457,6 +456,10 @@
             return index, subIndex
         return None
 
+    def OnSubindexGridCellLeftClick(self, event):
+        wxCallAfter(self.BeginDrag)
+        event.Skip()
+
     def OnAddButtonClick(self, event):
         if self.Editable:
             self.SubindexGrid.SetGridCursor(0, 0)
@@ -494,9 +497,31 @@
         event.Skip()
 
     def OnSubindexGridSelectCell(self, event):
+        wxCallAfter(self.BeginDrag)
         wxCallAfter(self.Parent.RefreshStatusBar)
         event.Skip()
 
+    def BeginDrag(self):
+        row = self.SubindexGrid.GetGridCursorRow()
+        col = self.SubindexGrid.GetGridCursorCol()
+        if not self.Editable and col == 0:
+            selected = self.IndexList.GetSelection()
+            if selected != wxNOT_FOUND:
+                index = self.ListIndex[selected]
+                subindex = self.SubindexGrid.GetGridCursorRow()
+                entry_infos = self.Manager.GetEntryInfos(index)
+                if not entry_infos["struct"] & OD_MultipleSubindexes or row != 0:
+                    subentry_infos = self.Manager.GetSubentryInfos(index, subindex)
+                    typeinfos = self.Manager.GetEntryInfos(subentry_infos["type"])
+                    if subentry_infos["pdo"] and typeinfos:
+                        bus_id = self.Parent.GetBusId()
+                        node_id = self.Parent.GetCurrentNodeId()
+                        size = typeinfos["size"]
+                        data = wxTextDataObject(str(("%s%d.%d.%d.%d"%(SizeConversion[size], bus_id, node_id, index, subindex), "location")))
+                        dragSource = wxDropSource(self.SubindexGrid)
+                        dragSource.SetData(data)
+                        dragSource.DoDragDrop()
+
 #-------------------------------------------------------------------------------
 #                             Refresh Functions
 #-------------------------------------------------------------------------------
@@ -636,16 +661,8 @@
                 index = self.ListIndex[selected]
                 if self.Manager.IsCurrentEntry(index):
                     infos = self.Manager.GetEntryInfos(index)
-                    if 0x5fff >= index >= 0x2000 and infos["struct"] & OD_MultipleSubindexes or infos["struct"] & OD_IdenticalSubindexes:
-                        # enable add and delet entries
-                        self.SubindexGridMenu.FindItemById(wxID_EDITINGPANELMENU1ITEMS0).Enable(True)
-                        self.SubindexGridMenu.FindItemById(wxID_EDITINGPANELMENU1ITEMS1).Enable(True)
-                    else:
-                        # disable add and delet entries
-                        self.SubindexGridMenu.FindItemById(wxID_EDITINGPANELMENU1ITEMS0).Enable(False)
-                        self.SubindexGridMenu.FindItemById(wxID_EDITINGPANELMENU1ITEMS1).Enable(False)
-                    self.SubindexGrid.SetGridCursor(event.GetRow(), event.GetCol())
-                    wxCallAfter(self.PopupMenu,self.SubindexGridMenu)
+                    if index >= 0x2000 and infos["struct"] & OD_MultipleSubindexes or infos["struct"] & OD_IdenticalSubindexes:
+                        self.PopupMenu(self.SubindexGridMenu)
         event.Skip()
 
     def OnRenameIndexMenu(self, event):
@@ -737,14 +754,3 @@
                     dialog.Destroy()
         event.Skip()
 
-    def OnDefaultValueSubindexMenu(self, event):
-        if self.Editable:
-            selected = self.IndexList.GetSelection()
-            if selected != wxNOT_FOUND:
-                index = self.ListIndex[selected]
-                if self.Manager.IsCurrentEntry(index):
-                    self.Manager.ResetCurrentDefaultValue(index,self.SubindexGrid.GetGridCursorRow())
-                    self.Parent.RefreshBufferState()
-                    self.RefreshIndexList()
-        event.Skip()
-