# HG changeset patch # User lbessard # Date 1188919002 -7200 # Node ID 73257cea38bdff538ef46b60d9c036f5a49f0e68 # Parent 0fac6d621a24879f29bdb42bc180e16cfe75c377 Adding Plugin params visualization with basic controls diff -r 0fac6d621a24 -r 73257cea38bd Beremiz.py --- a/Beremiz.py Mon Sep 03 17:12:43 2007 +0200 +++ b/Beremiz.py Tue Sep 04 17:16:42 2007 +0200 @@ -80,147 +80,6 @@ def isatty(self): return false -class AttributesTable(wx.grid.PyGridTableBase): - - """ - A custom wxGrid 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.colnames = colnames - 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(): - name = str(self.data[row].get(self.GetColLabelValue(col), "")) - return name - - def GetValueByName(self, row, colname): - return self.data[row].get(colname) - - def SetValue(self, row, col, value): - if col < len(self.colnames): - self.data[row][self.GetColLabelValue(col)] = value - - def ResetView(self, grid): - """ - (wxGrid) -> 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): - """ - wxGrid -> update the column attributes to add the - appropriate renderer given the column name. - - Otherwise default to the default renderer. - """ - - for row in range(self.GetNumberRows()): - for col in range(self.GetNumberCols()): - editor = None - renderer = None - align = wx.ALIGN_LEFT - colname = self.GetColLabelValue(col) - grid.SetReadOnly(row, col, False) - - if colname == "Value": - colSize = 100 - value_type = self.data[row]["Type"] - if isinstance(value_type, types.ListType): - editor = wx.grid.GridCellChoiceEditor() - editor.SetParameters(",".join(value_type)) - elif value_type == "boolean": - editor = wx.grid.GridCellChoiceEditor() - editor.SetParameters("True,False") - elif value_type in ["unsignedLong","long","integer"]: - editor = wx.grid.GridCellNumberEditor() - align = wx.ALIGN_RIGHT - elif value_type == "decimal": - editor = wx.grid.GridCellFloatEditor() - align = wx.ALIGN_RIGHT - else: - editor = wx.grid.GridCellTextEditor() - else: - colSize = 120 - grid.SetReadOnly(row, col, True) - - attr = wx.grid.GridCellAttr() - attr.SetAlignment(align, wx.ALIGN_CENTRE) - grid.SetColAttr(col, attr) - grid.SetColSize(col, colSize) - - grid.SetCellEditor(row, col, editor) - grid.SetCellRenderer(row, col, renderer) - - 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 GetRow(self, row_index): - return self.data[row_index] - - def Empty(self): - self.data = [] - [ID_BEREMIZ, ID_BEREMIZMAINSPLITTER, ID_BEREMIZSECONDSPLITTER, ID_BEREMIZLEFTPANEL, ID_BEREMIZPARAMSPANEL, ID_BEREMIZLOGCONSOLE, @@ -358,35 +217,16 @@ def _init_coll_ButtonGridSizer_Growables(self, parent): parent.AddGrowableCol(0) parent.AddGrowableRow(0) - - def _init_coll_ParamsPanelMainSizer_Items(self, parent): - parent.AddSizer(self.ParamsPanelChildSizer, 1, border=10, flag=wx.GROW|wx.ALL) - parent.AddSizer(self.ParamsPanelPluginSizer, 1, border=10, flag=wx.GROW|wx.ALL) - parent.AddWindow(self.AttributesGrid, 2, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT|wx.BOTTOM) - - def _init_coll_ParamsPanelChildSizer_Items(self, parent): - parent.AddWindow(self.ParamsEnable, 0, border=5, flag=wx.GROW|wx.BOTTOM) - parent.AddWindow(self.ParamsStaticText1, 0, border=5, flag=wx.GROW|wx.BOTTOM) - parent.AddWindow(self.ParamsIECChannel, 0, border=0, flag=wx.GROW) - - def _init_coll_ParamsPanelPluginSizer_Items(self, parent): - parent.AddWindow(self.ParamsStaticText2, 0, border=5, flag=wx.GROW|wx.BOTTOM) - parent.AddWindow(self.ParamsTargetType, 0, border=0, flag=wx.GROW) def _init_sizers(self): self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=2, rows=2, vgap=2) self.ButtonGridSizer = wx.FlexGridSizer(cols=3, hgap=2, rows=1, vgap=2) - self.ParamsPanelMainSizer = wx.StaticBoxSizer(self.ParamsStaticBox, wx.HORIZONTAL) - self.ParamsPanelChildSizer = wx.BoxSizer(wx.VERTICAL) - self.ParamsPanelPluginSizer = wx.BoxSizer(wx.VERTICAL) + self.ParamsPanelMainSizer = wx.BoxSizer(wx.VERTICAL) self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) self._init_coll_ButtonGridSizer_Growables(self.ButtonGridSizer) self._init_coll_ButtonGridSizer_Items(self.ButtonGridSizer) - self._init_coll_ParamsPanelMainSizer_Items(self.ParamsPanelMainSizer) - self._init_coll_ParamsPanelChildSizer_Items(self.ParamsPanelChildSizer) - self._init_coll_ParamsPanelPluginSizer_Items(self.ParamsPanelPluginSizer) self.LeftPanel.SetSizer(self.LeftGridSizer) self.ParamsPanel.SetSizer(self.ParamsPanelMainSizer) @@ -441,46 +281,10 @@ self.MainSplitter.SplitVertically(self.LeftPanel, self.SecondSplitter, 300) - self.ParamsPanel = wx.Panel(id=ID_BEREMIZPARAMSPANEL, + self.ParamsPanel = wx.ScrolledWindow(id=ID_BEREMIZPARAMSPANEL, name='ParamsPanel', parent=self.SecondSplitter, pos=wx.Point(0, 0), - size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) - - self.ParamsStaticBox = wx.StaticBox(id=ID_BEREMIZPARAMSSTATICBOX, - label='', name='staticBox1', parent=self.ParamsPanel, - pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) - - self.ParamsEnable = wx.CheckBox(id=ID_BEREMIZPARAMSENABLE, - label='Plugin enabled', name='ParamsEnable', parent=self.ParamsPanel, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_CHECKBOX, self.OnParamsEnableChanged, id=ID_BEREMIZPARAMSENABLE) - - self.ParamsStaticText1 = wx.StaticText(id=ID_BEREMIZPARAMSSTATICTEXT1, - label='IEC Channel:', name='ParamsStaticText1', parent=self.ParamsPanel, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.ParamsIECChannel = wx.SpinCtrl(id=ID_BEREMIZPARAMSIECCHANNEL, - name='ParamsIECChannel', parent=self.ParamsPanel, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0) - self.Bind(wx.EVT_SPINCTRL, self.OnParamsIECChannelChanged, id=ID_BEREMIZPARAMSIECCHANNEL) - - self.ParamsStaticText2 = wx.StaticText(id=ID_BEREMIZPARAMSSTATICTEXT2, - label='Target Type:', name='ParamsStaticText2', parent=self.ParamsPanel, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.ParamsTargetType = wx.Choice(id=ID_BEREMIZPARAMSTARGETTYPE, - name='TargetType', choices=[""], parent=self.ParamsPanel, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.LB_SINGLE) - self.Bind(wx.EVT_CHOICE, self.OnParamsTargetTypeChanged, id=ID_BEREMIZPARAMSTARGETTYPE) - - self.AttributesGrid = wx.grid.Grid(id=ID_BEREMIZPARAMSATTRIBUTESGRID, - name='AttributesGrid', parent=self.ParamsPanel, pos=wx.Point(0, 0), - size=wx.Size(0, 150), style=wx.VSCROLL) - self.AttributesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False, - 'Sans')) - self.AttributesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL, - False, 'Sans')) - self.AttributesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnAttributesGridCellChange) - + size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.VSCROLL) + self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='', name='LogConsole', parent=self.SecondSplitter, pos=wx.Point(0, 0), size=wx.Size(0, 0), style=wx.TE_MULTILINE|wx.TE_RICH2) @@ -496,12 +300,6 @@ self.Log = LogPseudoFile(self.LogConsole) self.PluginRoot = PluginsRoot() - for value in self.PluginRoot.GetTargetTypes(): - self.ParamsTargetType.Append(value) - - self.Table = AttributesTable(self, [], ["Attribute", "Value"]) - self.AttributesGrid.SetTable(self.Table) - self.AttributesGrid.SetRowLabelSize(0) if projectOpen: self.PluginRoot.LoadProject(projectOpen) @@ -622,21 +420,9 @@ else: # Refresh ParamsPanel self.ParamsPanel.Show() - self.ParamsStaticBox.SetLabel(plugin.BaseParams.getName()) - if plugin == self.PluginRoot: - self.ParamsPanelMainSizer.Hide(self.ParamsPanelChildSizer) - self.ParamsPanelMainSizer.Show(self.ParamsPanelPluginSizer) - self.ParamsTargetType.SetStringSelection(self.PluginRoot.GetTargetType()) - else: - self.ParamsPanelMainSizer.Show(self.ParamsPanelChildSizer) - self.ParamsPanelMainSizer.Hide(self.ParamsPanelPluginSizer) - self.ParamsEnable.SetValue(plugin.BaseParams.getEnabled()) - self.ParamsEnable.Enable(True) - self.ParamsStaticText1.Enable(True) - self.ParamsIECChannel.SetValue(plugin.BaseParams.getIEC_Channel()) - self.ParamsIECChannel.Enable(True) + infos = plugin.GetParamsAttributes() + self.RefreshSizerElement(self.ParamsPanelMainSizer, infos, None) self.ParamsPanelMainSizer.Layout() - self.RefreshAttributesGrid() # Refresh PluginChilds self.PluginChilds.Clear() @@ -651,22 +437,240 @@ self.AddButton.Enable(False) self.DeleteButton.Enable(True) + def GetChoiceCallBackFunction(self, choicectrl, path): + def OnChoiceChanged(event): + plugin = self.GetSelectedPlugin() + if plugin: + plugin.SetParamsAttribute(path, choicectrl.GetStringSelection()) + event.Skip() + return OnChoiceChanged + + def GetChoiceContentCallBackFunction(self, choicectrl, staticboxsizer, path): + def OnChoiceContentChanged(event): + plugin = self.GetSelectedPlugin() + if plugin: + plugin.SetParamsAttribute(path, choicectrl.GetStringSelection()) + infos = self.PluginRoot.GetParamsAttributes(path) + staticbox = staticboxsizer.GetStaticBox() + staticbox.SetLabel("%(name)s - %(value)s"%infos) + self.RefreshSizerElement(staticboxsizer, infos["children"], "%s.%s"%(path, infos["name"])) + self.ParamsPanelMainSizer.Layout() + event.Skip() + return OnChoiceContentChanged + + def GetTextCtrlCallBackFunction(self, textctrl, path): + def OnTextCtrlChanged(event): + plugin = self.GetSelectedPlugin() + if plugin: + plugin.SetParamsAttribute(path, textctrl.GetValue()) + event.Skip() + return OnTextCtrlChanged + + def GetCheckBoxCallBackFunction(self, textctrl, path): + def OnCheckBoxChanged(event): + plugin = self.GetSelectedPlugin() + if plugin: + plugin.SetParamsAttribute(path, textctrl.IsChecked()) + event.Skip() + return OnCheckBoxChanged + + def ClearSizer(self, sizer): + staticboxes = [] + for item in sizer.GetChildren(): + if item.IsSizer(): + item_sizer = item.GetSizer() + self.ClearSizer(item_sizer) + if isinstance(item_sizer, wx.StaticBoxSizer): + staticboxes.append(item_sizer.GetStaticBox()) + sizer.Clear(True) + for staticbox in staticboxes: + staticbox.Destroy() + + def RefreshSizerElement(self, sizer, elements, path): + self.ClearSizer(sizer) + first = True + for element_infos in elements: + if path: + element_path = "%s.%s"%(path, element_infos["name"]) + else: + element_path = element_infos["name"] + if isinstance(element_infos["type"], types.ListType): + boxsizer = wx.BoxSizer(wx.HORIZONTAL) + if first: + sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.ALL) + else: + sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM) + statictext = wx.StaticText(id=-1, label="%s:"%element_infos["name"], + name="%s_label"%element_infos["name"], parent=self.ParamsPanel, + pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0) + boxsizer.AddWindow(statictext, 0, border=0, flag=0) + id = wx.NewId() + choicectrl = wx.Choice(id=id, name=element_infos["name"], parent=self.ParamsPanel, + pos=wx.Point(0, 0), size=wx.Size(150, 25), style=0) + boxsizer.AddWindow(choicectrl, 0, border=0, flag=0) + choicectrl.Append("") + if len(element_infos["type"]) > 0 and isinstance(element_infos["type"][0], types.TupleType): + for choice, xsdclass in element_infos["type"]: + choicectrl.Append(choice) + staticbox = wx.StaticBox(id=-1, label="%(name)s - %(value)s"%element_infos, + name='%s_staticbox'%element_infos["name"], parent=self.ParamsPanel, + pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) + staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL) + sizer.AddSizer(staticboxsizer, 0, border=0, flag=wx.GROW) + self.RefreshSizerElement(staticboxsizer, element_infos["children"], element_path) + callback = self.GetChoiceContentCallBackFunction(choicectrl, staticboxsizer, element_path) + else: + for choice in element_infos["type"]: + choicectrl.Append(choice) + callback = self.GetChoiceCallBackFunction(choicectrl, element_path) + choicectrl.Bind(wx.EVT_CHOICE, callback, id=id) + choicectrl.SetStringSelection(element_infos["value"]) + elif isinstance(element_infos["type"], types.DictType): + boxsizer = wx.BoxSizer(wx.HORIZONTAL) + if first: + sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.ALL) + else: + sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM) + statictext = wx.StaticText(id=-1, label="%s:"%element_infos["name"], + name="%s_label"%element_infos["name"], parent=self.ParamsPanel, + pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0) + boxsizer.AddWindow(statictext, 0, border=0, flag=wx.TOP|wx.LEFT|wx.BOTTOM) + id = wx.NewId() + min = max = -1 + if "min" in element_infos["type"]: + min = element_infos["type"]["min"] + if "max" in element_infos["type"]: + max = element_infos["type"]["max"] + spinctrl = wx.SpinCtrl(id=id, name=element_infos["name"], parent=self.ParamsPanel, + pos=wx.Point(0, 0), size=wx.Size(150, 25), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT, + min=min, max=max) + boxsizer.AddWindow(spinctrl, 0, border=0, flag=0) + spinctrl.Bind(wx.EVT_SPINCTRL, self.GetTextCtrlCallBackFunction(spinctrl, element_path), id=id) + spinctrl.SetValue(element_infos["value"]) + elif element_infos["type"] == "element": + staticbox = wx.StaticBox(id=-1, label=element_infos["name"], + name='%s_staticbox'%element_infos["name"], parent=self.ParamsPanel, + pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) + staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL) + if first: + sizer.AddSizer(staticboxsizer, 0, border=0, flag=wx.GROW|wx.TOP) + else: + sizer.AddSizer(staticboxsizer, 0, border=0, flag=wx.GROW) + self.RefreshSizerElement(staticboxsizer, element_infos["children"], element_path) + else: + boxsizer = wx.BoxSizer(wx.HORIZONTAL) + if first: + sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.ALL) + else: + sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM) + statictext = wx.StaticText(id=-1, label="%s:"%element_infos["name"], + name="%s_label"%element_infos["name"], parent=self.ParamsPanel, + pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0) + boxsizer.AddWindow(statictext, 0, border=0, flag=0) + id = wx.NewId() + if element_infos["type"] == "boolean": + checkbox = wx.CheckBox(id=id, name=element_infos["name"], parent=self.ParamsPanel, + pos=wx.Point(0, 0), size=wx.Size(17, 25), style=0) + boxsizer.AddWindow(checkbox, 0, border=0, flag=0) + checkbox.Bind(wx.EVT_CHECKBOX, self.GetCheckBoxCallBackFunction(checkbox, element_path), id=id) + checkbox.SetValue(element_infos["value"]) + elif element_infos["type"] in ["unsignedLong", "long","integer"]: + spinctrl = wx.SpinCtrl(id=id, name=element_infos["name"], parent=self.ParamsPanel, + pos=wx.Point(0, 0), size=wx.Size(150, 25), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT) + boxsizer.AddWindow(spinctrl, 0, border=0, flag=0) + spinctrl.Bind(wx.EVT_SPINCTRL, self.GetTextCtrlCallBackFunction(spinctrl, element_path), id=id) + spinctrl.SetValue(element_infos["value"]) + else: + textctrl = wx.TextCtrl(id=id, name=element_infos["name"], parent=self.ParamsPanel, + pos=wx.Point(0, 0), size=wx.Size(150, 25), style=0) + boxsizer.AddWindow(textctrl, 0, border=0, flag=0) + textctrl.Bind(wx.EVT_TEXT, self.GetTextCtrlCallBackFunction(textctrl, element_path), id=id) + textctrl.SetValue(str(element_infos["value"])) + first = False + + def UpdateAttributesTreeParts(self, tree, new_tree): + tree_leafs = [(element_infos["name"], element_infos["type"]) for element_infos in tree["children"]] + new_tree_leafs = [(element_infos["name"], element_infos["type"]) for element_infos in new_tree["children"]] + if tree_leafs != new_tree_leafs: + tree["children"] = new_tree["children"] + for child in tree["children"]: + self.PrepareAttributesTree(child) + else: + for idx, new_element_infos in enumerate(new_tree["children"]): + tree["children"][idx]["value"] = new_element_infos["value"] + if len(new_element_infos["children"]) > 0: + self.UpdateAttributesTreeParts(tree["children"][idx], new_element_infos) + + def PrepareAttributesTree(self, tree): + if len(tree["children"]) > 0: + tree["open"] = False + for child in tree["children"]: + self.PrepareAttributesTree(child) + + def GenerateTable(self, data, tree, path, indent): + if path: + tree_path = "%s.%s"%(path, tree["name"]) + infos = {"Attribute" : " " * indent + tree["name"], "Value" : tree["value"], "Type" : tree["type"], "Open" : "", "Path" : tree_path} + data.append(infos) + indent += 1 + else: + tree_path = tree["name"] + if len(tree["children"]) > 0: + if tree["open"] or not path: + if path: + infos["Open"] = "v" + for child in tree["children"]: + self.GenerateTable(data, child, tree_path, indent) + elif path: + infos["Open"] = ">" + def RefreshAttributesGrid(self): plugin = self.GetSelectedPlugin() if not plugin: + self.AttributesTree = [] self.Table.Empty() else: - if plugin == self.PluginRoot: - attr_infos = self.PluginRoot.GetTargetAttributes() - else: - attr_infos = plugin.GetPlugParamsAttributes() + new_params = plugin.GetParamsAttributes() + for idx, child in enumerate(new_params): + if len(self.AttributesTree) > idx: + if self.AttributesTree[idx]["name"] == child["name"]: + self.UpdateAttributesTreeParts(self.AttributesTree[idx], child) + else: + self.AttributesTree[idx] = child + self.PrepareAttributesTree(child) + else: + self.AttributesTree.append(child) + self.PrepareAttributesTree(child) + while len(self.AttributesTree) > len(new_params): + self.AttributesTree.pop(-1) data = [] - for infos in attr_infos: - data.append({"Attribute" : infos["name"], "Value" : infos["value"], - "Type" : infos["type"]}) + for child in self.AttributesTree: + self.GenerateTable(data, child, None, 0) self.Table.SetData(data) self.Table.ResetView(self.AttributesGrid) + def OpenClose(self, tree, path): + parts = path.split(".", 1) + for child in tree["children"]: + if child["name"] == parts[0]: + if len(parts) > 1: + return self.OpenClose(child, parts[1]) + elif len(child["children"]) > 0: + child["open"] = not child["open"] + return True + return False + + def OpenCloseAttribute(self): + if self.AttributesGrid.GetGridCursorCol() == 0: + row = self.AttributesGrid.GetGridCursorRow() + path = self.Table.GetValueByName(row, "Path") + parts = path.split(".", 1) + for child in self.AttributesTree: + if child["name"] == parts[0] and len(parts) > 1: + result = self.OpenClose(child, parts[1]) + if result: + self.RefreshAttributesGrid() + def OnParamsEnableChanged(self, event): plugin = self.GetSelectedPlugin() if plugin and plugin != self.PluginRoot: @@ -690,12 +694,15 @@ row = event.GetRow() plugin = self.GetSelectedPlugin() if plugin: - name = self.Table.GetValueByName(row, "Attribute") + path = self.Table.GetValueByName(row, "Path") value = self.Table.GetValueByName(row, "Value") - if plugin == self.PluginRoot: - self.PluginRoot.SetTargetAttribute(name, value) - else: - plugin.SetPlugParamsAttribute(name, value) + plugin.SetParamsAttribute(path, value) + print plugin.GetParamsAttributes(path) + self.RefreshAttributesGrid() + event.Skip() + + def OnAttributesGridCellLeftClick(self, event): + wx.CallAfter(self.OpenCloseAttribute) event.Skip() def OnNewProjectMenu(self, event): diff -r 0fac6d621a24 -r 73257cea38bd plugger.py --- a/plugger.py Mon Sep 03 17:12:43 2007 +0200 +++ b/plugger.py Tue Sep 04 17:16:42 2007 +0200 @@ -36,7 +36,7 @@ def _AddParamsMembers(self): Classes = GenerateClassesFromXSDstring(self.XSD)[0] - self.PlugParams = [] + self.PlugParams = None Classes = [(name, XSDclass) for name, XSDclass in Classes.items() if XSDclass.IsBaseClass] if len(Classes) == 1: name, XSDclass = Classes[0] @@ -68,15 +68,27 @@ def OnPlugSave(self): return True - def GetPlugParamsAttributes(self): - return self.PlugParams[1].getElementAttributes() - - def SetPlugParamsAttribute(self, name, value): - attr = getattr(self.PlugParams[1], name, None) - if isinstance(attr, types.ClassType): - attr.SetValue(value) + def GetParamsAttributes(self, path = None): + if path: + parts = path.split(".", 1) + if self.MandatoryParams and parts[0] == self.MandatoryParams[0]: + return self.MandatoryParams[1].getElementInfos(parts[0], parts[1]) + elif self.PlugParams and parts[0] == self.PlugParams[0]: + return self.PlugParams[1].getElementInfos(parts[0], parts[1]) else: - setattr(self.PlugParams[1], name, value) + params = [] + if self.MandatoryParams: + params.append(self.MandatoryParams[1].getElementInfos(self.MandatoryParams[0])) + if self.PlugParams: + params.append(self.PlugParams[1].getElementInfos(self.PlugParams[0])) + return params + + def SetParamsAttribute(self, path, value): + parts = path.split(".", 1) + if self.MandatoryParams and parts[0] == self.MandatoryParams[0]: + self.MandatoryParams[1].setElementValue(parts[1], value) + elif self.PlugParams and parts[0] == self.PlugParams[0]: + self.PlugParams[1].setElementValue(parts[1], value) def PlugRequestSave(self): # If plugin do not have corresponding directory @@ -425,35 +437,6 @@ def GetProjectPath(self): return self.ProjectPath - def GetTargetTypes(self): - return self.BeremizRoot.TargetType.getChoices().keys() - - def ChangeTargetType(self, target_type): - self.BeremizRoot.TargetType.addContent(target_type) - - def GetTargetAttributes(self): - content = self.BeremizRoot.TargetType.getContent() - if content: - return content["value"].getElementAttributes() - else: - return [] - - def SetTargetAttribute(self, name, value): - content = self.BeremizRoot.TargetType.getContent() - if content: - attr = getattr(content["value"], name, None) - if isinstance(attr, types.ClassType): - attr.SetValue(value) - else: - setattr(content["value"], name, value) - - def GetTargetType(self): - content = self.BeremizRoot.TargetType.getContent() - if content: - return content["name"] - else: - return "" - def NewProject(self, ProjectPath, PLCParams): """ Create a new project in an empty folder