Merged with smarteh-dev
authorEdouard Tisserant
Thu, 09 Feb 2012 20:39:46 +0100
changeset 716 a28fc90dc23e
parent 714 ab83333fee78 (current diff)
parent 715 5795fb789230 (diff)
child 738 396839c5d70f
Merged with smarteh-dev
--- a/objdictgen/networkedit.py	Sat Feb 04 17:08:48 2012 +0100
+++ b/objdictgen/networkedit.py	Thu Feb 09 20:39:46 2012 +0100
@@ -84,6 +84,7 @@
 
 from nodelist import *
 from nodemanager import *
+from nodeeditor import NodeEditorTemplate
 from subindextable import *
 from commondialogs import *
 from doc_index.DS301_index import *
@@ -159,6 +160,126 @@
 except:
     Html_Window = False
 
+[ID_NETWORKEDITORNETWORKNODES,
+] = [wx.NewId() for _init_ctrls in range(1)]
+
+class NetworkEditorTemplate(NodeEditorTemplate):
+    
+    def _init_ctrls(self, prnt):
+        self.NetworkNodes = wx.Notebook(id=ID_NETWORKEDITNETWORKNODES,
+              name='NetworkNodes', parent=prnt, pos=wx.Point(0, 0),
+              size=wx.Size(0, 0), style=wx.NB_LEFT)
+        self.NetworkNodes.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
+              self.OnNodeSelectedChanged, id=ID_NETWORKEDITNETWORKNODES)
+    
+    def __init__(self, manager, frame, mode_solo):
+        self.NodeList = manager
+        NodeEditorTemplate.__init__(self, self.NodeList.GetManager(), frame, mode_solo)
+    
+    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 RefreshCurrentIndexList(self):
+        selected = self.NetworkNodes.GetSelection()
+        if selected == 0:
+            window = self.NetworkNodes.GetPage(selected)
+            window.RefreshIndexList()
+        else:
+            pass
+
+    def RefreshNetworkNodes(self):
+        if self.NetworkNodes.GetPageCount() > 0:
+            self.NetworkNodes.DeleteAllPages()
+        if self.NodeList:
+            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.NetworkNodes, self, self.NodeList, False)
+                new_editingpanel.SetIndex(idx)
+                self.NetworkNodes.AddPage(new_editingpanel, "")
+    
+    
+    
+    def OnNodeSelectedChanged(self, event):
+        if not self.Closing:
+            selected = event.GetSelection()
+            # At init selected = -1
+            if selected >= 0:
+                window = self.NetworkNodes.GetPage(selected)
+                self.NodeList.SetCurrentSelected(window.GetIndex())
+            wx.CallAfter(self.RefreshMainMenu)
+            wx.CallAfter(self.RefreshStatusBar)
+        event.Skip()
+
+#-------------------------------------------------------------------------------
+#                              Buffer Functions
+#-------------------------------------------------------------------------------
+
+    def RefreshBufferState(self):
+        if self.NodeList is not None:
+            nodeID = self.Manager.GetCurrentNodeID()
+            if nodeID != None:
+                nodename = "0x%2.2X %s"%(nodeID, self.Manager.GetCurrentNodeName())
+            else:
+                nodename = self.Manager.GetCurrentNodeName()
+            self.NetworkNodes.SetPageText(0, nodename)
+            for idx, name in enumerate(self.NodeList.GetSlaveNames()):
+                self.NetworkNodes.SetPageText(idx + 1, name)
+
+#-------------------------------------------------------------------------------
+#                             Slave Nodes Management
+#-------------------------------------------------------------------------------
+
+    def OnAddSlaveMenu(self, event):
+        dialog = AddSlaveDialog(self.Frame)
+        dialog.SetNodeList(self.NodeList)
+        if dialog.ShowModal() == wx.ID_OK:
+            values = dialog.GetValues()
+            result = self.NodeList.AddSlaveNode(values["slaveName"], values["slaveNodeID"], values["edsFile"])
+            if not result:
+                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, "")
+                self.NodeList.SetCurrentSelected(idx)
+                self.NetworkNodes.SetSelection(idx)
+                self.RefreshBufferState()
+            else:
+                self.ShowErrorMessage(result)
+        dialog.Destroy()
+        
+    def OnRemoveSlaveMenu(self, event):
+        slavenames = self.NodeList.GetSlaveNames()
+        slaveids = self.NodeList.GetSlaveIDs()
+        dialog = wx.SingleChoiceDialog(self.Frame, _("Choose a slave to remove"), _("Remove slave"), slavenames)
+        if dialog.ShowModal() == wx.ID_OK:
+            choice = dialog.GetSelection()
+            result = self.NodeList.RemoveSlaveNode(slaveids[choice])
+            if not result:
+                slaveids.pop(choice)
+                current = self.NetworkNodes.GetSelection()
+                self.NetworkNodes.DeletePage(choice + 1)
+                if self.NetworkNodes.GetPageCount() > 0:
+                    new_selection = min(current, self.NetworkNodes.GetPageCount() - 1)
+                    self.NetworkNodes.SetSelection(new_selection)
+                    if new_selection > 0:
+                        self.NodeList.SetCurrentSelected(slaveids[new_selection - 1])
+                    self.RefreshBufferState()
+            else:
+                self.ShowErrorMessage(result)
+        dialog.Destroy()
+
+    def OpenMasterDCFDialog(self, node_id):
+        self.NetworkNodes.SetSelection(0)
+        self.NetworkNodes.GetPage(0).OpenDCFDialog(node_id)
+
 
 [ID_NETWORKEDIT, ID_NETWORKEDITNETWORKNODES, 
  ID_NETWORKEDITHELPBAR,
@@ -176,7 +297,10 @@
  ID_NETWORKEDITADDMENUMAPVARIABLE, ID_NETWORKEDITADDMENUUSERTYPE, 
 ] = [wx.NewId() for _init_coll_AddMenu_Items in range(6)]
 
-class networkedit(wx.Frame):
+class networkedit(wx.Frame, NetworkEditorTemplate):
+    
+    EDITMENU_ID = ID_NETWORKEDITEDITMENUOTHERPROFILE
+    
     def _init_coll_MenuBar_Menus(self, parent):
         if self.ModeSolo:
             parent.Append(menu=self.FileMenu, title=_('File'))
@@ -325,11 +449,7 @@
             accel = wx.AcceleratorTable([wx.AcceleratorEntry(wx.ACCEL_CTRL, 83, wx.ID_SAVE)])
             self.SetAcceleratorTable(accel)
 
-        self.NetworkNodes = wx.Notebook(id=ID_NETWORKEDITNETWORKNODES,
-              name='NetworkNodes', parent=self, pos=wx.Point(0, 0),
-              size=wx.Size(0, 0), style=wx.NB_LEFT)
-        self.NetworkNodes.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
-              self.OnNodeSelectedChanged, id=ID_NETWORKEDITNETWORKNODES)
+        NetworkEditorTemplate._init_ctrls(self, self)
 
         self.HelpBar = wx.StatusBar(id=ID_NETWORKEDITHELPBAR, name='HelpBar',
               parent=self, style=wx.ST_SIZEGRIP)
@@ -337,54 +457,35 @@
         self.SetStatusBar(self.HelpBar)
 
     def __init__(self, parent, nodelist = None, projectOpen = None):
-        self.ModeSolo = nodelist == None
+        if nodelist is None:
+            NetworkEditorTemplate.__init__(self, NodeList(NodeManager()), self, True)
+        else:
+            NetworkEditorTemplate.__init__(self, nodelist, self, False)
         self._init_ctrls(parent)
         self.HtmlFrameOpened = []
-        self.BusId = None
-        self.Closing = False
         
         icon = wx.Icon(os.path.join(ScriptDirectory,"networkedit.ico"),wx.BITMAP_TYPE_ICO)
         self.SetIcon(icon)
                  
         if self.ModeSolo:
-            self.Manager = NodeManager()
             if projectOpen:
-                self.NodeList = NodeList(self.Manager)
                 result = self.NodeList.LoadProject(projectOpen)
                 if not result:
+                    self.NodeList.SetCurrentSelected(0)
                     self.RefreshNetworkNodes()
+                    self.RefreshProfileMenu()
             else:
                 self.NodeList = None
         else:
-            self.NodeList = nodelist
-            self.Manager = self.NodeList.GetManager()
             self.NodeList.SetCurrentSelected(0)
             self.RefreshNetworkNodes()
             self.RefreshProfileMenu()
-            self.NetworkNodes.SetFocus()
+        self.NetworkNodes.SetFocus()
         
         self.RefreshBufferState()
         self.RefreshTitle()
         self.RefreshMainMenu()
 
-    def SetBusId(self, bus_id):
-        self.BusId = bus_id
-
-    def GetBusId(self):
-        return self.BusId
-
-    def IsClosing(self):
-        return self.Closing
-
-    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):
         self.Closing = True
         if not self.ModeSolo and getattr(self, "_onclose", None) != None:
@@ -398,43 +499,6 @@
 
     def OnQuitMenu(self, event):
         self.Close()
-        
-    def OnAddSDOServerMenu(self, event):
-        self.Manager.AddSDOServerToCurrent()
-        self.RefreshBufferState()
-        self.RefreshCurrentIndexList()
-        
-    def OnAddSDOClientMenu(self, event):
-        self.Manager.AddSDOClientToCurrent()
-        self.RefreshBufferState()
-        self.RefreshCurrentIndexList()
-        
-    def OnAddPDOTransmitMenu(self, event):
-        self.Manager.AddPDOTransmitToCurrent()
-        self.RefreshBufferState()
-        self.RefreshCurrentIndexList()
-        
-    def OnAddPDOReceiveMenu(self, event):
-        self.Manager.AddPDOReceiveToCurrent()
-        self.RefreshBufferState()
-        self.RefreshCurrentIndexList()
-        
-    def OnAddMapVariableMenu(self, event):
-        self.AddMapVariable()
-        
-    def OnAddUserTypeMenu(self, event):
-        self.AddUserType()
-        
-    def OnNodeSelectedChanged(self, event):
-        if not self.Closing:
-            selected = event.GetSelection()
-            # At init selected = -1
-            if selected >= 0:
-                window = self.NetworkNodes.GetPage(selected)
-                self.NodeList.SetCurrentSelected(window.GetIndex())
-            wx.CallAfter(self.RefreshMainMenu)
-            wx.CallAfter(self.RefreshStatusBar)
-        event.Skip()
 
 #-------------------------------------------------------------------------------
 #                         Load and Save Funtions
@@ -526,51 +590,6 @@
                 self.RefreshTitle()
                 self.RefreshMainMenu()
         
-#-------------------------------------------------------------------------------
-#                             Slave Nodes Management
-#-------------------------------------------------------------------------------
-
-    def OnAddSlaveMenu(self, event):
-        dialog = AddSlaveDialog(self)
-        dialog.SetNodeList(self.NodeList)
-        if dialog.ShowModal() == wx.ID_OK:
-            values = dialog.GetValues()
-            result = self.NodeList.AddSlaveNode(values["slaveName"], values["slaveNodeID"], values["edsFile"])
-            if not result:
-                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, "")
-                self.NodeList.SetCurrentSelected(idx)
-                self.NetworkNodes.SetSelection(idx)
-                self.RefreshBufferState()
-            else:
-                message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR)
-                message.ShowModal()
-                message.Destroy()
-        dialog.Destroy()
-        
-    def OnRemoveSlaveMenu(self, event):
-        slavenames = self.NodeList.GetSlaveNames()
-        slaveids = self.NodeList.GetSlaveIDs()
-        dialog = wx.SingleChoiceDialog(self, _("Choose a slave to remove"), _("Remove slave"), slavenames)
-        if dialog.ShowModal() == wx.ID_OK:
-            choice = dialog.GetSelection()
-            result = self.NodeList.RemoveSlaveNode(slaveids[choice])
-            if not result:
-                slaveids.pop(choice)
-                current = self.NetworkNodes.GetSelection()
-                self.NetworkNodes.DeletePage(choice + 1)
-                if self.NetworkNodes.GetPageCount() > 0:
-                    new_selection = min(current, self.NetworkNodes.GetPageCount() - 1)
-                    self.NetworkNodes.SetSelection(new_selection)
-                    if new_selection > 0:
-                        self.NodeList.SetCurrentSelected(slaveids[new_selection - 1])
-                    self.RefreshBufferState()
-            else:
-                message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR)
-                message.ShowModal()
-                message.Destroy()
         
 #-------------------------------------------------------------------------------
 #                             Refresh Functions
@@ -578,65 +597,16 @@
 
     def RefreshTitle(self):
         if self.NodeList != None:
-            self.SetTitle(_("Networkedit - %s")%self.NodeList.GetNetworkName())
+            self.SetTitle(_("Networkedit - %s") % self.NodeList.GetNetworkName())
         else:
             self.SetTitle(_("Networkedit"))
-
-    def OnRefreshMenu(self, event):
-        self.RefreshCurrentIndexList()
-        
-    def RefreshCurrentIndexList(self):
-        selected = self.NetworkNodes.GetSelection()
-        if selected == 0:
-            window = self.NetworkNodes.GetPage(selected)
-            window.RefreshIndexList()
-        else:
-            pass
-
-    def RefreshNetworkNodes(self):
-        if self.NetworkNodes.GetPageCount() > 0:
-            self.NetworkNodes.DeleteAllPages()
-        if self.NodeList:
-            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.NetworkNodes, self, self.NodeList, False)
-                new_editingpanel.SetIndex(idx)
-                self.NetworkNodes.AddPage(new_editingpanel, "")
-
+    
     def RefreshStatusBar(self):
         selected = self.NetworkNodes.GetSelection()
         if self.HelpBar and selected >= 0:
             window = self.NetworkNodes.GetPage(selected)
-            selection = window.GetSelection()
-            if selection:
-                index, subIndex = selection
-                if self.NodeList.IsCurrentEntry(index):
-                    self.HelpBar.SetStatusText(_("Index: 0x%04X")%index, 0)
-                    self.HelpBar.SetStatusText(_("Subindex: 0x%02X")%subIndex, 1)
-                    entryinfos = self.NodeList.GetEntryInfos(index)
-                    name = entryinfos["name"]
-                    category = _("Optional")
-                    if entryinfos["need"]:
-                        category = _("Mandatory")
-                    struct = "VAR"
-                    number = ""
-                    if entryinfos["struct"] & OD_IdenticalIndexes:
-                        number = _(" possibly defined %d times")%entryinfos["nbmax"]
-                    if entryinfos["struct"] & OD_IdenticalSubindexes:
-                        struct = "REC"
-                    elif entryinfos["struct"] & OD_MultipleSubindexes:
-                        struct = "ARRAY"
-                    text = _("%s: %s entry of struct %s%s.")%(name,category,struct,number)
-                    self.HelpBar.SetStatusText(text, 2)
-                else:
-                    for i in xrange(3):
-                        self.HelpBar.SetStatusText("", i)
-            else:
-                for i in xrange(3):
-                    self.HelpBar.SetStatusText("", i)
-
+            self.SetStatusBarText(window.GetSelection(), self.NodeList)
+    
     def RefreshMainMenu(self):
         self.NetworkMenu.Enable(ID_NETWORKEDITNETWORKMENUBUILDMASTER, False)
         if self.NodeList == None:
@@ -672,59 +642,15 @@
                     self.MenuBar.EnableTop(1, False)      
                     self.MenuBar.EnableTop(2, False)
 
-    def RefreshProfileMenu(self):
-        profile = self.Manager.GetCurrentProfileName()
-        edititem = self.EditMenu.FindItemById(ID_NETWORKEDITEDITMENUOTHERPROFILE)
-        if edititem:
-            length = self.AddMenu.GetMenuItemCount()
-            for i in xrange(length-6):
-                additem = self.AddMenu.FindItemByPosition(6)
-                self.AddMenu.Delete(additem.GetId())
-            if profile not in ("None", "DS-301"):
-                edititem.SetText(_("%s Profile")%profile)
-                edititem.Enable(True)
-                self.AddMenu.AppendSeparator()
-                for text, indexes in self.Manager.GetCurrentSpecificMenu():
-                    new_id = wx.NewId()
-                    self.AddMenu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=text)
-                    self.Bind(wx.EVT_MENU, self.GetProfileCallBack(text), id=new_id)
-            else:
-                edititem.SetText(_("Other Profile"))
-                edititem.Enable(False)
-
-    def GetProfileCallBack(self, text):
-        def ProfileCallBack(event):
-            self.Manager.AddSpecificEntryToCurrent(text)
-            self.RefreshBufferState()
-            self.RefreshCurrentIndexList()
-        return ProfileCallBack
-
 #-------------------------------------------------------------------------------
 #                              Buffer Functions
 #-------------------------------------------------------------------------------
 
     def RefreshBufferState(self):
+        NetworkEditorTemplate.RefreshBufferState(self)
         if self.NodeList is not None:
-            nodeID = self.Manager.GetCurrentNodeID()
-            if nodeID != None:
-                nodename = "0x%2.2X %s"%(nodeID, self.Manager.GetCurrentNodeName())
-            else:
-                nodename = self.Manager.GetCurrentNodeName()
-            self.NetworkNodes.SetPageText(0, nodename)
-            for idx, name in enumerate(self.NodeList.GetSlaveNames()):
-                self.NetworkNodes.SetPageText(idx + 1, name)
             self.RefreshTitle()
 
-    def OnUndoMenu(self, event):
-        self.Manager.LoadCurrentPrevious()
-        self.RefreshCurrentIndexList()
-        self.RefreshBufferState()
-
-    def OnRedoMenu(self, event):
-        self.Manager.LoadCurrentNext()
-        self.RefreshCurrentIndexList()
-        self.RefreshBufferState()
-
 #-------------------------------------------------------------------------------
 #                                Help Method
 #-------------------------------------------------------------------------------
@@ -773,110 +699,6 @@
             window.Show()
 
 #-------------------------------------------------------------------------------
-#                          Editing Profiles functions
-#-------------------------------------------------------------------------------
-
-    def OnCommunicationMenu(self, event):
-        dictionary,current = self.Manager.GetCurrentCommunicationLists()
-        self.EditProfile(_("Edit DS-301 Profile"), dictionary, current)
-    
-    def OnOtherCommunicationMenu(self, event):
-        dictionary,current = self.Manager.GetCurrentDS302Lists()
-        self.EditProfile(_("Edit DS-302 Profile"), dictionary, current)
-    
-    def OnEditProfileMenu(self, event):
-        title = _("Edit %s Profile")%self.Manager.GetCurrentProfileName()
-        dictionary,current = self.Manager.GetCurrentProfileLists()
-        self.EditProfile(title, dictionary, current)
-    
-    def EditProfile(self, title, dictionary, current):
-        dialog = CommunicationDialog(self)
-        dialog.SetTitle(title)
-        dialog.SetIndexDictionary(dictionary)
-        dialog.SetCurrentList(current)
-        dialog.RefreshLists()
-        if dialog.ShowModal() == wx.ID_OK:
-            new_profile = dialog.GetCurrentList()
-            addinglist = []
-            removinglist = []
-            for index in new_profile:
-                if index not in current:
-                    addinglist.append(index)
-            for index in current:
-                if index not in new_profile:
-                    removinglist.append(index)
-            self.Manager.ManageEntriesOfCurrent(addinglist, removinglist)
-            self.Manager.BufferCurrentNode()
-            self.RefreshBufferState()
-            self.RefreshCurrentIndexList()
-        dialog.Destroy()
-
-#-------------------------------------------------------------------------------
-#                         Edit Node informations function
-#-------------------------------------------------------------------------------
-
-    def OnNodeInfosMenu(self, event):
-        dialog = NodeInfosDialog(self)
-        name, id, type, description = self.Manager.GetCurrentNodeInfos()
-        defaultstringsize = self.Manager.GetCurrentNodeDefaultStringSize()
-        dialog.SetValues(name, id, type, description, defaultstringsize)
-        if dialog.ShowModal() == wx.ID_OK:
-            name, id, type, description, defaultstringsize = dialog.GetValues()
-            self.Manager.SetCurrentNodeInfos(name, id, type, description)
-            self.Manager.SetCurrentNodeDefaultStringSize(defaultstringsize)
-            self.RefreshBufferState()
-            self.RefreshProfileMenu()
-            selected = self.NetworkNodes.GetSelection()
-            if selected >= 0:
-                window = self.NetworkNodes.GetPage(selected)
-                window.RefreshTable()
-
-
-#-------------------------------------------------------------------------------
-#                           Add User Types and Variables
-#-------------------------------------------------------------------------------
-        
-    def AddMapVariable(self):
-        index = self.Manager.GetCurrentNextMapIndex()
-        if index:
-            dialog = MapVariableDialog(self)
-            dialog.SetIndex(index)
-            if dialog.ShowModal() == wx.ID_OK:
-                index, name, struct, number = dialog.GetValues()
-                result = self.Manager.AddMapVariableToCurrent(index, name, struct, number)
-                if not isinstance(result, (StringType, UnicodeType)):
-                    self.RefreshBufferState()
-                    self.RefreshCurrentIndexList()
-                else:
-                    message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR)
-                    message.ShowModal()
-                    message.Destroy()
-            dialog.Destroy()
-        else:
-            message = wx.MessageDialog(self, result, _("No map variable index left!"), wx.OK|wx.ICON_ERROR)
-            message.ShowModal()
-            message.Destroy()
-        
-    def AddUserType(self):
-        dialog = UserTypeDialog(self)
-        dialog.SetTypeList(self.Manager.GetCustomisableTypes())
-        if dialog.ShowModal() == wx.ID_OK:
-            type, min, max, length = dialog.GetValues()
-            result = self.Manager.AddUserTypeToCurrent(type, min, max, length)
-            if not IsOfType(result, StringType):
-                self.RefreshBufferState()
-                self.RefreshCurrentIndexList()
-            else:
-                message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR)
-                message.ShowModal()
-                message.Destroy()
-        dialog.Destroy()
-
-    def OpenMasterDCFDialog(self, node_id):
-        self.NetworkNodes.SetSelection(0)
-        self.NetworkNodes.GetPage(0).OpenDCFDialog(node_id)
-
-#-------------------------------------------------------------------------------
 #                               Exception Handler
 #-------------------------------------------------------------------------------
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/objdictgen/nodeeditor.py	Thu Feb 09 20:39:46 2012 +0100
@@ -0,0 +1,226 @@
+import wx
+
+from node import OD_Subindex, OD_MultipleSubindexes, OD_IdenticalSubindexes, OD_IdenticalIndexes
+from commondialogs import *
+
+class NodeEditorTemplate:
+    
+    EDITMENU_ID = None
+    
+    def __init__(self, manager, frame, mode_solo):
+        self.Manager = manager
+        self.Frame = frame
+        self.ModeSolo = mode_solo
+        
+        self.BusId = None
+        self.Closing = False
+    
+    def SetBusId(self, bus_id):
+        self.BusId = bus_id
+
+    def GetBusId(self):
+        return self.BusId
+
+    def IsClosing(self):
+        return self.Closing
+    
+    def OnAddSDOServerMenu(self, event):
+        self.Manager.AddSDOServerToCurrent()
+        self.RefreshBufferState()
+        self.RefreshCurrentIndexList()
+        
+    def OnAddSDOClientMenu(self, event):
+        self.Manager.AddSDOClientToCurrent()
+        self.RefreshBufferState()
+        self.RefreshCurrentIndexList()
+        
+    def OnAddPDOTransmitMenu(self, event):
+        self.Manager.AddPDOTransmitToCurrent()
+        self.RefreshBufferState()
+        self.RefreshCurrentIndexList()
+        
+    def OnAddPDOReceiveMenu(self, event):
+        self.Manager.AddPDOReceiveToCurrent()
+        self.RefreshBufferState()
+        self.RefreshCurrentIndexList()
+        
+    def OnAddMapVariableMenu(self, event):
+        self.AddMapVariable()
+        
+    def OnAddUserTypeMenu(self, event):
+        self.AddUserType()
+    
+    def OnRefreshMenu(self, event):
+        self.RefreshCurrentIndexList()
+        
+    def RefreshCurrentIndexList(self):
+        pass
+    
+    def RefreshStatusBar(self):
+        pass
+    
+    def SetStatusBarText(self, selection, manager):
+        if selection:
+            index, subIndex = selection
+            if manager.IsCurrentEntry(index):
+                self.Frame.HelpBar.SetStatusText(_("Index: 0x%04X")%index, 0)
+                self.Frame.HelpBar.SetStatusText(_("Subindex: 0x%02X")%subIndex, 1)
+                entryinfos = manager.GetEntryInfos(index)
+                name = entryinfos["name"]
+                category = _("Optional")
+                if entryinfos["need"]:
+                    category = _("Mandatory")
+                struct = "VAR"
+                number = ""
+                if entryinfos["struct"] & OD_IdenticalIndexes:
+                    number = _(" possibly defined %d times")%entryinfos["nbmax"]
+                if entryinfos["struct"] & OD_IdenticalSubindexes:
+                    struct = "REC"
+                elif entryinfos["struct"] & OD_MultipleSubindexes:
+                    struct = "ARRAY"
+                text = _("%s: %s entry of struct %s%s.")%(name,category,struct,number)
+                self.Frame.HelpBar.SetStatusText(text, 2)
+            else:
+                for i in xrange(3):
+                    self.Frame.HelpBar.SetStatusText("", i)
+        else:
+            for i in xrange(3):
+                self.Frame.HelpBar.SetStatusText("", i)
+    
+    def RefreshProfileMenu(self):
+        if self.EDITMENU_ID is not None:
+            profile = self.Manager.GetCurrentProfileName()
+            edititem = self.Frame.EditMenu.FindItemById(self.EDITMENU_ID)
+            if edititem:
+                length = self.Frame.AddMenu.GetMenuItemCount()
+                for i in xrange(length-6):
+                    additem = self.Frame.AddMenu.FindItemByPosition(6)
+                    self.Frame.AddMenu.Delete(additem.GetId())
+                if profile not in ("None", "DS-301"):
+                    edititem.SetText(_("%s Profile")%profile)
+                    edititem.Enable(True)
+                    self.Frame.AddMenu.AppendSeparator()
+                    for text, indexes in self.Manager.GetCurrentSpecificMenu():
+                        new_id = wx.NewId()
+                        self.Frame.AddMenu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=text)
+                        self.Frame.Bind(wx.EVT_MENU, self.GetProfileCallBack(text), id=new_id)
+                else:
+                    edititem.SetText(_("Other Profile"))
+                    edititem.Enable(False)
+        
+#-------------------------------------------------------------------------------
+#                            Buffer Functions
+#-------------------------------------------------------------------------------
+
+    def RefreshBufferState(self):
+        pass
+
+    def OnUndoMenu(self, event):
+        self.Manager.LoadCurrentPrevious()
+        self.RefreshCurrentIndexList()
+        self.RefreshBufferState()
+        
+    def OnRedoMenu(self, event):
+        self.Manager.LoadCurrentNext()
+        self.RefreshCurrentIndexList()
+        self.RefreshBufferState()
+
+#-------------------------------------------------------------------------------
+#                          Editing Profiles functions
+#-------------------------------------------------------------------------------
+
+    def OnCommunicationMenu(self, event):
+        dictionary,current = self.Manager.GetCurrentCommunicationLists()
+        self.EditProfile(_("Edit DS-301 Profile"), dictionary, current)
+    
+    def OnOtherCommunicationMenu(self, event):
+        dictionary,current = self.Manager.GetCurrentDS302Lists()
+        self.EditProfile(_("Edit DS-302 Profile"), dictionary, current)
+    
+    def OnEditProfileMenu(self, event):
+        title = _("Edit %s Profile") % self.Manager.GetCurrentProfileName()
+        dictionary,current = self.Manager.GetCurrentProfileLists()
+        self.EditProfile(title, dictionary, current)
+    
+    def EditProfile(self, title, dictionary, current):
+        dialog = CommunicationDialog(self.Frame)
+        dialog.SetTitle(title)
+        dialog.SetIndexDictionary(dictionary)
+        dialog.SetCurrentList(current)
+        dialog.RefreshLists()
+        if dialog.ShowModal() == wx.ID_OK:
+            new_profile = dialog.GetCurrentList()
+            addinglist = []
+            removinglist = []
+            for index in new_profile:
+                if index not in current:
+                    addinglist.append(index)
+            for index in current:
+                if index not in new_profile:
+                    removinglist.append(index)
+            self.Manager.ManageEntriesOfCurrent(addinglist, removinglist)
+            self.Manager.BufferCurrentNode()
+            self.RefreshBufferState()
+            
+        dialog.Destroy()
+
+    def GetProfileCallBack(self, text):
+        def ProfileCallBack(event):
+            self.Manager.AddSpecificEntryToCurrent(text)
+            self.RefreshBufferState()
+            self.RefreshCurrentIndexList()
+        return ProfileCallBack
+
+#-------------------------------------------------------------------------------
+#                         Edit Node informations function
+#-------------------------------------------------------------------------------
+
+    def OnNodeInfosMenu(self, event):
+        dialog = NodeInfosDialog(self.Frame)
+        name, id, type, description = self.Manager.GetCurrentNodeInfos()
+        defaultstringsize = self.Manager.GetCurrentNodeDefaultStringSize()
+        dialog.SetValues(name, id, type, description, defaultstringsize)
+        if dialog.ShowModal() == wx.ID_OK:
+            name, id, type, description, defaultstringsize = dialog.GetValues()
+            self.Manager.SetCurrentNodeInfos(name, id, type, description)
+            self.Manager.SetCurrentNodeDefaultStringSize(defaultstringsize)
+            self.RefreshBufferState()
+            self.RefreshCurrentIndexList()
+            self.RefreshProfileMenu()
+
+#-------------------------------------------------------------------------------
+#                           Add User Types and Variables
+#-------------------------------------------------------------------------------
+        
+    def AddMapVariable(self):
+        index = self.Manager.GetCurrentNextMapIndex()
+        if index:
+            dialog = MapVariableDialog(self.Frame)
+            dialog.SetIndex(index)
+            if dialog.ShowModal() == wx.ID_OK:
+                result = self.Manager.AddMapVariableToCurrent(*dialog.GetValues())
+                if not isinstance(result, (StringType, UnicodeType)):
+                    self.RefreshBufferState()
+                    self.RefreshCurrentIndexList()
+                else:
+                    self.ShowErrorMessage(result)
+            dialog.Destroy()
+        else:
+            self.ShowErrorMessage(_("No map variable index left!"))
+        
+    def AddUserType(self):
+        dialog = UserTypeDialog(self)
+        dialog.SetTypeList(self.Manager.GetCustomisableTypes())
+        if dialog.ShowModal() == wx.ID_OK:
+            result = self.Manager.AddUserTypeToCurrent(*dialog.GetValues())
+            if not isinstance(result, (StringType, UnicodeType)):
+                self.RefreshBufferState()
+                self.RefreshCurrentIndexList()
+            else:
+                self.ShowErrorMessage(result)
+        dialog.Destroy()
+
+    def ShowErrorMessage(self, message):
+        message = wx.MessageDialog(self.Frame, message, _("Error"), wx.OK|wx.ICON_ERROR)
+        message.ShowModal()
+        message.Destroy()
--- a/objdictgen/objdictedit.py	Sat Feb 04 17:08:48 2012 +0100
+++ b/objdictgen/objdictedit.py	Thu Feb 09 20:39:46 2012 +0100
@@ -73,9 +73,8 @@
 if __name__ == '__main__':
     __builtin__.__dict__['_'] = wx.GetTranslation
 
-from node import OD_Subindex, OD_MultipleSubindexes, OD_IdenticalSubindexes, OD_IdenticalIndexes
-
 from nodemanager import *
+from nodeeditor import NodeEditorTemplate
 from subindextable import *
 from commondialogs import *
 from doc_index.DS301_index import *
@@ -167,7 +166,10 @@
  ID_OBJDICTEDITADDMENUMAPVARIABLE, ID_OBJDICTEDITADDMENUUSERTYPE, 
 ] = [wx.NewId() for _init_coll_AddMenu_Items in range(6)]
 
-class objdictedit(wx.Frame):
+class objdictedit(wx.Frame, NodeEditorTemplate):
+    
+    EDITMENU_ID = ID_OBJDICTEDITEDITMENUOTHERPROFILE
+    
     def _init_coll_MenuBar_Menus(self, parent):
         if self.ModeSolo:
             parent.Append(menu=self.FileMenu, title=_('File'))
@@ -328,17 +330,17 @@
         self.SetStatusBar(self.HelpBar)
 
     def __init__(self, parent, manager = None, filesOpen = []):
-        self.ModeSolo = manager == None
+        if manager is None:
+            NodeEditorTemplate.__init__(self, NodeManager(), self, True)
+        else:
+            NodeEditorTemplate.__init__(self, manager, self, False)
         self._init_ctrls(parent)
         self.HtmlFrameOpened = []
-        self.BusId = None
-        self.Closing = False
         
         icon = wx.Icon(os.path.join(ScriptDirectory,"networkedit.ico"),wx.BITMAP_TYPE_ICO)
         self.SetIcon(icon)
         
         if self.ModeSolo:
-            self.Manager = NodeManager()
             for filepath in filesOpen:
                 result = self.Manager.OpenFileInCurrent(os.path.abspath(filepath))
                 if isinstance(result, (IntType, LongType)):
@@ -346,7 +348,6 @@
                     new_editingpanel.SetIndex(result)
                     self.FileOpened.AddPage(new_editingpanel, "")
         else:
-            self.Manager = manager
             for index in self.Manager.GetBufferIndexes():
                 new_editingpanel = EditingPanel(self.FileOpened, self, self.Manager)
                 new_editingpanel.SetIndex(index)
@@ -368,41 +369,6 @@
         self.RefreshTitle()
         self.RefreshMainMenu()
 
-    def SetBusId(self, bus_id):
-        self.BusId = bus_id
-
-    def GetBusId(self):
-        return self.BusId
-
-    def IsClosing(self):
-        return self.Closing
-
-    def OnAddSDOServerMenu(self, event):
-        self.Manager.AddSDOServerToCurrent()
-        self.RefreshBufferState()
-        self.RefreshCurrentIndexList()
-        
-    def OnAddSDOClientMenu(self, event):
-        self.Manager.AddSDOClientToCurrent()
-        self.RefreshBufferState()
-        self.RefreshCurrentIndexList()
-        
-    def OnAddPDOTransmitMenu(self, event):
-        self.Manager.AddPDOTransmitToCurrent()
-        self.RefreshBufferState()
-        self.RefreshCurrentIndexList()
-        
-    def OnAddPDOReceiveMenu(self, event):
-        self.Manager.AddPDOReceiveToCurrent()
-        self.RefreshBufferState()
-        self.RefreshCurrentIndexList()
-        
-    def OnAddMapVariableMenu(self, event):
-        self.AddMapVariable()
-        
-    def OnAddUserTypeMenu(self, event):
-        self.AddUserType()
-        
     def OnFileSelectedChanged(self, event):
         if not self.Closing:
             selected = event.GetSelection()
@@ -506,9 +472,6 @@
         else:
             self.SetTitle(_("Objdictedit"))
 
-    def OnRefreshMenu(self, event):
-        self.RefreshCurrentIndexList()
-        
     def RefreshCurrentIndexList(self):
         selected = self.FileOpened.GetSelection()
         window = self.FileOpened.GetPage(selected)
@@ -518,33 +481,7 @@
         selected = self.FileOpened.GetSelection()
         if selected >= 0:
             window = self.FileOpened.GetPage(selected)
-            selection = window.GetSelection()
-            if selection:
-                index, subIndex = selection
-                if self.Manager.IsCurrentEntry(index):
-                    self.HelpBar.SetStatusText(_("Index: 0x%04X")%index, 0)
-                    self.HelpBar.SetStatusText(_("Subindex: 0x%02X")%subIndex, 1)
-                    entryinfos = self.Manager.GetEntryInfos(index)
-                    name = entryinfos["name"]
-                    category = _("Optional")
-                    if entryinfos["need"]:
-                        category = _("Mandatory")
-                    struct = "VAR"
-                    number = ""
-                    if entryinfos["struct"] & OD_IdenticalIndexes:
-                        number = _(" possibly defined %d times")%entryinfos["nbmax"]
-                    if entryinfos["struct"] & OD_IdenticalSubindexes:
-                        struct = "REC"
-                    elif entryinfos["struct"] & OD_MultipleSubindexes:
-                        struct = "ARRAY"
-                    text = _("%s: %s entry of struct %s%s.")%(name,category,struct,number)
-                    self.HelpBar.SetStatusText(text, 2)
-                else:
-                    for i in xrange(3):
-                        self.HelpBar.SetStatusText("", i)
-            else:
-                for i in xrange(3):
-                    self.HelpBar.SetStatusText("", i)
+            self.SetStatusBarText(window.GetSelection(), self.Manager)
 
     def RefreshMainMenu(self):
         if self.FileOpened.GetPageCount() > 0:
@@ -581,27 +518,6 @@
             self.EditMenu.Enable(wx.ID_UNDO, False)
             self.EditMenu.Enable(wx.ID_REDO, False)
 
-    def RefreshProfileMenu(self):
-        profile = self.Manager.GetCurrentProfileName()
-        edititem = self.EditMenu.FindItemById(ID_OBJDICTEDITEDITMENUOTHERPROFILE)
-        if edititem:
-            length = self.AddMenu.GetMenuItemCount()
-            for i in xrange(length-6):
-                additem = self.AddMenu.FindItemByPosition(6)
-                self.AddMenu.Delete(additem.GetId())
-            if profile not in ("None", "DS-301"):
-                edititem.SetText(_("%s Profile")%profile)
-                edititem.Enable(True)
-                self.AddMenu.AppendSeparator()
-                for text, indexes in self.Manager.GetCurrentSpecificMenu():
-                    new_id = wx.NewId()
-                    self.AddMenu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=text)
-                    self.Bind(wx.EVT_MENU, self.GetProfileCallBack(text), id=new_id)
-            else:
-                edititem.SetText(_("Other Profile"))
-                edititem.Enable(False)
-        
-
 #-------------------------------------------------------------------------------
 #                            Buffer Functions
 #-------------------------------------------------------------------------------
@@ -613,17 +529,6 @@
         self.RefreshEditMenu()
         self.RefreshTitle()
 
-    def OnUndoMenu(self, event):
-        self.Manager.LoadCurrentPrevious()
-        self.RefreshCurrentIndexList()
-        self.RefreshBufferState()
-        
-    def OnRedoMenu(self, event):
-        self.Manager.LoadCurrentNext()
-        self.RefreshCurrentIndexList()
-        self.RefreshBufferState()
-        
-
 #-------------------------------------------------------------------------------
 #                         Load and Save Funtions
 #-------------------------------------------------------------------------------
@@ -828,113 +733,6 @@
                 message.Destroy()
         dialog.Destroy()
 
-#-------------------------------------------------------------------------------
-#                          Editing Profiles functions
-#-------------------------------------------------------------------------------
-
-    def OnCommunicationMenu(self, event):
-        dictionary,current = self.Manager.GetCurrentCommunicationLists()
-        self.EditProfile(_("Edit DS-301 Profile"), dictionary, current)
-    
-    def OnOtherCommunicationMenu(self, event):
-        dictionary,current = self.Manager.GetCurrentDS302Lists()
-        self.EditProfile(_("Edit DS-302 Profile"), dictionary, current)
-    
-    def OnEditProfileMenu(self, event):
-        title = _("Edit %s Profile")%self.Manager.GetCurrentProfileName()
-        dictionary,current = self.Manager.GetCurrentProfileLists()
-        self.EditProfile(title, dictionary, current)
-    
-    def EditProfile(self, title, dictionary, current):
-        dialog = CommunicationDialog(self)
-        dialog.SetTitle(title)
-        dialog.SetIndexDictionary(dictionary)
-        dialog.SetCurrentList(current)
-        dialog.RefreshLists()
-        if dialog.ShowModal() == wx.ID_OK:
-            new_profile = dialog.GetCurrentList()
-            addinglist = []
-            removinglist = []
-            for index in new_profile:
-                if index not in current:
-                    addinglist.append(index)
-            for index in current:
-                if index not in new_profile:
-                    removinglist.append(index)
-            self.Manager.ManageEntriesOfCurrent(addinglist, removinglist)
-            self.Manager.BufferCurrentNode()
-            self.RefreshBufferState()
-            self.RefreshCurrentIndexList()
-        dialog.Destroy()
-
-    def GetProfileCallBack(self, text):
-        def ProfileCallBack(event):
-            self.Manager.AddSpecificEntryToCurrent(text)
-            self.RefreshBufferState()
-            self.RefreshCurrentIndexList()
-        return ProfileCallBack
-
-#-------------------------------------------------------------------------------
-#                         Edit Node informations function
-#-------------------------------------------------------------------------------
-
-    def OnNodeInfosMenu(self, event):
-        dialog = NodeInfosDialog(self)
-        name, id, type, description = self.Manager.GetCurrentNodeInfos()
-        defaultstringsize = self.Manager.GetCurrentNodeDefaultStringSize()
-        dialog.SetValues(name, id, type, description, defaultstringsize)
-        if dialog.ShowModal() == wx.ID_OK:
-            name, id, type, description, defaultstringsize = dialog.GetValues()
-            self.Manager.SetCurrentNodeInfos(name, id, type, description)
-            self.Manager.SetCurrentNodeDefaultStringSize(defaultstringsize)
-            self.RefreshBufferState()
-            self.RefreshProfileMenu()
-            selected = self.FileOpened.GetSelection()
-            if selected >= 0:
-                window = self.FileOpened.GetPage(selected)
-                window.RefreshTable()
-
-
-#-------------------------------------------------------------------------------
-#                           Add User Types and Variables
-#-------------------------------------------------------------------------------
-        
-    def AddMapVariable(self):
-        index = self.Manager.GetCurrentNextMapIndex()
-        if index:
-            dialog = MapVariableDialog(self)
-            dialog.SetIndex(index)
-            if dialog.ShowModal() == wx.ID_OK:
-                index, name, struct, number = dialog.GetValues()
-                result = self.Manager.AddMapVariableToCurrent(index, name, struct, number)
-                if not isinstance(result, (StringType, UnicodeType)):
-                    self.RefreshBufferState()
-                    self.RefreshCurrentIndexList()
-                else:
-                    message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR)
-                    message.ShowModal()
-                    message.Destroy()
-            dialog.Destroy()
-        else:
-            message = wx.MessageDialog(self, result, _("No map variable index left!"), wx.OK|wx.ICON_ERROR)
-            message.ShowModal()
-            message.Destroy()
-        
-    def AddUserType(self):
-        dialog = UserTypeDialog(self)
-        dialog.SetTypeList(self.Manager.GetCustomisableTypes())
-        if dialog.ShowModal() == wx.ID_OK:
-            type, min, max, length = dialog.GetValues()
-            result = self.Manager.AddUserTypeToCurrent(type, min, max, length)
-            if not result:
-                self.RefreshBufferState()
-                self.RefreshCurrentIndexList()
-            else:
-                message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR)
-                message.ShowModal()
-                message.Destroy()
-        dialog.Destroy()
-    
 
 #-------------------------------------------------------------------------------
 #                               Exception Handler