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 |
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)), |