]> git.saurik.com Git - wxWidgets.git/blob - wxPython/samples/ide/activegrid/tool/DebuggerService.py
Updates to doc/view modules and sample apps from ActiveGrid.
[wxWidgets.git] / wxPython / samples / ide / activegrid / tool / DebuggerService.py
1 #----------------------------------------------------------------------------
2 # Name: DebuggerService.py
3 # Purpose: Debugger Service for Python.
4 #
5 # Author: Matt Fryer
6 #
7 # Created: 12/9/04
8 # CVS-ID: $Id$
9 # Copyright: (c) 2004-2005 ActiveGrid, Inc.
10 # License: wxWindows License
11 #----------------------------------------------------------------------------
12
13 import wx
14 import wx.lib.intctrl
15 import wx.lib.docview
16 import wx.lib.dialogs
17 import wx.gizmos
18 import wx._core
19 import wx.lib.pydocview
20 import Service
21 import STCTextEditor
22 import CodeEditor
23 import PythonEditor
24 from IDE import ACTIVEGRID_BASE_IDE
25 if not ACTIVEGRID_BASE_IDE:
26 import ProcessModelEditor
27 import wx.lib.scrolledpanel as scrolled
28 import sys
29 import time
30 import SimpleXMLRPCServer
31 import xmlrpclib
32 import os
33 import threading
34 import process
35 import Queue
36 import SocketServer
37 import ProjectEditor
38 import types
39 from xml.dom.minidom import parse, parseString
40 import bz2
41 import pickle
42 import DebuggerHarness
43 import traceback
44 import StringIO
45 if wx.Platform == '__WXMSW__':
46 import win32api
47 _WINDOWS = True
48 else:
49 _WINDOWS = False
50 _ = wx.GetTranslation
51
52 _VERBOSE = False
53 _WATCHES_ON = False
54
55 # Class to read from stdout or stderr and write the result to a text control.
56 # Args: file=file-like object
57 # callback_function= function that takes a single argument, the line of text
58 # read.
59 class OutputReaderThread(threading.Thread):
60 def __init__(self, file, callback_function, callbackOnExit=None, accumulate=True):
61 threading.Thread.__init__(self)
62 self._file = file
63 self._callback_function = callback_function
64 self._keepGoing = True
65 self._lineCount = 0
66 self._accumulate = accumulate
67 self._callbackOnExit = callbackOnExit
68
69 def run(self):
70 file = self._file
71 start = time.time()
72 output = ""
73 while self._keepGoing:
74 try:
75 # This could block--how to handle that?
76 text = file.readline()
77 if text == '' or text == None:
78 self._keepGoing = False
79 elif not self._accumulate:
80 self._callback_function(text)
81 else:
82 # Should use a buffer? StringIO?
83 output += text
84 # Seems as though the read blocks if we got an error, so, to be
85 # sure that at least some of the exception gets printed, always
86 # send the first hundred lines back as they come in.
87 if self._lineCount < 100:
88 self._callback_function(output)
89 self._lineCount += 1
90 output = ""
91 elif time.time() - start > 0.25:
92 try:
93 self._callback_function(output)
94 except wx._core.PyDeadObjectError:
95 # GUI was killed while we were blocked.
96 self._keepGoing = False
97 start = time.time()
98 output = ""
99 except:
100 tp, val, tb = sys.exc_info()
101 print "Exception in OutputReaderThread.run():", tp, val
102 self._keepGoing = False
103 if self._callbackOnExit:
104 try:
105 self._callbackOnExit()
106 except wx._core.PyDeadObjectError:
107 pass
108 if _VERBOSE: print "Exiting OutputReaderThread"
109
110 def AskToStop(self):
111 self._keepGoing = False
112
113 import wx.lib.newevent
114 (UpdateTextEvent, EVT_UPDATE_STDTEXT) = wx.lib.newevent.NewEvent()
115 (UpdateErrorEvent, EVT_UPDATE_ERRTEXT) = wx.lib.newevent.NewEvent()
116
117 class Executor:
118
119 def GetPythonExecutablePath():
120 config = wx.ConfigBase_Get()
121 path = config.Read("ActiveGridPythonLocation")
122 if path:
123 return path
124 wx.MessageBox(_("To proceed I need to know the location of the python.exe you would like to use.\nTo set this, go to Tools-->Options and use the 'Python' tab to enter a value.\n"), _("Python Executable Location Unknown"))
125 return None
126 GetPythonExecutablePath = staticmethod(GetPythonExecutablePath)
127
128 def __init__(self, fileName, wxComponent, arg1=None, arg2=None, arg3=None, arg4=None, arg5=None, arg6=None, arg7=None, arg8=None, arg9=None, callbackOnExit=None):
129 self._fileName = fileName
130 self._stdOutCallback = self.OutCall
131 self._stdErrCallback = self.ErrCall
132 self._callbackOnExit = callbackOnExit
133 self._wxComponent = wxComponent
134 path = Executor.GetPythonExecutablePath()
135 self._cmd = '"' + path + '" -u \"' + fileName + '\"'
136 #Better way to do this? Quotes needed for windows file paths.
137 if(arg1 != None):
138 self._cmd += ' \"' + arg1 + '\"'
139 if(arg2 != None):
140 self._cmd += ' \"' + arg2 + '\"'
141 if(arg3 != None):
142 self._cmd += ' \"' + arg3 + '\"'
143 if(arg4 != None):
144 self._cmd += ' \"' + arg4 + '\"'
145 if(arg5 != None):
146 self._cmd += ' \"' + arg5 + '\"'
147 if(arg6 != None):
148 self._cmd += ' \"' + arg6 + '\"'
149 if(arg7 != None):
150 self._cmd += ' \"' + arg7 + '\"'
151 if(arg8 != None):
152 self._cmd += ' \"' + arg8 + '\"'
153 if(arg9 != None):
154 self._cmd += ' \"' + arg9 + '\"'
155
156 self._stdOutReader = None
157 self._stdErrReader = None
158 self._process = None
159
160 def OutCall(self, text):
161 evt = UpdateTextEvent(value = text)
162 wx.PostEvent(self._wxComponent, evt)
163
164 def ErrCall(self, text):
165 evt = UpdateErrorEvent(value = text)
166 wx.PostEvent(self._wxComponent, evt)
167
168 def Execute(self, arguments, startIn=None, environment=None):
169 if not startIn:
170 startIn = str(os.getcwd())
171 startIn = os.path.abspath(startIn)
172 command = self._cmd + ' ' + arguments
173 #stdinput = process.IOBuffer()
174 #self._process = process.ProcessProxy(command, mode='b', cwd=startIn, stdin=stdinput)
175 self._process = process.ProcessOpen(command, mode='b', cwd=startIn, env=environment)
176 # Kick off threads to read stdout and stderr and write them
177 # to our text control.
178 self._stdOutReader = OutputReaderThread(self._process.stdout, self._stdOutCallback, callbackOnExit=self._callbackOnExit)
179 self._stdOutReader.start()
180 self._stdErrReader = OutputReaderThread(self._process.stderr, self._stdErrCallback, accumulate=False)
181 self._stdErrReader.start()
182
183
184 def DoStopExecution(self):
185 if(self._process != None):
186 self._process.kill()
187 self._process.close()
188 self._process = None
189 if(self._stdOutReader != None):
190 self._stdOutReader.AskToStop()
191 if(self._stdErrReader != None):
192 self._stdErrReader.AskToStop()
193
194 class RunCommandUI(wx.Panel):
195
196 def __init__(self, parent, id, fileName):
197 wx.Panel.__init__(self, parent, id)
198 self._noteBook = parent
199
200 self.KILL_PROCESS_ID = wx.NewId()
201 self.CLOSE_TAB_ID = wx.NewId()
202
203 self.Bind(wx.EVT_END_PROCESS, self.OnProcessEnded)
204
205 # GUI Initialization follows
206 sizer = wx.BoxSizer(wx.HORIZONTAL)
207 self._tb = tb = wx.ToolBar(self, -1, wx.DefaultPosition, (30,1000), wx.TB_VERTICAL| wx.TB_FLAT, "Runner" )
208 tb.SetToolBitmapSize((16,16))
209 sizer.Add(tb, 0, wx.EXPAND |wx.ALIGN_LEFT|wx.ALL, 1)
210
211 close_bmp = getCloseBitmap()
212 tb.AddSimpleTool( self.CLOSE_TAB_ID, close_bmp, _('Close Window'))
213 wx.EVT_TOOL(self, self.CLOSE_TAB_ID, self.OnToolClicked)
214
215 stop_bmp = getStopBitmap()
216 tb.AddSimpleTool(self.KILL_PROCESS_ID, stop_bmp, _("Stop the Run."))
217 wx.EVT_TOOL(self, self.KILL_PROCESS_ID, self.OnToolClicked)
218
219 tb.Realize()
220 self._textCtrl = STCTextEditor.TextCtrl(self, wx.NewId()) #id)
221 sizer.Add(self._textCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
222 self._textCtrl.SetViewLineNumbers(False)
223 self._textCtrl.SetReadOnly(True)
224 if wx.Platform == '__WXMSW__':
225 font = "Courier New"
226 else:
227 font = "Courier"
228 self._textCtrl.SetFont(wx.Font(9, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = font))
229 self._textCtrl.SetFontColor(wx.BLACK)
230 self._textCtrl.StyleClearAll()
231
232 #Disabling for now...may interfere with file open. wx.stc.EVT_STC_DOUBLECLICK(self._textCtrl, self._textCtrl.GetId(), self.OnDoubleClick)
233
234 self.SetSizer(sizer)
235 sizer.Fit(self)
236
237 # Executor initialization
238 self._executor = Executor(fileName, self, callbackOnExit=self.ExecutorFinished)
239 self.Bind(EVT_UPDATE_STDTEXT, self.AppendText)
240 self.Bind(EVT_UPDATE_ERRTEXT, self.AppendErrorText)
241
242 def __del__(self):
243 self._executor.DoStopExecution()
244
245 def Execute(self, initialArgs, startIn, environment):
246 self._executor.Execute(initialArgs, startIn, environment)
247
248 def ExecutorFinished(self):
249 self._tb.EnableTool(self.KILL_PROCESS_ID, False)
250 nb = self.GetParent()
251 for i in range(0,nb.GetPageCount()):
252 if self == nb.GetPage(i):
253 text = nb.GetPageText(i)
254 newText = text.replace("Running", "Finished")
255 nb.SetPageText(i, newText)
256 break
257
258 def StopExecution(self):
259 self.Unbind(EVT_UPDATE_STDTEXT)
260 self.Unbind(EVT_UPDATE_ERRTEXT)
261 self._executor.DoStopExecution()
262
263 def AppendText(self, event):
264 self._textCtrl.SetReadOnly(False)
265 self._textCtrl.AddText(event.value)
266 self._textCtrl.ScrollToLine(self._textCtrl.GetLineCount())
267 self._textCtrl.SetReadOnly(True)
268
269 def AppendErrorText(self, event):
270 self._textCtrl.SetReadOnly(False)
271 self._textCtrl.SetFontColor(wx.RED)
272 self._textCtrl.StyleClearAll()
273 self._textCtrl.AddText(event.value)
274 self._textCtrl.ScrollToLine(self._textCtrl.GetLineCount())
275 self._textCtrl.SetFontColor(wx.BLACK)
276 self._textCtrl.StyleClearAll()
277 self._textCtrl.SetReadOnly(True)
278
279 #------------------------------------------------------------------------------
280 # Event handling
281 #-----------------------------------------------------------------------------
282
283 def OnToolClicked(self, event):
284 id = event.GetId()
285
286 if id == self.KILL_PROCESS_ID:
287 self._executor.DoStopExecution()
288
289 elif id == self.CLOSE_TAB_ID:
290 self._executor.DoStopExecution()
291 index = self._noteBook.GetSelection()
292 self._noteBook.GetPage(index).Show(False)
293 self._noteBook.RemovePage(index)
294
295 def OnDoubleClick(self, event):
296 # Looking for a stack trace line.
297 lineText, pos = self._textCtrl.GetCurLine()
298 fileBegin = lineText.find("File \"")
299 fileEnd = lineText.find("\", line ")
300 lineEnd = lineText.find(", in ")
301 if lineText == "\n" or fileBegin == -1 or fileEnd == -1 or lineEnd == -1:
302 # Check the line before the one that was clicked on
303 lineNumber = self._textCtrl.GetCurrentLine()
304 if(lineNumber == 0):
305 return
306 lineText = self._textCtrl.GetLine(lineNumber - 1)
307 fileBegin = lineText.find("File \"")
308 fileEnd = lineText.find("\", line ")
309 lineEnd = lineText.find(", in ")
310 if lineText == "\n" or fileBegin == -1 or fileEnd == -1 or lineEnd == -1:
311 return
312
313 filename = lineText[fileBegin + 6:fileEnd]
314 lineNum = int(lineText[fileEnd + 8:lineEnd])
315
316 foundView = None
317 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
318 for openDoc in openDocs:
319 if openDoc.GetFilename() == filename:
320 foundView = openDoc.GetFirstView()
321 break
322
323 if not foundView:
324 doc = wx.GetApp().GetDocumentManager().CreateDocument(filename, wx.lib.docview.DOC_SILENT)
325 foundView = doc.GetFirstView()
326
327 if foundView:
328 foundView.GetFrame().SetFocus()
329 foundView.Activate()
330 foundView.GotoLine(lineNum)
331 startPos = foundView.PositionFromLine(lineNum)
332
333 # FACTOR THIS INTO DocManager
334 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
335 for openDoc in openDocs:
336 if(isinstance(openDoc.GetFirstView(), CodeEditor.CodeView)):
337 openDoc.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
338
339 foundView.GetCtrl().MarkerAdd(lineNum -1, CodeEditor.CodeCtrl.CURRENT_LINE_MARKER_NUM)
340
341 def OnProcessEnded(self, evt):
342 self._executor.DoStopExecution()
343
344 DEFAULT_PORT = 32032
345 DEFAULT_HOST = 'localhost'
346 PORT_COUNT = 21
347
348 class DebugCommandUI(wx.Panel):
349 debuggerPortList = None
350 debuggers = []
351
352 def NotifyDebuggersOfBreakpointChange():
353 for debugger in DebugCommandUI.debuggers:
354 debugger.BreakPointChange()
355
356 NotifyDebuggersOfBreakpointChange = staticmethod(NotifyDebuggersOfBreakpointChange)
357
358 def DebuggerRunning():
359 for debugger in DebugCommandUI.debuggers:
360 if debugger._executor:
361 return True
362 return False
363 DebuggerRunning = staticmethod(DebuggerRunning)
364
365 def ShutdownAllDebuggers():
366 for debugger in DebugCommandUI.debuggers:
367 debugger.StopExecution()
368
369 ShutdownAllDebuggers = staticmethod(ShutdownAllDebuggers)
370
371 def GetAvailablePort():
372 for index in range( 0, len(DebugCommandUI.debuggerPortList)):
373 port = DebugCommandUI.debuggerPortList[index]
374 if DebugCommandUI.PortAvailable(port):
375 DebugCommandUI.debuggerPortList.pop(index)
376 return port
377 wx.MessageBox(_("Out of ports for debugging! Please restart the application builder.\nIf that does not work, check for and remove running instances of python."), _("Out of Ports"))
378 assert False, "Out of ports for debugger."
379
380 GetAvailablePort = staticmethod(GetAvailablePort)
381
382 def ReturnPortToPool(port):
383 config = wx.ConfigBase_Get()
384 startingPort = config.ReadInt("DebuggerStartingPort", DEFAULT_PORT)
385 if port in range(startingPort, startingPort + PORT_COUNT):
386 DebugCommandUI.debuggerPortList.append(port)
387
388 ReturnPortToPool = staticmethod(ReturnPortToPool)
389
390 def PortAvailable(port):
391 config = wx.ConfigBase_Get()
392 hostname = config.Read("DebuggerHostName", DEFAULT_HOST)
393 try:
394 server = AGXMLRPCServer((hostname, port))
395 server.server_close()
396 if _VERBOSE: print "Port ", str(port), " available."
397 return True
398 except:
399 tp,val,tb = sys.exc_info()
400 if _VERBOSE: traceback.print_exception(tp, val, tb)
401 if _VERBOSE: print "Port ", str(port), " unavailable."
402 return False
403
404 PortAvailable = staticmethod(PortAvailable)
405
406 def NewPortRange():
407 config = wx.ConfigBase_Get()
408 startingPort = config.ReadInt("DebuggerStartingPort", DEFAULT_PORT)
409 DebugCommandUI.debuggerPortList = range(startingPort, startingPort + PORT_COUNT)
410 NewPortRange = staticmethod(NewPortRange)
411
412 def __init__(self, parent, id, command, service):
413 # Check for ports before creating the panel.
414 if not DebugCommandUI.debuggerPortList:
415 DebugCommandUI.NewPortRange()
416 self._debuggerPort = str(DebugCommandUI.GetAvailablePort())
417 self._guiPort = str(DebugCommandUI.GetAvailablePort())
418 self._debuggerBreakPort = str(DebugCommandUI.GetAvailablePort())
419
420 wx.Panel.__init__(self, parent, id)
421
422 self._parentNoteBook = parent
423 self._command = command
424 self._textCtrl = None
425 self._service = service
426 self._executor = None
427 self.STEP_ID = wx.NewId()
428 self.CONTINUE_ID = wx.NewId()
429 self.STEP_OUT_ID = wx.NewId()
430 self.NEXT_ID = wx.NewId()
431 self.KILL_PROCESS_ID = wx.NewId()
432 self.CLOSE_WINDOW_ID = wx.NewId()
433 self.BREAK_INTO_DEBUGGER_ID = wx.NewId()
434 self.CLEAR_ID = wx.NewId()
435 self.ADD_WATCH_ID = wx.NewId()
436 sizer = wx.BoxSizer(wx.VERTICAL)
437 self._tb = tb = wx.ToolBar(self, -1, wx.DefaultPosition, (1000,30), wx.TB_HORIZONTAL| wx.NO_BORDER| wx.TB_FLAT| wx.TB_TEXT, "Debugger" )
438 sizer.Add(tb, 0, wx.EXPAND |wx.ALIGN_LEFT|wx.ALL, 1)
439 tb.SetToolBitmapSize((16,16))
440
441 close_bmp = getCloseBitmap()
442 tb.AddSimpleTool( self.CLOSE_WINDOW_ID, close_bmp, _('Close Window'))
443 wx.EVT_TOOL(self, self.CLOSE_WINDOW_ID, self.StopAndRemoveUI)
444
445 stop_bmp = getStopBitmap()
446 tb.AddSimpleTool( self.KILL_PROCESS_ID, stop_bmp, _("Stop Debugging"))
447 wx.EVT_TOOL(self, self.KILL_PROCESS_ID, self.StopExecution)
448
449 tb.AddSeparator()
450
451 break_bmp = getBreakBitmap()
452 tb.AddSimpleTool( self.BREAK_INTO_DEBUGGER_ID, break_bmp, _("Break into Debugger"))
453 wx.EVT_TOOL(self, self.BREAK_INTO_DEBUGGER_ID, self.BreakExecution)
454
455 tb.AddSeparator()
456
457 continue_bmp = getContinueBitmap()
458 tb.AddSimpleTool( self.CONTINUE_ID, continue_bmp, _("Continue Execution"))
459 wx.EVT_TOOL(self, self.CONTINUE_ID, self.OnContinue)
460
461 tb.AddSeparator()
462
463 next_bmp = getNextBitmap()
464 tb.AddSimpleTool( self.NEXT_ID, next_bmp, _("Step to next line"))
465 wx.EVT_TOOL(self, self.NEXT_ID, self.OnNext)
466
467 step_bmp = getStepInBitmap()
468 tb.AddSimpleTool( self.STEP_ID, step_bmp, _("Step in"))
469 wx.EVT_TOOL(self, self.STEP_ID, self.OnSingleStep)
470
471 stepOut_bmp = getStepReturnBitmap()
472 tb.AddSimpleTool(self.STEP_OUT_ID, stepOut_bmp, _("Stop at function return"))
473 wx.EVT_TOOL(self, self.STEP_OUT_ID, self.OnStepOut)
474
475 tb.AddSeparator()
476 if _WATCHES_ON:
477 watch_bmp = getAddWatchBitmap()
478 tb.AddSimpleTool(self.ADD_WATCH_ID, watch_bmp, _("Add a watch"))
479 wx.EVT_TOOL(self, self.ADD_WATCH_ID, self.OnAddWatch)
480 tb.AddSeparator()
481
482 clear_bmp = getClearOutputBitmap()
483 tb.AddSimpleTool(self.CLEAR_ID, clear_bmp, _("Clear output pane"))
484 wx.EVT_TOOL(self, self.CLEAR_ID, self.OnClearOutput)
485
486 tb.Realize()
487 self.framesTab = None
488 self.DisableWhileDebuggerRunning()
489 self._notebook = wx.Notebook(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.LB_DEFAULT, "Debugger")
490 sizer.Add(self._notebook, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
491 self.consoleTab = self.MakeConsoleTab(self._notebook, wx.NewId(), None)
492 self.framesTab = self.MakeFramesTab(self._notebook, wx.NewId(), None)
493 self.breakPointsTab = self.MakeBreakPointsTab(self._notebook, wx.NewId(), None)
494 self._notebook.AddPage(self.consoleTab, "Output")
495 self._notebook.AddPage(self.framesTab, "Frames")
496 self._notebook.AddPage(self.breakPointsTab, "Break Points")
497
498 self._statusBar = wx.StatusBar( self, -1)
499 self._statusBar.SetFieldsCount(1)
500 sizer.Add(self._statusBar, 0, wx.EXPAND |wx.ALIGN_LEFT|wx.ALL, 1)
501
502 self.SetStatusText("Starting debug...")
503
504 self.SetSizer(sizer)
505 sizer.Fit(self)
506 config = wx.ConfigBase_Get()
507 self._debuggerHost = self._guiHost = config.Read("DebuggerHostName", DEFAULT_HOST)
508 url = 'http://' + self._debuggerHost + ':' + self._debuggerPort + '/'
509 self._breakURL = 'http://' + self._debuggerHost + ':' + self._debuggerBreakPort + '/'
510 self._callback = DebuggerCallback(self._guiHost, self._guiPort, url, self._breakURL, self)
511 if DebuggerHarness.__file__.find('library.zip') > 0:
512 try:
513 fname = DebuggerHarness.__file__
514 parts = fname.split('library.zip')
515 path = os.path.join(parts[0],'activegrid', 'tool', 'DebuggerHarness.py')
516 except:
517 tp, val, tb = sys.exc_info()
518 traceback.print_exception(tp, val, tb)
519
520 else:
521 print "Starting debugger on these ports: %s, %s, %s" % (str(self._debuggerPort) , str(self._guiPort) , str(self._debuggerBreakPort))
522 path = DebuggerService.ExpandPath(DebuggerHarness.__file__)
523 self._executor = Executor(path, self, self._debuggerHost, \
524 self._debuggerPort, self._debuggerBreakPort, self._guiHost, self._guiPort, self._command, callbackOnExit=self.ExecutorFinished)
525
526 self.Bind(EVT_UPDATE_STDTEXT, self.AppendText)
527 self.Bind(EVT_UPDATE_ERRTEXT, self.AppendErrorText)
528 DebugCommandUI.debuggers.append(self)
529 self._stopped = False
530
531 def OnSingleStep(self, event):
532 self._callback.SingleStep()
533
534 def OnContinue(self, event):
535 self._callback.Continue()
536
537 def OnStepOut(self, event):
538 self._callback.Return()
539
540 def OnNext(self, event):
541 self._callback.Next()
542
543 def BreakPointChange(self):
544 if not self._stopped:
545 self._callback.pushBreakpoints()
546 self.breakPointsTab.PopulateBPList()
547
548 def __del__(self):
549 if self in DebugCommandUI.debuggers:
550 DebugCommandUI.debuggers.remove(self)
551
552 def SwitchToOutputTab(self):
553 self._notebook.SetSelection(0)
554
555 def DisableWhileDebuggerRunning(self):
556 self._tb.EnableTool(self.STEP_ID, False)
557 self._tb.EnableTool(self.CONTINUE_ID, False)
558 self._tb.EnableTool(self.STEP_OUT_ID, False)
559 self._tb.EnableTool(self.NEXT_ID, False)
560 self._tb.EnableTool(self.BREAK_INTO_DEBUGGER_ID, True)
561 if _WATCHES_ON:
562 self._tb.EnableTool(self.ADD_WATCH_ID, False)
563 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
564 for openDoc in openDocs:
565 if(isinstance(openDoc.GetFirstView(), CodeEditor.CodeView)):
566 openDoc.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
567 if self.framesTab:
568 self.framesTab.ClearWhileRunning()
569 #wx.GetApp().ProcessPendingEvents() #Yield(True)
570
571 def EnableWhileDebuggerStopped(self):
572 self._tb.EnableTool(self.STEP_ID, True)
573 self._tb.EnableTool(self.CONTINUE_ID, True)
574 self._tb.EnableTool(self.STEP_OUT_ID, True)
575 self._tb.EnableTool(self.NEXT_ID, True)
576 if _WATCHES_ON:
577 self._tb.EnableTool(self.ADD_WATCH_ID, True)
578 self._tb.EnableTool(self.BREAK_INTO_DEBUGGER_ID, False)
579 #if _WINDOWS:
580 # wx.GetApp().GetTopWindow().RequestUserAttention()
581
582 def ExecutorFinished(self):
583 if _VERBOSE: print "In ExectorFinished"
584 try:
585 self.DisableAfterStop()
586 except wx._core.PyDeadObjectError:
587 pass
588 try:
589 nb = self.GetParent()
590 for i in range(0, nb.GetPageCount()):
591 if self == nb.GetPage(i):
592 text = nb.GetPageText(i)
593 newText = text.replace("Debugging", "Finished")
594 nb.SetPageText(i, newText)
595 if _VERBOSE: print "In ExectorFinished, changed tab title."
596 break
597 except:
598 if _VERBOSE: print "In ExectorFinished, got exception"
599
600 def DisableAfterStop(self):
601 self.DisableWhileDebuggerRunning()
602 self._tb.EnableTool(self.BREAK_INTO_DEBUGGER_ID, False)
603 self._tb.EnableTool(self.KILL_PROCESS_ID, False)
604
605 def SynchCurrentLine(self, filename, lineNum):
606 # FACTOR THIS INTO DocManager
607 self.DeleteCurrentLineMarkers()
608
609 # Filename will be <string> if we're in a bit of code that was executed from
610 # a string (rather than a file). I haven't been able to get the original string
611 # for display.
612 if filename == '<string>':
613 return
614 foundView = None
615 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
616 for openDoc in openDocs:
617 # This ugliness to prevent comparison failing because the drive letter
618 # gets lowercased occasionally. Don't know why that happens or why it
619 # only happens occasionally.
620 if DebuggerService.ComparePaths(openDoc.GetFilename(),filename):
621 foundView = openDoc.GetFirstView()
622 break
623
624 if not foundView:
625 if _VERBOSE:
626 print "filename=", filename
627 doc = wx.GetApp().GetDocumentManager().CreateDocument(DebuggerService.ExpandPath(filename), wx.lib.docview.DOC_SILENT)
628 foundView = doc.GetFirstView()
629
630 if foundView:
631 foundView.GetFrame().SetFocus()
632 foundView.Activate()
633 foundView.GotoLine(lineNum)
634 startPos = foundView.PositionFromLine(lineNum)
635
636 foundView.GetCtrl().MarkerAdd(lineNum -1, CodeEditor.CodeCtrl.CURRENT_LINE_MARKER_NUM)
637
638 def DeleteCurrentLineMarkers(self):
639 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
640 for openDoc in openDocs:
641 if(isinstance(openDoc.GetFirstView(), CodeEditor.CodeView)):
642 openDoc.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
643
644 def LoadFramesListXML(self, framesXML):
645 self.framesTab.LoadFramesListXML(framesXML)
646
647 def SetStatusText(self, text):
648 self._statusBar.SetStatusText(text,0)
649
650 def Execute(self, initialArgs, startIn, environment):
651 self._callback.start()
652 self._executor.Execute(initialArgs, startIn, environment)
653 self._callback.waitForRPC()
654
655 def BreakExecution(self, event):
656 self._callback.BreakExecution()
657
658
659 def StopExecution(self, event):
660 self._stopped = True
661 self.DisableAfterStop()
662 try:
663 self._callback.ServerClose()
664 except:
665 pass
666 try:
667 if self._executor:
668 self._executor.DoStopExecution()
669 self._executor = None
670 except:
671 pass
672 self.DeleteCurrentLineMarkers()
673 DebugCommandUI.ReturnPortToPool(self._debuggerPort)
674 DebugCommandUI.ReturnPortToPool(self._guiPort)
675 DebugCommandUI.ReturnPortToPool(self._debuggerBreakPort)
676
677 def StopAndRemoveUI(self, event):
678 self.StopExecution(None)
679 if self in DebugCommandUI.debuggers:
680 DebugCommandUI.debuggers.remove(self)
681 index = self._parentNoteBook.GetSelection()
682 self._parentNoteBook.GetPage(index).Show(False)
683 self._parentNoteBook.RemovePage(index)
684
685 def GetConsoleTextControl(self):
686 return self._textCtrl
687
688 def OnClearOutput(self, event):
689 self._textCtrl.SetReadOnly(False)
690 self._textCtrl.ClearAll()
691 self._textCtrl.SetReadOnly(True)
692
693 def OnAddWatch(self, event):
694 if self.framesTab:
695 self.framesTab.OnWatch(event)
696
697 def MakeConsoleTab(self, parent, id, debugger):
698 panel = wx.Panel(parent, id)
699 sizer = wx.BoxSizer(wx.HORIZONTAL)
700 self._textCtrl = STCTextEditor.TextCtrl(panel, wx.NewId())
701 sizer.Add(self._textCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
702 self._textCtrl.SetViewLineNumbers(False)
703 self._textCtrl.SetReadOnly(True)
704 if wx.Platform == '__WXMSW__':
705 font = "Courier New"
706 else:
707 font = "Courier"
708 self._textCtrl.SetFont(wx.Font(9, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = font))
709 self._textCtrl.SetFontColor(wx.BLACK)
710 self._textCtrl.StyleClearAll()
711 panel.SetSizer(sizer)
712 sizer.Fit(panel)
713
714 return panel
715
716 def MakeFramesTab(self, parent, id, debugger):
717 panel = FramesUI(parent, id, self)
718 return panel
719
720 def MakeBreakPointsTab(self, parent, id, debugger):
721 panel = BreakpointsUI(parent, id, self)
722 return panel
723
724 def AppendText(self, event):
725 self._textCtrl.SetReadOnly(False)
726 self._textCtrl.AddText(event.value)
727 self._textCtrl.ScrollToLine(self._textCtrl.GetLineCount())
728 self._textCtrl.SetReadOnly(True)
729
730 def AppendErrorText(self, event):
731 self._textCtrl.SetReadOnly(False)
732 self._textCtrl.SetFontColor(wx.RED)
733 self._textCtrl.StyleClearAll()
734 self._textCtrl.AddText(event.value)
735 self._textCtrl.ScrollToLine(self._textCtrl.GetLineCount())
736 self._textCtrl.SetFontColor(wx.BLACK)
737 self._textCtrl.StyleClearAll()
738 self._textCtrl.SetReadOnly(True)
739
740 class BreakpointsUI(wx.Panel):
741 def __init__(self, parent, id, ui):
742 wx.Panel.__init__(self, parent, id)
743 self._ui = ui
744 self.currentItem = None
745 self.clearBPID = wx.NewId()
746 self.Bind(wx.EVT_MENU, self.ClearBreakPoint, id=self.clearBPID)
747 self.syncLineID = wx.NewId()
748 self.Bind(wx.EVT_MENU, self.SyncBPLine, id=self.syncLineID)
749
750 sizer = wx.BoxSizer(wx.VERTICAL)
751 p1 = self
752 self._bpListCtrl = wx.ListCtrl(p1, -1, pos=wx.DefaultPosition, size=(1000,1000), style=wx.LC_REPORT)
753 sizer.Add(self._bpListCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
754 self._bpListCtrl.InsertColumn(0, "File")
755 self._bpListCtrl.InsertColumn(1, "Line")
756 self._bpListCtrl.InsertColumn(2, "Path")
757 self._bpListCtrl.SetColumnWidth(0, 150)
758 self._bpListCtrl.SetColumnWidth(1, 50)
759 self._bpListCtrl.SetColumnWidth(2, 450)
760 self._bpListCtrl.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnListRightClick)
761 self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.ListItemSelected, self._bpListCtrl)
762 self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.ListItemDeselected, self._bpListCtrl)
763
764 self.PopulateBPList()
765
766 p1.SetSizer(sizer)
767 sizer.Fit(p1)
768 p1.Layout()
769
770 def PopulateBPList(self):
771 list = self._bpListCtrl
772 list.DeleteAllItems()
773
774 bps = wx.GetApp().GetService(DebuggerService).GetMasterBreakpointDict()
775 index = 0
776 for fileName in bps.keys():
777 shortFile = os.path.basename(fileName)
778 lines = bps[fileName]
779 if lines:
780 for line in lines:
781 list.InsertStringItem(index, shortFile)
782 list.SetStringItem(index, 1, str(line))
783 list.SetStringItem(index, 2, fileName)
784
785 def OnListRightClick(self, event):
786 menu = wx.Menu()
787 item = wx.MenuItem(menu, self.clearBPID, "Clear Breakpoint")
788 menu.AppendItem(item)
789 item = wx.MenuItem(menu, self.syncLineID, "Goto Source Line")
790 menu.AppendItem(item)
791 self.PopupMenu(menu, event.GetPosition())
792 menu.Destroy()
793
794 def SyncBPLine(self, event):
795 if self.currentItem != -1:
796 list = self._bpListCtrl
797 fileName = list.GetItem(self.currentItem, 2).GetText()
798 lineNumber = list.GetItem(self.currentItem, 1).GetText()
799 self._ui.SynchCurrentLine( fileName, int(lineNumber) )
800
801 def ClearBreakPoint(self, event):
802 if self.currentItem >= 0:
803 list = self._bpListCtrl
804 fileName = list.GetItem(self.currentItem, 2).GetText()
805 lineNumber = list.GetItem(self.currentItem, 1).GetText()
806 wx.GetApp().GetService(DebuggerService).OnToggleBreakpoint(None, line=int(lineNumber) -1, fileName=fileName )
807
808 def ListItemSelected(self, event):
809 self.currentItem = event.m_itemIndex
810
811 def ListItemDeselected(self, event):
812 self.currentItem = -1
813
814 class Watch:
815 CODE_ALL_FRAMES = 1
816 CODE_THIS_BLOCK = 2
817 CODE_THIS_LINE = 4
818 CODE_RUN_ONCE = 8
819
820 def __init__(self, name, command, show_code=CODE_ALL_FRAMES):
821 self._name = name
822 self._command = command
823 self._show_code = show_code
824
825 class WatchDialog(wx.Dialog):
826 WATCH_ALL_FRAMES = "Watch in all frames"
827 WATCH_THIS_FRAME = "Watch in this frame only"
828 WATCH_ONCE = "Watch once and delete"
829 def __init__(self, parent, title, chain):
830 wx.Dialog.__init__(self, parent, -1, title, style=wx.DEFAULT_DIALOG_STYLE)
831 self._chain = chain
832 self.label_2 = wx.StaticText(self, -1, "Watch Name:")
833 self._watchNameTextCtrl = wx.TextCtrl(self, -1, "")
834 self.label_3 = wx.StaticText(self, -1, "eval(", style=wx.ALIGN_RIGHT)
835 self._watchValueTextCtrl = wx.TextCtrl(self, -1, "")
836 self.label_4 = wx.StaticText(self, -1, ",frame.f_globals, frame.f_locals)")
837 self.radio_box_1 = wx.RadioBox(self, -1, "Watch Information", choices=[WatchDialog.WATCH_ALL_FRAMES, WatchDialog.WATCH_THIS_FRAME, WatchDialog.WATCH_ONCE], majorDimension=0, style=wx.RA_SPECIFY_ROWS)
838
839 self._okButton = wx.Button(self, wx.ID_OK, "OK", size=(75,-1))
840 self._okButton.SetDefault()
841 self._okButton.SetHelpText(_("The OK button completes the dialog"))
842 def OnOkClick(event):
843 if self._watchNameTextCtrl.GetValue() == "":
844 wx.MessageBox(_("You must enter a name for the watch."), _("Add Watch"))
845 return
846 if self._watchValueTextCtrl.GetValue() == "":
847 wx.MessageBox(_("You must enter some code to run for the watch."), _("Add Watch"))
848 return
849 self.EndModal(wx.ID_OK)
850 self.Bind(wx.EVT_BUTTON, OnOkClick, self._okButton)
851
852 self._cancelButton = wx.Button(self, wx.ID_CANCEL, _("Cancel"), size=(75,-1))
853 self._cancelButton.SetHelpText(_("The Cancel button cancels the dialog."))
854
855 self.__set_properties()
856 self.__do_layout()
857
858 def GetSettings(self):
859 return self._watchNameTextCtrl.GetValue(), self._watchValueTextCtrl.GetValue(), self.GetSendFrame(), self.GetRunOnce()
860
861 def GetSendFrame(self):
862 return (WatchDialog.WATCH_ALL_FRAMES != self.radio_box_1.GetStringSelection())
863
864 def GetRunOnce(self):
865 return (WatchDialog.WATCH_ONCE == self.radio_box_1.GetStringSelection())
866
867 def __set_properties(self):
868 self.SetTitle("Add a Watch")
869 #self.SetSize((400, 250))
870 self.radio_box_1.SetSelection(0)
871
872 def __do_layout(self):
873 sizer_1 = wx.BoxSizer(wx.VERTICAL)
874 grid_sizer_4 = wx.FlexGridSizer(1, 3, 5, 5)
875 grid_sizer_2 = wx.FlexGridSizer(1, 2, 5, 5)
876 grid_sizer_2.Add(self.label_2, 0, wx.ALIGN_CENTER_VERTICAL|wx.FIXED_MINSIZE, 0)
877 grid_sizer_2.Add(self._watchNameTextCtrl, 0, wx.EXPAND, 0)
878 grid_sizer_2.AddGrowableCol(1)
879 sizer_1.Add(grid_sizer_2, 1, wx.EXPAND, 0)
880 grid_sizer_4.Add(self.label_3, 0, wx.ALIGN_CENTER_VERTICAL|wx.FIXED_MINSIZE, 0)
881 grid_sizer_4.Add(self._watchValueTextCtrl, 0, wx.EXPAND, 0)
882 grid_sizer_4.AddGrowableCol(1)
883 grid_sizer_4.Add(self.label_4, 0, wx.ALIGN_CENTER_VERTICAL|wx.FIXED_MINSIZE, 0)
884 sizer_1.Add(grid_sizer_4, 0, wx.EXPAND, 0)
885 sizer_1.Add(self.radio_box_1, 0, wx.EXPAND, 0)
886
887 box = wx.BoxSizer(wx.HORIZONTAL)
888 box.Add(self._okButton, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
889 box.Add(self._cancelButton, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
890 sizer_1.Add(box, 1, wx.EXPAND, 0)
891 self.SetAutoLayout(True)
892 self.SetSizer(sizer_1)
893 self.Layout()
894
895 class FramesUI(wx.SplitterWindow):
896 def __init__(self, parent, id, ui):
897 wx.SplitterWindow.__init__(self, parent, id, style = wx.SP_3D)
898 self._ui = ui
899 sizer = wx.BoxSizer(wx.VERTICAL)
900 self._p1 = p1 = wx.ScrolledWindow(self, -1)
901 p1.Bind(wx.EVT_SIZE, self.OnSize)
902
903 self._framesListCtrl = wx.ListCtrl(p1, -1, pos=wx.DefaultPosition, size=(250,150), style=wx.LC_REPORT)
904 sizer.Add(self._framesListCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
905 self._framesListCtrl.InsertColumn(0, "Frame")
906 self._framesListCtrl.SetColumnWidth(0, 250)
907 self._framesListCtrl.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnListRightClick)
908 self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.ListItemSelected, self._framesListCtrl)
909 self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.ListItemDeselected, self._framesListCtrl)
910
911 sizer2 = wx.BoxSizer(wx.VERTICAL)
912 self._p2 = p2 = wx.ScrolledWindow(self, -1)
913 p2.Bind(wx.EVT_SIZE, self.OnSize)
914
915 self._treeCtrl = wx.gizmos.TreeListCtrl(p2, -1, size=(530,250), style=wx.TR_DEFAULT_STYLE| wx.TR_FULL_ROW_HIGHLIGHT)
916 self._treeCtrl.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnRightClick)
917 sizer2.Add(self._framesListCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
918 tree = self._treeCtrl
919 tree.AddColumn("Thing")
920 tree.AddColumn("Value")
921 tree.SetMainColumn(0) # the one with the tree in it...
922 tree.SetColumnWidth(0, 175)
923 tree.SetColumnWidth(1, 355)
924 self._root = tree.AddRoot("Frame")
925 tree.SetItemText(self._root, "", 1)
926
927 self.SetMinimumPaneSize(20)
928 self.SplitVertically(p1, p2, 250)
929 self.currentItem = None
930 self.Layout()
931
932 def OnRightClick(self, event):
933 #Refactor this...
934 self._introspectItem = event.GetItem()
935 self._parentChain = self.GetItemChain(event.GetItem())
936 watchOnly = len(self._parentChain) < 1
937 if not _WATCHES_ON and watchOnly:
938 return
939 menu = wx.Menu()
940 if not watchOnly:
941 if not hasattr(self, "introspectID"):
942 self.introspectID = wx.NewId()
943 self.Bind(wx.EVT_MENU, self.OnIntrospect, id=self.introspectID)
944 item = wx.MenuItem(menu, self.introspectID, "Attempt Introspection")
945 menu.AppendItem(item)
946 menu.AppendSeparator()
947 if _WATCHES_ON:
948 if not hasattr(self, "watchID"):
949 self.watchID = wx.NewId()
950 self.Bind(wx.EVT_MENU, self.OnWatch, id=self.watchID)
951 item = wx.MenuItem(menu, self.watchID, "Create a Watch")
952 menu.AppendItem(item)
953 menu.AppendSeparator()
954 if not watchOnly:
955 if not hasattr(self, "viewID"):
956 self.viewID = wx.NewId()
957 self.Bind(wx.EVT_MENU, self.OnView, id=self.viewID)
958 item = wx.MenuItem(menu, self.viewID, "View in Dialog")
959 menu.AppendItem(item)
960 offset = wx.Point(x=0, y=20)
961 menuSpot = event.GetPoint() + offset
962 self._treeCtrl.PopupMenu(menu, menuSpot)
963 menu.Destroy()
964 self._parentChain = None
965 self._introspectItem = None
966
967 def GetItemChain(self, item):
968 parentChain = []
969 if item:
970 if _VERBOSE: print 'Exploding: %s' % self._treeCtrl.GetItemText(item, 0)
971 while item != self._root:
972 text = self._treeCtrl.GetItemText(item, 0)
973 if _VERBOSE: print "Appending ", text
974 parentChain.append(text)
975 item = self._treeCtrl.GetItemParent(item)
976 parentChain.reverse()
977 return parentChain
978
979 def OnView(self, event):
980 title = self._treeCtrl.GetItemText(self._introspectItem,0)
981 value = self._treeCtrl.GetItemText(self._introspectItem,1)
982 dlg = wx.lib.dialogs.ScrolledMessageDialog(self, value, title, style=wx.DD_DEFAULT_STYLE | wx.RESIZE_BORDER)
983 dlg.Show()
984
985 def OnWatch(self, event):
986 try:
987 if hasattr(self, '_parentChain'):
988 wd = WatchDialog(wx.GetApp().GetTopWindow(), "Add a Watch", self._parentChain)
989 else:
990 wd = WatchDialog(wx.GetApp().GetTopWindow(), "Add a Watch", None)
991 if wd.ShowModal() == wx.ID_OK:
992 name, text, send_frame, run_once = wd.GetSettings()
993 if send_frame:
994 frameNode = self._stack[int(self.currentItem)]
995 message = frameNode.getAttribute("message")
996 else:
997 message = ""
998 binType = self._ui._callback._debuggerServer.add_watch(name, text, message, run_once)
999 xmldoc = bz2.decompress(binType.data)
1000 domDoc = parseString(xmldoc)
1001 nodeList = domDoc.getElementsByTagName('watch')
1002 if len(nodeList) == 1:
1003 watchValue = nodeList.item(0).getAttribute("message")
1004 except:
1005 tp, val, tb = sys.exc_info()
1006 traceback.print_exception(tp, val, tb)
1007
1008 def OnIntrospect(self, event):
1009 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
1010
1011 try:
1012 list = self._framesListCtrl
1013 frameNode = self._stack[int(self.currentItem)]
1014 message = frameNode.getAttribute("message")
1015 binType = self._ui._callback._debuggerServer.attempt_introspection(message, self._parentChain)
1016 xmldoc = bz2.decompress(binType.data)
1017
1018 domDoc = parseString(xmldoc)
1019 nodeList = domDoc.getElementsByTagName('replacement')
1020 replacementNode = nodeList.item(0)
1021 if len(replacementNode.childNodes):
1022 thingToWalk = replacementNode.childNodes.item(0)
1023 tree = self._treeCtrl
1024 parent = tree.GetItemParent(self._introspectItem)
1025 treeNode = self.AppendSubTreeFromNode(thingToWalk, thingToWalk.getAttribute('name'), parent, insertBefore=self._introspectItem)
1026 tree.Delete(self._introspectItem)
1027 except:
1028 tp,val,tb = sys.exc_info()
1029 traceback.print_exception(tp, val, tb)
1030
1031 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
1032
1033 def OnSize(self, event):
1034 self._treeCtrl.SetSize(self._p2.GetSize())
1035 w,h = self._p1.GetClientSizeTuple()
1036 self._framesListCtrl.SetDimensions(0, 0, w, h)
1037
1038 def ClearWhileRunning(self):
1039 list = self._framesListCtrl
1040 list.DeleteAllItems()
1041 tree = self._treeCtrl
1042 tree.Hide()
1043
1044 def OnListRightClick(self, event):
1045 if not hasattr(self, "syncFrameID"):
1046 self.syncFrameID = wx.NewId()
1047 self.Bind(wx.EVT_MENU, self.OnSyncFrame, id=self.syncFrameID)
1048 menu = wx.Menu()
1049 item = wx.MenuItem(menu, self.syncFrameID, "Goto Source Line")
1050 menu.AppendItem(item)
1051 self.PopupMenu(menu, event.GetPosition())
1052 menu.Destroy()
1053
1054 def OnSyncFrame(self, event):
1055 list = self._framesListCtrl
1056 frameNode = self._stack[int(self.currentItem)]
1057 file = frameNode.getAttribute("file")
1058 line = frameNode.getAttribute("line")
1059 self._ui.SynchCurrentLine( file, int(line) )
1060
1061 def LoadFramesListXML(self, framesXML):
1062 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
1063 try:
1064 domDoc = parseString(framesXML)
1065 list = self._framesListCtrl
1066 list.DeleteAllItems()
1067 self._stack = []
1068 nodeList = domDoc.getElementsByTagName('frame')
1069 frame_count = -1
1070 for index in range(0, nodeList.length):
1071 frameNode = nodeList.item(index)
1072 message = frameNode.getAttribute("message")
1073 list.InsertStringItem(index, message)
1074 self._stack.append(frameNode)
1075 frame_count += 1
1076 list.Select(frame_count)
1077 self._p1.FitInside()
1078 frameNode = nodeList.item(index)
1079 file = frameNode.getAttribute("file")
1080 line = frameNode.getAttribute("line")
1081 self._ui.SynchCurrentLine( file, int(line) )
1082 except:
1083 tp,val,tb=sys.exc_info()
1084 traceback.print_exception(tp, val, tb)
1085
1086 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
1087
1088 def ListItemDeselected(self, event):
1089 pass
1090
1091 def ListItemSelected(self, event):
1092 self.currentItem = event.m_itemIndex
1093 frameNode = self._stack[int(self.currentItem)]
1094 self.PopulateTreeFromFrameNode(frameNode)
1095 # Temporarily doing this to test out automatically swicting to source line.
1096 self.OnSyncFrame(None)
1097
1098 def PopulateTreeFromFrameNode(self, frameNode):
1099 tree = self._treeCtrl
1100 tree.Show(True)
1101 root = self._root
1102 tree.DeleteChildren(root)
1103 children = frameNode.childNodes
1104 firstChild = None
1105 for index in range(0, children.length):
1106 subNode = children.item(index)
1107 treeNode = self.AppendSubTreeFromNode(subNode, subNode.getAttribute('name'), root)
1108 if not firstChild:
1109 firstChild = treeNode
1110 tree.Expand(root)
1111 tree.Expand(firstChild)
1112 self._p2.FitInside()
1113
1114 def AppendSubTreeFromNode(self, node, name, parent, insertBefore=None):
1115 tree = self._treeCtrl
1116 if insertBefore != None:
1117 treeNode = tree.InsertItem(parent, insertBefore, name)
1118 else:
1119 treeNode = tree.AppendItem(parent, name)
1120 children = node.childNodes
1121 if children.length == 0:
1122 tree.SetItemText(treeNode, self.StripOuterSingleQuotes(node.getAttribute("value")), 1)
1123 for index in range(0, children.length):
1124 subNode = children.item(index)
1125 if self.HasChildren(subNode):
1126 self.AppendSubTreeFromNode(subNode, subNode.getAttribute("name"), treeNode)
1127 else:
1128 name = subNode.getAttribute("name")
1129 value = self.StripOuterSingleQuotes(subNode.getAttribute("value"))
1130 n = tree.AppendItem(treeNode, name)
1131 tree.SetItemText(n, value, 1)
1132 return treeNode
1133
1134 def StripOuterSingleQuotes(self, string):
1135 if string.startswith("'") and string.endswith("'"):
1136 return string[1:-1]
1137 elif type(string) == types.UnicodeType:
1138 return string[1:-1]
1139 else:
1140 return string
1141
1142 def HasChildren(self, node):
1143 try:
1144 return node.childNodes.length > 0
1145 except:
1146 tp,val,tb=sys.exc_info()
1147 return False
1148
1149 class DebuggerView(Service.ServiceView):
1150
1151 #----------------------------------------------------------------------------
1152 # Overridden methods
1153 #----------------------------------------------------------------------------
1154
1155 def __init__(self, service):
1156 Service.ServiceView.__init__(self, service)
1157
1158 def _CreateControl(self, parent, id):
1159 return None
1160
1161 #------------------------------------------------------------------------------
1162 # Event handling
1163 #-----------------------------------------------------------------------------
1164
1165 def OnToolClicked(self, event):
1166 self.GetFrame().ProcessEvent(event)
1167
1168 #------------------------------------------------------------------------------
1169 # Class methods
1170 #-----------------------------------------------------------------------------
1171
1172 class Interaction:
1173 def __init__(self, message, framesXML, info=None, quit=False):
1174 self._framesXML = framesXML
1175 self._message = message
1176 self._info = info
1177 self._quit = quit
1178
1179 def getFramesXML(self):
1180 return self._framesXML
1181
1182 def getMessage(self):
1183 return self._message
1184
1185 def getInfo(self):
1186 return self._info
1187
1188 def getQuit(self):
1189 return self._quit
1190
1191 class AGXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):
1192 def __init__(self, address, logRequests=0):
1193 SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self, address, logRequests=logRequests)
1194
1195 class RequestHandlerThread(threading.Thread):
1196 def __init__(self, queue, address):
1197 threading.Thread.__init__(self)
1198 self._keepGoing = True
1199 self._queue = queue
1200 self._address = address
1201 self._server = AGXMLRPCServer(self._address,logRequests=0)
1202 self._server.register_function(self.interaction)
1203 self._server.register_function(self.quit)
1204 self._server.register_function(self.dummyOperation)
1205 if _VERBOSE: print "RequestHandlerThread on fileno %s" % str(self._server.fileno())
1206
1207 def run(self):
1208 while self._keepGoing:
1209 try:
1210 self._server.handle_request()
1211 except:
1212 tp, val, tb = sys.exc_info()
1213 traceback.print_exception(tp, val, tb)
1214 self._keepGoing = False
1215 if _VERBOSE: print "Exiting Request Handler Thread."
1216
1217 def interaction(self, message, frameXML, info):
1218 if _VERBOSE: print "In RequestHandlerThread.interaction -- adding to queue"
1219 interaction = Interaction(message, frameXML, info)
1220 self._queue.put(interaction)
1221 return ""
1222
1223 def quit(self):
1224 interaction = Interaction(None, None, info=None, quit=True)
1225 self._queue.put(interaction)
1226 return ""
1227
1228 def dummyOperation(self):
1229 return ""
1230
1231 def AskToStop(self):
1232 self._keepGoing = False
1233 if type(self._server) is not types.NoneType:
1234 try:
1235 # This is a really ugly way to make sure this thread isn't blocked in
1236 # handle_request.
1237 url = 'http://' + self._address[0] + ':' + str(self._address[1]) + '/'
1238 tempServer = xmlrpclib.ServerProxy(url, allow_none=1)
1239 tempServer.dummyOperation()
1240 except:
1241 tp, val, tb = sys.exc_info()
1242 traceback.print_exception(tp, val, tb)
1243 self._server.server_close()
1244
1245
1246 class RequestBreakThread(threading.Thread):
1247 def __init__(self, server, interrupt=False, pushBreakpoints=False, breakDict=None, kill=False):
1248 threading.Thread.__init__(self)
1249 self._server = server
1250
1251 self._interrupt = interrupt
1252 self._pushBreakpoints = pushBreakpoints
1253 self._breakDict = breakDict
1254 self._kill = kill
1255
1256 def run(self):
1257 try:
1258 if _VERBOSE: print "RequestBreakThread, before call"
1259 if self._interrupt:
1260 self._server.break_requested()
1261 if self._pushBreakpoints:
1262 self._server.update_breakpoints(xmlrpclib.Binary(pickle.dumps(self._breakDict)))
1263 if self._kill:
1264 try:
1265 self._server.die()
1266 except:
1267 pass
1268 if _VERBOSE: print "RequestBreakThread, after call"
1269 except:
1270 tp,val,tb = sys.exc_info()
1271 traceback.print_exception(tp, val, tb)
1272
1273 class DebuggerOperationThread(threading.Thread):
1274 def __init__(self, function):
1275 threading.Thread.__init__(self)
1276 self._function = function
1277
1278 def run(self):
1279 if _VERBOSE: print "In DOT, before call"
1280 try:
1281 self._function()
1282 except:
1283 tp,val,tb = sys.exc_info()
1284 traceback.print_exception(tp, val, tb)
1285 if _VERBOSE: print "In DOT, after call"
1286
1287 class DebuggerCallback:
1288
1289 def __init__(self, host, port, debugger_url, break_url, debuggerUI):
1290 if _VERBOSE: print "+++++++ Creating server on port, ", str(port)
1291
1292 self._queue = Queue.Queue(50)
1293 self._host = host
1294 self._port = int(port)
1295 threading._VERBOSE = _VERBOSE
1296 self._serverHandlerThread = RequestHandlerThread(self._queue, (self._host, self._port))
1297
1298 self._debugger_url = debugger_url
1299 self._debuggerServer = None
1300 self._waiting = False
1301 self._service = wx.GetApp().GetService(DebuggerService)
1302 self._debuggerUI = debuggerUI
1303 self._break_url = break_url
1304 self._breakServer = None
1305 self._firstInteraction = True
1306 self._pendingBreak = False
1307
1308 def start(self):
1309 self._serverHandlerThread.start()
1310
1311 def ServerClose(self):
1312 rbt = RequestBreakThread(self._breakServer, kill=True)
1313 rbt.start()
1314 self.setWaiting(False)
1315 if self._serverHandlerThread:
1316 self._serverHandlerThread.AskToStop()
1317 self._serverHandlerThread = None
1318
1319 def BreakExecution(self):
1320 rbt = RequestBreakThread(self._breakServer, interrupt=True)
1321 rbt.start()
1322
1323 def SingleStep(self):
1324 self._debuggerUI.DisableWhileDebuggerRunning()
1325 #dot = DebuggerOperationThread(self._debuggerServer.set_step)
1326 #dot.start()
1327 self._debuggerServer.set_step() # Figure out where to set allowNone
1328 self.waitForRPC()
1329
1330 def Next(self):
1331 self._debuggerUI.DisableWhileDebuggerRunning()
1332 #dot = DebuggerOperationThread(self._debuggerServer.set_next)
1333 #dot.start()
1334 self._debuggerServer.set_next()
1335 self.waitForRPC()
1336
1337 def Continue(self):
1338 self._debuggerUI.DisableWhileDebuggerRunning()
1339 #dot = DebuggerOperationThread(self._debuggerServer.set_continue)
1340 #dot.start()
1341 self._debuggerServer.set_continue()
1342 self.waitForRPC()
1343
1344 def Return(self):
1345 self._debuggerUI.DisableWhileDebuggerRunning()
1346 #dot = DebuggerOperationThread(self._debuggerServer.set_return)
1347 #dot.start()
1348 self._debuggerServer.set_return()
1349 self.waitForRPC()
1350
1351 def setWaiting(self, value):
1352 self._waiting = value
1353
1354 def getWaiting(self):
1355 return self._waiting
1356
1357 def readQueue(self):
1358 if self._queue.qsize():
1359 try:
1360 item = self._queue.get_nowait()
1361 if item.getQuit():
1362 self.interaction(None, None, None, True)
1363 else:
1364 data = bz2.decompress(item.getFramesXML().data)
1365 self.interaction(item.getMessage().data, data, item.getInfo(), False)
1366 except Queue.Empty:
1367 pass
1368
1369 def pushBreakpoints(self):
1370 rbt = RequestBreakThread(self._breakServer, pushBreakpoints=True, breakDict=self._service.GetMasterBreakpointDict())
1371 rbt.start()
1372
1373
1374 def waitForRPC(self):
1375 self.setWaiting(True)
1376 while self.getWaiting():
1377 try:
1378 self.readQueue()
1379 import time
1380 time.sleep(0.02)
1381 except:
1382 tp, val, tb = sys.exc_info()
1383 traceback.print_exception(tp, val, tb)
1384 wx.GetApp().Yield(True)
1385 if _VERBOSE: print "Exiting waitForRPC."
1386
1387 def interaction(self, message, frameXML, info, quit):
1388
1389 #This method should be hit as the debugger starts.
1390 if self._firstInteraction:
1391 self._firstInteraction = False
1392 self._debuggerServer = xmlrpclib.ServerProxy(self._debugger_url, allow_none=1)
1393 self._breakServer = xmlrpclib.ServerProxy(self._break_url, allow_none=1)
1394 self.pushBreakpoints()
1395 self.setWaiting(False)
1396 if _VERBOSE: print "+"*40
1397 if(quit):
1398 self._debuggerUI.StopExecution(None)
1399 return ""
1400 if(info != ""):
1401 if _VERBOSE: print "Hit interaction with exception"
1402 #self._debuggerUI.StopExecution(None)
1403 #self._debuggerUI.SetStatusText("Got exception: " + str(info))
1404 self._debuggerUI.SwitchToOutputTab()
1405 else:
1406 if _VERBOSE: print "Hit interaction no exception"
1407 self._debuggerUI.SetStatusText(message)
1408 self._debuggerUI.LoadFramesListXML(frameXML)
1409 self._debuggerUI.EnableWhileDebuggerStopped()
1410 if _VERBOSE: print "+"*40
1411
1412 class DebuggerService(Service.Service):
1413
1414 #----------------------------------------------------------------------------
1415 # Constants
1416 #----------------------------------------------------------------------------
1417 TOGGLE_BREAKPOINT_ID = wx.NewId()
1418 CLEAR_ALL_BREAKPOINTS = wx.NewId()
1419 RUN_ID = wx.NewId()
1420 DEBUG_ID = wx.NewId()
1421 DEBUG_WEBSERVER_ID = wx.NewId()
1422
1423 def ComparePaths(first, second):
1424 one = DebuggerService.ExpandPath(first)
1425 two = DebuggerService.ExpandPath(second)
1426 if _WINDOWS:
1427 return one.lower() == two.lower()
1428 else:
1429 return one == two
1430 ComparePaths = staticmethod(ComparePaths)
1431
1432 # Make sure we're using an expanded path on windows.
1433 def ExpandPath(path):
1434 if _WINDOWS:
1435 try:
1436 return win32api.GetLongPathName(path)
1437 except:
1438 print "Cannot get long path for %s" % path
1439
1440 return path
1441
1442 ExpandPath = staticmethod(ExpandPath)
1443
1444 #----------------------------------------------------------------------------
1445 # Overridden methods
1446 #----------------------------------------------------------------------------
1447
1448 def __init__(self, serviceName, embeddedWindowLocation = wx.lib.pydocview.EMBEDDED_WINDOW_LEFT):
1449 Service.Service.__init__(self, serviceName, embeddedWindowLocation)
1450 self.BREAKPOINT_DICT_STRING = "MasterBreakpointDict"
1451 config = wx.ConfigBase_Get()
1452 pickledbps = config.Read(self.BREAKPOINT_DICT_STRING)
1453 if pickledbps:
1454 try:
1455 self._masterBPDict = pickle.loads(pickledbps.encode('ascii'))
1456 except:
1457 tp, val, tb = sys.exc_info()
1458 traceback.print_exception(tp,val,tb)
1459 self._masterBPDict = {}
1460 else:
1461 self._masterBPDict = {}
1462
1463 def OnCloseFrame(self, event):
1464 # IS THIS THE RIGHT PLACE?
1465 try:
1466 config = wx.ConfigBase_Get()
1467 config.Write(self.BREAKPOINT_DICT_STRING, pickle.dumps(self._masterBPDict))
1468 except:
1469 tp,val,tb = sys.exc_info()
1470 traceback.print_exception(tp, val, tb)
1471 return True
1472
1473 def _CreateView(self):
1474 return DebuggerView(self)
1475
1476
1477 #----------------------------------------------------------------------------
1478 # Service specific methods
1479 #----------------------------------------------------------------------------
1480
1481 def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
1482 #Service.Service.InstallControls(self, frame, menuBar, toolBar, statusBar, document)
1483
1484 config = wx.ConfigBase_Get()
1485
1486 debuggerMenu = wx.Menu()
1487 if not menuBar.FindItemById(DebuggerService.CLEAR_ALL_BREAKPOINTS):
1488
1489 debuggerMenu.Append(DebuggerService.RUN_ID, _("&Run...\tCtrl+R"), _("Runs a file"))
1490 wx.EVT_MENU(frame, DebuggerService.RUN_ID, frame.ProcessEvent)
1491 wx.EVT_UPDATE_UI(frame, DebuggerService.RUN_ID, frame.ProcessUpdateUIEvent)
1492
1493 debuggerMenu.Append(DebuggerService.DEBUG_ID, _("&Debug...\tCtrl+D"), _("Debugs a file"))
1494 wx.EVT_MENU(frame, DebuggerService.DEBUG_ID, frame.ProcessEvent)
1495 wx.EVT_UPDATE_UI(frame, DebuggerService.DEBUG_ID, frame.ProcessUpdateUIEvent)
1496
1497 if not ACTIVEGRID_BASE_IDE:
1498 debuggerMenu.AppendSeparator()
1499 debuggerMenu.Append(DebuggerService.DEBUG_WEBSERVER_ID, _("Debug Internal Web Server"), _("Debugs the internal webservier"))
1500 wx.EVT_MENU(frame, DebuggerService.DEBUG_WEBSERVER_ID, frame.ProcessEvent)
1501 wx.EVT_UPDATE_UI(frame, DebuggerService.DEBUG_WEBSERVER_ID, frame.ProcessUpdateUIEvent)
1502
1503 debuggerMenu.AppendSeparator()
1504
1505 debuggerMenu.Append(DebuggerService.TOGGLE_BREAKPOINT_ID, _("&Toggle Breakpoint...\tCtrl+B"), _("Toggle a breakpoint"))
1506 wx.EVT_MENU(frame, DebuggerService.TOGGLE_BREAKPOINT_ID, self.ProcessEvent)
1507 wx.EVT_UPDATE_UI(frame, DebuggerService.TOGGLE_BREAKPOINT_ID, self.ProcessUpdateUIEvent)
1508
1509 debuggerMenu.Append(DebuggerService.CLEAR_ALL_BREAKPOINTS, _("&Clear All Breakpoints"), _("Clear All Breakpoints"))
1510 wx.EVT_MENU(frame, DebuggerService.CLEAR_ALL_BREAKPOINTS, self.ProcessEvent)
1511 wx.EVT_UPDATE_UI(frame, DebuggerService.CLEAR_ALL_BREAKPOINTS, self.ProcessUpdateUIEvent)
1512
1513
1514 viewMenuIndex = menuBar.FindMenu(_("&Project"))
1515 menuBar.Insert(viewMenuIndex + 1, debuggerMenu, _("&Run"))
1516
1517 return True
1518
1519
1520
1521 #----------------------------------------------------------------------------
1522 # Event Processing Methods
1523 #----------------------------------------------------------------------------
1524
1525 def ProcessEventBeforeWindows(self, event):
1526 return False
1527
1528
1529 def ProcessEvent(self, event):
1530 if Service.Service.ProcessEvent(self, event):
1531 return True
1532
1533 an_id = event.GetId()
1534 if an_id == DebuggerService.TOGGLE_BREAKPOINT_ID:
1535 self.OnToggleBreakpoint(event)
1536 return True
1537 elif an_id == DebuggerService.CLEAR_ALL_BREAKPOINTS:
1538 self.ClearAllBreakpoints()
1539 return True
1540 elif an_id == DebuggerService.RUN_ID:
1541 self.OnRunProject(event)
1542 return True
1543 elif an_id == DebuggerService.DEBUG_ID:
1544 self.OnDebugProject(event)
1545 return True
1546 elif an_id == DebuggerService.DEBUG_WEBSERVER_ID:
1547 self.OnDebugWebServer(event)
1548 return True
1549 return False
1550
1551 def ProcessUpdateUIEvent(self, event):
1552 if Service.Service.ProcessUpdateUIEvent(self, event):
1553 return True
1554
1555 an_id = event.GetId()
1556 if an_id == DebuggerService.TOGGLE_BREAKPOINT_ID:
1557 currentView = self.GetDocumentManager().GetCurrentView()
1558 event.Enable(isinstance(currentView, PythonEditor.PythonView))
1559 return True
1560 elif an_id == DebuggerService.CLEAR_ALL_BREAKPOINTS:
1561 event.Enable(self.HasBreakpointsSet())
1562 return True
1563 elif an_id == DebuggerService.RUN_ID:
1564 event.Enable(self.HasAnyFiles())
1565 return True
1566 elif an_id == DebuggerService.DEBUG_ID:
1567 event.Enable(self.HasAnyFiles())
1568 return True
1569 else:
1570 return False
1571
1572 #----------------------------------------------------------------------------
1573 # Class Methods
1574 #----------------------------------------------------------------------------
1575
1576 def OnDebugProject(self, event):
1577 if not Executor.GetPythonExecutablePath():
1578 return
1579 if DebugCommandUI.DebuggerRunning():
1580 wx.MessageBox(_("A debugger is already running. Please shut down the other debugger first."), _("Debugger Running"))
1581 return
1582 self.ShowWindow(True)
1583 projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
1584 project = projectService.GetView().GetDocument()
1585 try:
1586 dlg = CommandPropertiesDialog(self.GetView().GetFrame(), 'Debug Python File', projectService, None, pythonOnly=True, okButtonName="Debug", debugging=True)
1587 except:
1588 return
1589 if dlg.ShowModal() == wx.ID_OK:
1590 fileToDebug, initialArgs, startIn, isPython, environment = dlg.GetSettings()
1591 dlg.Destroy()
1592 else:
1593 dlg.Destroy()
1594 return
1595 self.PromptToSaveFiles()
1596
1597 shortFile = os.path.basename(fileToDebug)
1598 fileToDebug = DebuggerService.ExpandPath(fileToDebug)
1599 try:
1600 page = DebugCommandUI(Service.ServiceView.bottomTab, -1, str(fileToDebug), self)
1601 count = Service.ServiceView.bottomTab.GetPageCount()
1602 Service.ServiceView.bottomTab.AddPage(page, _("Debugging: ") + shortFile)
1603 Service.ServiceView.bottomTab.SetSelection(count)
1604 page.Execute(initialArgs, startIn, environment)
1605 except:
1606 pass
1607
1608 def OnDebugWebServer(self, event):
1609 import WebServerService
1610 wsService = wx.GetApp().GetService(WebServerService.WebServerService)
1611 fileName, args = wsService.StopAndPrepareToDebug()
1612 try:
1613 page = DebugCommandUI(Service.ServiceView.bottomTab, -1, str(fileName), self)
1614 count = Service.ServiceView.bottomTab.GetPageCount()
1615 Service.ServiceView.bottomTab.AddPage(page, _("Debugging: Internal WebServer"))
1616 Service.ServiceView.bottomTab.SetSelection(count)
1617 page.Execute(args, startIn=os.getcwd(), environment=os.environ)
1618 except:
1619 pass
1620
1621
1622 def HasAnyFiles(self):
1623 docs = wx.GetApp().GetDocumentManager().GetDocuments()
1624 return len(docs) > 0
1625
1626 def PromptToSaveFiles(self, running=True):
1627 filesModified = False
1628 docs = wx.GetApp().GetDocumentManager().GetDocuments()
1629 for doc in docs:
1630 if doc.IsModified():
1631 filesModified = True
1632 break
1633 if filesModified:
1634 frame = self.GetView().GetFrame()
1635 if running:
1636 yesNoMsg = wx.MessageDialog(frame,
1637 _("Files have been modified.\nWould you like to save all files before running?"),
1638 _("Run"),
1639 wx.YES_NO
1640 )
1641 else:
1642 yesNoMsg = wx.MessageDialog(frame,
1643 _("Files have been modified.\nWould you like to save all files before debugging?"),
1644 _("Debug"),
1645 wx.YES_NO
1646 )
1647 if yesNoMsg.ShowModal() == wx.ID_YES:
1648 docs = wx.GetApp().GetDocumentManager().GetDocuments()
1649 for doc in docs:
1650 doc.Save()
1651
1652 def OnExit(self):
1653 DebugCommandUI.ShutdownAllDebuggers()
1654
1655 def OnRunProject(self, event):
1656 if not Executor.GetPythonExecutablePath():
1657 return
1658 projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
1659 project = projectService.GetView().GetDocument()
1660 try:
1661 dlg = CommandPropertiesDialog(self.GetView().GetFrame(), 'Run', projectService, None)
1662 except:
1663 return
1664 if dlg.ShowModal() == wx.ID_OK:
1665 fileToRun, initialArgs, startIn, isPython, environment = dlg.GetSettings()
1666
1667
1668 dlg.Destroy()
1669 else:
1670 dlg.Destroy()
1671 return
1672 self.PromptToSaveFiles()
1673 # This will need to change when we can run more than .py and .bpel files.
1674 if not isPython:
1675 projectService.RunProcessModel(fileToRun)
1676 return
1677
1678 self.ShowWindow(True)
1679 shortFile = os.path.basename(fileToRun)
1680 page = RunCommandUI(Service.ServiceView.bottomTab, -1, str(fileToRun))
1681 count = Service.ServiceView.bottomTab.GetPageCount()
1682 Service.ServiceView.bottomTab.AddPage(page, "Running: " + shortFile)
1683 Service.ServiceView.bottomTab.SetSelection(count)
1684 page.Execute(initialArgs, startIn, environment)
1685
1686 def OnToggleBreakpoint(self, event, line=-1, fileName=None):
1687 if not fileName:
1688 view = wx.GetApp().GetDocumentManager().GetCurrentView()
1689 # Test to make sure we aren't the project view.
1690 if not hasattr(view, 'MarkerExists'):
1691 return
1692 fileName = wx.GetApp().GetDocumentManager().GetCurrentDocument().GetFilename()
1693 if line < 0:
1694 line = view.GetCtrl().GetCurrentLine()
1695 if self.BreakpointSet(fileName, line + 1):
1696 self.ClearBreak(fileName, line + 1)
1697 else:
1698 self.SetBreak(fileName, line + 1)
1699 # Now refresh all the markers icons in all the open views.
1700 self.ClearAllBreakpointMarkers()
1701 self.SetAllBreakpointMarkers()
1702
1703 def SilentToggleBreakpoint(self, fileName, line):
1704 found = False
1705 for lineNumber in self.GetBreakpointList(fileName):
1706 if int(lineNumber) == int(line):
1707 found = True
1708 break
1709 if found:
1710 self.SetBreak(fileName, line)
1711 else:
1712 self.ClearBreak(fileName, line)
1713
1714 def SetBreak(self, fileName, line):
1715 expandedName = DebuggerService.ExpandPath(fileName)
1716 if not self._masterBPDict.has_key(expandedName):
1717 self._masterBPDict[expandedName] = [line]
1718 else:
1719 self._masterBPDict[expandedName] += [line]
1720 # If we're already debugging, pass this bp off to the DebuggerCallback
1721 self.NotifyDebuggersOfBreakpointChange()
1722
1723 def NotifyDebuggersOfBreakpointChange(self):
1724 DebugCommandUI.NotifyDebuggersOfBreakpointChange()
1725
1726 def GetBreakpointList(self, fileName):
1727 expandedName = DebuggerService.ExpandPath(fileName)
1728 if not self._masterBPDict.has_key(expandedName):
1729 return []
1730 else:
1731 return self._masterBPDict[expandedName]
1732
1733 def BreakpointSet(self, fileName, line):
1734 expandedName = DebuggerService.ExpandPath(fileName)
1735 if not self._masterBPDict.has_key(expandedName):
1736 return False
1737 else:
1738 newList = []
1739 for number in self._masterBPDict[expandedName]:
1740 if(int(number) == int(line)):
1741 return True
1742 return False
1743
1744 def ClearBreak(self, fileName, line):
1745 expandedName = DebuggerService.ExpandPath(fileName)
1746 if not self._masterBPDict.has_key(expandedName):
1747 print "In ClearBreak: no key"
1748 return
1749 else:
1750 newList = []
1751 for number in self._masterBPDict[expandedName]:
1752 if(int(number) != int(line)):
1753 newList.append(number)
1754 self._masterBPDict[expandedName] = newList
1755 self.NotifyDebuggersOfBreakpointChange()
1756
1757 def HasBreakpointsSet(self):
1758 for key, value in self._masterBPDict.items():
1759 if len(value) > 0:
1760 return True
1761 return False
1762
1763 def ClearAllBreakpoints(self):
1764 self._masterBPDict = {}
1765 self.NotifyDebuggersOfBreakpointChange()
1766 self.ClearAllBreakpointMarkers()
1767
1768 def ClearAllBreakpointMarkers(self):
1769 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
1770 for openDoc in openDocs:
1771 if(isinstance(openDoc.GetFirstView(), CodeEditor.CodeView)):
1772 openDoc.GetFirstView().MarkerDeleteAll(CodeEditor.CodeCtrl.BREAKPOINT_MARKER_NUM)
1773
1774 def GetMasterBreakpointDict(self):
1775 return self._masterBPDict
1776
1777 def SetAllBreakpointMarkers(self):
1778 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
1779 for openDoc in openDocs:
1780 if(isinstance(openDoc.GetFirstView(), CodeEditor.CodeView)):
1781 self.SetCurrentBreakpointMarkers(openDoc.GetFirstView())
1782
1783 def SetCurrentBreakpointMarkers(self, view):
1784 if isinstance(view, CodeEditor.CodeView) and hasattr(view, 'GetDocument'):
1785 view.MarkerDeleteAll(CodeEditor.CodeCtrl.BREAKPOINT_MARKER_NUM)
1786 for linenum in self.GetBreakpointList(view.GetDocument().GetFilename()):
1787 view.MarkerAdd(lineNum=int(linenum) - 1, marker_index=CodeEditor.CodeCtrl.BREAKPOINT_MARKER_NUM)
1788
1789 class DebuggerOptionsPanel(wx.Panel):
1790
1791
1792 def __init__(self, parent, id):
1793 wx.Panel.__init__(self, parent, id)
1794 SPACE = 10
1795 config = wx.ConfigBase_Get()
1796 localHostStaticText = wx.StaticText(self, -1, _("Local Host Name:"))
1797 self._LocalHostTextCtrl = wx.TextCtrl(self, -1, config.Read("DebuggerHostName", DEFAULT_HOST), size = (150, -1))
1798 portNumberStaticText = wx.StaticText(self, -1, _("Port Range:"))
1799 dashStaticText = wx.StaticText(self, -1, _("through to"))
1800 startingPort=config.ReadInt("DebuggerStartingPort", DEFAULT_PORT)
1801 self._PortNumberTextCtrl = wx.lib.intctrl.IntCtrl(self, -1, startingPort, size = (50, -1))
1802 self._PortNumberTextCtrl.SetMin(1)#What are real values?
1803 self._PortNumberTextCtrl.SetMax(65514) #What are real values?
1804 self.Bind(wx.lib.intctrl.EVT_INT, self.MinPortChange, self._PortNumberTextCtrl)
1805
1806 self._EndPortNumberTextCtrl = wx.lib.intctrl.IntCtrl(self, -1, startingPort + PORT_COUNT, size = (50, -1))
1807 self._EndPortNumberTextCtrl.SetMin(22)#What are real values?
1808 self._EndPortNumberTextCtrl.SetMax(65535)#What are real values?
1809 self._EndPortNumberTextCtrl.Enable( False )
1810 debuggerPanelBorderSizer = wx.BoxSizer(wx.VERTICAL)
1811 debuggerPanelSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
1812 debuggerPanelSizer.Add( localHostStaticText, (0,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
1813 debuggerPanelSizer.Add( self._LocalHostTextCtrl, (0,1), (1,3), flag=wx.EXPAND|wx.ALIGN_CENTER)
1814 debuggerPanelSizer.Add( portNumberStaticText, (1,0), flag=wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL)
1815 debuggerPanelSizer.Add( self._PortNumberTextCtrl, (1,1), flag=wx.ALIGN_CENTER)
1816 debuggerPanelSizer.Add( dashStaticText, (1,2), flag=wx.ALIGN_CENTER)
1817 debuggerPanelSizer.Add( self._EndPortNumberTextCtrl, (1,3), flag=wx.ALIGN_CENTER)
1818 FLUSH_PORTS_ID = wx.NewId()
1819 self._flushPortsButton = wx.Button(self, FLUSH_PORTS_ID, "Reset Port List")
1820 wx.EVT_BUTTON(parent, FLUSH_PORTS_ID, self.FlushPorts)
1821 debuggerPanelSizer.Add(self._flushPortsButton, (2,2), (1,2), flag=wx.ALIGN_RIGHT)
1822
1823 debuggerPanelBorderSizer.Add(debuggerPanelSizer, 0, wx.ALL, SPACE)
1824 self.SetSizer(debuggerPanelBorderSizer)
1825 self.Layout()
1826 parent.AddPage(self, _("Debugger"))
1827
1828 def FlushPorts(self, event):
1829 if self._PortNumberTextCtrl.IsInBounds():
1830 config = wx.ConfigBase_Get()
1831 config.WriteInt("DebuggerStartingPort", self._PortNumberTextCtrl.GetValue())
1832 DebugCommandUI.NewPortRange()
1833 else:
1834 wx.MessageBox(_("The starting port is not valid. Please change the value and try again.", "Invalid Starting Port Number"))
1835
1836 def MinPortChange(self, event):
1837 self._EndPortNumberTextCtrl.Enable( True )
1838 self._EndPortNumberTextCtrl.SetValue( self._PortNumberTextCtrl.GetValue() + PORT_COUNT)
1839 self._EndPortNumberTextCtrl.Enable( False )
1840
1841 def OnOK(self, optionsDialog):
1842 config = wx.ConfigBase_Get()
1843 config.Write("DebuggerHostName", self._LocalHostTextCtrl.GetValue())
1844 if self._PortNumberTextCtrl.IsInBounds():
1845 config.WriteInt("DebuggerStartingPort", self._PortNumberTextCtrl.GetValue())
1846
1847 class CommandPropertiesDialog(wx.Dialog):
1848
1849 def __init__(self, parent, title, projectService, currentProjectDocument, pythonOnly=False, okButtonName="Run", debugging=False):
1850 self._projService = projectService
1851 self._pmext = None
1852 self._pyext = None
1853 for template in self._projService.GetDocumentManager().GetTemplates():
1854 if not ACTIVEGRID_BASE_IDE and template.GetDocumentType() == ProcessModelEditor.ProcessModelDocument:
1855 self._pmext = template.GetDefaultExtension()
1856 if template.GetDocumentType() == PythonEditor.PythonDocument:
1857 self._pyext = template.GetDefaultExtension()
1858 self._pythonOnly = pythonOnly
1859 self._currentProj = currentProjectDocument
1860 self._projectNameList, self._projectDocumentList, selectedIndex = self.GetProjectList()
1861 if not self._projectNameList:
1862 wx.MessageBox(_("To run or debug you must have an open runnable file or project containing runnable files. Use File->Open to open the file you wish to run or debug."), _("Nothing to Run"))
1863 raise BadBadBad
1864 if _WINDOWS:
1865 wx.Dialog.__init__(self, parent, -1, title)
1866 else:
1867 wx.Dialog.__init__(self, parent, -1, title, size=(390,270))
1868
1869 projStaticText = wx.StaticText(self, -1, _("Project:"))
1870 fileStaticText = wx.StaticText(self, -1, _("File:"))
1871 argsStaticText = wx.StaticText(self, -1, _("Arguments:"))
1872 startInStaticText = wx.StaticText(self, -1, _("Start in:"))
1873 pythonPathStaticText = wx.StaticText(self, -1, _("PYTHONPATH:"))
1874 postpendStaticText = _("Postpend win32api path")
1875 cpPanelBorderSizer = wx.BoxSizer(wx.VERTICAL)
1876 self._projList = wx.Choice(self, -1, (200,-1), choices=self._projectNameList)
1877 self.Bind(wx.EVT_CHOICE, self.EvtListBox, self._projList)
1878 HALF_SPACE = 5
1879 flexGridSizer = wx.FlexGridSizer(cols = 3, vgap = 10, hgap = 10)
1880
1881 flexGridSizer.Add(projStaticText, 0, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
1882 flexGridSizer.Add(self._projList, 1, flag=wx.EXPAND)
1883 flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
1884
1885 flexGridSizer.Add(fileStaticText, 0, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
1886 self._fileList = wx.Choice(self, -1, (200,-1))
1887 self.Bind(wx.EVT_CHOICE, self.OnFileSelected, self._fileList)
1888 flexGridSizer.Add(self._fileList, 1, flag=wx.EXPAND)
1889 flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
1890
1891 config = wx.ConfigBase_Get()
1892 self._lastArguments = config.Read("LastRunArguments")
1893 self._argsEntry = wx.TextCtrl(self, -1, str(self._lastArguments))
1894 self._argsEntry.SetToolTipString(str(self._lastArguments))
1895 def TextChanged(event):
1896 self._argsEntry.SetToolTipString(event.GetString())
1897 self.Bind(wx.EVT_TEXT, TextChanged, self._argsEntry)
1898
1899 flexGridSizer.Add(argsStaticText, 0, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
1900 flexGridSizer.Add(self._argsEntry, 1, flag=wx.EXPAND)
1901 flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
1902
1903 flexGridSizer.Add(startInStaticText, 0, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
1904 self._lastStartIn = config.Read("LastRunStartIn")
1905 if not self._lastStartIn:
1906 self._lastStartIn = str(os.getcwd())
1907 self._startEntry = wx.TextCtrl(self, -1, self._lastStartIn)
1908 self._startEntry.SetToolTipString(self._lastStartIn)
1909 def TextChanged2(event):
1910 self._startEntry.SetToolTipString(event.GetString())
1911 self.Bind(wx.EVT_TEXT, TextChanged2, self._startEntry)
1912
1913 flexGridSizer.Add(self._startEntry, 1, wx.EXPAND)
1914 self._findDir = wx.Button(self, -1, _("Browse..."), size=(60,-1))
1915 self.Bind(wx.EVT_BUTTON, self.OnFindDirClick, self._findDir)
1916 flexGridSizer.Add(self._findDir, 0, wx.RIGHT, 10)
1917
1918 flexGridSizer.Add(pythonPathStaticText, 0, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
1919 if os.environ.has_key('PYTHONPATH'):
1920 startval = os.environ['PYTHONPATH']
1921 else:
1922 startval = ""
1923 self._lastPythonPath = config.Read("LastPythonPath", startval)
1924 self._pythonPathEntry = wx.TextCtrl(self, -1, self._lastPythonPath)
1925 self._pythonPathEntry.SetToolTipString(self._lastPythonPath)
1926 flexGridSizer.Add(self._pythonPathEntry, 1, wx.EXPAND)
1927 flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
1928 flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
1929 if debugging:
1930 self._postpendCheckBox = wx.CheckBox(self, -1, postpendStaticText)
1931 checked = bool(config.ReadInt("PythonPathPostpend", 1))
1932 self._postpendCheckBox.SetValue(checked)
1933 flexGridSizer.Add(self._postpendCheckBox, 1, wx.EXPAND)
1934 flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
1935 cpPanelBorderSizer.Add(flexGridSizer, 0, wx.ALL, 10)
1936
1937 box = wx.BoxSizer(wx.HORIZONTAL)
1938 self._okButton = wx.Button(self, wx.ID_OK, okButtonName, size=(75,-1))
1939 self._okButton.SetDefault()
1940 self._okButton.SetHelpText(_("The ") + okButtonName + _(" button completes the dialog"))
1941 box.Add(self._okButton, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
1942 self.Bind(wx.EVT_BUTTON, self.OnOKClick, self._okButton)
1943 btn = wx.Button(self, wx.ID_CANCEL, _("Cancel"), size=(75,-1))
1944 btn.SetHelpText(_("The Cancel button cancels the dialog."))
1945 box.Add(btn, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
1946 cpPanelBorderSizer.Add(box, 0, wx.ALIGN_RIGHT|wx.BOTTOM, 5)
1947
1948 self.SetSizer(cpPanelBorderSizer)
1949 if _WINDOWS:
1950 self.GetSizer().Fit(self)
1951
1952 self.Layout()
1953
1954 # Set up selections based on last values used.
1955 self._fileNameList = None
1956 self._selectedFileIndex = 0
1957 lastProject = config.Read("LastRunProject")
1958 lastFile = config.Read("LastRunFile")
1959
1960 if lastProject in self._projectNameList:
1961 selectedIndex = self._projectNameList.index(lastProject)
1962 elif selectedIndex < 0:
1963 selectedIndex = 0
1964 self._projList.Select(selectedIndex)
1965 self._selectedProjectIndex = selectedIndex
1966 self._selectedProjectDocument = self._projectDocumentList[selectedIndex]
1967 self.PopulateFileList(self._selectedProjectDocument, lastFile)
1968
1969 def OnOKClick(self, event):
1970 startIn = self._startEntry.GetValue()
1971 fileToRun = self._fileList.GetStringSelection()
1972 if not fileToRun:
1973 wx.MessageBox(_("You must select a file to proceed. Note that not all projects have files that can be run or debugged."))
1974 return
1975 isPython = fileToRun.endswith(self._pyext)
1976 if isPython and not os.path.exists(startIn):
1977 wx.MessageBox(_("Starting directory does not exist. Please change this value."))
1978 return
1979 config = wx.ConfigBase_Get()
1980 config.Write("LastRunProject", self._projectNameList[self._selectedProjectIndex])
1981 config.Write("LastRunFile", fileToRun)
1982 # Don't update the arguments or starting directory unless we're runing python.
1983 if isPython:
1984 config.Write("LastRunArguments", self._argsEntry.GetValue())
1985 config.Write("LastRunStartIn", self._startEntry.GetValue())
1986 config.Write("LastPythonPath",self._pythonPathEntry.GetValue())
1987 if hasattr(self, "_postpendCheckBox"):
1988 config.WriteInt("PythonPathPostpend", int(self._postpendCheckBox.GetValue()))
1989
1990 self.EndModal(wx.ID_OK)
1991
1992 def GetSettings(self):
1993 filename = self._fileNameList[self._selectedFileIndex]
1994 args = self._argsEntry.GetValue()
1995 startIn = self._startEntry.GetValue()
1996 isPython = filename.endswith(self._pyext)
1997 env = os.environ
1998 if hasattr(self, "_postpendCheckBox"):
1999 postpend = self._postpendCheckBox.GetValue()
2000 else:
2001 postpend = False
2002 if postpend:
2003 env['PYTHONPATH'] = self._pythonPathEntry.GetValue() + os.pathsep + os.path.join(os.getcwd(), "3rdparty", "pywin32")
2004 else:
2005 env['PYTHONPATH'] = self._pythonPathEntry.GetValue()
2006
2007 return filename, args, startIn, isPython, env
2008
2009 def OnFileSelected(self, event):
2010 self._selectedFileIndex = self._fileList.GetSelection()
2011 self.EnableForFileType(event.GetString())
2012
2013 def EnableForFileType(self, fileName):
2014 show = fileName.endswith(self._pyext)
2015 self._startEntry.Enable(show)
2016 self._findDir.Enable(show)
2017 self._argsEntry.Enable(show)
2018
2019 if not show:
2020 self._lastStartIn = self._startEntry.GetValue()
2021 self._startEntry.SetValue("")
2022 self._lastArguments = self._argsEntry.GetValue()
2023 self._argsEntry.SetValue("")
2024 else:
2025 self._startEntry.SetValue(self._lastStartIn)
2026 self._argsEntry.SetValue(self._lastArguments)
2027
2028
2029
2030 def OnFindDirClick(self, event):
2031 dlg = wx.DirDialog(self, "Choose a starting directory:", self._startEntry.GetValue(),
2032 style=wx.DD_DEFAULT_STYLE|wx.DD_NEW_DIR_BUTTON)
2033
2034 if dlg.ShowModal() == wx.ID_OK:
2035 self._startEntry.SetValue(dlg.GetPath())
2036
2037 dlg.Destroy()
2038
2039 def EvtListBox(self, event):
2040 if event.GetString():
2041 index = self._projectNameList.index(event.GetString())
2042 self._selectedProjectDocument = self._projectDocumentList[index]
2043 self._selectedProjectIndex = index
2044 self.PopulateFileList(self._selectedProjectDocument)
2045
2046 def FilterFileList(self, list):
2047 if self._pythonOnly:
2048 files = filter(lambda f: f.endswith(self._pyext), list)
2049 else:
2050 files = filter(lambda f: (self._pmext and f.endswith(self._pmext)) or f.endswith(self._pyext), list)
2051 return files
2052
2053 def PopulateFileList(self, project, shortNameToSelect=None):
2054 self._fileNameList = self.FilterFileList(project.GetFiles()[:])
2055 self._fileList.Clear()
2056 if not self._fileNameList:
2057 return
2058 self._fileNameList.sort(lambda a, b: cmp(os.path.basename(a).lower(), os.path.basename(b).lower()))
2059 strings = map(lambda file: os.path.basename(file), self._fileNameList)
2060 for index in range(0, len(strings)):
2061 if shortNameToSelect == strings[index]:
2062 self._selectedFileIndex = index
2063 break
2064 self._fileList.Hide()
2065 self._fileList.AppendItems(strings)
2066 self._fileList.Show()
2067 if self._selectedFileIndex not in range(0, len(strings)) : self._selectedFileIndex = 0
2068 self._fileList.SetSelection(self._selectedFileIndex)
2069 self.EnableForFileType(strings[self._selectedFileIndex])
2070
2071 def GetProjectList(self):
2072 docList = []
2073 nameList = []
2074 found = False
2075 index = -1
2076 count = 0
2077 for document in self._projService.GetDocumentManager().GetDocuments():
2078 if document.GetDocumentTemplate().GetDocumentType() == ProjectEditor.ProjectDocument and len(document.GetFiles()):
2079 docList.append(document)
2080 nameList.append(os.path.basename(document.GetFilename()))
2081 if document == self._currentProj:
2082 found = True
2083 index = count
2084 count += 1
2085 #Check for open files not in any of these projects and add them to a default project
2086 def AlreadyInProject(fileName):
2087 for projectDocument in docList:
2088 if projectDocument.IsFileInProject(fileName):
2089 return True
2090 return False
2091
2092 unprojectedFiles = []
2093 for document in self._projService.GetDocumentManager().GetDocuments():
2094 if not ACTIVEGRID_BASE_IDE and type(document) == ProcessModelEditor.ProcessModelDocument:
2095 if not AlreadyInProject(document.GetFilename()):
2096 unprojectedFiles.append(document.GetFilename())
2097 if type(document) == PythonEditor.PythonDocument:
2098 if not AlreadyInProject(document.GetFilename()):
2099 unprojectedFiles.append(document.GetFilename())
2100
2101 if unprojectedFiles:
2102 unprojProj = ProjectEditor.ProjectDocument()
2103 unprojProj.SetFilename(_("Not in any Project"))
2104 unprojProj.AddFiles(unprojectedFiles)
2105 docList.append(unprojProj)
2106 nameList.append(_("Not in any Project"))
2107
2108 return nameList, docList, index
2109
2110
2111 #----------------------------------------------------------------------
2112 from wx import ImageFromStream, BitmapFromImage
2113 import cStringIO
2114
2115 #----------------------------------------------------------------------
2116 def getBreakData():
2117 return \
2118 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x11\x08\x06\
2119 \x00\x00\x00\xd4\xaf,\xc4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2120 \x00\x00\x97IDAT8\x8d\xbdSA\x0e\xc3 \x0c\x8b\x13\xfe=\x1e^\xe2\x1dF\xbb\x8c\
2121 \xd2\x0c\xa9\xda,q\x88\x05\x8e\x1d\x00P\x93;\xd0[\xa7W\x04\xe8\x8d\x0f\xdfxU\
2122 c%\x02\xbd\xbd\x05HQ+Xv\xb0\xa3VN\xf9\xd4\x01\xbd\x11j\x18\x1d\x00\x10\xa8AD\
2123 \xa4\xa4\xd6_\x9b\x19\xbb\x03\xd8c|\x8f\x00\xe0\x93\xa8g>\x15 C\xee:\xe7\x8f\
2124 \x08\xdesj\xcf\xe6\xde(\xddn\xec\x18f0w\xe0m;\x8d\x9b\xe4\xb1\xd4\n\xa6\x0e2\
2125 \xc4{\x1f\xeb\xdf?\xe5\xff\t\xa8\x1a$\x0cg\xac\xaf\xb0\xf4\x992<\x01\xec\xa0\
2126 U9V\xf9\x18\xc8\x00\x00\x00\x00IEND\xaeB`\x82'
2127
2128 def getBreakBitmap():
2129 return BitmapFromImage(getBreakImage())
2130
2131 def getBreakImage():
2132 stream = cStringIO.StringIO(getBreakData())
2133 return ImageFromStream(stream)
2134
2135 def getBreakIcon():
2136 return wx.IconFromBitmap(getBreakBitmap())
2137
2138 #----------------------------------------------------------------------
2139 def getClearOutputData():
2140 return \
2141 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2142 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2143 \x00\x00\xb4IDAT8\x8d\xa5\x92\xdd\r\x03!\x0c\x83\xbf\xa0n\xd4\x9d\xda5\xb81\
2144 \xbaS\xbb\x12\xee\x03?\xe5\x08\xe5N\xba\xbc Db\xec\xd8p\xb1l\xb8\xa7\x83\xfe\
2145 \xb0\x02H\x92F\xc0_\xa3\x99$\x99\x99\xedznc\xe36\x81\x88\x98"\xb2\x02\xa2\
2146 \x1e\xc4Q\x9aUD\x161\xcd\xde\x1c\x83\x15\x084)\x8d\xc5)\x06\xab\xaaZ\x92\xee\
2147 \xce\x11W\xdbGD\x0cIT\x06\xe7\x00\xdeY\xfe\xcc\x89\x06\xf0\xf2\x99\x00\xe0\
2148 \x91\x7f\xab\x83\xed\xa4\xc8\xafK\x0c\xcf\x92\x83\x99\x8d\xe3p\xef\xe4\xa1\
2149 \x0b\xe57j\xc8:\x06\t\x08\x87.H\xb2n\xa8\xc9\xa9\x12vQ\xfeG"\xe3\xacw\x00\
2150 \x10$M\xd3\x86_\xf0\xe5\xfc\xb4\xfa\x02\xcb\x13j\x10\xc5\xd7\x92D\x00\x00\
2151 \x00\x00IEND\xaeB`\x82'
2152
2153 def getClearOutputBitmap():
2154 return BitmapFromImage(getClearOutputImage())
2155
2156 def getClearOutputImage():
2157 stream = cStringIO.StringIO(getClearOutputData())
2158 return ImageFromStream(stream)
2159
2160 def getClearOutputIcon():
2161 return wx.IconFromBitmap(getClearOutputBitmap())
2162
2163 #----------------------------------------------------------------------
2164 def getCloseData():
2165 return \
2166 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x12\x00\x00\x00\x12\x08\x06\
2167 \x00\x00\x00V\xce\x8eW\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\
2168 \x00\x86IDAT8\x8d\xed\x90\xb1\r\x80 \x10E_"c\xd80\x02-\x138\x87;8\x8f\x8d\
2169 \x8b\xb0\x02\xa5\xad\rS\x88\xcd\x11) \x82\xb6\xbe\xea\xf2\xc9\xbd\xfc\x03~\
2170 \xdeb\x81\xb9\x90\xabJ^%\x00N\x849\x0e\xf0\x85\xbc\x8a\x12YZR2\xc7\x1eIB\xcb\
2171 \xb2\xcb\x9at\x9d\x95c\xa5Y|\x92\x0c\x0f\xa2\r8e\x1e\x81\x1d8z\xdb8\xee?Ig\
2172 \xfa\xb7\x92)\xcb\xacd\x01XZ$QD\xba\xf0\xa6\x80\xd5\x18cZ\x1b\x95$?\x1f\xb9\
2173 \x00\x1d\x94\x1e*e_\x8a~\x00\x00\x00\x00IEND\xaeB`\x82'
2174
2175 def getCloseBitmap():
2176 return BitmapFromImage(getCloseImage())
2177
2178 def getCloseImage():
2179 stream = cStringIO.StringIO(getCloseData())
2180 return ImageFromStream(stream)
2181
2182 def getCloseIcon():
2183 return wx.IconFromBitmap(getCloseBitmap())
2184
2185 #----------------------------------------------------------------------
2186 def getContinueData():
2187 return \
2188 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2189 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2190 \x00\x00\x9eIDAT8\x8d\xbd\x92\xd1\r\x83@\x0cC\xed\x8a\x11X\xac\x1b\xddF,\xd6\
2191 \x11\x90\xdc\x0f\x9a\x93s)\x14Z\xa9\x91\x10\n\x97\xbc\xd89\x80?\x84\x1a\xa4\
2192 \x83\xfc\x1c$\x1e)7\xdf<Y0\xaf\x0b\xe6\xf5\x1d\xa1\xb5\x13C\x03 !\xaa\xfd\
2193 \xed\n:mr\xc0\x1d\x8f\xc9\x9a!\t$\xe5\xd3I\xe2\xe5B$\x99\x00[\x01\xe8\xc5\
2194 \xd9G\xfaN`\xd8\x81I\xed\x8c\xb19\x94\x8d\xcbL\x00;t\xcf\x9fwPh\xdb\x0e\xe8\
2195 \xd3,\x17\x8b\xc7\x9d\xbb>\x8a \xec5\x94\tc\xc4\x12\xab\x94\xeb\x7fkWr\xc9B%\
2196 \xfc\xd2\xfcM<\x01\xf6tn\x12O3c\xe6\x00\x00\x00\x00IEND\xaeB`\x82'
2197
2198 def getContinueBitmap():
2199 return BitmapFromImage(getContinueImage())
2200
2201 def getContinueImage():
2202 stream = cStringIO.StringIO(getContinueData())
2203 return ImageFromStream(stream)
2204
2205 def getContinueIcon():
2206 return wx.IconFromBitmap(getContinueBitmap())
2207
2208 #----------------------------------------------------------------------
2209 def getNextData():
2210 return \
2211 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2212 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2213 \x00\x00\x8eIDAT8\x8d\xa5SA\x12\xc4 \x08K\xb0\xff\xde\xe9\xbf\xb7\xa6\x87\
2214 \x1d:\xba\xa2tZn(\x84`"i\x05obk\x13\xd5CmN+\xcc\x00l\xd6\x0c\x00\xf5\xf8\x0e\
2215 gK\x06\x00 \xa5=k\x00\x00\xb0\xb2]\xd4?5f\xb1\xdb\xaf\xc6\xa2\xcb\xa8\xf0?\
2216 \x1c\x98\xae\x82\xbf\x81\xa4\x8eA\x16\xe1\n\xd1\xa4\x19\xb3\xe9\n\xce\xe8\
2217 \xf1\n\x9eg^\x18\x18\x90\xec<\x11\xf9#\x04XMZ\x19\xaac@+\x94\xd4\x99)SeP\xa1\
2218 )\xd6\x1dI\xe7*\xdc\xf4\x03\xdf~\xe7\x13T^Q?:X\x19d\x00\x00\x00\x00IEND\xaeB\
2219 `\x82'
2220
2221 def getNextBitmap():
2222 return BitmapFromImage(getNextImage())
2223
2224 def getNextImage():
2225 stream = cStringIO.StringIO(getNextData())
2226 return ImageFromStream(stream)
2227
2228 def getNextIcon():
2229 return wx.IconFromBitmap(getNextBitmap())
2230
2231 #----------------------------------------------------------------------
2232 def getStepInData():
2233 return \
2234 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2235 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2236 \x00\x00\x87IDAT8\x8d\xadSA\x12\x84 \x0ck\x8a\xffv\xfc\xb74{X\xeb0P@\x07s\
2237 \x84\xa4$\x01\x00M\xb2\x02]R\x8b\xc86\xda\xdc\xedd\xb4~\xe8\x86\xc6\x01-\x93\
2238 \x96\xd9#\xf6\x06\xc3;p1I\xd1\x14\x0b#|\x17aF\xec\r\xeeF\xa0eB\xd34\xca\xd0A\
2239 ]j\x84\xa6\x03\x00""\xb7\xb0tRZ\xf7x\xb7\x83\x91]\xcb\x7fa\xd9\x89\x0fC\xfd\
2240 \x94\x9d|9\x99^k\x13\xa1 \xb3\x16\x0f#\xd4\x88N~\x14\xe1-\x96\x7f\xe3\x0f\
2241 \x11\x91UC\x0cX\'\x1e\x00\x00\x00\x00IEND\xaeB`\x82'
2242
2243 def getStepInBitmap():
2244 return BitmapFromImage(getStepInImage())
2245
2246 def getStepInImage():
2247 stream = cStringIO.StringIO(getStepInData())
2248 return ImageFromStream(stream)
2249
2250 def getStepInIcon():
2251 return wx.IconFromBitmap(getStepInBitmap())
2252
2253 #----------------------------------------------------------------------
2254 def getStopData():
2255 return \
2256 "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2257 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2258 \x00\x00FIDAT8\x8d\xed\x91\xc1\t\xc00\x0c\x03O!\x0b\xa9\xfb\xef\xa6\xfcB\xa1\
2259 N\t\xf4Wr\xa0\x8f\xb1\x0f\x81\xe1\x97\xe4-\xb6}_V%\xc8\xc2, \t\x92\xe6]\xfbZ\
2260 \xf7\x08\xa0W\xc3\xea5\xdb\rl_IX\xe5\xf0d\x00\xfa\x8d#\x7f\xc4\xf7'\xab\x00\
2261 \x00\x00\x00IEND\xaeB`\x82"
2262
2263 def getStopBitmap():
2264 return BitmapFromImage(getStopImage())
2265
2266 def getStopImage():
2267 stream = cStringIO.StringIO(getStopData())
2268 return ImageFromStream(stream)
2269
2270 def getStopIcon():
2271 return wx.IconFromBitmap(getStopBitmap())
2272
2273 #----------------------------------------------------------------------
2274 def getStepReturnData():
2275 return \
2276 "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2277 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2278 \x00\x00\x8dIDAT8\x8d\xa5S\xd1\x0e\xc4 \x08\xa3\xb0\xff\xbe\xdc\x7fO\xba'6\
2279 \xf1\xf44\xb3O$Phk\x04\xd4d\x07\xba\xc5\x16\x91#\nza\xdb\x84\x1a\xa2\xfe\xf8\
2280 \x99\xfa_=p+\xe8\x91ED\xbc<\xa4 \xb4\x0b\x01\xb5{\x01\xf9\xbbG-\x13\x87\x16f\
2281 \x84\xbf\x16V\xb0l\x01@\no\x86\xae\x82Q\xa8=\xa4\x0c\x80\xe70\xbd\x10jh\xbd\
2282 \x07R\x06#\xc9^N\xb6\xde\x03)\x83\x18\xaeU\x90\x9c>a\xb2P\r\xb3&/Y\xa8\xd1^^\
2283 \xb6\xf0\x16\xdb\xbf\xf1\x02\x81\xa5TK\x1d\x07\xde\x92\x00\x00\x00\x00IEND\
2284 \xaeB`\x82"
2285
2286 def getStepReturnBitmap():
2287 return BitmapFromImage(getStepReturnImage())
2288
2289 def getStepReturnImage():
2290 stream = cStringIO.StringIO(getStepReturnData())
2291 return ImageFromStream(stream)
2292
2293 def getStepReturnIcon():
2294 return wx.IconFromBitmap(getStepReturnBitmap())
2295
2296 #----------------------------------------------------------------------
2297 def getAddWatchData():
2298 return \
2299 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2300 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2301 \x00\x00\x85IDAT8\x8dc`\x18h\xc0\x88.\xd0\xc0\xf0\xff?*\x9f\x11C\rN\x80\xae\
2302 \x19\x97\x18\xd1\x9a\x896\x84\x18[p\xa9aA\xe6\xfc7f\xc0P\xc4x\x163\x9cp\x1a0\
2303 \xeb,!w\x100 \x1dK\xac\x10\r\x08\x05".yFL\x85\x8c\x18b\xa8|Ty\xa2\x13\x92\'\
2304 \xc3\xe4\xff\x9f\x18\x1e3\xb82t\xa2\x88\x13\xedg.\x06aa&\x06VV\x7f\x86\xb9\
2305 \xcfU\x19\xbc\xb0\xba\x86h\xe0\xc8\xd0\xfc\xbf\x80\xe1>q)\x94\xe6\x00\x00\
2306 \x85\x923_\xd22\xa4\xcd\x00\x00\x00\x00IEND\xaeB`\x82'
2307
2308 def getAddWatchBitmap():
2309 return BitmapFromImage(getAddWatchImage())
2310
2311 def getAddWatchImage():
2312 stream = cStringIO.StringIO(getAddWatchData())
2313 return ImageFromStream(stream)
2314
2315 def getAddWatchIcon():
2316 return wx.IconFromBitmap(getAddWatchBitmap())