etherlab/ConfigEditor.py
changeset 2099 ea5384ab152c
parent 2098 392791b5cc04
child 2100 bb43a81356eb
equal deleted inserted replaced
2098:392791b5cc04 2099:ea5384ab152c
   329                 if result is not None:
   329                 if result is not None:
   330                     location = map(int, result.group(1).split('.'))
   330                     location = map(int, result.group(1).split('.'))
   331                 master_location = self.ParentWindow.GetMasterLocation()
   331                 master_location = self.ParentWindow.GetMasterLocation()
   332                 if (master_location == tuple(location[:len(master_location)]) and 
   332                 if (master_location == tuple(location[:len(master_location)]) and 
   333                     len(location) - len(master_location) == 3):
   333                     len(location) - len(master_location) == 3):
       
   334                     values = tuple(location[len(master_location):])
       
   335                     var_type = self.ParentWindow.Controler.GetSlaveVariableDataType(*values)
   334                     if col == 2:
   336                     if col == 2:
   335                         self.ParentWindow.ProcessVariablesTable.SetValueByName(
   337                         other_values = self.ParentWindow.ProcessVariablesTable.GetValueByName(row, "WriteTo")
   336                             row, "ReadFrom", tuple(location[len(master_location):]))
       
   337                     else:
   338                     else:
   338                         self.ParentWindow.ProcessVariablesTable.SetValueByName(
   339                         other_values = self.ParentWindow.ProcessVariablesTable.GetValueByName(row, "ReadFrom")
   339                             row, "WriteTo", tuple(location[len(master_location):]))
   340                     if other_values != "":
   340                     self.ParentWindow.SaveProcessVariables()
   341                         other_type = self.ParentWindow.Controler.GetSlaveVariableDataType(*other_values)
   341                     self.ParentWindow.RefreshProcessVariables()
   342                     else:
       
   343                         other_type = None
       
   344                     if other_type is None or var_type == other_type:
       
   345                         if col == 2:
       
   346                             self.ParentWindow.ProcessVariablesTable.SetValueByName(row, "ReadFrom", values)
       
   347                         else:
       
   348                             self.ParentWindow.ProcessVariablesTable.SetValueByName(row, "WriteTo", values)
       
   349                         self.ParentWindow.SaveProcessVariables()
       
   350                         self.ParentWindow.RefreshProcessVariables()
       
   351                     else:
       
   352                         message = _("'Read from' and 'Write to' variables types are not compatible")
   342                 else:
   353                 else:
   343                     message = _("Invalid value \"%s\" for process variable")%data
   354                     message = _("Invalid value \"%s\" for process variable")%data
   344                     
   355                     
   345         if message is not None:
   356         if message is not None:
   346             wx.CallAfter(self.ShowMessage, message)
   357             wx.CallAfter(self.ShowMessage, message)
   373             values = None
   384             values = None
   374         if values is not None:
   385         if values is not None:
   375             location = None
   386             location = None
   376             if values[1] == "location":
   387             if values[1] == "location":
   377                 result = LOCATION_MODEL.match(values[0])
   388                 result = LOCATION_MODEL.match(values[0])
   378                 if result is not None:
   389                 if result is not None and len(values) > 5:
   379                     location = map(int, result.group(1).split('.'))
   390                     location = map(int, result.group(1).split('.'))
   380                     access = values[5]
   391                     access = values[5]
   381             elif values[1] == "variable":
   392             elif values[1] == "variable":
   382                 location = values[0]
   393                 location = values[0]
   383                 access = values[2]
   394                 access = values[2]
   529         self.ProcessVariablesGrid.SetDropTarget(ProcessVariableDropTarget(self))
   540         self.ProcessVariablesGrid.SetDropTarget(ProcessVariableDropTarget(self))
   530         self.ProcessVariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, 
   541         self.ProcessVariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, 
   531               self.OnProcessVariablesGridCellChange)
   542               self.OnProcessVariablesGridCellChange)
   532         self.ProcessVariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, 
   543         self.ProcessVariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, 
   533               self.OnProcessVariablesGridCellLeftClick)
   544               self.OnProcessVariablesGridCellLeftClick)
       
   545         self.ProcessVariablesGrid.Bind(wx.EVT_KEY_DOWN, self.OnProcessVariablesGridKeyDown)
   534         
   546         
   535         startup_commands_header = wx.BoxSizer(wx.HORIZONTAL)
   547         startup_commands_header = wx.BoxSizer(wx.HORIZONTAL)
   536         
   548         
   537         startup_commands_label = wx.StaticText(self.EthercatMasterEditor,
   549         startup_commands_label = wx.StaticText(self.EthercatMasterEditor,
   538               label=_("Startup service variables assignments:"))
   550               label=_("Startup service variables assignments:"))
   584         
   596         
   585         return self.EthercatMasterEditor
   597         return self.EthercatMasterEditor
   586 
   598 
   587     def __init__(self, parent, controler, window):
   599     def __init__(self, parent, controler, window):
   588         ConfTreeNodeEditor.__init__(self, parent, controler, window)
   600         ConfTreeNodeEditor.__init__(self, parent, controler, window)
   589     
   601         
       
   602         self.ProcessVariables = []
       
   603         self.LastCommandInfos = None
       
   604         
   590         self.ProcessVariablesDefaultValue = {"Name": "", "ReadFrom": "", "WriteTo": "", "Description": ""}
   605         self.ProcessVariablesDefaultValue = {"Name": "", "ReadFrom": "", "WriteTo": "", "Description": ""}
   591         self.ProcessVariablesTable = ProcessVariablesTable(self, [], GetProcessVariablesTableColnames())
   606         self.ProcessVariablesTable = ProcessVariablesTable(self, [], GetProcessVariablesTableColnames())
   592         self.ProcessVariablesColSizes = [40, 100, 150, 150, 200]
   607         self.ProcessVariablesColSizes = [40, 100, 150, 150, 200]
   593         self.ProcessVariablesColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT]
   608         self.ProcessVariablesColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT]
   594         
   609         
   617                 self.SaveProcessVariables()
   632                 self.SaveProcessVariables()
   618                 self.ProcessVariablesTable.ResetView(self.ProcessVariablesGrid)
   633                 self.ProcessVariablesTable.ResetView(self.ProcessVariablesGrid)
   619             return new_row
   634             return new_row
   620         setattr(self.ProcessVariablesGrid, "_MoveRow", _MoveVariablesElement)
   635         setattr(self.ProcessVariablesGrid, "_MoveRow", _MoveVariablesElement)
   621         
   636         
       
   637         _refresh_buttons = getattr(self.ProcessVariablesGrid, "RefreshButtons")
       
   638         def _RefreshButtons():
       
   639             if self.NodesFilter.GetSelection() == 0:
       
   640                 _refresh_buttons()
       
   641             else:
       
   642                 self.AddVariableButton.Enable(False)
       
   643                 self.DeleteVariableButton.Enable(False)
       
   644                 self.UpVariableButton.Enable(False)
       
   645                 self.DownVariableButton.Enable(False)
       
   646         setattr(self.ProcessVariablesGrid, "RefreshButtons", _RefreshButtons)
       
   647         
   622         self.ProcessVariablesGrid.SetRowLabelSize(0)
   648         self.ProcessVariablesGrid.SetRowLabelSize(0)
   623         for col in range(self.ProcessVariablesTable.GetNumberCols()):
   649         for col in range(self.ProcessVariablesTable.GetNumberCols()):
   624             attr = wx.grid.GridCellAttr()
   650             attr = wx.grid.GridCellAttr()
   625             attr.SetAlignment(self.ProcessVariablesColAlignements[col], wx.ALIGN_CENTRE)
   651             attr.SetAlignment(self.ProcessVariablesColAlignements[col], wx.ALIGN_CENTRE)
   626             self.ProcessVariablesGrid.SetColAttr(col, attr)
   652             self.ProcessVariablesGrid.SetColAttr(col, attr)
   649             command = self.StartupCommandsTable.GetRow(row)
   675             command = self.StartupCommandsTable.GetRow(row)
   650             self.Controler.RemoveStartupCommand(command["Position"], command["command_idx"])
   676             self.Controler.RemoveStartupCommand(command["Position"], command["command_idx"])
   651             self.RefreshStartupCommands()
   677             self.RefreshStartupCommands()
   652             self.RefreshBuffer()
   678             self.RefreshBuffer()
   653         setattr(self.StartupCommandsGrid, "_DeleteRow", _DeleteCommandsElement)
   679         setattr(self.StartupCommandsGrid, "_DeleteRow", _DeleteCommandsElement)
   654             
   680         
   655         self.StartupCommandsGrid.SetRowLabelSize(0)
   681         self.StartupCommandsGrid.SetRowLabelSize(0)
   656         for col in range(self.StartupCommandsTable.GetNumberCols()):
   682         for col in range(self.StartupCommandsTable.GetNumberCols()):
   657             attr = wx.grid.GridCellAttr()
   683             attr = wx.grid.GridCellAttr()
   658             attr.SetAlignment(self.StartupCommandsColAlignements[col], wx.ALIGN_CENTRE)
   684             attr.SetAlignment(self.StartupCommandsColAlignements[col], wx.ALIGN_CENTRE)
   659             self.StartupCommandsGrid.SetColAttr(col, attr)
   685             self.StartupCommandsGrid.SetColAttr(col, attr)
   664     def RefreshBuffer(self):
   690     def RefreshBuffer(self):
   665         self.ParentWindow.RefreshTitle()
   691         self.ParentWindow.RefreshTitle()
   666         self.ParentWindow.RefreshFileMenu()
   692         self.ParentWindow.RefreshFileMenu()
   667         self.ParentWindow.RefreshEditMenu()
   693         self.ParentWindow.RefreshEditMenu()
   668         self.ParentWindow.RefreshPageTitles()
   694         self.ParentWindow.RefreshPageTitles()
       
   695     
       
   696     def GetBufferState(self):
       
   697         return self.Controler.GetBufferState()
       
   698     
       
   699     def Undo(self):
       
   700         self.Controler.LoadPrevious()
       
   701         self.RefreshView()
       
   702             
       
   703     def Redo(self):
       
   704         self.Controler.LoadNext()
       
   705         self.RefreshView()
   669     
   706     
   670     def RefreshView(self):
   707     def RefreshView(self):
   671         ConfTreeNodeEditor.RefreshView(self)
   708         ConfTreeNodeEditor.RefreshView(self)
   672         
   709         
   673         self.RefreshNodesFilter()
   710         self.RefreshNodesFilter()
   705             except:
   742             except:
   706                 self.CurrentNodesFilter = None
   743                 self.CurrentNodesFilter = None
   707         self.NodesVariables.SetCurrentNodesFilter(self.CurrentNodesFilter)
   744         self.NodesVariables.SetCurrentNodesFilter(self.CurrentNodesFilter)
   708     
   745     
   709     def RefreshProcessVariables(self):
   746     def RefreshProcessVariables(self):
   710         self.ProcessVariablesTable.SetData(
   747         if self.CurrentNodesFilter is not None:
   711             self.Controler.GetProcessVariables())
   748             self.ProcessVariables = self.Controler.GetProcessVariables()
   712         self.ProcessVariablesTable.ResetView(self.ProcessVariablesGrid)
   749             slaves = self.Controler.GetSlaves(**self.CurrentNodesFilter)
       
   750             data = []
       
   751             for variable in self.ProcessVariables:
       
   752                 if (variable["ReadFrom"] == "" or variable["ReadFrom"][0] in slaves or
       
   753                     variable["WriteTo"] == "" or variable["WriteTo"][0] in slaves):
       
   754                     data.append(variable)
       
   755             self.ProcessVariablesTable.SetData(data)
       
   756             self.ProcessVariablesTable.ResetView(self.ProcessVariablesGrid)
       
   757             self.ProcessVariablesGrid.RefreshButtons()
   713     
   758     
   714     def SaveProcessVariables(self):
   759     def SaveProcessVariables(self):
   715         self.Controler.SetProcessVariables(
   760         self.Controler.SetProcessVariables(
   716             self.ProcessVariablesTable.GetData())
   761             self.ProcessVariablesTable.GetData())
   717         self.RefreshBuffer()
   762         self.RefreshBuffer()
   718     
   763     
   719     def RefreshStartupCommands(self):
   764     def RefreshStartupCommands(self, position=None, command_idx=None):
   720         if self.CurrentNodesFilter is not None:
   765         if self.CurrentNodesFilter is not None:
       
   766             self.StartupCommandsGrid.CloseEditControl()
   721             self.StartupCommandsTable.SetData(
   767             self.StartupCommandsTable.SetData(
   722                 self.Controler.GetStartupCommands(**self.CurrentNodesFilter))
   768                 self.Controler.GetStartupCommands(**self.CurrentNodesFilter))
   723             self.StartupCommandsTable.ResetView(self.StartupCommandsGrid)
   769             self.StartupCommandsTable.ResetView(self.StartupCommandsGrid)
       
   770             if position is not None and command_idx is not None:
       
   771                 self.SelectStartupCommand(position, command_idx)
   724     
   772     
   725     def SelectStartupCommand(self, position, command_idx):
   773     def SelectStartupCommand(self, position, command_idx):
   726         self.StartupCommandsGrid.SetSelectedRow(
   774         self.StartupCommandsGrid.SetSelectedRow(
   727             self.StartupCommandsTable.GetCommandIndex(position, command_idx))
   775             self.StartupCommandsTable.GetCommandIndex(position, command_idx))
   728     
   776     
   766         else:
   814         else:
   767             dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
   815             dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
   768             dialog.ShowModal()
   816             dialog.ShowModal()
   769             dialog.Destroy()
   817             dialog.Destroy()
   770             event.Veto()
   818             event.Veto()
   771         
   819     
   772     def OnProcessVariablesGridCellLeftClick(self, event):
   820     def OnProcessVariablesGridCellLeftClick(self, event):
       
   821         row = event.GetRow()
       
   822         if event.GetCol() == 0:
       
   823             var_name = self.ProcessVariablesTable.GetValueByName(row, "Name")
       
   824             var_type = self.Controler.GetSlaveVariableDataType(
       
   825                 *self.ProcessVariablesTable.GetValueByName(row, "ReadFrom"))
       
   826             data_size = self.Controler.GetSizeOfType(var_type)
       
   827             number = self.ProcessVariablesTable.GetValueByName(row, "Number")
       
   828             location = "%%M%s" % data_size + \
       
   829                        ".".join(map(lambda x:str(x), self.Controler.GetCurrentLocation() + (number,)))
       
   830             
       
   831             data = wx.TextDataObject(str((location, "location", var_type, var_name, "")))
       
   832             dragSource = wx.DropSource(self.ProcessVariablesGrid)
       
   833             dragSource.SetData(data)
       
   834             dragSource.DoDragDrop()
   773         event.Skip()
   835         event.Skip()
       
   836     
       
   837     def OnProcessVariablesGridKeyDown(self, event):
       
   838         keycode = event.GetKeyCode()
       
   839         col = self.ProcessVariablesGrid.GetGridCursorCol()
       
   840         row = self.ProcessVariablesGrid.GetGridCursorRow()
       
   841         colname = self.ProcessVariablesTable.GetColLabelValue(col, False)
       
   842         if (keycode in (wx.WXK_DELETE, wx.WXK_NUMPAD_DELETE) and 
       
   843             (colname.startswith("Read from") or colname.startswith("Write to"))):
       
   844             self.ProcessVariablesTable.SetValue(row, col, "")
       
   845             self.SaveProcessVariables()
       
   846             wx.CallAfter(self.ProcessVariablesTable.ResetView, self.ProcessVariablesGrid)
       
   847         else:
       
   848             event.Skip()
   774     
   849     
   775     def OnStartupCommandsGridCellChange(self, event):
   850     def OnStartupCommandsGridCellChange(self, event):
   776         row, col = event.GetRow(), event.GetCol()
   851         row, col = event.GetRow(), event.GetCol()
   777         colname = self.StartupCommandsTable.GetColLabelValue(col, False)
   852         colname = self.StartupCommandsTable.GetColLabelValue(col, False)
   778         value = self.StartupCommandsTable.GetValue(row, col)
   853         value = self.StartupCommandsTable.GetValue(row, col)
   779         message = None
   854         message = None
       
   855         veto = False
   780         if colname == "Position":
   856         if colname == "Position":
   781             if value not in self.Controler.GetSlaves():
   857             if value not in self.Controler.GetSlaves():
   782                 message = _("No slave defined at position %d!") % value
   858                 message = _("No slave defined at position %d!") % value
   783             if message is None:
   859             if message is None:
   784                 self.Controler.RemoveStartupCommand(
   860                 self.Controler.RemoveStartupCommand(
   785                     self.StartupCommandsTable.GetOldValue(),
   861                     self.StartupCommandsTable.GetOldValue(),
   786                     self.StartupCommandsTable.GetValueByName(row, "command_idx"))
   862                     self.StartupCommandsTable.GetValueByName(row, "command_idx"))
   787                 command = self.StartupCommandsTable.GetRow(row)
   863                 command = self.StartupCommandsTable.GetRow(row)
   788                 command_idx = self.Controler.AppendStartupCommand(command)
   864                 command_idx = self.Controler.AppendStartupCommand(command)
   789                 wx.CallAfter(self.RefreshStartupCommands)
   865                 wx.CallAfter(self.RefreshStartupCommands, command["Position"], command_idx)
   790                 wx.CallAfter(self.SelectStartupCommand, command["Position"], command_idx)
   866                 veto = True
   791         else:
   867         else:
   792             self.Controler.SetStartupCommandInfos(self.StartupCommandsTable.GetRow(row))
   868             command = self.StartupCommandsTable.GetRow(row)
       
   869             if self.LastCommandInfos != command:
       
   870                 self.LastCommandInfos = command.copy()
       
   871                 self.Controler.SetStartupCommandInfos(command)
       
   872                 if colname in ["Index", "SubIndex"]: 
       
   873                     wx.CallAfter(self.RefreshStartupCommands, command["Position"], command["command_idx"])
       
   874                     veto = True
   793         if message is None:
   875         if message is None:
   794             self.RefreshBuffer()
   876             self.RefreshBuffer()
   795             event.Skip()
   877             if veto:
       
   878                 event.Veto()
       
   879             else:
       
   880                 event.Skip()
   796         else:
   881         else:
   797             dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
   882             dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
   798             dialog.ShowModal()
   883             dialog.ShowModal()
   799             dialog.Destroy()
   884             dialog.Destroy()
   800             event.Veto()
   885             event.Veto()