Beremiz.py
changeset 19 73257cea38bd
parent 18 0fac6d621a24
child 20 d3cb5020997b
equal deleted inserted replaced
18:0fac6d621a24 19:73257cea38bd
    77     def flush(self):
    77     def flush(self):
    78         self.output.SetValue("")
    78         self.output.SetValue("")
    79     
    79     
    80     def isatty(self):
    80     def isatty(self):
    81         return false
    81         return false
    82 
       
    83 class AttributesTable(wx.grid.PyGridTableBase):
       
    84     
       
    85     """
       
    86     A custom wxGrid Table using user supplied data
       
    87     """
       
    88     def __init__(self, parent, data, colnames):
       
    89         # The base class must be initialized *first*
       
    90         wx.grid.PyGridTableBase.__init__(self)
       
    91         self.data = data
       
    92         self.colnames = colnames
       
    93         self.Parent = parent
       
    94         # XXX
       
    95         # we need to store the row length and collength to
       
    96         # see if the table has changed size
       
    97         self._rows = self.GetNumberRows()
       
    98         self._cols = self.GetNumberCols()
       
    99     
       
   100     def GetNumberCols(self):
       
   101         return len(self.colnames)
       
   102         
       
   103     def GetNumberRows(self):
       
   104         return len(self.data)
       
   105 
       
   106     def GetColLabelValue(self, col):
       
   107         if col < len(self.colnames):
       
   108             return self.colnames[col]
       
   109 
       
   110     def GetRowLabelValues(self, row):
       
   111         return row
       
   112 
       
   113     def GetValue(self, row, col):
       
   114         if row < self.GetNumberRows():
       
   115             name = str(self.data[row].get(self.GetColLabelValue(col), ""))
       
   116             return name
       
   117     
       
   118     def GetValueByName(self, row, colname):
       
   119         return self.data[row].get(colname)
       
   120 
       
   121     def SetValue(self, row, col, value):
       
   122         if col < len(self.colnames):
       
   123             self.data[row][self.GetColLabelValue(col)] = value
       
   124         
       
   125     def ResetView(self, grid):
       
   126         """
       
   127         (wxGrid) -> Reset the grid view.   Call this to
       
   128         update the grid if rows and columns have been added or deleted
       
   129         """
       
   130         grid.BeginBatch()
       
   131         for current, new, delmsg, addmsg in [
       
   132             (self._rows, self.GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED),
       
   133             (self._cols, self.GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED),
       
   134         ]:
       
   135             if new < current:
       
   136                 msg = wx.grid.GridTableMessage(self,delmsg,new,current-new)
       
   137                 grid.ProcessTableMessage(msg)
       
   138             elif new > current:
       
   139                 msg = wx.grid.GridTableMessage(self,addmsg,new-current)
       
   140                 grid.ProcessTableMessage(msg)
       
   141                 self.UpdateValues(grid)
       
   142         grid.EndBatch()
       
   143 
       
   144         self._rows = self.GetNumberRows()
       
   145         self._cols = self.GetNumberCols()
       
   146         # update the column rendering scheme
       
   147         self._updateColAttrs(grid)
       
   148 
       
   149         # update the scrollbars and the displayed part of the grid
       
   150         grid.AdjustScrollbars()
       
   151         grid.ForceRefresh()
       
   152 
       
   153     def UpdateValues(self, grid):
       
   154         """Update all displayed values"""
       
   155         # This sends an event to the grid table to update all of the values
       
   156         msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
       
   157         grid.ProcessTableMessage(msg)
       
   158 
       
   159     def _updateColAttrs(self, grid):
       
   160         """
       
   161         wxGrid -> update the column attributes to add the
       
   162         appropriate renderer given the column name.
       
   163 
       
   164         Otherwise default to the default renderer.
       
   165         """
       
   166         
       
   167         for row in range(self.GetNumberRows()):
       
   168             for col in range(self.GetNumberCols()):
       
   169                 editor = None
       
   170                 renderer = None
       
   171                 align = wx.ALIGN_LEFT
       
   172                 colname = self.GetColLabelValue(col)
       
   173                 grid.SetReadOnly(row, col, False)
       
   174                 
       
   175                 if colname == "Value":
       
   176                     colSize = 100
       
   177                     value_type = self.data[row]["Type"]
       
   178                     if isinstance(value_type, types.ListType):
       
   179                         editor = wx.grid.GridCellChoiceEditor()
       
   180                         editor.SetParameters(",".join(value_type))
       
   181                     elif value_type == "boolean":
       
   182                         editor = wx.grid.GridCellChoiceEditor()
       
   183                         editor.SetParameters("True,False")
       
   184                     elif value_type in ["unsignedLong","long","integer"]:
       
   185                         editor = wx.grid.GridCellNumberEditor()
       
   186                         align = wx.ALIGN_RIGHT
       
   187                     elif value_type == "decimal":
       
   188                         editor = wx.grid.GridCellFloatEditor()
       
   189                         align = wx.ALIGN_RIGHT
       
   190                     else:
       
   191                         editor = wx.grid.GridCellTextEditor()
       
   192                 else:
       
   193                     colSize = 120
       
   194                     grid.SetReadOnly(row, col, True)
       
   195                 
       
   196                 attr = wx.grid.GridCellAttr()
       
   197                 attr.SetAlignment(align, wx.ALIGN_CENTRE)
       
   198                 grid.SetColAttr(col, attr)
       
   199                 grid.SetColSize(col, colSize)
       
   200                                     
       
   201                 grid.SetCellEditor(row, col, editor)
       
   202                 grid.SetCellRenderer(row, col, renderer)
       
   203                 
       
   204                 grid.SetCellBackgroundColour(row, col, wx.WHITE)
       
   205     
       
   206     def SetData(self, data):
       
   207         self.data = data
       
   208     
       
   209     def GetData(self):
       
   210         return self.data
       
   211     
       
   212     def AppendRow(self, row_content):
       
   213         self.data.append(row_content)
       
   214 
       
   215     def RemoveRow(self, row_index):
       
   216         self.data.pop(row_index)
       
   217 
       
   218     def GetRow(self, row_index):
       
   219         return self.data[row_index]
       
   220 
       
   221     def Empty(self):
       
   222         self.data = []
       
   223 
    82 
   224 [ID_BEREMIZ, ID_BEREMIZMAINSPLITTER, 
    83 [ID_BEREMIZ, ID_BEREMIZMAINSPLITTER, 
   225  ID_BEREMIZSECONDSPLITTER, ID_BEREMIZLEFTPANEL, 
    84  ID_BEREMIZSECONDSPLITTER, ID_BEREMIZLEFTPANEL, 
   226  ID_BEREMIZPARAMSPANEL, ID_BEREMIZLOGCONSOLE, 
    85  ID_BEREMIZPARAMSPANEL, ID_BEREMIZLOGCONSOLE, 
   227  ID_BEREMIZPLUGINTREE, ID_BEREMIZPLUGINCHILDS, 
    86  ID_BEREMIZPLUGINTREE, ID_BEREMIZPLUGINCHILDS, 
   356         parent.AddWindow(self.DeleteButton, 0, border=0, flag=0)
   215         parent.AddWindow(self.DeleteButton, 0, border=0, flag=0)
   357         
   216         
   358     def _init_coll_ButtonGridSizer_Growables(self, parent):
   217     def _init_coll_ButtonGridSizer_Growables(self, parent):
   359         parent.AddGrowableCol(0)
   218         parent.AddGrowableCol(0)
   360         parent.AddGrowableRow(0)
   219         parent.AddGrowableRow(0)
   361     
       
   362     def _init_coll_ParamsPanelMainSizer_Items(self, parent):
       
   363         parent.AddSizer(self.ParamsPanelChildSizer, 1, border=10, flag=wx.GROW|wx.ALL)
       
   364         parent.AddSizer(self.ParamsPanelPluginSizer, 1, border=10, flag=wx.GROW|wx.ALL)
       
   365         parent.AddWindow(self.AttributesGrid, 2, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT|wx.BOTTOM)
       
   366         
       
   367     def _init_coll_ParamsPanelChildSizer_Items(self, parent):
       
   368         parent.AddWindow(self.ParamsEnable, 0, border=5, flag=wx.GROW|wx.BOTTOM)
       
   369         parent.AddWindow(self.ParamsStaticText1, 0, border=5, flag=wx.GROW|wx.BOTTOM)
       
   370         parent.AddWindow(self.ParamsIECChannel, 0, border=0, flag=wx.GROW)
       
   371     
       
   372     def _init_coll_ParamsPanelPluginSizer_Items(self, parent):
       
   373         parent.AddWindow(self.ParamsStaticText2, 0, border=5, flag=wx.GROW|wx.BOTTOM)
       
   374         parent.AddWindow(self.ParamsTargetType, 0, border=0, flag=wx.GROW)
       
   375         
   220         
   376     def _init_sizers(self):
   221     def _init_sizers(self):
   377         self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=2, rows=2, vgap=2)
   222         self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=2, rows=2, vgap=2)
   378         self.ButtonGridSizer = wx.FlexGridSizer(cols=3, hgap=2, rows=1, vgap=2)
   223         self.ButtonGridSizer = wx.FlexGridSizer(cols=3, hgap=2, rows=1, vgap=2)
   379         self.ParamsPanelMainSizer = wx.StaticBoxSizer(self.ParamsStaticBox, wx.HORIZONTAL)
   224         self.ParamsPanelMainSizer = wx.BoxSizer(wx.VERTICAL)
   380         self.ParamsPanelChildSizer = wx.BoxSizer(wx.VERTICAL)
       
   381         self.ParamsPanelPluginSizer = wx.BoxSizer(wx.VERTICAL)
       
   382         
   225         
   383         self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer)
   226         self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer)
   384         self._init_coll_LeftGridSizer_Items(self.LeftGridSizer)
   227         self._init_coll_LeftGridSizer_Items(self.LeftGridSizer)
   385         self._init_coll_ButtonGridSizer_Growables(self.ButtonGridSizer)
   228         self._init_coll_ButtonGridSizer_Growables(self.ButtonGridSizer)
   386         self._init_coll_ButtonGridSizer_Items(self.ButtonGridSizer)
   229         self._init_coll_ButtonGridSizer_Items(self.ButtonGridSizer)
   387         self._init_coll_ParamsPanelMainSizer_Items(self.ParamsPanelMainSizer)
       
   388         self._init_coll_ParamsPanelChildSizer_Items(self.ParamsPanelChildSizer)
       
   389         self._init_coll_ParamsPanelPluginSizer_Items(self.ParamsPanelPluginSizer)
       
   390         
   230         
   391         self.LeftPanel.SetSizer(self.LeftGridSizer)
   231         self.LeftPanel.SetSizer(self.LeftGridSizer)
   392         self.ParamsPanel.SetSizer(self.ParamsPanelMainSizer)
   232         self.ParamsPanel.SetSizer(self.ParamsPanelMainSizer)
   393     
   233     
   394     def _init_ctrls(self, prnt):
   234     def _init_ctrls(self, prnt):
   439         self.SecondSplitter.SetMinimumPaneSize(1)
   279         self.SecondSplitter.SetMinimumPaneSize(1)
   440         
   280         
   441         self.MainSplitter.SplitVertically(self.LeftPanel, self.SecondSplitter,
   281         self.MainSplitter.SplitVertically(self.LeftPanel, self.SecondSplitter,
   442               300)
   282               300)
   443         
   283         
   444         self.ParamsPanel = wx.Panel(id=ID_BEREMIZPARAMSPANEL, 
   284         self.ParamsPanel = wx.ScrolledWindow(id=ID_BEREMIZPARAMSPANEL, 
   445               name='ParamsPanel', parent=self.SecondSplitter, pos=wx.Point(0, 0),
   285               name='ParamsPanel', parent=self.SecondSplitter, pos=wx.Point(0, 0),
   446               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
   286               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.VSCROLL)
   447         
   287         
   448         self.ParamsStaticBox = wx.StaticBox(id=ID_BEREMIZPARAMSSTATICBOX,
       
   449               label='', name='staticBox1', parent=self.ParamsPanel,
       
   450               pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0)
       
   451         
       
   452         self.ParamsEnable = wx.CheckBox(id=ID_BEREMIZPARAMSENABLE,
       
   453               label='Plugin enabled', name='ParamsEnable', parent=self.ParamsPanel,
       
   454               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
   455         self.Bind(wx.EVT_CHECKBOX, self.OnParamsEnableChanged, id=ID_BEREMIZPARAMSENABLE)
       
   456         
       
   457         self.ParamsStaticText1 = wx.StaticText(id=ID_BEREMIZPARAMSSTATICTEXT1,
       
   458               label='IEC Channel:', name='ParamsStaticText1', parent=self.ParamsPanel,
       
   459               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
   460         
       
   461         self.ParamsIECChannel = wx.SpinCtrl(id=ID_BEREMIZPARAMSIECCHANNEL,
       
   462               name='ParamsIECChannel', parent=self.ParamsPanel, pos=wx.Point(0, 0),
       
   463               size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0)
       
   464         self.Bind(wx.EVT_SPINCTRL, self.OnParamsIECChannelChanged, id=ID_BEREMIZPARAMSIECCHANNEL)
       
   465 
       
   466         self.ParamsStaticText2 = wx.StaticText(id=ID_BEREMIZPARAMSSTATICTEXT2,
       
   467               label='Target Type:', name='ParamsStaticText2', parent=self.ParamsPanel,
       
   468               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
   469 
       
   470         self.ParamsTargetType = wx.Choice(id=ID_BEREMIZPARAMSTARGETTYPE, 
       
   471               name='TargetType', choices=[""], parent=self.ParamsPanel, 
       
   472               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.LB_SINGLE)
       
   473         self.Bind(wx.EVT_CHOICE, self.OnParamsTargetTypeChanged, id=ID_BEREMIZPARAMSTARGETTYPE)
       
   474 
       
   475         self.AttributesGrid = wx.grid.Grid(id=ID_BEREMIZPARAMSATTRIBUTESGRID,
       
   476               name='AttributesGrid', parent=self.ParamsPanel, pos=wx.Point(0, 0), 
       
   477               size=wx.Size(0, 150), style=wx.VSCROLL)
       
   478         self.AttributesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
       
   479               'Sans'))
       
   480         self.AttributesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
       
   481               False, 'Sans'))
       
   482         self.AttributesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnAttributesGridCellChange)
       
   483 
       
   484         self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='',
   288         self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='',
   485               name='LogConsole', parent=self.SecondSplitter, pos=wx.Point(0, 0),
   289               name='LogConsole', parent=self.SecondSplitter, pos=wx.Point(0, 0),
   486               size=wx.Size(0, 0), style=wx.TE_MULTILINE|wx.TE_RICH2)
   290               size=wx.Size(0, 0), style=wx.TE_MULTILINE|wx.TE_RICH2)
   487         
   291         
   488         self.SecondSplitter.SplitHorizontally(self.ParamsPanel, self.LogConsole,
   292         self.SecondSplitter.SplitHorizontally(self.ParamsPanel, self.LogConsole,
   494         self._init_ctrls(parent)
   298         self._init_ctrls(parent)
   495         
   299         
   496         self.Log = LogPseudoFile(self.LogConsole)
   300         self.Log = LogPseudoFile(self.LogConsole)
   497         
   301         
   498         self.PluginRoot = PluginsRoot()
   302         self.PluginRoot = PluginsRoot()
   499         for value in self.PluginRoot.GetTargetTypes():
       
   500             self.ParamsTargetType.Append(value)
       
   501         
       
   502         self.Table = AttributesTable(self, [], ["Attribute", "Value"])
       
   503         self.AttributesGrid.SetTable(self.Table)
       
   504         self.AttributesGrid.SetRowLabelSize(0)
       
   505         
   303         
   506         if projectOpen:
   304         if projectOpen:
   507             self.PluginRoot.LoadProject(projectOpen)
   305             self.PluginRoot.LoadProject(projectOpen)
   508             self.RefreshPluginTree()
   306             self.RefreshPluginTree()
   509         
   307         
   620             self.AddButton.Enable(False)
   418             self.AddButton.Enable(False)
   621             self.DeleteButton.Enable(False)
   419             self.DeleteButton.Enable(False)
   622         else:
   420         else:
   623             # Refresh ParamsPanel
   421             # Refresh ParamsPanel
   624             self.ParamsPanel.Show()
   422             self.ParamsPanel.Show()
   625             self.ParamsStaticBox.SetLabel(plugin.BaseParams.getName())
   423             infos = plugin.GetParamsAttributes()
   626             if plugin == self.PluginRoot:
   424             self.RefreshSizerElement(self.ParamsPanelMainSizer, infos, None)
   627                 self.ParamsPanelMainSizer.Hide(self.ParamsPanelChildSizer)
       
   628                 self.ParamsPanelMainSizer.Show(self.ParamsPanelPluginSizer)
       
   629                 self.ParamsTargetType.SetStringSelection(self.PluginRoot.GetTargetType())
       
   630             else:
       
   631                 self.ParamsPanelMainSizer.Show(self.ParamsPanelChildSizer)
       
   632                 self.ParamsPanelMainSizer.Hide(self.ParamsPanelPluginSizer)
       
   633                 self.ParamsEnable.SetValue(plugin.BaseParams.getEnabled())
       
   634                 self.ParamsEnable.Enable(True)
       
   635                 self.ParamsStaticText1.Enable(True)
       
   636                 self.ParamsIECChannel.SetValue(plugin.BaseParams.getIEC_Channel())
       
   637                 self.ParamsIECChannel.Enable(True)
       
   638             self.ParamsPanelMainSizer.Layout()
   425             self.ParamsPanelMainSizer.Layout()
   639             self.RefreshAttributesGrid()
       
   640             
   426             
   641             # Refresh PluginChilds
   427             # Refresh PluginChilds
   642             self.PluginChilds.Clear()
   428             self.PluginChilds.Clear()
   643             if len(plugin.PlugChildsTypes) > 0:
   429             if len(plugin.PlugChildsTypes) > 0:
   644                 self.PluginChilds.Append("")
   430                 self.PluginChilds.Append("")
   649             else:
   435             else:
   650                 self.PluginChilds.Enable(False)
   436                 self.PluginChilds.Enable(False)
   651                 self.AddButton.Enable(False)
   437                 self.AddButton.Enable(False)
   652             self.DeleteButton.Enable(True)
   438             self.DeleteButton.Enable(True)
   653     
   439     
       
   440     def GetChoiceCallBackFunction(self, choicectrl, path):
       
   441         def OnChoiceChanged(event):
       
   442             plugin = self.GetSelectedPlugin()
       
   443             if plugin:
       
   444                 plugin.SetParamsAttribute(path, choicectrl.GetStringSelection())
       
   445             event.Skip()
       
   446         return OnChoiceChanged
       
   447     
       
   448     def GetChoiceContentCallBackFunction(self, choicectrl, staticboxsizer, path):
       
   449         def OnChoiceContentChanged(event):
       
   450             plugin = self.GetSelectedPlugin()
       
   451             if plugin:
       
   452                 plugin.SetParamsAttribute(path, choicectrl.GetStringSelection())
       
   453                 infos = self.PluginRoot.GetParamsAttributes(path)
       
   454                 staticbox = staticboxsizer.GetStaticBox()
       
   455                 staticbox.SetLabel("%(name)s - %(value)s"%infos)
       
   456                 self.RefreshSizerElement(staticboxsizer, infos["children"], "%s.%s"%(path, infos["name"]))
       
   457                 self.ParamsPanelMainSizer.Layout()
       
   458             event.Skip()
       
   459         return OnChoiceContentChanged
       
   460     
       
   461     def GetTextCtrlCallBackFunction(self, textctrl, path):
       
   462         def OnTextCtrlChanged(event):
       
   463             plugin = self.GetSelectedPlugin()
       
   464             if plugin:
       
   465                 plugin.SetParamsAttribute(path, textctrl.GetValue())
       
   466             event.Skip()
       
   467         return OnTextCtrlChanged
       
   468     
       
   469     def GetCheckBoxCallBackFunction(self, textctrl, path):
       
   470         def OnCheckBoxChanged(event):
       
   471             plugin = self.GetSelectedPlugin()
       
   472             if plugin:
       
   473                 plugin.SetParamsAttribute(path, textctrl.IsChecked())
       
   474             event.Skip()
       
   475         return OnCheckBoxChanged
       
   476     
       
   477     def ClearSizer(self, sizer):
       
   478         staticboxes = []
       
   479         for item in sizer.GetChildren():
       
   480             if item.IsSizer():
       
   481                 item_sizer = item.GetSizer()
       
   482                 self.ClearSizer(item_sizer)
       
   483                 if isinstance(item_sizer, wx.StaticBoxSizer):
       
   484                     staticboxes.append(item_sizer.GetStaticBox())
       
   485         sizer.Clear(True)
       
   486         for staticbox in staticboxes:
       
   487             staticbox.Destroy()
       
   488                 
       
   489     def RefreshSizerElement(self, sizer, elements, path):
       
   490         self.ClearSizer(sizer)
       
   491         first = True
       
   492         for element_infos in elements:
       
   493             if path:
       
   494                 element_path = "%s.%s"%(path, element_infos["name"])
       
   495             else:
       
   496                 element_path = element_infos["name"]
       
   497             if isinstance(element_infos["type"], types.ListType):
       
   498                 boxsizer = wx.BoxSizer(wx.HORIZONTAL)
       
   499                 if first:
       
   500                     sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.ALL)
       
   501                 else:
       
   502                     sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
       
   503                 statictext = wx.StaticText(id=-1, label="%s:"%element_infos["name"], 
       
   504                     name="%s_label"%element_infos["name"], parent=self.ParamsPanel, 
       
   505                     pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0)
       
   506                 boxsizer.AddWindow(statictext, 0, border=0, flag=0)
       
   507                 id = wx.NewId()
       
   508                 choicectrl = wx.Choice(id=id, name=element_infos["name"], parent=self.ParamsPanel, 
       
   509                     pos=wx.Point(0, 0), size=wx.Size(150, 25), style=0)
       
   510                 boxsizer.AddWindow(choicectrl, 0, border=0, flag=0)
       
   511                 choicectrl.Append("")
       
   512                 if len(element_infos["type"]) > 0 and isinstance(element_infos["type"][0], types.TupleType):
       
   513                     for choice, xsdclass in element_infos["type"]:
       
   514                         choicectrl.Append(choice)
       
   515                     staticbox = wx.StaticBox(id=-1, label="%(name)s - %(value)s"%element_infos, 
       
   516                         name='%s_staticbox'%element_infos["name"], parent=self.ParamsPanel,
       
   517                         pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0)
       
   518                     staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL)
       
   519                     sizer.AddSizer(staticboxsizer, 0, border=0, flag=wx.GROW)
       
   520                     self.RefreshSizerElement(staticboxsizer, element_infos["children"], element_path)
       
   521                     callback = self.GetChoiceContentCallBackFunction(choicectrl, staticboxsizer, element_path)
       
   522                 else:
       
   523                     for choice in element_infos["type"]:
       
   524                         choicectrl.Append(choice)
       
   525                     callback = self.GetChoiceCallBackFunction(choicectrl, element_path)
       
   526                 choicectrl.Bind(wx.EVT_CHOICE, callback, id=id)
       
   527                 choicectrl.SetStringSelection(element_infos["value"])
       
   528             elif isinstance(element_infos["type"], types.DictType):
       
   529                 boxsizer = wx.BoxSizer(wx.HORIZONTAL)
       
   530                 if first:
       
   531                     sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.ALL)
       
   532                 else:
       
   533                     sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
       
   534                 statictext = wx.StaticText(id=-1, label="%s:"%element_infos["name"], 
       
   535                     name="%s_label"%element_infos["name"], parent=self.ParamsPanel, 
       
   536                     pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0)
       
   537                 boxsizer.AddWindow(statictext, 0, border=0, flag=wx.TOP|wx.LEFT|wx.BOTTOM)
       
   538                 id = wx.NewId()
       
   539                 min = max = -1
       
   540                 if "min" in element_infos["type"]:
       
   541                     min = element_infos["type"]["min"]
       
   542                 if "max" in element_infos["type"]:
       
   543                     max = element_infos["type"]["max"]
       
   544                 spinctrl = wx.SpinCtrl(id=id, name=element_infos["name"], parent=self.ParamsPanel, 
       
   545                     pos=wx.Point(0, 0), size=wx.Size(150, 25), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT, 
       
   546                     min=min, max=max)
       
   547                 boxsizer.AddWindow(spinctrl, 0, border=0, flag=0)
       
   548                 spinctrl.Bind(wx.EVT_SPINCTRL, self.GetTextCtrlCallBackFunction(spinctrl, element_path), id=id)
       
   549                 spinctrl.SetValue(element_infos["value"])
       
   550             elif element_infos["type"] == "element":
       
   551                 staticbox = wx.StaticBox(id=-1, label=element_infos["name"], 
       
   552                     name='%s_staticbox'%element_infos["name"], parent=self.ParamsPanel,
       
   553                     pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0)
       
   554                 staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL)
       
   555                 if first:
       
   556                     sizer.AddSizer(staticboxsizer, 0, border=0, flag=wx.GROW|wx.TOP)
       
   557                 else:
       
   558                     sizer.AddSizer(staticboxsizer, 0, border=0, flag=wx.GROW)
       
   559                 self.RefreshSizerElement(staticboxsizer, element_infos["children"], element_path)
       
   560             else:
       
   561                 boxsizer = wx.BoxSizer(wx.HORIZONTAL)
       
   562                 if first:
       
   563                     sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.ALL)
       
   564                 else:
       
   565                     sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
       
   566                 statictext = wx.StaticText(id=-1, label="%s:"%element_infos["name"], 
       
   567                     name="%s_label"%element_infos["name"], parent=self.ParamsPanel, 
       
   568                     pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0)
       
   569                 boxsizer.AddWindow(statictext, 0, border=0, flag=0)
       
   570                 id = wx.NewId()
       
   571                 if element_infos["type"] == "boolean":
       
   572                     checkbox = wx.CheckBox(id=id, name=element_infos["name"], parent=self.ParamsPanel, 
       
   573                         pos=wx.Point(0, 0), size=wx.Size(17, 25), style=0)
       
   574                     boxsizer.AddWindow(checkbox, 0, border=0, flag=0)
       
   575                     checkbox.Bind(wx.EVT_CHECKBOX, self.GetCheckBoxCallBackFunction(checkbox, element_path), id=id)
       
   576                     checkbox.SetValue(element_infos["value"])
       
   577                 elif element_infos["type"] in ["unsignedLong", "long","integer"]:
       
   578                     spinctrl = wx.SpinCtrl(id=id, name=element_infos["name"], parent=self.ParamsPanel, 
       
   579                         pos=wx.Point(0, 0), size=wx.Size(150, 25), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT)
       
   580                     boxsizer.AddWindow(spinctrl, 0, border=0, flag=0)
       
   581                     spinctrl.Bind(wx.EVT_SPINCTRL, self.GetTextCtrlCallBackFunction(spinctrl, element_path), id=id)
       
   582                     spinctrl.SetValue(element_infos["value"])
       
   583                 else:
       
   584                     textctrl = wx.TextCtrl(id=id, name=element_infos["name"], parent=self.ParamsPanel, 
       
   585                         pos=wx.Point(0, 0), size=wx.Size(150, 25), style=0)
       
   586                     boxsizer.AddWindow(textctrl, 0, border=0, flag=0)
       
   587                     textctrl.Bind(wx.EVT_TEXT, self.GetTextCtrlCallBackFunction(textctrl, element_path), id=id)
       
   588                     textctrl.SetValue(str(element_infos["value"]))
       
   589             first = False
       
   590     
       
   591     def UpdateAttributesTreeParts(self, tree, new_tree):
       
   592         tree_leafs = [(element_infos["name"], element_infos["type"]) for element_infos in tree["children"]]
       
   593         new_tree_leafs = [(element_infos["name"], element_infos["type"]) for element_infos in new_tree["children"]]
       
   594         if tree_leafs != new_tree_leafs:
       
   595             tree["children"] = new_tree["children"]
       
   596             for child in tree["children"]:
       
   597                 self.PrepareAttributesTree(child)
       
   598         else:
       
   599             for idx, new_element_infos in enumerate(new_tree["children"]):
       
   600                 tree["children"][idx]["value"] = new_element_infos["value"]
       
   601                 if len(new_element_infos["children"]) > 0:
       
   602                     self.UpdateAttributesTreeParts(tree["children"][idx], new_element_infos)
       
   603     
       
   604     def PrepareAttributesTree(self, tree):
       
   605         if len(tree["children"]) > 0:
       
   606             tree["open"] = False
       
   607             for child in tree["children"]:
       
   608                 self.PrepareAttributesTree(child)
       
   609     
       
   610     def GenerateTable(self, data, tree, path, indent):
       
   611         if path:
       
   612             tree_path = "%s.%s"%(path, tree["name"])
       
   613             infos = {"Attribute" : "   " * indent + tree["name"], "Value" : tree["value"], "Type" : tree["type"], "Open" : "", "Path" : tree_path}
       
   614             data.append(infos)
       
   615             indent += 1
       
   616         else:
       
   617             tree_path = tree["name"]
       
   618         if len(tree["children"]) > 0:
       
   619             if tree["open"] or not path:
       
   620                 if path:
       
   621                     infos["Open"] = "v"
       
   622                 for child in tree["children"]:
       
   623                     self.GenerateTable(data, child, tree_path, indent)
       
   624             elif path:
       
   625                 infos["Open"] = ">"
       
   626     
   654     def RefreshAttributesGrid(self):
   627     def RefreshAttributesGrid(self):
   655         plugin = self.GetSelectedPlugin()
   628         plugin = self.GetSelectedPlugin()
   656         if not plugin:
   629         if not plugin:
       
   630             self.AttributesTree = []
   657             self.Table.Empty()
   631             self.Table.Empty()
   658         else:
   632         else:
   659             if plugin == self.PluginRoot:
   633             new_params = plugin.GetParamsAttributes()
   660                 attr_infos = self.PluginRoot.GetTargetAttributes()
   634             for idx, child in enumerate(new_params):
   661             else:
   635                 if len(self.AttributesTree) > idx:
   662                 attr_infos = plugin.GetPlugParamsAttributes()
   636                     if self.AttributesTree[idx]["name"] == child["name"]:
       
   637                         self.UpdateAttributesTreeParts(self.AttributesTree[idx], child)
       
   638                     else:
       
   639                         self.AttributesTree[idx] = child
       
   640                         self.PrepareAttributesTree(child)
       
   641                 else:
       
   642                     self.AttributesTree.append(child)
       
   643                     self.PrepareAttributesTree(child)
       
   644             while len(self.AttributesTree) > len(new_params):
       
   645                 self.AttributesTree.pop(-1)
   663             data = []
   646             data = []
   664             for infos in attr_infos:
   647             for child in self.AttributesTree:
   665                 data.append({"Attribute" : infos["name"], "Value" : infos["value"],
   648                 self.GenerateTable(data, child, None, 0)
   666                     "Type" : infos["type"]})
       
   667             self.Table.SetData(data)
   649             self.Table.SetData(data)
   668         self.Table.ResetView(self.AttributesGrid)
   650         self.Table.ResetView(self.AttributesGrid)
       
   651     
       
   652     def OpenClose(self, tree, path):
       
   653         parts = path.split(".", 1)
       
   654         for child in tree["children"]:
       
   655             if child["name"] == parts[0]:
       
   656                 if len(parts) > 1:
       
   657                     return self.OpenClose(child, parts[1])
       
   658                 elif len(child["children"]) > 0:
       
   659                     child["open"] = not child["open"]
       
   660                     return True
       
   661         return False
       
   662     
       
   663     def OpenCloseAttribute(self):
       
   664         if self.AttributesGrid.GetGridCursorCol() == 0:
       
   665             row = self.AttributesGrid.GetGridCursorRow()
       
   666             path = self.Table.GetValueByName(row, "Path")
       
   667             parts = path.split(".", 1)
       
   668             for child in self.AttributesTree:
       
   669                 if child["name"] == parts[0] and len(parts) > 1:
       
   670                     result = self.OpenClose(child, parts[1])
       
   671                     if result:
       
   672                         self.RefreshAttributesGrid()
   669     
   673     
   670     def OnParamsEnableChanged(self, event):
   674     def OnParamsEnableChanged(self, event):
   671         plugin = self.GetSelectedPlugin()
   675         plugin = self.GetSelectedPlugin()
   672         if plugin and plugin != self.PluginRoot:
   676         if plugin and plugin != self.PluginRoot:
   673             plugin.BaseParams.setEnabled(event.Checked())
   677             plugin.BaseParams.setEnabled(event.Checked())
   688     
   692     
   689     def OnAttributesGridCellChange(self, event):
   693     def OnAttributesGridCellChange(self, event):
   690         row = event.GetRow()
   694         row = event.GetRow()
   691         plugin = self.GetSelectedPlugin()
   695         plugin = self.GetSelectedPlugin()
   692         if plugin:
   696         if plugin:
   693             name = self.Table.GetValueByName(row, "Attribute")
   697             path = self.Table.GetValueByName(row, "Path")
   694             value = self.Table.GetValueByName(row, "Value")
   698             value = self.Table.GetValueByName(row, "Value")
   695             if plugin == self.PluginRoot:
   699             plugin.SetParamsAttribute(path, value)
   696                 self.PluginRoot.SetTargetAttribute(name, value)
   700             print plugin.GetParamsAttributes(path)
   697             else:
   701             self.RefreshAttributesGrid()
   698                 plugin.SetPlugParamsAttribute(name, value)
   702         event.Skip()
       
   703     
       
   704     def OnAttributesGridCellLeftClick(self, event):
       
   705         wx.CallAfter(self.OpenCloseAttribute)
   699         event.Skip()
   706         event.Skip()
   700     
   707     
   701     def OnNewProjectMenu(self, event):
   708     def OnNewProjectMenu(self, event):
   702         defaultpath = self.PluginRoot.GetProjectPath()
   709         defaultpath = self.PluginRoot.GetProjectPath()
   703         if defaultpath == "":
   710         if defaultpath == "":