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
38 from xml
.dom
.minidom
import parse
, parseString
41 import DebuggerHarness
44 if wx
.Platform
== '__WXMSW__':
47 _PYWIN32_INSTALLED
= True
49 _PYWIN32_INSTALLED
= False
54 if not _WINDOWS
or _PYWIN32_INSTALLED
:
62 # Class to read from stdout or stderr and write the result to a text control.
63 # Args: file=file-like object
64 # callback_function= function that takes a single argument, the line of text
66 class OutputReaderThread(threading
.Thread
):
67 def __init__(self
, file, callback_function
, callbackOnExit
=None, accumulate
=True):
68 threading
.Thread
.__init
__(self
)
70 self
._callback
_function
= callback_function
71 self
._keepGoing
= True
73 self
._accumulate
= accumulate
74 self
._callbackOnExit
= callbackOnExit
80 while self
._keepGoing
:
82 # This could block--how to handle that?
83 text
= file.readline()
84 if text
== '' or text
== None:
85 self
._keepGoing
= False
86 elif not self
._accumulate
:
87 self
._callback
_function
(text
)
89 # Should use a buffer? StringIO?
91 # Seems as though the read blocks if we got an error, so, to be
92 # sure that at least some of the exception gets printed, always
93 # send the first hundred lines back as they come in.
94 if self
._lineCount
< 100:
95 self
._callback
_function
(output
)
98 elif time
.time() - start
> 0.25:
100 self
._callback
_function
(output
)
101 except wx
._core
.PyDeadObjectError
:
102 # GUI was killed while we were blocked.
103 self
._keepGoing
= False
107 tp
, val
, tb
= sys
.exc_info()
108 print "Exception in OutputReaderThread.run():", tp
, val
109 self
._keepGoing
= False
110 if self
._callbackOnExit
:
112 self
._callbackOnExit
()
113 except wx
._core
.PyDeadObjectError
:
115 if _VERBOSE
: print "Exiting OutputReaderThread"
118 self
._keepGoing
= False
120 import wx
.lib
.newevent
121 (UpdateTextEvent
, EVT_UPDATE_STDTEXT
) = wx
.lib
.newevent
.NewEvent()
122 (UpdateErrorEvent
, EVT_UPDATE_ERRTEXT
) = wx
.lib
.newevent
.NewEvent()
126 def GetPythonExecutablePath():
127 config
= wx
.ConfigBase_Get()
128 path
= config
.Read("ActiveGridPythonLocation")
131 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"))
133 GetPythonExecutablePath
= staticmethod(GetPythonExecutablePath
)
135 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):
136 self
._fileName
= fileName
137 self
._stdOutCallback
= self
.OutCall
138 self
._stdErrCallback
= self
.ErrCall
139 self
._callbackOnExit
= callbackOnExit
140 self
._wxComponent
= wxComponent
141 path
= Executor
.GetPythonExecutablePath()
142 self
._cmd
= '"' + path
+ '" -u \"' + fileName
+ '\"'
143 #Better way to do this? Quotes needed for windows file paths.
145 self
._cmd
+= ' \"' + arg1
+ '\"'
147 self
._cmd
+= ' \"' + arg2
+ '\"'
149 self
._cmd
+= ' \"' + arg3
+ '\"'
151 self
._cmd
+= ' \"' + arg4
+ '\"'
153 self
._cmd
+= ' \"' + arg5
+ '\"'
155 self
._cmd
+= ' \"' + arg6
+ '\"'
157 self
._cmd
+= ' \"' + arg7
+ '\"'
159 self
._cmd
+= ' \"' + arg8
+ '\"'
161 self
._cmd
+= ' \"' + arg9
+ '\"'
163 self
._stdOutReader
= None
164 self
._stdErrReader
= None
167 def OutCall(self
, text
):
168 evt
= UpdateTextEvent(value
= text
)
169 wx
.PostEvent(self
._wxComponent
, evt
)
171 def ErrCall(self
, text
):
172 evt
= UpdateErrorEvent(value
= text
)
173 wx
.PostEvent(self
._wxComponent
, evt
)
175 def Execute(self
, arguments
, startIn
=None, environment
=None):
177 startIn
= str(os
.getcwd())
178 startIn
= os
.path
.abspath(startIn
)
179 command
= self
._cmd
+ ' ' + arguments
180 #stdinput = process.IOBuffer()
181 #self._process = process.ProcessProxy(command, mode='b', cwd=startIn, stdin=stdinput)
182 self
._process
= process
.ProcessOpen(command
, mode
='b', cwd
=startIn
, env
=environment
)
183 # Kick off threads to read stdout and stderr and write them
184 # to our text control.
185 self
._stdOutReader
= OutputReaderThread(self
._process
.stdout
, self
._stdOutCallback
, callbackOnExit
=self
._callbackOnExit
)
186 self
._stdOutReader
.start()
187 self
._stdErrReader
= OutputReaderThread(self
._process
.stderr
, self
._stdErrCallback
, accumulate
=False)
188 self
._stdErrReader
.start()
191 def DoStopExecution(self
):
192 if(self
._process
!= None):
194 self
._process
.close()
196 if(self
._stdOutReader
!= None):
197 self
._stdOutReader
.AskToStop()
198 if(self
._stdErrReader
!= None):
199 self
._stdErrReader
.AskToStop()
201 class RunCommandUI(wx
.Panel
):
203 def __init__(self
, parent
, id, fileName
):
204 wx
.Panel
.__init
__(self
, parent
, id)
205 self
._noteBook
= parent
207 self
.KILL_PROCESS_ID
= wx
.NewId()
208 self
.CLOSE_TAB_ID
= wx
.NewId()
210 self
.Bind(wx
.EVT_END_PROCESS
, self
.OnProcessEnded
)
212 # GUI Initialization follows
213 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
214 self
._tb
= tb
= wx
.ToolBar(self
, -1, wx
.DefaultPosition
, (30,1000), wx
.TB_VERTICAL| wx
.TB_FLAT
, "Runner" )
215 tb
.SetToolBitmapSize((16,16))
216 sizer
.Add(tb
, 0, wx
.EXPAND |wx
.ALIGN_LEFT|wx
.ALL
, 1)
218 close_bmp
= getCloseBitmap()
219 tb
.AddSimpleTool( self
.CLOSE_TAB_ID
, close_bmp
, _('Close Window'))
220 wx
.EVT_TOOL(self
, self
.CLOSE_TAB_ID
, self
.OnToolClicked
)
222 stop_bmp
= getStopBitmap()
223 tb
.AddSimpleTool(self
.KILL_PROCESS_ID
, stop_bmp
, _("Stop the Run."))
224 wx
.EVT_TOOL(self
, self
.KILL_PROCESS_ID
, self
.OnToolClicked
)
227 self
._textCtrl
= STCTextEditor
.TextCtrl(self
, wx
.NewId()) #id)
228 sizer
.Add(self
._textCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
229 self
._textCtrl
.SetViewLineNumbers(False)
230 self
._textCtrl
.SetReadOnly(True)
231 if wx
.Platform
== '__WXMSW__':
235 self
._textCtrl
.SetFont(wx
.Font(9, wx
.DEFAULT
, wx
.NORMAL
, wx
.NORMAL
, faceName
= font
))
236 self
._textCtrl
.SetFontColor(wx
.BLACK
)
237 self
._textCtrl
.StyleClearAll()
239 #Disabling for now...may interfere with file open. wx.stc.EVT_STC_DOUBLECLICK(self._textCtrl, self._textCtrl.GetId(), self.OnDoubleClick)
244 # Executor initialization
245 self
._executor
= Executor(fileName
, self
, callbackOnExit
=self
.ExecutorFinished
)
246 self
.Bind(EVT_UPDATE_STDTEXT
, self
.AppendText
)
247 self
.Bind(EVT_UPDATE_ERRTEXT
, self
.AppendErrorText
)
250 self
._executor
.DoStopExecution()
252 def Execute(self
, initialArgs
, startIn
, environment
):
253 self
._executor
.Execute(initialArgs
, startIn
, environment
)
255 def ExecutorFinished(self
):
256 self
._tb
.EnableTool(self
.KILL_PROCESS_ID
, False)
257 nb
= self
.GetParent()
258 for i
in range(0,nb
.GetPageCount()):
259 if self
== nb
.GetPage(i
):
260 text
= nb
.GetPageText(i
)
261 newText
= text
.replace("Running", "Finished")
262 nb
.SetPageText(i
, newText
)
265 def StopExecution(self
):
266 self
.Unbind(EVT_UPDATE_STDTEXT
)
267 self
.Unbind(EVT_UPDATE_ERRTEXT
)
268 self
._executor
.DoStopExecution()
270 def AppendText(self
, event
):
271 self
._textCtrl
.SetReadOnly(False)
272 self
._textCtrl
.AddText(event
.value
)
273 self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount())
274 self
._textCtrl
.SetReadOnly(True)
276 def AppendErrorText(self
, event
):
277 self
._textCtrl
.SetReadOnly(False)
278 self
._textCtrl
.SetFontColor(wx
.RED
)
279 self
._textCtrl
.StyleClearAll()
280 self
._textCtrl
.AddText(event
.value
)
281 self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount())
282 self
._textCtrl
.SetFontColor(wx
.BLACK
)
283 self
._textCtrl
.StyleClearAll()
284 self
._textCtrl
.SetReadOnly(True)
286 #------------------------------------------------------------------------------
288 #-----------------------------------------------------------------------------
290 def OnToolClicked(self
, event
):
293 if id == self
.KILL_PROCESS_ID
:
294 self
._executor
.DoStopExecution()
296 elif id == self
.CLOSE_TAB_ID
:
297 self
._executor
.DoStopExecution()
298 index
= self
._noteBook
.GetSelection()
299 self
._noteBook
.GetPage(index
).Show(False)
300 self
._noteBook
.RemovePage(index
)
302 def OnDoubleClick(self
, event
):
303 # Looking for a stack trace line.
304 lineText
, pos
= self
._textCtrl
.GetCurLine()
305 fileBegin
= lineText
.find("File \"")
306 fileEnd
= lineText
.find("\", line ")
307 lineEnd
= lineText
.find(", in ")
308 if lineText
== "\n" or fileBegin
== -1 or fileEnd
== -1 or lineEnd
== -1:
309 # Check the line before the one that was clicked on
310 lineNumber
= self
._textCtrl
.GetCurrentLine()
313 lineText
= self
._textCtrl
.GetLine(lineNumber
- 1)
314 fileBegin
= lineText
.find("File \"")
315 fileEnd
= lineText
.find("\", line ")
316 lineEnd
= lineText
.find(", in ")
317 if lineText
== "\n" or fileBegin
== -1 or fileEnd
== -1 or lineEnd
== -1:
320 filename
= lineText
[fileBegin
+ 6:fileEnd
]
321 lineNum
= int(lineText
[fileEnd
+ 8:lineEnd
])
324 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
325 for openDoc
in openDocs
:
326 if openDoc
.GetFilename() == filename
:
327 foundView
= openDoc
.GetFirstView()
331 doc
= wx
.GetApp().GetDocumentManager().CreateDocument(filename
, wx
.lib
.docview
.DOC_SILENT
)
332 foundView
= doc
.GetFirstView()
335 foundView
.GetFrame().SetFocus()
337 foundView
.GotoLine(lineNum
)
338 startPos
= foundView
.PositionFromLine(lineNum
)
340 # FACTOR THIS INTO DocManager
341 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
342 for openDoc
in openDocs
:
343 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
344 openDoc
.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
346 foundView
.GetCtrl().MarkerAdd(lineNum
-1, CodeEditor
.CodeCtrl
.CURRENT_LINE_MARKER_NUM
)
348 def OnProcessEnded(self
, evt
):
349 self
._executor
.DoStopExecution()
352 DEFAULT_HOST
= 'localhost'
355 class DebugCommandUI(wx
.Panel
):
356 debuggerPortList
= None
359 def NotifyDebuggersOfBreakpointChange():
360 for debugger
in DebugCommandUI
.debuggers
:
361 debugger
.BreakPointChange()
363 NotifyDebuggersOfBreakpointChange
= staticmethod(NotifyDebuggersOfBreakpointChange
)
365 def DebuggerRunning():
366 for debugger
in DebugCommandUI
.debuggers
:
367 if debugger
._executor
:
370 DebuggerRunning
= staticmethod(DebuggerRunning
)
372 def ShutdownAllDebuggers():
373 for debugger
in DebugCommandUI
.debuggers
:
374 debugger
.StopExecution()
376 ShutdownAllDebuggers
= staticmethod(ShutdownAllDebuggers
)
378 def GetAvailablePort():
379 for index
in range( 0, len(DebugCommandUI
.debuggerPortList
)):
380 port
= DebugCommandUI
.debuggerPortList
[index
]
381 if DebugCommandUI
.PortAvailable(port
):
382 DebugCommandUI
.debuggerPortList
.pop(index
)
384 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"))
385 assert False, "Out of ports for debugger."
387 GetAvailablePort
= staticmethod(GetAvailablePort
)
389 def ReturnPortToPool(port
):
390 config
= wx
.ConfigBase_Get()
391 startingPort
= config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
)
392 if port
in range(startingPort
, startingPort
+ PORT_COUNT
):
393 DebugCommandUI
.debuggerPortList
.append(port
)
395 ReturnPortToPool
= staticmethod(ReturnPortToPool
)
397 def PortAvailable(port
):
398 config
= wx
.ConfigBase_Get()
399 hostname
= config
.Read("DebuggerHostName", DEFAULT_HOST
)
401 server
= AGXMLRPCServer((hostname
, port
))
402 server
.server_close()
403 if _VERBOSE
: print "Port ", str(port
), " available."
406 tp
,val
,tb
= sys
.exc_info()
407 if _VERBOSE
: traceback
.print_exception(tp
, val
, tb
)
408 if _VERBOSE
: print "Port ", str(port
), " unavailable."
411 PortAvailable
= staticmethod(PortAvailable
)
414 config
= wx
.ConfigBase_Get()
415 startingPort
= config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
)
416 DebugCommandUI
.debuggerPortList
= range(startingPort
, startingPort
+ PORT_COUNT
)
417 NewPortRange
= staticmethod(NewPortRange
)
419 def __init__(self
, parent
, id, command
, service
):
420 # Check for ports before creating the panel.
421 if not DebugCommandUI
.debuggerPortList
:
422 DebugCommandUI
.NewPortRange()
423 self
._debuggerPort
= str(DebugCommandUI
.GetAvailablePort())
424 self
._guiPort
= str(DebugCommandUI
.GetAvailablePort())
425 self
._debuggerBreakPort
= str(DebugCommandUI
.GetAvailablePort())
427 wx
.Panel
.__init
__(self
, parent
, id)
429 self
._parentNoteBook
= parent
430 self
._command
= command
431 self
._textCtrl
= None
432 self
._service
= service
433 self
._executor
= None
434 self
.STEP_ID
= wx
.NewId()
435 self
.CONTINUE_ID
= wx
.NewId()
436 self
.STEP_OUT_ID
= wx
.NewId()
437 self
.NEXT_ID
= wx
.NewId()
438 self
.KILL_PROCESS_ID
= wx
.NewId()
439 self
.CLOSE_WINDOW_ID
= wx
.NewId()
440 self
.BREAK_INTO_DEBUGGER_ID
= wx
.NewId()
441 self
.CLEAR_ID
= wx
.NewId()
442 self
.ADD_WATCH_ID
= wx
.NewId()
443 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
444 self
._tb
= tb
= wx
.ToolBar(self
, -1, wx
.DefaultPosition
, (1000,30), wx
.TB_HORIZONTAL| wx
.NO_BORDER| wx
.TB_FLAT| wx
.TB_TEXT
, "Debugger" )
445 sizer
.Add(tb
, 0, wx
.EXPAND |wx
.ALIGN_LEFT|wx
.ALL
, 1)
446 tb
.SetToolBitmapSize((16,16))
448 close_bmp
= getCloseBitmap()
449 tb
.AddSimpleTool( self
.CLOSE_WINDOW_ID
, close_bmp
, _('Close Window'))
450 wx
.EVT_TOOL(self
, self
.CLOSE_WINDOW_ID
, self
.StopAndRemoveUI
)
452 stop_bmp
= getStopBitmap()
453 tb
.AddSimpleTool( self
.KILL_PROCESS_ID
, stop_bmp
, _("Stop Debugging"))
454 wx
.EVT_TOOL(self
, self
.KILL_PROCESS_ID
, self
.StopExecution
)
458 break_bmp
= getBreakBitmap()
459 tb
.AddSimpleTool( self
.BREAK_INTO_DEBUGGER_ID
, break_bmp
, _("Break into Debugger"))
460 wx
.EVT_TOOL(self
, self
.BREAK_INTO_DEBUGGER_ID
, self
.BreakExecution
)
464 continue_bmp
= getContinueBitmap()
465 tb
.AddSimpleTool( self
.CONTINUE_ID
, continue_bmp
, _("Continue Execution"))
466 wx
.EVT_TOOL(self
, self
.CONTINUE_ID
, self
.OnContinue
)
470 next_bmp
= getNextBitmap()
471 tb
.AddSimpleTool( self
.NEXT_ID
, next_bmp
, _("Step to next line"))
472 wx
.EVT_TOOL(self
, self
.NEXT_ID
, self
.OnNext
)
474 step_bmp
= getStepInBitmap()
475 tb
.AddSimpleTool( self
.STEP_ID
, step_bmp
, _("Step in"))
476 wx
.EVT_TOOL(self
, self
.STEP_ID
, self
.OnSingleStep
)
478 stepOut_bmp
= getStepReturnBitmap()
479 tb
.AddSimpleTool(self
.STEP_OUT_ID
, stepOut_bmp
, _("Stop at function return"))
480 wx
.EVT_TOOL(self
, self
.STEP_OUT_ID
, self
.OnStepOut
)
484 watch_bmp
= getAddWatchBitmap()
485 tb
.AddSimpleTool(self
.ADD_WATCH_ID
, watch_bmp
, _("Add a watch"))
486 wx
.EVT_TOOL(self
, self
.ADD_WATCH_ID
, self
.OnAddWatch
)
489 clear_bmp
= getClearOutputBitmap()
490 tb
.AddSimpleTool(self
.CLEAR_ID
, clear_bmp
, _("Clear output pane"))
491 wx
.EVT_TOOL(self
, self
.CLEAR_ID
, self
.OnClearOutput
)
494 self
.framesTab
= None
495 self
.DisableWhileDebuggerRunning()
496 self
._notebook
= wx
.Notebook(self
, -1, wx
.DefaultPosition
, wx
.DefaultSize
, wx
.LB_DEFAULT
, "Debugger")
497 sizer
.Add(self
._notebook
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
498 self
.consoleTab
= self
.MakeConsoleTab(self
._notebook
, wx
.NewId(), None)
499 self
.framesTab
= self
.MakeFramesTab(self
._notebook
, wx
.NewId(), None)
500 self
.breakPointsTab
= self
.MakeBreakPointsTab(self
._notebook
, wx
.NewId(), None)
501 self
._notebook
.AddPage(self
.consoleTab
, "Output")
502 self
._notebook
.AddPage(self
.framesTab
, "Frames")
503 self
._notebook
.AddPage(self
.breakPointsTab
, "Break Points")
505 self
._statusBar
= wx
.StatusBar( self
, -1)
506 self
._statusBar
.SetFieldsCount(1)
507 sizer
.Add(self
._statusBar
, 0, wx
.EXPAND |wx
.ALIGN_LEFT|wx
.ALL
, 1)
509 self
.SetStatusText("Starting debug...")
513 config
= wx
.ConfigBase_Get()
514 self
._debuggerHost
= self
._guiHost
= config
.Read("DebuggerHostName", DEFAULT_HOST
)
515 url
= 'http://' + self
._debuggerHost
+ ':' + self
._debuggerPort
+ '/'
516 self
._breakURL
= 'http://' + self
._debuggerHost
+ ':' + self
._debuggerBreakPort
+ '/'
517 self
._callback
= DebuggerCallback(self
._guiHost
, self
._guiPort
, url
, self
._breakURL
, self
)
518 if DebuggerHarness
.__file
__.find('library.zip') > 0:
520 fname
= DebuggerHarness
.__file
__
521 parts
= fname
.split('library.zip')
522 path
= os
.path
.join(parts
[0],'activegrid', 'tool', 'DebuggerHarness.py')
524 tp
, val
, tb
= sys
.exc_info()
525 traceback
.print_exception(tp
, val
, tb
)
528 print "Starting debugger on these ports: %s, %s, %s" % (str(self
._debuggerPort
) , str(self
._guiPort
) , str(self
._debuggerBreakPort
))
529 path
= DebuggerService
.ExpandPath(DebuggerHarness
.__file
__)
530 self
._executor
= Executor(path
, self
, self
._debuggerHost
, \
531 self
._debuggerPort
, self
._debuggerBreakPort
, self
._guiHost
, self
._guiPort
, self
._command
, callbackOnExit
=self
.ExecutorFinished
)
533 self
.Bind(EVT_UPDATE_STDTEXT
, self
.AppendText
)
534 self
.Bind(EVT_UPDATE_ERRTEXT
, self
.AppendErrorText
)
535 DebugCommandUI
.debuggers
.append(self
)
536 self
._stopped
= False
538 def OnSingleStep(self
, event
):
539 self
._callback
.SingleStep()
541 def OnContinue(self
, event
):
542 self
._callback
.Continue()
544 def OnStepOut(self
, event
):
545 self
._callback
.Return()
547 def OnNext(self
, event
):
548 self
._callback
.Next()
550 def BreakPointChange(self
):
551 if not self
._stopped
:
552 self
._callback
.pushBreakpoints()
553 self
.breakPointsTab
.PopulateBPList()
556 if self
in DebugCommandUI
.debuggers
:
557 DebugCommandUI
.debuggers
.remove(self
)
559 def SwitchToOutputTab(self
):
560 self
._notebook
.SetSelection(0)
562 def DisableWhileDebuggerRunning(self
):
563 self
._tb
.EnableTool(self
.STEP_ID
, False)
564 self
._tb
.EnableTool(self
.CONTINUE_ID
, False)
565 self
._tb
.EnableTool(self
.STEP_OUT_ID
, False)
566 self
._tb
.EnableTool(self
.NEXT_ID
, False)
567 self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, True)
569 self
._tb
.EnableTool(self
.ADD_WATCH_ID
, False)
570 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
571 for openDoc
in openDocs
:
572 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
573 openDoc
.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
575 self
.framesTab
.ClearWhileRunning()
576 #wx.GetApp().ProcessPendingEvents() #Yield(True)
578 def EnableWhileDebuggerStopped(self
):
579 self
._tb
.EnableTool(self
.STEP_ID
, True)
580 self
._tb
.EnableTool(self
.CONTINUE_ID
, True)
581 self
._tb
.EnableTool(self
.STEP_OUT_ID
, True)
582 self
._tb
.EnableTool(self
.NEXT_ID
, True)
584 self
._tb
.EnableTool(self
.ADD_WATCH_ID
, True)
585 self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, False)
587 # wx.GetApp().GetTopWindow().RequestUserAttention()
589 def ExecutorFinished(self
):
590 if _VERBOSE
: print "In ExectorFinished"
592 self
.DisableAfterStop()
593 except wx
._core
.PyDeadObjectError
:
596 nb
= self
.GetParent()
597 for i
in range(0, nb
.GetPageCount()):
598 if self
== nb
.GetPage(i
):
599 text
= nb
.GetPageText(i
)
600 newText
= text
.replace("Debugging", "Finished")
601 nb
.SetPageText(i
, newText
)
602 if _VERBOSE
: print "In ExectorFinished, changed tab title."
605 if _VERBOSE
: print "In ExectorFinished, got exception"
607 def DisableAfterStop(self
):
608 self
.DisableWhileDebuggerRunning()
609 self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, False)
610 self
._tb
.EnableTool(self
.KILL_PROCESS_ID
, False)
612 def SynchCurrentLine(self
, filename
, lineNum
):
613 # FACTOR THIS INTO DocManager
614 self
.DeleteCurrentLineMarkers()
616 # Filename will be <string> if we're in a bit of code that was executed from
617 # a string (rather than a file). I haven't been able to get the original string
619 if filename
== '<string>':
622 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
623 for openDoc
in openDocs
:
624 # This ugliness to prevent comparison failing because the drive letter
625 # gets lowercased occasionally. Don't know why that happens or why it
626 # only happens occasionally.
627 if DebuggerService
.ComparePaths(openDoc
.GetFilename(),filename
):
628 foundView
= openDoc
.GetFirstView()
633 print "filename=", filename
634 doc
= wx
.GetApp().GetDocumentManager().CreateDocument(DebuggerService
.ExpandPath(filename
), wx
.lib
.docview
.DOC_SILENT
)
635 foundView
= doc
.GetFirstView()
638 foundView
.GetFrame().SetFocus()
640 foundView
.GotoLine(lineNum
)
641 startPos
= foundView
.PositionFromLine(lineNum
)
643 foundView
.GetCtrl().MarkerAdd(lineNum
-1, CodeEditor
.CodeCtrl
.CURRENT_LINE_MARKER_NUM
)
645 def DeleteCurrentLineMarkers(self
):
646 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
647 for openDoc
in openDocs
:
648 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
649 openDoc
.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
651 def LoadFramesListXML(self
, framesXML
):
652 self
.framesTab
.LoadFramesListXML(framesXML
)
654 def SetStatusText(self
, text
):
655 self
._statusBar
.SetStatusText(text
,0)
657 def Execute(self
, initialArgs
, startIn
, environment
):
658 self
._callback
.start()
659 self
._executor
.Execute(initialArgs
, startIn
, environment
)
660 self
._callback
.waitForRPC()
662 def BreakExecution(self
, event
):
663 self
._callback
.BreakExecution()
666 def StopExecution(self
, event
):
668 self
.DisableAfterStop()
670 self
._callback
.ServerClose()
675 self
._executor
.DoStopExecution()
676 self
._executor
= None
679 self
.DeleteCurrentLineMarkers()
680 DebugCommandUI
.ReturnPortToPool(self
._debuggerPort
)
681 DebugCommandUI
.ReturnPortToPool(self
._guiPort
)
682 DebugCommandUI
.ReturnPortToPool(self
._debuggerBreakPort
)
684 def StopAndRemoveUI(self
, event
):
685 self
.StopExecution(None)
686 if self
in DebugCommandUI
.debuggers
:
687 DebugCommandUI
.debuggers
.remove(self
)
688 index
= self
._parentNoteBook
.GetSelection()
689 self
._parentNoteBook
.GetPage(index
).Show(False)
690 self
._parentNoteBook
.RemovePage(index
)
692 def GetConsoleTextControl(self
):
693 return self
._textCtrl
695 def OnClearOutput(self
, event
):
696 self
._textCtrl
.SetReadOnly(False)
697 self
._textCtrl
.ClearAll()
698 self
._textCtrl
.SetReadOnly(True)
700 def OnAddWatch(self
, event
):
702 self
.framesTab
.OnWatch(event
)
704 def MakeConsoleTab(self
, parent
, id, debugger
):
705 panel
= wx
.Panel(parent
, id)
706 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
707 self
._textCtrl
= STCTextEditor
.TextCtrl(panel
, wx
.NewId())
708 sizer
.Add(self
._textCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
709 self
._textCtrl
.SetViewLineNumbers(False)
710 self
._textCtrl
.SetReadOnly(True)
711 if wx
.Platform
== '__WXMSW__':
715 self
._textCtrl
.SetFont(wx
.Font(9, wx
.DEFAULT
, wx
.NORMAL
, wx
.NORMAL
, faceName
= font
))
716 self
._textCtrl
.SetFontColor(wx
.BLACK
)
717 self
._textCtrl
.StyleClearAll()
718 panel
.SetSizer(sizer
)
723 def MakeFramesTab(self
, parent
, id, debugger
):
724 panel
= FramesUI(parent
, id, self
)
727 def MakeBreakPointsTab(self
, parent
, id, debugger
):
728 panel
= BreakpointsUI(parent
, id, self
)
731 def AppendText(self
, event
):
732 self
._textCtrl
.SetReadOnly(False)
733 self
._textCtrl
.AddText(event
.value
)
734 self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount())
735 self
._textCtrl
.SetReadOnly(True)
737 def AppendErrorText(self
, event
):
738 self
._textCtrl
.SetReadOnly(False)
739 self
._textCtrl
.SetFontColor(wx
.RED
)
740 self
._textCtrl
.StyleClearAll()
741 self
._textCtrl
.AddText(event
.value
)
742 self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount())
743 self
._textCtrl
.SetFontColor(wx
.BLACK
)
744 self
._textCtrl
.StyleClearAll()
745 self
._textCtrl
.SetReadOnly(True)
747 class BreakpointsUI(wx
.Panel
):
748 def __init__(self
, parent
, id, ui
):
749 wx
.Panel
.__init
__(self
, parent
, id)
751 self
.currentItem
= None
752 self
.clearBPID
= wx
.NewId()
753 self
.Bind(wx
.EVT_MENU
, self
.ClearBreakPoint
, id=self
.clearBPID
)
754 self
.syncLineID
= wx
.NewId()
755 self
.Bind(wx
.EVT_MENU
, self
.SyncBPLine
, id=self
.syncLineID
)
757 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
759 self
._bpListCtrl
= wx
.ListCtrl(p1
, -1, pos
=wx
.DefaultPosition
, size
=(1000,1000), style
=wx
.LC_REPORT
)
760 sizer
.Add(self
._bpListCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
761 self
._bpListCtrl
.InsertColumn(0, "File")
762 self
._bpListCtrl
.InsertColumn(1, "Line")
763 self
._bpListCtrl
.InsertColumn(2, "Path")
764 self
._bpListCtrl
.SetColumnWidth(0, 150)
765 self
._bpListCtrl
.SetColumnWidth(1, 50)
766 self
._bpListCtrl
.SetColumnWidth(2, 450)
767 self
._bpListCtrl
.Bind(wx
.EVT_LIST_ITEM_RIGHT_CLICK
, self
.OnListRightClick
)
768 self
.Bind(wx
.EVT_LIST_ITEM_SELECTED
, self
.ListItemSelected
, self
._bpListCtrl
)
769 self
.Bind(wx
.EVT_LIST_ITEM_DESELECTED
, self
.ListItemDeselected
, self
._bpListCtrl
)
771 self
.PopulateBPList()
777 def PopulateBPList(self
):
778 list = self
._bpListCtrl
779 list.DeleteAllItems()
781 bps
= wx
.GetApp().GetService(DebuggerService
).GetMasterBreakpointDict()
783 for fileName
in bps
.keys():
784 shortFile
= os
.path
.basename(fileName
)
785 lines
= bps
[fileName
]
788 list.InsertStringItem(index
, shortFile
)
789 list.SetStringItem(index
, 1, str(line
))
790 list.SetStringItem(index
, 2, fileName
)
792 def OnListRightClick(self
, event
):
794 item
= wx
.MenuItem(menu
, self
.clearBPID
, "Clear Breakpoint")
795 menu
.AppendItem(item
)
796 item
= wx
.MenuItem(menu
, self
.syncLineID
, "Goto Source Line")
797 menu
.AppendItem(item
)
798 self
.PopupMenu(menu
, event
.GetPosition())
801 def SyncBPLine(self
, event
):
802 if self
.currentItem
!= -1:
803 list = self
._bpListCtrl
804 fileName
= list.GetItem(self
.currentItem
, 2).GetText()
805 lineNumber
= list.GetItem(self
.currentItem
, 1).GetText()
806 self
._ui
.SynchCurrentLine( fileName
, int(lineNumber
) )
808 def ClearBreakPoint(self
, event
):
809 if self
.currentItem
>= 0:
810 list = self
._bpListCtrl
811 fileName
= list.GetItem(self
.currentItem
, 2).GetText()
812 lineNumber
= list.GetItem(self
.currentItem
, 1).GetText()
813 wx
.GetApp().GetService(DebuggerService
).OnToggleBreakpoint(None, line
=int(lineNumber
) -1, fileName
=fileName
)
815 def ListItemSelected(self
, event
):
816 self
.currentItem
= event
.m_itemIndex
818 def ListItemDeselected(self
, event
):
819 self
.currentItem
= -1
827 def __init__(self
, name
, command
, show_code
=CODE_ALL_FRAMES
):
829 self
._command
= command
830 self
._show
_code
= show_code
832 class WatchDialog(wx
.Dialog
):
833 WATCH_ALL_FRAMES
= "Watch in all frames"
834 WATCH_THIS_FRAME
= "Watch in this frame only"
835 WATCH_ONCE
= "Watch once and delete"
836 def __init__(self
, parent
, title
, chain
):
837 wx
.Dialog
.__init
__(self
, parent
, -1, title
, style
=wx
.DEFAULT_DIALOG_STYLE
)
839 self
.label_2
= wx
.StaticText(self
, -1, "Watch Name:")
840 self
._watchNameTextCtrl
= wx
.TextCtrl(self
, -1, "")
841 self
.label_3
= wx
.StaticText(self
, -1, "eval(", style
=wx
.ALIGN_RIGHT
)
842 self
._watchValueTextCtrl
= wx
.TextCtrl(self
, -1, "")
843 self
.label_4
= wx
.StaticText(self
, -1, ",frame.f_globals, frame.f_locals)")
844 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
)
846 self
._okButton
= wx
.Button(self
, wx
.ID_OK
, "OK", size
=(75,-1))
847 self
._okButton
.SetDefault()
848 self
._okButton
.SetHelpText(_("The OK button completes the dialog"))
849 def OnOkClick(event
):
850 if self
._watchNameTextCtrl
.GetValue() == "":
851 wx
.MessageBox(_("You must enter a name for the watch."), _("Add Watch"))
853 if self
._watchValueTextCtrl
.GetValue() == "":
854 wx
.MessageBox(_("You must enter some code to run for the watch."), _("Add Watch"))
856 self
.EndModal(wx
.ID_OK
)
857 self
.Bind(wx
.EVT_BUTTON
, OnOkClick
, self
._okButton
)
859 self
._cancelButton
= wx
.Button(self
, wx
.ID_CANCEL
, _("Cancel"), size
=(75,-1))
860 self
._cancelButton
.SetHelpText(_("The Cancel button cancels the dialog."))
862 self
.__set
_properties
()
865 def GetSettings(self
):
866 return self
._watchNameTextCtrl
.GetValue(), self
._watchValueTextCtrl
.GetValue(), self
.GetSendFrame(), self
.GetRunOnce()
868 def GetSendFrame(self
):
869 return (WatchDialog
.WATCH_ALL_FRAMES
!= self
.radio_box_1
.GetStringSelection())
871 def GetRunOnce(self
):
872 return (WatchDialog
.WATCH_ONCE
== self
.radio_box_1
.GetStringSelection())
874 def __set_properties(self
):
875 self
.SetTitle("Add a Watch")
876 #self.SetSize((400, 250))
877 self
.radio_box_1
.SetSelection(0)
879 def __do_layout(self
):
880 sizer_1
= wx
.BoxSizer(wx
.VERTICAL
)
881 grid_sizer_4
= wx
.FlexGridSizer(1, 3, 5, 5)
882 grid_sizer_2
= wx
.FlexGridSizer(1, 2, 5, 5)
883 grid_sizer_2
.Add(self
.label_2
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0)
884 grid_sizer_2
.Add(self
._watchNameTextCtrl
, 0, wx
.EXPAND
, 0)
885 grid_sizer_2
.AddGrowableCol(1)
886 sizer_1
.Add(grid_sizer_2
, 1, wx
.EXPAND
, 0)
887 grid_sizer_4
.Add(self
.label_3
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0)
888 grid_sizer_4
.Add(self
._watchValueTextCtrl
, 0, wx
.EXPAND
, 0)
889 grid_sizer_4
.AddGrowableCol(1)
890 grid_sizer_4
.Add(self
.label_4
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0)
891 sizer_1
.Add(grid_sizer_4
, 0, wx
.EXPAND
, 0)
892 sizer_1
.Add(self
.radio_box_1
, 0, wx
.EXPAND
, 0)
894 box
= wx
.BoxSizer(wx
.HORIZONTAL
)
895 box
.Add(self
._okButton
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5)
896 box
.Add(self
._cancelButton
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5)
897 sizer_1
.Add(box
, 1, wx
.EXPAND
, 0)
898 self
.SetAutoLayout(True)
899 self
.SetSizer(sizer_1
)
902 class FramesUI(wx
.SplitterWindow
):
903 def __init__(self
, parent
, id, ui
):
904 wx
.SplitterWindow
.__init
__(self
, parent
, id, style
= wx
.SP_3D
)
906 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
907 self
._p
1 = p1
= wx
.ScrolledWindow(self
, -1)
908 p1
.Bind(wx
.EVT_SIZE
, self
.OnSize
)
910 self
._framesListCtrl
= wx
.ListCtrl(p1
, -1, pos
=wx
.DefaultPosition
, size
=(250,150), style
=wx
.LC_REPORT
)
911 sizer
.Add(self
._framesListCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
912 self
._framesListCtrl
.InsertColumn(0, "Frame")
913 self
._framesListCtrl
.SetColumnWidth(0, 250)
914 self
._framesListCtrl
.Bind(wx
.EVT_LIST_ITEM_RIGHT_CLICK
, self
.OnListRightClick
)
915 self
.Bind(wx
.EVT_LIST_ITEM_SELECTED
, self
.ListItemSelected
, self
._framesListCtrl
)
916 self
.Bind(wx
.EVT_LIST_ITEM_DESELECTED
, self
.ListItemDeselected
, self
._framesListCtrl
)
918 sizer2
= wx
.BoxSizer(wx
.VERTICAL
)
919 self
._p
2 = p2
= wx
.ScrolledWindow(self
, -1)
920 p2
.Bind(wx
.EVT_SIZE
, self
.OnSize
)
922 self
._treeCtrl
= wx
.gizmos
.TreeListCtrl(p2
, -1, size
=(530,250), style
=wx
.TR_DEFAULT_STYLE| wx
.TR_FULL_ROW_HIGHLIGHT
)
923 self
._treeCtrl
.Bind(wx
.EVT_TREE_ITEM_RIGHT_CLICK
, self
.OnRightClick
)
924 sizer2
.Add(self
._framesListCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
925 tree
= self
._treeCtrl
926 tree
.AddColumn("Thing")
927 tree
.AddColumn("Value")
928 tree
.SetMainColumn(0) # the one with the tree in it...
929 tree
.SetColumnWidth(0, 175)
930 tree
.SetColumnWidth(1, 355)
931 self
._root
= tree
.AddRoot("Frame")
932 tree
.SetItemText(self
._root
, "", 1)
934 self
.SetMinimumPaneSize(20)
935 self
.SplitVertically(p1
, p2
, 250)
936 self
.currentItem
= None
939 def OnRightClick(self
, event
):
941 self
._introspectItem
= event
.GetItem()
942 self
._parentChain
= self
.GetItemChain(event
.GetItem())
943 watchOnly
= len(self
._parentChain
) < 1
944 if not _WATCHES_ON
and watchOnly
:
948 if not hasattr(self
, "introspectID"):
949 self
.introspectID
= wx
.NewId()
950 self
.Bind(wx
.EVT_MENU
, self
.OnIntrospect
, id=self
.introspectID
)
951 item
= wx
.MenuItem(menu
, self
.introspectID
, "Attempt Introspection")
952 menu
.AppendItem(item
)
953 menu
.AppendSeparator()
955 if not hasattr(self
, "watchID"):
956 self
.watchID
= wx
.NewId()
957 self
.Bind(wx
.EVT_MENU
, self
.OnWatch
, id=self
.watchID
)
958 item
= wx
.MenuItem(menu
, self
.watchID
, "Create a Watch")
959 menu
.AppendItem(item
)
960 menu
.AppendSeparator()
962 if not hasattr(self
, "viewID"):
963 self
.viewID
= wx
.NewId()
964 self
.Bind(wx
.EVT_MENU
, self
.OnView
, id=self
.viewID
)
965 item
= wx
.MenuItem(menu
, self
.viewID
, "View in Dialog")
966 menu
.AppendItem(item
)
967 offset
= wx
.Point(x
=0, y
=20)
968 menuSpot
= event
.GetPoint() + offset
969 self
._treeCtrl
.PopupMenu(menu
, menuSpot
)
971 self
._parentChain
= None
972 self
._introspectItem
= None
974 def GetItemChain(self
, item
):
977 if _VERBOSE
: print 'Exploding: %s' % self
._treeCtrl
.GetItemText(item
, 0)
978 while item
!= self
._root
:
979 text
= self
._treeCtrl
.GetItemText(item
, 0)
980 if _VERBOSE
: print "Appending ", text
981 parentChain
.append(text
)
982 item
= self
._treeCtrl
.GetItemParent(item
)
983 parentChain
.reverse()
986 def OnView(self
, event
):
987 title
= self
._treeCtrl
.GetItemText(self
._introspectItem
,0)
988 value
= self
._treeCtrl
.GetItemText(self
._introspectItem
,1)
989 dlg
= wx
.lib
.dialogs
.ScrolledMessageDialog(self
, value
, title
, style
=wx
.DD_DEFAULT_STYLE | wx
.RESIZE_BORDER
)
992 def OnWatch(self
, event
):
994 if hasattr(self
, '_parentChain'):
995 wd
= WatchDialog(wx
.GetApp().GetTopWindow(), "Add a Watch", self
._parentChain
)
997 wd
= WatchDialog(wx
.GetApp().GetTopWindow(), "Add a Watch", None)
998 if wd
.ShowModal() == wx
.ID_OK
:
999 name
, text
, send_frame
, run_once
= wd
.GetSettings()
1001 frameNode
= self
._stack
[int(self
.currentItem
)]
1002 message
= frameNode
.getAttribute("message")
1005 binType
= self
._ui
._callback
._debuggerServer
.add_watch(name
, text
, message
, run_once
)
1006 xmldoc
= bz2
.decompress(binType
.data
)
1007 domDoc
= parseString(xmldoc
)
1008 nodeList
= domDoc
.getElementsByTagName('watch')
1009 if len(nodeList
) == 1:
1010 watchValue
= nodeList
.item(0).getAttribute("message")
1012 tp
, val
, tb
= sys
.exc_info()
1013 traceback
.print_exception(tp
, val
, tb
)
1015 def OnIntrospect(self
, event
):
1016 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
))
1019 list = self
._framesListCtrl
1020 frameNode
= self
._stack
[int(self
.currentItem
)]
1021 message
= frameNode
.getAttribute("message")
1022 binType
= self
._ui
._callback
._debuggerServer
.attempt_introspection(message
, self
._parentChain
)
1023 xmldoc
= bz2
.decompress(binType
.data
)
1025 domDoc
= parseString(xmldoc
)
1026 nodeList
= domDoc
.getElementsByTagName('replacement')
1027 replacementNode
= nodeList
.item(0)
1028 if len(replacementNode
.childNodes
):
1029 thingToWalk
= replacementNode
.childNodes
.item(0)
1030 tree
= self
._treeCtrl
1031 parent
= tree
.GetItemParent(self
._introspectItem
)
1032 treeNode
= self
.AppendSubTreeFromNode(thingToWalk
, thingToWalk
.getAttribute('name'), parent
, insertBefore
=self
._introspectItem
)
1033 tree
.Delete(self
._introspectItem
)
1035 tp
,val
,tb
= sys
.exc_info()
1036 traceback
.print_exception(tp
, val
, tb
)
1038 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
))
1040 def OnSize(self
, event
):
1041 self
._treeCtrl
.SetSize(self
._p
2.GetSize())
1042 w
,h
= self
._p
1.GetClientSizeTuple()
1043 self
._framesListCtrl
.SetDimensions(0, 0, w
, h
)
1045 def ClearWhileRunning(self
):
1046 list = self
._framesListCtrl
1047 list.DeleteAllItems()
1048 tree
= self
._treeCtrl
1051 def OnListRightClick(self
, event
):
1052 if not hasattr(self
, "syncFrameID"):
1053 self
.syncFrameID
= wx
.NewId()
1054 self
.Bind(wx
.EVT_MENU
, self
.OnSyncFrame
, id=self
.syncFrameID
)
1056 item
= wx
.MenuItem(menu
, self
.syncFrameID
, "Goto Source Line")
1057 menu
.AppendItem(item
)
1058 self
.PopupMenu(menu
, event
.GetPosition())
1061 def OnSyncFrame(self
, event
):
1062 list = self
._framesListCtrl
1063 frameNode
= self
._stack
[int(self
.currentItem
)]
1064 file = frameNode
.getAttribute("file")
1065 line
= frameNode
.getAttribute("line")
1066 self
._ui
.SynchCurrentLine( file, int(line
) )
1068 def LoadFramesListXML(self
, framesXML
):
1069 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
))
1071 domDoc
= parseString(framesXML
)
1072 list = self
._framesListCtrl
1073 list.DeleteAllItems()
1075 nodeList
= domDoc
.getElementsByTagName('frame')
1077 for index
in range(0, nodeList
.length
):
1078 frameNode
= nodeList
.item(index
)
1079 message
= frameNode
.getAttribute("message")
1080 list.InsertStringItem(index
, message
)
1081 self
._stack
.append(frameNode
)
1083 list.Select(frame_count
)
1084 self
._p
1.FitInside()
1085 frameNode
= nodeList
.item(index
)
1086 file = frameNode
.getAttribute("file")
1087 line
= frameNode
.getAttribute("line")
1088 self
._ui
.SynchCurrentLine( file, int(line
) )
1090 tp
,val
,tb
=sys
.exc_info()
1091 traceback
.print_exception(tp
, val
, tb
)
1093 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
))
1095 def ListItemDeselected(self
, event
):
1098 def ListItemSelected(self
, event
):
1099 self
.currentItem
= event
.m_itemIndex
1100 frameNode
= self
._stack
[int(self
.currentItem
)]
1101 self
.PopulateTreeFromFrameNode(frameNode
)
1102 # Temporarily doing this to test out automatically swicting to source line.
1103 self
.OnSyncFrame(None)
1105 def PopulateTreeFromFrameNode(self
, frameNode
):
1106 tree
= self
._treeCtrl
1109 tree
.DeleteChildren(root
)
1110 children
= frameNode
.childNodes
1112 for index
in range(0, children
.length
):
1113 subNode
= children
.item(index
)
1114 treeNode
= self
.AppendSubTreeFromNode(subNode
, subNode
.getAttribute('name'), root
)
1116 firstChild
= treeNode
1118 tree
.Expand(firstChild
)
1119 self
._p
2.FitInside()
1121 def AppendSubTreeFromNode(self
, node
, name
, parent
, insertBefore
=None):
1122 tree
= self
._treeCtrl
1123 if insertBefore
!= None:
1124 treeNode
= tree
.InsertItem(parent
, insertBefore
, name
)
1126 treeNode
= tree
.AppendItem(parent
, name
)
1127 children
= node
.childNodes
1128 if children
.length
== 0:
1129 tree
.SetItemText(treeNode
, self
.StripOuterSingleQuotes(node
.getAttribute("value")), 1)
1130 for index
in range(0, children
.length
):
1131 subNode
= children
.item(index
)
1132 if self
.HasChildren(subNode
):
1133 self
.AppendSubTreeFromNode(subNode
, subNode
.getAttribute("name"), treeNode
)
1135 name
= subNode
.getAttribute("name")
1136 value
= self
.StripOuterSingleQuotes(subNode
.getAttribute("value"))
1137 n
= tree
.AppendItem(treeNode
, name
)
1138 tree
.SetItemText(n
, value
, 1)
1141 def StripOuterSingleQuotes(self
, string
):
1142 if string
.startswith("'") and string
.endswith("'"):
1144 elif type(string
) == types
.UnicodeType
:
1149 def HasChildren(self
, node
):
1151 return node
.childNodes
.length
> 0
1153 tp
,val
,tb
=sys
.exc_info()
1156 class DebuggerView(Service
.ServiceView
):
1158 #----------------------------------------------------------------------------
1159 # Overridden methods
1160 #----------------------------------------------------------------------------
1162 def __init__(self
, service
):
1163 Service
.ServiceView
.__init
__(self
, service
)
1165 def _CreateControl(self
, parent
, id):
1168 #------------------------------------------------------------------------------
1170 #-----------------------------------------------------------------------------
1172 def OnToolClicked(self
, event
):
1173 self
.GetFrame().ProcessEvent(event
)
1175 #------------------------------------------------------------------------------
1177 #-----------------------------------------------------------------------------
1180 def __init__(self
, message
, framesXML
, info
=None, quit
=False):
1181 self
._framesXML
= framesXML
1182 self
._message
= message
1186 def getFramesXML(self
):
1187 return self
._framesXML
1189 def getMessage(self
):
1190 return self
._message
1198 class AGXMLRPCServer(SimpleXMLRPCServer
.SimpleXMLRPCServer
):
1199 def __init__(self
, address
, logRequests
=0):
1200 SimpleXMLRPCServer
.SimpleXMLRPCServer
.__init
__(self
, address
, logRequests
=logRequests
)
1202 class RequestHandlerThread(threading
.Thread
):
1203 def __init__(self
, queue
, address
):
1204 threading
.Thread
.__init
__(self
)
1205 self
._keepGoing
= True
1207 self
._address
= address
1208 self
._server
= AGXMLRPCServer(self
._address
,logRequests
=0)
1209 self
._server
.register_function(self
.interaction
)
1210 self
._server
.register_function(self
.quit
)
1211 self
._server
.register_function(self
.dummyOperation
)
1212 if _VERBOSE
: print "RequestHandlerThread on fileno %s" % str(self
._server
.fileno())
1215 while self
._keepGoing
:
1217 self
._server
.handle_request()
1219 tp
, val
, tb
= sys
.exc_info()
1220 traceback
.print_exception(tp
, val
, tb
)
1221 self
._keepGoing
= False
1222 if _VERBOSE
: print "Exiting Request Handler Thread."
1224 def interaction(self
, message
, frameXML
, info
):
1225 if _VERBOSE
: print "In RequestHandlerThread.interaction -- adding to queue"
1226 interaction
= Interaction(message
, frameXML
, info
)
1227 self
._queue
.put(interaction
)
1231 interaction
= Interaction(None, None, info
=None, quit
=True)
1232 self
._queue
.put(interaction
)
1235 def dummyOperation(self
):
1238 def AskToStop(self
):
1239 self
._keepGoing
= False
1240 if type(self
._server
) is not types
.NoneType
:
1242 # This is a really ugly way to make sure this thread isn't blocked in
1244 url
= 'http://' + self
._address
[0] + ':' + str(self
._address
[1]) + '/'
1245 tempServer
= xmlrpclib
.ServerProxy(url
, allow_none
=1)
1246 tempServer
.dummyOperation()
1248 tp
, val
, tb
= sys
.exc_info()
1249 traceback
.print_exception(tp
, val
, tb
)
1250 self
._server
.server_close()
1253 class RequestBreakThread(threading
.Thread
):
1254 def __init__(self
, server
, interrupt
=False, pushBreakpoints
=False, breakDict
=None, kill
=False):
1255 threading
.Thread
.__init
__(self
)
1256 self
._server
= server
1258 self
._interrupt
= interrupt
1259 self
._pushBreakpoints
= pushBreakpoints
1260 self
._breakDict
= breakDict
1265 if _VERBOSE
: print "RequestBreakThread, before call"
1267 self
._server
.break_requested()
1268 if self
._pushBreakpoints
:
1269 self
._server
.update_breakpoints(xmlrpclib
.Binary(pickle
.dumps(self
._breakDict
)))
1275 if _VERBOSE
: print "RequestBreakThread, after call"
1277 tp
,val
,tb
= sys
.exc_info()
1278 traceback
.print_exception(tp
, val
, tb
)
1280 class DebuggerOperationThread(threading
.Thread
):
1281 def __init__(self
, function
):
1282 threading
.Thread
.__init
__(self
)
1283 self
._function
= function
1286 if _VERBOSE
: print "In DOT, before call"
1290 tp
,val
,tb
= sys
.exc_info()
1291 traceback
.print_exception(tp
, val
, tb
)
1292 if _VERBOSE
: print "In DOT, after call"
1294 class DebuggerCallback
:
1296 def __init__(self
, host
, port
, debugger_url
, break_url
, debuggerUI
):
1297 if _VERBOSE
: print "+++++++ Creating server on port, ", str(port
)
1299 self
._queue
= Queue
.Queue(50)
1301 self
._port
= int(port
)
1302 threading
._VERBOSE
= _VERBOSE
1303 self
._serverHandlerThread
= RequestHandlerThread(self
._queue
, (self
._host
, self
._port
))
1305 self
._debugger
_url
= debugger_url
1306 self
._debuggerServer
= None
1307 self
._waiting
= False
1308 self
._service
= wx
.GetApp().GetService(DebuggerService
)
1309 self
._debuggerUI
= debuggerUI
1310 self
._break
_url
= break_url
1311 self
._breakServer
= None
1312 self
._firstInteraction
= True
1313 self
._pendingBreak
= False
1316 self
._serverHandlerThread
.start()
1318 def ServerClose(self
):
1319 rbt
= RequestBreakThread(self
._breakServer
, kill
=True)
1321 self
.setWaiting(False)
1322 if self
._serverHandlerThread
:
1323 self
._serverHandlerThread
.AskToStop()
1324 self
._serverHandlerThread
= None
1326 def BreakExecution(self
):
1327 rbt
= RequestBreakThread(self
._breakServer
, interrupt
=True)
1330 def SingleStep(self
):
1331 self
._debuggerUI
.DisableWhileDebuggerRunning()
1332 #dot = DebuggerOperationThread(self._debuggerServer.set_step)
1334 self
._debuggerServer
.set_step() # Figure out where to set allowNone
1338 self
._debuggerUI
.DisableWhileDebuggerRunning()
1339 #dot = DebuggerOperationThread(self._debuggerServer.set_next)
1341 self
._debuggerServer
.set_next()
1345 self
._debuggerUI
.DisableWhileDebuggerRunning()
1346 #dot = DebuggerOperationThread(self._debuggerServer.set_continue)
1348 self
._debuggerServer
.set_continue()
1352 self
._debuggerUI
.DisableWhileDebuggerRunning()
1353 #dot = DebuggerOperationThread(self._debuggerServer.set_return)
1355 self
._debuggerServer
.set_return()
1358 def setWaiting(self
, value
):
1359 self
._waiting
= value
1361 def getWaiting(self
):
1362 return self
._waiting
1364 def readQueue(self
):
1365 if self
._queue
.qsize():
1367 item
= self
._queue
.get_nowait()
1369 self
.interaction(None, None, None, True)
1371 data
= bz2
.decompress(item
.getFramesXML().data
)
1372 self
.interaction(item
.getMessage().data
, data
, item
.getInfo(), False)
1376 def pushBreakpoints(self
):
1377 rbt
= RequestBreakThread(self
._breakServer
, pushBreakpoints
=True, breakDict
=self
._service
.GetMasterBreakpointDict())
1381 def waitForRPC(self
):
1382 self
.setWaiting(True)
1383 while self
.getWaiting():
1389 tp
, val
, tb
= sys
.exc_info()
1390 traceback
.print_exception(tp
, val
, tb
)
1391 wx
.GetApp().Yield(True)
1392 if _VERBOSE
: print "Exiting waitForRPC."
1394 def interaction(self
, message
, frameXML
, info
, quit
):
1396 #This method should be hit as the debugger starts.
1397 if self
._firstInteraction
:
1398 self
._firstInteraction
= False
1399 self
._debuggerServer
= xmlrpclib
.ServerProxy(self
._debugger
_url
, allow_none
=1)
1400 self
._breakServer
= xmlrpclib
.ServerProxy(self
._break
_url
, allow_none
=1)
1401 self
.pushBreakpoints()
1402 self
.setWaiting(False)
1403 if _VERBOSE
: print "+"*40
1405 self
._debuggerUI
.StopExecution(None)
1408 if _VERBOSE
: print "Hit interaction with exception"
1409 #self._debuggerUI.StopExecution(None)
1410 #self._debuggerUI.SetStatusText("Got exception: " + str(info))
1411 self
._debuggerUI
.SwitchToOutputTab()
1413 if _VERBOSE
: print "Hit interaction no exception"
1414 self
._debuggerUI
.SetStatusText(message
)
1415 self
._debuggerUI
.LoadFramesListXML(frameXML
)
1416 self
._debuggerUI
.EnableWhileDebuggerStopped()
1417 if _VERBOSE
: print "+"*40
1419 class DebuggerService(Service
.Service
):
1421 #----------------------------------------------------------------------------
1423 #----------------------------------------------------------------------------
1424 TOGGLE_BREAKPOINT_ID
= wx
.NewId()
1425 CLEAR_ALL_BREAKPOINTS
= wx
.NewId()
1427 DEBUG_ID
= wx
.NewId()
1428 DEBUG_WEBSERVER_ID
= wx
.NewId()
1430 def ComparePaths(first
, second
):
1431 one
= DebuggerService
.ExpandPath(first
)
1432 two
= DebuggerService
.ExpandPath(second
)
1434 return one
.lower() == two
.lower()
1437 ComparePaths
= staticmethod(ComparePaths
)
1439 # Make sure we're using an expanded path on windows.
1440 def ExpandPath(path
):
1443 return win32api
.GetLongPathName(path
)
1445 print "Cannot get long path for %s" % path
1449 ExpandPath
= staticmethod(ExpandPath
)
1451 #----------------------------------------------------------------------------
1452 # Overridden methods
1453 #----------------------------------------------------------------------------
1455 def __init__(self
, serviceName
, embeddedWindowLocation
= wx
.lib
.pydocview
.EMBEDDED_WINDOW_LEFT
):
1456 Service
.Service
.__init
__(self
, serviceName
, embeddedWindowLocation
)
1457 self
.BREAKPOINT_DICT_STRING
= "MasterBreakpointDict"
1458 config
= wx
.ConfigBase_Get()
1459 pickledbps
= config
.Read(self
.BREAKPOINT_DICT_STRING
)
1462 self
._masterBPDict
= pickle
.loads(pickledbps
.encode('ascii'))
1464 tp
, val
, tb
= sys
.exc_info()
1465 traceback
.print_exception(tp
,val
,tb
)
1466 self
._masterBPDict
= {}
1468 self
._masterBPDict
= {}
1470 def OnCloseFrame(self
, event
):
1471 # IS THIS THE RIGHT PLACE?
1473 config
= wx
.ConfigBase_Get()
1474 config
.Write(self
.BREAKPOINT_DICT_STRING
, pickle
.dumps(self
._masterBPDict
))
1476 tp
,val
,tb
= sys
.exc_info()
1477 traceback
.print_exception(tp
, val
, tb
)
1480 def _CreateView(self
):
1481 return DebuggerView(self
)
1484 #----------------------------------------------------------------------------
1485 # Service specific methods
1486 #----------------------------------------------------------------------------
1488 def InstallControls(self
, frame
, menuBar
= None, toolBar
= None, statusBar
= None, document
= None):
1489 #Service.Service.InstallControls(self, frame, menuBar, toolBar, statusBar, document)
1491 config
= wx
.ConfigBase_Get()
1493 debuggerMenu
= wx
.Menu()
1494 if not menuBar
.FindItemById(DebuggerService
.CLEAR_ALL_BREAKPOINTS
):
1496 debuggerMenu
.Append(DebuggerService
.RUN_ID
, _("&Run...\tCtrl+R"), _("Runs a file"))
1497 wx
.EVT_MENU(frame
, DebuggerService
.RUN_ID
, frame
.ProcessEvent
)
1498 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.RUN_ID
, frame
.ProcessUpdateUIEvent
)
1500 debuggerMenu
.Append(DebuggerService
.DEBUG_ID
, _("&Debug...\tCtrl+D"), _("Debugs a file"))
1501 wx
.EVT_MENU(frame
, DebuggerService
.DEBUG_ID
, frame
.ProcessEvent
)
1502 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.DEBUG_ID
, frame
.ProcessUpdateUIEvent
)
1504 if not ACTIVEGRID_BASE_IDE
:
1505 debuggerMenu
.AppendSeparator()
1506 debuggerMenu
.Append(DebuggerService
.DEBUG_WEBSERVER_ID
, _("Debug Internal Web Server"), _("Debugs the internal webservier"))
1507 wx
.EVT_MENU(frame
, DebuggerService
.DEBUG_WEBSERVER_ID
, frame
.ProcessEvent
)
1508 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.DEBUG_WEBSERVER_ID
, frame
.ProcessUpdateUIEvent
)
1510 debuggerMenu
.AppendSeparator()
1512 debuggerMenu
.Append(DebuggerService
.TOGGLE_BREAKPOINT_ID
, _("&Toggle Breakpoint...\tCtrl+B"), _("Toggle a breakpoint"))
1513 wx
.EVT_MENU(frame
, DebuggerService
.TOGGLE_BREAKPOINT_ID
, self
.ProcessEvent
)
1514 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.TOGGLE_BREAKPOINT_ID
, self
.ProcessUpdateUIEvent
)
1516 debuggerMenu
.Append(DebuggerService
.CLEAR_ALL_BREAKPOINTS
, _("&Clear All Breakpoints"), _("Clear All Breakpoints"))
1517 wx
.EVT_MENU(frame
, DebuggerService
.CLEAR_ALL_BREAKPOINTS
, self
.ProcessEvent
)
1518 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.CLEAR_ALL_BREAKPOINTS
, self
.ProcessUpdateUIEvent
)
1521 viewMenuIndex
= menuBar
.FindMenu(_("&Project"))
1522 menuBar
.Insert(viewMenuIndex
+ 1, debuggerMenu
, _("&Run"))
1528 #----------------------------------------------------------------------------
1529 # Event Processing Methods
1530 #----------------------------------------------------------------------------
1532 def ProcessEventBeforeWindows(self
, event
):
1536 def ProcessEvent(self
, event
):
1537 if Service
.Service
.ProcessEvent(self
, event
):
1540 an_id
= event
.GetId()
1541 if an_id
== DebuggerService
.TOGGLE_BREAKPOINT_ID
:
1542 self
.OnToggleBreakpoint(event
)
1544 elif an_id
== DebuggerService
.CLEAR_ALL_BREAKPOINTS
:
1545 self
.ClearAllBreakpoints()
1547 elif an_id
== DebuggerService
.RUN_ID
:
1548 self
.OnRunProject(event
)
1550 elif an_id
== DebuggerService
.DEBUG_ID
:
1551 self
.OnDebugProject(event
)
1553 elif an_id
== DebuggerService
.DEBUG_WEBSERVER_ID
:
1554 self
.OnDebugWebServer(event
)
1558 def ProcessUpdateUIEvent(self
, event
):
1559 if Service
.Service
.ProcessUpdateUIEvent(self
, event
):
1562 an_id
= event
.GetId()
1563 if an_id
== DebuggerService
.TOGGLE_BREAKPOINT_ID
:
1564 currentView
= self
.GetDocumentManager().GetCurrentView()
1565 event
.Enable(isinstance(currentView
, PythonEditor
.PythonView
))
1567 elif an_id
== DebuggerService
.CLEAR_ALL_BREAKPOINTS
:
1568 event
.Enable(self
.HasBreakpointsSet())
1570 elif (an_id
== DebuggerService
.RUN_ID
1571 or an_id
== DebuggerService
.DEBUG_ID
):
1572 event
.Enable(self
.HasAnyFiles())
1577 #----------------------------------------------------------------------------
1579 #----------------------------------------------------------------------------
1581 def OnDebugProject(self
, event
):
1582 if _WINDOWS
and not _PYWIN32_INSTALLED
:
1583 wx
.MessageBox(_("Python for Windows extensions (pywin32) is required to debug on Windows machines. Please go to http://sourceforge.net/projects/pywin32/, download and install pywin32."))
1585 if not Executor
.GetPythonExecutablePath():
1587 if DebugCommandUI
.DebuggerRunning():
1588 wx
.MessageBox(_("A debugger is already running. Please shut down the other debugger first."), _("Debugger Running"))
1590 self
.ShowWindow(True)
1591 projectService
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
)
1592 project
= projectService
.GetView().GetDocument()
1594 dlg
= CommandPropertiesDialog(self
.GetView().GetFrame(), 'Debug Python File', projectService
, None, pythonOnly
=True, okButtonName
="Debug", debugging
=True)
1597 if dlg
.ShowModal() == wx
.ID_OK
:
1598 fileToDebug
, initialArgs
, startIn
, isPython
, environment
= dlg
.GetSettings()
1603 self
.PromptToSaveFiles()
1605 shortFile
= os
.path
.basename(fileToDebug
)
1606 fileToDebug
= DebuggerService
.ExpandPath(fileToDebug
)
1608 page
= DebugCommandUI(Service
.ServiceView
.bottomTab
, -1, str(fileToDebug
), self
)
1609 count
= Service
.ServiceView
.bottomTab
.GetPageCount()
1610 Service
.ServiceView
.bottomTab
.AddPage(page
, _("Debugging: ") + shortFile
)
1611 Service
.ServiceView
.bottomTab
.SetSelection(count
)
1612 page
.Execute(initialArgs
, startIn
, environment
)
1616 def OnDebugWebServer(self
, event
):
1617 import WebServerService
1618 wsService
= wx
.GetApp().GetService(WebServerService
.WebServerService
)
1619 fileName
, args
= wsService
.StopAndPrepareToDebug()
1621 page
= DebugCommandUI(Service
.ServiceView
.bottomTab
, -1, str(fileName
), self
)
1622 count
= Service
.ServiceView
.bottomTab
.GetPageCount()
1623 Service
.ServiceView
.bottomTab
.AddPage(page
, _("Debugging: Internal WebServer"))
1624 Service
.ServiceView
.bottomTab
.SetSelection(count
)
1625 page
.Execute(args
, startIn
=os
.getcwd(), environment
=os
.environ
)
1630 def HasAnyFiles(self
):
1631 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1632 return len(docs
) > 0
1634 def PromptToSaveFiles(self
, running
=True):
1635 filesModified
= False
1636 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1638 if doc
.IsModified():
1639 filesModified
= True
1642 frame
= self
.GetView().GetFrame()
1644 yesNoMsg
= wx
.MessageDialog(frame
,
1645 _("Files have been modified.\nWould you like to save all files before running?"),
1647 wx
.YES_NO|wx
.ICON_QUESTION
1650 yesNoMsg
= wx
.MessageDialog(frame
,
1651 _("Files have been modified.\nWould you like to save all files before debugging?"),
1653 wx
.YES_NO|wx
.ICON_QUESTION
1655 if yesNoMsg
.ShowModal() == wx
.ID_YES
:
1656 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1661 DebugCommandUI
.ShutdownAllDebuggers()
1663 def OnRunProject(self
, event
):
1664 if _WINDOWS
and not _PYWIN32_INSTALLED
:
1665 wx
.MessageBox(_("Python for Windows extensions (pywin32) is required to run on Windows machines. Please go to http://sourceforge.net/projects/pywin32/, download and install pywin32."))
1667 if not Executor
.GetPythonExecutablePath():
1669 projectService
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
)
1670 project
= projectService
.GetView().GetDocument()
1672 dlg
= CommandPropertiesDialog(self
.GetView().GetFrame(), 'Run', projectService
, None)
1675 if dlg
.ShowModal() == wx
.ID_OK
:
1676 fileToRun
, initialArgs
, startIn
, isPython
, environment
= dlg
.GetSettings()
1683 self
.PromptToSaveFiles()
1684 # This will need to change when we can run more than .py and .bpel files.
1686 projectService
.RunProcessModel(fileToRun
)
1689 self
.ShowWindow(True)
1690 shortFile
= os
.path
.basename(fileToRun
)
1691 page
= RunCommandUI(Service
.ServiceView
.bottomTab
, -1, str(fileToRun
))
1692 count
= Service
.ServiceView
.bottomTab
.GetPageCount()
1693 Service
.ServiceView
.bottomTab
.AddPage(page
, "Running: " + shortFile
)
1694 Service
.ServiceView
.bottomTab
.SetSelection(count
)
1695 page
.Execute(initialArgs
, startIn
, environment
)
1697 def OnToggleBreakpoint(self
, event
, line
=-1, fileName
=None):
1699 view
= wx
.GetApp().GetDocumentManager().GetCurrentView()
1700 # Test to make sure we aren't the project view.
1701 if not hasattr(view
, 'MarkerExists'):
1703 fileName
= wx
.GetApp().GetDocumentManager().GetCurrentDocument().GetFilename()
1705 line
= view
.GetCtrl().GetCurrentLine()
1706 if self
.BreakpointSet(fileName
, line
+ 1):
1707 self
.ClearBreak(fileName
, line
+ 1)
1709 self
.SetBreak(fileName
, line
+ 1)
1710 # Now refresh all the markers icons in all the open views.
1711 self
.ClearAllBreakpointMarkers()
1712 self
.SetAllBreakpointMarkers()
1714 def SilentToggleBreakpoint(self
, fileName
, line
):
1716 for lineNumber
in self
.GetBreakpointList(fileName
):
1717 if int(lineNumber
) == int(line
):
1721 self
.SetBreak(fileName
, line
)
1723 self
.ClearBreak(fileName
, line
)
1725 def SetBreak(self
, fileName
, line
):
1726 expandedName
= DebuggerService
.ExpandPath(fileName
)
1727 if not self
._masterBPDict
.has_key(expandedName
):
1728 self
._masterBPDict
[expandedName
] = [line
]
1730 self
._masterBPDict
[expandedName
] += [line
]
1731 # If we're already debugging, pass this bp off to the DebuggerCallback
1732 self
.NotifyDebuggersOfBreakpointChange()
1734 def NotifyDebuggersOfBreakpointChange(self
):
1735 DebugCommandUI
.NotifyDebuggersOfBreakpointChange()
1737 def GetBreakpointList(self
, fileName
):
1738 expandedName
= DebuggerService
.ExpandPath(fileName
)
1739 if not self
._masterBPDict
.has_key(expandedName
):
1742 return self
._masterBPDict
[expandedName
]
1744 def BreakpointSet(self
, fileName
, line
):
1745 expandedName
= DebuggerService
.ExpandPath(fileName
)
1746 if not self
._masterBPDict
.has_key(expandedName
):
1750 for number
in self
._masterBPDict
[expandedName
]:
1751 if(int(number
) == int(line
)):
1755 def ClearBreak(self
, fileName
, line
):
1756 expandedName
= DebuggerService
.ExpandPath(fileName
)
1757 if not self
._masterBPDict
.has_key(expandedName
):
1758 print "In ClearBreak: no key"
1762 for number
in self
._masterBPDict
[expandedName
]:
1763 if(int(number
) != int(line
)):
1764 newList
.append(number
)
1765 self
._masterBPDict
[expandedName
] = newList
1766 self
.NotifyDebuggersOfBreakpointChange()
1768 def HasBreakpointsSet(self
):
1769 for key
, value
in self
._masterBPDict
.items():
1774 def ClearAllBreakpoints(self
):
1775 self
._masterBPDict
= {}
1776 self
.NotifyDebuggersOfBreakpointChange()
1777 self
.ClearAllBreakpointMarkers()
1779 def ClearAllBreakpointMarkers(self
):
1780 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1781 for openDoc
in openDocs
:
1782 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
1783 openDoc
.GetFirstView().MarkerDeleteAll(CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
)
1785 def GetMasterBreakpointDict(self
):
1786 return self
._masterBPDict
1788 def SetAllBreakpointMarkers(self
):
1789 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1790 for openDoc
in openDocs
:
1791 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
1792 self
.SetCurrentBreakpointMarkers(openDoc
.GetFirstView())
1794 def SetCurrentBreakpointMarkers(self
, view
):
1795 if isinstance(view
, CodeEditor
.CodeView
) and hasattr(view
, 'GetDocument'):
1796 view
.MarkerDeleteAll(CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
)
1797 for linenum
in self
.GetBreakpointList(view
.GetDocument().GetFilename()):
1798 view
.MarkerAdd(lineNum
=int(linenum
) - 1, marker_index
=CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
)
1800 class DebuggerOptionsPanel(wx
.Panel
):
1803 def __init__(self
, parent
, id):
1804 wx
.Panel
.__init
__(self
, parent
, id)
1806 config
= wx
.ConfigBase_Get()
1807 localHostStaticText
= wx
.StaticText(self
, -1, _("Local Host Name:"))
1808 self
._LocalHostTextCtrl
= wx
.TextCtrl(self
, -1, config
.Read("DebuggerHostName", DEFAULT_HOST
), size
= (150, -1))
1809 portNumberStaticText
= wx
.StaticText(self
, -1, _("Port Range:"))
1810 dashStaticText
= wx
.StaticText(self
, -1, _("through to"))
1811 startingPort
=config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
)
1812 self
._PortNumberTextCtrl
= wx
.lib
.intctrl
.IntCtrl(self
, -1, startingPort
, size
= (50, -1))
1813 self
._PortNumberTextCtrl
.SetMin(1)#What are real values?
1814 self
._PortNumberTextCtrl
.SetMax(65514) #What are real values?
1815 self
.Bind(wx
.lib
.intctrl
.EVT_INT
, self
.MinPortChange
, self
._PortNumberTextCtrl
)
1817 self
._EndPortNumberTextCtrl
= wx
.lib
.intctrl
.IntCtrl(self
, -1, startingPort
+ PORT_COUNT
, size
= (50, -1))
1818 self
._EndPortNumberTextCtrl
.SetMin(22)#What are real values?
1819 self
._EndPortNumberTextCtrl
.SetMax(65535)#What are real values?
1820 self
._EndPortNumberTextCtrl
.Enable( False )
1821 debuggerPanelBorderSizer
= wx
.BoxSizer(wx
.VERTICAL
)
1822 debuggerPanelSizer
= wx
.GridBagSizer(hgap
= 5, vgap
= 5)
1823 debuggerPanelSizer
.Add( localHostStaticText
, (0,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
1824 debuggerPanelSizer
.Add( self
._LocalHostTextCtrl
, (0,1), (1,3), flag
=wx
.EXPAND|wx
.ALIGN_CENTER
)
1825 debuggerPanelSizer
.Add( portNumberStaticText
, (1,0), flag
=wx
.ALIGN_LEFT|wx
.ALIGN_CENTER_VERTICAL
)
1826 debuggerPanelSizer
.Add( self
._PortNumberTextCtrl
, (1,1), flag
=wx
.ALIGN_CENTER
)
1827 debuggerPanelSizer
.Add( dashStaticText
, (1,2), flag
=wx
.ALIGN_CENTER
)
1828 debuggerPanelSizer
.Add( self
._EndPortNumberTextCtrl
, (1,3), flag
=wx
.ALIGN_CENTER
)
1829 FLUSH_PORTS_ID
= wx
.NewId()
1830 self
._flushPortsButton
= wx
.Button(self
, FLUSH_PORTS_ID
, "Reset Port List")
1831 wx
.EVT_BUTTON(parent
, FLUSH_PORTS_ID
, self
.FlushPorts
)
1832 debuggerPanelSizer
.Add(self
._flushPortsButton
, (2,2), (1,2), flag
=wx
.ALIGN_RIGHT
)
1834 debuggerPanelBorderSizer
.Add(debuggerPanelSizer
, 0, wx
.ALL
, SPACE
)
1835 self
.SetSizer(debuggerPanelBorderSizer
)
1837 parent
.AddPage(self
, _("Debugger"))
1839 def FlushPorts(self
, event
):
1840 if self
._PortNumberTextCtrl
.IsInBounds():
1841 config
= wx
.ConfigBase_Get()
1842 config
.WriteInt("DebuggerStartingPort", self
._PortNumberTextCtrl
.GetValue())
1843 DebugCommandUI
.NewPortRange()
1845 wx
.MessageBox(_("The starting port is not valid. Please change the value and try again.", "Invalid Starting Port Number"))
1847 def MinPortChange(self
, event
):
1848 self
._EndPortNumberTextCtrl
.Enable( True )
1849 self
._EndPortNumberTextCtrl
.SetValue( self
._PortNumberTextCtrl
.GetValue() + PORT_COUNT
)
1850 self
._EndPortNumberTextCtrl
.Enable( False )
1852 def OnOK(self
, optionsDialog
):
1853 config
= wx
.ConfigBase_Get()
1854 config
.Write("DebuggerHostName", self
._LocalHostTextCtrl
.GetValue())
1855 if self
._PortNumberTextCtrl
.IsInBounds():
1856 config
.WriteInt("DebuggerStartingPort", self
._PortNumberTextCtrl
.GetValue())
1858 class CommandPropertiesDialog(wx
.Dialog
):
1860 def __init__(self
, parent
, title
, projectService
, currentProjectDocument
, pythonOnly
=False, okButtonName
="Run", debugging
=False):
1861 self
._projService
= projectService
1864 for template
in self
._projService
.GetDocumentManager().GetTemplates():
1865 if not ACTIVEGRID_BASE_IDE
and template
.GetDocumentType() == ProcessModelEditor
.ProcessModelDocument
:
1866 self
._pmext
= template
.GetDefaultExtension()
1867 if template
.GetDocumentType() == PythonEditor
.PythonDocument
:
1868 self
._pyext
= template
.GetDefaultExtension()
1869 self
._pythonOnly
= pythonOnly
1870 self
._currentProj
= currentProjectDocument
1871 self
._projectNameList
, self
._projectDocumentList
, selectedIndex
= self
.GetProjectList()
1872 if not self
._projectNameList
:
1873 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"))
1876 wx
.Dialog
.__init
__(self
, parent
, -1, title
)
1878 wx
.Dialog
.__init
__(self
, parent
, -1, title
, size
=(390,270))
1880 projStaticText
= wx
.StaticText(self
, -1, _("Project:"))
1881 fileStaticText
= wx
.StaticText(self
, -1, _("File:"))
1882 argsStaticText
= wx
.StaticText(self
, -1, _("Arguments:"))
1883 startInStaticText
= wx
.StaticText(self
, -1, _("Start in:"))
1884 pythonPathStaticText
= wx
.StaticText(self
, -1, _("PYTHONPATH:"))
1885 postpendStaticText
= _("Postpend win32api path")
1886 cpPanelBorderSizer
= wx
.BoxSizer(wx
.VERTICAL
)
1887 self
._projList
= wx
.Choice(self
, -1, (200,-1), choices
=self
._projectNameList
)
1888 self
.Bind(wx
.EVT_CHOICE
, self
.EvtListBox
, self
._projList
)
1890 flexGridSizer
= wx
.FlexGridSizer(cols
= 3, vgap
= 10, hgap
= 10)
1892 flexGridSizer
.Add(projStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
1893 flexGridSizer
.Add(self
._projList
, 1, flag
=wx
.EXPAND
)
1894 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
1896 flexGridSizer
.Add(fileStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
1897 self
._fileList
= wx
.Choice(self
, -1, (200,-1))
1898 self
.Bind(wx
.EVT_CHOICE
, self
.OnFileSelected
, self
._fileList
)
1899 flexGridSizer
.Add(self
._fileList
, 1, flag
=wx
.EXPAND
)
1900 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
1902 config
= wx
.ConfigBase_Get()
1903 self
._lastArguments
= config
.Read("LastRunArguments")
1904 self
._argsEntry
= wx
.TextCtrl(self
, -1, str(self
._lastArguments
))
1905 self
._argsEntry
.SetToolTipString(str(self
._lastArguments
))
1907 flexGridSizer
.Add(argsStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
1908 flexGridSizer
.Add(self
._argsEntry
, 1, flag
=wx
.EXPAND
)
1909 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
1911 flexGridSizer
.Add(startInStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
1912 self
._lastStartIn
= config
.Read("LastRunStartIn")
1913 if not self
._lastStartIn
:
1914 self
._lastStartIn
= str(os
.getcwd())
1915 self
._startEntry
= wx
.TextCtrl(self
, -1, self
._lastStartIn
)
1916 self
._startEntry
.SetToolTipString(self
._lastStartIn
)
1917 def TextChanged2(event
):
1918 self
._startEntry
.SetToolTipString(event
.GetString())
1919 self
.Bind(wx
.EVT_TEXT
, TextChanged2
, self
._startEntry
)
1921 flexGridSizer
.Add(self
._startEntry
, 1, wx
.EXPAND
)
1922 self
._findDir
= wx
.Button(self
, -1, _("Browse..."))
1923 self
.Bind(wx
.EVT_BUTTON
, self
.OnFindDirClick
, self
._findDir
)
1924 flexGridSizer
.Add(self
._findDir
, 0, wx
.RIGHT
, 10)
1926 flexGridSizer
.Add(pythonPathStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
1927 if os
.environ
.has_key('PYTHONPATH'):
1928 startval
= os
.environ
['PYTHONPATH']
1931 self
._lastPythonPath
= config
.Read("LastPythonPath", startval
)
1932 self
._pythonPathEntry
= wx
.TextCtrl(self
, -1, self
._lastPythonPath
)
1933 self
._pythonPathEntry
.SetToolTipString(self
._lastPythonPath
)
1934 flexGridSizer
.Add(self
._pythonPathEntry
, 1, wx
.EXPAND
)
1935 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
1936 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
1938 self
._postpendCheckBox
= wx
.CheckBox(self
, -1, postpendStaticText
)
1939 checked
= bool(config
.ReadInt("PythonPathPostpend", 1))
1940 self
._postpendCheckBox
.SetValue(checked
)
1941 flexGridSizer
.Add(self
._postpendCheckBox
, 1, wx
.EXPAND
)
1942 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
1943 cpPanelBorderSizer
.Add(flexGridSizer
, 0, wx
.ALL
, 10)
1945 box
= wx
.BoxSizer(wx
.HORIZONTAL
)
1946 self
._okButton
= wx
.Button(self
, wx
.ID_OK
, okButtonName
)
1947 self
._okButton
.SetDefault()
1948 self
._okButton
.SetHelpText(_("The ") + okButtonName
+ _(" button completes the dialog"))
1949 box
.Add(self
._okButton
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5)
1950 self
.Bind(wx
.EVT_BUTTON
, self
.OnOKClick
, self
._okButton
)
1951 btn
= wx
.Button(self
, wx
.ID_CANCEL
, _("Cancel"))
1952 btn
.SetHelpText(_("The Cancel button cancels the dialog."))
1953 box
.Add(btn
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5)
1954 cpPanelBorderSizer
.Add(box
, 0, wx
.ALIGN_RIGHT|wx
.BOTTOM
, 5)
1956 self
.SetSizer(cpPanelBorderSizer
)
1958 self
.GetSizer().Fit(self
)
1962 # Set up selections based on last values used.
1963 self
._fileNameList
= None
1964 self
._selectedFileIndex
= 0
1965 lastProject
= config
.Read("LastRunProject")
1966 lastFile
= config
.Read("LastRunFile")
1968 if lastProject
in self
._projectNameList
:
1969 selectedIndex
= self
._projectNameList
.index(lastProject
)
1970 elif selectedIndex
< 0:
1972 self
._projList
.Select(selectedIndex
)
1973 self
._selectedProjectIndex
= selectedIndex
1974 self
._selectedProjectDocument
= self
._projectDocumentList
[selectedIndex
]
1975 self
.PopulateFileList(self
._selectedProjectDocument
, lastFile
)
1977 def OnOKClick(self
, event
):
1978 startIn
= self
._startEntry
.GetValue()
1979 fileToRun
= self
._fileList
.GetStringSelection()
1981 wx
.MessageBox(_("You must select a file to proceed. Note that not all projects have files that can be run or debugged."))
1983 isPython
= fileToRun
.endswith(self
._pyext
)
1984 if isPython
and not os
.path
.exists(startIn
):
1985 wx
.MessageBox(_("Starting directory does not exist. Please change this value."))
1987 config
= wx
.ConfigBase_Get()
1988 config
.Write("LastRunProject", self
._projectNameList
[self
._selectedProjectIndex
])
1989 config
.Write("LastRunFile", fileToRun
)
1990 # Don't update the arguments or starting directory unless we're runing python.
1992 config
.Write("LastRunArguments", self
._argsEntry
.GetValue())
1993 config
.Write("LastRunStartIn", self
._startEntry
.GetValue())
1994 config
.Write("LastPythonPath",self
._pythonPathEntry
.GetValue())
1995 if hasattr(self
, "_postpendCheckBox"):
1996 config
.WriteInt("PythonPathPostpend", int(self
._postpendCheckBox
.GetValue()))
1998 self
.EndModal(wx
.ID_OK
)
2000 def GetSettings(self
):
2001 filename
= self
._fileNameList
[self
._selectedFileIndex
]
2002 args
= self
._argsEntry
.GetValue()
2003 startIn
= self
._startEntry
.GetValue()
2004 isPython
= filename
.endswith(self
._pyext
)
2006 if hasattr(self
, "_postpendCheckBox"):
2007 postpend
= self
._postpendCheckBox
.GetValue()
2011 env
['PYTHONPATH'] = self
._pythonPathEntry
.GetValue() + os
.pathsep
+ os
.path
.join(os
.getcwd(), "3rdparty", "pywin32")
2013 env
['PYTHONPATH'] = self
._pythonPathEntry
.GetValue()
2015 return filename
, args
, startIn
, isPython
, env
2017 def OnFileSelected(self
, event
):
2018 self
._selectedFileIndex
= self
._fileList
.GetSelection()
2019 self
.EnableForFileType(event
.GetString())
2021 def EnableForFileType(self
, fileName
):
2022 show
= fileName
.endswith(self
._pyext
)
2023 self
._startEntry
.Enable(show
)
2024 self
._findDir
.Enable(show
)
2025 self
._argsEntry
.Enable(show
)
2028 self
._lastStartIn
= self
._startEntry
.GetValue()
2029 self
._startEntry
.SetValue("")
2030 self
._lastArguments
= self
._argsEntry
.GetValue()
2031 self
._argsEntry
.SetValue("")
2033 self
._startEntry
.SetValue(self
._lastStartIn
)
2034 self
._argsEntry
.SetValue(self
._lastArguments
)
2038 def OnFindDirClick(self
, event
):
2039 dlg
= wx
.DirDialog(self
, "Choose a starting directory:", self
._startEntry
.GetValue(),
2040 style
=wx
.DD_DEFAULT_STYLE|wx
.DD_NEW_DIR_BUTTON
)
2042 if dlg
.ShowModal() == wx
.ID_OK
:
2043 self
._startEntry
.SetValue(dlg
.GetPath())
2047 def EvtListBox(self
, event
):
2048 if event
.GetString():
2049 index
= self
._projectNameList
.index(event
.GetString())
2050 self
._selectedProjectDocument
= self
._projectDocumentList
[index
]
2051 self
._selectedProjectIndex
= index
2052 self
.PopulateFileList(self
._selectedProjectDocument
)
2054 def FilterFileList(self
, list):
2055 if self
._pythonOnly
:
2056 files
= filter(lambda f
: f
.endswith(self
._pyext
), list)
2058 files
= filter(lambda f
: (self
._pmext
and f
.endswith(self
._pmext
)) or f
.endswith(self
._pyext
), list)
2061 def PopulateFileList(self
, project
, shortNameToSelect
=None):
2062 self
._fileNameList
= self
.FilterFileList(project
.GetFiles()[:])
2063 self
._fileList
.Clear()
2064 if not self
._fileNameList
:
2066 self
._fileNameList
.sort(lambda a
, b
: cmp(os
.path
.basename(a
).lower(), os
.path
.basename(b
).lower()))
2067 strings
= map(lambda file: os
.path
.basename(file), self
._fileNameList
)
2068 for index
in range(0, len(strings
)):
2069 if shortNameToSelect
== strings
[index
]:
2070 self
._selectedFileIndex
= index
2072 self
._fileList
.Hide()
2073 self
._fileList
.AppendItems(strings
)
2074 self
._fileList
.Show()
2075 if self
._selectedFileIndex
not in range(0, len(strings
)) : self
._selectedFileIndex
= 0
2076 self
._fileList
.SetSelection(self
._selectedFileIndex
)
2077 self
.EnableForFileType(strings
[self
._selectedFileIndex
])
2079 def GetProjectList(self
):
2085 for document
in self
._projService
.GetDocumentManager().GetDocuments():
2086 if document
.GetDocumentTemplate().GetDocumentType() == ProjectEditor
.ProjectDocument
and len(document
.GetFiles()):
2087 docList
.append(document
)
2088 nameList
.append(os
.path
.basename(document
.GetFilename()))
2089 if document
== self
._currentProj
:
2093 #Check for open files not in any of these projects and add them to a default project
2094 def AlreadyInProject(fileName
):
2095 for projectDocument
in docList
:
2096 if projectDocument
.IsFileInProject(fileName
):
2100 unprojectedFiles
= []
2101 for document
in self
._projService
.GetDocumentManager().GetDocuments():
2102 if not ACTIVEGRID_BASE_IDE
and type(document
) == ProcessModelEditor
.ProcessModelDocument
:
2103 if not AlreadyInProject(document
.GetFilename()):
2104 unprojectedFiles
.append(document
.GetFilename())
2105 if type(document
) == PythonEditor
.PythonDocument
:
2106 if not AlreadyInProject(document
.GetFilename()):
2107 unprojectedFiles
.append(document
.GetFilename())
2109 if unprojectedFiles
:
2110 unprojProj
= ProjectEditor
.ProjectDocument()
2111 unprojProj
.SetFilename(_("Not in any Project"))
2112 unprojProj
.AddFiles(unprojectedFiles
)
2113 docList
.append(unprojProj
)
2114 nameList
.append(_("Not in any Project"))
2116 return nameList
, docList
, index
2119 #----------------------------------------------------------------------
2120 from wx
import ImageFromStream
, BitmapFromImage
2123 #----------------------------------------------------------------------
2126 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x02\
2127 \x00\x00\x00\x90\x91h6\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\
2128 \x00\x85IDAT(\x91\xbd\x92A\x16\x03!\x08CI\xdf\xdc\x0b\x8e\xe6\xd1\xe0d\xe9\
2129 \x82\xd6\xc7(\x9di7\xfd\xab<\x14\x13Q\xb8\xbb\xfc\xc2\xe3\xd3\x82\x99\xb9\
2130 \xe9\xaeq\xe1`f)HF\xc4\x8dC2\x06\xbf\x8a4\xcf\x1e\x03K\xe5h\x1bH\x02\x98\xc7\
2131 \x03\x98\xa9z\x07\x00%\xd6\xa9\xd27\x90\xac\xbbk\xe5\x15I\xcdD$\xdc\xa7\xceT\
2132 5a\xce\xf3\xe4\xa0\xaa\x8bO\x12\x11\xabC\xcb\x9c}\xd57\xef\xb0\xf3\xb7\x86p\
2133 \x97\xf7\xb5\xaa\xde\xb9\xfa|-O\xbdjN\x9b\xf8\x06A\xcb\x00\x00\x00\x00IEND\
2136 def getBreakBitmap():
2137 return BitmapFromImage(getBreakImage())
2139 def getBreakImage():
2140 stream
= cStringIO
.StringIO(getBreakData())
2141 return ImageFromStream(stream
)
2144 return wx
.IconFromBitmap(getBreakBitmap())
2146 #----------------------------------------------------------------------
2147 def getClearOutputData():
2149 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2150 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2151 \x00\x00\xb4IDAT8\x8d\xa5\x92\xdd\r\x03!\x0c\x83\xbf\xa0n\xd4\x9d\xda5\xb81\
2152 \xbaS\xbb\x12\xee\x03?\xe5\x08\xe5N\xba\xbc Db\xec\xd8p\xb1l\xb8\xa7\x83\xfe\
2153 \xb0\x02H\x92F\xc0_\xa3\x99$\x99\x99\xedznc\xe36\x81\x88\x98"\xb2\x02\xa2\
2154 \x1e\xc4Q\x9aUD\x161\xcd\xde\x1c\x83\x15\x084)\x8d\xc5)\x06\xab\xaaZ\x92\xee\
2155 \xce\x11W\xdbGD\x0cIT\x06\xe7\x00\xdeY\xfe\xcc\x89\x06\xf0\xf2\x99\x00\xe0\
2156 \x91\x7f\xab\x83\xed\xa4\xc8\xafK\x0c\xcf\x92\x83\x99\x8d\xe3p\xef\xe4\xa1\
2157 \x0b\xe57j\xc8:\x06\t\x08\x87.H\xb2n\xa8\xc9\xa9\x12vQ\xfeG"\xe3\xacw\x00\
2158 \x10$M\xd3\x86_\xf0\xe5\xfc\xb4\xfa\x02\xcb\x13j\x10\xc5\xd7\x92D\x00\x00\
2159 \x00\x00IEND\xaeB`\x82'
2161 def getClearOutputBitmap():
2162 return BitmapFromImage(getClearOutputImage())
2164 def getClearOutputImage():
2165 stream
= cStringIO
.StringIO(getClearOutputData())
2166 return ImageFromStream(stream
)
2168 def getClearOutputIcon():
2169 return wx
.IconFromBitmap(getClearOutputBitmap())
2171 #----------------------------------------------------------------------
2174 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x02\
2175 \x00\x00\x00\x90\x91h6\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\
2176 \x00\xedIDAT(\x91\xa5\x90!\xae\x840\x10\x86g_\xd6"*kz\x82j\xb0h\x1c\t\' x\
2177 \x92Z\xc2\x05\x10\x95\x18\x0e\x00\x02M\x82 \xe1\nMF#jz\x80\xea&+\x9a\x10\x96\
2178 \xdd}\xfb\xc8\x1b\xd7?\xdf\x97\xfe3\xb7u]\xe1\xca\xfc\\\xa2\xff- \xe24M\xc7\
2179 \xc49wJ\xee\xc7G]\xd7\x8c1\xc6\x18\xe7\xdc\'B\x08k\xed1y\xfaa\x1cG\xad\xb5\
2180 \x94\x12\x11\x9dsy\x9e+\xa5\x84\x10;\r\x00\xb7\xd3\x95\x8c1UU\x05A\x00\x00\
2181 \xd6\xda,\xcb\x92$\xf9\xb8\x03\x00PJ\x85\x10Zk\xa5\xd4+\xfdF\x00\x80\xae\xeb\
2182 \x08!\x84\x90y\x9e\x11\xf1\x8bP\x96\xa5\xef\xdd\xb6\xad\xb5VJ\xf9\x9b\xe0\
2183 \xe9\xa6i8\xe7\xbe\xdb\xb6mi\x9a\x0e\xc3\xf0F\x88\xe3\x18\x00\xfa\xbe\x0f\
2184 \xc3\xd0\'\x9c\xf3eY\xa2(*\x8ab\xc7\x9e\xaed\x8c\xa1\x94\xben\xf5\xb1\xd2W\
2185 \xfa,\xfce.\x0b\x0f\xb8\x96e\x90gS\xe0v\x00\x00\x00\x00IEND\xaeB`\x82'
2187 def getCloseBitmap():
2188 return BitmapFromImage(getCloseImage())
2190 def getCloseImage():
2191 stream
= cStringIO
.StringIO(getCloseData())
2192 return ImageFromStream(stream
)
2195 return wx
.IconFromBitmap(getCloseBitmap())
2197 #----------------------------------------------------------------------
2198 def getContinueData():
2200 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2201 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2202 \x00\x00\x9eIDAT8\x8d\xbd\x92\xd1\r\x83@\x0cC\xed\x8a\x11X\xac\x1b\xddF,\xd6\
2203 \x11\x90\xdc\x0f\x9a\x93s)\x14Z\xa9\x91\x10\n\x97\xbc\xd89\x80?\x84\x1a\xa4\
2204 \x83\xfc\x1c$\x1e)7\xdf<Y0\xaf\x0b\xe6\xf5\x1d\xa1\xb5\x13C\x03 !\xaa\xfd\
2205 \xed\n:mr\xc0\x1d\x8f\xc9\x9a!\t$\xe5\xd3I\xe2\xe5B$\x99\x00[\x01\xe8\xc5\
2206 \xd9G\xfaN`\xd8\x81I\xed\x8c\xb19\x94\x8d\xcbL\x00;t\xcf\x9fwPh\xdb\x0e\xe8\
2207 \xd3,\x17\x8b\xc7\x9d\xbb>\x8a \xec5\x94\tc\xc4\x12\xab\x94\xeb\x7fkWr\xc9B%\
2208 \xfc\xd2\xfcM<\x01\xf6tn\x12O3c\xe6\x00\x00\x00\x00IEND\xaeB`\x82'
2210 def getContinueBitmap():
2211 return BitmapFromImage(getContinueImage())
2213 def getContinueImage():
2214 stream
= cStringIO
.StringIO(getContinueData())
2215 return ImageFromStream(stream
)
2217 def getContinueIcon():
2218 return wx
.IconFromBitmap(getContinueBitmap())
2220 #----------------------------------------------------------------------
2223 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2224 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2225 \x00\x00\x8eIDAT8\x8d\xa5SA\x12\xc4 \x08K\xb0\xff\xde\xe9\xbf\xb7\xa6\x87\
2226 \x1d:\xba\xa2tZn(\x84`"i\x05obk\x13\xd5CmN+\xcc\x00l\xd6\x0c\x00\xf5\xf8\x0e\
2227 gK\x06\x00 \xa5=k\x00\x00\xb0\xb2]\xd4?5f\xb1\xdb\xaf\xc6\xa2\xcb\xa8\xf0?\
2228 \x1c\x98\xae\x82\xbf\x81\xa4\x8eA\x16\xe1\n\xd1\xa4\x19\xb3\xe9\n\xce\xe8\
2229 \xf1\n\x9eg^\x18\x18\x90\xec<\x11\xf9#\x04XMZ\x19\xaac@+\x94\xd4\x99)SeP\xa1\
2230 )\xd6\x1dI\xe7*\xdc\xf4\x03\xdf~\xe7\x13T^Q?:X\x19d\x00\x00\x00\x00IEND\xaeB\
2233 def getNextBitmap():
2234 return BitmapFromImage(getNextImage())
2237 stream
= cStringIO
.StringIO(getNextData())
2238 return ImageFromStream(stream
)
2241 return wx
.IconFromBitmap(getNextBitmap())
2243 #----------------------------------------------------------------------
2244 def getStepInData():
2246 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2247 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2248 \x00\x00\x87IDAT8\x8d\xadSA\x12\x84 \x0ck\x8a\xffv\xfc\xb74{X\xeb0P@\x07s\
2249 \x84\xa4$\x01\x00M\xb2\x02]R\x8b\xc86\xda\xdc\xedd\xb4~\xe8\x86\xc6\x01-\x93\
2250 \x96\xd9#\xf6\x06\xc3;p1I\xd1\x14\x0b#|\x17aF\xec\r\xeeF\xa0eB\xd34\xca\xd0A\
2251 ]j\x84\xa6\x03\x00""\xb7\xb0tRZ\xf7x\xb7\x83\x91]\xcb\x7fa\xd9\x89\x0fC\xfd\
2252 \x94\x9d|9\x99^k\x13\xa1 \xb3\x16\x0f#\xd4\x88N~\x14\xe1-\x96\x7f\xe3\x0f\
2253 \x11\x91UC\x0cX\'\x1e\x00\x00\x00\x00IEND\xaeB`\x82'
2255 def getStepInBitmap():
2256 return BitmapFromImage(getStepInImage())
2258 def getStepInImage():
2259 stream
= cStringIO
.StringIO(getStepInData())
2260 return ImageFromStream(stream
)
2262 def getStepInIcon():
2263 return wx
.IconFromBitmap(getStepInBitmap())
2265 #----------------------------------------------------------------------
2268 "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2269 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2270 \x00\x00FIDAT8\x8d\xed\x91\xc1\t\xc00\x0c\x03O!\x0b\xa9\xfb\xef\xa6\xfcB\xa1\
2271 N\t\xf4Wr\xa0\x8f\xb1\x0f\x81\xe1\x97\xe4-\xb6}_V%\xc8\xc2, \t\x92\xe6]\xfbZ\
2272 \xf7\x08\xa0W\xc3\xea5\xdb\rl_IX\xe5\xf0d\x00\xfa\x8d#\x7f\xc4\xf7'\xab\x00\
2273 \x00\x00\x00IEND\xaeB`\x82"
2275 def getStopBitmap():
2276 return BitmapFromImage(getStopImage())
2279 stream
= cStringIO
.StringIO(getStopData())
2280 return ImageFromStream(stream
)
2283 return wx
.IconFromBitmap(getStopBitmap())
2285 #----------------------------------------------------------------------
2286 def getStepReturnData():
2288 "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2289 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2290 \x00\x00\x8dIDAT8\x8d\xa5S\xd1\x0e\xc4 \x08\xa3\xb0\xff\xbe\xdc\x7fO\xba'6\
2291 \xf1\xf44\xb3O$Phk\x04\xd4d\x07\xba\xc5\x16\x91#\nza\xdb\x84\x1a\xa2\xfe\xf8\
2292 \x99\xfa_=p+\xe8\x91ED\xbc<\xa4 \xb4\x0b\x01\xb5{\x01\xf9\xbbG-\x13\x87\x16f\
2293 \x84\xbf\x16V\xb0l\x01@\no\x86\xae\x82Q\xa8=\xa4\x0c\x80\xe70\xbd\x10jh\xbd\
2294 \x07R\x06#\xc9^N\xb6\xde\x03)\x83\x18\xaeU\x90\x9c>a\xb2P\r\xb3&/Y\xa8\xd1^^\
2295 \xb6\xf0\x16\xdb\xbf\xf1\x02\x81\xa5TK\x1d\x07\xde\x92\x00\x00\x00\x00IEND\
2298 def getStepReturnBitmap():
2299 return BitmapFromImage(getStepReturnImage())
2301 def getStepReturnImage():
2302 stream
= cStringIO
.StringIO(getStepReturnData())
2303 return ImageFromStream(stream
)
2305 def getStepReturnIcon():
2306 return wx
.IconFromBitmap(getStepReturnBitmap())
2308 #----------------------------------------------------------------------
2309 def getAddWatchData():
2311 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2312 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2313 \x00\x00\x85IDAT8\x8dc`\x18h\xc0\x88.\xd0\xc0\xf0\xff?*\x9f\x11C\rN\x80\xae\
2314 \x19\x97\x18\xd1\x9a\x896\x84\x18[p\xa9aA\xe6\xfc7f\xc0P\xc4x\x163\x9cp\x1a0\
2315 \xeb,!w\x100 \x1dK\xac\x10\r\x08\x05".yFL\x85\x8c\x18b\xa8|Ty\xa2\x13\x92\'\
2316 \xc3\xe4\xff\x9f\x18\x1e3\xb82t\xa2\x88\x13\xedg.\x06aa&\x06VV\x7f\x86\xb9\
2317 \xcfU\x19\xbc\xb0\xba\x86h\xe0\xc8\xd0\xfc\xbf\x80\xe1>q)\x94\xe6\x00\x00\
2318 \x85\x923_\xd22\xa4\xcd\x00\x00\x00\x00IEND\xaeB`\x82'
2320 def getAddWatchBitmap():
2321 return BitmapFromImage(getAddWatchImage())
2323 def getAddWatchImage():
2324 stream
= cStringIO
.StringIO(getAddWatchData())
2325 return ImageFromStream(stream
)
2327 def getAddWatchIcon():
2328 return wx
.IconFromBitmap(getAddWatchBitmap())