Beremiz.py
changeset 21 bded6d31365c
parent 20 d3cb5020997b
child 22 9a0c535c3272
equal deleted inserted replaced
20:d3cb5020997b 21:bded6d31365c
    29 import types
    29 import types
    30 
    30 
    31 import os, re, platform, sys, time, traceback, getopt, commands
    31 import os, re, platform, sys, time, traceback, getopt, commands
    32 
    32 
    33 from plugger import PluginsRoot
    33 from plugger import PluginsRoot
       
    34 
       
    35 def CHECK_WX_VERSION(major, minor, release):
       
    36     return not (wx.MAJOR_VERSION < major or wx.MINOR_VERSION < minor or wx.RELEASE_NUMBER < release)
    34 
    37 
    35 class LogPseudoFile:
    38 class LogPseudoFile:
    36     """ Base class for file like objects to facilitate StdOut for the Shell."""
    39     """ Base class for file like objects to facilitate StdOut for the Shell."""
    37     def __init__(self, output = None):
    40     def __init__(self, output = None):
    38         self.red_white = wx.TextAttr("RED", "WHITE")
    41         self.red_white = wx.TextAttr("RED", "WHITE")
   304         self.MainSplitter.SplitVertically(self.LeftPanel, self.SecondSplitter,
   307         self.MainSplitter.SplitVertically(self.LeftPanel, self.SecondSplitter,
   305               300)
   308               300)
   306         
   309         
   307         self.ParamsPanel = wx.ScrolledWindow(id=ID_BEREMIZPARAMSPANEL, 
   310         self.ParamsPanel = wx.ScrolledWindow(id=ID_BEREMIZPARAMSPANEL, 
   308               name='ParamsPanel', parent=self.SecondSplitter, pos=wx.Point(0, 0),
   311               name='ParamsPanel', parent=self.SecondSplitter, pos=wx.Point(0, 0),
   309               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.VSCROLL)
   312               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
   313         self.ParamsPanel.SetScrollbars(10, 10, 0, 0, 0, 0)
   310         
   314         
   311         self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='',
   315         self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='',
   312               name='LogConsole', parent=self.SecondSplitter, pos=wx.Point(0, 0),
   316               name='LogConsole', parent=self.SecondSplitter, pos=wx.Point(0, 0),
   313               size=wx.Size(0, 0), style=wx.TE_MULTILINE|wx.TE_RICH2)
   317               size=wx.Size(0, 0), style=wx.TE_MULTILINE|wx.TE_RICH2)
   314         
   318         
   358                 self.FileMenu.Enable(ID_BEREMIZFILEMENUITEMS5, False)
   362                 self.FileMenu.Enable(ID_BEREMIZFILEMENUITEMS5, False)
   359 
   363 
   360     def RefreshPluginTree(self):
   364     def RefreshPluginTree(self):
   361         infos = self.PluginRoot.GetPlugInfos()
   365         infos = self.PluginRoot.GetPlugInfos()
   362         root = self.PluginTree.GetRootItem()
   366         root = self.PluginTree.GetRootItem()
   363         self.GenerateTreeBranch(root, infos)
   367         if not root.IsOk():
       
   368             root = self.PluginTree.AddRoot(infos["name"])
       
   369         self.GenerateTreeBranch(root, infos, True)
   364         self.PluginTree.Expand(self.PluginTree.GetRootItem())
   370         self.PluginTree.Expand(self.PluginTree.GetRootItem())
   365         self.RefreshPluginParams()
   371         self.RefreshPluginParams()
   366 
   372 
   367     def GenerateTreeBranch(self, root, infos):
   373     def GenerateTreeBranch(self, root, infos, first = False):
   368         to_delete = []
   374         to_delete = []
   369         if root.IsOk():
   375         self.PluginTree.SetItemText(root, infos["name"])
   370             self.PluginTree.SetItemText(root, infos["name"])
       
   371         else:
       
   372             root = self.PluginTree.AddRoot(infos["name"])
       
   373         self.PluginTree.SetPyData(root, infos["type"])
   376         self.PluginTree.SetPyData(root, infos["type"])
   374         item, root_cookie = self.PluginTree.GetFirstChild(root)
   377         item, root_cookie = self.PluginTree.GetFirstChild(root)
   375         if len(infos["values"]) > 0:
   378         for values in infos["values"]:
   376             for values in infos["values"]:
   379             if not item.IsOk():
   377                 if not item.IsOk():
   380                 item = self.PluginTree.AppendItem(root, "")
   378                     item = self.PluginTree.AppendItem(root, "")
   381                 if wx.VERSION < (2, 7, 0):
   379                     item, root_cookie = self.PluginTree.GetNextChild(root, root_cookie)
   382                     item, root_cookie = self.PluginTree.GetNextChild(root, root_cookie)
   380                 self.GenerateTreeBranch(item, values)
   383             self.GenerateTreeBranch(item, values)
   381                 item, root_cookie = self.PluginTree.GetNextChild(root, root_cookie)
   384             item, root_cookie = self.PluginTree.GetNextChild(root, root_cookie)
   382         while item.IsOk():
   385         while item.IsOk():
   383             to_delete.append(item)
   386             to_delete.append(item)
   384             item, root_cookie = self.PluginTree.GetNextChild(root, root_cookie)
   387             item, root_cookie = self.PluginTree.GetNextChild(root, root_cookie)
   385         for item in to_delete:
   388         for item in to_delete:
   386             self.PluginTree.Delete(item)
   389             self.PluginTree.Delete(item)
   441         else:
   444         else:
   442             # Refresh ParamsPanel
   445             # Refresh ParamsPanel
   443             self.ParamsPanel.Show()
   446             self.ParamsPanel.Show()
   444             infos = plugin.GetParamsAttributes()
   447             infos = plugin.GetParamsAttributes()
   445             self.RefreshSizerElement(self.ParamsPanelMainSizer, infos, None)
   448             self.RefreshSizerElement(self.ParamsPanelMainSizer, infos, None)
       
   449             if len(plugin.PluginMethods) > 0:
       
   450                 boxsizer = wx.BoxSizer(wx.HORIZONTAL)
       
   451                 self.ParamsPanelMainSizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.ALL)
       
   452                 for name, method in plugin.PluginMethods:
       
   453                     if method:
       
   454                         id = wx.NewId()
       
   455                         button = wx.Button(id=id, label=name, name=name, parent=self.ParamsPanel, 
       
   456                             pos=wx.Point(0, 0), style=wx.BU_EXACTFIT)
       
   457                         button.Bind(wx.EVT_BUTTON, self.GetButtonCallBackFunction(plugin, method), id=id)
       
   458                         boxsizer.AddWindow(button, 0, border=5, flag=wx.GROW|wx.RIGHT)
   446             self.ParamsPanelMainSizer.Layout()
   459             self.ParamsPanelMainSizer.Layout()
   447             
   460             
   448             # Refresh PluginChilds
   461             # Refresh PluginChilds
   449             self.PluginChilds.Clear()
   462             self.PluginChilds.Clear()
   450             if len(plugin.PlugChildsTypes) > 0:
   463             if len(plugin.PlugChildsTypes) > 0:
   456             else:
   469             else:
   457                 self.PluginChilds.Enable(False)
   470                 self.PluginChilds.Enable(False)
   458                 self.AddButton.Enable(False)
   471                 self.AddButton.Enable(False)
   459             self.DeleteButton.Enable(True)
   472             self.DeleteButton.Enable(True)
   460     
   473     
       
   474     def GetButtonCallBackFunction(self, plugin, method):
       
   475         def OnButtonClick(event):
       
   476             method(plugin, self.Log)
       
   477             event.Skip()
       
   478         return OnButtonClick
       
   479     
   461     def GetChoiceCallBackFunction(self, choicectrl, path):
   480     def GetChoiceCallBackFunction(self, choicectrl, path):
   462         def OnChoiceChanged(event):
   481         def OnChoiceChanged(event):
   463             plugin = self.GetSelectedPlugin()
   482             plugin = self.GetSelectedPlugin()
   464             if plugin:
   483             if plugin:
   465                 plugin.SetParamsAttribute(path, choicectrl.GetStringSelection())
   484                 plugin.SetParamsAttribute(path, choicectrl.GetStringSelection())
   472             if plugin:
   491             if plugin:
   473                 plugin.SetParamsAttribute(path, choicectrl.GetStringSelection())
   492                 plugin.SetParamsAttribute(path, choicectrl.GetStringSelection())
   474                 infos = self.PluginRoot.GetParamsAttributes(path)
   493                 infos = self.PluginRoot.GetParamsAttributes(path)
   475                 staticbox = staticboxsizer.GetStaticBox()
   494                 staticbox = staticboxsizer.GetStaticBox()
   476                 staticbox.SetLabel("%(name)s - %(value)s"%infos)
   495                 staticbox.SetLabel("%(name)s - %(value)s"%infos)
       
   496                 self.ParamsPanel.Freeze()
   477                 self.RefreshSizerElement(staticboxsizer, infos["children"], "%s.%s"%(path, infos["name"]))
   497                 self.RefreshSizerElement(staticboxsizer, infos["children"], "%s.%s"%(path, infos["name"]))
   478                 self.ParamsPanelMainSizer.Layout()
   498                 self.ParamsPanelMainSizer.Layout()
       
   499                 self.ParamsPanel.Thaw()
       
   500                 self.ParamsPanel.Refresh()
   479             event.Skip()
   501             event.Skip()
   480         return OnChoiceContentChanged
   502         return OnChoiceContentChanged
   481     
   503     
   482     def GetTextCtrlCallBackFunction(self, textctrl, path):
   504     def GetTextCtrlCallBackFunction(self, textctrl, path):
   483         def OnTextCtrlChanged(event):
   505         def OnTextCtrlChanged(event):
   506         sizer.Clear(True)
   528         sizer.Clear(True)
   507         for staticbox in staticboxes:
   529         for staticbox in staticboxes:
   508             staticbox.Destroy()
   530             staticbox.Destroy()
   509                 
   531                 
   510     def RefreshSizerElement(self, sizer, elements, path):
   532     def RefreshSizerElement(self, sizer, elements, path):
   511         self.ClearSizer(sizer)
   533         if wx.VERSION >= (2, 7, 0):
       
   534             sizer.Clear(True)
       
   535         else:
       
   536             self.ClearSizer(sizer)
   512         first = True
   537         first = True
   513         for element_infos in elements:
   538         for element_infos in elements:
   514             if path:
   539             if path:
   515                 element_path = "%s.%s"%(path, element_infos["name"])
   540                 element_path = "%s.%s"%(path, element_infos["name"])
   516             else:
   541             else:
   727     
   752     
   728     def DeletePlugin(self):
   753     def DeletePlugin(self):
   729         pass
   754         pass
   730 
   755 
   731 #-------------------------------------------------------------------------------
   756 #-------------------------------------------------------------------------------
   732 #                             Add Bus Dialog
       
   733 #-------------------------------------------------------------------------------
       
   734 
       
   735 [ID_ADDBUSDIALOG, ID_ADDBUSDIALOGBUSID, 
       
   736  ID_ADDBUSDIALOGBUSNAME, ID_ADDBUSDIALOGBUSTYPE, 
       
   737  ID_ADDBUSDIALOGSTATICTEXT1, ID_ADDBUSDIALOGSTATICTEXT2, 
       
   738  ID_ADDBUSDIALOGSTATICTEXT3,
       
   739 ] = [wx.NewId() for _init_ctrls in range(7)]
       
   740 
       
   741 class AddBusDialog(wx.Dialog):
       
   742     def _init_coll_flexGridSizer1_Items(self, parent):
       
   743         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
   744         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
   745         
       
   746     def _init_coll_flexGridSizer1_Growables(self, parent):
       
   747         parent.AddGrowableCol(0)
       
   748         parent.AddGrowableRow(0)
       
   749     
       
   750     def _init_coll_MainSizer_Items(self, parent):
       
   751         parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
       
   752         parent.AddWindow(self.BusId, 0, border=0, flag=wx.GROW)
       
   753         parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
       
   754         parent.AddWindow(self.BusType, 0, border=0, flag=wx.GROW)
       
   755         parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
       
   756         parent.AddWindow(self.BusName, 0, border=0, flag=wx.GROW)
       
   757         
       
   758     def _init_coll_MainSizer_Growables(self, parent):
       
   759         parent.AddGrowableCol(1)
       
   760         
       
   761     def _init_sizers(self):
       
   762         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
   763         self.MainSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=3, vgap=15)
       
   764 
       
   765         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
   766         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
   767         self._init_coll_MainSizer_Items(self.MainSizer)
       
   768         self._init_coll_MainSizer_Growables(self.MainSizer)
       
   769 
       
   770         self.SetSizer(self.flexGridSizer1)
       
   771 
       
   772     def _init_ctrls(self, prnt):
       
   773         wx.Dialog.__init__(self, id=ID_ADDBUSDIALOG,
       
   774               name='PouDialog', parent=prnt, pos=wx.Point(376, 183),
       
   775               size=wx.Size(300, 200), style=wx.DEFAULT_DIALOG_STYLE,
       
   776               title='Create a new POU')
       
   777         self.SetClientSize(wx.Size(300, 200))
       
   778 
       
   779         self.staticText1 = wx.StaticText(id=ID_ADDBUSDIALOGSTATICTEXT1,
       
   780               label='Bus ID:', name='staticText1', parent=self,
       
   781               pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0)
       
   782 
       
   783         self.BusId = wx.TextCtrl(id=ID_ADDBUSDIALOGBUSID,
       
   784               name='BusId', parent=self, pos=wx.Point(0, 0), 
       
   785               size=wx.Size(0, 24), style=0)
       
   786 
       
   787         self.staticText2 = wx.StaticText(id=ID_ADDBUSDIALOGSTATICTEXT2,
       
   788               label='Bus Type:', name='staticText2', parent=self,
       
   789               pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0)
       
   790 
       
   791         self.BusType = wx.Choice(id=ID_ADDBUSDIALOGBUSTYPE,
       
   792               name='BusType', parent=self, pos=wx.Point(0, 0),
       
   793               size=wx.Size(0, 24), style=0)
       
   794         
       
   795         self.staticText3 = wx.StaticText(id=ID_ADDBUSDIALOGSTATICTEXT3,
       
   796               label='Bus Name:', name='staticText3', parent=self,
       
   797               pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0)
       
   798 
       
   799         self.BusName = wx.TextCtrl(id=ID_ADDBUSDIALOGBUSNAME,
       
   800               name='BusName', parent=self, pos=wx.Point(0, 0),
       
   801               size=wx.Size(0, 24), style=0)
       
   802         
       
   803         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
   804         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
   805         
       
   806         self._init_sizers()
       
   807 
       
   808     def __init__(self, parent):
       
   809         self._init_ctrls(parent)
       
   810         
       
   811         for option in [""] + plugins.__all__:
       
   812             self.BusType.Append(option)
       
   813     
       
   814     def OnOK(self, event):
       
   815         error = []
       
   816         bus_id = self.BusId.GetValue()
       
   817         if bus_id == "":
       
   818             error.append("Bus ID")
       
   819         if self.BusType.GetStringSelection() == "":
       
   820             error.append("Bus Type")
       
   821         if self.BusName.GetValue() == "":
       
   822             error.append("Bus Name")
       
   823         if len(error) > 0:
       
   824             text = ""
       
   825             for i, item in enumerate(error):
       
   826                 if i == 0:
       
   827                     text += item
       
   828                 elif i == len(error) - 1:
       
   829                     text += " and %s"%item
       
   830                 else:
       
   831                     text += ", %s"%item 
       
   832             message = wxMessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wxOK|wxICON_ERROR)
       
   833             message.ShowModal()
       
   834             message.Destroy()
       
   835         elif bus_id.startswith("0x"):
       
   836             try:
       
   837                 bus_id = int(bus_id, 16)
       
   838                 self.EndModal(wx.ID_OK)
       
   839             except:
       
   840                 message = wxMessageDialog(self, "Bus ID must be a decimal or hexadecimal number!", "Error", wxOK|wxICON_ERROR)
       
   841                 message.ShowModal()
       
   842                 message.Destroy()
       
   843         elif not bus_id.startswith("-"):
       
   844             try:
       
   845                 bus_id = int(bus_id)
       
   846                 self.EndModal(wx.ID_OK)
       
   847             except:
       
   848                 message = wxMessageDialog(self, "Bus ID must be a decimal or hexadecimal number!", "Error", wxOK|wxICON_ERROR)
       
   849                 message.ShowModal()
       
   850                 message.Destroy()
       
   851         else:
       
   852             message = wxMessageDialog(self, "Bus Id must be greater than 0!", "Error", wxOK|wxICON_ERROR)
       
   853             message.ShowModal()
       
   854             message.Destroy()
       
   855 
       
   856     def SetValues(self, values):
       
   857         for item, value in values.items():
       
   858             if item == "busID":
       
   859                 self.BusID.SetValue(value)
       
   860             elif item == "busType":
       
   861                 self.BusType.SetStringSelection(value)
       
   862             elif item == "busName":
       
   863                 self.BusName.SetValue(value)
       
   864                 
       
   865     def GetValues(self):
       
   866         values = {}
       
   867         values["busID"] = self.BusId.GetValue()
       
   868         values["busType"] = self.BusType.GetStringSelection()
       
   869         values["busName"] = self.BusName.GetValue()
       
   870         return values
       
   871 
       
   872 #-------------------------------------------------------------------------------
       
   873 #                               Exception Handler
   757 #                               Exception Handler
   874 #-------------------------------------------------------------------------------
   758 #-------------------------------------------------------------------------------
   875 
   759 
   876 Max_Traceback_List_Size = 20
   760 Max_Traceback_List_Size = 20
   877 
   761