1 #----------------------------------------------------------------------------
2 # Name: DebuggerService.py
3 # Purpose: Debugger Service for Python.
9 # Copyright: (c) 2004-2005 ActiveGrid, Inc.
10 # License: wxWindows License
11 #----------------------------------------------------------------------------
19 import wx
.lib
.pydocview
24 from IDE
import ACTIVEGRID_BASE_IDE
25 if not ACTIVEGRID_BASE_IDE
:
26 import ProcessModelEditor
27 import wx
.lib
.scrolledpanel
as scrolled
30 import SimpleXMLRPCServer
39 from xml
.dom
.minidom
import parse
, parseString
42 import DebuggerHarness
45 if wx
.Platform
== '__WXMSW__':
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
59 class OutputReaderThread(threading
.Thread
):
60 def __init__(self
, file, callback_function
, callbackOnExit
=None, accumulate
=True):
61 threading
.Thread
.__init
__(self
)
63 self
._callback
_function
= callback_function
64 self
._keepGoing
= True
66 self
._accumulate
= accumulate
67 self
._callbackOnExit
= callbackOnExit
73 while self
._keepGoing
:
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
)
82 # Should use a buffer? StringIO?
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
)
91 elif time
.time() - start
> 0.25:
93 self
._callback
_function
(output
)
94 except wx
._core
.PyDeadObjectError
:
95 # GUI was killed while we were blocked.
96 self
._keepGoing
= False
100 tp
, val
, tb
= sys
.exc_info()
101 print "Exception in OutputReaderThread.run():", tp
, val
102 self
._keepGoing
= False
103 if self
._callbackOnExit
:
105 self
._callbackOnExit
()
106 except wx
._core
.PyDeadObjectError
:
108 if _VERBOSE
: print "Exiting OutputReaderThread"
111 self
._keepGoing
= False
113 import wx
.lib
.newevent
114 (UpdateTextEvent
, EVT_UPDATE_STDTEXT
) = wx
.lib
.newevent
.NewEvent()
115 (UpdateErrorEvent
, EVT_UPDATE_ERRTEXT
) = wx
.lib
.newevent
.NewEvent()
119 def GetPythonExecutablePath():
120 config
= wx
.ConfigBase_Get()
121 path
= config
.Read("ActiveGridPythonLocation")
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"))
126 GetPythonExecutablePath
= staticmethod(GetPythonExecutablePath
)
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.
138 self
._cmd
+= ' \"' + arg1
+ '\"'
140 self
._cmd
+= ' \"' + arg2
+ '\"'
142 self
._cmd
+= ' \"' + arg3
+ '\"'
144 self
._cmd
+= ' \"' + arg4
+ '\"'
146 self
._cmd
+= ' \"' + arg5
+ '\"'
148 self
._cmd
+= ' \"' + arg6
+ '\"'
150 self
._cmd
+= ' \"' + arg7
+ '\"'
152 self
._cmd
+= ' \"' + arg8
+ '\"'
154 self
._cmd
+= ' \"' + arg9
+ '\"'
156 self
._stdOutReader
= None
157 self
._stdErrReader
= None
160 def OutCall(self
, text
):
161 evt
= UpdateTextEvent(value
= text
)
162 wx
.PostEvent(self
._wxComponent
, evt
)
164 def ErrCall(self
, text
):
165 evt
= UpdateErrorEvent(value
= text
)
166 wx
.PostEvent(self
._wxComponent
, evt
)
168 def Execute(self
, arguments
, startIn
=None, environment
=None):
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()
184 def DoStopExecution(self
):
185 if(self
._process
!= None):
187 self
._process
.close()
189 if(self
._stdOutReader
!= None):
190 self
._stdOutReader
.AskToStop()
191 if(self
._stdErrReader
!= None):
192 self
._stdErrReader
.AskToStop()
194 class RunCommandUI(wx
.Panel
):
196 def __init__(self
, parent
, id, fileName
):
197 wx
.Panel
.__init
__(self
, parent
, id)
198 self
._noteBook
= parent
200 self
.KILL_PROCESS_ID
= wx
.NewId()
201 self
.CLOSE_TAB_ID
= wx
.NewId()
203 self
.Bind(wx
.EVT_END_PROCESS
, self
.OnProcessEnded
)
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)
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
)
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
)
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__':
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()
232 #Disabling for now...may interfere with file open. wx.stc.EVT_STC_DOUBLECLICK(self._textCtrl, self._textCtrl.GetId(), self.OnDoubleClick)
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
)
243 self
._executor
.DoStopExecution()
245 def Execute(self
, initialArgs
, startIn
, environment
):
246 self
._executor
.Execute(initialArgs
, startIn
, environment
)
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
)
258 def StopExecution(self
):
259 self
.Unbind(EVT_UPDATE_STDTEXT
)
260 self
.Unbind(EVT_UPDATE_ERRTEXT
)
261 self
._executor
.DoStopExecution()
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)
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)
279 #------------------------------------------------------------------------------
281 #-----------------------------------------------------------------------------
283 def OnToolClicked(self
, event
):
286 if id == self
.KILL_PROCESS_ID
:
287 self
._executor
.DoStopExecution()
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
)
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()
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:
313 filename
= lineText
[fileBegin
+ 6:fileEnd
]
314 lineNum
= int(lineText
[fileEnd
+ 8:lineEnd
])
317 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
318 for openDoc
in openDocs
:
319 if openDoc
.GetFilename() == filename
:
320 foundView
= openDoc
.GetFirstView()
324 doc
= wx
.GetApp().GetDocumentManager().CreateDocument(filename
, wx
.lib
.docview
.DOC_SILENT
)
325 foundView
= doc
.GetFirstView()
328 foundView
.GetFrame().SetFocus()
330 foundView
.GotoLine(lineNum
)
331 startPos
= foundView
.PositionFromLine(lineNum
)
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()
339 foundView
.GetCtrl().MarkerAdd(lineNum
-1, CodeEditor
.CodeCtrl
.CURRENT_LINE_MARKER_NUM
)
341 def OnProcessEnded(self
, evt
):
342 self
._executor
.DoStopExecution()
345 DEFAULT_HOST
= 'localhost'
348 class DebugCommandUI(wx
.Panel
):
349 debuggerPortList
= None
352 def NotifyDebuggersOfBreakpointChange():
353 for debugger
in DebugCommandUI
.debuggers
:
354 debugger
.BreakPointChange()
356 NotifyDebuggersOfBreakpointChange
= staticmethod(NotifyDebuggersOfBreakpointChange
)
358 def DebuggerRunning():
359 for debugger
in DebugCommandUI
.debuggers
:
360 if debugger
._executor
:
363 DebuggerRunning
= staticmethod(DebuggerRunning
)
365 def ShutdownAllDebuggers():
366 for debugger
in DebugCommandUI
.debuggers
:
367 debugger
.StopExecution()
369 ShutdownAllDebuggers
= staticmethod(ShutdownAllDebuggers
)
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
)
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."
380 GetAvailablePort
= staticmethod(GetAvailablePort
)
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
)
388 ReturnPortToPool
= staticmethod(ReturnPortToPool
)
390 def PortAvailable(port
):
391 config
= wx
.ConfigBase_Get()
392 hostname
= config
.Read("DebuggerHostName", DEFAULT_HOST
)
394 server
= AGXMLRPCServer((hostname
, port
))
395 server
.server_close()
396 if _VERBOSE
: print "Port ", str(port
), " available."
399 tp
,val
,tb
= sys
.exc_info()
400 if _VERBOSE
: traceback
.print_exception(tp
, val
, tb
)
401 if _VERBOSE
: print "Port ", str(port
), " unavailable."
404 PortAvailable
= staticmethod(PortAvailable
)
407 config
= wx
.ConfigBase_Get()
408 startingPort
= config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
)
409 DebugCommandUI
.debuggerPortList
= range(startingPort
, startingPort
+ PORT_COUNT
)
410 NewPortRange
= staticmethod(NewPortRange
)
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())
420 wx
.Panel
.__init
__(self
, parent
, id)
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))
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
)
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
)
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
)
457 continue_bmp
= getContinueBitmap()
458 tb
.AddSimpleTool( self
.CONTINUE_ID
, continue_bmp
, _("Continue Execution"))
459 wx
.EVT_TOOL(self
, self
.CONTINUE_ID
, self
.OnContinue
)
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
)
467 step_bmp
= getStepInBitmap()
468 tb
.AddSimpleTool( self
.STEP_ID
, step_bmp
, _("Step in"))
469 wx
.EVT_TOOL(self
, self
.STEP_ID
, self
.OnSingleStep
)
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
)
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
)
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
)
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")
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)
502 self
.SetStatusText("Starting debug...")
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:
513 fname
= DebuggerHarness
.__file
__
514 parts
= fname
.split('library.zip')
515 path
= os
.path
.join(parts
[0],'activegrid', 'tool', 'DebuggerHarness.py')
517 tp
, val
, tb
= sys
.exc_info()
518 traceback
.print_exception(tp
, val
, tb
)
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
)
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
531 def OnSingleStep(self
, event
):
532 self
._callback
.SingleStep()
534 def OnContinue(self
, event
):
535 self
._callback
.Continue()
537 def OnStepOut(self
, event
):
538 self
._callback
.Return()
540 def OnNext(self
, event
):
541 self
._callback
.Next()
543 def BreakPointChange(self
):
544 if not self
._stopped
:
545 self
._callback
.pushBreakpoints()
546 self
.breakPointsTab
.PopulateBPList()
549 if self
in DebugCommandUI
.debuggers
:
550 DebugCommandUI
.debuggers
.remove(self
)
552 def SwitchToOutputTab(self
):
553 self
._notebook
.SetSelection(0)
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)
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()
568 self
.framesTab
.ClearWhileRunning()
569 #wx.GetApp().ProcessPendingEvents() #Yield(True)
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)
577 self
._tb
.EnableTool(self
.ADD_WATCH_ID
, True)
578 self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, False)
580 # wx.GetApp().GetTopWindow().RequestUserAttention()
582 def ExecutorFinished(self
):
583 if _VERBOSE
: print "In ExectorFinished"
585 self
.DisableAfterStop()
586 except wx
._core
.PyDeadObjectError
:
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."
598 if _VERBOSE
: print "In ExectorFinished, got exception"
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)
605 def SynchCurrentLine(self
, filename
, lineNum
):
606 # FACTOR THIS INTO DocManager
607 self
.DeleteCurrentLineMarkers()
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
612 if filename
== '<string>':
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()
626 print "filename=", filename
627 doc
= wx
.GetApp().GetDocumentManager().CreateDocument(DebuggerService
.ExpandPath(filename
), wx
.lib
.docview
.DOC_SILENT
)
628 foundView
= doc
.GetFirstView()
631 foundView
.GetFrame().SetFocus()
633 foundView
.GotoLine(lineNum
)
634 startPos
= foundView
.PositionFromLine(lineNum
)
636 foundView
.GetCtrl().MarkerAdd(lineNum
-1, CodeEditor
.CodeCtrl
.CURRENT_LINE_MARKER_NUM
)
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()
644 def LoadFramesListXML(self
, framesXML
):
645 self
.framesTab
.LoadFramesListXML(framesXML
)
647 def SetStatusText(self
, text
):
648 self
._statusBar
.SetStatusText(text
,0)
650 def Execute(self
, initialArgs
, startIn
, environment
):
651 self
._callback
.start()
652 self
._executor
.Execute(initialArgs
, startIn
, environment
)
653 self
._callback
.waitForRPC()
655 def BreakExecution(self
, event
):
656 self
._callback
.BreakExecution()
659 def StopExecution(self
, event
):
661 self
.DisableAfterStop()
663 self
._callback
.ServerClose()
668 self
._executor
.DoStopExecution()
669 self
._executor
= None
672 self
.DeleteCurrentLineMarkers()
673 DebugCommandUI
.ReturnPortToPool(self
._debuggerPort
)
674 DebugCommandUI
.ReturnPortToPool(self
._guiPort
)
675 DebugCommandUI
.ReturnPortToPool(self
._debuggerBreakPort
)
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
)
685 def GetConsoleTextControl(self
):
686 return self
._textCtrl
688 def OnClearOutput(self
, event
):
689 self
._textCtrl
.SetReadOnly(False)
690 self
._textCtrl
.ClearAll()
691 self
._textCtrl
.SetReadOnly(True)
693 def OnAddWatch(self
, event
):
695 self
.framesTab
.OnWatch(event
)
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__':
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
)
716 def MakeFramesTab(self
, parent
, id, debugger
):
717 panel
= FramesUI(parent
, id, self
)
720 def MakeBreakPointsTab(self
, parent
, id, debugger
):
721 panel
= BreakpointsUI(parent
, id, self
)
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)
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)
740 class BreakpointsUI(wx
.Panel
):
741 def __init__(self
, parent
, id, ui
):
742 wx
.Panel
.__init
__(self
, parent
, id)
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
)
750 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
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
)
764 self
.PopulateBPList()
770 def PopulateBPList(self
):
771 list = self
._bpListCtrl
772 list.DeleteAllItems()
774 bps
= wx
.GetApp().GetService(DebuggerService
).GetMasterBreakpointDict()
776 for fileName
in bps
.keys():
777 shortFile
= os
.path
.basename(fileName
)
778 lines
= bps
[fileName
]
781 list.InsertStringItem(index
, shortFile
)
782 list.SetStringItem(index
, 1, str(line
))
783 list.SetStringItem(index
, 2, fileName
)
785 def OnListRightClick(self
, event
):
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())
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
) )
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
)
808 def ListItemSelected(self
, event
):
809 self
.currentItem
= event
.m_itemIndex
811 def ListItemDeselected(self
, event
):
812 self
.currentItem
= -1
820 def __init__(self
, name
, command
, show_code
=CODE_ALL_FRAMES
):
822 self
._command
= command
823 self
._show
_code
= show_code
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
)
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
)
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"))
846 if self
._watchValueTextCtrl
.GetValue() == "":
847 wx
.MessageBox(_("You must enter some code to run for the watch."), _("Add Watch"))
849 self
.EndModal(wx
.ID_OK
)
850 self
.Bind(wx
.EVT_BUTTON
, OnOkClick
, self
._okButton
)
852 self
._cancelButton
= wx
.Button(self
, wx
.ID_CANCEL
, _("Cancel"), size
=(75,-1))
853 self
._cancelButton
.SetHelpText(_("The Cancel button cancels the dialog."))
855 self
.__set
_properties
()
858 def GetSettings(self
):
859 return self
._watchNameTextCtrl
.GetValue(), self
._watchValueTextCtrl
.GetValue(), self
.GetSendFrame(), self
.GetRunOnce()
861 def GetSendFrame(self
):
862 return (WatchDialog
.WATCH_ALL_FRAMES
!= self
.radio_box_1
.GetStringSelection())
864 def GetRunOnce(self
):
865 return (WatchDialog
.WATCH_ONCE
== self
.radio_box_1
.GetStringSelection())
867 def __set_properties(self
):
868 self
.SetTitle("Add a Watch")
869 #self.SetSize((400, 250))
870 self
.radio_box_1
.SetSelection(0)
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)
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
)
895 class FramesUI(wx
.SplitterWindow
):
896 def __init__(self
, parent
, id, ui
):
897 wx
.SplitterWindow
.__init
__(self
, parent
, id, style
= wx
.SP_3D
)
899 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
900 self
._p
1 = p1
= wx
.ScrolledWindow(self
, -1)
901 p1
.Bind(wx
.EVT_SIZE
, self
.OnSize
)
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
)
911 sizer2
= wx
.BoxSizer(wx
.VERTICAL
)
912 self
._p
2 = p2
= wx
.ScrolledWindow(self
, -1)
913 p2
.Bind(wx
.EVT_SIZE
, self
.OnSize
)
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)
927 self
.SetMinimumPaneSize(20)
928 self
.SplitVertically(p1
, p2
, 250)
929 self
.currentItem
= None
932 def OnRightClick(self
, event
):
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
:
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()
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()
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
)
964 self
._parentChain
= None
965 self
._introspectItem
= None
967 def GetItemChain(self
, 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()
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
)
985 def OnWatch(self
, event
):
987 if hasattr(self
, '_parentChain'):
988 wd
= WatchDialog(wx
.GetApp().GetTopWindow(), "Add a Watch", self
._parentChain
)
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()
994 frameNode
= self
._stack
[int(self
.currentItem
)]
995 message
= frameNode
.getAttribute("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")
1005 tp
, val
, tb
= sys
.exc_info()
1006 traceback
.print_exception(tp
, val
, tb
)
1008 def OnIntrospect(self
, event
):
1009 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
))
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
)
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
)
1028 tp
,val
,tb
= sys
.exc_info()
1029 traceback
.print_exception(tp
, val
, tb
)
1031 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
))
1033 def OnSize(self
, event
):
1034 self
._treeCtrl
.SetSize(self
._p
2.GetSize())
1035 w
,h
= self
._p
1.GetClientSizeTuple()
1036 self
._framesListCtrl
.SetDimensions(0, 0, w
, h
)
1038 def ClearWhileRunning(self
):
1039 list = self
._framesListCtrl
1040 list.DeleteAllItems()
1041 tree
= self
._treeCtrl
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
)
1049 item
= wx
.MenuItem(menu
, self
.syncFrameID
, "Goto Source Line")
1050 menu
.AppendItem(item
)
1051 self
.PopupMenu(menu
, event
.GetPosition())
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
) )
1061 def LoadFramesListXML(self
, framesXML
):
1062 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
))
1064 domDoc
= parseString(framesXML
)
1065 list = self
._framesListCtrl
1066 list.DeleteAllItems()
1068 nodeList
= domDoc
.getElementsByTagName('frame')
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
)
1076 list.Select(frame_count
)
1077 self
._p
1.FitInside()
1078 frameNode
= nodeList
.item(index
)
1079 file = frameNode
.getAttribute("file")
1080 line
= frameNode
.getAttribute("line")
1081 self
._ui
.SynchCurrentLine( file, int(line
) )
1083 tp
,val
,tb
=sys
.exc_info()
1084 traceback
.print_exception(tp
, val
, tb
)
1086 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
))
1088 def ListItemDeselected(self
, event
):
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)
1098 def PopulateTreeFromFrameNode(self
, frameNode
):
1099 tree
= self
._treeCtrl
1102 tree
.DeleteChildren(root
)
1103 children
= frameNode
.childNodes
1105 for index
in range(0, children
.length
):
1106 subNode
= children
.item(index
)
1107 treeNode
= self
.AppendSubTreeFromNode(subNode
, subNode
.getAttribute('name'), root
)
1109 firstChild
= treeNode
1111 tree
.Expand(firstChild
)
1112 self
._p
2.FitInside()
1114 def AppendSubTreeFromNode(self
, node
, name
, parent
, insertBefore
=None):
1115 tree
= self
._treeCtrl
1116 if insertBefore
!= None:
1117 treeNode
= tree
.InsertItem(parent
, insertBefore
, name
)
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
)
1128 name
= subNode
.getAttribute("name")
1129 value
= self
.StripOuterSingleQuotes(subNode
.getAttribute("value"))
1130 n
= tree
.AppendItem(treeNode
, name
)
1131 tree
.SetItemText(n
, value
, 1)
1134 def StripOuterSingleQuotes(self
, string
):
1135 if string
.startswith("'") and string
.endswith("'"):
1137 elif type(string
) == types
.UnicodeType
:
1142 def HasChildren(self
, node
):
1144 return node
.childNodes
.length
> 0
1146 tp
,val
,tb
=sys
.exc_info()
1149 class DebuggerView(Service
.ServiceView
):
1151 #----------------------------------------------------------------------------
1152 # Overridden methods
1153 #----------------------------------------------------------------------------
1155 def __init__(self
, service
):
1156 Service
.ServiceView
.__init
__(self
, service
)
1158 def _CreateControl(self
, parent
, id):
1161 #------------------------------------------------------------------------------
1163 #-----------------------------------------------------------------------------
1165 def OnToolClicked(self
, event
):
1166 self
.GetFrame().ProcessEvent(event
)
1168 #------------------------------------------------------------------------------
1170 #-----------------------------------------------------------------------------
1173 def __init__(self
, message
, framesXML
, info
=None, quit
=False):
1174 self
._framesXML
= framesXML
1175 self
._message
= message
1179 def getFramesXML(self
):
1180 return self
._framesXML
1182 def getMessage(self
):
1183 return self
._message
1191 class AGXMLRPCServer(SimpleXMLRPCServer
.SimpleXMLRPCServer
):
1192 def __init__(self
, address
, logRequests
=0):
1193 SimpleXMLRPCServer
.SimpleXMLRPCServer
.__init
__(self
, address
, logRequests
=logRequests
)
1195 class RequestHandlerThread(threading
.Thread
):
1196 def __init__(self
, queue
, address
):
1197 threading
.Thread
.__init
__(self
)
1198 self
._keepGoing
= True
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())
1208 while self
._keepGoing
:
1210 self
._server
.handle_request()
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."
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
)
1224 interaction
= Interaction(None, None, info
=None, quit
=True)
1225 self
._queue
.put(interaction
)
1228 def dummyOperation(self
):
1231 def AskToStop(self
):
1232 self
._keepGoing
= False
1233 if type(self
._server
) is not types
.NoneType
:
1235 # This is a really ugly way to make sure this thread isn't blocked in
1237 url
= 'http://' + self
._address
[0] + ':' + str(self
._address
[1]) + '/'
1238 tempServer
= xmlrpclib
.ServerProxy(url
, allow_none
=1)
1239 tempServer
.dummyOperation()
1241 tp
, val
, tb
= sys
.exc_info()
1242 traceback
.print_exception(tp
, val
, tb
)
1243 self
._server
.server_close()
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
1251 self
._interrupt
= interrupt
1252 self
._pushBreakpoints
= pushBreakpoints
1253 self
._breakDict
= breakDict
1258 if _VERBOSE
: print "RequestBreakThread, before call"
1260 self
._server
.break_requested()
1261 if self
._pushBreakpoints
:
1262 self
._server
.update_breakpoints(xmlrpclib
.Binary(pickle
.dumps(self
._breakDict
)))
1268 if _VERBOSE
: print "RequestBreakThread, after call"
1270 tp
,val
,tb
= sys
.exc_info()
1271 traceback
.print_exception(tp
, val
, tb
)
1273 class DebuggerOperationThread(threading
.Thread
):
1274 def __init__(self
, function
):
1275 threading
.Thread
.__init
__(self
)
1276 self
._function
= function
1279 if _VERBOSE
: print "In DOT, before call"
1283 tp
,val
,tb
= sys
.exc_info()
1284 traceback
.print_exception(tp
, val
, tb
)
1285 if _VERBOSE
: print "In DOT, after call"
1287 class DebuggerCallback
:
1289 def __init__(self
, host
, port
, debugger_url
, break_url
, debuggerUI
):
1290 if _VERBOSE
: print "+++++++ Creating server on port, ", str(port
)
1292 self
._queue
= Queue
.Queue(50)
1294 self
._port
= int(port
)
1295 threading
._VERBOSE
= _VERBOSE
1296 self
._serverHandlerThread
= RequestHandlerThread(self
._queue
, (self
._host
, self
._port
))
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
1309 self
._serverHandlerThread
.start()
1311 def ServerClose(self
):
1312 rbt
= RequestBreakThread(self
._breakServer
, kill
=True)
1314 self
.setWaiting(False)
1315 if self
._serverHandlerThread
:
1316 self
._serverHandlerThread
.AskToStop()
1317 self
._serverHandlerThread
= None
1319 def BreakExecution(self
):
1320 rbt
= RequestBreakThread(self
._breakServer
, interrupt
=True)
1323 def SingleStep(self
):
1324 self
._debuggerUI
.DisableWhileDebuggerRunning()
1325 #dot = DebuggerOperationThread(self._debuggerServer.set_step)
1327 self
._debuggerServer
.set_step() # Figure out where to set allowNone
1331 self
._debuggerUI
.DisableWhileDebuggerRunning()
1332 #dot = DebuggerOperationThread(self._debuggerServer.set_next)
1334 self
._debuggerServer
.set_next()
1338 self
._debuggerUI
.DisableWhileDebuggerRunning()
1339 #dot = DebuggerOperationThread(self._debuggerServer.set_continue)
1341 self
._debuggerServer
.set_continue()
1345 self
._debuggerUI
.DisableWhileDebuggerRunning()
1346 #dot = DebuggerOperationThread(self._debuggerServer.set_return)
1348 self
._debuggerServer
.set_return()
1351 def setWaiting(self
, value
):
1352 self
._waiting
= value
1354 def getWaiting(self
):
1355 return self
._waiting
1357 def readQueue(self
):
1358 if self
._queue
.qsize():
1360 item
= self
._queue
.get_nowait()
1362 self
.interaction(None, None, None, True)
1364 data
= bz2
.decompress(item
.getFramesXML().data
)
1365 self
.interaction(item
.getMessage().data
, data
, item
.getInfo(), False)
1369 def pushBreakpoints(self
):
1370 rbt
= RequestBreakThread(self
._breakServer
, pushBreakpoints
=True, breakDict
=self
._service
.GetMasterBreakpointDict())
1374 def waitForRPC(self
):
1375 self
.setWaiting(True)
1376 while self
.getWaiting():
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."
1387 def interaction(self
, message
, frameXML
, info
, quit
):
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
1398 self
._debuggerUI
.StopExecution(None)
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()
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
1412 class DebuggerService(Service
.Service
):
1414 #----------------------------------------------------------------------------
1416 #----------------------------------------------------------------------------
1417 TOGGLE_BREAKPOINT_ID
= wx
.NewId()
1418 CLEAR_ALL_BREAKPOINTS
= wx
.NewId()
1420 DEBUG_ID
= wx
.NewId()
1421 DEBUG_WEBSERVER_ID
= wx
.NewId()
1423 def ComparePaths(first
, second
):
1424 one
= DebuggerService
.ExpandPath(first
)
1425 two
= DebuggerService
.ExpandPath(second
)
1427 return one
.lower() == two
.lower()
1430 ComparePaths
= staticmethod(ComparePaths
)
1432 # Make sure we're using an expanded path on windows.
1433 def ExpandPath(path
):
1436 return win32api
.GetLongPathName(path
)
1438 print "Cannot get long path for %s" % path
1442 ExpandPath
= staticmethod(ExpandPath
)
1444 #----------------------------------------------------------------------------
1445 # Overridden methods
1446 #----------------------------------------------------------------------------
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
)
1455 self
._masterBPDict
= pickle
.loads(pickledbps
.encode('ascii'))
1457 tp
, val
, tb
= sys
.exc_info()
1458 traceback
.print_exception(tp
,val
,tb
)
1459 self
._masterBPDict
= {}
1461 self
._masterBPDict
= {}
1463 def OnCloseFrame(self
, event
):
1464 # IS THIS THE RIGHT PLACE?
1466 config
= wx
.ConfigBase_Get()
1467 config
.Write(self
.BREAKPOINT_DICT_STRING
, pickle
.dumps(self
._masterBPDict
))
1469 tp
,val
,tb
= sys
.exc_info()
1470 traceback
.print_exception(tp
, val
, tb
)
1473 def _CreateView(self
):
1474 return DebuggerView(self
)
1477 #----------------------------------------------------------------------------
1478 # Service specific methods
1479 #----------------------------------------------------------------------------
1481 def InstallControls(self
, frame
, menuBar
= None, toolBar
= None, statusBar
= None, document
= None):
1482 #Service.Service.InstallControls(self, frame, menuBar, toolBar, statusBar, document)
1484 config
= wx
.ConfigBase_Get()
1486 debuggerMenu
= wx
.Menu()
1487 if not menuBar
.FindItemById(DebuggerService
.CLEAR_ALL_BREAKPOINTS
):
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
)
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
)
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
)
1503 debuggerMenu
.AppendSeparator()
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
)
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
)
1514 viewMenuIndex
= menuBar
.FindMenu(_("&Project"))
1515 menuBar
.Insert(viewMenuIndex
+ 1, debuggerMenu
, _("&Run"))
1521 #----------------------------------------------------------------------------
1522 # Event Processing Methods
1523 #----------------------------------------------------------------------------
1525 def ProcessEventBeforeWindows(self
, event
):
1529 def ProcessEvent(self
, event
):
1530 if Service
.Service
.ProcessEvent(self
, event
):
1533 an_id
= event
.GetId()
1534 if an_id
== DebuggerService
.TOGGLE_BREAKPOINT_ID
:
1535 self
.OnToggleBreakpoint(event
)
1537 elif an_id
== DebuggerService
.CLEAR_ALL_BREAKPOINTS
:
1538 self
.ClearAllBreakpoints()
1540 elif an_id
== DebuggerService
.RUN_ID
:
1541 self
.OnRunProject(event
)
1543 elif an_id
== DebuggerService
.DEBUG_ID
:
1544 self
.OnDebugProject(event
)
1546 elif an_id
== DebuggerService
.DEBUG_WEBSERVER_ID
:
1547 self
.OnDebugWebServer(event
)
1551 def ProcessUpdateUIEvent(self
, event
):
1552 if Service
.Service
.ProcessUpdateUIEvent(self
, event
):
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
))
1560 elif an_id
== DebuggerService
.CLEAR_ALL_BREAKPOINTS
:
1561 event
.Enable(self
.HasBreakpointsSet())
1563 elif an_id
== DebuggerService
.RUN_ID
:
1564 event
.Enable(self
.HasAnyFiles())
1566 elif an_id
== DebuggerService
.DEBUG_ID
:
1567 event
.Enable(self
.HasAnyFiles())
1572 #----------------------------------------------------------------------------
1574 #----------------------------------------------------------------------------
1576 def OnDebugProject(self
, event
):
1577 if not Executor
.GetPythonExecutablePath():
1579 if DebugCommandUI
.DebuggerRunning():
1580 wx
.MessageBox(_("A debugger is already running. Please shut down the other debugger first."), _("Debugger Running"))
1582 self
.ShowWindow(True)
1583 projectService
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
)
1584 project
= projectService
.GetView().GetDocument()
1586 dlg
= CommandPropertiesDialog(self
.GetView().GetFrame(), 'Debug Python File', projectService
, None, pythonOnly
=True, okButtonName
="Debug", debugging
=True)
1589 if dlg
.ShowModal() == wx
.ID_OK
:
1590 fileToDebug
, initialArgs
, startIn
, isPython
, environment
= dlg
.GetSettings()
1595 self
.PromptToSaveFiles()
1597 shortFile
= os
.path
.basename(fileToDebug
)
1598 fileToDebug
= DebuggerService
.ExpandPath(fileToDebug
)
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
)
1608 def OnDebugWebServer(self
, event
):
1609 import WebServerService
1610 wsService
= wx
.GetApp().GetService(WebServerService
.WebServerService
)
1611 fileName
, args
= wsService
.StopAndPrepareToDebug()
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
)
1622 def HasAnyFiles(self
):
1623 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1624 return len(docs
) > 0
1626 def PromptToSaveFiles(self
, running
=True):
1627 filesModified
= False
1628 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1630 if doc
.IsModified():
1631 filesModified
= True
1634 frame
= self
.GetView().GetFrame()
1636 yesNoMsg
= wx
.MessageDialog(frame
,
1637 _("Files have been modified.\nWould you like to save all files before running?"),
1642 yesNoMsg
= wx
.MessageDialog(frame
,
1643 _("Files have been modified.\nWould you like to save all files before debugging?"),
1647 if yesNoMsg
.ShowModal() == wx
.ID_YES
:
1648 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1653 DebugCommandUI
.ShutdownAllDebuggers()
1655 def OnRunProject(self
, event
):
1656 if not Executor
.GetPythonExecutablePath():
1658 projectService
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
)
1659 project
= projectService
.GetView().GetDocument()
1661 dlg
= CommandPropertiesDialog(self
.GetView().GetFrame(), 'Run', projectService
, None)
1664 if dlg
.ShowModal() == wx
.ID_OK
:
1665 fileToRun
, initialArgs
, startIn
, isPython
, environment
= dlg
.GetSettings()
1672 self
.PromptToSaveFiles()
1673 # This will need to change when we can run more than .py and .bpel files.
1675 projectService
.RunProcessModel(fileToRun
)
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
)
1686 def OnToggleBreakpoint(self
, event
, line
=-1, fileName
=None):
1688 view
= wx
.GetApp().GetDocumentManager().GetCurrentView()
1689 # Test to make sure we aren't the project view.
1690 if not hasattr(view
, 'MarkerExists'):
1692 fileName
= wx
.GetApp().GetDocumentManager().GetCurrentDocument().GetFilename()
1694 line
= view
.GetCtrl().GetCurrentLine()
1695 if self
.BreakpointSet(fileName
, line
+ 1):
1696 self
.ClearBreak(fileName
, line
+ 1)
1698 self
.SetBreak(fileName
, line
+ 1)
1699 # Now refresh all the markers icons in all the open views.
1700 self
.ClearAllBreakpointMarkers()
1701 self
.SetAllBreakpointMarkers()
1703 def SilentToggleBreakpoint(self
, fileName
, line
):
1705 for lineNumber
in self
.GetBreakpointList(fileName
):
1706 if int(lineNumber
) == int(line
):
1710 self
.SetBreak(fileName
, line
)
1712 self
.ClearBreak(fileName
, line
)
1714 def SetBreak(self
, fileName
, line
):
1715 expandedName
= DebuggerService
.ExpandPath(fileName
)
1716 if not self
._masterBPDict
.has_key(expandedName
):
1717 self
._masterBPDict
[expandedName
] = [line
]
1719 self
._masterBPDict
[expandedName
] += [line
]
1720 # If we're already debugging, pass this bp off to the DebuggerCallback
1721 self
.NotifyDebuggersOfBreakpointChange()
1723 def NotifyDebuggersOfBreakpointChange(self
):
1724 DebugCommandUI
.NotifyDebuggersOfBreakpointChange()
1726 def GetBreakpointList(self
, fileName
):
1727 expandedName
= DebuggerService
.ExpandPath(fileName
)
1728 if not self
._masterBPDict
.has_key(expandedName
):
1731 return self
._masterBPDict
[expandedName
]
1733 def BreakpointSet(self
, fileName
, line
):
1734 expandedName
= DebuggerService
.ExpandPath(fileName
)
1735 if not self
._masterBPDict
.has_key(expandedName
):
1739 for number
in self
._masterBPDict
[expandedName
]:
1740 if(int(number
) == int(line
)):
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"
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()
1757 def HasBreakpointsSet(self
):
1758 for key
, value
in self
._masterBPDict
.items():
1763 def ClearAllBreakpoints(self
):
1764 self
._masterBPDict
= {}
1765 self
.NotifyDebuggersOfBreakpointChange()
1766 self
.ClearAllBreakpointMarkers()
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
)
1774 def GetMasterBreakpointDict(self
):
1775 return self
._masterBPDict
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())
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
)
1789 class DebuggerOptionsPanel(wx
.Panel
):
1792 def __init__(self
, parent
, id):
1793 wx
.Panel
.__init
__(self
, parent
, id)
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
)
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
)
1823 debuggerPanelBorderSizer
.Add(debuggerPanelSizer
, 0, wx
.ALL
, SPACE
)
1824 self
.SetSizer(debuggerPanelBorderSizer
)
1826 parent
.AddPage(self
, _("Debugger"))
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()
1834 wx
.MessageBox(_("The starting port is not valid. Please change the value and try again.", "Invalid Starting Port Number"))
1836 def MinPortChange(self
, event
):
1837 self
._EndPortNumberTextCtrl
.Enable( True )
1838 self
._EndPortNumberTextCtrl
.SetValue( self
._PortNumberTextCtrl
.GetValue() + PORT_COUNT
)
1839 self
._EndPortNumberTextCtrl
.Enable( False )
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())
1847 class CommandPropertiesDialog(wx
.Dialog
):
1849 def __init__(self
, parent
, title
, projectService
, currentProjectDocument
, pythonOnly
=False, okButtonName
="Run", debugging
=False):
1850 self
._projService
= projectService
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"))
1865 wx
.Dialog
.__init
__(self
, parent
, -1, title
)
1867 wx
.Dialog
.__init
__(self
, parent
, -1, title
, size
=(390,270))
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
)
1879 flexGridSizer
= wx
.FlexGridSizer(cols
= 3, vgap
= 10, hgap
= 10)
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)
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)
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
)
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)
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
)
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)
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']
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)
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)
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)
1948 self
.SetSizer(cpPanelBorderSizer
)
1950 self
.GetSizer().Fit(self
)
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")
1960 if lastProject
in self
._projectNameList
:
1961 selectedIndex
= self
._projectNameList
.index(lastProject
)
1962 elif selectedIndex
< 0:
1964 self
._projList
.Select(selectedIndex
)
1965 self
._selectedProjectIndex
= selectedIndex
1966 self
._selectedProjectDocument
= self
._projectDocumentList
[selectedIndex
]
1967 self
.PopulateFileList(self
._selectedProjectDocument
, lastFile
)
1969 def OnOKClick(self
, event
):
1970 startIn
= self
._startEntry
.GetValue()
1971 fileToRun
= self
._fileList
.GetStringSelection()
1973 wx
.MessageBox(_("You must select a file to proceed. Note that not all projects have files that can be run or debugged."))
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."))
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.
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()))
1990 self
.EndModal(wx
.ID_OK
)
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
)
1998 if hasattr(self
, "_postpendCheckBox"):
1999 postpend
= self
._postpendCheckBox
.GetValue()
2003 env
['PYTHONPATH'] = self
._pythonPathEntry
.GetValue() + os
.pathsep
+ os
.path
.join(os
.getcwd(), "3rdparty", "pywin32")
2005 env
['PYTHONPATH'] = self
._pythonPathEntry
.GetValue()
2007 return filename
, args
, startIn
, isPython
, env
2009 def OnFileSelected(self
, event
):
2010 self
._selectedFileIndex
= self
._fileList
.GetSelection()
2011 self
.EnableForFileType(event
.GetString())
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
)
2020 self
._lastStartIn
= self
._startEntry
.GetValue()
2021 self
._startEntry
.SetValue("")
2022 self
._lastArguments
= self
._argsEntry
.GetValue()
2023 self
._argsEntry
.SetValue("")
2025 self
._startEntry
.SetValue(self
._lastStartIn
)
2026 self
._argsEntry
.SetValue(self
._lastArguments
)
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
)
2034 if dlg
.ShowModal() == wx
.ID_OK
:
2035 self
._startEntry
.SetValue(dlg
.GetPath())
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
)
2046 def FilterFileList(self
, list):
2047 if self
._pythonOnly
:
2048 files
= filter(lambda f
: f
.endswith(self
._pyext
), list)
2050 files
= filter(lambda f
: (self
._pmext
and f
.endswith(self
._pmext
)) or f
.endswith(self
._pyext
), list)
2053 def PopulateFileList(self
, project
, shortNameToSelect
=None):
2054 self
._fileNameList
= self
.FilterFileList(project
.GetFiles()[:])
2055 self
._fileList
.Clear()
2056 if not self
._fileNameList
:
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
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
])
2071 def GetProjectList(self
):
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
:
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
):
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())
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"))
2108 return nameList
, docList
, index
2111 #----------------------------------------------------------------------
2112 from wx
import ImageFromStream
, BitmapFromImage
2115 #----------------------------------------------------------------------
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'
2128 def getBreakBitmap():
2129 return BitmapFromImage(getBreakImage())
2131 def getBreakImage():
2132 stream
= cStringIO
.StringIO(getBreakData())
2133 return ImageFromStream(stream
)
2136 return wx
.IconFromBitmap(getBreakBitmap())
2138 #----------------------------------------------------------------------
2139 def getClearOutputData():
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'
2153 def getClearOutputBitmap():
2154 return BitmapFromImage(getClearOutputImage())
2156 def getClearOutputImage():
2157 stream
= cStringIO
.StringIO(getClearOutputData())
2158 return ImageFromStream(stream
)
2160 def getClearOutputIcon():
2161 return wx
.IconFromBitmap(getClearOutputBitmap())
2163 #----------------------------------------------------------------------
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'
2175 def getCloseBitmap():
2176 return BitmapFromImage(getCloseImage())
2178 def getCloseImage():
2179 stream
= cStringIO
.StringIO(getCloseData())
2180 return ImageFromStream(stream
)
2183 return wx
.IconFromBitmap(getCloseBitmap())
2185 #----------------------------------------------------------------------
2186 def getContinueData():
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'
2198 def getContinueBitmap():
2199 return BitmapFromImage(getContinueImage())
2201 def getContinueImage():
2202 stream
= cStringIO
.StringIO(getContinueData())
2203 return ImageFromStream(stream
)
2205 def getContinueIcon():
2206 return wx
.IconFromBitmap(getContinueBitmap())
2208 #----------------------------------------------------------------------
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\
2221 def getNextBitmap():
2222 return BitmapFromImage(getNextImage())
2225 stream
= cStringIO
.StringIO(getNextData())
2226 return ImageFromStream(stream
)
2229 return wx
.IconFromBitmap(getNextBitmap())
2231 #----------------------------------------------------------------------
2232 def getStepInData():
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'
2243 def getStepInBitmap():
2244 return BitmapFromImage(getStepInImage())
2246 def getStepInImage():
2247 stream
= cStringIO
.StringIO(getStepInData())
2248 return ImageFromStream(stream
)
2250 def getStepInIcon():
2251 return wx
.IconFromBitmap(getStepInBitmap())
2253 #----------------------------------------------------------------------
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"
2263 def getStopBitmap():
2264 return BitmapFromImage(getStopImage())
2267 stream
= cStringIO
.StringIO(getStopData())
2268 return ImageFromStream(stream
)
2271 return wx
.IconFromBitmap(getStopBitmap())
2273 #----------------------------------------------------------------------
2274 def getStepReturnData():
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\
2286 def getStepReturnBitmap():
2287 return BitmapFromImage(getStepReturnImage())
2289 def getStepReturnImage():
2290 stream
= cStringIO
.StringIO(getStepReturnData())
2291 return ImageFromStream(stream
)
2293 def getStepReturnIcon():
2294 return wx
.IconFromBitmap(getStepReturnBitmap())
2296 #----------------------------------------------------------------------
2297 def getAddWatchData():
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'
2308 def getAddWatchBitmap():
2309 return BitmapFromImage(getAddWatchImage())
2311 def getAddWatchImage():
2312 stream
= cStringIO
.StringIO(getAddWatchData())
2313 return ImageFromStream(stream
)
2315 def getAddWatchIcon():
2316 return wx
.IconFromBitmap(getAddWatchBitmap())