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) |
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() |