Beremiz.py
changeset 999 cbab4c1635bd
parent 994 0401295d9804
child 1000 d19af9341d28
equal deleted inserted replaced
998:2f7721dae9a0 999:cbab4c1635bd
   128         sys.path.append(extension_folder)
   128         sys.path.append(extension_folder)
   129         AddCatalog(os.path.join(extension_folder, "locale"))
   129         AddCatalog(os.path.join(extension_folder, "locale"))
   130         AddBitmapFolder(os.path.join(extension_folder, "images"))
   130         AddBitmapFolder(os.path.join(extension_folder, "images"))
   131         execfile(extfilename, locals())
   131         execfile(extfilename, locals())
   132 
   132 
   133 import wx.lib.buttons, wx.lib.statbmp
   133 import wx.lib.buttons, wx.lib.statbmp, wx.stc
   134 import cPickle
   134 import cPickle
   135 import types, time, re, platform, time, traceback, commands
   135 import types, time, re, platform, time, traceback, commands
   136 
   136 
   137 from docutil import OpenHtmlFrame
   137 from docutil import OpenHtmlFrame
   138 from IDEFrame import IDEFrame, AppendMenu
   138 from IDEFrame import IDEFrame, AppendMenu
   175         dc.SetBrush(wx.Brush(colour ))
   175         dc.SetBrush(wx.Brush(colour ))
   176         dc.DrawRectangle(0, 0, *dc.GetSizeTuple())
   176         dc.DrawRectangle(0, 0, *dc.GetSizeTuple())
   177         if self._bitmap:
   177         if self._bitmap:
   178             dc.DrawBitmap(self._bitmap, 0, 0, True)
   178             dc.DrawBitmap(self._bitmap, 0, 0, True)
   179 
   179 
   180                         
   180 if wx.Platform == '__WXMSW__':
       
   181     faces = {
       
   182         'mono' : 'Courier New',
       
   183         'size' : 8,
       
   184     }
       
   185 else:
       
   186     faces = {
       
   187         'mono' : 'Courier',
       
   188         'size' : 10,
       
   189     }
       
   190 
   181 from threading import Lock,Timer,currentThread
   191 from threading import Lock,Timer,currentThread
   182 MainThread = currentThread().ident
   192 MainThread = currentThread().ident
   183 REFRESH_PERIOD = 0.1
   193 REFRESH_PERIOD = 0.1
   184 from time import time as gettime
   194 from time import time as gettime
   185 class LogPseudoFile:
   195 class LogPseudoFile:
   186     """ Base class for file like objects to facilitate StdOut for the Shell."""
   196     """ Base class for file like objects to facilitate StdOut for the Shell."""
   187     def __init__(self, output, risecall):
   197     def __init__(self, output, risecall):
   188         self.red_white = wx.TextAttr("RED", "WHITE")
   198         self.red_white = 1
   189         self.red_yellow = wx.TextAttr("RED", "YELLOW")
   199         self.red_yellow = 2
   190         self.black_white = wx.TextAttr("BLACK", "WHITE")
   200         self.black_white = wx.stc.STC_STYLE_DEFAULT
   191         self.default_style = None
       
   192         self.output = output
   201         self.output = output
   193         self.risecall = risecall
   202         self.risecall = risecall
   194         # to prevent rapid fire on rising log panel
   203         # to prevent rapid fire on rising log panel
   195         self.rising_timer = 0
   204         self.rising_timer = 0
   196         self.lock = Lock()
   205         self.lock = Lock()
   241         if self.output :
   250         if self.output :
   242             self.output.Freeze()
   251             self.output.Freeze()
   243             self.lock.acquire()
   252             self.lock.acquire()
   244             for s, style in self.stack:
   253             for s, style in self.stack:
   245                 if style is None : style=self.black_white
   254                 if style is None : style=self.black_white
   246                 if self.default_style != style: 
   255                 if style != self.black_white:
   247                     self.output.SetDefaultStyle(style)
   256                     self.output.StartStyling(self.output.GetLength(), 0xff)
   248                     self.default_style = style
   257                 self.output.AddText(s)
   249                 self.output.AppendText(s)
   258                 if style != self.black_white:
   250                 self.output.ScrollLines(s.count('\n')+1)
   259                     self.output.SetStyling(len(s), style)
   251             self.stack = []
   260             self.stack = []
   252             self.lock.release()
   261             self.lock.release()
   253             self.output.ShowPosition(self.output.GetLastPosition())
   262             self.output.ScrollToLine(self.output.GetLineCount())
   254             self.output.Thaw()
   263             self.output.Thaw()
   255             self.LastRefreshTime = gettime()
   264             self.LastRefreshTime = gettime()
   256             try:
   265             try:
   257                 self.RefreshLock.release()
   266                 self.RefreshLock.release()
   258             except:
   267             except:
   259                 pass
   268                 pass
   260             newtime = time.time()
   269             newtime = time.time()
   261             if newtime - self.rising_timer > 1:
   270             if newtime - self.rising_timer > 1:
   262                 self.risecall()
   271                 self.risecall(self.output)
   263             self.rising_timer = newtime
   272             self.rising_timer = newtime
   264         
   273         
   265     def write_warning(self, s):
   274     def write_warning(self, s):
   266         self.write(s,self.red_white)
   275         self.write(s,self.red_white)
   267 
   276 
   271     def writeyield(self, s):
   280     def writeyield(self, s):
   272         self.write(s)
   281         self.write(s)
   273         wx.GetApp().Yield()
   282         wx.GetApp().Yield()
   274 
   283 
   275     def flush(self):
   284     def flush(self):
   276         self.output.SetValue("")
   285         self.output.SetText("")
   277     
   286     
   278     def isatty(self):
   287     def isatty(self):
   279         return false
   288         return false
   280 
   289 
   281 [ID_BEREMIZ, ID_BEREMIZMAINSPLITTER, 
   290 [ID_BEREMIZ, ID_BEREMIZMAINSPLITTER, 
   377             self.Bind(wx.EVT_MENU, OnMethodGen(self,method), id=newid)
   386             self.Bind(wx.EVT_MENU, OnMethodGen(self,method), id=newid)
   378             accels += [wx.AcceleratorEntry(wx.ACCEL_NORMAL, shortcut,newid)]
   387             accels += [wx.AcceleratorEntry(wx.ACCEL_NORMAL, shortcut,newid)]
   379         
   388         
   380         self.SetAcceleratorTable(wx.AcceleratorTable(accels))
   389         self.SetAcceleratorTable(wx.AcceleratorTable(accels))
   381         
   390         
   382         self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='',
   391         self.LogConsole = wx.stc.StyledTextCtrl(id=ID_BEREMIZLOGCONSOLE,
   383                   name='LogConsole', parent=self.BottomNoteBook, pos=wx.Point(0, 0),
   392                   name='LogConsole', parent=self.BottomNoteBook, pos=wx.Point(0, 0),
   384                   size=wx.Size(0, 0), style=wx.TE_MULTILINE|wx.TE_RICH2)
   393                   size=wx.Size(0, 0))
   385         self.LogConsole.Bind(wx.EVT_LEFT_DCLICK, self.OnLogConsoleDClick)
   394         
       
   395         # Define Log Console styles
       
   396         self.LogConsole.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces)
       
   397         self.LogConsole.StyleClearAll()
       
   398         self.LogConsole.StyleSetSpec(1, "face:%(mono)s,fore:#FF0000,size:%(size)d" % faces)
       
   399         self.LogConsole.StyleSetSpec(2, "face:%(mono)s,fore:#FF0000,back:#FFFF00,size:%(size)d" % faces)
       
   400         
       
   401         # Define Log Console markers
       
   402         self.LogConsole.SetMarginSensitive(1, True)
       
   403         self.LogConsole.SetMarginType(1, wx.stc.STC_MARGIN_SYMBOL)
       
   404         self.LogConsole.MarkerDefine(0, wx.stc.STC_MARK_CIRCLE, "BLACK", "RED")
       
   405         
       
   406         self.LogConsole.SetModEventMask(wx.stc.STC_MOD_INSERTTEXT)
       
   407         
       
   408         self.LogConsole.Bind(wx.stc.EVT_STC_MARGINCLICK, self.OnLogConsoleMarginClick)
       
   409         self.LogConsole.Bind(wx.stc.EVT_STC_MODIFIED, self.OnLogConsoleModified)
       
   410         
   386         self.MainTabs["LogConsole"] = (self.LogConsole, _("Console"))
   411         self.MainTabs["LogConsole"] = (self.LogConsole, _("Console"))
   387         self.BottomNoteBook.AddPage(*self.MainTabs["LogConsole"])
   412         self.BottomNoteBook.AddPage(*self.MainTabs["LogConsole"])
       
   413         #self.BottomNoteBook.Split(self.BottomNoteBook.GetPageIndex(self.LogConsole), wx.RIGHT)
   388         
   414         
   389         self.LogViewer = LogViewer(self.BottomNoteBook, self)
   415         self.LogViewer = LogViewer(self.BottomNoteBook, self)
   390         self.MainTabs["LogViewer"] = (self.LogViewer, _("PLC Log"))
   416         self.MainTabs["LogViewer"] = (self.LogViewer, _("PLC Log"))
   391         self.BottomNoteBook.AddPage(*self.MainTabs["LogViewer"])
   417         self.BottomNoteBook.AddPage(*self.MainTabs["LogViewer"])
   392         #self.BottomNoteBook.Split(self.BottomNoteBook.GetPageIndex(self.LogViewer), wx.RIGHT)
   418         #self.BottomNoteBook.Split(self.BottomNoteBook.GetPageIndex(self.LogViewer), wx.RIGHT)
   393         self.BottomNoteBook.Split(self.BottomNoteBook.GetPageIndex(self.LogConsole), wx.RIGHT)
       
   394         
   419         
   395         StatusToolBar = wx.ToolBar(self, -1, wx.DefaultPosition, wx.DefaultSize,
   420         StatusToolBar = wx.ToolBar(self, -1, wx.DefaultPosition, wx.DefaultSize,
   396                 wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
   421                 wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
   397         StatusToolBar.SetToolBitmapSize(wx.Size(25, 25))
   422         StatusToolBar.SetToolBitmapSize(wx.Size(25, 25))
   398         StatusToolBar.Realize()
   423         StatusToolBar.Realize()
   404         
   429         
   405         self.AUIManager.Update()
   430         self.AUIManager.Update()
   406         
   431         
   407     def __init__(self, parent, projectOpen=None, buildpath=None, ctr=None, debug=True):
   432     def __init__(self, parent, projectOpen=None, buildpath=None, ctr=None, debug=True):
   408         IDEFrame.__init__(self, parent, debug)
   433         IDEFrame.__init__(self, parent, debug)
   409         self.Log = LogPseudoFile(self.LogConsole,self.RiseLogConsole)
   434         self.Log = LogPseudoFile(self.LogConsole,self.SelectTab)
   410         
   435         
   411         self.local_runtime = None
   436         self.local_runtime = None
   412         self.runtime_port = None
   437         self.runtime_port = None
   413         self.local_runtime_tmpdir = None
   438         self.local_runtime_tmpdir = None
   414         
   439         
   467         
   492         
   468         self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
   493         self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
   469         self.RefreshAll()
   494         self.RefreshAll()
   470         self.LogConsole.SetFocus()
   495         self.LogConsole.SetFocus()
   471 
   496 
   472     def RiseLogConsole(self):
       
   473         self.BottomNoteBook.SetSelection(self.BottomNoteBook.GetPageIndex(self.LogConsole))
       
   474         
       
   475     def RefreshTitle(self):
   497     def RefreshTitle(self):
   476         name = _("Beremiz")
   498         name = _("Beremiz")
   477         if self.CTR is not None:
   499         if self.CTR is not None:
   478             projectname = self.CTR.GetProjectName()
   500             projectname = self.CTR.GetProjectName()
   479             if self.CTR.ProjectTestModified():
   501             if self.CTR.ProjectTestModified():
   522         wnd = wx.FindWindowAtPointer()
   544         wnd = wx.FindWindowAtPointer()
   523         if not wnd:
   545         if not wnd:
   524             wnd = self
   546             wnd = self
   525         InspectionTool().Show(wnd, True)
   547         InspectionTool().Show(wnd, True)
   526 
   548 
   527     def OnLogConsoleDClick(self, event):
   549     def OnLogConsoleMarginClick(self, event):
   528         wx.CallAfter(self.SearchLineForError)
   550         line_idx = self.LogConsole.LineFromPosition(event.GetPosition())
       
   551         wx.CallAfter(self.SearchLineForError, self.LogConsole.GetLine(line_idx))
   529         event.Skip()
   552         event.Skip()
   530 
   553         
   531     def SearchLineForError(self):
   554     def OnLogConsoleModified(self, event):
       
   555         line_idx = self.LogConsole.LineFromPosition(event.GetPosition())
       
   556         line = self.LogConsole.GetLine(line_idx)
       
   557         if line:
       
   558             result = MATIEC_ERROR_MODEL.match(line)
       
   559             if result is not None:
       
   560                 self.LogConsole.MarkerAdd(line_idx, 0)
       
   561         event.Skip()
       
   562 
       
   563     def SearchLineForError(self, line):
   532         if self.CTR is not None:
   564         if self.CTR is not None:
   533             text = self.LogConsole.GetRange(0, self.LogConsole.GetInsertionPoint())
       
   534             line = self.LogConsole.GetLineText(len(text.splitlines()) - 1)
       
   535             result = MATIEC_ERROR_MODEL.match(line)
   565             result = MATIEC_ERROR_MODEL.match(line)
   536             if result is not None:
   566             if result is not None:
   537                 first_line, first_column, last_line, last_column, error = result.groups()
   567                 first_line, first_column, last_line, last_column, error = result.groups()
   538                 infos = self.CTR.ShowError(self.Log,
   568                 infos = self.CTR.ShowError(self.Log,
   539                                                   (int(first_line), int(first_column)), 
   569                                                   (int(first_line), int(first_column)),