etherlab/ConfigEditor.py
changeset 2041 ce3727171207
parent 2040 d676082c1d2f
child 2043 27d4cb689a79
equal deleted inserted replaced
2040:d676082c1d2f 2041:ce3727171207
     1 import wx
     1 import wx
     2 import wx.grid
     2 import wx.grid
     3 import wx.gizmos
     3 import wx.gizmos
     4 
     4 
     5 from controls import CustomGrid, CustomTable, EditorPanel
     5 from controls import CustomGrid, CustomTable, EditorPanel
     6 
       
     7 SCAN_COMMAND = """
       
     8 import commands
       
     9 result = commands.getoutput("ethercat slaves")
       
    10 slaves = []
       
    11 for slave_line in result.splitlines():
       
    12     chunks = slave_line.split()
       
    13     idx, pos, state, flag = chunks[:4]
       
    14     name = " ".join(chunks[4:])
       
    15     alias, position = pos.split(":")
       
    16     slave = {"idx": int(idx),
       
    17              "alias": int(alias),
       
    18              "position": int(position),
       
    19              "name": name}
       
    20     details = commands.getoutput("ethercat slaves -p %d -v" % slave["idx"])
       
    21     for details_line in details.splitlines():
       
    22         details_line = details_line.strip()
       
    23         for header, param in [("Vendor Id:", "vendor_id"),
       
    24                               ("Product code:", "product_code"),
       
    25                               ("Revision number:", "revision_number")]:
       
    26             if details_line.startswith(header):
       
    27                 slave[param] = int(details_line.split()[-1], 16)
       
    28                 break
       
    29     slaves.append(slave)
       
    30 returnVal = slaves
       
    31 """
       
    32 
     6 
    33 [ETHERCAT_VENDOR, ETHERCAT_GROUP, ETHERCAT_DEVICE] = range(3)
     7 [ETHERCAT_VENDOR, ETHERCAT_GROUP, ETHERCAT_DEVICE] = range(3)
    34 
     8 
    35 def AppendMenu(parent, help, id, kind, text):
     9 def AppendMenu(parent, help, id, kind, text):
    36     if wx.VERSION >= (2, 6, 0):
    10     if wx.VERSION >= (2, 6, 0):
    37         parent.Append(help=help, id=id, kind=kind, text=text)
    11         parent.Append(help=help, id=id, kind=kind, text=text)
    38     else:
    12     else:
    39         parent.Append(helpString=help, id=id, kind=kind, item=text)
    13         parent.Append(helpString=help, id=id, kind=kind, item=text)
    40 
    14 
    41 [ID_SLAVETYPECHOICEDIALOG, ID_SLAVETYPECHOICEDIALOGSTATICTEXT1,
       
    42  ID_SLAVETYPECHOICEDIALOGSLAVETYPESLIBRARY
       
    43 ] = [wx.NewId() for _init_ctrls in range(3)]
       
    44 
       
    45 class SlaveTypeChoiceDialog(wx.Dialog):
       
    46     
       
    47     if wx.VERSION < (2, 6, 0):
       
    48         def Bind(self, event, function, id = None):
       
    49             if id is not None:
       
    50                 event(self, id, function)
       
    51             else:
       
    52                 event(self, function)
       
    53     
       
    54     def _init_coll_flexGridSizer1_Items(self, parent):
       
    55         parent.AddWindow(self.staticText1, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
    56         parent.AddWindow(self.SlaveTypesLibrary, 0, border=20, flag=wx.GROW|wx.LEFT|wx.RIGHT)
       
    57         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
    58     
       
    59     def _init_coll_flexGridSizer1_Growables(self, parent):
       
    60         parent.AddGrowableCol(0)
       
    61         parent.AddGrowableRow(1)
       
    62     
       
    63     def _init_sizers(self):
       
    64         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10)
       
    65         
       
    66         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
    67         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
    68         
       
    69         self.SetSizer(self.flexGridSizer1)
       
    70 
       
    71     def _init_ctrls(self, prnt):
       
    72         wx.Dialog.__init__(self, id=ID_SLAVETYPECHOICEDIALOG,
       
    73               name='SlaveTypeChoiceDialog', parent=prnt,
       
    74               size=wx.Size(600, 400), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER,
       
    75               title=_('Browse slave types library'))
       
    76         self.SetClientSize(wx.Size(600, 400))
       
    77 
       
    78         self.staticText1 = wx.StaticText(id=ID_SLAVETYPECHOICEDIALOGSTATICTEXT1,
       
    79               label=_('Choose a slave type:'), name='staticText1', parent=self,
       
    80               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
    81         
       
    82         self.SlaveTypesLibrary = wx.TreeCtrl(id=ID_SLAVETYPECHOICEDIALOGSLAVETYPESLIBRARY,
       
    83               name='TypeTree', parent=self, pos=wx.Point(0, 0),
       
    84               size=wx.Size(0, 0), style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER|wx.TR_HIDE_ROOT|wx.TR_LINES_AT_ROOT)
       
    85         
       
    86         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
    87         if wx.VERSION >= (2, 5, 0):
       
    88             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
    89         else:
       
    90             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
    91         
       
    92         self._init_sizers()
       
    93 
       
    94     def __init__(self, parent, controler, default=None):
       
    95         self._init_ctrls(parent)
       
    96         
       
    97         slaves_types = controler.GetSlaveTypesLibrary()
       
    98         
       
    99         root = self.SlaveTypesLibrary.AddRoot("")
       
   100         self.GenerateSlaveTypesLibraryTreeBranch(root, slaves_types, default)
       
   101 
       
   102     def GenerateSlaveTypesLibraryTreeBranch(self, root, children, default):
       
   103         for infos in children:
       
   104             item = self.SlaveTypesLibrary.AppendItem(root, infos["name"])
       
   105             if infos["type"] == ETHERCAT_DEVICE:
       
   106                 self.SlaveTypesLibrary.SetPyData(item, infos["infos"])
       
   107                 if infos["infos"] == default:
       
   108                     self.SlaveTypesLibrary.SelectItem(item)
       
   109                     self.SlaveTypesLibrary.EnsureVisible(item)
       
   110             else:
       
   111                 self.GenerateSlaveTypesLibraryTreeBranch(item, infos["children"], default)
       
   112 
       
   113     def GetType(self):
       
   114         selected = self.SlaveTypesLibrary.GetSelection()
       
   115         return self.SlaveTypesLibrary.GetPyData(selected)
       
   116 
       
   117     def OnOK(self, event):
       
   118         selected = self.SlaveTypesLibrary.GetSelection()
       
   119         if not selected.IsOk() or self.SlaveTypesLibrary.GetPyData(selected) is None:
       
   120             message = wx.MessageDialog(self, _("No valid slave type selected!"), _("Error"), wx.OK|wx.ICON_ERROR)
       
   121             message.ShowModal()
       
   122             message.Destroy()
       
   123         else:
       
   124             self.EndModal(wx.ID_OK)
       
   125 
       
   126 def GetSyncManagersTableColnames():
    15 def GetSyncManagersTableColnames():
   127     _ = lambda x : x
    16     _ = lambda x : x
   128     return ["#", _("Name"), _("Start Address"), _("Default Size"), _("Control Byte"), _("Enable")]
    17     return ["#", _("Name"), _("Start Address"), _("Default Size"), _("Control Byte"), _("Enable")]
   129 
    18 
   130 class SyncManagersTable(CustomTable):
    19 class SyncManagersTable(CustomTable):
   137 
    26 
   138 def GetVariablesTableColnames():
    27 def GetVariablesTableColnames():
   139     _ = lambda x : x
    28     _ = lambda x : x
   140     return ["#", _("Name"), _("Index"), _("SubIndex"), _("Type"), _("PDO index"), _("PDO name"), _("PDO type")]
    29     return ["#", _("Name"), _("Index"), _("SubIndex"), _("Type"), _("PDO index"), _("PDO name"), _("PDO type")]
   141 
    30 
   142 [ID_SLAVEINFOSPANEL, ID_SLAVEINFOSPANELVENDORLABEL, 
    31 [ID_NODEEDITOR, ID_NODEEDITORVENDORLABEL, 
   143  ID_SLAVEINFOSPANELVENDOR, ID_SLAVEINFOSPANELPRODUCTCODELABEL, 
    32  ID_NODEEDITORVENDOR, ID_NODEEDITORPRODUCTCODELABEL, 
   144  ID_SLAVEINFOSPANELPRODUCTCODE, ID_SLAVEINFOSPANELREVISIONNUMBERLABEL, 
    33  ID_NODEEDITORPRODUCTCODE, ID_NODEEDITORREVISIONNUMBERLABEL, 
   145  ID_SLAVEINFOSPANELREVISIONNUMBER, ID_SLAVEINFOSPANELPHYSICSLABEL, 
    34  ID_NODEEDITORREVISIONNUMBER, ID_NODEEDITORPHYSICSLABEL, 
   146  ID_SLAVEINFOSPANELPHYSICS, ID_SLAVEINFOSPANELSYNCMANAGERSLABEL, 
    35  ID_NODEEDITORPHYSICS, ID_NODEEDITORSYNCMANAGERSLABEL, 
   147  ID_SLAVEINFOSPANELSYNCMANAGERSGRID, ID_SLAVEINFOSPANELVARIABLESLABEL, 
    36  ID_NODEEDITORSYNCMANAGERSGRID, ID_NODEEDITORVARIABLESLABEL, 
   148  ID_SLAVEINFOSPANELVARIABLESGRID, 
    37  ID_NODEEDITORVARIABLESGRID, 
   149 ] = [wx.NewId() for _init_ctrls in range(13)]
    38 ] = [wx.NewId() for _init_ctrls in range(13)]
   150 
    39 
   151 class SlaveInfosPanel(wx.Panel):
    40 class NodeEditor(EditorPanel):
   152     
    41     
   153     if wx.VERSION < (2, 6, 0):
    42     ID = ID_NODEEDITOR
   154         def Bind(self, event, function, id = None):
       
   155             if id is not None:
       
   156                 event(self, id, function)
       
   157             else:
       
   158                 event(self, function)
       
   159     
    43     
   160     def _init_coll_MainSizer_Items(self, parent):
    44     def _init_coll_MainSizer_Items(self, parent):
   161         parent.AddSizer(self.SlaveInfosDetailsSizer, 0, border=5, flag=wx.TOP|wx.LEFT|wx.RIGHT|wx.GROW)
    45         parent.AddSizer(self.SlaveInfosDetailsSizer, 0, border=5, flag=wx.TOP|wx.LEFT|wx.RIGHT|wx.GROW)
   162         parent.AddWindow(self.SyncManagersLabel, 0, border=5, flag=wx.LEFT|wx.RIGHT|wx.GROW)
    46         parent.AddWindow(self.SyncManagersLabel, 0, border=5, flag=wx.LEFT|wx.RIGHT|wx.GROW)
   163         parent.AddWindow(self.SyncManagersGrid, 0, border=5, flag=wx.LEFT|wx.RIGHT|wx.GROW)
    47         parent.AddWindow(self.SyncManagersGrid, 0, border=5, flag=wx.LEFT|wx.RIGHT|wx.GROW)
   190         self._init_coll_MainSizer_Growables(self.MainSizer)
    74         self._init_coll_MainSizer_Growables(self.MainSizer)
   191         self._init_coll_MainSizer_Items(self.MainSizer)
    75         self._init_coll_MainSizer_Items(self.MainSizer)
   192         self._init_coll_SlaveInfosDetailsSizer_Growables(self.SlaveInfosDetailsSizer)
    76         self._init_coll_SlaveInfosDetailsSizer_Growables(self.SlaveInfosDetailsSizer)
   193         self._init_coll_SlaveInfosDetailsSizer_Items(self.SlaveInfosDetailsSizer)
    77         self._init_coll_SlaveInfosDetailsSizer_Items(self.SlaveInfosDetailsSizer)
   194         
    78         
   195         self.SetSizer(self.MainSizer)
    79         self.Editor.SetSizer(self.MainSizer)
   196 
    80 
   197     def _init_ctrls(self, prnt):
    81     def _init_Editor(self, prnt):
   198         wx.Panel.__init__(self, id=ID_SLAVEINFOSPANEL, name='SlavePanel', parent=prnt,
    82         self.Editor = wx.Panel(id=-1, name='SlavePanel', parent=prnt,
   199               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
    83               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
   200         
    84         
   201         self.VendorLabel = wx.StaticText(id=ID_SLAVEINFOSPANELVENDORLABEL,
    85         self.VendorLabel = wx.StaticText(id=ID_NODEEDITORVENDORLABEL,
   202               label=_('Vendor:'), name='VendorLabel', parent=self,
    86               label=_('Vendor:'), name='VendorLabel', parent=self.Editor,
   203               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
    87               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
   204         
    88         
   205         self.Vendor = wx.TextCtrl(id=ID_SLAVEINFOSPANELVENDOR, value='',
    89         self.Vendor = wx.TextCtrl(id=ID_NODEEDITORVENDOR, value='',
   206               name='Vendor', parent=self, pos=wx.Point(0, 0),
    90               name='Vendor', parent=self.Editor, pos=wx.Point(0, 0),
   207               size=wx.Size(0, 24), style=wx.TE_READONLY)
    91               size=wx.Size(0, 24), style=wx.TE_READONLY)
   208         
    92         
   209         self.ProductCodeLabel = wx.StaticText(id=ID_SLAVEINFOSPANELPRODUCTCODELABEL,
    93         self.ProductCodeLabel = wx.StaticText(id=ID_NODEEDITORPRODUCTCODELABEL,
   210               label=_('Product code:'), name='ProductCodeLabel', parent=self,
    94               label=_('Product code:'), name='ProductCodeLabel', parent=self.Editor,
   211               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
    95               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
   212         
    96         
   213         self.ProductCode = wx.TextCtrl(id=ID_SLAVEINFOSPANELPRODUCTCODE, value='',
    97         self.ProductCode = wx.TextCtrl(id=ID_NODEEDITORPRODUCTCODE, value='',
   214               name='ProductCode', parent=self, pos=wx.Point(0, 0),
    98               name='ProductCode', parent=self.Editor, pos=wx.Point(0, 0),
   215               size=wx.Size(0, 24), style=wx.TE_READONLY)
    99               size=wx.Size(0, 24), style=wx.TE_READONLY)
   216         
   100         
   217         self.RevisionNumberLabel = wx.StaticText(id=ID_SLAVEINFOSPANELREVISIONNUMBERLABEL,
   101         self.RevisionNumberLabel = wx.StaticText(id=ID_NODEEDITORREVISIONNUMBERLABEL,
   218               label=_('Revision number:'), name='RevisionNumberLabel', parent=self,
   102               label=_('Revision number:'), name='RevisionNumberLabel', parent=self.Editor,
   219               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
   103               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
   220         
   104         
   221         self.RevisionNumber = wx.TextCtrl(id=ID_SLAVEINFOSPANELREVISIONNUMBER, value='',
   105         self.RevisionNumber = wx.TextCtrl(id=ID_NODEEDITORREVISIONNUMBER, value='',
   222               name='RevisionNumber', parent=self, pos=wx.Point(0, 0),
   106               name='RevisionNumber', parent=self.Editor, pos=wx.Point(0, 0),
   223               size=wx.Size(0, 24), style=wx.TE_READONLY)
   107               size=wx.Size(0, 24), style=wx.TE_READONLY)
   224         
   108         
   225         self.PhysicsLabel = wx.StaticText(id=ID_SLAVEINFOSPANELPHYSICSLABEL,
   109         self.PhysicsLabel = wx.StaticText(id=ID_NODEEDITORPHYSICSLABEL,
   226               label=_('Physics:'), name='PhysicsLabel', parent=self,
   110               label=_('Physics:'), name='PhysicsLabel', parent=self.Editor,
   227               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
   111               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
   228         
   112         
   229         self.Physics = wx.TextCtrl(id=ID_SLAVEINFOSPANELPHYSICS, value='',
   113         self.Physics = wx.TextCtrl(id=ID_NODEEDITORPHYSICS, value='',
   230               name='Physics', parent=self, pos=wx.Point(0, 0),
   114               name='Physics', parent=self.Editor, pos=wx.Point(0, 0),
   231               size=wx.Size(0, 24), style=wx.TE_READONLY)
   115               size=wx.Size(0, 24), style=wx.TE_READONLY)
   232         
   116         
   233         self.SyncManagersLabel =  wx.StaticText(id=ID_SLAVEINFOSPANELSYNCMANAGERSLABEL,
   117         self.SyncManagersLabel =  wx.StaticText(id=ID_NODEEDITORSYNCMANAGERSLABEL,
   234               label=_('Sync managers:'), name='SyncManagersLabel', parent=self,
   118               label=_('Sync managers:'), name='SyncManagersLabel', parent=self.Editor,
   235               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
   119               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
   236         
   120         
   237         self.SyncManagersGrid = CustomGrid(id=ID_SLAVEINFOSPANELSYNCMANAGERSGRID,
   121         self.SyncManagersGrid = CustomGrid(id=ID_NODEEDITORSYNCMANAGERSGRID,
   238               name='SyncManagersGrid', parent=self, pos=wx.Point(0, 0), 
   122               name='SyncManagersGrid', parent=self.Editor, pos=wx.Point(0, 0), 
   239               size=wx.Size(0, 0), style=wx.VSCROLL)
   123               size=wx.Size(0, 0), style=wx.VSCROLL)
   240         
   124         
   241         self.VariablesLabel =  wx.StaticText(id=ID_SLAVEINFOSPANELVARIABLESLABEL,
   125         self.VariablesLabel =  wx.StaticText(id=ID_NODEEDITORVARIABLESLABEL,
   242               label=_('Variable entries:'), name='VariablesLabel', parent=self,
   126               label=_('Variable entries:'), name='VariablesLabel', parent=self,
   243               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
   127               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
   244         
   128         
   245         self.VariablesGrid = wx.gizmos.TreeListCtrl(id=ID_SLAVEINFOSPANELVARIABLESGRID,
   129         self.VariablesGrid = wx.gizmos.TreeListCtrl(id=ID_NODEEDITORVARIABLESGRID,
   246               name='VariablesGrid', parent=self, pos=wx.Point(0, 0), 
   130               name='VariablesGrid', parent=self.Editor, pos=wx.Point(0, 0), 
   247               size=wx.Size(0, 0), style=wx.TR_DEFAULT_STYLE |
   131               size=wx.Size(0, 0), style=wx.TR_DEFAULT_STYLE |
   248                                         wx.TR_ROW_LINES |
   132                                         wx.TR_ROW_LINES |
   249                                         wx.TR_COLUMN_LINES |
   133                                         wx.TR_COLUMN_LINES |
   250                                         wx.TR_HIDE_ROOT |
   134                                         wx.TR_HIDE_ROOT |
   251                                         wx.TR_FULL_ROW_HIGHLIGHT)
   135                                         wx.TR_FULL_ROW_HIGHLIGHT)
   252         self.VariablesGrid.GetMainWindow().Bind(wx.EVT_LEFT_DOWN, self.OnVariablesGridLeftClick)
   136         self.VariablesGrid.GetMainWindow().Bind(wx.EVT_LEFT_DOWN, self.OnVariablesGridLeftClick)
   253                 
   137                 
   254         self._init_sizers()
   138         self._init_sizers()
   255         
   139     
   256     def __init__(self, parent, controler):
   140     def __init__(self, parent, controler, window):
   257         self._init_ctrls(parent)
   141         EditorPanel.__init__(self, parent, "", window, controler)
   258         
   142     
   259         self.Controler = controler
       
   260         self.Slave = None
       
   261         self.Type = None
       
   262         
       
   263         self.SyncManagersTable = SyncManagersTable(self, [], GetSyncManagersTableColnames())
   143         self.SyncManagersTable = SyncManagersTable(self, [], GetSyncManagersTableColnames())
   264         self.SyncManagersGrid.SetTable(self.SyncManagersTable)
   144         self.SyncManagersGrid.SetTable(self.SyncManagersTable)
   265         self.SyncManagersGridColAlignements = [wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_RIGHT, 
   145         self.SyncManagersGridColAlignements = [wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_RIGHT, 
   266                                                wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_RIGHT]
   146                                                wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_RIGHT]
   267         self.SyncManagersGridColSizes = [40, 150, 100, 100, 100, 100]
   147         self.SyncManagersGridColSizes = [40, 150, 100, 100, 100, 100]
   279                                                wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_RIGHT, 
   159                                                wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_RIGHT, 
   280                                                wx.ALIGN_LEFT, wx.ALIGN_LEFT]):
   160                                                wx.ALIGN_LEFT, wx.ALIGN_LEFT]):
   281             self.VariablesGrid.AddColumn(colname, colsize, colalign)
   161             self.VariablesGrid.AddColumn(colname, colsize, colalign)
   282         self.VariablesGrid.SetMainColumn(1)
   162         self.VariablesGrid.SetMainColumn(1)
   283         
   163         
   284     def SetSlaveInfos(self, slave_pos, slave_infos):
   164         img = wx.Bitmap(self.Controler.GetIconPath("Cfile.png"), wx.BITMAP_TYPE_PNG).ConvertToImage()
   285         self.Slave = slave_pos
   165         self.SetIcon(wx.BitmapFromImage(img.Rescale(16, 16)))
       
   166     
       
   167     def __del__(self):
       
   168         self.Controler.OnCloseEditor(self)
       
   169     
       
   170     def GetTitle(self):
       
   171         return self.Controler.PlugFullName()
       
   172     
       
   173     def GetBufferState(self):
       
   174         return False, False
       
   175         
       
   176     def RefreshView(self):
       
   177         slave_infos = self.Controler.GetSlaveInfos()
   286         if slave_infos is not None:
   178         if slave_infos is not None:
   287             self.Type = slave_infos["device_type"]
       
   288             self.Vendor.SetValue(slave_infos["vendor"])
   179             self.Vendor.SetValue(slave_infos["vendor"])
   289             self.ProductCode.SetValue(slave_infos["product_code"])
   180             self.ProductCode.SetValue(slave_infos["product_code"])
   290             self.RevisionNumber.SetValue(slave_infos["revision_number"])
   181             self.RevisionNumber.SetValue(slave_infos["revision_number"])
   291             self.Physics.SetValue(slave_infos["physics"])
   182             self.Physics.SetValue(slave_infos["physics"])
   292             self.SyncManagersTable.SetData(slave_infos["sync_managers"])
   183             self.SyncManagersTable.SetData(slave_infos["sync_managers"])
   293             self.SyncManagersTable.ResetView(self.SyncManagersGrid)
   184             self.SyncManagersTable.ResetView(self.SyncManagersGrid)
   294             self.RefreshVariablesGrid(slave_infos["entries"])
   185             self.RefreshVariablesGrid(slave_infos["entries"])
   295         else:
   186         else:
   296             self.Type = None
       
   297             self.Vendor.SetValue("")
   187             self.Vendor.SetValue("")
   298             self.ProductCode.SetValue("")
   188             self.ProductCode.SetValue("")
   299             self.RevisionNumber.SetValue("")
   189             self.RevisionNumber.SetValue("")
   300             self.Physics.SetValue("")
   190             self.Physics.SetValue("")
   301             self.SyncManagersTable.SetData([])
   191             self.SyncManagersTable.SetData([])
   302             self.SyncManagersTable.ResetView(self.SyncManagersGrid)
   192             self.SyncManagersTable.ResetView(self.SyncManagersGrid)
   303             self.RefreshVariablesGrid([])
   193             self.RefreshVariablesGrid([])
   304             
   194     
   305     def RefreshVariablesGrid(self, entries):
   195     def RefreshVariablesGrid(self, entries):
   306         root = self.VariablesGrid.GetRootItem()
   196         root = self.VariablesGrid.GetRootItem()
   307         if not root.IsOk():
   197         if not root.IsOk():
   308             root = self.VariablesGrid.AddRoot("Slave entries")
   198             root = self.VariablesGrid.AddRoot("Slave entries")
   309         self.GenerateVariablesGridBranch(root, entries, GetVariablesTableColnames())
   199         self.GenerateVariablesGridBranch(root, entries, GetVariablesTableColnames())
   315         else:
   205         else:
   316             item, root_cookie = self.VariablesGrid.GetFirstChild(root, 0)
   206             item, root_cookie = self.VariablesGrid.GetFirstChild(root, 0)
   317         
   207         
   318         for entry in entries:
   208         for entry in entries:
   319             idx += 1
   209             idx += 1
   320             if not item.IsOk():
   210             create_new = not item.IsOk()
       
   211             if create_new:
   321                 item = self.VariablesGrid.AppendItem(root, "")
   212                 item = self.VariablesGrid.AppendItem(root, "")
   322             for col, colname in enumerate(colnames):
   213             for col, colname in enumerate(colnames):
   323                 if col == 0:
   214                 if col == 0:
   324                     self.VariablesGrid.SetItemText(item, str(idx), 0)
   215                     self.VariablesGrid.SetItemText(item, str(idx), 0)
   325                 else:
   216                 else:
   326                     self.VariablesGrid.SetItemText(item, entry.get(colname, ""), col)
   217                     self.VariablesGrid.SetItemText(item, entry.get(colname, ""), col)
   327             if entry["PDOMapping"] == "":
   218             if entry["PDOMapping"] == "":
   328                 self.VariablesGrid.SetItemBackgroundColour(item, wx.LIGHT_GREY)
   219                 self.VariablesGrid.SetItemBackgroundColour(item, wx.LIGHT_GREY)
   329             self.VariablesGrid.SetItemPyData(item, entry)
   220             self.VariablesGrid.SetItemPyData(item, entry)
       
   221             if create_new and wx.Platform != '__WXMSW__':
       
   222                 item, root_cookie = self.VariablesGrid.GetNextChild(root, root_cookie)
   330             idx = self.GenerateVariablesGridBranch(item, entry["children"], colnames, idx)
   223             idx = self.GenerateVariablesGridBranch(item, entry["children"], colnames, idx)
   331             if wx.Platform != '__WXMSW__':
       
   332                 item, root_cookie = self.VariablesGrid.GetNextChild(root, root_cookie)
       
   333             item, root_cookie = self.VariablesGrid.GetNextChild(root, root_cookie)
   224             item, root_cookie = self.VariablesGrid.GetNextChild(root, root_cookie)
   334         
   225         
   335         to_delete = []
   226         to_delete = []
   336         while item.IsOk():
   227         while item.IsOk():
   337             to_delete.append(item)
   228             to_delete.append(item)
   351             if (col == -1 and pdo_mapping != "" and
   242             if (col == -1 and pdo_mapping != "" and
   352                 self.Controler.GetSizeOfType(data_type) is not None):
   243                 self.Controler.GetSizeOfType(data_type) is not None):
   353                 
   244                 
   354                 entry_index = self.Controler.ExtractHexDecValue(entry.get("Index", "0"))
   245                 entry_index = self.Controler.ExtractHexDecValue(entry.get("Index", "0"))
   355                 entry_subindex = self.Controler.ExtractHexDecValue(entry.get("SubIndex", "0"))
   246                 entry_subindex = self.Controler.ExtractHexDecValue(entry.get("SubIndex", "0"))
   356                 var_name = "%s_%4.4x_%2.2x" % (self.Type, entry_index, entry_subindex)
   247                 var_name = "%s_%4.4x_%2.2x" % (self.Controler.PlugName(), entry_index, entry_subindex)
   357                 if pdo_mapping == "R":
   248                 if pdo_mapping == "R":
   358                     dir = "%I"
   249                     dir = "%I"
   359                 else:
   250                 else:
   360                     dir = "%Q"
   251                     dir = "%Q"
   361                 location = "%s%s" % (dir, self.Controler.GetSizeOfType(data_type)) + \
   252                 location = "%s%s" % (dir, self.Controler.GetSizeOfType(data_type)) + \
   362                            ".".join(map(lambda x:str(x), self.Controler.GetCurrentLocation() + self.Slave + (entry_index, entry_subindex)))
   253                            ".".join(map(lambda x:str(x), self.Controler.GetCurrentLocation() + (self.Controler.GetSlavePos(), entry_index, entry_subindex)))
   363                 
   254                 
   364                 data = wx.TextDataObject(str((location, "location", data_type, var_name, "")))
   255                 data = wx.TextDataObject(str((location, "location", data_type, var_name, "")))
   365                 dragSource = wx.DropSource(self.VariablesGrid)
   256                 dragSource = wx.DropSource(self.VariablesGrid)
   366                 dragSource.SetData(data)
   257                 dragSource.SetData(data)
   367                 dragSource.DoDragDrop()
   258                 dragSource.DoDragDrop()
   368             
   259             
   369         event.Skip()
   260         event.Skip()
   370 
   261 
   371 [ID_SLAVEPANEL, ID_SLAVEPANELTYPELABEL,
   262 DS402NodeEditor = NodeEditor
   372  ID_SLAVEPANELTYPE, ID_SLAVEPANELTYPEBROWSE, 
       
   373  ID_SLAVEPANELALIASLABEL, ID_SLAVEPANELALIAS, 
       
   374  ID_SLAVEPANELPOSLABEL, ID_SLAVEPANELPOS, 
       
   375  ID_SLAVEPANELSLAVEINFOSSTATICBOX, 
       
   376 ] = [wx.NewId() for _init_ctrls in range(9)]
       
   377 
       
   378 class SlavePanel(wx.Panel):
       
   379     
       
   380     if wx.VERSION < (2, 6, 0):
       
   381         def Bind(self, event, function, id = None):
       
   382             if id is not None:
       
   383                 event(self, id, function)
       
   384             else:
       
   385                 event(self, function)
       
   386     
       
   387     def _init_coll_MainSizer_Items(self, parent):
       
   388         parent.AddSizer(self.PositionSizer, 0, border=5, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
   389         parent.AddSizer(self.SlaveInfosBoxSizer, 0, border=5, flag=wx.GROW|wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT)
       
   390     
       
   391     def _init_coll_MainSizer_Growables(self, parent):
       
   392         parent.AddGrowableCol(0)
       
   393         parent.AddGrowableRow(1)
       
   394     
       
   395     def _init_coll_PositionSizer_Items(self, parent):
       
   396         parent.AddWindow(self.TypeLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL)
       
   397         parent.AddSizer(self.TypeSizer, 0, border=0, flag=wx.GROW)
       
   398         parent.AddWindow(self.AliasLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL)
       
   399         parent.AddWindow(self.Alias, 0, border=0, flag=wx.GROW)
       
   400         parent.AddWindow(self.PosLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL)
       
   401         parent.AddWindow(self.Pos, 0, border=0, flag=wx.GROW)
       
   402     
       
   403     def _init_coll_PositionSizer_Growables(self, parent):
       
   404         parent.AddGrowableCol(1)
       
   405         parent.AddGrowableCol(3)
       
   406         parent.AddGrowableCol(5)
       
   407         parent.AddGrowableRow(0)
       
   408     
       
   409     def _init_coll_TypeSizer_Items(self, parent):
       
   410         parent.AddWindow(self.Type, 1, border=0, flag=0)
       
   411         parent.AddWindow(self.TypeBrowse, 0, border=0, flag=0)
       
   412     
       
   413     def _init_coll_SlaveInfosBoxSizer_Items(self, parent):
       
   414         parent.AddWindow(self.SlaveInfosPanel, 1, border=0, flag=wx.GROW)
       
   415     
       
   416     def _init_sizers(self):
       
   417         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
   418         self.PositionSizer = wx.FlexGridSizer(cols=6, hgap=5, rows=1, vgap=0)
       
   419         self.TypeSizer = wx.BoxSizer(wx.HORIZONTAL)
       
   420         self.SlaveInfosBoxSizer = wx.StaticBoxSizer(self.SlaveInfosStaticBox, wx.VERTICAL)
       
   421         
       
   422         self._init_coll_MainSizer_Growables(self.MainSizer)
       
   423         self._init_coll_MainSizer_Items(self.MainSizer)
       
   424         self._init_coll_PositionSizer_Growables(self.PositionSizer)
       
   425         self._init_coll_PositionSizer_Items(self.PositionSizer)
       
   426         self._init_coll_TypeSizer_Items(self.TypeSizer)
       
   427         self._init_coll_SlaveInfosBoxSizer_Items(self.SlaveInfosBoxSizer)
       
   428         
       
   429         self.SetSizer(self.MainSizer)
       
   430     
       
   431     def _init_ctrls(self, prnt):
       
   432         wx.Panel.__init__(self, id=ID_SLAVEPANEL, name='SlavePanel', parent=prnt,
       
   433               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
   434         
       
   435         self.TypeLabel = wx.StaticText(id=ID_SLAVEPANELTYPELABEL,
       
   436               label=_('Type:'), name='TypeLabel', parent=self,
       
   437               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   438         
       
   439         self.Type = wx.TextCtrl(id=ID_SLAVEPANELTYPE, value='',
       
   440               name='Type', parent=self, pos=wx.Point(0, 0),
       
   441               size=wx.Size(0, 24), style=wx.TE_READONLY)
       
   442         
       
   443         self.TypeBrowse = wx.Button(id=ID_SLAVEPANELTYPEBROWSE, label='...',
       
   444               name='TypeBrowse', parent=self, pos=wx.Point(0, 0),
       
   445               size=wx.Size(30, 24), style=0)
       
   446         self.Bind(wx.EVT_BUTTON, self.OnTypeBrowseClick, id=ID_SLAVEPANELTYPEBROWSE)
       
   447         
       
   448         self.AliasLabel = wx.StaticText(id=ID_SLAVEPANELALIASLABEL,
       
   449               label=_('Alias:'), name='AliasLabel', parent=self,
       
   450               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   451         
       
   452         self.Alias = wx.SpinCtrl(id=ID_SLAVEPANELALIAS,
       
   453               name='Alias', parent=self, pos=wx.Point(0, 0),
       
   454               size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0, max=0xffff)
       
   455         self.Bind(wx.EVT_SPINCTRL, self.OnAliasChanged, id=ID_SLAVEPANELALIAS)
       
   456         
       
   457         self.PosLabel = wx.StaticText(id=ID_SLAVEPANELPOSLABEL,
       
   458               label=_('Position:'), name='PositionLabel', parent=self,
       
   459               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   460         
       
   461         self.Pos = wx.SpinCtrl(id=ID_SLAVEPANELPOS,
       
   462               name='Pos', parent=self, pos=wx.Point(0, 0),
       
   463               size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0, max=0xffff)
       
   464         self.Bind(wx.EVT_SPINCTRL, self.OnPositionChanged, id=ID_SLAVEPANELPOS)
       
   465         
       
   466         self.SlaveInfosStaticBox = wx.StaticBox(id=ID_SLAVEPANELSLAVEINFOSSTATICBOX,
       
   467               label=_('Slave infos:'), name='SlaveInfosStaticBox', parent=self,
       
   468               pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0)
       
   469         
       
   470         self.SlaveInfosPanel = SlaveInfosPanel(self, self.Controler)
       
   471         
       
   472         self._init_sizers()
       
   473     
       
   474     def __init__(self, parent, controler, window, slave):
       
   475         self.Controler = controler
       
   476         self.ParentWindow = window
       
   477         self.Slave = slave
       
   478         
       
   479         self._init_ctrls(parent)
       
   480         
       
   481         self.RefreshView()
       
   482     
       
   483     def GetSlaveTitle(self):
       
   484         type_infos = self.Controler.GetSlaveType(self.Slave)
       
   485         return "%s (%d:%d)" % (type_infos["device_type"], self.Slave[0], self.Slave[1])
       
   486     
       
   487     def GetSlave(self):
       
   488         return self.Slave
       
   489     
       
   490     def SetSlave(self, slave):
       
   491         if self.Slave != slave:
       
   492             self.Slave = slave
       
   493             self.RefreshView()
       
   494 
       
   495     def RefreshView(self):
       
   496         self.Alias.SetValue(self.Slave[0])
       
   497         self.Pos.SetValue(self.Slave[1])
       
   498         slave_infos = self.Controler.GetSlaveInfos(self.Slave)
       
   499         if slave_infos is not None:
       
   500             self.Type.SetValue(slave_infos["device_type"])
       
   501         else:
       
   502             type_infos = self.Controler.GetSlaveType(self.Slave)
       
   503             self.Type.SetValue(type_infos["device_type"])
       
   504         self.SlaveInfosPanel.SetSlaveInfos(self.Slave, slave_infos)
       
   505         
       
   506     def OnAliasChanged(self, event):
       
   507         alias = self.Alias.GetValue()
       
   508         if alias != self.Slave[0]:
       
   509             result = self.Controler.SetSlavePos(self.Slave[:2], alias = alias)
       
   510             if result is not None:
       
   511                 message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR)
       
   512                 message.ShowModal()
       
   513                 message.Destroy()
       
   514             else:
       
   515                 wx.CallAfter(self.ParentWindow.RefreshView, (alias, self.Slave[1]))
       
   516                 wx.CallAfter(self.ParentWindow.RefreshParentWindow)
       
   517         event.Skip()
       
   518         
       
   519     def OnPositionChanged(self, event):
       
   520         position = self.Pos.GetValue()
       
   521         if position != self.Slave[1]:
       
   522             result = self.Controler.SetSlavePos(self.Slave, position = position)
       
   523             if result is not None:
       
   524                 message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR)
       
   525                 message.ShowModal()
       
   526                 message.Destroy()
       
   527             else:
       
   528                 wx.CallAfter(self.ParentWindow.RefreshView, (self.Slave[0], position))
       
   529                 wx.CallAfter(self.ParentWindow.RefreshParentWindow)
       
   530         event.Skip()
       
   531 
       
   532     def OnTypeBrowseClick(self, event):
       
   533         dialog = SlaveTypeChoiceDialog(self, self.Controler, self.Controler.GetSlaveType(self.Slave))
       
   534         if dialog.ShowModal() == wx.ID_OK:
       
   535             result = self.Controler.SetSlaveType(self.Slave, dialog.GetType())
       
   536             if result is not None:
       
   537                 message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR)
       
   538                 message.ShowModal()
       
   539                 message.Destroy()
       
   540             else:
       
   541                 wx.CallAfter(self.RefreshView)
       
   542                 wx.CallAfter(self.ParentWindow.RefreshSlaveNodesTitles)
       
   543                 wx.CallAfter(self.ParentWindow.RefreshParentWindow)
       
   544         dialog.Destroy()
       
   545         event.Skip()
       
   546 
       
   547 [ID_CONFIGEDITOR, ID_CONFIGEDITORSLAVENODES,
       
   548 ] = [wx.NewId() for _init_ctrls in range(2)]
       
   549 
       
   550 [ID_CONFIGEDITORPLUGINMENUSCANNETWORK, ID_CONFIGEDITORPLUGINMENUADDSLAVE, 
       
   551  ID_CONFIGEDITORPLUGINMENUDELETESLAVE,
       
   552 ] = [wx.NewId() for _init_coll_PluginMenu_Items in range(3)]
       
   553 
       
   554 class ConfigEditor(EditorPanel):
       
   555     
       
   556     ID = ID_CONFIGEDITOR
       
   557     
       
   558     def _init_coll_MainSizer_Items(self, parent):
       
   559         parent.AddWindow(self.SlaveNodes, 0, border=5, flag=wx.GROW|wx.ALL)
       
   560 
       
   561     def _init_coll_MainSizer_Growables(self, parent):
       
   562         parent.AddGrowableCol(0)
       
   563         parent.AddGrowableRow(0)
       
   564     
       
   565     def _init_sizers(self):
       
   566         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=1, vgap=0)
       
   567         
       
   568         self._init_coll_MainSizer_Items(self.MainSizer)
       
   569         self._init_coll_MainSizer_Growables(self.MainSizer)
       
   570         
       
   571         self.Editor.SetSizer(self.MainSizer)
       
   572     
       
   573     def _init_Editor(self, prnt):
       
   574         self.Editor = wx.Panel(id=-1, parent=prnt, pos=wx.Point(0, 0), 
       
   575                 size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
   576         
       
   577         self.SlaveNodes = wx.Notebook(id=ID_CONFIGEDITORSLAVENODES,
       
   578               name='SlaveNodes', parent=self.Editor, pos=wx.Point(0, 0),
       
   579               size=wx.Size(0, 0), style=wx.NB_LEFT)
       
   580         
       
   581         self._init_sizers()
       
   582     
       
   583     def _init_MenuItems(self):
       
   584         self.MenuItems = [
       
   585             (wx.ITEM_NORMAL, (_("Scan network"), ID_CONFIGEDITORPLUGINMENUSCANNETWORK, '', self.OnScanNetworkMenu)),
       
   586             (wx.ITEM_SEPARATOR, None),
       
   587             (wx.ITEM_NORMAL, (_("Add slave"), ID_CONFIGEDITORPLUGINMENUADDSLAVE, '', self.OnAddSlaveMenu)),
       
   588             (wx.ITEM_NORMAL, (_("Delete slave"), ID_CONFIGEDITORPLUGINMENUDELETESLAVE, '', self.OnDeleteSlaveMenu)),
       
   589         ]
       
   590     
       
   591     def __init__(self, parent, controler, window):
       
   592         EditorPanel.__init__(self, parent, "", window, controler)
       
   593         
       
   594         img = wx.Bitmap(self.Controler.GetIconPath("Cfile.png"), wx.BITMAP_TYPE_PNG).ConvertToImage()
       
   595         self.SetIcon(wx.BitmapFromImage(img.Rescale(16, 16)))
       
   596     
       
   597     def __del__(self):
       
   598         self.Controler.OnCloseEditor(self)
       
   599     
       
   600     def GetTitle(self):
       
   601         fullname = self.Controler.PlugFullName()
       
   602         if not self.Controler.ConfigIsSaved():
       
   603             return "~%s~" % fullname
       
   604         return fullname
       
   605     
       
   606     def GetBufferState(self):
       
   607         return self.Controler.GetBufferState()
       
   608         
       
   609     def Undo(self):
       
   610         self.Controler.LoadPrevious()
       
   611         self.RefreshView()
       
   612             
       
   613     def Redo(self):
       
   614         self.Controler.LoadNext()
       
   615         self.RefreshView()
       
   616     
       
   617     def RefreshView(self, slave_pos=None):
       
   618         slaves = self.Controler.GetSlaves()
       
   619         for i, slave in enumerate(slaves):
       
   620             if i < self.SlaveNodes.GetPageCount():
       
   621                 panel = self.SlaveNodes.GetPage(i)
       
   622                 panel.SetSlave(slave)
       
   623             else:
       
   624                 panel = SlavePanel(self.SlaveNodes, self.Controler, self, slave)
       
   625                 self.SlaveNodes.AddPage(panel, "")
       
   626         while self.SlaveNodes.GetPageCount() > len(slaves):
       
   627             self.SlaveNodes.RemovePage(len(slaves))
       
   628         self.RefreshSlaveNodesTitles()
       
   629         if slave_pos is not None:
       
   630             self.SelectSlave(slave_pos)
       
   631     
       
   632     def RefreshParentWindow(self):
       
   633         self.ParentWindow.RefreshTitle()
       
   634         self.ParentWindow.RefreshFileMenu()
       
   635         self.ParentWindow.RefreshEditMenu()
       
   636         self.ParentWindow.RefreshPluginMenu()
       
   637         self.ParentWindow.RefreshPageTitles()
       
   638     
       
   639     def RefreshSlaveNodesTitles(self):
       
   640         for idx in xrange(self.SlaveNodes.GetPageCount()):
       
   641             panel = self.SlaveNodes.GetPage(idx)
       
   642             self.SlaveNodes.SetPageText(idx, panel.GetSlaveTitle())
       
   643             
       
   644     def RefreshPluginMenu(self, plugin_menu):
       
   645         plugin_menu.Enable(ID_CONFIGEDITORPLUGINMENUDELETESLAVE, 
       
   646                            self.SlaveNodes.GetPageCount() > 0)
       
   647     
       
   648     def SelectSlave(self, slave):
       
   649         for idx in xrange(self.SlaveNodes.GetPageCount()):
       
   650             panel = self.SlaveNodes.GetPage(idx)
       
   651             if panel.GetSlave() == slave:
       
   652                 self.SlaveNodes.SetSelection(idx)
       
   653                 return
       
   654     
       
   655     def OnScanNetworkMenu(self, event):
       
   656         error, returnVal = self.Controler.RemoteExec(SCAN_COMMAND, returnVal = None)
       
   657         if error != 0:
       
   658             dialog = wx.MessageDialog(self, returnVal, "Error", wx.OK|wx.ICON_ERROR)
       
   659             dialog.ShowModal()
       
   660             dialog.Destroy()
       
   661         elif returnVal is not None:
       
   662             print returnVal
       
   663             wx.CallAfter(self.RefreshView)
       
   664 
       
   665     def OnAddSlaveMenu(self, event):
       
   666         slave = self.Controler.AddSlave()
       
   667         self.RefreshParentWindow()
       
   668         wx.CallAfter(self.RefreshView, slave)
       
   669         
       
   670     def OnDeleteSlaveMenu(self, event):
       
   671         selected = self.SlaveNodes.GetSelection()
       
   672         if selected != -1:
       
   673             panel = self.SlaveNodes.GetPage(selected)
       
   674             if self.Controler.RemoveSlave(panel.GetSlave()[:2]):
       
   675                 self.RefreshParentWindow()
       
   676                 wx.CallAfter(self.RefreshView)
       
   677 
       
   678 
       
   679 [ID_DS402NODEEDITOR,
       
   680 ] = [wx.NewId() for _init_ctrls in range(1)]
       
   681 
       
   682 class DS402NodeEditor(EditorPanel):
       
   683     
       
   684     ID = ID_DS402NODEEDITOR
       
   685     
       
   686     def _init_Editor(self, prnt):
       
   687         self.Editor = SlaveInfosPanel(prnt, self.Controler)
       
   688         
       
   689     def __init__(self, parent, controler, window):
       
   690         EditorPanel.__init__(self, parent, "", window, controler)
       
   691         
       
   692         img = wx.Bitmap(self.Controler.GetIconPath("Cfile.png"), wx.BITMAP_TYPE_PNG).ConvertToImage()
       
   693         self.SetIcon(wx.BitmapFromImage(img.Rescale(16, 16)))
       
   694     
       
   695     def __del__(self):
       
   696         self.Controler.OnCloseEditor(self)
       
   697     
       
   698     def GetTitle(self):
       
   699         return self.Controler.PlugFullName()
       
   700     
       
   701     def GetBufferState(self):
       
   702         return False, False
       
   703         
       
   704     def RefreshView(self):
       
   705         self.Editor.SetSlaveInfos(self.Controler.GetSlavePos(), self.Controler.GetSlaveInfos())
       
   706