Beremiz.py
changeset 675 44b35c27e9ff
parent 666 5056f17a0c6b
child 678 92a1ec3c6fdd
equal deleted inserted replaced
674:761de581cf7a 675:44b35c27e9ff
    30 from wx.lib.agw.advancedsplash import AdvancedSplash
    30 from wx.lib.agw.advancedsplash import AdvancedSplash
    31 import tempfile
    31 import tempfile
    32 import shutil
    32 import shutil
    33 import random
    33 import random
    34 import time
    34 import time
       
    35 from types import ListType
    35 
    36 
    36 CWD = os.path.split(os.path.realpath(__file__))[0]
    37 CWD = os.path.split(os.path.realpath(__file__))[0]
    37 
    38 
    38 def Bpath(*args):
    39 def Bpath(*args):
    39     return os.path.join(CWD,*args)
    40     return os.path.join(CWD,*args)
   170               'helv' : 'Helvetica',
   171               'helv' : 'Helvetica',
   171               'other': 'new century schoolbook',
   172               'other': 'new century schoolbook',
   172               'size' : 18,
   173               'size' : 18,
   173              }
   174              }
   174 
   175 
       
   176 MAX_RECENT_PROJECTS = 10
       
   177 
   175 # Some helpers to tweak GenBitmapTextButtons
   178 # Some helpers to tweak GenBitmapTextButtons
   176 # TODO: declare customized classes instead.
   179 # TODO: declare customized classes instead.
   177 gen_mini_GetBackgroundBrush = lambda obj:lambda dc: wx.Brush(obj.GetParent().GetBackgroundColour(), wx.SOLID)
   180 gen_mini_GetBackgroundBrush = lambda obj:lambda dc: wx.Brush(obj.GetParent().GetBackgroundColour(), wx.SOLID)
   178 gen_textbutton_GetLabelSize = lambda obj:lambda:(wx.lib.buttons.GenButton._GetLabelSize(obj)[:-1] + (False,))
   181 gen_textbutton_GetLabelSize = lambda obj:lambda:(wx.lib.buttons.GenButton._GetLabelSize(obj)[:-1] + (False,))
   179 
   182 
   325 
   328 
   326 [ID_BEREMIZ, ID_BEREMIZMAINSPLITTER, 
   329 [ID_BEREMIZ, ID_BEREMIZMAINSPLITTER, 
   327  ID_BEREMIZPLCCONFIG, ID_BEREMIZLOGCONSOLE, 
   330  ID_BEREMIZPLCCONFIG, ID_BEREMIZLOGCONSOLE, 
   328  ID_BEREMIZINSPECTOR] = [wx.NewId() for _init_ctrls in range(5)]
   331  ID_BEREMIZINSPECTOR] = [wx.NewId() for _init_ctrls in range(5)]
   329 
   332 
       
   333 [ID_FILEMENURECENTPROJECTS,
       
   334 ] = [wx.NewId() for _init_ctrls in range(1)]
       
   335 
       
   336 PLUGINMENU_POSITION = 3
       
   337 
   330 class Beremiz(IDEFrame):
   338 class Beremiz(IDEFrame):
   331 	
   339 	
       
   340     def _init_coll_MenuBar_Menus(self, parent):
       
   341         IDEFrame._init_coll_MenuBar_Menus(self, parent)
       
   342         
       
   343         parent.Insert(pos=PLUGINMENU_POSITION, 
       
   344                       menu=self.PluginMenu, title=_(u'&Plugin'))
       
   345     
       
   346     def _init_utils(self):
       
   347         self.PluginMenu = wx.Menu(title='')
       
   348         self.RecentProjectsMenu = wx.Menu(title='')
       
   349         
       
   350         IDEFrame._init_utils(self)
       
   351         
   332     def _init_coll_FileMenu_Items(self, parent):
   352     def _init_coll_FileMenu_Items(self, parent):
   333         AppendMenu(parent, help='', id=wx.ID_NEW,
   353         AppendMenu(parent, help='', id=wx.ID_NEW,
   334               kind=wx.ITEM_NORMAL, text=_(u'New\tCTRL+N'))
   354               kind=wx.ITEM_NORMAL, text=_(u'New\tCTRL+N'))
   335         AppendMenu(parent, help='', id=wx.ID_OPEN,
   355         AppendMenu(parent, help='', id=wx.ID_OPEN,
   336               kind=wx.ITEM_NORMAL, text=_(u'Open\tCTRL+O'))
   356               kind=wx.ITEM_NORMAL, text=_(u'Open\tCTRL+O'))
       
   357         parent.AppendMenu(ID_FILEMENURECENTPROJECTS, _("Recent Projects"), self.RecentProjectsMenu)
       
   358         parent.AppendSeparator()
   337         AppendMenu(parent, help='', id=wx.ID_SAVE,
   359         AppendMenu(parent, help='', id=wx.ID_SAVE,
   338               kind=wx.ITEM_NORMAL, text=_(u'Save\tCTRL+S'))
   360               kind=wx.ITEM_NORMAL, text=_(u'Save\tCTRL+S'))
   339         AppendMenu(parent, help='', id=wx.ID_SAVEAS,
   361         AppendMenu(parent, help='', id=wx.ID_SAVEAS,
   340               kind=wx.ITEM_NORMAL, text=_(u'Save as\tCTRL+SHIFT+S'))
   362               kind=wx.ITEM_NORMAL, text=_(u'Save as\tCTRL+SHIFT+S'))
   341         AppendMenu(parent, help='', id=wx.ID_CLOSE,
   363         AppendMenu(parent, help='', id=wx.ID_CLOSE,
   451         
   473         
   452         self.DisableEvents = False
   474         self.DisableEvents = False
   453         # Variable allowing disabling of PLCConfig scroll when Popup shown 
   475         # Variable allowing disabling of PLCConfig scroll when Popup shown 
   454         self.ScrollingEnabled = True
   476         self.ScrollingEnabled = True
   455         
   477         
       
   478         self.LastPanelSelected = None
       
   479         
   456         self.PluginInfos = {}
   480         self.PluginInfos = {}
   457         
   481         
   458         # Define Tree item icon list
   482         # Define Tree item icon list
   459         self.LocationImageList = wx.ImageList(16, 16)
   483         self.LocationImageList = wx.ImageList(16, 16)
   460         self.LocationImageDict = {}
   484         self.LocationImageDict = {}
   492             self.DebugVariablePanel.SetDataProducer(self.PluginRoot)
   516             self.DebugVariablePanel.SetDataProducer(self.PluginRoot)
   493         
   517         
   494         self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
   518         self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
   495         
   519         
   496         self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
   520         self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
       
   521         self.RefreshPluginMenu()
   497         self.LogConsole.SetFocus()
   522         self.LogConsole.SetFocus()
   498 
   523 
   499     def RiseLogConsole(self):
   524     def RiseLogConsole(self):
   500         self.BottomNoteBook.SetSelection(self.BottomNoteBook.GetPageIndex(self.LogConsole))
   525         self.BottomNoteBook.SetSelection(self.BottomNoteBook.GetPageIndex(self.LogConsole))
   501         
   526         
   608         if isinstance(focused, TextCtrlAutoComplete.TextCtrlAutoComplete):
   633         if isinstance(focused, TextCtrlAutoComplete.TextCtrlAutoComplete):
   609             focused.DismissListBox()
   634             focused.DismissListBox()
   610         event.Skip()
   635         event.Skip()
   611     
   636     
   612     def RefreshFileMenu(self):
   637     def RefreshFileMenu(self):
       
   638         self.RefreshRecentProjectsMenu()
       
   639         
   613         if self.PluginRoot is not None:
   640         if self.PluginRoot is not None:
   614             selected = self.TabsOpened.GetSelection()
   641             selected = self.TabsOpened.GetSelection()
   615             if selected >= 0:
   642             if selected >= 0:
   616                 graphic_viewer = isinstance(self.TabsOpened.GetPage(selected), Viewer)
   643                 graphic_viewer = isinstance(self.TabsOpened.GetPage(selected), Viewer)
   617             else:
   644             else:
   640             self.FileMenu.Enable(wx.ID_PRINT, False)
   667             self.FileMenu.Enable(wx.ID_PRINT, False)
   641             self.FileMenu.Enable(wx.ID_SAVE, False)
   668             self.FileMenu.Enable(wx.ID_SAVE, False)
   642             self.FileMenu.Enable(wx.ID_SAVEAS, False)
   669             self.FileMenu.Enable(wx.ID_SAVEAS, False)
   643             self.FileMenu.Enable(wx.ID_PROPERTIES, False)
   670             self.FileMenu.Enable(wx.ID_PROPERTIES, False)
   644             self.FileMenu.Enable(wx.ID_CLOSE_ALL, False)
   671             self.FileMenu.Enable(wx.ID_CLOSE_ALL, False)
   645         
   672     
       
   673     def RefreshRecentProjectsMenu(self):
       
   674         for i in xrange(self.RecentProjectsMenu.GetMenuItemCount()):
       
   675             item = self.RecentProjectsMenu.FindItemByPosition(0)
       
   676             self.RecentProjectsMenu.Delete(item.GetId())
       
   677         
       
   678         recent_projects = cPickle.loads(str(self.Config.Read("RecentProjects", cPickle.dumps([]))))
       
   679         self.FileMenu.Enable(ID_FILEMENURECENTPROJECTS, len(recent_projects) > 0)
       
   680         for idx, projectpath in enumerate(recent_projects):
       
   681             id = wx.NewId()
       
   682             AppendMenu(self.RecentProjectsMenu, help='', id=id, 
       
   683                        kind=wx.ITEM_NORMAL, text="%d: %s" % (idx + 1, projectpath))
       
   684             self.Bind(wx.EVT_MENU, self.GenerateOpenRecentProjectFunction(projectpath), id=id)
       
   685     
       
   686     def GenerateOpenRecentProjectFunction(self, projectpath):
       
   687         def OpenRecentProject(event):
       
   688             if self.PluginRoot is not None and not self.CheckSaveBeforeClosing():
       
   689                 return
       
   690             
       
   691             self.OpenProject(projectpath)
       
   692         return OpenRecentProject
       
   693     
       
   694     def GenerateMenuRecursive(self, items, menu):
       
   695         for kind, infos in items:
       
   696             if isinstance(kind, ListType):
       
   697                 text, id = infos
       
   698                 submenu = wx.Menu('')
       
   699                 self.GenerateMenuRecursive(kind, submenu)
       
   700                 menu.AppendMenu(id, text, submenu)
       
   701             elif kind == wx.ITEM_SEPARATOR:
       
   702                 menu.AppendSeparator()
       
   703             else:
       
   704                 text, id, help, callback = infos
       
   705                 AppendMenu(menu, help='', id=id, kind=kind, text=text)
       
   706                 if callback is not None:
       
   707                     self.Bind(wx.EVT_MENU, callback, id=id)
       
   708     
       
   709     def RefreshPluginMenu(self):
       
   710         if self.PluginRoot is not None:
       
   711             selected = self.TabsOpened.GetSelection()
       
   712             if selected >= 0:
       
   713                 panel = self.TabsOpened.GetPage(selected)
       
   714             else:
       
   715                 panel = None
       
   716             if panel != self.LastPanelSelected:
       
   717                 for i in xrange(self.PluginMenu.GetMenuItemCount()):
       
   718                     item = self.PluginMenu.FindItemByPosition(0)
       
   719                     self.PluginMenu.Delete(item.GetId())
       
   720                 self.LastPanelSelected = panel
       
   721                 if panel is not None:
       
   722                     items = panel.GetPluginMenuItems()
       
   723                 else:
       
   724                     items = []
       
   725                 self.MenuBar.EnableTop(PLUGINMENU_POSITION, len(items) > 0)
       
   726                 self.GenerateMenuRecursive(items, self.PluginMenu)
       
   727             if panel is not None:
       
   728                 panel.RefreshPluginMenu(self.PluginMenu)
       
   729         else:
       
   730             self.MenuBar.EnableTop(PLUGINMENU_POSITION, False)
       
   731         self.MenuBar.UpdateMenus()
       
   732     
   646     def RefreshScrollBars(self):
   733     def RefreshScrollBars(self):
   647         xstart, ystart = self.PLCConfig.GetViewStart()
   734         xstart, ystart = self.PLCConfig.GetViewStart()
   648         window_size = self.PLCConfig.GetClientSize()
   735         window_size = self.PLCConfig.GetClientSize()
   649         sizer = self.PLCConfig.GetSizer()
   736         sizer = self.PLCConfig.GetSizer()
   650         if sizer:
   737         if sizer:
   739             
   826             
   740         self.PLCConfigMainSizer.Layout()
   827         self.PLCConfigMainSizer.Layout()
   741         self.RefreshScrollBars()
   828         self.RefreshScrollBars()
   742         self.Thaw()
   829         self.Thaw()
   743 
   830 
       
   831     def GenerateEnableButton(self, parent, sizer, plugin):
       
   832         enabled = plugin.PlugEnabled()
       
   833         if enabled is not None:
       
   834             enablebutton_id = wx.NewId()
       
   835             enablebutton = wx.lib.buttons.GenBitmapToggleButton(id=enablebutton_id, bitmap=wx.Bitmap(Bpath( 'images', 'Disabled.png')),
       
   836                   name='EnableButton', parent=parent, size=wx.Size(16, 16), pos=wx.Point(0, 0), style=0)#wx.NO_BORDER)
       
   837             enablebutton.SetToolTipString(_("Enable/Disable this plugin"))
       
   838             make_genbitmaptogglebutton_flat(enablebutton)
       
   839             enablebutton.SetBitmapSelected(wx.Bitmap(Bpath( 'images', 'Enabled.png')))
       
   840             enablebutton.SetToggle(enabled)
       
   841             def toggleenablebutton(event):
       
   842                 res = self.SetPluginParamsAttribute(plugin, "BaseParams.Enabled", enablebutton.GetToggle())
       
   843                 enablebutton.SetToggle(res)
       
   844                 event.Skip()
       
   845             enablebutton.Bind(wx.EVT_BUTTON, toggleenablebutton, id=enablebutton_id)
       
   846             sizer.AddWindow(enablebutton, 0, border=0, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
       
   847         else:
       
   848             sizer.AddSpacer(wx.Size(16, 16))
       
   849     
   744     def GenerateMethodButtonSizer(self, plugin, parent, horizontal = True):
   850     def GenerateMethodButtonSizer(self, plugin, parent, horizontal = True):
   745         normal_bt_font=wx.Font(faces["size"] / 3, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = faces["helv"])
   851         normal_bt_font=wx.Font(faces["size"] / 3, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = faces["helv"])
   746         mouseover_bt_font=wx.Font(faces["size"] / 3, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=True, faceName = faces["helv"])
   852         mouseover_bt_font=wx.Font(faces["size"] / 3, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=True, faceName = faces["helv"])
   747         if horizontal:
   853         if horizontal:
   748             msizer = wx.FlexGridSizer(cols=len(plugin.PluginMethods))
   854             msizer = wx.FlexGridSizer(cols=len(plugin.PluginMethods))
   771                 if not plugin_method.get("enabled",True):
   877                 if not plugin_method.get("enabled",True):
   772                     button.Disable()
   878                     button.Disable()
   773                 msizer.AddWindow(button, 0, border=0, flag=wx.ALIGN_CENTER)
   879                 msizer.AddWindow(button, 0, border=0, flag=wx.ALIGN_CENTER)
   774         return msizer
   880         return msizer
   775 
   881 
       
   882     def GenerateParamsPanel(self, plugin, bkgdclr):
       
   883         rightwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
       
   884         rightwindow.SetBackgroundColour(bkgdclr)
       
   885         
       
   886         rightwindowmainsizer = wx.BoxSizer(wx.VERTICAL)
       
   887         rightwindow.SetSizer(rightwindowmainsizer)
       
   888         
       
   889         rightwindowsizer = wx.FlexGridSizer(cols=2, rows=1)
       
   890         rightwindowsizer.AddGrowableCol(1)
       
   891         rightwindowsizer.AddGrowableRow(0)
       
   892         rightwindowmainsizer.AddSizer(rightwindowsizer, 0, border=0, flag=wx.GROW)
       
   893         
       
   894         msizer = self.GenerateMethodButtonSizer(plugin, rightwindow, not self.PluginInfos[plugin]["right_visible"])
       
   895         rightwindowsizer.AddSizer(msizer, 0, border=0, flag=wx.GROW)
       
   896         
       
   897         rightparamssizer = wx.BoxSizer(wx.HORIZONTAL)
       
   898         rightwindowsizer.AddSizer(rightparamssizer, 0, border=0, flag=wx.ALIGN_RIGHT)
       
   899         
       
   900         paramswindow = wx.Panel(rightwindow, -1, size=wx.Size(-1, -1))
       
   901         paramswindow.SetBackgroundColour(bkgdclr)
       
   902         
       
   903         psizer = wx.BoxSizer(wx.HORIZONTAL)
       
   904         paramswindow.SetSizer(psizer)
       
   905         self.PluginInfos[plugin]["params"] = paramswindow
       
   906         
       
   907         rightparamssizer.AddWindow(paramswindow, 0, border=5, flag=wx.ALL)
       
   908         
       
   909         plugin_infos = plugin.GetParamsAttributes()
       
   910         if len(plugin_infos) > 0:
       
   911             self.RefreshSizerElement(paramswindow, psizer, plugin, plugin_infos, None, False)
       
   912             
       
   913             if not self.PluginInfos[plugin]["right_visible"]:
       
   914                 paramswindow.Hide()
       
   915             
       
   916             rightminimizebutton_id = wx.NewId()
       
   917             rightminimizebutton = wx.lib.buttons.GenBitmapToggleButton(id=rightminimizebutton_id, bitmap=wx.Bitmap(Bpath( 'images', 'Maximize.png')),
       
   918                   name='MinimizeButton', parent=rightwindow, pos=wx.Point(0, 0),
       
   919                   size=wx.Size(24, 24), style=wx.NO_BORDER)
       
   920             make_genbitmaptogglebutton_flat(rightminimizebutton)
       
   921             rightminimizebutton.SetBitmapSelected(wx.Bitmap(Bpath( 'images', 'Minimize.png')))
       
   922             rightminimizebutton.SetToggle(self.PluginInfos[plugin]["right_visible"])
       
   923             rightparamssizer.AddWindow(rightminimizebutton, 0, border=5, flag=wx.ALL)
       
   924                         
       
   925             def togglerightwindow(event):
       
   926                 if rightminimizebutton.GetToggle():
       
   927                     rightparamssizer.Show(0)
       
   928                     msizer.SetCols(1)
       
   929                 else:
       
   930                     rightparamssizer.Hide(0)
       
   931                     msizer.SetCols(len(plugin.PluginMethods))
       
   932                 self.PluginInfos[plugin]["right_visible"] = rightminimizebutton.GetToggle()
       
   933                 self.PLCConfigMainSizer.Layout()
       
   934                 self.RefreshScrollBars()
       
   935                 event.Skip()
       
   936             rightminimizebutton.Bind(wx.EVT_BUTTON, togglerightwindow, id=rightminimizebutton_id)
       
   937         
       
   938         return rightwindow
       
   939     
       
   940 
   776     def RefreshPluginTree(self):
   941     def RefreshPluginTree(self):
   777         self.Freeze()
   942         self.Freeze()
   778         self.ClearSizer(self.PluginTreeSizer)
   943         self.ClearSizer(self.PluginTreeSizer)
   779         if self.PluginRoot is not None:
   944         if self.PluginRoot is not None:
   780             for child in self.PluginRoot.IECSortedChilds():
   945             for child in self.PluginRoot.IECSortedChilds():
   857             if force:
  1022             if force:
   858                 for child in locations_infos[group]["children"]:
  1023                 for child in locations_infos[group]["children"]:
   859                     self.CollapseLocation(locations_infos, child, force, False)
  1024                     self.CollapseLocation(locations_infos, child, force, False)
   860         if locations_infos["root"]["left"] is not None and refresh_size:
  1025         if locations_infos["root"]["left"] is not None and refresh_size:
   861             self.RefreshTreeCtrlSize(locations_infos["root"]["left"])
  1026             self.RefreshTreeCtrlSize(locations_infos["root"]["left"])
   862                 
  1027     
   863     def GenerateTreeBranch(self, plugin):
  1028     def GenerateTreeBranch(self, plugin):
   864         leftwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
  1029         leftwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
   865         if plugin.PlugTestModified():
  1030         if plugin.PlugTestModified():
   866             bkgdclr=CHANGED_WINDOW_COLOUR
  1031             bkgdclr=CHANGED_WINDOW_COLOUR
   867         else:
  1032         else:
   899         leftsizer = wx.BoxSizer(wx.VERTICAL)
  1064         leftsizer = wx.BoxSizer(wx.VERTICAL)
   900         leftbuttonsizer.AddSizer(leftsizer, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
  1065         leftbuttonsizer.AddSizer(leftsizer, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
   901 
  1066 
   902         rolesizer = wx.BoxSizer(wx.HORIZONTAL)
  1067         rolesizer = wx.BoxSizer(wx.HORIZONTAL)
   903         leftsizer.AddSizer(rolesizer, 0, border=0, flag=wx.GROW|wx.RIGHT)
  1068         leftsizer.AddSizer(rolesizer, 0, border=0, flag=wx.GROW|wx.RIGHT)
   904 
  1069         
   905         enablebutton_id = wx.NewId()
  1070         self.GenerateEnableButton(leftwindow, rolesizer, plugin)
   906         enablebutton = wx.lib.buttons.GenBitmapToggleButton(id=enablebutton_id, bitmap=wx.Bitmap(Bpath( 'images', 'Disabled.png')),
       
   907               name='EnableButton', parent=leftwindow, size=wx.Size(16, 16), pos=wx.Point(0, 0), style=0)#wx.NO_BORDER)
       
   908         enablebutton.SetToolTipString(_("Enable/Disable this plugin"))
       
   909         make_genbitmaptogglebutton_flat(enablebutton)
       
   910         enablebutton.SetBitmapSelected(wx.Bitmap(Bpath( 'images', 'Enabled.png')))
       
   911         enablebutton.SetToggle(plugin.MandatoryParams[1].getEnabled())
       
   912         def toggleenablebutton(event):
       
   913             res = self.SetPluginParamsAttribute(plugin, "BaseParams.Enabled", enablebutton.GetToggle())
       
   914             enablebutton.SetToggle(res)
       
   915             event.Skip()
       
   916         enablebutton.Bind(wx.EVT_BUTTON, toggleenablebutton, id=enablebutton_id)
       
   917         rolesizer.AddWindow(enablebutton, 0, border=0, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
       
   918 
  1071 
   919         roletext = wx.StaticText(leftwindow, -1)
  1072         roletext = wx.StaticText(leftwindow, -1)
   920         roletext.SetLabel(plugin.PlugHelp)
  1073         roletext.SetLabel(plugin.PlugHelp)
   921         rolesizer.AddWindow(roletext, 0, border=5, flag=wx.RIGHT|wx.ALIGN_LEFT)
  1074         rolesizer.AddWindow(roletext, 0, border=5, flag=wx.RIGHT|wx.ALIGN_LEFT)
   922         
  1075         
  1011         tc = wx.TextCtrl(leftwindow, tc_id, size=wx.Size(150, 25), style=wx.NO_BORDER)
  1164         tc = wx.TextCtrl(leftwindow, tc_id, size=wx.Size(150, 25), style=wx.NO_BORDER)
  1012         tc.SetFont(wx.Font(faces["size"] * 0.75, wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
  1165         tc.SetFont(wx.Font(faces["size"] * 0.75, wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
  1013         tc.ChangeValue(plugin.MandatoryParams[1].getName())
  1166         tc.ChangeValue(plugin.MandatoryParams[1].getName())
  1014         tc.Bind(wx.EVT_TEXT, self.GetTextCtrlCallBackFunction(tc, plugin, "BaseParams.Name"), id=tc_id)
  1167         tc.Bind(wx.EVT_TEXT, self.GetTextCtrlCallBackFunction(tc, plugin, "BaseParams.Name"), id=tc_id)
  1015         iecsizer.AddWindow(tc, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
  1168         iecsizer.AddWindow(tc, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
  1016        
  1169         
  1017         rightwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
  1170         rightwindow = self.GenerateParamsPanel(plugin, bkgdclr)
  1018         rightwindow.SetBackgroundColour(bkgdclr)
  1171         self.PluginTreeSizer.AddWindow(rightwindow, 0, border=8, flag=wx.TOP|wx.GROW)
  1019         
       
  1020         self.PluginTreeSizer.AddWindow(rightwindow, 0, border=0, flag=wx.GROW)
       
  1021         
       
  1022         rightwindowmainsizer = wx.BoxSizer(wx.VERTICAL)
       
  1023         rightwindow.SetSizer(rightwindowmainsizer)
       
  1024         
       
  1025         rightwindowsizer = wx.FlexGridSizer(cols=2, rows=1)
       
  1026         rightwindowsizer.AddGrowableCol(1)
       
  1027         rightwindowsizer.AddGrowableRow(0)
       
  1028         rightwindowmainsizer.AddSizer(rightwindowsizer, 0, border=8, flag=wx.TOP|wx.GROW)
       
  1029         
       
  1030         msizer = self.GenerateMethodButtonSizer(plugin, rightwindow, not self.PluginInfos[plugin]["right_visible"])
       
  1031         rightwindowsizer.AddSizer(msizer, 0, border=0, flag=wx.GROW)
       
  1032         
       
  1033         rightparamssizer = wx.BoxSizer(wx.HORIZONTAL)
       
  1034         rightwindowsizer.AddSizer(rightparamssizer, 0, border=0, flag=wx.ALIGN_RIGHT)
       
  1035         
       
  1036         paramswindow = wx.Panel(rightwindow, -1, size=wx.Size(-1, -1))
       
  1037         paramswindow.SetBackgroundColour(bkgdclr)
       
  1038         
       
  1039         psizer = wx.BoxSizer(wx.HORIZONTAL)
       
  1040         paramswindow.SetSizer(psizer)
       
  1041         self.PluginInfos[plugin]["params"] = paramswindow
       
  1042         
       
  1043         rightparamssizer.AddWindow(paramswindow, 0, border=5, flag=wx.ALL)
       
  1044         
       
  1045         plugin_infos = plugin.GetParamsAttributes()
       
  1046         self.RefreshSizerElement(paramswindow, psizer, plugin, plugin_infos, None, False)
       
  1047         
       
  1048         if not self.PluginInfos[plugin]["right_visible"]:
       
  1049             paramswindow.Hide()
       
  1050         
       
  1051         rightminimizebutton_id = wx.NewId()
       
  1052         rightminimizebutton = wx.lib.buttons.GenBitmapToggleButton(id=rightminimizebutton_id, bitmap=wx.Bitmap(Bpath( 'images', 'Maximize.png')),
       
  1053               name='MinimizeButton', parent=rightwindow, pos=wx.Point(0, 0),
       
  1054               size=wx.Size(24, 24), style=wx.NO_BORDER)
       
  1055         make_genbitmaptogglebutton_flat(rightminimizebutton)
       
  1056         rightminimizebutton.SetBitmapSelected(wx.Bitmap(Bpath( 'images', 'Minimize.png')))
       
  1057         rightminimizebutton.SetToggle(self.PluginInfos[plugin]["right_visible"])
       
  1058         rightparamssizer.AddWindow(rightminimizebutton, 0, border=5, flag=wx.ALL)
       
  1059                     
       
  1060         def togglerightwindow(event):
       
  1061             if rightminimizebutton.GetToggle():
       
  1062                 rightparamssizer.Show(0)
       
  1063                 msizer.SetCols(1)
       
  1064             else:
       
  1065                 rightparamssizer.Hide(0)
       
  1066                 msizer.SetCols(len(plugin.PluginMethods))
       
  1067             self.PluginInfos[plugin]["right_visible"] = rightminimizebutton.GetToggle()
       
  1068             self.PLCConfigMainSizer.Layout()
       
  1069             self.RefreshScrollBars()
       
  1070             event.Skip()
       
  1071         rightminimizebutton.Bind(wx.EVT_BUTTON, togglerightwindow, id=rightminimizebutton_id)
       
  1072         
  1172         
  1073         self.PluginInfos[plugin]["left"] = leftwindow
  1173         self.PluginInfos[plugin]["left"] = leftwindow
  1074         self.PluginInfos[plugin]["right"] = rightwindow
  1174         self.PluginInfos[plugin]["right"] = rightwindow
  1075         for child in self.PluginInfos[plugin]["children"]:
  1175         for child in self.PluginInfos[plugin]["children"]:
  1076             self.GenerateTreeBranch(child)
  1176             self.GenerateTreeBranch(child)
  1383                         spinctrl.SetRange(scmin, scmax)
  1483                         spinctrl.SetRange(scmin, scmax)
  1384                         boxsizer.AddWindow(spinctrl, 0, border=0, flag=0)
  1484                         boxsizer.AddWindow(spinctrl, 0, border=0, flag=0)
  1385                         spinctrl.SetValue(element_infos["value"])
  1485                         spinctrl.SetValue(element_infos["value"])
  1386                         spinctrl.Bind(wx.EVT_SPINCTRL, self.GetTextCtrlCallBackFunction(spinctrl, plugin, element_path), id=id)
  1486                         spinctrl.Bind(wx.EVT_SPINCTRL, self.GetTextCtrlCallBackFunction(spinctrl, plugin, element_path), id=id)
  1387                     else:
  1487                     else:
  1388                         choices = cPickle.loads(str(self.Config.Read(element_path, cPickle.dumps([""]))))                           
  1488                         choices = cPickle.loads(str(self.Config.Read(element_path, cPickle.dumps([""]))))
  1389                         textctrl = TextCtrlAutoComplete.TextCtrlAutoComplete(id=id, 
  1489                         textctrl = TextCtrlAutoComplete.TextCtrlAutoComplete(id=id, 
  1390                                                                      name=element_infos["name"], 
  1490                                                                      name=element_infos["name"], 
  1391                                                                      parent=parent, 
  1491                                                                      parent=parent, 
  1392                                                                      appframe=self, 
  1492                                                                      appframe=self, 
  1393                                                                      choices=choices, 
  1493                                                                      choices=choices, 
  1449         else:
  1549         else:
  1450             defaultpath = self.Config.Read("lastopenedfolder")
  1550             defaultpath = self.Config.Read("lastopenedfolder")
  1451         
  1551         
  1452         dialog = wx.DirDialog(self , _("Choose a project"), defaultpath, wx.DD_NEW_DIR_BUTTON)
  1552         dialog = wx.DirDialog(self , _("Choose a project"), defaultpath, wx.DD_NEW_DIR_BUTTON)
  1453         if dialog.ShowModal() == wx.ID_OK:
  1553         if dialog.ShowModal() == wx.ID_OK:
  1454             projectpath = dialog.GetPath()
  1554             self.OpenProject(dialog.GetPath())
  1455             if os.path.isdir(projectpath):
  1555         dialog.Destroy()
  1456                 self.Config.Write("lastopenedfolder", os.path.dirname(projectpath))
  1556     
  1457                 self.Config.Flush()
  1557     def OpenProject(self, projectpath):
       
  1558         if os.path.isdir(projectpath):
       
  1559             self.Config.Write("lastopenedfolder", os.path.dirname(projectpath))
       
  1560             recent_projects = cPickle.loads(str(self.Config.Read("RecentProjects", cPickle.dumps([]))))
       
  1561             if projectpath in recent_projects:
       
  1562                 recent_projects.remove(projectpath)
       
  1563             recent_projects.insert(0, projectpath)
       
  1564             self.Config.Write("RecentProjects", cPickle.dumps(recent_projects[:MAX_RECENT_PROJECTS]))
       
  1565             self.Config.Flush()
       
  1566             self.ResetView()
       
  1567             self.PluginRoot = PluginsRoot(self, self.Log)
       
  1568             self.Controler = self.PluginRoot
       
  1569             result = self.PluginRoot.LoadProject(projectpath)
       
  1570             if not result:
       
  1571                 if self.EnableDebug:
       
  1572                     self.DebugVariablePanel.SetDataProducer(self.PluginRoot)
       
  1573                 self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE)
       
  1574                 self.RefreshAll()
       
  1575             else:
  1458                 self.ResetView()
  1576                 self.ResetView()
  1459                 self.PluginRoot = PluginsRoot(self, self.Log)
  1577                 self.ShowErrorMessage(result)
  1460                 self.Controler = self.PluginRoot
  1578         else:
  1461                 result = self.PluginRoot.LoadProject(projectpath)
  1579             self.ShowErrorMessage(_("\"%s\" folder is not a valid Beremiz project\n") % projectpath)
  1462                 if not result:
  1580         self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU)
  1463                     if self.EnableDebug:
       
  1464                         self.DebugVariablePanel.SetDataProducer(self.PluginRoot)
       
  1465                     self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE)
       
  1466                     self.RefreshAll()
       
  1467                 else:
       
  1468                     self.ResetView()
       
  1469                     self.ShowErrorMessage(result)
       
  1470             else:
       
  1471                 self.ShowErrorMessage(_("\"%s\" folder is not a valid Beremiz project\n") % projectpath)
       
  1472             self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU)
       
  1473         dialog.Destroy()
       
  1474     
  1581     
  1475     def OnCloseProjectMenu(self, event):
  1582     def OnCloseProjectMenu(self, event):
  1476         if self.PluginRoot is not None and not self.CheckSaveBeforeClosing():
  1583         if self.PluginRoot is not None and not self.CheckSaveBeforeClosing():
  1477             return
  1584             return
  1478         
  1585         
  1502     def OnBeremizMenu(self, event):
  1609     def OnBeremizMenu(self, event):
  1503         open_pdf(Bpath( "doc", "manual_beremiz.pdf"))
  1610         open_pdf(Bpath( "doc", "manual_beremiz.pdf"))
  1504     
  1611     
  1505     def OnAboutMenu(self, event):
  1612     def OnAboutMenu(self, event):
  1506         OpenHtmlFrame(self,_("About Beremiz"), Bpath("doc","about.html"), wx.Size(550, 500))
  1613         OpenHtmlFrame(self,_("About Beremiz"), Bpath("doc","about.html"), wx.Size(550, 500))
       
  1614     
       
  1615     def OnPouSelectedChanged(self, event):
       
  1616         wx.CallAfter(self.RefreshPluginMenu)
       
  1617         IDEFrame.OnPouSelectedChanged(self, event)
       
  1618     
       
  1619     def OnPageClose(self, event):
       
  1620         wx.CallAfter(self.RefreshPluginMenu)
       
  1621         IDEFrame.OnPageClose(self, event)
  1507     
  1622     
  1508     def GetAddButtonFunction(self, plugin, window):
  1623     def GetAddButtonFunction(self, plugin, window):
  1509         def AddButtonFunction(event):
  1624         def AddButtonFunction(event):
  1510             if plugin and len(plugin.PlugChildsTypes) > 0:
  1625             if plugin and len(plugin.PlugChildsTypes) > 0:
  1511                 plugin_menu = wx.Menu(title='')
  1626                 plugin_menu = wx.Menu(title='')