diff -r 4a36f2ec8967 -r c6ef6d92ce16 DataTypeEditor.py --- a/DataTypeEditor.py Mon Dec 15 09:45:16 2008 +0100 +++ b/DataTypeEditor.py Fri Dec 19 15:07:54 2008 +0100 @@ -25,12 +25,183 @@ import wx import wx.grid import wx.gizmos -from plcopen.structures import IEC_KEYWORDS +from plcopen.structures import IEC_KEYWORDS, TestIdentifier import re DIMENSION_MODEL = re.compile("([0-9]+)\.\.([0-9]+)$") +def AppendMenu(parent, help, id, kind, text): + if wx.VERSION >= (2, 6, 0): + parent.Append(help=help, id=id, kind=kind, text=text) + else: + parent.Append(helpString=help, id=id, kind=kind, item=text) + +#------------------------------------------------------------------------------- +# Structure Elements Table +#------------------------------------------------------------------------------- + +class ElementsTable(wx.grid.PyGridTableBase): + + """ + A custom wx.grid.Grid Table using user supplied data + """ + def __init__(self, parent, data, colnames): + # The base class must be initialized *first* + wx.grid.PyGridTableBase.__init__(self) + self.data = data + self.old_value = None + self.colnames = colnames + self.Errors = {} + self.Parent = parent + # XXX + # we need to store the row length and collength to + # see if the table has changed size + self._rows = self.GetNumberRows() + self._cols = self.GetNumberCols() + + def GetNumberCols(self): + return len(self.colnames) + + def GetNumberRows(self): + return len(self.data) + + def GetColLabelValue(self, col): + if col < len(self.colnames): + return self.colnames[col] + + def GetRowLabelValues(self, row): + return row + + def GetValue(self, row, col): + if row < self.GetNumberRows(): + if col == 0: + return row + 1 + name = str(self.data[row].get(self.GetColLabelValue(col), "")) + return name + + def SetValue(self, row, col, value): + if col < len(self.colnames): + colname = self.GetColLabelValue(col) + if colname == "Name": + self.old_value = self.data[row][colname] + self.data[row][colname] = value + + def GetValueByName(self, row, colname): + if row < self.GetNumberRows(): + return self.data[row].get(colname) + + def SetValueByName(self, row, colname, value): + if row < self.GetNumberRows(): + self.data[row][colname] = value + + def GetOldValue(self): + return self.old_value + + def ResetView(self, grid): + """ + (wx.grid.Grid) -> Reset the grid view. Call this to + update the grid if rows and columns have been added or deleted + """ + grid.BeginBatch() + for current, new, delmsg, addmsg in [ + (self._rows, self.GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED), + (self._cols, self.GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED), + ]: + if new < current: + msg = wx.grid.GridTableMessage(self,delmsg,new,current-new) + grid.ProcessTableMessage(msg) + elif new > current: + msg = wx.grid.GridTableMessage(self,addmsg,new-current) + grid.ProcessTableMessage(msg) + self.UpdateValues(grid) + grid.EndBatch() + + self._rows = self.GetNumberRows() + self._cols = self.GetNumberCols() + # update the column rendering scheme + self._updateColAttrs(grid) + + # update the scrollbars and the displayed part of the grid + grid.AdjustScrollbars() + grid.ForceRefresh() + + def UpdateValues(self, grid): + """Update all displayed values""" + # This sends an event to the grid table to update all of the values + msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES) + grid.ProcessTableMessage(msg) + + def _updateColAttrs(self, grid): + """ + wx.grid.Grid -> update the column attributes to add the + appropriate renderer given the column name. + + Otherwise default to the default renderer. + """ + + typelist = None + accesslist = None + for row in range(self.GetNumberRows()): + for col in range(self.GetNumberCols()): + editor = None + renderer = None + colname = self.GetColLabelValue(col) + if col != 0: + grid.SetReadOnly(row, col, False) + if colname == "Name": + editor = wx.grid.GridCellTextEditor() + renderer = wx.grid.GridCellStringRenderer() + elif colname == "Initial Value": + editor = wx.grid.GridCellTextEditor() + renderer = wx.grid.GridCellStringRenderer() + elif colname == "Type": + editor = wx.grid.GridCellTextEditor() + else: + grid.SetReadOnly(row, col, True) + + grid.SetCellEditor(row, col, editor) + grid.SetCellRenderer(row, col, renderer) + + if row in self.Errors and self.Errors[row][0] == colname.lower(): + grid.SetCellBackgroundColour(row, col, wx.Colour(255, 255, 0)) + grid.SetCellTextColour(row, col, wx.RED) + grid.MakeCellVisible(row, col) + else: + grid.SetCellTextColour(row, col, wx.BLACK) + grid.SetCellBackgroundColour(row, col, wx.WHITE) + + def SetData(self, data): + self.data = data + + def GetData(self): + return self.data + + def AppendRow(self, row_content): + self.data.append(row_content) + + def RemoveRow(self, row_index): + self.data.pop(row_index) + + def MoveRow(self, idx, move): + new_idx = max(0, min(idx + move, len(self.data) - 1)) + if new_idx != idx: + self.data.insert(new_idx, self.data.pop(idx)) + return new_idx + return None + + def GetRow(self, row_index): + return self.data[row_index] + + def Empty(self): + self.data = [] + self.editors = [] + + def AddError(self, infos): + self.Errors[infos[0]] = infos[1:] + + def ClearErrors(self): + self.Errors = {} #------------------------------------------------------------------------------- # Configuration Editor class @@ -45,12 +216,16 @@ ID_DATATYPEEDITORENUMERATEDVALUES, ID_DATATYPEEDITORENUMERATEDINITIALVALUE, ID_DATATYPEEDITORARRAYPANEL, ID_DATATYPEEDITORARRAYBASETYPE, ID_DATATYPEEDITORARRAYDIMENSIONS, ID_DATATYPEEDITORARRAYINITIALVALUE, + ID_DATATYPEEDITORSTRUCTUREPANEL, ID_DATATYPEEDITORSTRUCTUREELEMENTSGRID, + ID_DATATYPEEDITORSTRUCTUREADDBUTTON, ID_DATATYPEEDITORSTRUCTUREDELETEBUTTON, + ID_DATATYPEEDITORSTRUCTUREUPBUTTON, ID_DATATYPEEDITORSTRUCTUREDOWNBUTTON, ID_DATATYPEEDITORSTATICTEXT1, ID_DATATYPEEDITORSTATICTEXT2, ID_DATATYPEEDITORSTATICTEXT3, ID_DATATYPEEDITORSTATICTEXT4, ID_DATATYPEEDITORSTATICTEXT5, ID_DATATYPEEDITORSTATICTEXT6, ID_DATATYPEEDITORSTATICTEXT7, ID_DATATYPEEDITORSTATICTEXT8, ID_DATATYPEEDITORSTATICTEXT9, ID_DATATYPEEDITORSTATICTEXT10, -] = [wx.NewId() for _init_ctrls in range(28)] + ID_DATATYPEEDITORSTATICTEXT11, +] = [wx.NewId() for _init_ctrls in range(35)] class DataTypeEditor(wx.Panel): @@ -71,6 +246,7 @@ parent.AddWindow(self.SubrangePanel, 1, border=0, flag=wx.ALL) parent.AddWindow(self.EnumeratedPanel, 1, border=0, flag=wx.GROW|wx.ALL) parent.AddWindow(self.ArrayPanel, 1, border=0, flag=wx.ALL) + parent.AddWindow(self.StructurePanel, 1, border=0, flag=wx.GROW|wx.ALL) def _init_coll_DirectlyPanelSizer_Items(self, parent): parent.AddWindow(self.staticText2, 1, border=5, flag=wx.GROW|wx.ALL) @@ -113,6 +289,21 @@ parent.AddWindow(self.staticText10, 1, border=5, flag=wx.GROW|wx.ALL) parent.AddWindow(self.ArrayInitialValue, 1, border=5, flag=wx.GROW|wx.ALL) + def _init_coll_StructurePanelSizer_Items(self, parent): + parent.AddWindow(self.staticText11, 0, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.StructureElementsGrid, 0, border=0, flag=wx.GROW) + parent.AddSizer(self.StructurePanelButtonSizer, 0, border=0, flag=wx.ALIGN_RIGHT) + + def _init_coll_StructurePanelSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_coll_StructurePanelButtonSizer_Items(self, parent): + parent.AddWindow(self.StructureAddButton, 1, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.StructureDeleteButton, 1, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.StructureUpButton, 1, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.StructureDownButton, 1, border=5, flag=wx.GROW|wx.ALL) + def _init_sizers(self): self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) self.TopSizer = wx.BoxSizer(wx.HORIZONTAL) @@ -123,7 +314,8 @@ self.ArrayPanelSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=2, vgap=0) self.ArrayPanelLeftSizer = wx.BoxSizer(wx.HORIZONTAL) self.ArrayPanelRightSizer = wx.BoxSizer(wx.HORIZONTAL) - + self.StructurePanelSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=0) + self.StructurePanelButtonSizer = wx.BoxSizer(wx.HORIZONTAL) self._init_coll_MainSizer_Items(self.MainSizer) self._init_coll_MainSizer_Growables(self.MainSizer) self._init_coll_TopSizer_Items(self.TopSizer) @@ -135,12 +327,16 @@ self._init_coll_ArrayPanelSizer_Growables(self.ArrayPanelSizer) self._init_coll_ArrayPanelLeftSizer_Items(self.ArrayPanelLeftSizer) self._init_coll_ArrayPanelRightSizer_Items(self.ArrayPanelRightSizer) + self._init_coll_StructurePanelSizer_Items(self.StructurePanelSizer) + self._init_coll_StructurePanelSizer_Growables(self.StructurePanelSizer) + self._init_coll_StructurePanelButtonSizer_Items(self.StructurePanelButtonSizer) self.SetSizer(self.MainSizer) self.DirectlyPanel.SetSizer(self.DirectlyPanelSizer) self.SubrangePanel.SetSizer(self.SubrangePanelSizer) self.EnumeratedPanel.SetSizer(self.EnumeratedPanelSizer) self.ArrayPanel.SetSizer(self.ArrayPanelSizer) + self.StructurePanel.SetSizer(self.StructurePanelSizer) def _init_ctrls(self, prnt): wx.Panel.__init__(self, id=ID_DATATYPEEDITOR, name='', parent=prnt, @@ -282,18 +478,79 @@ size=wx.Size(0, 24), style=wx.TAB_TRAVERSAL|wx.TE_PROCESS_ENTER|wx.TE_MULTILINE|wx.TE_RICH) self.Bind(wx.EVT_TEXT_ENTER, self.OnReturnKeyPressed, id=ID_DATATYPEEDITORARRAYINITIALVALUE) + # Panel for Structure data types + + self.StructurePanel = wx.Panel(id=ID_DATATYPEEDITORSTRUCTUREPANEL, + name='StructurePanel', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) + + self.staticText11 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT11, + label='Elements :', name='staticText11', parent=self.StructurePanel, + pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + + self.StructureElementsGrid = wx.grid.Grid(id=ID_DATATYPEEDITORSTRUCTUREELEMENTSGRID, + name='StructureElementsGrid', parent=self.StructurePanel, pos=wx.Point(0, 0), + size=wx.Size(0, 150), style=wx.VSCROLL) + self.StructureElementsGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False, + 'Sans')) + self.StructureElementsGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL, + False, 'Sans')) + self.StructureElementsGrid.SetSelectionBackground(wx.WHITE) + self.StructureElementsGrid.SetSelectionForeground(wx.BLACK) + if wx.VERSION >= (2, 6, 0): + self.StructureElementsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnStructureElementsGridCellChange) + self.StructureElementsGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, self.OnStructureElementsGridEditorShown) + else: + wx.grid.EVT_GRID_CELL_CHANGE(self.StructureElementsGrid, self.OnStructureElementsGridCellChange) + wx.grid.EVT_GRID_EDITOR_SHOWN(self.StructureElementsGrid, self.OnStructureElementsGridEditorShown) + + self.StructureAddButton = wx.Button(id=ID_DATATYPEEDITORSTRUCTUREADDBUTTON, label='Add', + name='StructureAddButton', parent=self.StructurePanel, pos=wx.Point(0, 0), + size=wx.Size(72, 32), style=0) + self.Bind(wx.EVT_BUTTON, self.OnStructureAddButton, id=ID_DATATYPEEDITORSTRUCTUREADDBUTTON) + + self.StructureDeleteButton = wx.Button(id=ID_DATATYPEEDITORSTRUCTUREDELETEBUTTON, label='Delete', + name='StructureDeleteButton', parent=self.StructurePanel, pos=wx.Point(0, 0), + size=wx.Size(72, 32), style=0) + self.Bind(wx.EVT_BUTTON, self.OnStructureDeleteButton, id=ID_DATATYPEEDITORSTRUCTUREDELETEBUTTON) + + self.StructureUpButton = wx.Button(id=ID_DATATYPEEDITORSTRUCTUREUPBUTTON, label='^', + name='StructureUpButton', parent=self.StructurePanel, pos=wx.Point(0, 0), + size=wx.Size(32, 32), style=0) + self.Bind(wx.EVT_BUTTON, self.OnStructureUpButton, id=ID_DATATYPEEDITORSTRUCTUREUPBUTTON) + + self.StructureDownButton = wx.Button(id=ID_DATATYPEEDITORSTRUCTUREDOWNBUTTON, label='v', + name='StructureDownButton', parent=self.StructurePanel, pos=wx.Point(0, 0), + size=wx.Size(32, 32), style=0) + self.Bind(wx.EVT_BUTTON, self.OnStructureDownButton, id=ID_DATATYPEEDITORSTRUCTUREDOWNBUTTON) + self._init_sizers() def __init__(self, parent, tagname, window, controler): self._init_ctrls(parent) + self.StructureElementDefaultValue = {"Name" : "", "Type" : "INT", "Initial Value" : ""} + self.StructureElementsTable = ElementsTable(self, [], ["#", "Name", "Type", "Initial Value"]) + self.StructureColSizes = [40, 150, 100, 250] + self.StructureColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT] + + self.StructureElementsGrid.SetTable(self.StructureElementsTable) + self.StructureElementsGrid.SetRowLabelSize(0) + for col in range(self.StructureElementsTable.GetNumberCols()): + attr = wx.grid.GridCellAttr() + attr.SetAlignment(self.StructureColAlignements[col], wx.ALIGN_CENTRE) + self.StructureElementsGrid.SetColAttr(col, attr) + self.StructureElementsGrid.SetColSize(col, self.StructureColSizes[col]) + self.DerivationType.Append("Directly") self.DerivationType.Append("Subrange") self.DerivationType.Append("Enumerated") self.DerivationType.Append("Array") + self.DerivationType.Append("Structure") self.SubrangePanel.Hide() self.EnumeratedPanel.Hide() self.ArrayPanel.Hide() + self.StructurePanel.Hide() self.CurrentPanel = "Directly" self.Errors = [] self.Initializing = False @@ -302,34 +559,6 @@ self.Controler = controler self.TagName = tagname - def OnEnumeratedValueEndEdit(self, event): - text = event.GetText() - values = self.EnumeratedValues.GetStrings() - index = event.GetIndex() - if index >= len(values) or values[index].upper() != text.upper(): - if text.upper() in [value.upper() for value in values]: - message = wx.MessageDialog(self, "\"%s\" value already defined!"%text, "Error", wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - event.Veto() - elif text.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%text, "Error", wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - else: - wx.CallAfter(self.RefreshEnumeratedValues) - wx.CallAfter(self.RefreshTypeInfos) - event.Skip() - else: - wx.CallAfter(self.RefreshEnumeratedValues) - wx.CallAfter(self.RefreshTypeInfos) - event.Skip() - - def OnEnumeratedValuesChanged(self, event): - wx.CallAfter(self.RefreshEnumeratedValues) - wx.CallAfter(self.RefreshTypeInfos) - event.Skip() - def SetTagName(self, tagname): self.TagName = tagname @@ -383,6 +612,9 @@ self.ArrayBaseType.SetStringSelection(type_infos["base_type"]) self.ArrayDimensions.SetStrings(map(lambda x : "..".join(map(str, x)), type_infos["dimensions"])) self.ArrayInitialValue.SetValue(type_infos["initial"]) + elif type_infos["type"] == "Structure": + self.StructureElementsTable.SetData(type_infos["elements"]) + self.StructureElementsTable.ResetView(self.StructureElementsGrid) self.RefreshDisplayedInfos() self.ShowErrors() self.Initializing = False @@ -425,6 +657,144 @@ wx.CallAfter(self.RefreshTypeInfos) event.Skip() + def OnEnumeratedValueEndEdit(self, event): + text = event.GetText() + values = self.EnumeratedValues.GetStrings() + index = event.GetIndex() + if index >= len(values) or values[index].upper() != text.upper(): + if text.upper() in [value.upper() for value in values]: + message = wx.MessageDialog(self, "\"%s\" value already defined!"%text, "Error", wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + event.Veto() + elif text.upper() in IEC_KEYWORDS: + message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%text, "Error", wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + wx.CallAfter(self.RefreshEnumeratedValues) + wx.CallAfter(self.RefreshTypeInfos) + event.Skip() + else: + wx.CallAfter(self.RefreshEnumeratedValues) + wx.CallAfter(self.RefreshTypeInfos) + event.Skip() + + def OnEnumeratedValuesChanged(self, event): + wx.CallAfter(self.RefreshEnumeratedValues) + wx.CallAfter(self.RefreshTypeInfos) + event.Skip() + + def OnStructureAddButton(self, event): + new_row = self.StructureElementDefaultValue.copy() + self.StructureElementsTable.AppendRow(new_row) + self.RefreshTypeInfos() + self.StructureElementsTable.ResetView(self.StructureElementsGrid) + event.Skip() + + def OnStructureDeleteButton(self, event): + row = self.StructureElementsGrid.GetGridCursorRow() + self.StructureElementsTable.RemoveRow(row) + self.RefreshTypeInfos() + self.StructureElementsTable.ResetView(self.StructureElementsGrid) + event.Skip() + + def OnStructureUpButton(self, event): + row = self.StructureElementsGrid.GetGridCursorRow() + new_index = self.StructureElementsTable.MoveRow(row, -1) + if new_index is not None: + self.RefreshTypeInfos() + self.StructureElementsTable.ResetView(self.StructureElementsGrid) + self.StructureElementsGrid.SetGridCursor(new_index, self.StructureElementsGrid.GetGridCursorCol()) + event.Skip() + + def OnStructureDownButton(self, event): + row = self.StructureElementsGrid.GetGridCursorRow() + new_index = self.StructureElementsTable.MoveRow(row, 1) + if new_index is not None: + self.RefreshTypeInfos() + self.StructureElementsTable.ResetView(self.StructureElementsGrid) + self.StructureElementsGrid.SetGridCursor(new_index, self.StructureElementsGrid.GetGridCursorCol()) + event.Skip() + + def OnStructureElementsGridCellChange(self, event): + row, col = event.GetRow(), event.GetCol() + colname = self.StructureElementsTable.GetColLabelValue(col) + value = self.StructureElementsTable.GetValue(row, col) + if colname == "Name": + if not TestIdentifier(value): + message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%value, "Error", wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + event.Veto() + elif value.upper() in IEC_KEYWORDS: + message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%value, "Error", wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + event.Veto() +## elif value.upper() in self.PouNames: +## message = wx.MessageDialog(self, "A pou with \"%s\" as name exists!"%value, "Error", wx.OK|wx.ICON_ERROR) +## message.ShowModal() +## message.Destroy() +## event.Veto() + elif value.upper() in [var["Name"].upper() for idx, var in enumerate(self.StructureElementsTable.GetData()) if idx != row]: + message = wx.MessageDialog(self, "A element with \"%s\" as name exists in this structure!"%value, "Error", wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + event.Veto() + else: + self.RefreshTypeInfos() + self.StructureElementsTable.ResetView(self.StructureElementsGrid) +## old_value = self.Table.GetOldValue() +## if old_value != "": +## self.Controler.UpdateEditedElementUsedVariable(self.TagName, old_value, value) +## self.Controler.BufferProject() + event.Skip() + else: + self.RefreshTypeInfos() + self.StructureElementsTable.ResetView(self.StructureElementsGrid) + event.Skip() + + def OnStructureElementsGridEditorShown(self, event): + row, col = event.GetRow(), event.GetCol() + if self.StructureElementsTable.GetColLabelValue(col) == "Type": + type_menu = wx.Menu(title='') + base_menu = wx.Menu(title='') + for base_type in self.Controler.GetBaseTypes(): + new_id = wx.NewId() + AppendMenu(base_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=base_type) + self.Bind(wx.EVT_MENU, self.GetElementTypeFunction(base_type), id=new_id) + type_menu.AppendMenu(wx.NewId(), "Base Types", base_menu) + datatype_menu = wx.Menu(title='') + for datatype in self.Controler.GetDataTypes(self.TagName, False, self.ParentWindow.Debug): + new_id = wx.NewId() + AppendMenu(datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype) + self.Bind(wx.EVT_MENU, self.GetElementTypeFunction(datatype), id=new_id) + type_menu.AppendMenu(wx.NewId(), "User Data Types", datatype_menu) +## functionblock_menu = wx.Menu(title='') +## bodytype = self.Controler.GetEditedElementBodyType(self.TagName, self.ParentWindow.Debug) +## pouname, poutype = self.Controler.GetEditedElementType(self.TagName, self.ParentWindow.Debug) +## if classtype in ["Input","Output","InOut","External","Global"] or poutype != "function" and bodytype in ["ST", "IL"]: +## for functionblock_type in self.Controler.GetFunctionBlockTypes(self.TagName, self.ParentWindow.Debug): +## new_id = wx.NewId() +## AppendMenu(functionblock_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=functionblock_type) +## self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(functionblock_type), id=new_id) +## type_menu.AppendMenu(wx.NewId(), "Function Block Types", functionblock_menu) + rect = self.StructureElementsGrid.BlockToDeviceRect((row, col), (row, col)) + self.StructureElementsGrid.PopupMenuXY(type_menu, rect.x + rect.width, rect.y + self.StructureElementsGrid.GetColLabelSize()) + event.Veto() + else: + event.Skip() + + def GetElementTypeFunction(self, base_type): + def ElementTypeFunction(event): + row = self.StructureElementsGrid.GetGridCursorRow() + self.StructureElementsTable.SetValueByName(row, "Type", base_type) + self.RefreshTypeInfos() + self.StructureElementsTable.ResetView(self.StructureElementsGrid) + event.Skip() + return ElementTypeFunction + def RefreshDisplayedInfos(self): selected = self.DerivationType.GetStringSelection() if selected != self.CurrentPanel: @@ -436,6 +806,8 @@ self.EnumeratedPanel.Hide() elif self.CurrentPanel == "Array": self.ArrayPanel.Hide() + elif self.CurrentPanel == "Structure": + self.StructurePanel.Hide() self.CurrentPanel = selected if selected == "Directly": self.DirectlyPanel.Show() @@ -445,6 +817,8 @@ self.EnumeratedPanel.Show() elif selected == "Array": self.ArrayPanel.Show() + elif selected == "Structure": + self.StructurePanel.Show() self.MainSizer.Layout() def RefreshEnumeratedValues(self): @@ -505,6 +879,9 @@ return infos["dimensions"].append(map(int, bounds)) infos["initial"] = self.ArrayInitialValue.GetValue() + elif selected == "Structure": + infos["elements"] = self.StructureElementsTable.GetData() + infos["initial"] = "" self.Controler.SetDataTypeInfos(self.TagName, infos) self.ParentWindow.RefreshTitle() self.ParentWindow.RefreshEditMenu()