Beremiz.py
changeset 97 9c6fdf60ad2e
parent 94 c7fac98c9351
child 98 d359f0e7a97c
equal deleted inserted replaced
96:0c06f7874a3f 97:9c6fdf60ad2e
    24 
    24 
    25 __version__ = "$Revision$"
    25 __version__ = "$Revision$"
    26 
    26 
    27 import wx
    27 import wx
    28 import wx.lib.buttons
    28 import wx.lib.buttons
    29 if wx.VERSION >= (2, 8, 0):
       
    30     import wx.lib.customtreectrl as CT
       
    31 
    29 
    32 import types
    30 import types
    33 
    31 
    34 import time
    32 import time
    35 
    33 
    37 
    35 
    38 from plugger import PluginsRoot
    36 from plugger import PluginsRoot
    39 
    37 
    40 from wxPopen import wxPopen3
    38 from wxPopen import wxPopen3
    41 
    39 
       
    40 SCROLLBAR_UNIT = 10
       
    41 WINDOW_COLOUR = wx.Colour(240,240,240)
       
    42 
       
    43 if wx.Platform == '__WXMSW__':
       
    44     faces = { 'times': 'Times New Roman',
       
    45               'mono' : 'Courier New',
       
    46               'helv' : 'Arial',
       
    47               'other': 'Comic Sans MS',
       
    48               'size' : 18,
       
    49              }
       
    50 else:
       
    51     faces = { 'times': 'Times',
       
    52               'mono' : 'Courier',
       
    53               'helv' : 'Helvetica',
       
    54               'other': 'new century schoolbook',
       
    55               'size' : 18,
       
    56              }
       
    57 
    42 CWD = os.path.split(os.path.realpath(__file__))[0]
    58 CWD = os.path.split(os.path.realpath(__file__))[0]
    43 
    59 
       
    60 gen_mini_GetBackgroundBrush = lambda obj:lambda dc: wx.Brush(obj.faceDnClr, wx.SOLID)
       
    61 gen_mini_GetLabelSize = lambda obj:lambda:(wx.lib.buttons.GenBitmapTextButton._GetLabelSize(obj)[:-1] + (False,))
       
    62 
       
    63 def GenerateEmptyBitmap():
       
    64     bitmap = wx.EmptyBitmap(24, 24)
       
    65     dc = wx.MemoryDC(bitmap)
       
    66     dc.SetPen(wx.Pen(WINDOW_COLOUR))
       
    67     dc.SetBrush(wx.Brush(WINDOW_COLOUR))
       
    68     dc.DrawRectangle(0, 0, 24, 24)
       
    69     return bitmap
       
    70                         
    44 class LogPseudoFile:
    71 class LogPseudoFile:
    45     """ Base class for file like objects to facilitate StdOut for the Shell."""
    72     """ Base class for file like objects to facilitate StdOut for the Shell."""
    46     def __init__(self, output = None):
    73     def __init__(self, output = None):
    47         self.red_white = wx.TextAttr("RED", "WHITE")
    74         self.red_white = wx.TextAttr("RED", "WHITE")
    48         self.red_yellow = wx.TextAttr("RED", "YELLOW")
    75         self.red_yellow = wx.TextAttr("RED", "YELLOW")
   107         	spin(p)
   134         	spin(p)
   108 
   135 
   109         return (self.exitcode, self.outdata, self.errdata)
   136         return (self.exitcode, self.outdata, self.errdata)
   110 
   137 
   111 [ID_BEREMIZ, ID_BEREMIZMAINSPLITTER, 
   138 [ID_BEREMIZ, ID_BEREMIZMAINSPLITTER, 
   112  ID_BEREMIZSECONDSPLITTER, ID_BEREMIZLEFTPANEL, 
   139  ID_BEREMIZPLCCONFIG, ID_BEREMIZLOGCONSOLE, 
   113  ID_BEREMIZPARAMSPANEL, ID_BEREMIZLOGCONSOLE, 
   140 ] = [wx.NewId() for _init_ctrls in range(4)]
   114  ID_BEREMIZPLUGINTREE, ID_BEREMIZPLUGINCHILDS, 
       
   115  ID_BEREMIZADDBUTTON, ID_BEREMIZDELETEBUTTON,
       
   116  ID_BEREMIZPARAMSSTATICBOX, ID_BEREMIZPARAMSENABLE, 
       
   117  ID_BEREMIZPARAMSTARGETTYPE, ID_BEREMIZPARAMSIECCHANNEL, 
       
   118  ID_BEREMIZPARAMSSTATICTEXT1, ID_BEREMIZPARAMSSTATICTEXT2, 
       
   119  ID_BEREMIZPARAMSATTRIBUTESGRID,
       
   120 ] = [wx.NewId() for _init_ctrls in range(17)]
       
   121 
   141 
   122 [ID_BEREMIZFILEMENUITEMS0, ID_BEREMIZFILEMENUITEMS1, 
   142 [ID_BEREMIZFILEMENUITEMS0, ID_BEREMIZFILEMENUITEMS1, 
   123  ID_BEREMIZFILEMENUITEMS2, ID_BEREMIZFILEMENUITEMS3, 
   143  ID_BEREMIZFILEMENUITEMS2, ID_BEREMIZFILEMENUITEMS3, 
   124  ID_BEREMIZFILEMENUITEMS5, ID_BEREMIZFILEMENUITEMS7, 
   144  ID_BEREMIZFILEMENUITEMS5, ID_BEREMIZFILEMENUITEMS7, 
   125 ] = [wx.NewId() for _init_coll_FileMenu_Items in range(6)]
   145 ] = [wx.NewId() for _init_coll_FileMenu_Items in range(6)]
   227         self._init_coll_FileMenu_Items(self.FileMenu)
   247         self._init_coll_FileMenu_Items(self.FileMenu)
   228         #self._init_coll_EditMenu_Items(self.EditMenu)
   248         #self._init_coll_EditMenu_Items(self.EditMenu)
   229         #self._init_coll_RunMenu_Items(self.RunMenu)
   249         #self._init_coll_RunMenu_Items(self.RunMenu)
   230         self._init_coll_HelpMenu_Items(self.HelpMenu)
   250         self._init_coll_HelpMenu_Items(self.HelpMenu)
   231     
   251     
   232     def _init_coll_LeftGridSizer_Items(self, parent):
   252     def _init_coll_PLCConfigMainSizer_Items(self, parent):
   233         parent.AddWindow(self.PluginTree, 0, border=0, flag=wx.GROW)
   253         parent.AddSizer(self.PLCParamsSizer, 0, border=10, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
   234         parent.AddSizer(self.ButtonGridSizer, 0, border=0, flag=wx.GROW)
   254         parent.AddSizer(self.PluginTreeSizer, 0, border=10, flag=wx.BOTTOM|wx.LEFT|wx.RIGHT)
   235         
   255         
   236     def _init_coll_LeftGridSizer_Growables(self, parent):
   256     def _init_coll_PLCConfigMainSizer_Growables(self, parent):
   237         parent.AddGrowableCol(0)
       
   238         parent.AddGrowableRow(0)
       
   239     
       
   240     def _init_coll_RightGridSizer_Items(self, parent):
       
   241         parent.AddSizer(self.MenuSizer, 0, border=0, flag=wx.GROW)
       
   242         if wx.VERSION < (2, 8, 0):
       
   243             parent.AddWindow(self.SecondSplitter, 0, border=0, flag=wx.GROW)
       
   244         else:
       
   245             parent.AddWindow(self.ParamsPanel, 0, border=0, flag=wx.GROW)
       
   246         
       
   247     def _init_coll_RightGridSizer_Growables(self, parent):
       
   248         parent.AddGrowableCol(0)
   257         parent.AddGrowableCol(0)
   249         parent.AddGrowableRow(1)
   258         parent.AddGrowableRow(1)
   250     
   259     
   251     def _init_coll_ButtonGridSizer_Items(self, parent):
   260     def _init_coll_PluginTreeSizer_Growables(self, parent):
   252         parent.AddWindow(self.PluginChilds, 0, border=0, flag=wx.GROW)
       
   253         parent.AddWindow(self.AddButton, 0, border=0, flag=0) 
       
   254         parent.AddWindow(self.DeleteButton, 0, border=0, flag=0)
       
   255         
       
   256     def _init_coll_ButtonGridSizer_Growables(self, parent):
       
   257         parent.AddGrowableCol(0)
   261         parent.AddGrowableCol(0)
   258         parent.AddGrowableRow(0)
   262         parent.AddGrowableCol(1)
   259         
   263         
   260     def _init_sizers(self):
   264     def _init_sizers(self):
   261         self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=2, rows=1, vgap=2)
   265         self.PLCConfigMainSizer = wx.FlexGridSizer(cols=1, hgap=2, rows=2, vgap=2)
   262         self.ButtonGridSizer = wx.FlexGridSizer(cols=3, hgap=2, rows=1, vgap=2)
   266         self.PLCParamsSizer = wx.BoxSizer(wx.VERTICAL)
   263         self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=2, rows=2, vgap=2)
   267         self.PluginTreeSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=0, vgap=2)
   264         self.MenuSizer = wx.BoxSizer(wx.VERTICAL)
   268         
   265         self.ParamsPanelMainSizer = wx.BoxSizer(wx.VERTICAL)
   269         self._init_coll_PLCConfigMainSizer_Items(self.PLCConfigMainSizer)
   266         
   270         self._init_coll_PLCConfigMainSizer_Growables(self.PLCConfigMainSizer)
   267         self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer)
   271         self._init_coll_PluginTreeSizer_Growables(self.PluginTreeSizer)
   268         self._init_coll_LeftGridSizer_Items(self.LeftGridSizer)
   272         
   269         self._init_coll_ButtonGridSizer_Growables(self.ButtonGridSizer)
   273         self.PLCConfig.SetSizer(self.PLCConfigMainSizer)
   270         self._init_coll_ButtonGridSizer_Items(self.ButtonGridSizer)
   274         
   271         self._init_coll_RightGridSizer_Growables(self.RightGridSizer)
       
   272         self._init_coll_RightGridSizer_Items(self.RightGridSizer)
       
   273         
       
   274         self.LeftPanel.SetSizer(self.LeftGridSizer)
       
   275         self.RightPanel.SetSizer(self.RightGridSizer)
       
   276         self.ParamsPanel.SetSizer(self.ParamsPanelMainSizer)
       
   277     
       
   278     def _init_ctrls(self, prnt):
   275     def _init_ctrls(self, prnt):
   279         wx.Frame.__init__(self, id=ID_BEREMIZ, name=u'Beremiz',
   276         wx.Frame.__init__(self, id=ID_BEREMIZ, name=u'Beremiz',
   280               parent=prnt, pos=wx.Point(0, 0), size=wx.Size(1000, 600),
   277               parent=prnt, pos=wx.Point(0, 0), size=wx.Size(1000, 600),
   281               style=wx.DEFAULT_FRAME_STYLE|wx.CLIP_CHILDREN, title=u'Beremiz')
   278               style=wx.DEFAULT_FRAME_STYLE|wx.CLIP_CHILDREN, title=u'Beremiz')
   282         self._init_utils()
   279         self._init_utils()
   289                   name='MainSplitter', parent=self, point=wx.Point(0, 0),
   286                   name='MainSplitter', parent=self, point=wx.Point(0, 0),
   290                   size=wx.Size(0, 0), style=wx.SP_3D)
   287                   size=wx.Size(0, 0), style=wx.SP_3D)
   291             self.MainSplitter.SetNeedUpdating(True)
   288             self.MainSplitter.SetNeedUpdating(True)
   292             self.MainSplitter.SetMinimumPaneSize(1)
   289             self.MainSplitter.SetMinimumPaneSize(1)
   293         
   290         
   294             self.LeftPanel = wx.Panel(id=ID_BEREMIZLEFTPANEL, 
   291             parent = self.MainSplitter
   295                   name='LeftPanel', parent=self.MainSplitter, pos=wx.Point(0, 0),
   292         else:
   296                   size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
   293             parent = self
   297         
   294         
   298             self.PluginTree = wx.TreeCtrl(id=ID_BEREMIZPLUGINTREE,
   295         self.PLCConfig = wx.ScrolledWindow(id=ID_BEREMIZPLCCONFIG,
   299                   name='PluginTree', parent=self.LeftPanel, pos=wx.Point(0, 0),
   296               name='PLCConfig', parent=parent, pos=wx.Point(0, 0),
   300                   size=wx.Size(-1, -1), style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER)
   297               size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER|wx.HSCROLL|wx.VSCROLL)
   301             self.PluginTree.Bind(wx.EVT_RIGHT_UP, self.OnPluginTreeRightUp)
   298         self.PLCConfig.SetBackgroundColour(wx.WHITE)
   302             self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnPluginTreeItemSelected,
   299         self.PLCConfig.Bind(wx.EVT_SIZE, self.OnMoveWindow)
   303                   id=ID_BEREMIZPLUGINTREE)
   300         
   304         
   301         self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='',
   305             self.PluginChilds = wx.Choice(id=ID_BEREMIZPLUGINCHILDS,
   302                   name='LogConsole', parent=parent, pos=wx.Point(0, 0),
   306                   name='PluginChilds', parent=self.LeftPanel, pos=wx.Point(0, 0),
       
   307                   size=wx.Size(-1, -1), style=0)
       
   308 
       
   309             self.AddButton = wx.lib.buttons.GenBitmapButton(ID=ID_BEREMIZADDBUTTON, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'Add32x32.png')),
       
   310                   name='AddBusButton', parent=self.LeftPanel, pos=wx.Point(0, 0),
       
   311                   size=wx.Size(32, 32), style=wx.NO_BORDER)
       
   312             self.AddButton.SetToolTipString("Add a plugin of the type selected")
       
   313             self.AddButton.Bind(wx.EVT_BUTTON, self.OnAddButton,
       
   314                   id=ID_BEREMIZADDBUTTON)
       
   315             self.DeleteButton = wx.lib.buttons.GenBitmapButton(ID=ID_BEREMIZDELETEBUTTON, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'Delete32x32.png')),
       
   316                   name='DeleteBusButton', parent=self.LeftPanel, pos=wx.Point(0, 0),
       
   317                   size=wx.Size(32, 32), style=wx.NO_BORDER)
       
   318             self.DeleteButton.SetToolTipString("Delete the current selected plugin")
       
   319             self.DeleteButton.Bind(wx.EVT_BUTTON, self.OnDeleteButton,
       
   320                   id=ID_BEREMIZDELETEBUTTON)
       
   321             
       
   322             self.RightPanel = wx.Panel(id=ID_BEREMIZLEFTPANEL, 
       
   323                   name='RightPanel', parent=self.MainSplitter, pos=wx.Point(0, 0),
       
   324                   size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
   325         
       
   326             self.SecondSplitter = wx.SplitterWindow(id=ID_BEREMIZSECONDSPLITTER,
       
   327                   name='SecondSplitter', parent=self.RightPanel, point=wx.Point(0, 0),
       
   328                   size=wx.Size(0, 0), style=wx.SP_3D)
       
   329             self.SecondSplitter.SetNeedUpdating(True)
       
   330             self.SecondSplitter.SetMinimumPaneSize(1)
       
   331         
       
   332             self.MainSplitter.SplitVertically(self.LeftPanel, self.RightPanel,
       
   333                   300)
       
   334         
       
   335             self.ParamsPanel = wx.ScrolledWindow(id=ID_BEREMIZPARAMSPANEL, 
       
   336                   name='ParamsPanel', parent=self.SecondSplitter, pos=wx.Point(0, 0),
       
   337                   size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
   338             self.ParamsPanel.SetScrollbars(10, 10, 0, 0, 0, 0)
       
   339         
       
   340             self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='',
       
   341                   name='LogConsole', parent=self.SecondSplitter, pos=wx.Point(0, 0),
       
   342                   size=wx.Size(0, 0), style=wx.TE_MULTILINE|wx.TE_RICH2)
   303                   size=wx.Size(0, 0), style=wx.TE_MULTILINE|wx.TE_RICH2)
   343             
   304         
   344             self.SecondSplitter.SplitHorizontally(self.ParamsPanel, self.LogConsole,
   305         if wx.VERSION < (2, 8, 0):
   345                   -250)
   306             self.MainSplitter.SplitHorizontally(self.PLCConfig, self.LogConsole, -250)
   346             
   307             
   347             self._init_sizers()
       
   348         else:
   308         else:
   349             self.AUIManager = wx.aui.AuiManager(self)
   309             self.AUIManager = wx.aui.AuiManager(self)
   350             self.AUIManager.SetDockSizeConstraint(0.5, 0.5)
   310             self.AUIManager.SetDockSizeConstraint(0.5, 0.5)
   351             self.Panes = {}
   311             
   352             
   312             self.AUIManager.AddPane(self.PLCConfig, wx.aui.AuiPaneInfo().CenterPane())
   353             self.PluginTree = CT.CustomTreeCtrl(id=ID_BEREMIZPLUGINTREE,
   313             
   354               name='PluginTree', parent=self, pos=wx.Point(0, 0),
   314             self.AUIManager.AddPane(self.LogConsole, wx.aui.AuiPaneInfo().
   355               size=wx.Size(-1, -1), style=CT.TR_HAS_BUTTONS|CT.TR_EDIT_LABELS|CT.TR_HAS_VARIABLE_ROW_HEIGHT|wx.TR_SINGLE|wx.SUNKEN_BORDER)
   315                 Caption("Log Console").Bottom().Layer(1).
   356             self.PluginTree.Bind(wx.EVT_RIGHT_UP, self.OnPluginTreeRightUp)
   316                 BestSize(wx.Size(800, 200)).CloseButton(False))
   357             self.PluginTree.Bind(wx.EVT_IDLE, self.OnPluginTreeIdle)
       
   358             self.Bind(CT.EVT_TREE_SEL_CHANGED, self.OnPluginTreeItemSelected,
       
   359                   id=ID_BEREMIZPLUGINTREE)
       
   360             self.Bind(CT.EVT_TREE_ITEM_CHECKED, self.OnPluginTreeItemChecked,
       
   361                   id=ID_BEREMIZPLUGINTREE)
       
   362             self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnPluginTreeItemBeginEdit,
       
   363                   id=ID_BEREMIZPLUGINTREE)
       
   364             self.Bind(CT.EVT_TREE_END_LABEL_EDIT, self.OnPluginTreeItemEndEdit,
       
   365                   id=ID_BEREMIZPLUGINTREE)
       
   366             self.Bind(CT.EVT_TREE_ITEM_EXPANDED, self.OnPluginTreeItemExpanded,
       
   367                   id=ID_BEREMIZPLUGINTREE)
       
   368             self.Bind(CT.EVT_TREE_ITEM_COLLAPSED, self.OnPluginTreeItemCollapsed,
       
   369                   id=ID_BEREMIZPLUGINTREE)
       
   370             
       
   371             self.AUIManager.AddPane(self.PluginTree, wx.aui.AuiPaneInfo().CenterPane())
       
   372             
       
   373             self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='',
       
   374                   name='LogConsole', parent=self, pos=wx.Point(0, 0),
       
   375                   size=wx.Size(0, 0), style=wx.TE_MULTILINE|wx.TE_RICH2)
       
   376             self.AUIManager.AddPane(self.LogConsole, wx.aui.AuiPaneInfo().Caption("Log Console").Bottom().Layer(1).BestSize(wx.Size(800, 200)).CloseButton(False))
       
   377         
   317         
   378             self.AUIManager.Update()
   318             self.AUIManager.Update()
       
   319 
       
   320         self._init_sizers()
   379 
   321 
   380     def __init__(self, parent, projectOpen):
   322     def __init__(self, parent, projectOpen):
   381         self._init_ctrls(parent)
   323         self._init_ctrls(parent)
   382         
   324         
   383         self.Log = LogPseudoFile(self.LogConsole)
   325         self.Log = LogPseudoFile(self.LogConsole)
   384         
   326         
   385         self.PluginRoot = PluginsRoot(self)
   327         self.PluginRoot = PluginsRoot(self)
   386         self.DisableEvents = False
   328         self.DisableEvents = False
   387         
   329         
       
   330         self.PluginInfos = {}
       
   331         
   388         if projectOpen:
   332         if projectOpen:
   389             self.PluginRoot.LoadProject(projectOpen, self.Log)
   333             self.PluginRoot.LoadProject(projectOpen, self.Log)
       
   334             self.RefreshPLCParams()
   390             self.RefreshPluginTree()
   335             self.RefreshPluginTree()
   391             self.RefreshPluginToolBar()
       
   392             self.PluginTree.SelectItem(self.PluginTree.GetRootItem())
       
   393         
       
   394         if wx.VERSION < (2, 8, 0):
       
   395             self.RefreshPluginParams()
       
   396             self.RefreshButtons()
       
   397         
   336         
   398         self.RefreshMainMenu()
   337         self.RefreshMainMenu()
       
   338     
       
   339     def OnMoveWindow(self, event):
       
   340         self.GetBestSize()
       
   341         self.RefreshScrollBars()
       
   342         event.Skip()
   399     
   343     
   400     def OnFrameActivated(self, event):
   344     def OnFrameActivated(self, event):
   401         if not event.GetActive():
   345         if not event.GetActive():
   402             self.PluginRoot.RefreshPluginsBlockLists()
   346             self.PluginRoot.RefreshPluginsBlockLists()
   403     
   347     
   404     def RefreshButtons(self):
       
   405         if wx.VERSION < (2, 8, 0):
       
   406             if self.PluginRoot.HasProjectOpened():
       
   407                 self.PluginChilds.Enable(True)
       
   408                 self.AddButton.Enable(True)
       
   409                 self.DeleteButton.Enable(True)
       
   410             else:
       
   411                 self.PluginChilds.Enable(False)
       
   412                 self.AddButton.Enable(False)
       
   413                 self.DeleteButton.Enable(False)
       
   414         
       
   415     def RefreshMainMenu(self):
   348     def RefreshMainMenu(self):
   416         if self.menuBar1:
   349         if self.menuBar1:
   417             if self.PluginRoot.HasProjectOpened():
   350             if self.PluginRoot.HasProjectOpened():
   418 ##                self.menuBar1.EnableTop(1, True)
   351 ##                self.menuBar1.EnableTop(1, True)
   419 ##                self.menuBar1.EnableTop(2, True)
   352 ##                self.menuBar1.EnableTop(2, True)
   425 ##                self.menuBar1.EnableTop(2, False)
   358 ##                self.menuBar1.EnableTop(2, False)
   426                 self.FileMenu.Enable(ID_BEREMIZFILEMENUITEMS2, False)
   359                 self.FileMenu.Enable(ID_BEREMIZFILEMENUITEMS2, False)
   427                 self.FileMenu.Enable(ID_BEREMIZFILEMENUITEMS3, False)
   360                 self.FileMenu.Enable(ID_BEREMIZFILEMENUITEMS3, False)
   428                 self.FileMenu.Enable(ID_BEREMIZFILEMENUITEMS5, False)
   361                 self.FileMenu.Enable(ID_BEREMIZFILEMENUITEMS5, False)
   429 
   362 
       
   363     def RefreshScrollBars(self):
       
   364         xstart, ystart = self.PLCConfig.GetViewStart()
       
   365         window_size = self.PLCConfig.GetClientSize()
       
   366         sizer = self.PLCConfig.GetSizer()
       
   367         if sizer:
       
   368             maxx, maxy = sizer.GetMinSize()
       
   369             self.PLCConfig.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT, 
       
   370                 maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, xstart, ystart, True)
       
   371 
       
   372     def RefreshPLCParams(self):
       
   373         self.ClearSizer(self.PLCParamsSizer)
       
   374         
       
   375         if self.PluginRoot.HasProjectOpened():
       
   376             plcwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
       
   377             plcwindow.SetBackgroundColour(WINDOW_COLOUR)
       
   378             self.PLCParamsSizer.AddWindow(plcwindow, 0, border=0, flag=wx.GROW)
       
   379             
       
   380             plcwindowsizer = wx.BoxSizer(wx.VERTICAL)
       
   381             plcwindow.SetSizer(plcwindowsizer)
       
   382             
       
   383             titlesizer = wx.BoxSizer(wx.HORIZONTAL)
       
   384             plcwindowsizer.AddSizer(titlesizer, 0, border=0, flag=wx.ALIGN_CENTER)
       
   385             
       
   386             st = wx.StaticText(plcwindow, -1)
       
   387             st.SetFont(wx.Font(faces["size"] * 2, wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
       
   388             st.SetLabel("PLC (%s)"%self.PluginRoot.GetProjectName())
       
   389             titlesizer.AddWindow(st, 0, border=5, flag=wx.ALL|wx.ALIGN_CENTER)
       
   390             
       
   391             if len(self.PluginRoot.PlugChildsTypes) > 0:
       
   392                 addbutton_id = wx.NewId()
       
   393                 addbutton = wx.lib.buttons.GenBitmapButton(id=addbutton_id, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'AddPlugin.png')),
       
   394                       name='AddBusButton', parent=plcwindow, pos=wx.Point(0, 0),
       
   395                       size=wx.Size(24, 24), style=wx.NO_BORDER)
       
   396                 addbutton.GetBackgroundBrush = gen_mini_GetBackgroundBrush(addbutton)
       
   397                 addbutton.SetToolTipString("Add a plugin to this one")
       
   398                 addbutton.Bind(wx.EVT_BUTTON, self.GetAddButtonFunction(self.PluginRoot, plcwindow), id=addbutton_id)
       
   399                 titlesizer.AddWindow(addbutton, 0, border=5, flag=wx.ALL|wx.ALIGN_CENTER)
       
   400             
       
   401             plcwindowmainsizer = wx.BoxSizer(wx.HORIZONTAL)
       
   402             plcwindowsizer.AddSizer(plcwindowmainsizer, 0, border=0, flag=wx.ALIGN_CENTER)
       
   403             
       
   404             msizer = wx.FlexGridSizer(cols=len(self.PluginRoot.PluginMethods))
       
   405             plcwindowmainsizer.AddSizer(msizer, 0, border=0, flag=wx.GROW)
       
   406             if len(self.PluginRoot.PluginMethods) > 0: 
       
   407                 for plugin_method in self.PluginRoot.PluginMethods:
       
   408                     if "method" in plugin_method:
       
   409                         id = wx.NewId()
       
   410                         button = wx.lib.buttons.GenBitmapTextButton(id=id, parent=plcwindow,
       
   411                             bitmap=wx.Bitmap(os.path.join(CWD, "%s24x24.png"%plugin_method.get("bitmap", os.path.join("images", "Unknown")))), label=plugin_method["name"], 
       
   412                             name=plugin_method["name"], pos=wx.DefaultPosition, style=wx.NO_BORDER)
       
   413                         button.SetToolTipString(plugin_method["tooltip"])
       
   414                         button.Bind(wx.EVT_BUTTON, self.GetButtonCallBackFunction(self.PluginRoot, plugin_method["method"]), id=id)
       
   415                         #hack to force size to mini
       
   416                         button._GetLabelSize = gen_mini_GetLabelSize(button)  
       
   417                         #button._GetLabelSize = lambda :(-1,-1,False)
       
   418                         msizer.AddWindow(button, 0, border=0, flag=0)
       
   419             
       
   420             paramswindow = wx.Panel(plcwindow, -1, size=wx.Size(-1, -1))
       
   421             paramswindow.SetBackgroundColour(WINDOW_COLOUR)
       
   422             plcwindowmainsizer.AddWindow(paramswindow, 0, border=0, flag=0)
       
   423             
       
   424             psizer = wx.BoxSizer(wx.HORIZONTAL)
       
   425             paramswindow.SetSizer(psizer)
       
   426             
       
   427             plugin_infos = self.PluginRoot.GetParamsAttributes()
       
   428             self.RefreshSizerElement(paramswindow, psizer, self.PluginRoot, plugin_infos, None, False)
       
   429             
       
   430             paramswindow.Hide()
       
   431             
       
   432             minimizebutton_id = wx.NewId()
       
   433             minimizebutton = wx.lib.buttons.GenBitmapToggleButton(id=minimizebutton_id, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'Maximize.png')),
       
   434                   name='MinimizeButton', parent=plcwindow, pos=wx.Point(0, 0),
       
   435                   size=wx.Size(24, 24), style=wx.NO_BORDER)
       
   436             minimizebutton.GetBackgroundBrush = gen_mini_GetBackgroundBrush(minimizebutton)
       
   437             minimizebutton.SetBackgroundColour(wx.Colour(208, 208, 208))
       
   438             minimizebutton.labelDelta = 0
       
   439             minimizebutton.SetBezelWidth(0)
       
   440             minimizebutton.SetUseFocusIndicator(False)
       
   441             minimizebutton.SetBitmapSelected(wx.Bitmap(os.path.join(CWD, 'images', 'Minimize.png')))
       
   442             def togglewindow(event):
       
   443                 if minimizebutton.GetToggle():
       
   444                     paramswindow.Show()
       
   445                     msizer.SetCols(1)
       
   446                 else:
       
   447                     paramswindow.Hide()
       
   448                     msizer.SetCols(len(self.PluginRoot.PluginMethods))
       
   449                 self.PLCConfigMainSizer.Layout()
       
   450                 self.RefreshScrollBars()
       
   451                 event.Skip()
       
   452             minimizebutton.Bind(wx.EVT_BUTTON, togglewindow, id=minimizebutton_id)
       
   453             plcwindowmainsizer.AddWindow(minimizebutton, 0, border=5, flag=wx.ALL)
       
   454             
       
   455             self.PLCConfigMainSizer.Layout()
       
   456             self.RefreshScrollBars()
       
   457 
   430     def RefreshPluginTree(self):
   458     def RefreshPluginTree(self):
   431         self.DisableEvents = True
   459         self.ClearSizer(self.PluginTreeSizer)
   432         infos = self.PluginRoot.GetPlugInfos()
   460         if self.PluginRoot.HasProjectOpened():
   433         root = self.PluginTree.GetRootItem()
   461             index = [0]
   434         if root is None or not root.IsOk():
   462             for child in self.PluginRoot.IECSortedChilds():
   435             root = self.PluginTree.AddRoot(infos["name"])
   463                 self.GenerateTreeBranch(child, index)
   436         last_selected = self.GetSelectedPluginName()
   464                 if not self.PluginInfos[child]["expanded"]:
   437         self.GenerateTreeBranch(root, infos, True)
   465                     self.CollapsePlugin(child)
   438         self.PluginTree.Expand(self.PluginTree.GetRootItem())
   466         self.PLCConfigMainSizer.Layout()
   439         self.SelectedPluginByName(root, last_selected)
   467         self.RefreshScrollBars()
   440         
   468 
   441         if wx.VERSION < (2, 8, 0):
   469     def ExpandPlugin(self, plugin, force = False):
   442             self.RefreshPluginParams()
   470         for child in self.PluginInfos[plugin]["children"]:
   443         
   471             self.PluginTreeSizer.Show(self.PluginInfos[child]["left"])
   444         self.DisableEvents = False
   472             self.PluginTreeSizer.Show(self.PluginInfos[child]["right"])
   445         self.MustRecalTreeSizes = True
   473             if force or not self.PluginInfos[child]["expanded"]:
   446 
   474                 self.ExpandPlugin(child, force)
   447     def SelectedPluginByName(self, root, name):
   475                 if force:
   448         if name:
   476                     self.PluginInfos[child]["expanded"] = True
   449             toks = name.split('.', 1)
   477     
   450             item, root_cookie = self.PluginTree.GetFirstChild(root)
   478     def CollapsePlugin(self, plugin, force = False):
   451             while item is not None and item.IsOk():
   479         for child in self.PluginInfos[plugin]["children"]:
   452                 if self.PluginTree.GetPyData(item) == toks[0]:
   480             self.PluginTreeSizer.Hide(self.PluginInfos[child]["left"])
   453                     if len(toks)>1:
   481             self.PluginTreeSizer.Hide(self.PluginInfos[child]["right"])
   454                         return self.SelectedPluginByName(item, toks[1])
   482             if force or self.PluginInfos[child]["expanded"]:
   455                     else:
   483                 self.CollapsePlugin(child, force)
   456                         self.PluginTree.SelectItem(item, True)
   484                 if force:
   457                         return True
   485                     self.PluginInfos[child]["expanded"] = False
   458                 item, root_cookie = self.PluginTree.GetNextChild(root, root_cookie)
   486 
   459         return False
   487     def GenerateTreeBranch(self, plugin, index):
   460 
   488         leftwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
   461     def GenerateTreeBranch(self, root, infos, first = False):
   489         leftwindow.SetBackgroundColour(WINDOW_COLOUR)
   462         to_delete = []
   490         
   463         self.PluginTree.SetItemText(root, infos["name"])
   491         if plugin not in self.PluginInfos:
   464         self.PluginTree.SetPyData(root, infos["type"])
   492             self.PluginInfos[plugin] = {"expanded" : False, "left_visible" : False, "right_visible" : False}
   465         
   493             
   466         if wx.VERSION >= (2, 8, 0):
   494         self.PluginInfos[plugin]["children"] = plugin.IECSortedChilds()
   467             plugin = self.GetSelectedPlugin(root)
   495         
   468             if plugin is not None:
   496         self.PluginTreeSizer.AddWindow(leftwindow, 0, border=0, flag=wx.GROW)
   469                 old_window = self.PluginTree.GetItemWindow(root)
   497         
   470                 if old_window is not None:
   498         leftwindowsizer = wx.FlexGridSizer(cols=1, rows=2)
   471                     old_window.GetSizer().Clear(True)
   499         leftwindowsizer.AddGrowableCol(0)
   472                     old_window.Destroy()
   500         leftwindowsizer.AddGrowableRow(1)
   473                 
   501         leftwindow.SetSizer(leftwindowsizer)
   474                 outside = wx.Panel(self.PluginTree, -1, size=wx.Size(-1, -1))
   502         
   475                 outside.SetBackgroundColour(wx.WHITE)
   503         leftbuttonmainsizer = wx.FlexGridSizer(cols=3, rows=1)
   476                 
   504         leftbuttonmainsizer.AddGrowableCol(0)
   477                 insidesizer = wx.FlexGridSizer(cols=2,rows=1)
   505         leftwindowsizer.AddSizer(leftbuttonmainsizer, 0, border=5, flag=wx.GROW|wx.ALL)
   478                 insidesizer.AddGrowableCol(1)
   506         
   479                 
   507         leftbuttonsizer = wx.BoxSizer(wx.HORIZONTAL)
   480                 outside.SetSizer(insidesizer)
   508         leftbuttonmainsizer.AddSizer(leftbuttonsizer, 0, border=15, flag=wx.GROW|wx.RIGHT)
   481 
   509         
   482                 insidesizer.AddSpacer(-1)
   510         ieccsizer = wx.BoxSizer(wx.VERTICAL)
   483                 
   511         leftbuttonsizer.AddSizer(ieccsizer, 0, border=15, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
   484                 window = wx.Panel(outside, -1, size=wx.Size(-1, -1))
   512         
   485                 window.SetBackgroundColour(wx.Colour(250,250,255))
   513         plugin_IECChannel = plugin.BaseParams.getIEC_Channel()
   486                 insidesizer.AddWindow(window, border=1, flag=wx.GROW|wx.ALL)
   514         
   487                 
   515         ieccdownbutton_id = wx.NewId()
   488                 tcsizer = wx.FlexGridSizer(cols=3, hgap=0, rows=1, vgap=0)
   516         ieccdownbutton = wx.lib.buttons.GenBitmapButton(id=ieccdownbutton_id, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'IECCDown.png')),
   489 
   517               name='IECCDownButton', parent=leftwindow, pos=wx.Point(0, 0),
   490                 if "channel" in infos:
   518               size=wx.Size(16, 16), style=wx.NO_BORDER)
   491                     sc = wx.SpinCtrl(window, -1, size=wx.Size(50, 25))
   519         if plugin_IECChannel > 0:
   492                     sc.SetValue(infos["channel"])
   520             ieccdownbutton.Bind(wx.EVT_BUTTON, self.GetItemChannelChangedFunction(plugin, plugin_IECChannel - 1), id=ieccdownbutton_id)
   493                     sc.Bind(wx.EVT_SPINCTRL, self.GetItemChannelChangedFunction(root))
   521         else:
   494                     tcsizer.AddWindow(sc, 0, border=5, flag=wx.LEFT|wx.TOP|wx.BOTTOM|wx.ALIGN_CENTER)
   522             ieccdownbutton.Enable(False)
   495 
   523         ieccsizer.AddWindow(ieccdownbutton, 0, border=0, flag=wx.ALIGN_CENTER)
   496                 bsizer = wx.BoxSizer(wx.HORIZONTAL)
   524         
   497                 
   525         st = wx.StaticText(leftwindow, -1)
   498                 if "parent" in infos or plugin == self.PluginRoot:
   526         st.SetFont(wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
   499                     addbutton_id = wx.NewId()
   527         st.SetLabel(plugin.GetFullIEC_Channel())
   500                     addbutton = wx.lib.buttons.GenBitmapButton(id=addbutton_id, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'Add24x24.png')),
   528         ieccsizer.AddWindow(st, 0, border=0, flag=0)
   501                           name='AddBusButton', parent=window, pos=wx.Point(0, 0),
   529         
   502                           size=wx.Size(24, 24), style=wx.NO_BORDER)
   530         ieccupbutton_id = wx.NewId()
   503                     addbutton.SetToolTipString("Add a plugin to this one")
   531         ieccupbutton = wx.lib.buttons.GenBitmapTextButton(id=ieccupbutton_id, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'IECCUp.png')),
   504                     addbutton.Bind(wx.EVT_BUTTON, self.GetAddButtonFunction(root, window), id=addbutton_id)
   532               name='IECCUpButton', parent=leftwindow, pos=wx.Point(0, 0),
   505                     bsizer.AddWindow(addbutton, 0, border=5, flag=wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM|wx.ALIGN_CENTER)
   533               size=wx.Size(16, 16), style=wx.NO_BORDER)
   506                 
   534         ieccupbutton.Bind(wx.EVT_BUTTON, self.GetItemChannelChangedFunction(plugin, plugin_IECChannel + 1), id=ieccupbutton_id)
   507                 if plugin != self.PluginRoot:
   535         ieccsizer.AddWindow(ieccupbutton, 0, border=0, flag=wx.ALIGN_CENTER)
   508                     deletebutton_id = wx.NewId()
   536         
   509                     deletebutton = wx.lib.buttons.GenBitmapButton(id=deletebutton_id, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'Delete24x24.png')),
   537         if len(self.PluginInfos[plugin]["children"]) > 0:
   510                           name='DeleteBusButton', parent=window, pos=wx.Point(0, 0),
   538             expandbutton_id = wx.NewId()
   511                           size=wx.Size(24, 24), style=wx.NO_BORDER)
   539             expandbutton = wx.lib.buttons.GenBitmapToggleButton(id=expandbutton_id, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'plus.png')),
   512                     deletebutton.SetToolTipString("Delete this plugin")
   540                   name='ExpandButton', parent=leftwindow, pos=wx.Point(0, 0),
   513                     deletebutton.Bind(wx.EVT_BUTTON, self.GetDeleteButtonFunction(root), id=deletebutton_id)
   541                   size=wx.Size(13, 13), style=wx.NO_BORDER)
   514                     bsizer.AddWindow(deletebutton, 0, border=5, flag=wx.RIGHT|wx.TOP|wx.BOTTOM|wx.ALIGN_CENTER)
   542             expandbutton.labelDelta = 0
   515                 
   543             expandbutton.SetBezelWidth(0)
   516                 plugin_infos = plugin.GetParamsAttributes()
   544             expandbutton.SetUseFocusIndicator(False)
   517 
   545             expandbutton.SetBitmapSelected(wx.Bitmap(os.path.join(CWD, 'images', 'minus.png')))
   518                 psizer = wx.BoxSizer(wx.HORIZONTAL)
   546             expandbutton.SetToggle(self.PluginInfos[plugin]["expanded"])
   519                 self.RefreshSizerElement(window, psizer, plugin, plugin_infos, None, True, root)
   547             
   520 
   548             def togglebutton(event):
   521                 msizer = wx.BoxSizer(wx.VERTICAL)
   549                 if expandbutton.GetToggle():
   522                 msizer.AddSizer(bsizer, 0, border=0, flag=wx.GROW)
   550                     self.ExpandPlugin(plugin)
   523                 if len(plugin.PluginMethods) > 0: #and plugin != self.PluginRoot 
       
   524                     for plugin_method in plugin.PluginMethods:
       
   525                         if "method" in plugin_method:
       
   526                             id = wx.NewId()
       
   527                             button = wx.lib.buttons.GenBitmapTextButton(id=id, parent=window,
       
   528                                 bitmap=wx.Bitmap(os.path.join(CWD, "%s24x24.png"%plugin_method.get("bitmap", os.path.join("images", "Unknown")))), label=plugin_method["name"], 
       
   529                                 name=plugin_method["name"], pos=wx.DefaultPosition, style=wx.NO_BORDER)
       
   530                             button.SetToolTipString(plugin_method["tooltip"])
       
   531                             button.Bind(wx.EVT_BUTTON, self.GetButtonCallBackFunction(plugin, plugin_method["method"]), id=id)
       
   532                             #hack to force size to mini
       
   533                             gen_mini_GetLabelSize = lambda obj:lambda:(wx.lib.buttons.GenBitmapTextButton._GetLabelSize(obj)[:-1] + (False,))
       
   534                             button._GetLabelSize = gen_mini_GetLabelSize(button)  
       
   535                             #button._GetLabelSize = lambda :(-1,-1,False)
       
   536                             msizer.AddWindow(button, 0, border=5, flag=0)
       
   537                 tcsizer.AddSizer(msizer, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL)
       
   538                 tcsizer.AddSizer(psizer, 0, border=0, flag=wx.GROW)
       
   539                 if plugin == self.PluginRoot:
       
   540                     tcsizer.AddGrowableCol(0)
       
   541                 else:
   551                 else:
   542                     tcsizer.AddGrowableCol(1)
   552                     self.CollapsePlugin(plugin)
   543                 
   553                 self.PluginInfos[plugin]["expanded"] = expandbutton.GetToggle()
   544             window.SetSizer(tcsizer)
   554                 self.PLCConfigMainSizer.Layout()
   545             insidesizer.Fit(outside)
   555                 self.RefreshScrollBars()
   546             self.PluginTree.SetItemWindow(root, outside)
   556                 event.Skip()
   547             if "enabled" in infos:
   557             expandbutton.Bind(wx.EVT_BUTTON, togglebutton, id=expandbutton_id)
   548                 self.PluginTree.CheckItem(root, infos["enabled"])
   558             leftbuttonsizer.AddWindow(expandbutton, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
   549                 self.PluginTree.SetItemWindowEnabled(root, infos["enabled"])
   559         
   550 
   560         tc_id = wx.NewId()
   551         item, root_cookie = self.PluginTree.GetFirstChild(root)
   561         tc = wx.TextCtrl(leftwindow, tc_id, size=wx.Size(150, 35), style=wx.TE_PROCESS_ENTER|wx.NO_BORDER)
   552         for values in infos["values"]:    
   562         tc.SetFont(wx.Font(faces["size"] * 0.75, wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
   553             if item is None or not item.IsOk():
   563         tc.SetValue(plugin.MandatoryParams[1].getName())
   554                 item = self.PluginTree.AppendItem(root, "")
   564         tc.Bind(wx.EVT_TEXT_ENTER, self.GetTextCtrlCallBackFunction(tc, plugin, "BaseParams.Name"), id=tc_id)
   555                 # 2.6.x returns bad item on gtk
   565         leftbuttonsizer.AddWindow(tc, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
   556                 if wx.Platform != '__WXMSW__' or wx.VERSION >= (2, 8, 0):
   566         
   557                     item, root_cookie = self.PluginTree.GetNextChild(root, root_cookie)
   567         enablebutton_id = wx.NewId()
   558             self.GenerateTreeBranch(item, values)
   568         enablebutton = wx.lib.buttons.GenBitmapTextToggleButton(id=enablebutton_id, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'Disabled.png')),
   559             item, root_cookie = self.PluginTree.GetNextChild(root, root_cookie)
   569               name='EnableButton', parent=leftwindow, pos=wx.Point(0, 0), label="Enabled", style=wx.NO_BORDER)
   560         while item is not None and item.IsOk():
   570         enablebutton.GetBackgroundBrush = gen_mini_GetBackgroundBrush(enablebutton)
   561             to_delete.append(item)
   571         enablebutton.SetBackgroundColour(wx.Colour(208, 208, 208))
   562             item, root_cookie = self.PluginTree.GetNextChild(root, root_cookie)
   572         enablebutton._GetLabelSize = gen_mini_GetLabelSize(enablebutton)
   563         for item in to_delete:
   573         enablebutton.labelDelta = 0
   564             self.PluginTree.Delete(item)
   574         enablebutton.SetBezelWidth(0)
   565 
   575         enablebutton.SetUseFocusIndicator(False)
   566     MustRecalTreeSizes = False
   576         enablebutton.SetBitmapSelected(wx.Bitmap(os.path.join(CWD, 'images', 'Enabled.png')))
   567     def OnPluginTreeIdle(self,event):
   577         enablebutton.SetToggle(plugin.MandatoryParams[1].getEnabled())
   568         if self.MustRecalTreeSizes:
   578         
   569             self.ResizePluginTreeWindow()
   579         def toggleenablebutton(event):
   570             event.RequestMore()
   580             res, StructChanged = plugin.SetParamsAttribute("BaseParams.Enabled", enablebutton.GetToggle(), self.Log)
   571         event.Skip()
   581             if StructChanged: wx.CallAfter(self.RefreshPluginTree)
   572 
   582             enablebutton.SetToggle(res)
   573     def ResizePluginTreeWindow(self):
   583             event.Skip()
   574         if getattr(self, "PluginRoot", None):
   584         enablebutton.Bind(wx.EVT_BUTTON, toggleenablebutton, id=enablebutton_id)
   575             root = self.PluginTree.GetRootItem()
   585         leftbuttonsizer.AddWindow(enablebutton, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
   576             if root is not None and root.IsOk():
   586         
   577                 minimalsz = wx.Size(-1,-1)
   587         if len(plugin.PlugChildsTypes) > 0:
   578                 minimalpos = wx.Point(-1,-1)
   588             addbutton_id = wx.NewId()
   579                 itemswindows = self.ResizePluginTreeWindow_r(root, minimalsz, minimalpos)
   589             addbutton = wx.lib.buttons.GenBitmapButton(id=addbutton_id, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'AddPlugin.png')),
   580                 for window, posx in itemswindows:
   590                   name='AddBusButton', parent=leftwindow, pos=wx.Point(0, 0),
   581                     spacer_width = minimalpos.x - posx
   591                   size=wx.Size(24, 24), style=wx.NO_BORDER)
   582                     window.GetSizer().GetItem(0).SetSpacer(wx.Size(spacer_width,-1))
   592             addbutton.GetBackgroundBrush = gen_mini_GetBackgroundBrush(addbutton)
   583                     window.SetSize(wx.Size(spacer_width + minimalsz.x, -1))
   593             addbutton.SetToolTipString("Add a plugin to this one")
   584                     window.GetSizer().Layout()
   594             addbutton.Bind(wx.EVT_BUTTON, self.GetAddButtonFunction(plugin, leftwindow), id=addbutton_id)
   585                     #wx.MessageBox(str(itemswindows) + "\n" + str(minimalpos) + "\n" + str(minimalsz) + "\n" + str(window.GetSizer().GetItem(0).GetSpacer()))
   595             leftbuttonsizer.AddWindow(addbutton, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER)
   586                 self.MustRecalTreeSizes = False
   596 
   587 
   597         leftminimizebutton_id = wx.NewId()
   588     def ResizePluginTreeWindow_r(self, root, sz, pt):
   598         leftminimizebutton = wx.lib.buttons.GenBitmapToggleButton(id=leftminimizebutton_id, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'Maximize.png')),
   589         window = self.PluginTree.GetItemWindow(root)
   599               name='MinimizeButton', parent=leftwindow, pos=wx.Point(0, 0),
   590         posx = window.GetPosition().x
   600               size=wx.Size(24, 24), style=wx.NO_BORDER)
   591         res = [(window,posx)]
   601         leftminimizebutton.GetBackgroundBrush = gen_mini_GetBackgroundBrush(leftminimizebutton)
   592         window.GetSizer().GetItem(0).SetSpacer(wx.Size(0,0))
   602         leftminimizebutton.SetBackgroundColour(wx.Colour(208, 208, 208))
   593         bestsz = window.GetBestSize()
   603         leftminimizebutton.labelDelta = 0
   594         pt.x = max(pt.x, posx)
   604         leftminimizebutton.SetBezelWidth(0)
   595         sz.x = max(sz.x, bestsz.x)
   605         leftminimizebutton.SetUseFocusIndicator(False)
   596         if root.IsExpanded():
   606         leftminimizebutton.SetBitmapSelected(wx.Bitmap(os.path.join(CWD, 'images', 'Minimize.png')))
   597             item, root_cookie = self.PluginTree.GetFirstChild(root)
   607         leftminimizebutton.SetToggle(self.PluginInfos[plugin]["left_visible"])
   598             while item is not None and item.IsOk() :
   608         def toggleleftwindow(event):
   599                 res.extend(self.ResizePluginTreeWindow_r(item, sz, pt))
   609             if leftminimizebutton.GetToggle():
   600                 item, root_cookie = self.PluginTree.GetNextChild(root, root_cookie)
   610                 leftwindowsizer.Show(1)
   601         return res
   611             else:
   602 
   612                 leftwindowsizer.Hide(1)
   603     def GetSelectedPluginName(self, selected = None):
   613             self.PluginInfos[plugin]["left_visible"] = leftminimizebutton.GetToggle()
   604         if selected is None:
   614             self.PLCConfigMainSizer.Layout()
   605             selected = self.PluginTree.GetSelection()
   615             self.RefreshScrollBars()
   606         if selected is None or not selected.IsOk():
   616             event.Skip()
   607             return None
   617         leftminimizebutton.Bind(wx.EVT_BUTTON, toggleleftwindow, id=leftminimizebutton_id)
   608         if selected == self.PluginTree.GetRootItem():
   618         leftbuttonmainsizer.AddWindow(leftminimizebutton, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER)
   609             return ""
   619 
       
   620         deletebutton_id = wx.NewId()
       
   621         deletebutton = wx.lib.buttons.GenBitmapButton(id=deletebutton_id, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'Delete24x24.png')),
       
   622               name='DeleteBusButton', parent=leftwindow, pos=wx.Point(0, 0),
       
   623               size=wx.Size(24, 24), style=wx.NO_BORDER)
       
   624         deletebutton.SetToolTipString("Delete this plugin")
       
   625         deletebutton.Bind(wx.EVT_BUTTON, self.GetDeleteButtonFunction(plugin), id=deletebutton_id)
       
   626         leftbuttonmainsizer.AddWindow(deletebutton, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER)
       
   627 
       
   628         lb = wx.ListBox(leftwindow, -1, size=wx.Size(-1, 100), style=wx.NO_BORDER)
       
   629         for location in plugin.GetLocations():
       
   630             lb.Append(location["NAME"].replace("__", "%").replace("_", "."))
       
   631         if not self.PluginInfos[plugin]["left_visible"]:
       
   632             lb.Hide()
       
   633         leftwindowsizer.AddWindow(lb, 0, border=5, flag=wx.GROW|wx.ALL)
       
   634 
       
   635         rightwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
       
   636         rightwindow.SetBackgroundColour(wx.Colour(240,240,240))
       
   637         
       
   638         self.PluginTreeSizer.AddWindow(rightwindow, 0, border=0, flag=wx.GROW)
       
   639         
       
   640         rightwindowmainsizer = wx.BoxSizer(wx.VERTICAL)
       
   641         rightwindow.SetSizer(rightwindowmainsizer)
       
   642         
       
   643         rightwindowsizer = wx.FlexGridSizer(cols=2, rows=1)
       
   644         rightwindowsizer.AddGrowableCol(1)
       
   645         rightwindowsizer.AddGrowableRow(0)
       
   646         rightwindowmainsizer.AddSizer(rightwindowsizer, 0, border=17, flag=wx.TOP|wx.GROW)
       
   647         
       
   648         if self.PluginInfos[plugin]["right_visible"]:
       
   649             msizer = wx.FlexGridSizer(cols=1)
   610         else:
   650         else:
   611             name = self.PluginTree.GetPyData(selected)
   651             msizer = wx.FlexGridSizer(cols=len(plugin.PluginMethods))
   612             item = self.PluginTree.GetItemParent(selected)
   652         rightwindowsizer.AddSizer(msizer, 0, border=0, flag=wx.GROW)
   613             while item.IsOk() and item != self.PluginTree.GetRootItem():
   653         if len(plugin.PluginMethods) > 0: 
   614                 name = "%s.%s"%(self.PluginTree.GetPyData(item), name)
   654             for plugin_method in plugin.PluginMethods:
   615                 item = self.PluginTree.GetItemParent(item)
   655                 if "method" in plugin_method:
   616             return name
   656                     id = wx.NewId()
   617 
   657                     button = wx.lib.buttons.GenBitmapTextButton(id=id, parent=rightwindow,
   618     def GetSelectedPlugin(self, selected = None):
   658                         bitmap=wx.Bitmap(os.path.join(CWD, "%s24x24.png"%plugin_method.get("bitmap", os.path.join("images", "Unknown")))), label=plugin_method["name"], 
   619         name = self.GetSelectedPluginName(selected)
   659                         name=plugin_method["name"], pos=wx.DefaultPosition, style=wx.NO_BORDER)
   620         if name is None:
   660                     button.SetToolTipString(plugin_method["tooltip"])
   621             return None
   661                     button.Bind(wx.EVT_BUTTON, self.GetButtonCallBackFunction(plugin, plugin_method["method"]), id=id)
   622         elif name == "":
   662                     #hack to force size to mini
   623             return self.PluginRoot
   663                     button._GetLabelSize = gen_mini_GetLabelSize(button)  
   624         else:
   664                     #button._GetLabelSize = lambda :(-1,-1,False)
   625             return self.PluginRoot.GetChildByName(name)
   665                     msizer.AddWindow(button, 0, border=0, flag=0)
   626 
   666         
   627     def OnPluginTreeItemSelected(self, event):
   667         rightparamssizer = wx.BoxSizer(wx.HORIZONTAL)
   628         if wx.VERSION < (2, 8, 0):
   668         rightwindowsizer.AddSizer(rightparamssizer, 0, border=0, flag=wx.ALIGN_RIGHT)
   629             wx.CallAfter(self.RefreshPluginParams)
   669         
   630         event.Skip()
   670         paramswindow = wx.Panel(rightwindow, -1, size=wx.Size(-1, -1))
   631     
   671         paramswindow.SetBackgroundColour(WINDOW_COLOUR)
   632     def OnPluginTreeItemChecked(self, event):
   672         
   633         if not self.DisableEvents:
   673         psizer = wx.BoxSizer(wx.HORIZONTAL)
   634             item = event.GetItem()
   674         paramswindow.SetSizer(psizer)
   635             plugin = self.GetSelectedPlugin(item)
   675         
   636             if plugin:
   676         rightparamssizer.AddWindow(paramswindow, 0, border=5, flag=wx.ALL)
   637                 res, StructChanged = plugin.SetParamsAttribute("BaseParams.Enabled", self.PluginTree.IsItemChecked(item), self.Log)
   677         
   638                 wx.CallAfter(self.RefreshPluginTree)
   678         plugin_infos = plugin.GetParamsAttributes()
   639         event.Skip()
   679         self.RefreshSizerElement(paramswindow, psizer, plugin, plugin_infos, None, False)
   640     
   680         
   641     def OnPluginTreeItemBeginEdit(self, event):
   681         if not self.PluginInfos[plugin]["right_visible"]:
   642         if event.GetItem() == self.PluginTree.GetRootItem():
   682             paramswindow.Hide()
   643             event.Veto()
   683         
   644         else:
   684         rightminimizebutton_id = wx.NewId()
       
   685         rightminimizebutton = wx.lib.buttons.GenBitmapToggleButton(id=rightminimizebutton_id, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'Maximize.png')),
       
   686               name='MinimizeButton', parent=rightwindow, pos=wx.Point(0, 0),
       
   687               size=wx.Size(24, 24), style=wx.NO_BORDER)
       
   688         rightminimizebutton.GetBackgroundBrush = gen_mini_GetBackgroundBrush(rightminimizebutton)
       
   689         rightminimizebutton.SetBackgroundColour(wx.Colour(208, 208, 208))
       
   690         rightminimizebutton.labelDelta = 0
       
   691         rightminimizebutton.SetBezelWidth(0)
       
   692         rightminimizebutton.SetUseFocusIndicator(False)
       
   693         rightminimizebutton.SetBitmapSelected(wx.Bitmap(os.path.join(CWD, 'images', 'Minimize.png')))
       
   694         rightminimizebutton.SetToggle(self.PluginInfos[plugin]["right_visible"])
       
   695         def togglerightwindow(event):
       
   696             if rightminimizebutton.GetToggle():
       
   697                 rightparamssizer.Show(0)
       
   698                 msizer.SetCols(1)
       
   699             else:
       
   700                 rightparamssizer.Hide(0)
       
   701                 msizer.SetCols(len(plugin.PluginMethods))
       
   702             self.PluginInfos[plugin]["right_visible"] = rightminimizebutton.GetToggle()
       
   703             self.PLCConfigMainSizer.Layout()
       
   704             self.RefreshScrollBars()
   645             event.Skip()
   705             event.Skip()
   646     
   706         rightminimizebutton.Bind(wx.EVT_BUTTON, togglerightwindow, id=rightminimizebutton_id)
   647     def OnPluginTreeItemEndEdit(self, event):
   707         rightparamssizer.AddWindow(rightminimizebutton, 0, border=5, flag=wx.ALL)
   648         if event.GetLabel() == "":
   708             
   649             event.Veto()
   709         self.PluginInfos[plugin]["left"] = index[0]
   650         elif not self.DisableEvents:
   710         self.PluginInfos[plugin]["right"] = index[0] + 1
   651             plugin = self.GetSelectedPlugin()
   711         index[0] += 2
   652             if plugin:
   712         for child in self.PluginInfos[plugin]["children"]:
   653                 res, StructChanged = plugin.SetParamsAttribute("BaseParams.Name", event.GetLabel(), self.Log)
   713             self.GenerateTreeBranch(child, index)
   654                 wx.CallAfter(self.RefreshPluginTree)
   714             if not self.PluginInfos[child]["expanded"]:
   655             event.Skip()
   715                 self.CollapsePlugin(child)
   656     
   716 
   657     def ShowChildrenWindows(self, root, show = True):
   717     def GetItemChannelChangedFunction(self, plugin, value):
   658         item, root_cookie = self.PluginTree.GetFirstChild(root)
       
   659         while item is not None and item.IsOk():
       
   660             window = self.PluginTree.GetItemWindow(item)
       
   661             if show:
       
   662                 window.Show()
       
   663             else:
       
   664                 window.Hide()
       
   665             if self.PluginTree.IsExpanded(item):
       
   666                 self.ShowChildrenWindows(item, show)
       
   667             item, root_cookie = self.PluginTree.GetNextChild(root, root_cookie)
       
   668 
       
   669     def OnPluginTreeItemExpanded(self, event):
       
   670         self.ShowChildrenWindows(event.GetItem(), True)
       
   671         self.MustRecalTreeSizes = True
       
   672         event.Skip()
       
   673 
       
   674     def OnPluginTreeItemCollapsed(self, event):
       
   675         self.ShowChildrenWindows(event.GetItem(), False)
       
   676         event.Skip()
       
   677     
       
   678     def GetItemChannelChangedFunction(self, item):
       
   679         def OnPluginTreeItemChannelChanged(event):
   718         def OnPluginTreeItemChannelChanged(event):
   680             if not self.DisableEvents:
   719             res, StructChanged = plugin.SetParamsAttribute("BaseParams.IEC_Channel", value, self.Log)
   681                 plugin = self.GetSelectedPlugin(item)
   720             wx.CallAfter(self.RefreshPluginTree)
   682                 if plugin:
       
   683                     res, StructChanged = plugin.SetParamsAttribute("BaseParams.IEC_Channel", event.GetInt(), self.Log)
       
   684                     wx.CallAfter(self.RefreshPluginTree)
       
   685             event.Skip()
   721             event.Skip()
   686         return OnPluginTreeItemChannelChanged
   722         return OnPluginTreeItemChannelChanged
   687     
   723     
   688     def _GetAddPluginFunction(self, name, selected = None):
   724     def _GetAddPluginFunction(self, name, plugin):
   689         def OnPluginMenu(event):
   725         def OnPluginMenu(event):
   690             self.AddPlugin(name, selected)
   726             self.AddPlugin(name, plugin)
   691             event.Skip()
   727             event.Skip()
   692         return OnPluginMenu
   728         return OnPluginMenu
   693     
   729     
   694     def OnPluginTreeRightUp(self, event):
   730     def OnPluginTreeRightUp(self, event):
   695         plugin = self.GetSelectedPlugin()
   731         plugin = self.GetSelectedPlugin()
   707             self.Bind(wx.EVT_MENU, self.OnDeleteButton, id=new_id)
   743             self.Bind(wx.EVT_MENU, self.OnDeleteButton, id=new_id)
   708             pos_x, pos_y = event.GetPosition()
   744             pos_x, pos_y = event.GetPosition()
   709             self.PluginTree.PopupMenuXY(main_menu, pos_x, pos_y)
   745             self.PluginTree.PopupMenuXY(main_menu, pos_x, pos_y)
   710         event.Skip()
   746         event.Skip()
   711     
   747     
   712     def RefreshPluginToolBar(self):
       
   713         if wx.VERSION < (2, 8, 0):
       
   714             self.ClearSizer(self.MenuSizer)
       
   715         else:
       
   716             # toolbar temporarely disabled.
       
   717             return
       
   718             if "ToolBar" in self.Panes:
       
   719                 self.AUIManager.DetachPane(self.Panes["ToolBar"])
       
   720                 self.Panes["ToolBar"].Destroy()
       
   721         if self.PluginRoot.HasOpenedProject() and len(self.PluginRoot.PluginMethods) > 0:
       
   722             if wx.VERSION > (2, 8, 0):
       
   723                 toolbar = wx.ToolBar(self, -1, wx.DefaultPosition, wx.DefaultSize,
       
   724                     wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER | wx.TB_TEXT)
       
   725                 toolbar.SetToolBitmapSize(wx.Size(48, 48))
       
   726             else:
       
   727                 boxsizer = wx.BoxSizer(wx.HORIZONTAL)
       
   728             width = 0
       
   729             for plugin_infos in self.PluginRoot.PluginMethods:
       
   730                 if "method" in plugin_infos:
       
   731                     id = wx.NewId()
       
   732                     if "bitmap" in plugin_infos:
       
   733                         if wx.VERSION < (2, 8, 0):
       
   734                             button = wx.lib.buttons.GenBitmapTextButton(ID=id, parent=self.RightPanel,
       
   735                                 bitmap=wx.Bitmap(os.path.join(CWD, "%s32x32.png"%plugin_infos["bitmap"])), label=plugin_infos["name"],
       
   736                                 name=plugin_infos["name"], pos=wx.Point(0, 0), style=wx.BU_EXACTFIT|wx.NO_BORDER)
       
   737                         else:
       
   738                             button = wx.lib.buttons.GenBitmapTextButton(id=id, parent=toolbar,
       
   739                                 bitmap=wx.Bitmap(os.path.join(CWD, "%s32x32.png"%plugin_infos["bitmap"])), label=plugin_infos["name"],
       
   740                                 name=plugin_infos["name"], pos=wx.Point(0, 0), style=wx.BU_EXACTFIT|wx.NO_BORDER)
       
   741                             button.SetSize(button.GetBestSize())
       
   742                     else:
       
   743                         if wx.VERSION < (2, 8, 0):
       
   744                             button = wx.Button(id=id, label=plugin_infos["name"], 
       
   745                                 name=plugin_infos["name"], parent=self.RightPanel, 
       
   746                                 pos=wx.Point(0, 0), style=wx.BU_EXACTFIT)
       
   747                         else:
       
   748                             button = wx.Button(id=id, label=plugin_infos["name"], 
       
   749                                 name=plugin_infos["name"], parent=toolbar, 
       
   750                                 pos=wx.Point(0, 0), size=(-1, 48), style=wx.BU_EXACTFIT)
       
   751                     button.SetToolTipString(plugin_infos["tooltip"])
       
   752                     button.Bind(wx.EVT_BUTTON, self.GetButtonCallBackFunction(self.PluginRoot, plugin_infos["method"]), id=id)
       
   753                     width += button.GetSize()[0]
       
   754                     if wx.VERSION < (2, 8, 0):
       
   755                         boxsizer.AddWindow(button, 0, border=5, flag=wx.GROW|wx.RIGHT)
       
   756                     else:
       
   757                         toolbar.AddControl(button)
       
   758             if wx.VERSION < (2, 8, 0):
       
   759                 self.MenuSizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.ALL)
       
   760                 self.RightGridSizer.Layout()
       
   761             else:
       
   762                 toolbar.Realize()
       
   763                 self.Panes["ToolBar"] = toolbar
       
   764                 self.AUIManager.AddPane(toolbar, wx.aui.AuiPaneInfo().
       
   765                       Name("ToolBar").Caption("Toolbar").
       
   766                       ToolbarPane().Top().
       
   767                       LeftDockable(False).RightDockable(False))
       
   768                 if wx.Platform == '__WXMSW__':
       
   769                     self.AUIManager.GetPane("ToolBar").BestSize(wx.Size(width + 3, 55))
       
   770                 self.AUIManager.Update()
       
   771     
       
   772     def RefreshPluginParams(self):
       
   773         plugin = self.GetSelectedPlugin()
       
   774         if not plugin:
       
   775             # Refresh ParamsPanel
       
   776             self.ParamsPanel.Hide()
       
   777             
       
   778             # Refresh PluginChilds
       
   779             self.PluginChilds.Clear()
       
   780             self.PluginChilds.Enable(False)
       
   781             self.AddButton.Enable(False)
       
   782             self.DeleteButton.Enable(False)
       
   783         else:
       
   784             # Refresh ParamsPanel
       
   785             self.ParamsPanel.Show()
       
   786             infos = plugin.GetParamsAttributes()
       
   787             if len(self.MenuSizer.GetChildren()) > 1:
       
   788                 self.ClearSizer(self.MenuSizer.GetChildren()[1].GetSizer())
       
   789                 self.MenuSizer.Remove(1)
       
   790             self.ClearSizer(self.ParamsPanelMainSizer)
       
   791             self.RefreshSizerElement(self.ParamsPanel, self.ParamsPanelMainSizer, plugin, infos, None, False)
       
   792             if plugin != self.PluginRoot and len(plugin.PluginMethods) > 0:
       
   793                 boxsizer = wx.BoxSizer(wx.HORIZONTAL)
       
   794                 self.MenuSizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.ALL)
       
   795                 for plugin_infos in plugin.PluginMethods:
       
   796                     if "method" in plugin_infos:
       
   797                         id = wx.NewId()
       
   798                         if "bitmap" in plugin_infos:
       
   799                             button = wx.lib.buttons.GenBitmapTextButton(ID=id, parent=self.RightPanel, 
       
   800                                   bitmap=wx.Bitmap(os.path.join(CWD, "%s32x32.png"%plugin_infos["bitmap"])), label=plugin_infos["name"], 
       
   801                                   name=plugin_infos["name"], pos=wx.Point(0, 0), style=wx.BU_EXACTFIT|wx.NO_BORDER)
       
   802                         else:
       
   803                             button = wx.Button(id=id, label=plugin_infos["name"], 
       
   804                                 name=plugin_infos["name"], parent=self.RightPanel, 
       
   805                                 pos=wx.Point(0, 0), style=wx.BU_EXACTFIT)
       
   806                         button.SetToolTipString(plugin_infos["tooltip"])
       
   807                         button.Bind(wx.EVT_BUTTON, self.GetButtonCallBackFunction(plugin, plugin_infos["method"]), id=id)
       
   808                         boxsizer.AddWindow(button, 0, border=5, flag=wx.GROW|wx.RIGHT)
       
   809             self.RightGridSizer.Layout()
       
   810             self.ParamsPanelMainSizer.Layout()
       
   811             self.ParamsPanel.SetClientSize(self.ParamsPanel.GetClientSize())
       
   812             
       
   813             # Refresh PluginChilds
       
   814             self.PluginChilds.Clear()
       
   815             if len(plugin.PlugChildsTypes) > 0:
       
   816                 self.PluginChilds.Append("")
       
   817                 for name, XSDClass in plugin.PlugChildsTypes:
       
   818                     self.PluginChilds.Append(name)
       
   819                 self.PluginChilds.Enable(True)
       
   820                 self.AddButton.Enable(True)
       
   821             else:
       
   822                 self.PluginChilds.Enable(False)
       
   823                 self.AddButton.Enable(False)
       
   824             self.DeleteButton.Enable(True)
       
   825     
       
   826     def GetButtonCallBackFunction(self, plugin, method):
   748     def GetButtonCallBackFunction(self, plugin, method):
   827         def OnButtonClick(event):
   749         def OnButtonClick(event):
   828             method(plugin, self.Log)
   750             method(plugin, self.Log)
   829             event.Skip()
   751             event.Skip()
   830         return OnButtonClick
   752         return OnButtonClick
   831     
   753     
   832     def GetChoiceCallBackFunction(self, choicectrl, plugin, path, selected=None):
   754     def GetChoiceCallBackFunction(self, choicectrl, plugin, path):
   833         def OnChoiceChanged(event):
   755         def OnChoiceChanged(event):
   834             if plugin:
   756             res, StructChanged = plugin.SetParamsAttribute(path, choicectrl.GetStringSelection(), self.Log)
   835                 res, StructChanged = plugin.SetParamsAttribute(path, choicectrl.GetStringSelection(), self.Log)
   757             if StructChanged: wx.CallAfter(self.RefreshPluginTree)
   836                 if StructChanged: wx.CallAfter(self.RefreshPluginTree)
   758             choicectrl.SetStringSelection(res)
   837                 choicectrl.SetStringSelection(res)
       
   838             event.Skip()
   759             event.Skip()
   839         return OnChoiceChanged
   760         return OnChoiceChanged
   840     
   761     
   841     def GetChoiceContentCallBackFunction(self, choicectrl, staticboxsizer, plugin, path, selected=None):
   762     def GetChoiceContentCallBackFunction(self, choicectrl, staticboxsizer, plugin, path):
   842         def OnChoiceContentChanged(event):
   763         def OnChoiceContentChanged(event):
   843             if plugin:
   764             res, StructChanged = plugin.SetParamsAttribute(path, choicectrl.GetStringSelection(), self.Log)
   844                 res, StructChanged = plugin.SetParamsAttribute(path, choicectrl.GetStringSelection(), self.Log)
   765             if StructChanged: wx.CallAfter(self.RefreshPluginTree)
   845                 if StructChanged: wx.CallAfter(self.RefreshPluginTree)
   766             choicectrl.SetStringSelection(res)
   846                 choicectrl.SetStringSelection(res)
   767             infos = self.PluginRoot.GetParamsAttributes(path)
   847                 infos = self.PluginRoot.GetParamsAttributes(path)
   768             staticbox = staticboxsizer.GetStaticBox()
   848                 staticbox = staticboxsizer.GetStaticBox()
   769             staticbox.SetLabel("%(name)s - %(value)s"%infos)
   849                 staticbox.SetLabel("%(name)s - %(value)s"%infos)
   770             if wx.VERSION < (2, 8, 0):
   850                 if wx.VERSION < (2, 8, 0):
   771                 self.ParamsPanel.Freeze()
   851                     self.ParamsPanel.Freeze()
   772                 self.RefreshSizerElement(self.ParamsPanel, staticboxsizer, infos["children"], "%s.%s"%(path, infos["name"]), selected=selected)
   852                     self.RefreshSizerElement(self.ParamsPanel, staticboxsizer, plugin, infos["children"], "%s.%s"%(path, infos["name"]), selected=selected)
   773                 self.ParamsPanelMainSizer.Layout()
   853                     self.ParamsPanelMainSizer.Layout()
   774                 self.ParamsPanel.Thaw()
   854                     self.ParamsPanel.Thaw()
   775                 self.ParamsPanel.Refresh()
   855                     self.ParamsPanel.Refresh()
   776             else:
   856                 else:
   777                 wx.CallAfter(self.RefreshPluginTree)
   857                     wx.CallAfter(self.RefreshPluginTree)
       
   858             event.Skip()
   778             event.Skip()
   859         return OnChoiceContentChanged
   779         return OnChoiceContentChanged
   860     
   780     
   861     def GetTextCtrlCallBackFunction(self, textctrl, plugin, path, selected=None):
   781     def GetTextCtrlCallBackFunction(self, textctrl, plugin, path):
   862         def OnTextCtrlChanged(event):
   782         def OnTextCtrlChanged(event):
   863             if plugin:
   783             res, StructChanged = plugin.SetParamsAttribute(path, textctrl.GetValue(), self.Log)
   864                 res, StructChanged = plugin.SetParamsAttribute(path, textctrl.GetValue(), self.Log)
   784             if StructChanged: wx.CallAfter(self.RefreshPluginTree)
   865                 if StructChanged: wx.CallAfter(self.RefreshPluginTree)
   785             textctrl.SetValue(res)
   866                 textctrl.SetValue(res)
       
   867             event.Skip()
   786             event.Skip()
   868         return OnTextCtrlChanged
   787         return OnTextCtrlChanged
   869     
   788     
   870     def GetCheckBoxCallBackFunction(self, chkbx, plugin, path, selected=None):
   789     def GetCheckBoxCallBackFunction(self, chkbx, plugin, path):
   871         def OnCheckBoxChanged(event):
   790         def OnCheckBoxChanged(event):
   872             if plugin:
   791             res, StructChanged = plugin.SetParamsAttribute(path, chkbx.IsChecked(), self.Log)
   873                 res, StructChanged = plugin.SetParamsAttribute(path, chkbx.IsChecked(), self.Log)
   792             if StructChanged: wx.CallAfter(self.RefreshPluginTree)
   874                 if StructChanged: wx.CallAfter(self.RefreshPluginTree)
   793             chkbx.SetValue(res)
   875                 chkbx.SetValue(res)
       
   876             event.Skip()
   794             event.Skip()
   877         return OnCheckBoxChanged
   795         return OnCheckBoxChanged
   878     
   796     
   879     def ClearSizer(self, sizer):
   797     def ClearSizer(self, sizer):
   880         staticboxes = []
   798         staticboxes = []
   886                     staticboxes.append(item_sizer.GetStaticBox())
   804                     staticboxes.append(item_sizer.GetStaticBox())
   887         sizer.Clear(True)
   805         sizer.Clear(True)
   888         for staticbox in staticboxes:
   806         for staticbox in staticboxes:
   889             staticbox.Destroy()
   807             staticbox.Destroy()
   890                 
   808                 
   891     def RefreshSizerElement(self, parent, sizer, plugin, elements, path, clean = True, selected = None):
   809     def RefreshSizerElement(self, parent, sizer, plugin, elements, path, clean = True):
   892         if clean:
   810         if clean:
   893             sizer.Clear(True)
   811             if wx.VERSION < (2, 8, 0):
       
   812                 self.ClearSizer(sizer)
       
   813             else:
       
   814                 sizer.Clear(True)
   894         first = True
   815         first = True
   895         for element_infos in elements:
   816         for element_infos in elements:
   896             if path:
   817             if path:
   897                 element_path = "%s.%s"%(path, element_infos["name"])
   818                 element_path = "%s.%s"%(path, element_infos["name"])
   898             else:
   819             else:
   904                 else:
   825                 else:
   905                     sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
   826                     sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
   906                 bitmappath = os.path.join("images", "%s.png"%element_infos["name"])
   827                 bitmappath = os.path.join("images", "%s.png"%element_infos["name"])
   907                 if os.path.isfile(bitmappath):
   828                 if os.path.isfile(bitmappath):
   908                     staticbitmap = wx.StaticBitmap(id=-1, bitmap=wx.Bitmap(bitmappath),
   829                     staticbitmap = wx.StaticBitmap(id=-1, bitmap=wx.Bitmap(bitmappath),
       
   830                         name="%s_bitmap"%element_infos["name"], parent=parent,
       
   831                         pos=wx.Point(0, 0), size=wx.Size(24, 24), style=0)
       
   832                     boxsizer.AddWindow(staticbitmap, 0, border=5, flag=wx.RIGHT)
       
   833                 else:
       
   834                     staticbitmap = wx.StaticBitmap(id=-1, bitmap=GenerateEmptyBitmap(),
   909                         name="%s_bitmap"%element_infos["name"], parent=parent,
   835                         name="%s_bitmap"%element_infos["name"], parent=parent,
   910                         pos=wx.Point(0, 0), size=wx.Size(24, 24), style=0)
   836                         pos=wx.Point(0, 0), size=wx.Size(24, 24), style=0)
   911                     boxsizer.AddWindow(staticbitmap, 0, border=5, flag=wx.RIGHT)
   837                     boxsizer.AddWindow(staticbitmap, 0, border=5, flag=wx.RIGHT)
   912                 statictext = wx.StaticText(id=-1, label="%s:"%element_infos["name"], 
   838                 statictext = wx.StaticText(id=-1, label="%s:"%element_infos["name"], 
   913                     name="%s_label"%element_infos["name"], parent=parent, 
   839                     name="%s_label"%element_infos["name"], parent=parent, 
   924                     staticbox = wx.StaticBox(id=-1, label="%(name)s - %(value)s"%element_infos, 
   850                     staticbox = wx.StaticBox(id=-1, label="%(name)s - %(value)s"%element_infos, 
   925                         name='%s_staticbox'%element_infos["name"], parent=parent,
   851                         name='%s_staticbox'%element_infos["name"], parent=parent,
   926                         pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0)
   852                         pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0)
   927                     staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL)
   853                     staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL)
   928                     sizer.AddSizer(staticboxsizer, 0, border=5, flag=wx.GROW|wx.BOTTOM)
   854                     sizer.AddSizer(staticboxsizer, 0, border=5, flag=wx.GROW|wx.BOTTOM)
   929                     self.RefreshSizerElement(parent, staticboxsizer, plugin, element_infos["children"], element_path, selected)
   855                     self.RefreshSizerElement(parent, staticboxsizer, plugin, element_infos["children"], element_path)
   930                     callback = self.GetChoiceContentCallBackFunction(choicectrl, staticboxsizer, plugin, element_path, selected)
   856                     callback = self.GetChoiceContentCallBackFunction(choicectrl, staticboxsizer, plugin, element_path)
   931                 else:
   857                 else:
   932                     for choice in element_infos["type"]:
   858                     for choice in element_infos["type"]:
   933                         choicectrl.Append(choice)
   859                         choicectrl.Append(choice)
   934                     callback = self.GetChoiceCallBackFunction(choicectrl, plugin, element_path, selected)
   860                     callback = self.GetChoiceCallBackFunction(choicectrl, plugin, element_path)
   935                 if element_infos["value"]:
   861                 if element_infos["value"]:
   936                     choicectrl.SetStringSelection(element_infos["value"])
   862                     choicectrl.SetStringSelection(element_infos["value"])
   937                 choicectrl.Bind(wx.EVT_CHOICE, callback, id=id)
   863                 choicectrl.Bind(wx.EVT_CHOICE, callback, id=id)
   938             elif isinstance(element_infos["type"], types.DictType):
   864             elif isinstance(element_infos["type"], types.DictType):
   939                 boxsizer = wx.BoxSizer(wx.HORIZONTAL)
   865                 boxsizer = wx.BoxSizer(wx.HORIZONTAL)
   942                 else:
   868                 else:
   943                     sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
   869                     sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
   944                 bitmappath = os.path.join("images", "%s.png"%element_infos["name"])
   870                 bitmappath = os.path.join("images", "%s.png"%element_infos["name"])
   945                 if os.path.isfile(bitmappath):
   871                 if os.path.isfile(bitmappath):
   946                     staticbitmap = wx.StaticBitmap(id=-1, bitmap=wx.Bitmap(bitmappath),
   872                     staticbitmap = wx.StaticBitmap(id=-1, bitmap=wx.Bitmap(bitmappath),
       
   873                         name="%s_bitmap"%element_infos["name"], parent=parent,
       
   874                         pos=wx.Point(0, 0), size=wx.Size(24, 24), style=0)
       
   875                     boxsizer.AddWindow(staticbitmap, 0, border=5, flag=wx.RIGHT)
       
   876                 else:
       
   877                     staticbitmap = wx.StaticBitmap(id=-1, bitmap=GenerateEmptyBitmap(),
   947                         name="%s_bitmap"%element_infos["name"], parent=parent,
   878                         name="%s_bitmap"%element_infos["name"], parent=parent,
   948                         pos=wx.Point(0, 0), size=wx.Size(24, 24), style=0)
   879                         pos=wx.Point(0, 0), size=wx.Size(24, 24), style=0)
   949                     boxsizer.AddWindow(staticbitmap, 0, border=5, flag=wx.RIGHT)
   880                     boxsizer.AddWindow(staticbitmap, 0, border=5, flag=wx.RIGHT)
   950                 statictext = wx.StaticText(id=-1, label="%s:"%element_infos["name"], 
   881                 statictext = wx.StaticText(id=-1, label="%s:"%element_infos["name"], 
   951                     name="%s_label"%element_infos["name"], parent=parent, 
   882                     name="%s_label"%element_infos["name"], parent=parent, 
   961                 spinctrl = wx.SpinCtrl(id=id, name=element_infos["name"], parent=parent, 
   892                 spinctrl = wx.SpinCtrl(id=id, name=element_infos["name"], parent=parent, 
   962                     pos=wx.Point(0, 0), size=wx.Size(150, 25), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT)
   893                     pos=wx.Point(0, 0), size=wx.Size(150, 25), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT)
   963                 spinctrl.SetRange(scmin,scmax)
   894                 spinctrl.SetRange(scmin,scmax)
   964                 boxsizer.AddWindow(spinctrl, 0, border=0, flag=0)
   895                 boxsizer.AddWindow(spinctrl, 0, border=0, flag=0)
   965                 spinctrl.SetValue(element_infos["value"])
   896                 spinctrl.SetValue(element_infos["value"])
   966                 spinctrl.Bind(wx.EVT_SPINCTRL, self.GetTextCtrlCallBackFunction(spinctrl, plugin, element_path, selected), id=id)
   897                 spinctrl.Bind(wx.EVT_SPINCTRL, self.GetTextCtrlCallBackFunction(spinctrl, plugin, element_path), id=id)
   967             elif element_infos["type"] == "element":
   898             elif element_infos["type"] == "element":
   968                 staticbox = wx.StaticBox(id=-1, label=element_infos["name"], 
   899                 staticbox = wx.StaticBox(id=-1, label=element_infos["name"], 
   969                     name='%s_staticbox'%element_infos["name"], parent=parent,
   900                     name='%s_staticbox'%element_infos["name"], parent=parent,
   970                     pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0)
   901                     pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0)
   971                 staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL)
   902                 staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL)
   972                 if first:
   903                 if first:
   973                     sizer.AddSizer(staticboxsizer, 0, border=0, flag=wx.GROW|wx.TOP)
   904                     sizer.AddSizer(staticboxsizer, 0, border=0, flag=wx.GROW|wx.TOP)
   974                 else:
   905                 else:
   975                     sizer.AddSizer(staticboxsizer, 0, border=0, flag=wx.GROW)
   906                     sizer.AddSizer(staticboxsizer, 0, border=0, flag=wx.GROW)
   976                 self.RefreshSizerElement(parent, staticboxsizer, plugin, element_infos["children"], element_path, False, selected)
   907                 self.RefreshSizerElement(parent, staticboxsizer, plugin, element_infos["children"], element_path)
   977             else:
   908             else:
   978                 boxsizer = wx.BoxSizer(wx.HORIZONTAL)
   909                 boxsizer = wx.BoxSizer(wx.HORIZONTAL)
   979                 if first:
   910                 if first:
   980                     sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.ALL)
   911                     sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.ALL)
   981                 else:
   912                 else:
   984                 if os.path.isfile(bitmappath):
   915                 if os.path.isfile(bitmappath):
   985                     staticbitmap = wx.StaticBitmap(id=-1, bitmap=wx.Bitmap(bitmappath),
   916                     staticbitmap = wx.StaticBitmap(id=-1, bitmap=wx.Bitmap(bitmappath),
   986                         name="%s_bitmap"%element_infos["name"], parent=parent,
   917                         name="%s_bitmap"%element_infos["name"], parent=parent,
   987                         pos=wx.Point(0, 0), size=wx.Size(24, 24), style=0)
   918                         pos=wx.Point(0, 0), size=wx.Size(24, 24), style=0)
   988                     boxsizer.AddWindow(staticbitmap, 0, border=5, flag=wx.RIGHT)
   919                     boxsizer.AddWindow(staticbitmap, 0, border=5, flag=wx.RIGHT)
       
   920                 else:
       
   921                     staticbitmap = wx.StaticBitmap(id=-1, bitmap=GenerateEmptyBitmap(),
       
   922                         name="%s_bitmap"%element_infos["name"], parent=parent,
       
   923                         pos=wx.Point(0, 0), size=wx.Size(24, 24), style=0)
       
   924                     boxsizer.AddWindow(staticbitmap, 0, border=5, flag=wx.RIGHT)
       
   925 
   989                 statictext = wx.StaticText(id=-1, label="%s:"%element_infos["name"], 
   926                 statictext = wx.StaticText(id=-1, label="%s:"%element_infos["name"], 
   990                     name="%s_label"%element_infos["name"], parent=parent, 
   927                     name="%s_label"%element_infos["name"], parent=parent, 
   991                     pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0)
   928                     pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0)
   992                 boxsizer.AddWindow(statictext, 0, border=4, flag=wx.TOP)
   929                 boxsizer.AddWindow(statictext, 0, border=4, flag=wx.TOP)
   993                 id = wx.NewId()
   930                 id = wx.NewId()
   994                 if element_infos["type"] == "boolean":
   931                 if element_infos["type"] == "boolean":
   995                     checkbox = wx.CheckBox(id=id, name=element_infos["name"], parent=parent, 
   932                     checkbox = wx.CheckBox(id=id, name=element_infos["name"], parent=parent, 
   996                         pos=wx.Point(0, 0), size=wx.Size(17, 25), style=0)
   933                         pos=wx.Point(0, 0), size=wx.Size(17, 25), style=0)
   997                     boxsizer.AddWindow(checkbox, 0, border=0, flag=0)
   934                     boxsizer.AddWindow(checkbox, 0, border=0, flag=0)
   998                     checkbox.SetValue(element_infos["value"])
   935                     checkbox.SetValue(element_infos["value"])
   999                     checkbox.Bind(wx.EVT_CHECKBOX, self.GetCheckBoxCallBackFunction(checkbox, plugin, element_path, selected), id=id)
   936                     checkbox.Bind(wx.EVT_CHECKBOX, self.GetCheckBoxCallBackFunction(checkbox, plugin, element_path), id=id)
  1000                 elif element_infos["type"] in ["unsignedLong", "long","integer"]:
   937                 elif element_infos["type"] in ["unsignedLong", "long","integer"]:
  1001                     if element_infos["type"].startswith("unsigned"):
   938                     if element_infos["type"].startswith("unsigned"):
  1002                         scmin = 0
   939                         scmin = 0
  1003                     else:
   940                     else:
  1004                         scmin = -(2**31)
   941                         scmin = -(2**31)
  1006                     spinctrl = wx.SpinCtrl(id=id, name=element_infos["name"], parent=parent, 
   943                     spinctrl = wx.SpinCtrl(id=id, name=element_infos["name"], parent=parent, 
  1007                         pos=wx.Point(0, 0), size=wx.Size(150, 25), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT)
   944                         pos=wx.Point(0, 0), size=wx.Size(150, 25), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT)
  1008                     spinctrl.SetRange(scmin, scmax)
   945                     spinctrl.SetRange(scmin, scmax)
  1009                     boxsizer.AddWindow(spinctrl, 0, border=0, flag=0)
   946                     boxsizer.AddWindow(spinctrl, 0, border=0, flag=0)
  1010                     spinctrl.SetValue(element_infos["value"])
   947                     spinctrl.SetValue(element_infos["value"])
  1011                     spinctrl.Bind(wx.EVT_SPINCTRL, self.GetTextCtrlCallBackFunction(spinctrl, plugin, element_path, selected), id=id)
   948                     spinctrl.Bind(wx.EVT_SPINCTRL, self.GetTextCtrlCallBackFunction(spinctrl, plugin, element_path), id=id)
  1012                 else:
   949                 else:
  1013                     textctrl = wx.TextCtrl(id=id, name=element_infos["name"], parent=parent, 
   950                     textctrl = wx.TextCtrl(id=id, name=element_infos["name"], parent=parent, 
  1014                         pos=wx.Point(0, 0), size=wx.Size(150, 25), style=wx.TE_PROCESS_ENTER)
   951                         pos=wx.Point(0, 0), size=wx.Size(150, 25), style=wx.TE_PROCESS_ENTER)
  1015                     boxsizer.AddWindow(textctrl, 0, border=0, flag=0)
   952                     boxsizer.AddWindow(textctrl, 0, border=0, flag=0)
  1016                     textctrl.SetValue(str(element_infos["value"]))
   953                     textctrl.SetValue(str(element_infos["value"]))
  1017                     textctrl.Bind(wx.EVT_TEXT_ENTER, self.GetTextCtrlCallBackFunction(textctrl, plugin, element_path, selected), id=id)
   954                     textctrl.Bind(wx.EVT_TEXT_ENTER, self.GetTextCtrlCallBackFunction(textctrl, plugin, element_path), id=id)
  1018                     textctrl.Bind(wx.EVT_KILL_FOCUS, self.GetTextCtrlCallBackFunction(textctrl, plugin, element_path, selected))
   955                     textctrl.Bind(wx.EVT_KILL_FOCUS, self.GetTextCtrlCallBackFunction(textctrl, plugin, element_path))
  1019             first = False
   956             first = False
  1020     
   957     
  1021     def OnNewProjectMenu(self, event):
   958     def OnNewProjectMenu(self, event):
  1022         defaultpath = self.PluginRoot.GetProjectPath()
   959         defaultpath = self.PluginRoot.GetProjectPath()
  1023         if not defaultpath:
   960         if not defaultpath:
  1026         if dialog.ShowModal() == wx.ID_OK:
   963         if dialog.ShowModal() == wx.ID_OK:
  1027             projectpath = dialog.GetPath()
   964             projectpath = dialog.GetPath()
  1028             dialog.Destroy()
   965             dialog.Destroy()
  1029             res = self.PluginRoot.NewProject(projectpath)
   966             res = self.PluginRoot.NewProject(projectpath)
  1030             if not res :
   967             if not res :
  1031                 self.RefreshPluginToolBar()
   968                 self.RefreshPLCParams()
  1032                 self.RefreshPluginTree()
   969                 self.RefreshPluginTree()
  1033                 self.RefreshButtons()
       
  1034                 self.RefreshMainMenu()
   970                 self.RefreshMainMenu()
  1035             else:
   971             else:
  1036                 message = wx.MessageDialog(self, res, "ERROR", wx.OK|wx.ICON_ERROR)
   972                 message = wx.MessageDialog(self, res, "ERROR", wx.OK|wx.ICON_ERROR)
  1037                 message.ShowModal()
   973                 message.ShowModal()
  1038                 message.Destroy()
   974                 message.Destroy()
  1046         if dialog.ShowModal() == wx.ID_OK:
   982         if dialog.ShowModal() == wx.ID_OK:
  1047             projectpath = dialog.GetPath()
   983             projectpath = dialog.GetPath()
  1048             if os.path.isdir(projectpath):
   984             if os.path.isdir(projectpath):
  1049                 result = self.PluginRoot.LoadProject(projectpath, self.Log)
   985                 result = self.PluginRoot.LoadProject(projectpath, self.Log)
  1050                 if not result:
   986                 if not result:
  1051                     self.RefreshPluginToolBar()
   987                     self.RefreshPLCParams()
  1052                     self.RefreshPluginTree()
   988                     self.RefreshPluginTree()
  1053                     self.PluginTree.SelectItem(self.PluginTree.GetRootItem())
       
  1054                     self.RefreshButtons()
       
  1055                     self.RefreshMainMenu()
   989                     self.RefreshMainMenu()
  1056                     self.PluginTree.ScrollWindow(0, self.PluginTree.GetClientSize()[1])
       
  1057                 else:
   990                 else:
  1058                     message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
   991                     message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
  1059                     message.ShowModal()
   992                     message.ShowModal()
  1060                     message.Destroy()
   993                     message.Destroy()
  1061             else:
   994             else:
  1064                 message.Destroy()
   997                 message.Destroy()
  1065             dialog.Destroy()
   998             dialog.Destroy()
  1066         event.Skip()
   999         event.Skip()
  1067     
  1000     
  1068     def OnCloseProjectMenu(self, event):
  1001     def OnCloseProjectMenu(self, event):
  1069         self.RefreshPluginToolBar()
  1002         self.PluginInfos = {}
       
  1003         self.RefreshPLCParams()
  1070         self.RefreshPluginTree()
  1004         self.RefreshPluginTree()
  1071         self.RefreshButtons()
       
  1072         self.RefreshMainMenu()
  1005         self.RefreshMainMenu()
  1073         event.Skip()
  1006         event.Skip()
  1074     
  1007     
  1075     def OnSaveProjectMenu(self, event):
  1008     def OnSaveProjectMenu(self, event):
  1076         if self.PluginRoot.HasProjectOpened():
  1009         if self.PluginRoot.HasProjectOpened():
  1123     
  1056     
  1124     def OnDeleteButton(self, event):
  1057     def OnDeleteButton(self, event):
  1125         self.DeletePlugin()
  1058         self.DeletePlugin()
  1126         event.Skip()
  1059         event.Skip()
  1127     
  1060     
  1128     def CloseEditor(self, bus_id):
  1061     def GetAddButtonFunction(self, plugin, window):
  1129         if self.BusManagers.get(bus_id, None) != None:
       
  1130             self.BusManagers[bus_id]["Editor"] = None
       
  1131     
       
  1132     def GetAddButtonFunction(self, item, window):
       
  1133         def AddButtonFunction(event):
  1062         def AddButtonFunction(event):
  1134             plugin = self.GetSelectedPlugin(item)
       
  1135             if plugin and len(plugin.PlugChildsTypes) > 0:
  1063             if plugin and len(plugin.PlugChildsTypes) > 0:
  1136                 plugin_menu = wx.Menu(title='')
  1064                 plugin_menu = wx.Menu(title='')
  1137                 for name, XSDClass in plugin.PlugChildsTypes:
  1065                 for name, XSDClass in plugin.PlugChildsTypes:
  1138                     new_id = wx.NewId()
  1066                     new_id = wx.NewId()
  1139                     plugin_menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=name)
  1067                     plugin_menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=name)
  1140                     self.Bind(wx.EVT_MENU, self._GetAddPluginFunction(name, item), id=new_id)
  1068                     self.Bind(wx.EVT_MENU, self._GetAddPluginFunction(name, plugin), id=new_id)
  1141                 window_pos = window.GetPosition()
  1069                 window_pos = window.GetPosition()
  1142                 wx.CallAfter(self.PluginTree.PopupMenu, plugin_menu)
  1070                 wx.CallAfter(self.PLCConfig.PopupMenu, plugin_menu)
  1143             event.Skip()
  1071             event.Skip()
  1144         return AddButtonFunction
  1072         return AddButtonFunction
  1145     
  1073     
  1146     def GetDeleteButtonFunction(self, item):
  1074     def GetDeleteButtonFunction(self, plugin):
  1147         def DeleteButtonFunction(event):
  1075         def DeleteButtonFunction(event):
  1148             wx.CallAfter(self.DeletePlugin, item)
  1076             wx.CallAfter(self.DeletePlugin, plugin)
  1149             event.Skip()
  1077             event.Skip()
  1150         return DeleteButtonFunction
  1078         return DeleteButtonFunction
  1151     
  1079     
  1152     def AddPlugin(self, PluginType, selected = None):
  1080     def AddPlugin(self, PluginType, plugin):
  1153         dialog = wx.TextEntryDialog(self, "Please enter a name for plugin:", "Add Plugin", "", wx.OK|wx.CANCEL)
  1081         dialog = wx.TextEntryDialog(self, "Please enter a name for plugin:", "Add Plugin", "", wx.OK|wx.CANCEL)
  1154         if dialog.ShowModal() == wx.ID_OK:
  1082         if dialog.ShowModal() == wx.ID_OK:
  1155             PluginName = dialog.GetValue()
  1083             PluginName = dialog.GetValue()
  1156             plugin = self.GetSelectedPlugin(selected)
       
  1157             plugin.PlugAddChild(PluginName, PluginType, self.Log)
  1084             plugin.PlugAddChild(PluginName, PluginType, self.Log)
  1158             self.RefreshPluginTree()
  1085             self.RefreshPluginTree()
  1159         dialog.Destroy()
  1086         dialog.Destroy()
  1160     
  1087     
  1161     def DeletePlugin(self, selected = None):
  1088     def DeletePlugin(self, plugin):
  1162         dialog = wx.MessageDialog(self, "Really delete plugin ?", "Remove plugin", wx.YES_NO|wx.NO_DEFAULT)
  1089         dialog = wx.MessageDialog(self, "Really delete plugin ?", "Remove plugin", wx.YES_NO|wx.NO_DEFAULT)
  1163         if dialog.ShowModal() == wx.ID_YES:
  1090         if dialog.ShowModal() == wx.ID_YES:
  1164             plugin = self.GetSelectedPlugin(selected)
  1091             self.PluginInfos.pop(plugin)
  1165             plugin.PlugRemove()
  1092             plugin.PlugRemove()
  1166             del plugin
  1093             del plugin
  1167             self.RefreshPluginTree()
  1094             self.RefreshPluginTree()
  1168         dialog.Destroy()
  1095         dialog.Destroy()
  1169 
  1096