beremiz

Parents 0fac6d621a24
Children d3cb5020997b
Adding Plugin params visualization with basic controls
  • +238 -231
    Beremiz.py
  • +21 -38
    plugger.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)
    + size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.VSCROLL)
    - 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)
    -
    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):
    --- 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