lbessard@205: #!/usr/bin/env python lbessard@205: # -*- coding: utf-8 -*- lbessard@205: lbessard@205: #This file is part of CanFestival, a library implementing CanOpen Stack. lbessard@205: # lbessard@205: #Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD lbessard@205: # lbessard@205: #See COPYING file for copyrights details. lbessard@205: # lbessard@205: #This library is free software; you can redistribute it and/or lbessard@205: #modify it under the terms of the GNU Lesser General Public lbessard@205: #License as published by the Free Software Foundation; either lbessard@205: #version 2.1 of the License, or (at your option) any later version. lbessard@205: # lbessard@205: #This library is distributed in the hope that it will be useful, lbessard@205: #but WITHOUT ANY WARRANTY; without even the implied warranty of lbessard@205: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU lbessard@205: #Lesser General Public License for more details. lbessard@205: # lbessard@205: #You should have received a copy of the GNU Lesser General Public lbessard@205: #License along with this library; if not, write to the Free Software lbessard@205: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA lbessard@205: lbessard@205: import wx lbessard@205: import wx.grid lbessard@205: lbessard@205: from types import * lbessard@281: from commondialogs import * lbessard@205: greg@206: from node import OD_Subindex, OD_MultipleSubindexes, OD_IdenticalSubindexes, OD_IdenticalIndexes lbessard@205: lbessard@205: ColSizes = [75, 250, 150, 125, 100, 60, 250] lbessard@254: ColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_CENTER, wx.ALIGN_RIGHT, wx.ALIGN_CENTER, wx.ALIGN_CENTER, wx.ALIGN_LEFT] lbessard@205: AccessList = "Read Only,Write Only,Read/Write" lbessard@205: RAccessList = "Read Only,Read/Write" lbessard@205: BoolList = "True,False" lbessard@205: OptionList = "Yes,No" lbessard@205: lbessard@205: DictionaryOrganisation = [ lbessard@205: {"minIndex" : 0x0001, "maxIndex" : 0x0FFF, "name" : "Data Type Definitions"}, lbessard@205: {"minIndex" : 0x1000, "maxIndex" : 0x1029, "name" : "Communication Parameters"}, lbessard@205: {"minIndex" : 0x1200, "maxIndex" : 0x12FF, "name" : "SDO Parameters"}, lbessard@205: {"minIndex" : 0x1400, "maxIndex" : 0x15FF, "name" : "Receive PDO Parameters"}, lbessard@205: {"minIndex" : 0x1600, "maxIndex" : 0x17FF, "name" : "Receive PDO Mapping"}, lbessard@205: {"minIndex" : 0x1800, "maxIndex" : 0x19FF, "name" : "Transmit PDO Parameters"}, lbessard@205: {"minIndex" : 0x1A00, "maxIndex" : 0x1BFF, "name" : "Transmit PDO Mapping"}, lbessard@205: {"minIndex" : 0x1C00, "maxIndex" : 0x1FFF, "name" : "Other Communication Parameters"}, lbessard@205: {"minIndex" : 0x2000, "maxIndex" : 0x5FFF, "name" : "Manufacturer Specific"}, lbessard@205: {"minIndex" : 0x6000, "maxIndex" : 0x9FFF, "name" : "Standardized Device Profile"}, lbessard@205: {"minIndex" : 0xA000, "maxIndex" : 0xBFFF, "name" : "Standardized Interface Profile"}] lbessard@205: lbessard@242: SizeConversion = {1 : "X", 8 : "B", 16 : "W", 24 : "D", 32 : "D", 40 : "L", 48 : "L", 56 : "L", 64 : "L"} lbessard@242: lbessard@254: class SubindexTable(wx.grid.PyGridTableBase): lbessard@205: lbessard@205: """ lbessard@205: A custom wxGrid Table using user supplied data lbessard@205: """ lbessard@205: def __init__(self, parent, data, editors, colnames): lbessard@205: # The base class must be initialized *first* lbessard@254: wx.grid.PyGridTableBase.__init__(self) lbessard@205: self.data = data lbessard@205: self.editors = editors lbessard@205: self.CurrentIndex = 0 lbessard@205: self.colnames = colnames lbessard@205: self.Parent = parent lbessard@205: self.Editable = True lbessard@205: # XXX lbessard@205: # we need to store the row length and collength to lbessard@205: # see if the table has changed size lbessard@205: self._rows = self.GetNumberRows() lbessard@205: self._cols = self.GetNumberCols() lbessard@205: lbessard@205: def Disable(self): lbessard@205: self.Editable = False lbessard@205: lbessard@205: def Enable(self): lbessard@205: self.Editable = True lbessard@205: lbessard@205: def GetNumberCols(self): lbessard@205: return len(self.colnames) lbessard@205: lbessard@205: def GetNumberRows(self): lbessard@205: return len(self.data) lbessard@205: lbessard@205: def GetColLabelValue(self, col): lbessard@205: if col < len(self.colnames): lbessard@205: return self.colnames[col] lbessard@205: lbessard@205: def GetRowLabelValues(self, row): lbessard@205: return row lbessard@205: lbessard@205: def GetValue(self, row, col): lbessard@205: if row < self.GetNumberRows(): lbessard@266: return str(self.data[row].get(self.GetColLabelValue(col), "")) lbessard@266: lbessard@205: def GetEditor(self, row, col): lbessard@205: if row < self.GetNumberRows(): lbessard@205: return self.editors[row].get(self.GetColLabelValue(col), "") lbessard@205: lbessard@205: def GetValueByName(self, row, colname): lbessard@205: return self.data[row].get(colname) lbessard@205: lbessard@205: def SetValue(self, row, col, value): lbessard@205: if col < len(self.colnames): lbessard@205: self.data[row][self.GetColLabelValue(col)] = value lbessard@205: lbessard@205: def ResetView(self, grid): lbessard@205: """ lbessard@254: (wx.grid.Grid) -> Reset the grid view. Call this to lbessard@205: update the grid if rows and columns have been added or deleted lbessard@205: """ lbessard@205: grid.BeginBatch() lbessard@205: for current, new, delmsg, addmsg in [ lbessard@254: (self._rows, self.GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED), lbessard@254: (self._cols, self.GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED), lbessard@205: ]: lbessard@205: if new < current: lbessard@254: msg = wx.grid.GridTableMessage(self,delmsg,new,current-new) lbessard@205: grid.ProcessTableMessage(msg) lbessard@205: elif new > current: lbessard@254: msg = wx.grid.GridTableMessage(self,addmsg,new-current) lbessard@205: grid.ProcessTableMessage(msg) lbessard@205: self.UpdateValues(grid) lbessard@205: grid.EndBatch() lbessard@205: lbessard@205: self._rows = self.GetNumberRows() lbessard@205: self._cols = self.GetNumberCols() lbessard@205: # update the column rendering scheme lbessard@205: self._updateColAttrs(grid) lbessard@205: lbessard@205: # update the scrollbars and the displayed part of the grid lbessard@205: grid.AdjustScrollbars() lbessard@205: grid.ForceRefresh() lbessard@205: lbessard@205: lbessard@205: def UpdateValues(self, grid): lbessard@205: """Update all displayed values""" lbessard@205: # This sends an event to the grid table to update all of the values lbessard@254: msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES) lbessard@205: grid.ProcessTableMessage(msg) lbessard@205: lbessard@205: def _updateColAttrs(self, grid): lbessard@205: """ lbessard@254: wx.grid.Grid -> update the column attributes to add the lbessard@205: appropriate renderer given the column name. lbessard@205: lbessard@205: Otherwise default to the default renderer. lbessard@205: """ lbessard@205: lbessard@205: for col in range(self.GetNumberCols()): lbessard@254: attr = wx.grid.GridCellAttr() lbessard@254: attr.SetAlignment(ColAlignements[col], wx.ALIGN_CENTRE) lbessard@205: grid.SetColAttr(col, attr) lbessard@205: grid.SetColSize(col, ColSizes[col]) lbessard@205: lbessard@205: typelist = None lbessard@205: maplist = None lbessard@205: for row in range(self.GetNumberRows()): lbessard@205: editors = self.editors[row] lbessard@205: for col in range(self.GetNumberCols()): lbessard@205: editor = None lbessard@205: renderer = None lbessard@205: lbessard@205: colname = self.GetColLabelValue(col) lbessard@205: editortype = editors[colname] lbessard@205: if editortype and self.Editable: lbessard@205: grid.SetReadOnly(row, col, False) lbessard@205: if editortype == "string": lbessard@254: editor = wx.grid.GridCellTextEditor() lbessard@254: renderer = wx.grid.GridCellStringRenderer() lbessard@205: if colname == "value" and "length" in editors: lbessard@205: editor.SetParameters(editors["length"]) lbessard@205: elif editortype == "number": lbessard@254: editor = wx.grid.GridCellNumberEditor() lbessard@254: renderer = wx.grid.GridCellNumberRenderer() lbessard@205: if colname == "value" and "min" in editors and "max" in editors: lbessard@205: editor.SetParameters("%s,%s"%(editors["min"],editors["max"])) lbessard@205: elif editortype == "real": lbessard@254: editor = wx.grid.GridCellFloatEditor() lbessard@254: renderer = wx.grid.GridCellFloatRenderer() lbessard@205: if colname == "value" and "min" in editors and "max" in editors: lbessard@205: editor.SetParameters("%s,%s"%(editors["min"],editors["max"])) lbessard@205: elif editortype == "bool": lbessard@254: editor = wx.grid.GridCellChoiceEditor() lbessard@205: editor.SetParameters(BoolList) lbessard@205: elif editortype == "access": lbessard@254: editor = wx.grid.GridCellChoiceEditor() lbessard@205: editor.SetParameters(AccessList) lbessard@205: elif editortype == "raccess": lbessard@254: editor = wx.grid.GridCellChoiceEditor() lbessard@205: editor.SetParameters(RAccessList) lbessard@205: elif editortype == "option": lbessard@254: editor = wx.grid.GridCellChoiceEditor() lbessard@205: editor.SetParameters(OptionList) lbessard@205: elif editortype == "type": lbessard@254: editor = wx.grid.GridCellChoiceEditor() lbessard@205: if typelist == None: lbessard@205: typelist = self.Parent.Manager.GetCurrentTypeList() lbessard@205: editor.SetParameters(typelist) lbessard@205: elif editortype == "map": lbessard@254: editor = wx.grid.GridCellChoiceEditor() lbessard@205: if maplist == None: lbessard@205: maplist = self.Parent.Manager.GetCurrentMapList() lbessard@205: editor.SetParameters(maplist) lbessard@205: elif editortype == "time": lbessard@254: editor = wx.grid.GridCellTextEditor() lbessard@254: renderer = wx.grid.GridCellStringRenderer() lbessard@205: elif editortype == "domain": lbessard@254: editor = wx.grid.GridCellTextEditor() lbessard@254: renderer = wx.grid.GridCellStringRenderer() lbessard@327: elif editortype == "dcf": lbessard@327: editor = wx.grid.GridCellTextEditor() lbessard@327: renderer = wx.grid.GridCellStringRenderer() lbessard@205: else: lbessard@205: grid.SetReadOnly(row, col, True) lbessard@205: lbessard@205: grid.SetCellEditor(row, col, editor) lbessard@205: grid.SetCellRenderer(row, col, renderer) lbessard@205: lbessard@254: grid.SetCellBackgroundColour(row, col, wx.WHITE) lbessard@205: lbessard@205: def SetData(self, data): lbessard@205: self.data = data lbessard@205: lbessard@205: def SetEditors(self, editors): lbessard@205: self.editors = editors lbessard@205: lbessard@205: def GetCurrentIndex(self): lbessard@205: return self.CurrentIndex lbessard@205: lbessard@205: def SetCurrentIndex(self, index): lbessard@205: self.CurrentIndex = index lbessard@205: lbessard@205: def AppendRow(self, row_content): lbessard@205: self.data.append(row_content) lbessard@205: lbessard@205: def Empty(self): lbessard@205: self.data = [] lbessard@205: self.editors = [] lbessard@205: lbessard@254: [ID_EDITINGPANEL, ID_EDITINGPANELADDBUTTON, ID_EDITINGPANELINDEXCHOICE, lbessard@254: ID_EDITINGPANELINDEXLIST, ID_EDITINGPANELINDEXLISTPANEL, ID_EDITINGPANELPARTLIST, lbessard@254: ID_EDITINGPANELSECONDSPLITTER, ID_EDITINGPANELSUBINDEXGRID, lbessard@254: ID_EDITINGPANELSUBINDEXGRIDPANEL, ID_EDITINGPANELCALLBACKCHECK, lbessard@205: ] = [wx.NewId() for _init_ctrls in range(10)] lbessard@205: lbessard@254: [ID_EDITINGPANELINDEXLISTMENUITEMS0, ID_EDITINGPANELINDEXLISTMENUITEMS1, lbessard@254: ID_EDITINGPANELINDEXLISTMENUITEMS2, lbessard@205: ] = [wx.NewId() for _init_coll_IndexListMenu_Items in range(3)] lbessard@205: lbessard@254: [ID_EDITINGPANELMENU1ITEMS0, ID_EDITINGPANELMENU1ITEMS1, lbessard@327: ID_EDITINGPANELMENU1ITEMS3, ID_EDITINGPANELMENU1ITEMS4, lbessard@327: ] = [wx.NewId() for _init_coll_SubindexGridMenu_Items in range(4)] lbessard@205: lbessard@205: class EditingPanel(wx.SplitterWindow): lbessard@205: def _init_coll_AddToListSizer_Items(self, parent): lbessard@205: parent.AddWindow(self.AddButton, 0, border=0, flag=0) lbessard@254: parent.AddWindow(self.IndexChoice, 0, border=0, flag=wx.GROW) lbessard@205: lbessard@205: def _init_coll_SubindexGridSizer_Items(self, parent): lbessard@205: parent.AddWindow(self.CallbackCheck, 0, border=0, flag=0) lbessard@254: parent.AddWindow(self.SubindexGrid, 0, border=0, flag=wx.GROW) lbessard@205: lbessard@205: def _init_coll_IndexListSizer_Items(self, parent): lbessard@254: parent.AddWindow(self.IndexList, 0, border=0, flag=wx.GROW) lbessard@254: parent.AddSizer(self.AddToListSizer, 0, border=0, flag=wx.GROW) lbessard@205: lbessard@205: def _init_coll_AddToListSizer_Growables(self, parent): lbessard@205: parent.AddGrowableCol(1) lbessard@205: lbessard@205: def _init_coll_SubindexGridSizer_Growables(self, parent): lbessard@205: parent.AddGrowableCol(0) lbessard@205: parent.AddGrowableRow(1) lbessard@205: lbessard@205: def _init_coll_IndexListSizer_Growables(self, parent): lbessard@205: parent.AddGrowableCol(0) lbessard@205: parent.AddGrowableRow(0) lbessard@205: lbessard@205: def _init_coll_SubindexGridMenu_Items(self, parent): lbessard@254: parent.Append(help='', id=ID_EDITINGPANELMENU1ITEMS0, lbessard@299: kind=wx.ITEM_NORMAL, text='Add subindexes') lbessard@254: parent.Append(help='', id=ID_EDITINGPANELMENU1ITEMS1, lbessard@299: kind=wx.ITEM_NORMAL, text='Delete subindexes') lbessard@299: parent.AppendSeparator() lbessard@299: parent.Append(help='', id=ID_EDITINGPANELMENU1ITEMS3, lbessard@299: kind=wx.ITEM_NORMAL, text='Default value') lbessard@327: if not self.Editable: lbessard@327: parent.Append(help='', id=ID_EDITINGPANELMENU1ITEMS4, lbessard@327: kind=wx.ITEM_NORMAL, text='Add to DCF') lbessard@205: self.Bind(wx.EVT_MENU, self.OnAddSubindexMenu, lbessard@254: id=ID_EDITINGPANELMENU1ITEMS0) lbessard@205: self.Bind(wx.EVT_MENU, self.OnDeleteSubindexMenu, lbessard@254: id=ID_EDITINGPANELMENU1ITEMS1) lbessard@299: self.Bind(wx.EVT_MENU, self.OnDefaultValueSubindexMenu, lbessard@299: id=ID_EDITINGPANELMENU1ITEMS3) lbessard@327: if not self.Editable: lbessard@327: self.Bind(wx.EVT_MENU, self.OnAddToDCFSubindexMenu, lbessard@327: id=ID_EDITINGPANELMENU1ITEMS4) lbessard@205: lbessard@205: def _init_coll_IndexListMenu_Items(self, parent): lbessard@254: parent.Append(help='', id=ID_EDITINGPANELINDEXLISTMENUITEMS0, lbessard@205: kind=wx.ITEM_NORMAL, text='Rename') lbessard@254: parent.Append(help='', id=ID_EDITINGPANELINDEXLISTMENUITEMS2, lbessard@205: kind=wx.ITEM_NORMAL, text='Modify') lbessard@254: parent.Append(help='', id=ID_EDITINGPANELINDEXLISTMENUITEMS1, lbessard@205: kind=wx.ITEM_NORMAL, text='Delete') lbessard@205: self.Bind(wx.EVT_MENU, self.OnRenameIndexMenu, lbessard@254: id=ID_EDITINGPANELINDEXLISTMENUITEMS0) lbessard@205: self.Bind(wx.EVT_MENU, self.OnDeleteIndexMenu, lbessard@254: id=ID_EDITINGPANELINDEXLISTMENUITEMS1) lbessard@205: self.Bind(wx.EVT_MENU, self.OnModifyIndexMenu, lbessard@254: id=ID_EDITINGPANELINDEXLISTMENUITEMS2) lbessard@205: lbessard@205: def _init_utils(self): lbessard@205: self.IndexListMenu = wx.Menu(title='') lbessard@205: self.SubindexGridMenu = wx.Menu(title='') lbessard@205: lbessard@205: self._init_coll_IndexListMenu_Items(self.IndexListMenu) lbessard@205: self._init_coll_SubindexGridMenu_Items(self.SubindexGridMenu) lbessard@205: lbessard@205: def _init_sizers(self): lbessard@205: self.IndexListSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) lbessard@205: self.SubindexGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) lbessard@205: self.AddToListSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0) lbessard@205: lbessard@205: self._init_coll_IndexListSizer_Growables(self.IndexListSizer) lbessard@205: self._init_coll_IndexListSizer_Items(self.IndexListSizer) lbessard@205: self._init_coll_SubindexGridSizer_Growables(self.SubindexGridSizer) lbessard@205: self._init_coll_SubindexGridSizer_Items(self.SubindexGridSizer) lbessard@205: self._init_coll_AddToListSizer_Growables(self.AddToListSizer) lbessard@205: self._init_coll_AddToListSizer_Items(self.AddToListSizer) lbessard@205: lbessard@205: self.SubindexGridPanel.SetSizer(self.SubindexGridSizer) lbessard@205: self.IndexListPanel.SetSizer(self.IndexListSizer) lbessard@205: lbessard@205: def _init_ctrls(self, prnt): lbessard@254: wx.SplitterWindow.__init__(self, id=ID_EDITINGPANEL, lbessard@205: name='MainSplitter', parent=prnt, point=wx.Point(0, 0), lbessard@205: size=wx.Size(-1, -1), style=wx.SP_3D) lbessard@205: self._init_utils() lbessard@205: self.SetNeedUpdating(True) lbessard@205: self.SetMinimumPaneSize(1) lbessard@205: lbessard@254: self.PartList = wx.ListBox(choices=[], id=ID_EDITINGPANELPARTLIST, lbessard@205: name='PartList', parent=self, pos=wx.Point(0, 0), lbessard@205: size=wx.Size(-1, -1), style=0) lbessard@205: self.PartList.Bind(wx.EVT_LISTBOX, self.OnPartListBoxClick, lbessard@254: id=ID_EDITINGPANELPARTLIST) lbessard@254: lbessard@254: self.SecondSplitter = wx.SplitterWindow(id=ID_EDITINGPANELSECONDSPLITTER, lbessard@254: name='SecondSplitter', parent=self, point=wx.Point(0, 0), lbessard@254: size=wx.Size(-1, -1), style=wx.SP_3D) lbessard@205: self.SecondSplitter.SetMinimumPaneSize(1) lbessard@205: self.SplitHorizontally(self.PartList, self.SecondSplitter, lbessard@205: 110) lbessard@205: lbessard@254: self.SubindexGridPanel = wx.Panel(id=ID_EDITINGPANELSUBINDEXGRIDPANEL, lbessard@254: name='SubindexGridPanel', parent=self.SecondSplitter, lbessard@254: pos=wx.Point(0, 0), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) lbessard@254: lbessard@254: self.IndexListPanel = wx.Panel(id=ID_EDITINGPANELINDEXLISTPANEL, lbessard@254: name='IndexListPanel', parent=self.SecondSplitter, lbessard@254: pos=wx.Point(0, 0), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) lbessard@205: self.SecondSplitter.SplitVertically(self.IndexListPanel, lbessard@205: self.SubindexGridPanel, 280) lbessard@205: lbessard@254: self.SubindexGrid = wx.grid.Grid(id=ID_EDITINGPANELSUBINDEXGRID, lbessard@205: name='SubindexGrid', parent=self.SubindexGridPanel, pos=wx.Point(0, lbessard@205: 0), size=wx.Size(-1, -1), style=0) lbessard@205: self.SubindexGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False, lbessard@205: 'Sans')) lbessard@205: self.SubindexGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL, lbessard@205: False, 'Sans')) lbessard@205: self.SubindexGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, lbessard@205: self.OnSubindexGridCellChange) lbessard@205: self.SubindexGrid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, lbessard@205: self.OnSubindexGridRightClick) lbessard@205: self.SubindexGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL, lbessard@205: self.OnSubindexGridSelectCell) lbessard@324: self.SubindexGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, lbessard@324: self.OnSubindexGridCellLeftClick) lbessard@327: self.SubindexGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, lbessard@327: self.OnSubindexGridEditorShown) lbessard@205: lbessard@254: self.CallbackCheck = wx.CheckBox(id=ID_EDITINGPANELCALLBACKCHECK, lbessard@205: label='Have Callbacks', name='CallbackCheck', lbessard@205: parent=self.SubindexGridPanel, pos=wx.Point(0, 0), size=wx.Size(152, lbessard@205: 24), style=0) lbessard@205: self.CallbackCheck.Bind(wx.EVT_CHECKBOX, self.OnCallbackCheck, lbessard@254: id=ID_EDITINGPANELCALLBACKCHECK) lbessard@254: lbessard@254: self.IndexList = wx.ListBox(choices=[], id=ID_EDITINGPANELINDEXLIST, lbessard@205: name='IndexList', parent=self.IndexListPanel, pos=wx.Point(0, 0), lbessard@205: size=wx.Size(-1, -1), style=0) lbessard@205: self.IndexList.Bind(wx.EVT_LISTBOX, self.OnIndexListClick, lbessard@254: id=ID_EDITINGPANELINDEXLIST) lbessard@205: self.IndexList.Bind(wx.EVT_RIGHT_UP, self.OnIndexListRightUp) lbessard@205: lbessard@254: self.AddButton = wx.Button(id=ID_EDITINGPANELADDBUTTON, label='Add', lbessard@205: name='AddButton', parent=self.IndexListPanel, pos=wx.Point(0, 0), lbessard@205: size=wx.Size(50, 30), style=0) lbessard@205: self.AddButton.Bind(wx.EVT_BUTTON, self.OnAddButtonClick, lbessard@254: id=ID_EDITINGPANELADDBUTTON) lbessard@254: lbessard@254: self.IndexChoice = wx.Choice(choices=[], id=ID_EDITINGPANELINDEXCHOICE, lbessard@205: name='IndexChoice', parent=self.IndexListPanel, pos=wx.Point(50, lbessard@205: 0), size=wx.Size(-1, 30), style=0) lbessard@205: lbessard@205: self._init_sizers() lbessard@205: lbessard@299: def __init__(self, parent, window, manager, editable = True): lbessard@327: self.Editable = editable lbessard@299: self._init_ctrls(parent) lbessard@299: self.ParentWindow = window lbessard@205: self.Manager = manager lbessard@205: self.ListIndex = [] lbessard@205: self.ChoiceIndex = [] lbessard@205: self.FirstCall = False lbessard@205: self.Index = None lbessard@205: lbessard@205: for values in DictionaryOrganisation: lbessard@299: text = " 0x%04X-0x%04X %s"%(values["minIndex"], values["maxIndex"], values["name"]) lbessard@205: self.PartList.Append(text) lbessard@205: self.Table = SubindexTable(self, [], [], ["subindex", "name", "type", "value", "access", "save", "comment"]) lbessard@205: self.SubindexGrid.SetTable(self.Table) lbessard@205: self.SubindexGrid.SetRowLabelSize(0) lbessard@205: self.CallbackCheck.Disable() lbessard@205: self.Table.ResetView(self.SubindexGrid) lbessard@205: lbessard@205: if not self.Editable: lbessard@205: self.AddButton.Disable() lbessard@205: self.IndexChoice.Disable() lbessard@205: self.CallbackCheck.Disable() lbessard@205: self.Table.Disable() lbessard@205: lbessard@205: def GetIndex(self): lbessard@205: return self.Index lbessard@205: lbessard@205: def SetIndex(self, index): lbessard@205: self.Index = index lbessard@205: lbessard@205: def GetSelection(self): lbessard@205: selected = self.IndexList.GetSelection() lbessard@254: if selected != wx.NOT_FOUND: lbessard@205: index = self.ListIndex[selected] lbessard@205: subIndex = self.SubindexGrid.GetGridCursorRow() lbessard@205: return index, subIndex lbessard@205: return None lbessard@205: lbessard@242: def OnSubindexGridCellLeftClick(self, event): lbessard@324: if not self.ParentWindow.ModeSolo: lbessard@324: col = event.GetCol() lbessard@324: if not self.Editable and col == 0: lbessard@324: selected = self.IndexList.GetSelection() lbessard@324: if selected != wx.NOT_FOUND: lbessard@324: index = self.ListIndex[selected] lbessard@324: subindex = event.GetRow() lbessard@324: entry_infos = self.Manager.GetEntryInfos(index) lbessard@324: if not entry_infos["struct"] & OD_MultipleSubindexes or subindex != 0: lbessard@324: subentry_infos = self.Manager.GetSubentryInfos(index, subindex) lbessard@324: typeinfos = self.Manager.GetEntryInfos(subentry_infos["type"]) lbessard@324: if subentry_infos["pdo"] and typeinfos: lbessard@324: bus_id = '.'.join(map(str, self.ParentWindow.GetBusId())) lbessard@324: node_id = self.ParentWindow.GetCurrentNodeId() lbessard@324: size = typeinfos["size"] lbessard@324: data = wx.TextDataObject(str(("%s%s.%d.%d.%d"%(SizeConversion[size], bus_id, node_id, index, subindex), "location"))) lbessard@324: dragSource = wx.DropSource(self.SubindexGrid) lbessard@324: dragSource.SetData(data) lbessard@324: dragSource.DoDragDrop() lbessard@242: event.Skip() lbessard@242: lbessard@205: def OnAddButtonClick(self, event): lbessard@205: if self.Editable: lbessard@205: self.SubindexGrid.SetGridCursor(0, 0) lbessard@205: selected = self.IndexChoice.GetStringSelection() lbessard@205: if selected != "": lbessard@205: if selected == "User Type": lbessard@271: self.ParentWindow.AddUserType() lbessard@205: elif selected == "SDO Server": lbessard@205: self.Manager.AddSDOServerToCurrent() lbessard@205: elif selected == "SDO Client": lbessard@205: self.Manager.AddSDOClientToCurrent() lbessard@205: elif selected == "PDO Receive": lbessard@205: self.Manager.AddPDOReceiveToCurrent() lbessard@205: elif selected == "PDO Transmit": lbessard@205: self.Manager.AddPDOTransmitToCurrent() lbessard@205: elif selected == "Map Variable": lbessard@271: self.ParentWindow.AddMapVariable() lbessard@205: elif selected in [menu for menu, indexes in self.Manager.GetCurrentSpecificMenu()]: lbessard@205: self.Manager.AddSpecificEntryToCurrent(selected) lbessard@205: else: lbessard@205: index = self.ChoiceIndex[self.IndexChoice.GetSelection()] lbessard@205: self.Manager.ManageEntriesOfCurrent([index], []) lbessard@271: self.ParentWindow.RefreshBufferState() lbessard@205: self.RefreshIndexList() lbessard@205: event.Skip() lbessard@205: lbessard@205: def OnPartListBoxClick(self, event): lbessard@205: self.SubindexGrid.SetGridCursor(0, 0) lbessard@205: self.RefreshIndexList() lbessard@205: event.Skip() lbessard@205: lbessard@205: def OnIndexListClick(self, event): lbessard@205: self.SubindexGrid.SetGridCursor(0, 0) lbessard@205: self.RefreshTable() lbessard@205: event.Skip() lbessard@205: lbessard@205: def OnSubindexGridSelectCell(self, event): lbessard@271: wx.CallAfter(self.ParentWindow.RefreshStatusBar) lbessard@205: event.Skip() lbessard@205: lbessard@205: #------------------------------------------------------------------------------- lbessard@205: # Refresh Functions lbessard@205: #------------------------------------------------------------------------------- lbessard@205: lbessard@205: def RefreshIndexList(self): lbessard@205: selected = self.IndexList.GetSelection() lbessard@205: choice = self.IndexChoice.GetStringSelection() lbessard@205: choiceindex = self.IndexChoice.GetSelection() lbessard@254: if selected != wx.NOT_FOUND: lbessard@205: selectedindex = self.ListIndex[selected] lbessard@205: self.IndexList.Clear() lbessard@205: self.IndexChoice.Clear() lbessard@205: i = self.PartList.GetSelection() lbessard@205: if i < len(DictionaryOrganisation): lbessard@205: values = DictionaryOrganisation[i] lbessard@205: self.ListIndex = [] lbessard@205: for name, index in self.Manager.GetCurrentValidIndexes(values["minIndex"], values["maxIndex"]): lbessard@205: self.IndexList.Append("0x%04X %s"%(index, name)) lbessard@205: self.ListIndex.append(index) lbessard@205: if self.Editable: lbessard@205: self.ChoiceIndex = [] lbessard@205: if i == 0: lbessard@205: self.IndexChoice.Append("User Type") lbessard@205: self.IndexChoice.SetStringSelection("User Type") lbessard@205: elif i == 2: lbessard@205: self.IndexChoice.Append("SDO Server") lbessard@205: self.IndexChoice.Append("SDO Client") lbessard@254: if choiceindex != wx.NOT_FOUND and choice == self.IndexChoice.GetString(choiceindex): lbessard@205: self.IndexChoice.SetStringSelection(choice) lbessard@205: elif i in (3, 4): lbessard@205: self.IndexChoice.Append("PDO Receive") lbessard@205: self.IndexChoice.SetStringSelection("PDO Receive") lbessard@205: elif i in (5, 6): lbessard@205: self.IndexChoice.Append("PDO Transmit") lbessard@205: self.IndexChoice.SetStringSelection("PDO Transmit") lbessard@205: elif i == 8: lbessard@205: self.IndexChoice.Append("Map Variable") lbessard@205: self.IndexChoice.SetStringSelection("Map Variable") lbessard@205: else: lbessard@205: for name, index in self.Manager.GetCurrentValidChoices(values["minIndex"], values["maxIndex"]): lbessard@205: if index: lbessard@205: self.IndexChoice.Append("0x%04X %s"%(index, name)) lbessard@205: else: lbessard@205: self.IndexChoice.Append(name) lbessard@205: self.ChoiceIndex.append(index) lbessard@312: if choiceindex != wx.NOT_FOUND and choiceindex < self.IndexChoice.GetCount() and choice == self.IndexChoice.GetString(choiceindex): lbessard@205: self.IndexChoice.SetStringSelection(choice) lbessard@205: if self.Editable: lbessard@205: self.IndexChoice.Enable(self.IndexChoice.GetCount() != 0) lbessard@205: self.AddButton.Enable(self.IndexChoice.GetCount() != 0) lbessard@254: if selected == wx.NOT_FOUND or selected >= len(self.ListIndex) or selectedindex != self.ListIndex[selected]: lbessard@205: self.Table.Empty() lbessard@205: self.CallbackCheck.SetValue(False) lbessard@205: self.CallbackCheck.Disable() lbessard@205: self.Table.ResetView(self.SubindexGrid) lbessard@271: self.ParentWindow.RefreshStatusBar() lbessard@205: else: lbessard@205: self.IndexList.SetSelection(selected) lbessard@205: self.RefreshTable() lbessard@205: lbessard@205: def RefreshTable(self): lbessard@205: selected = self.IndexList.GetSelection() lbessard@254: if selected != wx.NOT_FOUND: lbessard@205: index = self.ListIndex[selected] lbessard@205: if index > 0x260 and self.Editable: lbessard@205: self.CallbackCheck.Enable() lbessard@205: self.CallbackCheck.SetValue(self.Manager.HasCurrentEntryCallbacks(index)) lbessard@205: result = self.Manager.GetCurrentEntryValues(index) lbessard@205: if result != None: lbessard@205: self.Table.SetCurrentIndex(index) lbessard@205: data, editors = result lbessard@205: self.Table.SetData(data) lbessard@205: self.Table.SetEditors(editors) lbessard@205: self.Table.ResetView(self.SubindexGrid) lbessard@271: self.ParentWindow.RefreshStatusBar() lbessard@205: lbessard@205: #------------------------------------------------------------------------------- lbessard@205: # Editing Table value function lbessard@205: #------------------------------------------------------------------------------- lbessard@205: lbessard@327: def OnSubindexGridEditorShown(self, event): lbessard@327: row, col = event.GetRow(), event.GetCol() lbessard@327: if self.Table.GetEditor(row, col) == "dcf": lbessard@327: wx.CallAfter(self.ShowDCFEntryDialog, row, col) lbessard@327: event.Veto() lbessard@327: else: lbessard@327: event.Skip() lbessard@327: lbessard@327: def ShowDCFEntryDialog(self, row, col): lbessard@327: if self.Editable: lbessard@327: selected = self.IndexList.GetSelection() lbessard@327: if selected != wx.NOT_FOUND: lbessard@327: index = self.ListIndex[selected] lbessard@327: if self.Manager.IsCurrentEntry(index): lbessard@327: dialog = DCFEntryValuesDialog(self) lbessard@327: dialog.SetValues(self.Table.GetValue(row, col).decode("hex_codec")) lbessard@327: if dialog.ShowModal() == wx.ID_OK: lbessard@327: value = dialog.GetValues() lbessard@327: self.Manager.SetCurrentEntry(index, row, value, "value", "dcf") lbessard@327: self.ParentWindow.RefreshBufferState() lbessard@327: wx.CallAfter(self.RefreshTable) lbessard@327: lbessard@205: def OnSubindexGridCellChange(self, event): lbessard@205: if self.Editable: lbessard@205: index = self.Table.GetCurrentIndex() lbessard@205: subIndex = event.GetRow() lbessard@205: col = event.GetCol() lbessard@205: name = self.Table.GetColLabelValue(col) lbessard@205: value = self.Table.GetValue(subIndex, col) lbessard@205: editor = self.Table.GetEditor(subIndex, col) lbessard@205: self.Manager.SetCurrentEntry(index, subIndex, value, name, editor) lbessard@271: self.ParentWindow.RefreshBufferState() lbessard@254: wx.CallAfter(self.RefreshTable) lbessard@205: event.Skip() lbessard@205: lbessard@205: def OnCallbackCheck(self, event): lbessard@205: if self.Editable: lbessard@205: index = self.Table.GetCurrentIndex() lbessard@205: self.Manager.SetCurrentEntryCallbacks(index, self.CallbackCheck.GetValue()) lbessard@271: self.ParentWindow.RefreshBufferState() lbessard@254: wx.CallAfter(self.RefreshTable) lbessard@205: event.Skip() lbessard@205: lbessard@205: #------------------------------------------------------------------------------- lbessard@205: # Contextual Menu functions lbessard@205: #------------------------------------------------------------------------------- lbessard@205: lbessard@205: def OnIndexListRightUp(self, event): lbessard@205: if self.Editable: lbessard@205: if not self.FirstCall: lbessard@205: self.FirstCall = True lbessard@205: selected = self.IndexList.GetSelection() lbessard@254: if selected != wx.NOT_FOUND: lbessard@205: index = self.ListIndex[selected] lbessard@205: if index < 0x260: lbessard@205: self.IndexListMenu.FindItemByPosition(0).Enable(False) lbessard@205: self.IndexListMenu.FindItemByPosition(1).Enable(True) lbessard@205: self.PopupMenu(self.IndexListMenu) lbessard@273: elif 0x1000 <= index <= 0x1FFF: lbessard@205: self.IndexListMenu.FindItemByPosition(0).Enable(False) lbessard@205: self.IndexListMenu.FindItemByPosition(1).Enable(False) lbessard@205: self.PopupMenu(self.IndexListMenu) lbessard@205: elif 0x2000 <= index <= 0x5FFF: lbessard@205: self.IndexListMenu.FindItemByPosition(0).Enable(True) lbessard@205: self.IndexListMenu.FindItemByPosition(1).Enable(False) lbessard@205: self.PopupMenu(self.IndexListMenu) lbessard@205: elif index >= 0x6000: lbessard@205: self.IndexListMenu.FindItemByPosition(0).Enable(False) lbessard@205: self.IndexListMenu.FindItemByPosition(1).Enable(False) lbessard@205: self.PopupMenu(self.IndexListMenu) lbessard@205: else: lbessard@205: self.FirstCall = False lbessard@205: event.Skip() lbessard@205: lbessard@205: def OnSubindexGridRightClick(self, event): lbessard@299: self.SubindexGrid.SetGridCursor(event.GetRow(), event.GetCol()) lbessard@205: if self.Editable: lbessard@205: selected = self.IndexList.GetSelection() lbessard@254: if selected != wx.NOT_FOUND: lbessard@205: index = self.ListIndex[selected] lbessard@205: if self.Manager.IsCurrentEntry(index): lbessard@299: showpopup = False lbessard@205: infos = self.Manager.GetEntryInfos(index) lbessard@310: if 0x2000 <= index <= 0x5FFF and infos["struct"] & OD_MultipleSubindexes or infos["struct"] & OD_IdenticalSubindexes: lbessard@299: showpopup = True lbessard@299: self.SubindexGridMenu.FindItemByPosition(0).Enable(True) lbessard@299: self.SubindexGridMenu.FindItemByPosition(1).Enable(True) lbessard@299: else: lbessard@299: self.SubindexGridMenu.FindItemByPosition(0).Enable(False) lbessard@299: self.SubindexGridMenu.FindItemByPosition(1).Enable(False) lbessard@299: if self.Table.GetColLabelValue(event.GetCol()) == "value": lbessard@299: showpopup = True lbessard@299: self.SubindexGridMenu.FindItemByPosition(3).Enable(True) lbessard@299: else: lbessard@299: self.SubindexGridMenu.FindItemByPosition(3).Enable(False) lbessard@299: if showpopup: lbessard@242: self.PopupMenu(self.SubindexGridMenu) lbessard@327: elif self.Table.GetColLabelValue(event.GetCol()) == "value": lbessard@327: selected = self.IndexList.GetSelection() lbessard@327: if selected != wx.NOT_FOUND: lbessard@327: index = self.ListIndex[selected] lbessard@327: if self.Manager.IsCurrentEntry(index): lbessard@327: infos = self.Manager.GetEntryInfos(index) lbessard@327: if not infos["struct"] & OD_MultipleSubindexes or event.GetRow() > 0: lbessard@327: self.SubindexGridMenu.FindItemByPosition(0).Enable(False) lbessard@327: self.SubindexGridMenu.FindItemByPosition(1).Enable(False) lbessard@327: self.SubindexGridMenu.FindItemByPosition(3).Enable(False) lbessard@327: self.SubindexGridMenu.FindItemByPosition(4).Enable(True) lbessard@327: self.PopupMenu(self.SubindexGridMenu) lbessard@327: event.Skip() lbessard@327: lbessard@327: def OnAddToDCFSubindexMenu(self, event): lbessard@327: if not self.Editable: lbessard@327: selected = self.IndexList.GetSelection() lbessard@327: if selected != wx.NOT_FOUND: lbessard@327: index = self.ListIndex[selected] lbessard@327: subindex = self.SubindexGrid.GetGridCursorRow() lbessard@327: entry_infos = self.Manager.GetEntryInfos(index) lbessard@327: if not entry_infos["struct"] & OD_MultipleSubindexes or subindex != 0: lbessard@327: subentry_infos = self.Manager.GetSubentryInfos(index, subindex) lbessard@327: typeinfos = self.Manager.GetEntryInfos(subentry_infos["type"]) lbessard@327: if typeinfos: lbessard@327: node_id = self.ParentWindow.GetCurrentNodeId() lbessard@336: value = self.Table.GetValueByName(subindex, "value") lbessard@336: if value == "True": lbessard@340: value = 1 lbessard@340: elif value == "False": lbessard@336: value = 0 lbessard@336: elif value.isdigit(): lbessard@336: value = int(value) lbessard@336: elif value.startswith("0x"): lbessard@336: value = int(value, 16) lbessard@336: else: lbessard@336: value = int(value.encode("hex_codec"), 16) lbessard@336: self.Manager.AddToMasterDCF(node_id, index, subindex, max(1, typeinfos["size"] / 8), value) lbessard@327: self.ParentWindow.OpenMasterDCFDialog(node_id) lbessard@327: lbessard@336: def OpenDCFDialog(self, node_id): lbessard@327: self.PartList.SetSelection(7) lbessard@327: self.RefreshIndexList() lbessard@327: self.IndexList.SetSelection(self.ListIndex.index(0x1F22)) lbessard@327: self.RefreshTable() lbessard@327: self.SubindexGrid.SetGridCursor(node_id, 3) lbessard@327: self.ShowDCFEntryDialog(node_id, 3) lbessard@205: lbessard@205: def OnRenameIndexMenu(self, event): lbessard@205: if self.Editable: lbessard@205: selected = self.IndexList.GetSelection() lbessard@254: if selected != wx.NOT_FOUND: lbessard@205: index = self.ListIndex[selected] lbessard@205: if self.Manager.IsCurrentEntry(index): lbessard@205: infos = self.Manager.GetEntryInfos(index) lbessard@254: dialog = wx.TextEntryDialog(self, "Give a new name for index 0x%04X"%index, lbessard@254: "Rename an index", infos["name"], wx.OK|wx.CANCEL) lbessard@254: if dialog.ShowModal() == wx.ID_OK: lbessard@205: self.Manager.SetCurrentEntryName(index, dialog.GetValue()) lbessard@271: self.ParentWindow.RefreshBufferState() lbessard@205: self.RefreshIndexList() lbessard@205: dialog.Destroy() lbessard@205: event.Skip() lbessard@205: lbessard@205: def OnModifyIndexMenu(self, event): lbessard@205: if self.Editable: lbessard@205: selected = self.IndexList.GetSelection() lbessard@254: if selected != wx.NOT_FOUND: lbessard@205: index = self.ListIndex[selected] lbessard@205: if self.Manager.IsCurrentEntry(index) and index < 0x260: lbessard@205: values, valuetype = self.Manager.GetCustomisedTypeValues(index) lbessard@205: dialog = UserTypeDialog(self) lbessard@205: dialog.SetTypeList(self.Manager.GetCustomisableTypes(), values[1]) lbessard@205: if valuetype == 0: lbessard@205: dialog.SetValues(min = values[2], max = values[3]) lbessard@205: elif valuetype == 1: lbessard@205: dialog.SetValues(length = values[2]) lbessard@254: if dialog.ShowModal() == wx.ID_OK: lbessard@205: type, min, max, length = dialog.GetValues() lbessard@205: self.Manager.SetCurrentUserType(index, type, min, max, length) lbessard@271: self.ParentWindow.RefreshBufferState() lbessard@205: self.RefreshIndexList() lbessard@205: event.Skip() lbessard@205: lbessard@205: def OnDeleteIndexMenu(self, event): lbessard@205: if self.Editable: lbessard@205: selected = self.IndexList.GetSelection() lbessard@254: if selected != wx.NOT_FOUND: lbessard@205: index = self.ListIndex[selected] lbessard@205: if self.Manager.IsCurrentEntry(index): lbessard@205: self.Manager.ManageEntriesOfCurrent([],[index]) lbessard@271: self.ParentWindow.RefreshBufferState() lbessard@205: self.RefreshIndexList() lbessard@205: event.Skip() lbessard@205: lbessard@205: def OnAddSubindexMenu(self, event): lbessard@205: if self.Editable: lbessard@205: selected = self.IndexList.GetSelection() lbessard@254: if selected != wx.NOT_FOUND: lbessard@205: index = self.ListIndex[selected] lbessard@205: if self.Manager.IsCurrentEntry(index): lbessard@254: dialog = wx.TextEntryDialog(self, "Number of subindexes to add:", lbessard@254: "Add subindexes", "1", wx.OK|wx.CANCEL) lbessard@254: if dialog.ShowModal() == wx.ID_OK: lbessard@205: try: lbessard@205: number = int(dialog.GetValue()) lbessard@205: self.Manager.AddSubentriesToCurrent(index, number) lbessard@271: self.ParentWindow.RefreshBufferState() lbessard@205: self.RefreshIndexList() lbessard@205: except: lbessard@254: message = wx.MessageDialog(self, "An integer is required!", "ERROR", wx.OK|wx.ICON_ERROR) lbessard@205: message.ShowModal() lbessard@205: message.Destroy() lbessard@205: dialog.Destroy() lbessard@205: event.Skip() lbessard@205: lbessard@205: def OnDeleteSubindexMenu(self, event): lbessard@205: if self.Editable: lbessard@205: selected = self.IndexList.GetSelection() lbessard@254: if selected != wx.NOT_FOUND: lbessard@205: index = self.ListIndex[selected] lbessard@205: if self.Manager.IsCurrentEntry(index): lbessard@254: dialog = wx.TextEntryDialog(self, "Number of subindexes to delete:", lbessard@254: "Delete subindexes", "1", wx.OK|wx.CANCEL) lbessard@254: if dialog.ShowModal() == wx.ID_OK: lbessard@205: try: lbessard@205: number = int(dialog.GetValue()) lbessard@205: self.Manager.RemoveSubentriesFromCurrent(index, number) lbessard@271: self.ParentWindow.RefreshBufferState() lbessard@205: self.RefreshIndexList() lbessard@205: except: lbessard@254: message = wx.MessageDialog(self, "An integer is required!", "ERROR", wx.OK|wx.ICON_ERROR) lbessard@205: message.ShowModal() lbessard@205: message.Destroy() lbessard@205: dialog.Destroy() lbessard@205: event.Skip() lbessard@205: lbessard@299: def OnDefaultValueSubindexMenu(self, event): lbessard@299: if self.Editable: lbessard@299: selected = self.IndexList.GetSelection() lbessard@299: if selected != wx.NOT_FOUND: lbessard@299: index = self.ListIndex[selected] lbessard@299: if self.Manager.IsCurrentEntry(index): lbessard@299: row = self.SubindexGrid.GetGridCursorRow() lbessard@299: self.Manager.SetCurrentEntryToDefault(index, row) lbessard@299: self.ParentWindow.RefreshBufferState() lbessard@299: self.RefreshIndexList() lbessard@327: event.Skip()