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
45 if wx
.Platform
== '__WXMSW__':
48 _PYWIN32_INSTALLED
= True
50 _PYWIN32_INSTALLED
= False
55 if not _WINDOWS
or _PYWIN32_INSTALLED
:
63 # Class to read from stdout or stderr and write the result to a text control.
64 # Args: file=file-like object
65 # callback_function= function that takes a single argument, the line of text
67 class OutputReaderThread(threading
.Thread
):
68 def __init__(self
, file, callback_function
, callbackOnExit
=None, accumulate
=True):
69 threading
.Thread
.__init
__(self
)
71 self
._callback
_function
= callback_function
72 self
._keepGoing
= True
74 self
._accumulate
= accumulate
75 self
._callbackOnExit
= callbackOnExit
79 # See comment on DebugCommandUI.StopExecution
80 self
._keepGoing
= False
86 while self
._keepGoing
:
88 # This could block--how to handle that?
89 text
= file.readline()
90 if text
== '' or text
== None:
91 self
._keepGoing
= False
92 elif not self
._accumulate
and self
._keepGoing
:
93 self
._callback
_function
(text
)
95 # Should use a buffer? StringIO?
97 # Seems as though the read blocks if we got an error, so, to be
98 # sure that at least some of the exception gets printed, always
99 # send the first hundred lines back as they come in.
100 if self
._lineCount
< 100 and self
._keepGoing
:
101 self
._callback
_function
(output
)
104 elif time
.time() - start
> 0.25 and self
._keepGoing
:
106 self
._callback
_function
(output
)
107 except wx
._core
.PyDeadObjectError
:
108 # GUI was killed while we were blocked.
109 self
._keepGoing
= False
115 tp
, val
, tb
= sys
.exc_info()
116 print "Exception in OutputReaderThread.run():", tp
, val
117 self
._keepGoing
= False
118 if self
._callbackOnExit
:
120 self
._callbackOnExit
()
121 except wx
._core
.PyDeadObjectError
:
123 if _VERBOSE
: print "Exiting OutputReaderThread"
126 self
._keepGoing
= False
128 import wx
.lib
.newevent
129 (UpdateTextEvent
, EVT_UPDATE_STDTEXT
) = wx
.lib
.newevent
.NewEvent()
130 (UpdateErrorEvent
, EVT_UPDATE_ERRTEXT
) = wx
.lib
.newevent
.NewEvent()
134 def GetPythonExecutablePath():
135 path
= UICommon
.GetPythonExecPath()
138 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"))
140 GetPythonExecutablePath
= staticmethod(GetPythonExecutablePath
)
142 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):
143 self
._fileName
= fileName
144 self
._stdOutCallback
= self
.OutCall
145 self
._stdErrCallback
= self
.ErrCall
146 self
._callbackOnExit
= callbackOnExit
147 self
._wxComponent
= wxComponent
148 path
= Executor
.GetPythonExecutablePath()
149 self
._cmd
= '"' + path
+ '" -u \"' + fileName
+ '\"'
150 #Better way to do this? Quotes needed for windows file paths.
151 def spaceAndQuote(text
):
152 if text
.startswith("\"") and text
.endswith("\""):
155 return ' \"' + text
+ '\"'
157 self
._cmd
+= spaceAndQuote(arg1
)
159 self
._cmd
+= spaceAndQuote(arg2
)
161 self
._cmd
+= spaceAndQuote(arg3
)
163 self
._cmd
+= spaceAndQuote(arg4
)
165 self
._cmd
+= spaceAndQuote(arg5
)
167 self
._cmd
+= spaceAndQuote(arg6
)
169 self
._cmd
+= spaceAndQuote(arg7
)
171 self
._cmd
+= spaceAndQuote(arg8
)
173 self
._cmd
+= spaceAndQuote(arg9
)
175 self
._stdOutReader
= None
176 self
._stdErrReader
= None
179 def OutCall(self
, text
):
180 evt
= UpdateTextEvent(value
= text
)
181 wx
.PostEvent(self
._wxComponent
, evt
)
183 def ErrCall(self
, text
):
184 evt
= UpdateErrorEvent(value
= text
)
185 wx
.PostEvent(self
._wxComponent
, evt
)
187 def Execute(self
, arguments
, startIn
=None, environment
=None):
189 startIn
= str(os
.getcwd())
190 startIn
= os
.path
.abspath(startIn
)
191 command
= self
._cmd
+ ' ' + arguments
192 self
._process
= process
.ProcessOpen(command
, mode
='b', cwd
=startIn
, env
=environment
)
193 # Kick off threads to read stdout and stderr and write them
194 # to our text control.
195 self
._stdOutReader
= OutputReaderThread(self
._process
.stdout
, self
._stdOutCallback
, callbackOnExit
=self
._callbackOnExit
)
196 self
._stdOutReader
.start()
197 self
._stdErrReader
= OutputReaderThread(self
._process
.stderr
, self
._stdErrCallback
, accumulate
=False)
198 self
._stdErrReader
.start()
200 def DoStopExecution(self
):
201 # See comment on DebugCommandUI.StopExecution
202 if(self
._process
!= None):
203 self
._stdOutReader
.AskToStop()
204 self
._stdErrReader
.AskToStop()
206 self
._process
.kill(gracePeriod
=2.0)
211 class RunCommandUI(wx
.Panel
):
214 def ShutdownAllRunners():
215 # See comment on DebugCommandUI.StopExecution
216 for runner
in RunCommandUI
.runners
:
218 runner
.StopExecution(None)
219 except wx
._core
.PyDeadObjectError
:
221 RunCommandUI
.runners
= []
222 ShutdownAllRunners
= staticmethod(ShutdownAllRunners
)
224 def __init__(self
, parent
, id, fileName
):
225 wx
.Panel
.__init
__(self
, parent
, id)
226 self
._noteBook
= parent
228 threading
._VERBOSE
= _VERBOSE
230 self
.KILL_PROCESS_ID
= wx
.NewId()
231 self
.CLOSE_TAB_ID
= wx
.NewId()
234 # GUI Initialization follows
235 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
236 self
._tb
= tb
= wx
.ToolBar(self
, -1, wx
.DefaultPosition
, (30,1000), wx
.TB_VERTICAL| wx
.TB_FLAT
, "Runner" )
237 tb
.SetToolBitmapSize((16,16))
238 sizer
.Add(tb
, 0, wx
.EXPAND|wx
.ALIGN_LEFT|wx
.ALL
, 1)
240 close_bmp
= getCloseBitmap()
241 tb
.AddSimpleTool( self
.CLOSE_TAB_ID
, close_bmp
, _('Close Window'))
242 wx
.EVT_TOOL(self
, self
.CLOSE_TAB_ID
, self
.OnToolClicked
)
244 stop_bmp
= getStopBitmap()
245 tb
.AddSimpleTool(self
.KILL_PROCESS_ID
, stop_bmp
, _("Stop the Run."))
246 wx
.EVT_TOOL(self
, self
.KILL_PROCESS_ID
, self
.OnToolClicked
)
249 self
._textCtrl
= STCTextEditor
.TextCtrl(self
, wx
.NewId()) #id)
250 sizer
.Add(self
._textCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
251 self
._textCtrl
.SetViewLineNumbers(False)
252 self
._textCtrl
.SetReadOnly(True)
253 if wx
.Platform
== '__WXMSW__':
257 self
._textCtrl
.SetFont(wx
.Font(9, wx
.DEFAULT
, wx
.NORMAL
, wx
.NORMAL
, faceName
= font
))
258 self
._textCtrl
.SetFontColor(wx
.BLACK
)
259 self
._textCtrl
.StyleClearAll()
261 #Disabling for now...may interfere with file open. wx.stc.EVT_STC_DOUBLECLICK(self._textCtrl, self._textCtrl.GetId(), self.OnDoubleClick)
266 self
._stopped
= False
267 # Executor initialization
268 self
._executor
= Executor(fileName
, self
, callbackOnExit
=self
.ExecutorFinished
)
269 self
.Bind(EVT_UPDATE_STDTEXT
, self
.AppendText
)
270 self
.Bind(EVT_UPDATE_ERRTEXT
, self
.AppendErrorText
)
272 RunCommandUI
.runners
.append(self
)
275 # See comment on DebugCommandUI.StopExecution
276 self
._executor
.DoStopExecution()
278 def Execute(self
, initialArgs
, startIn
, environment
):
279 self
._executor
.Execute(initialArgs
, startIn
, environment
)
281 def ExecutorFinished(self
):
282 self
._tb
.EnableTool(self
.KILL_PROCESS_ID
, False)
283 nb
= self
.GetParent()
284 for i
in range(0,nb
.GetPageCount()):
285 if self
== nb
.GetPage(i
):
286 text
= nb
.GetPageText(i
)
287 newText
= text
.replace("Running", "Finished")
288 nb
.SetPageText(i
, newText
)
291 def StopExecution(self
):
292 if not self
._stopped
:
294 self
.Unbind(EVT_UPDATE_STDTEXT
)
295 self
.Unbind(EVT_UPDATE_ERRTEXT
)
296 self
._executor
.DoStopExecution()
298 def AppendText(self
, event
):
299 self
._textCtrl
.SetReadOnly(False)
300 self
._textCtrl
.AddText(event
.value
)
301 self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount())
302 self
._textCtrl
.SetReadOnly(True)
304 def AppendErrorText(self
, event
):
305 self
._textCtrl
.SetReadOnly(False)
306 self
._textCtrl
.SetFontColor(wx
.RED
)
307 self
._textCtrl
.StyleClearAll()
308 self
._textCtrl
.AddText(event
.value
)
309 self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount())
310 self
._textCtrl
.SetFontColor(wx
.BLACK
)
311 self
._textCtrl
.StyleClearAll()
312 self
._textCtrl
.SetReadOnly(True)
314 def StopAndRemoveUI(self
, event
):
317 index
= self
._noteBook
.GetSelection()
318 self
._noteBook
.GetPage(index
).Show(False)
319 self
._noteBook
.RemovePage(index
)
321 #------------------------------------------------------------------------------
323 #-----------------------------------------------------------------------------
325 def OnToolClicked(self
, event
):
328 if id == self
.KILL_PROCESS_ID
:
331 elif id == self
.CLOSE_TAB_ID
:
332 self
.StopAndRemoveUI(event
)
334 def OnDoubleClick(self
, event
):
335 # Looking for a stack trace line.
336 lineText
, pos
= self
._textCtrl
.GetCurLine()
337 fileBegin
= lineText
.find("File \"")
338 fileEnd
= lineText
.find("\", line ")
339 lineEnd
= lineText
.find(", in ")
340 if lineText
== "\n" or fileBegin
== -1 or fileEnd
== -1 or lineEnd
== -1:
341 # Check the line before the one that was clicked on
342 lineNumber
= self
._textCtrl
.GetCurrentLine()
345 lineText
= self
._textCtrl
.GetLine(lineNumber
- 1)
346 fileBegin
= lineText
.find("File \"")
347 fileEnd
= lineText
.find("\", line ")
348 lineEnd
= lineText
.find(", in ")
349 if lineText
== "\n" or fileBegin
== -1 or fileEnd
== -1 or lineEnd
== -1:
352 filename
= lineText
[fileBegin
+ 6:fileEnd
]
353 lineNum
= int(lineText
[fileEnd
+ 8:lineEnd
])
356 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
357 for openDoc
in openDocs
:
358 if openDoc
.GetFilename() == filename
:
359 foundView
= openDoc
.GetFirstView()
363 doc
= wx
.GetApp().GetDocumentManager().CreateDocument(filename
, wx
.lib
.docview
.DOC_SILENT
)
364 foundView
= doc
.GetFirstView()
367 foundView
.GetFrame().SetFocus()
369 foundView
.GotoLine(lineNum
)
370 startPos
= foundView
.PositionFromLine(lineNum
)
372 # FACTOR THIS INTO DocManager
373 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
374 for openDoc
in openDocs
:
375 if(isinstance(openDoc
, CodeEditor
.CodeDocument
)):
376 openDoc
.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
378 foundView
.GetCtrl().MarkerAdd(lineNum
-1, CodeEditor
.CodeCtrl
.CURRENT_LINE_MARKER_NUM
)
382 DEFAULT_HOST
= 'localhost'
385 class DebugCommandUI(wx
.Panel
):
386 debuggerPortList
= None
389 def NotifyDebuggersOfBreakpointChange():
390 for debugger
in DebugCommandUI
.debuggers
:
391 debugger
.BreakPointChange()
393 NotifyDebuggersOfBreakpointChange
= staticmethod(NotifyDebuggersOfBreakpointChange
)
395 def DebuggerRunning():
396 for debugger
in DebugCommandUI
.debuggers
:
397 if debugger
._executor
:
400 DebuggerRunning
= staticmethod(DebuggerRunning
)
402 def ShutdownAllDebuggers():
403 # See comment on DebugCommandUI.StopExecution
404 for debugger
in DebugCommandUI
.debuggers
:
406 debugger
.StopExecution(None)
407 except wx
._core
.PyDeadObjectError
:
409 DebugCommandUI
.debuggers
= []
410 ShutdownAllDebuggers
= staticmethod(ShutdownAllDebuggers
)
412 def GetAvailablePort():
413 for index
in range( 0, len(DebugCommandUI
.debuggerPortList
)):
414 port
= DebugCommandUI
.debuggerPortList
[index
]
415 if DebugCommandUI
.PortAvailable(port
):
416 DebugCommandUI
.debuggerPortList
.pop(index
)
418 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"))
419 assert False, "Out of ports for debugger."
421 GetAvailablePort
= staticmethod(GetAvailablePort
)
423 def ReturnPortToPool(port
):
424 config
= wx
.ConfigBase_Get()
425 startingPort
= config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
)
426 val
= int(startingPort
) + int(PORT_COUNT
)
427 if int(port
) >= startingPort
and (int(port
) <= val
):
428 DebugCommandUI
.debuggerPortList
.append(int(port
))
430 ReturnPortToPool
= staticmethod(ReturnPortToPool
)
432 def PortAvailable(port
):
433 config
= wx
.ConfigBase_Get()
434 hostname
= config
.Read("DebuggerHostName", DEFAULT_HOST
)
436 server
= AGXMLRPCServer((hostname
, port
))
437 server
.server_close()
438 if _VERBOSE
: print "Port ", str(port
), " available."
441 tp
,val
,tb
= sys
.exc_info()
442 if _VERBOSE
: traceback
.print_exception(tp
, val
, tb
)
443 if _VERBOSE
: print "Port ", str(port
), " unavailable."
446 PortAvailable
= staticmethod(PortAvailable
)
449 config
= wx
.ConfigBase_Get()
450 startingPort
= config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
)
451 DebugCommandUI
.debuggerPortList
= range(startingPort
, startingPort
+ PORT_COUNT
)
452 NewPortRange
= staticmethod(NewPortRange
)
454 def __init__(self
, parent
, id, command
, service
):
455 # Check for ports before creating the panel.
456 if not DebugCommandUI
.debuggerPortList
:
457 DebugCommandUI
.NewPortRange()
458 self
._debuggerPort
= str(DebugCommandUI
.GetAvailablePort())
459 self
._guiPort
= str(DebugCommandUI
.GetAvailablePort())
460 self
._debuggerBreakPort
= str(DebugCommandUI
.GetAvailablePort())
462 wx
.Panel
.__init
__(self
, parent
, id)
464 self
._parentNoteBook
= parent
465 self
._command
= command
466 self
._service
= service
467 self
._executor
= None
468 self
.STEP_ID
= wx
.NewId()
469 self
.CONTINUE_ID
= wx
.NewId()
470 self
.STEP_OUT_ID
= wx
.NewId()
471 self
.NEXT_ID
= wx
.NewId()
472 self
.KILL_PROCESS_ID
= wx
.NewId()
473 self
.CLOSE_WINDOW_ID
= wx
.NewId()
474 self
.BREAK_INTO_DEBUGGER_ID
= wx
.NewId()
475 self
.CLEAR_ID
= wx
.NewId()
476 self
.ADD_WATCH_ID
= wx
.NewId()
477 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
478 self
._tb
= tb
= wx
.ToolBar(self
, -1, wx
.DefaultPosition
, (1000,30), wx
.TB_HORIZONTAL| wx
.NO_BORDER| wx
.TB_FLAT| wx
.TB_TEXT
, "Debugger" )
479 sizer
.Add(tb
, 0, wx
.EXPAND |wx
.ALIGN_LEFT|wx
.ALL
, 1)
480 tb
.SetToolBitmapSize((16,16))
482 close_bmp
= getCloseBitmap()
483 tb
.AddSimpleTool( self
.CLOSE_WINDOW_ID
, close_bmp
, _('Close Window'))
484 wx
.EVT_TOOL(self
, self
.CLOSE_WINDOW_ID
, self
.StopAndRemoveUI
)
486 stop_bmp
= getStopBitmap()
487 tb
.AddSimpleTool( self
.KILL_PROCESS_ID
, stop_bmp
, _("Stop Debugging"))
488 wx
.EVT_TOOL(self
, self
.KILL_PROCESS_ID
, self
.StopExecution
)
492 break_bmp
= getBreakBitmap()
493 tb
.AddSimpleTool( self
.BREAK_INTO_DEBUGGER_ID
, break_bmp
, _("Break into Debugger"))
494 wx
.EVT_TOOL(self
, self
.BREAK_INTO_DEBUGGER_ID
, self
.BreakExecution
)
498 continue_bmp
= getContinueBitmap()
499 tb
.AddSimpleTool( self
.CONTINUE_ID
, continue_bmp
, _("Continue Execution"))
500 wx
.EVT_TOOL(self
, self
.CONTINUE_ID
, self
.OnContinue
)
504 next_bmp
= getNextBitmap()
505 tb
.AddSimpleTool( self
.NEXT_ID
, next_bmp
, _("Step to next line"))
506 wx
.EVT_TOOL(self
, self
.NEXT_ID
, self
.OnNext
)
508 step_bmp
= getStepInBitmap()
509 tb
.AddSimpleTool( self
.STEP_ID
, step_bmp
, _("Step in"))
510 wx
.EVT_TOOL(self
, self
.STEP_ID
, self
.OnSingleStep
)
512 stepOut_bmp
= getStepReturnBitmap()
513 tb
.AddSimpleTool(self
.STEP_OUT_ID
, stepOut_bmp
, _("Stop at function return"))
514 wx
.EVT_TOOL(self
, self
.STEP_OUT_ID
, self
.OnStepOut
)
518 watch_bmp
= getAddWatchBitmap()
519 tb
.AddSimpleTool(self
.ADD_WATCH_ID
, watch_bmp
, _("Add a watch"))
520 wx
.EVT_TOOL(self
, self
.ADD_WATCH_ID
, self
.OnAddWatch
)
523 clear_bmp
= getClearOutputBitmap()
524 tb
.AddSimpleTool(self
.CLEAR_ID
, clear_bmp
, _("Clear output pane"))
525 wx
.EVT_TOOL(self
, self
.CLEAR_ID
, self
.OnClearOutput
)
527 self
.framesTab
= None
528 self
.DisableWhileDebuggerRunning()
529 self
.framesTab
= self
.MakeFramesUI(self
, wx
.NewId(), None)
530 sizer
.Add(self
.framesTab
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
531 self
._statusBar
= wx
.StatusBar( self
, -1)
532 self
._statusBar
.SetFieldsCount(1)
533 sizer
.Add(self
._statusBar
, 0, wx
.EXPAND |wx
.ALIGN_LEFT|wx
.ALL
, 1)
535 self
.SetStatusText("Starting debug...")
540 config
= wx
.ConfigBase_Get()
541 self
._debuggerHost
= self
._guiHost
= config
.Read("DebuggerHostName", DEFAULT_HOST
)
542 url
= 'http://' + self
._debuggerHost
+ ':' + self
._debuggerPort
+ '/'
543 self
._breakURL
= 'http://' + self
._debuggerHost
+ ':' + self
._debuggerBreakPort
+ '/'
544 self
._callback
= DebuggerCallback(self
._guiHost
, self
._guiPort
, url
, self
._breakURL
, self
)
545 if DebuggerHarness
.__file
__.find('library.zip') > 0:
547 fname
= DebuggerHarness
.__file
__
548 parts
= fname
.split('library.zip')
549 path
= os
.path
.join(parts
[0],'activegrid', 'tool', 'DebuggerHarness.py')
551 tp
, val
, tb
= sys
.exc_info()
552 traceback
.print_exception(tp
, val
, tb
)
555 print "Starting debugger on these ports: %s, %s, %s" % (str(self
._debuggerPort
) , str(self
._guiPort
) , str(self
._debuggerBreakPort
))
556 path
= DebuggerService
.ExpandPath(DebuggerHarness
.__file
__)
557 self
._executor
= Executor(path
, self
, self
._debuggerHost
, \
558 self
._debuggerPort
, self
._debuggerBreakPort
, self
._guiHost
, self
._guiPort
, self
._command
, callbackOnExit
=self
.ExecutorFinished
)
560 self
.Bind(EVT_UPDATE_STDTEXT
, self
.AppendText
)
561 self
.Bind(EVT_UPDATE_ERRTEXT
, self
.AppendErrorText
)
562 DebugCommandUI
.debuggers
.append(self
)
563 self
._stopped
= False
565 def OnSingleStep(self
, event
):
566 self
._callback
.SingleStep()
568 def OnContinue(self
, event
):
569 self
._callback
.Continue()
571 def OnStepOut(self
, event
):
572 self
._callback
.Return()
574 def OnNext(self
, event
):
575 self
._callback
.Next()
577 def BreakPointChange(self
):
578 if not self
._stopped
:
579 self
._callback
.pushBreakpoints()
580 self
.framesTab
.PopulateBPList()
583 # See comment on DebugCommandUI.StopExecution
584 self
.StopExecution(None)
586 def DisableWhileDebuggerRunning(self
):
587 self
._tb
.EnableTool(self
.STEP_ID
, False)
588 self
._tb
.EnableTool(self
.CONTINUE_ID
, False)
589 self
._tb
.EnableTool(self
.STEP_OUT_ID
, False)
590 self
._tb
.EnableTool(self
.NEXT_ID
, False)
591 self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, True)
593 self
._tb
.EnableTool(self
.ADD_WATCH_ID
, False)
594 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
595 for openDoc
in openDocs
:
596 if(isinstance(openDoc
, CodeEditor
.CodeDocument
)):
597 openDoc
.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
599 self
.framesTab
.ClearWhileRunning()
601 def EnableWhileDebuggerStopped(self
):
602 self
._tb
.EnableTool(self
.STEP_ID
, True)
603 self
._tb
.EnableTool(self
.CONTINUE_ID
, True)
604 self
._tb
.EnableTool(self
.STEP_OUT_ID
, True)
605 self
._tb
.EnableTool(self
.NEXT_ID
, True)
607 self
._tb
.EnableTool(self
.ADD_WATCH_ID
, True)
608 self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, False)
610 def ExecutorFinished(self
):
611 if _VERBOSE
: print "In ExectorFinished"
613 self
.DisableAfterStop()
614 except wx
._core
.PyDeadObjectError
:
617 nb
= self
.GetParent()
618 for i
in range(0, nb
.GetPageCount()):
619 if self
== nb
.GetPage(i
):
620 text
= nb
.GetPageText(i
)
621 newText
= text
.replace("Debugging", "Finished")
622 nb
.SetPageText(i
, newText
)
623 if _VERBOSE
: print "In ExectorFinished, changed tab title."
626 if _VERBOSE
: print "In ExectorFinished, got exception"
628 def DisableAfterStop(self
):
629 self
.DisableWhileDebuggerRunning()
630 self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, False)
631 self
._tb
.EnableTool(self
.KILL_PROCESS_ID
, False)
633 def SynchCurrentLine(self
, filename
, lineNum
, noArrow
=False):
634 # FACTOR THIS INTO DocManager
635 self
.DeleteCurrentLineMarkers()
637 # Filename will be <string> if we're in a bit of code that was executed from
638 # a string (rather than a file). I haven't been able to get the original string
640 if filename
== '<string>':
643 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
644 for openDoc
in openDocs
:
645 # This ugliness to prevent comparison failing because the drive letter
646 # gets lowercased occasionally. Don't know why that happens or why it
647 # only happens occasionally.
648 if DebuggerService
.ComparePaths(openDoc
.GetFilename(),filename
):
649 foundView
= openDoc
.GetFirstView()
654 print "filename=", filename
655 doc
= wx
.GetApp().GetDocumentManager().CreateDocument(DebuggerService
.ExpandPath(filename
), wx
.lib
.docview
.DOC_SILENT
)
656 foundView
= doc
.GetFirstView()
659 foundView
.GetFrame().SetFocus()
661 foundView
.GotoLine(lineNum
)
662 startPos
= foundView
.PositionFromLine(lineNum
)
665 foundView
.GetCtrl().MarkerAdd(lineNum
-1, CodeEditor
.CodeCtrl
.CURRENT_LINE_MARKER_NUM
)
667 def DeleteCurrentLineMarkers(self
):
668 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
669 for openDoc
in openDocs
:
670 if(isinstance(openDoc
, CodeEditor
.CodeDocument
)):
671 openDoc
.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
673 def LoadFramesListXML(self
, framesXML
):
674 self
.framesTab
.LoadFramesListXML(framesXML
)
676 def SetStatusText(self
, text
):
677 self
._statusBar
.SetStatusText(text
,0)
679 def Execute(self
, initialArgs
, startIn
, environment
):
680 self
._callback
.start()
681 self
._executor
.Execute(initialArgs
, startIn
, environment
)
682 self
._callback
.waitForRPC()
684 def BreakExecution(self
, event
):
685 self
._callback
.BreakExecution()
688 def StopExecution(self
, event
):
689 # This is a general comment on shutdown for the running and debugged processes. Basically, the
690 # current state of this is the result of trial and error coding. The common problems were memory
691 # access violations and threads that would not exit. Making the OutputReaderThreads daemons seems
692 # to have side-stepped the hung thread issue. Being very careful not to touch things after calling
693 # process.py:ProcessOpen.kill() also seems to have fixed the memory access violations, but if there
694 # were more ugliness discovered I would not be surprised. If anyone has any help/advice, please send
695 # it on to mfryer@activegrid.com.
696 if not self
._stopped
:
699 self
.DisableAfterStop()
700 except wx
._core
.PyDeadObjectError
:
703 self
._callback
.ShutdownServer()
705 tp
,val
,tb
= sys
.exc_info()
706 traceback
.print_exception(tp
, val
, tb
)
709 self
.DeleteCurrentLineMarkers()
713 DebugCommandUI
.ReturnPortToPool(self
._debuggerPort
)
714 DebugCommandUI
.ReturnPortToPool(self
._guiPort
)
715 DebugCommandUI
.ReturnPortToPool(self
._debuggerBreakPort
)
720 self
._executor
.DoStopExecution()
721 self
._executor
= None
723 tp
,val
,tb
= sys
.exc_info()
724 traceback
.print_exception(tp
, val
, tb
)
725 def StopAndRemoveUI(self
, event
):
726 self
.StopExecution(None)
727 if self
in DebugCommandUI
.debuggers
:
728 DebugCommandUI
.debuggers
.remove(self
)
729 index
= self
._parentNoteBook
.GetSelection()
730 self
._parentNoteBook
.GetPage(index
).Show(False)
731 self
._parentNoteBook
.RemovePage(index
)
733 def OnAddWatch(self
, event
):
735 self
.framesTab
.OnWatch(event
)
737 def MakeFramesUI(self
, parent
, id, debugger
):
738 panel
= FramesUI(parent
, id, self
)
741 def AppendText(self
, event
):
742 self
.framesTab
.AppendText(event
.value
)
744 def AppendErrorText(self
, event
):
745 self
.framesTab
.AppendErrorText(event
.value
)
747 def OnClearOutput(self
, event
):
748 self
.framesTab
.ClearOutput(None)
750 def SwitchToOutputTab(self
):
751 self
.framesTab
.SwitchToOutputTab()
753 class BreakpointsUI(wx
.Panel
):
754 def __init__(self
, parent
, id, ui
):
755 wx
.Panel
.__init
__(self
, parent
, id)
757 self
.currentItem
= None
758 self
.clearBPID
= wx
.NewId()
759 self
.Bind(wx
.EVT_MENU
, self
.ClearBreakPoint
, id=self
.clearBPID
)
760 self
.syncLineID
= wx
.NewId()
761 self
.Bind(wx
.EVT_MENU
, self
.SyncBPLine
, id=self
.syncLineID
)
762 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
764 self
._bpListCtrl
= wx
.ListCtrl(p1
, -1, pos
=wx
.DefaultPosition
, size
=(1000,1000), style
=wx
.LC_REPORT
)
765 sizer
.Add(self
._bpListCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
766 self
._bpListCtrl
.InsertColumn(0, "File")
767 self
._bpListCtrl
.InsertColumn(1, "Line")
768 self
._bpListCtrl
.InsertColumn(2, "Path")
769 self
._bpListCtrl
.SetColumnWidth(0, 150)
770 self
._bpListCtrl
.SetColumnWidth(1, 50)
771 self
._bpListCtrl
.SetColumnWidth(2, 450)
772 self
._bpListCtrl
.Bind(wx
.EVT_LIST_ITEM_RIGHT_CLICK
, self
.OnListRightClick
)
773 self
.Bind(wx
.EVT_LIST_ITEM_SELECTED
, self
.ListItemSelected
, self
._bpListCtrl
)
774 self
.Bind(wx
.EVT_LIST_ITEM_DESELECTED
, self
.ListItemDeselected
, self
._bpListCtrl
)
776 def OnLeftDoubleClick(event
):
777 self
.SyncBPLine(event
)
779 wx
.EVT_LEFT_DCLICK(self
._bpListCtrl
, OnLeftDoubleClick
)
781 self
.PopulateBPList()
787 def PopulateBPList(self
):
788 list = self
._bpListCtrl
789 list.DeleteAllItems()
791 bps
= wx
.GetApp().GetService(DebuggerService
).GetMasterBreakpointDict()
793 for fileName
in bps
.keys():
794 shortFile
= os
.path
.basename(fileName
)
795 lines
= bps
[fileName
]
798 list.InsertStringItem(index
, shortFile
)
799 list.SetStringItem(index
, 1, str(line
))
800 list.SetStringItem(index
, 2, fileName
)
802 def OnListRightClick(self
, event
):
804 item
= wx
.MenuItem(menu
, self
.clearBPID
, "Clear Breakpoint")
805 menu
.AppendItem(item
)
806 item
= wx
.MenuItem(menu
, self
.syncLineID
, "Goto Source Line")
807 menu
.AppendItem(item
)
808 self
.PopupMenu(menu
, event
.GetPosition())
811 def SyncBPLine(self
, event
):
812 if self
.currentItem
!= -1:
813 list = self
._bpListCtrl
814 fileName
= list.GetItem(self
.currentItem
, 2).GetText()
815 lineNumber
= list.GetItem(self
.currentItem
, 1).GetText()
816 self
._ui
.SynchCurrentLine( fileName
, int(lineNumber
) , noArrow
=True)
818 def ClearBreakPoint(self
, event
):
819 if self
.currentItem
>= 0:
820 list = self
._bpListCtrl
821 fileName
= list.GetItem(self
.currentItem
, 2).GetText()
822 lineNumber
= list.GetItem(self
.currentItem
, 1).GetText()
823 wx
.GetApp().GetService(DebuggerService
).OnToggleBreakpoint(None, line
=int(lineNumber
) -1, fileName
=fileName
)
825 def ListItemSelected(self
, event
):
826 self
.currentItem
= event
.m_itemIndex
828 def ListItemDeselected(self
, event
):
829 self
.currentItem
= -1
837 def __init__(self
, name
, command
, show_code
=CODE_ALL_FRAMES
):
839 self
._command
= command
840 self
._show
_code
= show_code
842 class WatchDialog(wx
.Dialog
):
843 WATCH_ALL_FRAMES
= "Watch in all frames"
844 WATCH_THIS_FRAME
= "Watch in this frame only"
845 WATCH_ONCE
= "Watch once and delete"
846 def __init__(self
, parent
, title
, chain
):
847 wx
.Dialog
.__init
__(self
, parent
, -1, title
, style
=wx
.DEFAULT_DIALOG_STYLE
)
849 self
.label_2
= wx
.StaticText(self
, -1, "Watch Name:")
850 self
._watchNameTextCtrl
= wx
.TextCtrl(self
, -1, "")
851 self
.label_3
= wx
.StaticText(self
, -1, "eval(", style
=wx
.ALIGN_RIGHT
)
852 self
._watchValueTextCtrl
= wx
.TextCtrl(self
, -1, "")
853 self
.label_4
= wx
.StaticText(self
, -1, ",frame.f_globals, frame.f_locals)")
854 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
)
856 self
._okButton
= wx
.Button(self
, wx
.ID_OK
, "OK")
857 self
._okButton
.SetDefault()
858 self
._okButton
.SetHelpText(_("The OK button completes the dialog"))
859 def OnOkClick(event
):
860 if self
._watchNameTextCtrl
.GetValue() == "":
861 wx
.MessageBox(_("You must enter a name for the watch."), _("Add Watch"))
863 if self
._watchValueTextCtrl
.GetValue() == "":
864 wx
.MessageBox(_("You must enter some code to run for the watch."), _("Add Watch"))
866 self
.EndModal(wx
.ID_OK
)
867 self
.Bind(wx
.EVT_BUTTON
, OnOkClick
, self
._okButton
)
869 self
._cancelButton
= wx
.Button(self
, wx
.ID_CANCEL
, _("Cancel"))
870 self
._cancelButton
.SetHelpText(_("The Cancel button cancels the dialog."))
872 self
.__set
_properties
()
875 def GetSettings(self
):
876 return self
._watchNameTextCtrl
.GetValue(), self
._watchValueTextCtrl
.GetValue(), self
.GetSendFrame(), self
.GetRunOnce()
878 def GetSendFrame(self
):
879 return (WatchDialog
.WATCH_ALL_FRAMES
!= self
.radio_box_1
.GetStringSelection())
881 def GetRunOnce(self
):
882 return (WatchDialog
.WATCH_ONCE
== self
.radio_box_1
.GetStringSelection())
884 def __set_properties(self
):
885 self
.SetTitle("Add a Watch")
886 #self.SetSize((400, 250))
887 self
.radio_box_1
.SetSelection(0)
889 def __do_layout(self
):
890 sizer_1
= wx
.BoxSizer(wx
.VERTICAL
)
891 grid_sizer_4
= wx
.FlexGridSizer(1, 3, 5, 5)
892 grid_sizer_2
= wx
.FlexGridSizer(1, 2, 5, 5)
893 grid_sizer_2
.Add(self
.label_2
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0)
894 grid_sizer_2
.Add(self
._watchNameTextCtrl
, 0, wx
.EXPAND
, 0)
895 grid_sizer_2
.AddGrowableCol(1)
896 sizer_1
.Add(grid_sizer_2
, 1, wx
.EXPAND
, 0)
897 grid_sizer_4
.Add(self
.label_3
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0)
898 grid_sizer_4
.Add(self
._watchValueTextCtrl
, 0, wx
.EXPAND
, 0)
899 grid_sizer_4
.AddGrowableCol(1)
900 grid_sizer_4
.Add(self
.label_4
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0)
901 sizer_1
.Add(grid_sizer_4
, 0, wx
.EXPAND
, 0)
902 sizer_1
.Add(self
.radio_box_1
, 0, wx
.EXPAND
, 0)
904 box
= wx
.BoxSizer(wx
.HORIZONTAL
)
905 box
.Add(self
._okButton
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5)
906 box
.Add(self
._cancelButton
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5)
907 sizer_1
.Add(box
, 1, wx
.EXPAND
, 0)
908 self
.SetSizer(sizer_1
)
911 class FramesUI(wx
.SplitterWindow
):
912 def __init__(self
, parent
, id, ui
):
913 wx
.SplitterWindow
.__init
__(self
, parent
, id, style
= wx
.SP_3D
)
915 self
._p
1 = p1
= wx
.ScrolledWindow(self
, -1)
917 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
918 framesLabel
= wx
.StaticText(self
, -1, "Stack Frame:")
919 sizer
.Add(framesLabel
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT|wx
.LEFT
, border
=2)
921 self
._framesChoiceCtrl
= wx
.Choice(p1
, -1, choices
=[" "])
922 sizer
.Add(self
._framesChoiceCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
923 self
._framesChoiceCtrl
.Bind(wx
.EVT_LIST_ITEM_RIGHT_CLICK
, self
.OnListRightClick
)
924 self
.Bind(wx
.EVT_CHOICE
, self
.ListItemSelected
, self
._framesChoiceCtrl
)
926 sizer2
= wx
.BoxSizer(wx
.VERTICAL
)
929 self
._treeCtrl
= wx
.gizmos
.TreeListCtrl(p1
, -1, style
=wx
.TR_DEFAULT_STYLE| wx
.TR_FULL_ROW_HIGHLIGHT
)
930 self
._treeCtrl
.Bind(wx
.EVT_TREE_ITEM_RIGHT_CLICK
, self
.OnRightClick
)
931 sizer2
.Add(sizer
, 0, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
932 sizer2
.Add(self
._treeCtrl
,1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
933 tree
= self
._treeCtrl
934 tree
.AddColumn("Thing")
935 tree
.AddColumn("Value")
936 tree
.SetMainColumn(0) # the one with the tree in it...
937 tree
.SetColumnWidth(0, 175)
938 tree
.SetColumnWidth(1, 355)
939 self
._root
= tree
.AddRoot("Frame")
940 tree
.SetItemText(self
._root
, "", 1)
941 tree
.Bind(wx
.EVT_TREE_ITEM_EXPANDING
, self
.IntrospectCallback
)
943 self
._p
2 = p2
= wx
.Window(self
, -1)
944 sizer3
= wx
.BoxSizer(wx
.HORIZONTAL
)
946 p2
.Bind(wx
.EVT_SIZE
, self
.OnSize
)
947 self
._notebook
= wx
.Notebook(p2
, -1, size
=(20,20))
948 self
._notebook
.Hide()
949 sizer3
.Add(self
._notebook
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
950 self
.consoleTab
= self
.MakeConsoleTab(self
._notebook
, wx
.NewId())
951 self
.inspectConsoleTab
= self
.MakeInspectConsoleTab(self
._notebook
, wx
.NewId())
952 self
.breakPointsTab
= self
.MakeBreakPointsTab(self
._notebook
, wx
.NewId())
953 self
._notebook
.AddPage(self
.consoleTab
, "Output")
954 self
._notebook
.AddPage(self
.inspectConsoleTab
, "Interact")
955 self
._notebook
.AddPage(self
.breakPointsTab
, "Break Points")
957 self
.SetMinimumPaneSize(20)
958 self
.SplitVertically(p1
, p2
, 550)
959 self
.currentItem
= None
960 self
._notebook
.Show(True)
962 def PopulateBPList(self
):
963 self
.breakPointsTab
.PopulateBPList()
965 def OnSize(self
, event
):
966 self
._notebook
.SetSize(self
._p
2.GetSize())
968 def MakeConsoleTab(self
, parent
, id):
969 panel
= wx
.Panel(parent
, id)
970 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
971 self
._textCtrl
= STCTextEditor
.TextCtrl(panel
, wx
.NewId())
972 sizer
.Add(self
._textCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 2)
973 self
._textCtrl
.SetViewLineNumbers(False)
974 self
._textCtrl
.SetReadOnly(True)
975 if wx
.Platform
== '__WXMSW__':
979 self
._textCtrl
.SetFont(wx
.Font(9, wx
.DEFAULT
, wx
.NORMAL
, wx
.NORMAL
, faceName
= font
))
980 self
._textCtrl
.SetFontColor(wx
.BLACK
)
981 self
._textCtrl
.StyleClearAll()
982 panel
.SetSizer(sizer
)
987 def ReplaceLastLine(self
, command
):
988 line
= self
._interCtrl
.GetLineCount() - 1
989 self
._interCtrl
.GotoLine(line
)
990 start
= self
._interCtrl
.GetCurrentPos()
991 self
._interCtrl
.SetTargetStart(start
)
992 end
= self
._interCtrl
.GetLineEndPosition(line
)
993 self
._interCtrl
.SetTargetEnd(end
)
994 self
._interCtrl
.ReplaceTarget(">>> " + command
)
995 self
._interCtrl
.GotoLine(line
)
996 self
._interCtrl
.SetSelectionStart(self
._interCtrl
.GetLineEndPosition(line
))
998 def ExecuteCommand(self
, command
):
999 if not len(self
.command_list
) or not command
== self
.command_list
[len(self
.command_list
) -1]:
1000 self
.command_list
.append(command
)
1001 self
.command_index
= len(self
.command_list
) - 1
1002 retval
= self
._ui
._callback
._debuggerServer
.execute_in_frame(self
._framesChoiceCtrl
.GetStringSelection(), command
)
1003 self
._interCtrl
.AddText("\n" + str(retval
))
1004 self
._interCtrl
.ScrollToLine(self
._interCtrl
.GetLineCount())
1005 # Refresh the tree view in case this command resulted in changes there. TODO: Need to reopen tree items.
1006 self
.PopulateTreeFromFrameMessage(self
._framesChoiceCtrl
.GetStringSelection())
1008 def MakeInspectConsoleTab(self
, parent
, id):
1009 self
.command_list
= []
1010 self
.command_index
= 0
1012 def OnKeyPressed(event
):
1013 key
= event
.KeyCode()
1014 if key
== wx
.WXK_DELETE
or key
== wx
.WXK_BACK
:
1015 if self
._interCtrl
.GetLine(self
._interCtrl
.GetCurrentLine()) == ">>> ":
1017 elif key
== wx
.WXK_RETURN
:
1018 command
= self
._interCtrl
.GetLine(self
._interCtrl
.GetCurrentLine())[4:]
1019 self
.ExecuteCommand(command
)
1020 self
._interCtrl
.AddText("\n>>> ")
1022 elif key
== wx
.WXK_UP
:
1023 if not len(self
.command_list
):
1025 self
.ReplaceLastLine(self
.command_list
[self
.command_index
])
1026 if self
.command_index
== 0:
1027 self
.command_index
= len(self
.command_list
) - 1
1029 self
.command_index
= self
.command_index
- 1
1031 elif key
== wx
.WXK_DOWN
:
1032 if not len(self
.command_list
):
1034 if self
.command_index
< len(self
.command_list
) - 1:
1035 self
.command_index
= self
.command_index
+ 1
1037 self
.command_index
= 0
1038 self
.ReplaceLastLine(self
.command_list
[self
.command_index
])
1043 panel
= wx
.Panel(parent
, id)
1044 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
1045 self
._interCtrl
= STCTextEditor
.TextCtrl(panel
, wx
.NewId())
1046 sizer
.Add(self
._interCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 2)
1047 self
._interCtrl
.SetViewLineNumbers(False)
1048 if wx
.Platform
== '__WXMSW__':
1049 font
= "Courier New"
1052 self
._interCtrl
.SetFont(wx
.Font(9, wx
.DEFAULT
, wx
.NORMAL
, wx
.NORMAL
, faceName
= font
))
1053 self
._interCtrl
.SetFontColor(wx
.BLACK
)
1054 self
._interCtrl
.StyleClearAll()
1055 wx
.EVT_KEY_DOWN(self
._interCtrl
, OnKeyPressed
)
1056 self
._interCtrl
.AddText(">>> ")
1057 panel
.SetSizer(sizer
)
1059 tp
, val
, tb
= sys
.exc_info()
1060 traceback
.print_exception(tp
, val
, tb
)
1064 def MakeBreakPointsTab(self
, parent
, id):
1065 panel
= BreakpointsUI(parent
, id, self
._ui
)
1068 def OnRightClick(self
, event
):
1070 self
._introspectItem
= event
.GetItem()
1071 self
._parentChain
= self
.GetItemChain(event
.GetItem())
1072 watchOnly
= len(self
._parentChain
) < 1
1073 if not _WATCHES_ON
and watchOnly
:
1077 if not hasattr(self
, "watchID"):
1078 self
.watchID
= wx
.NewId()
1079 self
.Bind(wx
.EVT_MENU
, self
.OnWatch
, id=self
.watchID
)
1080 item
= wx
.MenuItem(menu
, self
.watchID
, "Create a Watch")
1081 menu
.AppendItem(item
)
1082 menu
.AppendSeparator()
1084 if not hasattr(self
, "viewID"):
1085 self
.viewID
= wx
.NewId()
1086 self
.Bind(wx
.EVT_MENU
, self
.OnView
, id=self
.viewID
)
1087 item
= wx
.MenuItem(menu
, self
.viewID
, "View in Dialog")
1088 menu
.AppendItem(item
)
1089 if not hasattr(self
, "toInteractID"):
1090 self
.toInteractID
= wx
.NewId()
1091 self
.Bind(wx
.EVT_MENU
, self
.OnSendToInteract
, id=self
.toInteractID
)
1092 item
= wx
.MenuItem(menu
, self
.toInteractID
, "Send to Interact")
1093 menu
.AppendItem(item
)
1095 offset
= wx
.Point(x
=0, y
=20)
1096 menuSpot
= event
.GetPoint() + offset
1097 self
._treeCtrl
.PopupMenu(menu
, menuSpot
)
1099 self
._parentChain
= None
1100 self
._introspectItem
= None
1102 def GetItemChain(self
, item
):
1105 if _VERBOSE
: print 'Exploding: %s' % self
._treeCtrl
.GetItemText(item
, 0)
1106 while item
!= self
._root
:
1107 text
= self
._treeCtrl
.GetItemText(item
, 0)
1108 if _VERBOSE
: print "Appending ", text
1109 parentChain
.append(text
)
1110 item
= self
._treeCtrl
.GetItemParent(item
)
1111 parentChain
.reverse()
1114 def OnView(self
, event
):
1115 title
= self
._treeCtrl
.GetItemText(self
._introspectItem
,0)
1116 value
= self
._treeCtrl
.GetItemText(self
._introspectItem
,1)
1117 dlg
= wx
.lib
.dialogs
.ScrolledMessageDialog(self
, value
, title
, style
=wx
.DD_DEFAULT_STYLE | wx
.RESIZE_BORDER
)
1120 def OnSendToInteract(self
, event
):
1123 for item
in self
._parentChain
:
1125 if item
.find(prevItem
+ '[') != -1:
1126 value
+= item
[item
.find('['):]
1130 if item
== 'globals':
1132 if item
!= 'locals':
1136 self
.ReplaceLastLine(value
)
1137 self
.ExecuteCommand(value
)
1139 def OnWatch(self
, event
):
1141 if hasattr(self
, '_parentChain'):
1142 wd
= WatchDialog(wx
.GetApp().GetTopWindow(), "Add a Watch", self
._parentChain
)
1144 wd
= WatchDialog(wx
.GetApp().GetTopWindow(), "Add a Watch", None)
1146 if wd
.ShowModal() == wx
.ID_OK
:
1147 name
, text
, send_frame
, run_once
= wd
.GetSettings()
1149 frameNode
= self
._stack
[int(self
.currentItem
)]
1150 message
= frameNode
.getAttribute("message")
1153 binType
= self
._ui
._callback
._debuggerServer
.add_watch(name
, text
, message
, run_once
)
1154 xmldoc
= bz2
.decompress(binType
.data
)
1155 domDoc
= parseString(xmldoc
)
1156 nodeList
= domDoc
.getElementsByTagName('watch')
1157 if len(nodeList
) == 1:
1158 watchValue
= nodeList
.item(0).getAttribute("message")
1161 tp
, val
, tb
= sys
.exc_info()
1162 traceback
.print_exception(tp
, val
, tb
)
1164 def OnIntrospect(self
, event
):
1165 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
))
1168 list = self
._framesChoiceCtrl
1169 frameNode
= self
._stack
[int(self
.currentItem
)]
1170 message
= frameNode
.getAttribute("message")
1171 binType
= self
._ui
._callback
._debuggerServer
.attempt_introspection(message
, self
._parentChain
)
1172 xmldoc
= bz2
.decompress(binType
.data
)
1173 domDoc
= parseString(xmldoc
)
1174 #wx.MessageBox(xmldoc, "result of introspection")
1175 nodeList
= domDoc
.getElementsByTagName('replacement')
1176 replacementNode
= nodeList
.item(0)
1177 if len(replacementNode
.childNodes
):
1178 thingToWalk
= replacementNode
.childNodes
.item(0)
1179 tree
= self
._treeCtrl
1180 parent
= tree
.GetItemParent(self
._introspectItem
)
1181 treeNode
= self
.AppendSubTreeFromNode(thingToWalk
, thingToWalk
.getAttribute('name'), parent
, insertBefore
=self
._introspectItem
)
1182 if thingToWalk
.getAttribute('name').find('[') == -1:
1183 self
._treeCtrl
.SortChildren(treeNode
)
1184 self
._treeCtrl
.Expand(treeNode
)
1185 tree
.Delete(self
._introspectItem
)
1187 tp
,val
,tb
= sys
.exc_info()
1188 traceback
.print_exception(tp
, val
, tb
)
1190 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
))
1192 def ClearWhileRunning(self
):
1193 list = self
._framesChoiceCtrl
1196 tree
= self
._treeCtrl
1198 tree
.DeleteChildren(root
)
1199 self
._interCtrl
.Enable(False)
1203 def OnListRightClick(self
, event
):
1204 if not hasattr(self
, "syncFrameID"):
1205 self
.syncFrameID
= wx
.NewId()
1206 self
.Bind(wx
.EVT_MENU
, self
.OnSyncFrame
, id=self
.syncFrameID
)
1208 item
= wx
.MenuItem(menu
, self
.syncFrameID
, "Goto Source Line")
1209 menu
.AppendItem(item
)
1210 self
.PopupMenu(menu
, event
.GetPosition())
1213 def OnSyncFrame(self
, event
):
1214 list = self
._framesChoiceCtrl
1215 frameNode
= self
._stack
[int(self
.currentItem
)]
1216 file = frameNode
.getAttribute("file")
1217 line
= frameNode
.getAttribute("line")
1218 self
._ui
.SynchCurrentLine( file, int(line
) )
1220 def LoadFramesListXML(self
, framesXML
):
1221 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
))
1222 self
._interCtrl
.Enable(True)
1225 domDoc
= parseString(framesXML
)
1226 list = self
._framesChoiceCtrl
1229 nodeList
= domDoc
.getElementsByTagName('frame')
1231 for index
in range(0, nodeList
.length
):
1232 frameNode
= nodeList
.item(index
)
1233 message
= frameNode
.getAttribute("message")
1234 list.Append(message
)
1235 self
._stack
.append(frameNode
)
1237 index
= len(self
._stack
) - 1
1238 list.SetSelection(index
)
1240 node
= self
._stack
[index
]
1241 self
.currentItem
= index
1242 self
.PopulateTreeFromFrameNode(node
)
1243 self
.OnSyncFrame(None)
1245 self
._p
1.FitInside()
1246 frameNode
= nodeList
.item(index
)
1247 file = frameNode
.getAttribute("file")
1248 line
= frameNode
.getAttribute("line")
1249 self
._ui
.SynchCurrentLine( file, int(line
) )
1251 tp
,val
,tb
=sys
.exc_info()
1252 traceback
.print_exception(tp
, val
, tb
)
1254 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
))
1257 def ListItemSelected(self
, event
):
1258 self
.PopulateTreeFromFrameMessage(event
.GetString())
1259 self
.OnSyncFrame(None)
1261 def PopulateTreeFromFrameMessage(self
, message
):
1263 for node
in self
._stack
:
1264 if node
.getAttribute("message") == message
:
1265 binType
= self
._ui
._callback
._debuggerServer
.request_frame_document(message
)
1266 xmldoc
= bz2
.decompress(binType
.data
)
1267 domDoc
= parseString(xmldoc
)
1268 nodeList
= domDoc
.getElementsByTagName('frame')
1269 self
.currentItem
= index
1271 self
.PopulateTreeFromFrameNode(nodeList
[0])
1275 def PopulateTreeFromFrameNode(self
, frameNode
):
1276 list = self
._framesChoiceCtrl
1278 tree
= self
._treeCtrl
1281 tree
.DeleteChildren(root
)
1282 children
= frameNode
.childNodes
1284 for index
in range(0, children
.length
):
1285 subNode
= children
.item(index
)
1286 treeNode
= self
.AppendSubTreeFromNode(subNode
, subNode
.getAttribute('name'), root
)
1288 firstChild
= treeNode
1291 tree
.Expand(firstChild
)
1292 self
._p
2.FitInside()
1294 def IntrospectCallback(self
, event
):
1295 tree
= self
._treeCtrl
1296 item
= event
.GetItem()
1298 print "In introspectCallback item is %s, pydata is %s" % (event
.GetItem(), tree
.GetPyData(item
))
1299 if tree
.GetPyData(item
) != "Introspect":
1302 self
._introspectItem
= item
1303 self
._parentChain
= self
.GetItemChain(item
)
1304 self
.OnIntrospect(event
)
1307 def AppendSubTreeFromNode(self
, node
, name
, parent
, insertBefore
=None):
1308 tree
= self
._treeCtrl
1309 if insertBefore
!= None:
1310 treeNode
= tree
.InsertItem(parent
, insertBefore
, name
)
1312 treeNode
= tree
.AppendItem(parent
, name
)
1313 children
= node
.childNodes
1314 intro
= node
.getAttribute('intro')
1317 tree
.SetItemHasChildren(treeNode
, True)
1318 tree
.SetPyData(treeNode
, "Introspect")
1319 if node
.getAttribute("value"):
1320 tree
.SetItemText(treeNode
, self
.StripOuterSingleQuotes(node
.getAttribute("value")), 1)
1321 for index
in range(0, children
.length
):
1322 subNode
= children
.item(index
)
1323 if self
.HasChildren(subNode
):
1324 self
.AppendSubTreeFromNode(subNode
, subNode
.getAttribute("name"), treeNode
)
1326 name
= subNode
.getAttribute("name")
1327 value
= self
.StripOuterSingleQuotes(subNode
.getAttribute("value"))
1328 n
= tree
.AppendItem(treeNode
, name
)
1329 tree
.SetItemText(n
, value
, 1)
1330 intro
= subNode
.getAttribute('intro')
1332 tree
.SetItemHasChildren(n
, True)
1333 tree
.SetPyData(n
, "Introspect")
1334 if name
.find('[') == -1:
1335 self
._treeCtrl
.SortChildren(treeNode
)
1338 def StripOuterSingleQuotes(self
, string
):
1339 if string
.startswith("'") and string
.endswith("'"):
1340 retval
= string
[1:-1]
1341 elif string
.startswith("\"") and string
.endswith("\""):
1342 retval
= string
[1:-1]
1345 if retval
.startswith("u'") and retval
.endswith("'"):
1349 def HasChildren(self
, node
):
1351 return node
.childNodes
.length
> 0
1353 tp
,val
,tb
=sys
.exc_info()
1356 def AppendText(self
, text
):
1357 self
._textCtrl
.SetReadOnly(False)
1358 self
._textCtrl
.AddText(text
)
1359 self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount())
1360 self
._textCtrl
.SetReadOnly(True)
1362 def AppendErrorText(self
, text
):
1363 self
._textCtrl
.SetReadOnly(False)
1364 self
._textCtrl
.SetFontColor(wx
.RED
)
1365 self
._textCtrl
.StyleClearAll()
1366 self
._textCtrl
.AddText(text
)
1367 self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount())
1368 self
._textCtrl
.SetFontColor(wx
.BLACK
)
1369 self
._textCtrl
.StyleClearAll()
1370 self
._textCtrl
.SetReadOnly(True)
1372 def ClearOutput(self
, event
):
1373 self
._textCtrl
.SetReadOnly(False)
1374 self
._textCtrl
.ClearAll()
1375 self
._textCtrl
.SetReadOnly(True)
1377 def SwitchToOutputTab(self
):
1378 self
._notebook
.SetSelection(0)
1380 class DebuggerView(Service
.ServiceView
):
1382 #----------------------------------------------------------------------------
1383 # Overridden methods
1384 #----------------------------------------------------------------------------
1386 def __init__(self
, service
):
1387 Service
.ServiceView
.__init
__(self
, service
)
1389 def _CreateControl(self
, parent
, id):
1392 #------------------------------------------------------------------------------
1394 #-----------------------------------------------------------------------------
1396 def OnToolClicked(self
, event
):
1397 self
.GetFrame().ProcessEvent(event
)
1399 def ProcessUpdateUIEvent(self
, event
):
1402 def ProcessEvent(self
, event
):
1405 #------------------------------------------------------------------------------
1407 #-----------------------------------------------------------------------------
1410 def __init__(self
, message
, framesXML
, info
=None, quit
=False):
1411 self
._framesXML
= framesXML
1412 self
._message
= message
1416 def getFramesXML(self
):
1417 return self
._framesXML
1419 def getMessage(self
):
1420 return self
._message
1428 class AGXMLRPCServer(SimpleXMLRPCServer
.SimpleXMLRPCServer
):
1429 def __init__(self
, address
, logRequests
=0):
1430 SimpleXMLRPCServer
.SimpleXMLRPCServer
.__init
__(self
, address
, logRequests
=logRequests
)
1432 class RequestHandlerThread(threading
.Thread
):
1433 def __init__(self
, queue
, address
):
1434 threading
.Thread
.__init
__(self
)
1435 self
._keepGoing
= True
1437 self
._address
= address
1438 self
._server
= AGXMLRPCServer(self
._address
,logRequests
=0)
1439 self
._server
.register_function(self
.interaction
)
1440 self
._server
.register_function(self
.quit
)
1441 self
._server
.register_function(self
.dummyOperation
)
1442 if _VERBOSE
: print "RequestHandlerThread on fileno %s" % str(self
._server
.fileno())
1445 while self
._keepGoing
:
1447 self
._server
.handle_request()
1449 tp
, val
, tb
= sys
.exc_info()
1450 traceback
.print_exception(tp
, val
, tb
)
1451 self
._keepGoing
= False
1452 if _VERBOSE
: print "Exiting Request Handler Thread."
1454 def interaction(self
, message
, frameXML
, info
):
1455 if _VERBOSE
: print "In RequestHandlerThread.interaction -- adding to queue"
1456 interaction
= Interaction(message
, frameXML
, info
)
1457 self
._queue
.put(interaction
)
1461 interaction
= Interaction(None, None, info
=None, quit
=True)
1462 self
._queue
.put(interaction
)
1465 def dummyOperation(self
):
1468 def AskToStop(self
):
1469 self
._keepGoing
= False
1470 if type(self
._server
) is not types
.NoneType
:
1472 # This is a really ugly way to make sure this thread isn't blocked in
1474 url
= 'http://' + self
._address
[0] + ':' + str(self
._address
[1]) + '/'
1475 tempServer
= xmlrpclib
.ServerProxy(url
, allow_none
=1)
1476 tempServer
.dummyOperation()
1478 tp
, val
, tb
= sys
.exc_info()
1479 traceback
.print_exception(tp
, val
, tb
)
1480 self
._server
.server_close()
1483 class RequestBreakThread(threading
.Thread
):
1484 def __init__(self
, server
, interrupt
=False, pushBreakpoints
=False, breakDict
=None, kill
=False):
1485 threading
.Thread
.__init
__(self
)
1486 self
._server
= server
1488 self
._interrupt
= interrupt
1489 self
._pushBreakpoints
= pushBreakpoints
1490 self
._breakDict
= breakDict
1495 if _VERBOSE
: print "RequestBreakThread, before call"
1497 self
._server
.break_requested()
1498 if self
._pushBreakpoints
:
1499 self
._server
.update_breakpoints(xmlrpclib
.Binary(pickle
.dumps(self
._breakDict
)))
1505 if _VERBOSE
: print "RequestBreakThread, after call"
1507 tp
,val
,tb
= sys
.exc_info()
1508 traceback
.print_exception(tp
, val
, tb
)
1510 class DebuggerOperationThread(threading
.Thread
):
1511 def __init__(self
, function
):
1512 threading
.Thread
.__init
__(self
)
1513 self
._function
= function
1516 if _VERBOSE
: print "In DOT, before call"
1520 tp
,val
,tb
= sys
.exc_info()
1521 traceback
.print_exception(tp
, val
, tb
)
1522 if _VERBOSE
: print "In DOT, after call"
1524 class DebuggerCallback
:
1526 def __init__(self
, host
, port
, debugger_url
, break_url
, debuggerUI
):
1527 if _VERBOSE
: print "+++++++ Creating server on port, ", str(port
)
1529 self
._queue
= Queue
.Queue(50)
1531 self
._port
= int(port
)
1532 threading
._VERBOSE
= _VERBOSE
1533 self
._serverHandlerThread
= RequestHandlerThread(self
._queue
, (self
._host
, self
._port
))
1535 self
._debugger
_url
= debugger_url
1536 self
._debuggerServer
= None
1537 self
._waiting
= False
1538 self
._service
= wx
.GetApp().GetService(DebuggerService
)
1539 self
._debuggerUI
= debuggerUI
1540 self
._break
_url
= break_url
1541 self
._breakServer
= None
1542 self
._firstInteraction
= True
1543 self
._pendingBreak
= False
1546 self
._serverHandlerThread
.start()
1548 def ShutdownServer(self
):
1549 #rbt = RequestBreakThread(self._breakServer, kill=True)
1551 self
.setWaiting(False)
1552 if self
._serverHandlerThread
:
1553 self
._serverHandlerThread
.AskToStop()
1554 self
._serverHandlerThread
= None
1556 def BreakExecution(self
):
1557 rbt
= RequestBreakThread(self
._breakServer
, interrupt
=True)
1560 def SingleStep(self
):
1561 self
._debuggerUI
.DisableWhileDebuggerRunning()
1562 self
._debuggerServer
.set_step() # Figure out where to set allowNone
1566 self
._debuggerUI
.DisableWhileDebuggerRunning()
1567 self
._debuggerServer
.set_next()
1571 self
._debuggerUI
.DisableWhileDebuggerRunning()
1572 self
._debuggerServer
.set_continue()
1576 self
._debuggerUI
.DisableWhileDebuggerRunning()
1577 self
._debuggerServer
.set_return()
1580 def setWaiting(self
, value
):
1581 self
._waiting
= value
1583 def getWaiting(self
):
1584 return self
._waiting
1586 def readQueue(self
):
1587 if self
._queue
.qsize():
1589 item
= self
._queue
.get_nowait()
1591 self
.interaction(None, None, None, True)
1593 data
= bz2
.decompress(item
.getFramesXML().data
)
1594 self
.interaction(item
.getMessage().data
, data
, item
.getInfo(), False)
1598 def pushBreakpoints(self
):
1599 rbt
= RequestBreakThread(self
._breakServer
, pushBreakpoints
=True, breakDict
=self
._service
.GetMasterBreakpointDict())
1603 def waitForRPC(self
):
1604 self
.setWaiting(True)
1605 while self
.getWaiting():
1611 tp
, val
, tb
= sys
.exc_info()
1612 traceback
.print_exception(tp
, val
, tb
)
1613 wx
.GetApp().Yield(True)
1614 if _VERBOSE
: print "Exiting waitForRPC."
1616 def interaction(self
, message
, frameXML
, info
, quit
):
1618 #This method should be hit as the debugger starts.
1619 if self
._firstInteraction
:
1620 self
._firstInteraction
= False
1621 self
._debuggerServer
= xmlrpclib
.ServerProxy(self
._debugger
_url
, allow_none
=1)
1622 self
._breakServer
= xmlrpclib
.ServerProxy(self
._break
_url
, allow_none
=1)
1623 self
.pushBreakpoints()
1624 self
.setWaiting(False)
1625 if _VERBOSE
: print "+"*40
1627 self
._debuggerUI
.StopExecution(None)
1630 if _VERBOSE
: print "Hit interaction with exception"
1631 #self._debuggerUI.StopExecution(None)
1632 #self._debuggerUI.SetStatusText("Got exception: " + str(info))
1633 self
._debuggerUI
.SwitchToOutputTab()
1635 if _VERBOSE
: print "Hit interaction no exception"
1636 self
._debuggerUI
.SetStatusText(message
)
1637 self
._debuggerUI
.LoadFramesListXML(frameXML
)
1638 self
._debuggerUI
.EnableWhileDebuggerStopped()
1639 if _VERBOSE
: print "+"*40
1641 class DebuggerService(Service
.Service
):
1643 #----------------------------------------------------------------------------
1645 #----------------------------------------------------------------------------
1646 TOGGLE_BREAKPOINT_ID
= wx
.NewId()
1647 CLEAR_ALL_BREAKPOINTS
= wx
.NewId()
1649 DEBUG_ID
= wx
.NewId()
1650 DEBUG_WEBSERVER_ID
= wx
.NewId()
1651 RUN_WEBSERVER_ID
= wx
.NewId()
1653 def ComparePaths(first
, second
):
1654 one
= DebuggerService
.ExpandPath(first
)
1655 two
= DebuggerService
.ExpandPath(second
)
1657 return one
.lower() == two
.lower()
1660 ComparePaths
= staticmethod(ComparePaths
)
1662 # Make sure we're using an expanded path on windows.
1663 def ExpandPath(path
):
1666 return win32api
.GetLongPathName(path
)
1669 print "Cannot get long path for %s" % path
1673 ExpandPath
= staticmethod(ExpandPath
)
1675 #----------------------------------------------------------------------------
1676 # Overridden methods
1677 #----------------------------------------------------------------------------
1679 def __init__(self
, serviceName
, embeddedWindowLocation
= wx
.lib
.pydocview
.EMBEDDED_WINDOW_LEFT
):
1680 Service
.Service
.__init
__(self
, serviceName
, embeddedWindowLocation
)
1681 self
.BREAKPOINT_DICT_STRING
= "MasterBreakpointDict"
1682 config
= wx
.ConfigBase_Get()
1683 pickledbps
= config
.Read(self
.BREAKPOINT_DICT_STRING
)
1686 self
._masterBPDict
= pickle
.loads(pickledbps
.encode('ascii'))
1688 tp
, val
, tb
= sys
.exc_info()
1689 traceback
.print_exception(tp
,val
,tb
)
1690 self
._masterBPDict
= {}
1692 self
._masterBPDict
= {}
1694 def OnCloseFrame(self
, event
):
1695 # IS THIS THE RIGHT PLACE?
1697 config
= wx
.ConfigBase_Get()
1698 config
.Write(self
.BREAKPOINT_DICT_STRING
, pickle
.dumps(self
._masterBPDict
))
1700 tp
,val
,tb
= sys
.exc_info()
1701 traceback
.print_exception(tp
, val
, tb
)
1704 def _CreateView(self
):
1705 return DebuggerView(self
)
1708 #----------------------------------------------------------------------------
1709 # Service specific methods
1710 #----------------------------------------------------------------------------
1712 def InstallControls(self
, frame
, menuBar
= None, toolBar
= None, statusBar
= None, document
= None):
1713 #Service.Service.InstallControls(self, frame, menuBar, toolBar, statusBar, document)
1715 config
= wx
.ConfigBase_Get()
1717 debuggerMenu
= wx
.Menu()
1718 if not menuBar
.FindItemById(DebuggerService
.CLEAR_ALL_BREAKPOINTS
):
1720 debuggerMenu
.Append(DebuggerService
.RUN_ID
, _("&Run...\tCtrl+R"), _("Runs a file"))
1721 wx
.EVT_MENU(frame
, DebuggerService
.RUN_ID
, frame
.ProcessEvent
)
1722 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.RUN_ID
, frame
.ProcessUpdateUIEvent
)
1724 debuggerMenu
.Append(DebuggerService
.DEBUG_ID
, _("&Debug...\tCtrl+D"), _("Debugs a file"))
1725 wx
.EVT_MENU(frame
, DebuggerService
.DEBUG_ID
, frame
.ProcessEvent
)
1726 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.DEBUG_ID
, frame
.ProcessUpdateUIEvent
)
1728 if not ACTIVEGRID_BASE_IDE
:
1729 debuggerMenu
.AppendSeparator()
1730 debuggerMenu
.Append(DebuggerService
.DEBUG_WEBSERVER_ID
, _("Debug Internal Web Server"), _("Debugs the internal webservier"))
1731 wx
.EVT_MENU(frame
, DebuggerService
.DEBUG_WEBSERVER_ID
, frame
.ProcessEvent
)
1732 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.DEBUG_WEBSERVER_ID
, frame
.ProcessUpdateUIEvent
)
1733 debuggerMenu
.Append(DebuggerService
.RUN_WEBSERVER_ID
, _("Restart Internal Web Server"), _("Restarts the internal webservier"))
1734 wx
.EVT_MENU(frame
, DebuggerService
.RUN_WEBSERVER_ID
, frame
.ProcessEvent
)
1735 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.RUN_WEBSERVER_ID
, frame
.ProcessUpdateUIEvent
)
1737 debuggerMenu
.AppendSeparator()
1739 debuggerMenu
.Append(DebuggerService
.TOGGLE_BREAKPOINT_ID
, _("&Toggle Breakpoint...\tCtrl+B"), _("Toggle a breakpoint"))
1740 wx
.EVT_MENU(frame
, DebuggerService
.TOGGLE_BREAKPOINT_ID
, self
.ProcessEvent
)
1741 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.TOGGLE_BREAKPOINT_ID
, self
.ProcessUpdateUIEvent
)
1743 debuggerMenu
.Append(DebuggerService
.CLEAR_ALL_BREAKPOINTS
, _("&Clear All Breakpoints"), _("Clear All Breakpoints"))
1744 wx
.EVT_MENU(frame
, DebuggerService
.CLEAR_ALL_BREAKPOINTS
, self
.ProcessEvent
)
1745 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.CLEAR_ALL_BREAKPOINTS
, self
.ProcessUpdateUIEvent
)
1748 viewMenuIndex
= menuBar
.FindMenu(_("&Project"))
1749 menuBar
.Insert(viewMenuIndex
+ 1, debuggerMenu
, _("&Run"))
1751 toolBar
.AddSeparator()
1752 toolBar
.AddTool(DebuggerService
.RUN_ID
, getRunningManBitmap(), shortHelpString
= _("Run"), longHelpString
= _("Run"))
1753 toolBar
.AddTool(DebuggerService
.DEBUG_ID
, getDebuggingManBitmap(), shortHelpString
= _("Debug"), longHelpString
= _("Debug"))
1760 #----------------------------------------------------------------------------
1761 # Event Processing Methods
1762 #----------------------------------------------------------------------------
1764 def ProcessEventBeforeWindows(self
, event
):
1768 def ProcessEvent(self
, event
):
1769 if Service
.Service
.ProcessEvent(self
, event
):
1772 an_id
= event
.GetId()
1773 if an_id
== DebuggerService
.TOGGLE_BREAKPOINT_ID
:
1774 self
.OnToggleBreakpoint(event
)
1776 elif an_id
== DebuggerService
.CLEAR_ALL_BREAKPOINTS
:
1777 self
.ClearAllBreakpoints()
1779 elif an_id
== DebuggerService
.RUN_ID
:
1780 self
.OnRunProject(event
)
1782 elif an_id
== DebuggerService
.DEBUG_ID
:
1783 self
.OnDebugProject(event
)
1785 elif an_id
== DebuggerService
.DEBUG_WEBSERVER_ID
:
1786 self
.OnDebugWebServer(event
)
1788 elif an_id
== DebuggerService
.RUN_WEBSERVER_ID
:
1789 self
.OnRunWebServer(event
)
1793 def ProcessUpdateUIEvent(self
, event
):
1794 if Service
.Service
.ProcessUpdateUIEvent(self
, event
):
1797 an_id
= event
.GetId()
1798 if an_id
== DebuggerService
.TOGGLE_BREAKPOINT_ID
:
1799 currentView
= self
.GetDocumentManager().GetCurrentView()
1800 event
.Enable(isinstance(currentView
, PythonEditor
.PythonView
))
1802 elif an_id
== DebuggerService
.CLEAR_ALL_BREAKPOINTS
:
1803 event
.Enable(self
.HasBreakpointsSet())
1805 elif (an_id
== DebuggerService
.RUN_ID
1806 or an_id
== DebuggerService
.DEBUG_ID
):
1807 event
.Enable(self
.HasAnyFiles())
1812 #----------------------------------------------------------------------------
1814 #----------------------------------------------------------------------------
1816 def OnDebugProject(self
, event
):
1817 if _WINDOWS
and not _PYWIN32_INSTALLED
:
1818 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."))
1820 if not Executor
.GetPythonExecutablePath():
1822 if DebugCommandUI
.DebuggerRunning():
1823 wx
.MessageBox(_("A debugger is already running. Please shut down the other debugger first."), _("Debugger Running"))
1825 self
.ShowWindow(True)
1826 projectService
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
)
1828 dlg
= CommandPropertiesDialog(self
.GetView().GetFrame(), 'Debug Python File', projectService
, None, pythonOnly
=True, okButtonName
="Debug", debugging
=True)
1831 dlg
.CenterOnParent()
1832 if dlg
.ShowModal() == wx
.ID_OK
:
1833 projectPath
, fileToDebug
, initialArgs
, startIn
, isPython
, environment
= dlg
.GetSettings()
1838 self
.PromptToSaveFiles()
1840 shortFile
= os
.path
.basename(fileToDebug
)
1841 fileToDebug
= DebuggerService
.ExpandPath(fileToDebug
)
1843 page
= DebugCommandUI(Service
.ServiceView
.bottomTab
, -1, str(fileToDebug
), self
)
1844 count
= Service
.ServiceView
.bottomTab
.GetPageCount()
1845 Service
.ServiceView
.bottomTab
.AddPage(page
, _("Debugging: ") + shortFile
)
1846 Service
.ServiceView
.bottomTab
.SetSelection(count
)
1847 page
.Execute(initialArgs
, startIn
, environment
)
1851 def OnDebugWebServer(self
, event
):
1852 if _WINDOWS
and not _PYWIN32_INSTALLED
:
1853 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."))
1855 if not Executor
.GetPythonExecutablePath():
1857 if DebugCommandUI
.DebuggerRunning():
1858 wx
.MessageBox(_("A debugger is already running. Please shut down the other debugger first."), _("Debugger Running"))
1860 import WebServerService
1861 wsService
= wx
.GetApp().GetService(WebServerService
.WebServerService
)
1862 fileName
, args
= wsService
.StopAndPrepareToDebug()
1864 page
= DebugCommandUI(Service
.ServiceView
.bottomTab
, -1, fileName
, self
)
1865 count
= Service
.ServiceView
.bottomTab
.GetPageCount()
1866 Service
.ServiceView
.bottomTab
.AddPage(page
, _("Debugging: Internal WebServer"))
1867 Service
.ServiceView
.bottomTab
.SetSelection(count
)
1868 page
.Execute(args
, startIn
=os
.getcwd(), environment
=os
.environ
)
1872 def OnRunWebServer(self
, event
):
1873 if not Executor
.GetPythonExecutablePath():
1875 import WebServerService
1876 wsService
= wx
.GetApp().GetService(WebServerService
.WebServerService
)
1877 wsService
.ShutDownAndRestart()
1879 def HasAnyFiles(self
):
1880 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1881 return len(docs
) > 0
1883 def PromptToSaveFiles(self
, running
=True):
1884 filesModified
= False
1885 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1887 if doc
.IsModified():
1888 filesModified
= True
1891 frame
= self
.GetView().GetFrame()
1893 yesNoMsg
= wx
.MessageDialog(frame
,
1894 _("Files have been modified.\nWould you like to save all files before running?"),
1896 wx
.YES_NO|wx
.ICON_QUESTION
1899 yesNoMsg
= wx
.MessageDialog(frame
,
1900 _("Files have been modified.\nWould you like to save all files before debugging?"),
1902 wx
.YES_NO|wx
.ICON_QUESTION
1904 yesNoMsg
.CenterOnParent()
1905 if yesNoMsg
.ShowModal() == wx
.ID_YES
:
1906 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1912 DebugCommandUI
.ShutdownAllDebuggers()
1913 RunCommandUI
.ShutdownAllRunners()
1915 def OnRunProject(self
, event
):
1916 if _WINDOWS
and not _PYWIN32_INSTALLED
:
1917 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."))
1919 if not Executor
.GetPythonExecutablePath():
1921 projectService
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
)
1923 dlg
= CommandPropertiesDialog(self
.GetView().GetFrame(), 'Run', projectService
, None)
1926 dlg
.CenterOnParent()
1927 if dlg
.ShowModal() == wx
.ID_OK
:
1928 projectPath
, fileToRun
, initialArgs
, startIn
, isPython
, environment
= dlg
.GetSettings()
1933 self
.PromptToSaveFiles()
1934 # This will need to change when we can run more than .py and .bpel files.
1936 projects
= projectService
.FindProjectByFile(projectPath
)
1939 project
= projects
[0]
1940 deployFilePath
= project
.GenerateDeployment()
1941 projectService
.RunProcessModel(fileToRun
, project
.GetAppInfo().language
, deployFilePath
)
1944 self
.ShowWindow(True)
1945 shortFile
= os
.path
.basename(fileToRun
)
1946 page
= RunCommandUI(Service
.ServiceView
.bottomTab
, -1, str(fileToRun
))
1947 count
= Service
.ServiceView
.bottomTab
.GetPageCount()
1948 Service
.ServiceView
.bottomTab
.AddPage(page
, "Running: " + shortFile
)
1949 Service
.ServiceView
.bottomTab
.SetSelection(count
)
1950 page
.Execute(initialArgs
, startIn
, environment
)
1952 def OnToggleBreakpoint(self
, event
, line
=-1, fileName
=None):
1954 view
= wx
.GetApp().GetDocumentManager().GetCurrentView()
1955 # Test to make sure we aren't the project view.
1956 if not hasattr(view
, 'MarkerExists'):
1958 fileName
= wx
.GetApp().GetDocumentManager().GetCurrentDocument().GetFilename()
1960 line
= view
.GetCtrl().GetCurrentLine()
1963 if self
.BreakpointSet(fileName
, line
+ 1):
1964 self
.ClearBreak(fileName
, line
+ 1)
1966 view
.GetCtrl().Refresh()
1968 self
.SetBreak(fileName
, line
+ 1)
1970 view
.GetCtrl().Refresh()
1971 # Now refresh all the markers icons in all the open views.
1972 self
.ClearAllBreakpointMarkers()
1973 self
.SetAllBreakpointMarkers()
1975 def SilentToggleBreakpoint(self
, fileName
, line
):
1977 for lineNumber
in self
.GetBreakpointList(fileName
):
1978 if int(lineNumber
) == int(line
):
1982 self
.SetBreak(fileName
, line
)
1984 self
.ClearBreak(fileName
, line
)
1986 def SetBreak(self
, fileName
, line
):
1987 expandedName
= DebuggerService
.ExpandPath(fileName
)
1988 if not self
._masterBPDict
.has_key(expandedName
):
1989 self
._masterBPDict
[expandedName
] = [line
]
1991 self
._masterBPDict
[expandedName
] += [line
]
1992 # If we're already debugging, pass this bp off to the DebuggerCallback
1993 self
.NotifyDebuggersOfBreakpointChange()
1995 def NotifyDebuggersOfBreakpointChange(self
):
1996 DebugCommandUI
.NotifyDebuggersOfBreakpointChange()
1998 def GetBreakpointList(self
, fileName
):
1999 expandedName
= DebuggerService
.ExpandPath(fileName
)
2000 if not self
._masterBPDict
.has_key(expandedName
):
2003 return self
._masterBPDict
[expandedName
]
2005 def SetBreakpointList(self
, fileName
, bplist
):
2006 expandedName
= DebuggerService
.ExpandPath(fileName
)
2007 self
._masterBPDict
[expandedName
] = bplist
2009 def BreakpointSet(self
, fileName
, line
):
2010 expandedName
= DebuggerService
.ExpandPath(fileName
)
2011 if not self
._masterBPDict
.has_key(expandedName
):
2015 for number
in self
._masterBPDict
[expandedName
]:
2016 if(int(number
) == int(line
)):
2020 def ClearBreak(self
, fileName
, line
):
2021 expandedName
= DebuggerService
.ExpandPath(fileName
)
2022 if not self
._masterBPDict
.has_key(expandedName
):
2023 print "In ClearBreak: no key"
2027 for number
in self
._masterBPDict
[expandedName
]:
2028 if(int(number
) != int(line
)):
2029 newList
.append(number
)
2030 self
._masterBPDict
[expandedName
] = newList
2031 self
.NotifyDebuggersOfBreakpointChange()
2033 def HasBreakpointsSet(self
):
2034 for key
, value
in self
._masterBPDict
.items():
2039 def ClearAllBreakpoints(self
):
2040 self
._masterBPDict
= {}
2041 self
.NotifyDebuggersOfBreakpointChange()
2042 self
.ClearAllBreakpointMarkers()
2044 def ClearAllBreakpointMarkers(self
):
2045 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
2046 for openDoc
in openDocs
:
2047 if isinstance(openDoc
, CodeEditor
.CodeDocument
):
2048 openDoc
.GetFirstView().MarkerDeleteAll(CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
)
2050 def UpdateBreakpointsFromMarkers(self
, view
, fileName
):
2051 newbpLines
= view
.GetMarkerLines(CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
)
2052 self
.SetBreakpointList(fileName
, newbpLines
)
2054 def GetMasterBreakpointDict(self
):
2055 return self
._masterBPDict
2057 def SetAllBreakpointMarkers(self
):
2058 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
2059 for openDoc
in openDocs
:
2060 if(isinstance(openDoc
, CodeEditor
.CodeDocument
)):
2061 self
.SetCurrentBreakpointMarkers(openDoc
.GetFirstView())
2063 def SetCurrentBreakpointMarkers(self
, view
):
2064 if isinstance(view
, CodeEditor
.CodeView
) and hasattr(view
, 'GetDocument'):
2065 view
.MarkerDeleteAll(CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
)
2066 for linenum
in self
.GetBreakpointList(view
.GetDocument().GetFilename()):
2067 view
.MarkerAdd(lineNum
=int(linenum
) - 1, marker_index
=CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
)
2069 class DebuggerOptionsPanel(wx
.Panel
):
2072 def __init__(self
, parent
, id):
2073 wx
.Panel
.__init
__(self
, parent
, id)
2075 config
= wx
.ConfigBase_Get()
2076 localHostStaticText
= wx
.StaticText(self
, -1, _("Local Host Name:"))
2077 self
._LocalHostTextCtrl
= wx
.TextCtrl(self
, -1, config
.Read("DebuggerHostName", DEFAULT_HOST
), size
= (150, -1))
2078 portNumberStaticText
= wx
.StaticText(self
, -1, _("Port Range:"))
2079 dashStaticText
= wx
.StaticText(self
, -1, _("through to"))
2080 startingPort
=config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
)
2081 self
._PortNumberTextCtrl
= wx
.lib
.intctrl
.IntCtrl(self
, -1, startingPort
, size
= (50, -1))
2082 self
._PortNumberTextCtrl
.SetMin(1)#What are real values?
2083 self
._PortNumberTextCtrl
.SetMax(65514) #What are real values?
2084 self
.Bind(wx
.lib
.intctrl
.EVT_INT
, self
.MinPortChange
, self
._PortNumberTextCtrl
)
2086 self
._EndPortNumberTextCtrl
= wx
.lib
.intctrl
.IntCtrl(self
, -1, startingPort
+ PORT_COUNT
, size
= (50, -1))
2087 self
._EndPortNumberTextCtrl
.SetMin(22)#What are real values?
2088 self
._EndPortNumberTextCtrl
.SetMax(65535)#What are real values?
2089 self
._EndPortNumberTextCtrl
.Enable( False )
2090 debuggerPanelBorderSizer
= wx
.BoxSizer(wx
.VERTICAL
)
2091 debuggerPanelSizer
= wx
.GridBagSizer(hgap
= 5, vgap
= 5)
2092 debuggerPanelSizer
.Add( localHostStaticText
, (0,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2093 debuggerPanelSizer
.Add( self
._LocalHostTextCtrl
, (0,1), (1,3), flag
=wx
.EXPAND|wx
.ALIGN_CENTER
)
2094 debuggerPanelSizer
.Add( portNumberStaticText
, (1,0), flag
=wx
.ALIGN_LEFT|wx
.ALIGN_CENTER_VERTICAL
)
2095 debuggerPanelSizer
.Add( self
._PortNumberTextCtrl
, (1,1), flag
=wx
.ALIGN_CENTER
)
2096 debuggerPanelSizer
.Add( dashStaticText
, (1,2), flag
=wx
.ALIGN_CENTER
)
2097 debuggerPanelSizer
.Add( self
._EndPortNumberTextCtrl
, (1,3), flag
=wx
.ALIGN_CENTER
)
2098 FLUSH_PORTS_ID
= wx
.NewId()
2099 self
._flushPortsButton
= wx
.Button(self
, FLUSH_PORTS_ID
, "Reset Port List")
2100 wx
.EVT_BUTTON(parent
, FLUSH_PORTS_ID
, self
.FlushPorts
)
2101 debuggerPanelSizer
.Add(self
._flushPortsButton
, (2,2), (1,2), flag
=wx
.ALIGN_RIGHT
)
2103 debuggerPanelBorderSizer
.Add(debuggerPanelSizer
, 0, wx
.ALL
, SPACE
)
2104 self
.SetSizer(debuggerPanelBorderSizer
)
2106 parent
.AddPage(self
, _("Debugger"))
2108 def FlushPorts(self
, event
):
2109 if self
._PortNumberTextCtrl
.IsInBounds():
2110 config
= wx
.ConfigBase_Get()
2111 config
.WriteInt("DebuggerStartingPort", self
._PortNumberTextCtrl
.GetValue())
2112 DebugCommandUI
.NewPortRange()
2114 wx
.MessageBox(_("The starting port is not valid. Please change the value and try again.", "Invalid Starting Port Number"))
2116 def MinPortChange(self
, event
):
2117 self
._EndPortNumberTextCtrl
.Enable( True )
2118 self
._EndPortNumberTextCtrl
.SetValue( self
._PortNumberTextCtrl
.GetValue() + PORT_COUNT
)
2119 self
._EndPortNumberTextCtrl
.Enable( False )
2121 def OnOK(self
, optionsDialog
):
2122 config
= wx
.ConfigBase_Get()
2123 config
.Write("DebuggerHostName", self
._LocalHostTextCtrl
.GetValue())
2124 if self
._PortNumberTextCtrl
.IsInBounds():
2125 config
.WriteInt("DebuggerStartingPort", self
._PortNumberTextCtrl
.GetValue())
2129 return getContinueIcon()
2132 class CommandPropertiesDialog(wx
.Dialog
):
2134 def __init__(self
, parent
, title
, projectService
, currentProjectDocument
, pythonOnly
=False, okButtonName
="Run", debugging
=False):
2135 self
._projService
= projectService
2138 for template
in self
._projService
.GetDocumentManager().GetTemplates():
2139 if not ACTIVEGRID_BASE_IDE
and template
.GetDocumentType() == ProcessModelEditor
.ProcessModelDocument
:
2140 self
._pmext
= template
.GetDefaultExtension()
2141 if template
.GetDocumentType() == PythonEditor
.PythonDocument
:
2142 self
._pyext
= template
.GetDefaultExtension()
2143 self
._pythonOnly
= pythonOnly
2144 self
._currentProj
= currentProjectDocument
2145 self
._projectNameList
, self
._projectDocumentList
, selectedIndex
= self
.GetProjectList()
2146 if not self
._projectNameList
:
2147 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"))
2150 wx
.Dialog
.__init
__(self
, parent
, -1, title
)
2152 projStaticText
= wx
.StaticText(self
, -1, _("Project:"))
2153 fileStaticText
= wx
.StaticText(self
, -1, _("File:"))
2154 argsStaticText
= wx
.StaticText(self
, -1, _("Arguments:"))
2155 startInStaticText
= wx
.StaticText(self
, -1, _("Start in:"))
2156 pythonPathStaticText
= wx
.StaticText(self
, -1, _("PYTHONPATH:"))
2157 postpendStaticText
= _("Postpend win32api path")
2158 cpPanelBorderSizer
= wx
.BoxSizer(wx
.VERTICAL
)
2159 self
._projList
= wx
.Choice(self
, -1, choices
=self
._projectNameList
)
2160 self
.Bind(wx
.EVT_CHOICE
, self
.EvtListBox
, self
._projList
)
2163 if wx
.Platform
== "__WXMAC__":
2165 flexGridSizer
= wx
.GridBagSizer(GAP
, GAP
)
2167 flexGridSizer
.Add(projStaticText
, (0,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2168 flexGridSizer
.Add(self
._projList
, (0,1), (1,2), flag
=wx
.EXPAND
)
2170 flexGridSizer
.Add(fileStaticText
, (1,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2171 self
._fileList
= wx
.Choice(self
, -1)
2172 self
.Bind(wx
.EVT_CHOICE
, self
.OnFileSelected
, self
._fileList
)
2173 flexGridSizer
.Add(self
._fileList
, (1,1), (1,2), flag
=wx
.EXPAND
)
2175 config
= wx
.ConfigBase_Get()
2176 self
._lastArguments
= config
.Read("LastRunArguments")
2177 self
._argsEntry
= wx
.TextCtrl(self
, -1, str(self
._lastArguments
))
2178 self
._argsEntry
.SetToolTipString(str(self
._lastArguments
))
2180 flexGridSizer
.Add(argsStaticText
, (2,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2181 flexGridSizer
.Add(self
._argsEntry
, (2,1), (1,2), flag
=wx
.EXPAND
)
2183 flexGridSizer
.Add(startInStaticText
, (3,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2184 self
._lastStartIn
= config
.Read("LastRunStartIn")
2185 if not self
._lastStartIn
:
2186 self
._lastStartIn
= str(os
.getcwd())
2187 self
._startEntry
= wx
.TextCtrl(self
, -1, self
._lastStartIn
)
2188 self
._startEntry
.SetToolTipString(self
._lastStartIn
)
2190 flexGridSizer
.Add(self
._startEntry
, (3,1), flag
=wx
.EXPAND
)
2191 self
._findDir
= wx
.Button(self
, -1, _("Browse..."))
2192 self
.Bind(wx
.EVT_BUTTON
, self
.OnFindDirClick
, self
._findDir
)
2193 flexGridSizer
.Add(self
._findDir
, (3,2))
2195 flexGridSizer
.Add(pythonPathStaticText
, (4,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2196 if os
.environ
.has_key('PYTHONPATH'):
2197 startval
= os
.environ
['PYTHONPATH']
2200 self
._lastPythonPath
= config
.Read("LastPythonPath", startval
)
2201 self
._pythonPathEntry
= wx
.TextCtrl(self
, -1, self
._lastPythonPath
)
2202 self
._pythonPathEntry
.SetToolTipString(self
._lastPythonPath
)
2203 flexGridSizer
.Add(self
._pythonPathEntry
, (4,1), (1,2), flag
=wx
.EXPAND
)
2205 if debugging
and _WINDOWS
:
2206 self
._postpendCheckBox
= wx
.CheckBox(self
, -1, postpendStaticText
)
2207 checked
= bool(config
.ReadInt("PythonPathPostpend", 1))
2208 self
._postpendCheckBox
.SetValue(checked
)
2209 flexGridSizer
.Add(self
._postpendCheckBox
, (5,1), flag
=wx
.EXPAND
)
2210 cpPanelBorderSizer
.Add(flexGridSizer
, 0, flag
=wx
.ALL
, border
=10)
2212 box
= wx
.StdDialogButtonSizer()
2213 self
._okButton
= wx
.Button(self
, wx
.ID_OK
, okButtonName
)
2214 self
._okButton
.SetDefault()
2215 self
._okButton
.SetHelpText(_("The ") + okButtonName
+ _(" button completes the dialog"))
2216 box
.AddButton(self
._okButton
)
2217 self
.Bind(wx
.EVT_BUTTON
, self
.OnOKClick
, self
._okButton
)
2218 btn
= wx
.Button(self
, wx
.ID_CANCEL
, _("Cancel"))
2219 btn
.SetHelpText(_("The Cancel button cancels the dialog."))
2222 cpPanelBorderSizer
.Add(box
, 0, flag
=wx
.ALIGN_RIGHT|wx
.ALL
, border
=5)
2224 self
.SetSizer(cpPanelBorderSizer
)
2226 # Set up selections based on last values used.
2227 self
._fileNameList
= None
2228 self
._selectedFileIndex
= 0
2229 lastProject
= config
.Read("LastRunProject")
2230 lastFile
= config
.Read("LastRunFile")
2232 if lastProject
in self
._projectNameList
:
2233 selectedIndex
= self
._projectNameList
.index(lastProject
)
2234 elif selectedIndex
< 0:
2236 self
._projList
.Select(selectedIndex
)
2237 self
._selectedProjectIndex
= selectedIndex
2238 self
._selectedProjectDocument
= self
._projectDocumentList
[selectedIndex
]
2239 self
.PopulateFileList(self
._selectedProjectDocument
, lastFile
)
2241 cpPanelBorderSizer
.Fit(self
)
2244 def OnOKClick(self
, event
):
2245 startIn
= self
._startEntry
.GetValue()
2246 fileToRun
= self
._fileList
.GetStringSelection()
2248 wx
.MessageBox(_("You must select a file to proceed. Note that not all projects have files that can be run or debugged."))
2250 isPython
= fileToRun
.endswith(self
._pyext
)
2251 if isPython
and not os
.path
.exists(startIn
):
2252 wx
.MessageBox(_("Starting directory does not exist. Please change this value."))
2254 config
= wx
.ConfigBase_Get()
2255 config
.Write("LastRunProject", self
._projectNameList
[self
._selectedProjectIndex
])
2256 config
.Write("LastRunFile", fileToRun
)
2257 # Don't update the arguments or starting directory unless we're runing python.
2259 config
.Write("LastRunArguments", self
._argsEntry
.GetValue())
2260 config
.Write("LastRunStartIn", self
._startEntry
.GetValue())
2261 config
.Write("LastPythonPath",self
._pythonPathEntry
.GetValue())
2262 if hasattr(self
, "_postpendCheckBox"):
2263 config
.WriteInt("PythonPathPostpend", int(self
._postpendCheckBox
.GetValue()))
2265 self
.EndModal(wx
.ID_OK
)
2267 def GetSettings(self
):
2268 projectPath
= self
._selectedProjectDocument
.GetFilename()
2269 filename
= self
._fileNameList
[self
._selectedFileIndex
]
2270 args
= self
._argsEntry
.GetValue()
2271 startIn
= self
._startEntry
.GetValue()
2272 isPython
= filename
.endswith(self
._pyext
)
2274 if hasattr(self
, "_postpendCheckBox"):
2275 postpend
= self
._postpendCheckBox
.GetValue()
2279 env
['PYTHONPATH'] = self
._pythonPathEntry
.GetValue() + os
.pathsep
+ os
.path
.join(os
.getcwd(), "3rdparty", "pywin32")
2281 env
['PYTHONPATH'] = self
._pythonPathEntry
.GetValue()
2283 return projectPath
, filename
, args
, startIn
, isPython
, env
2285 def OnFileSelected(self
, event
):
2286 self
._selectedFileIndex
= self
._fileList
.GetSelection()
2287 self
.EnableForFileType(event
.GetString())
2289 def EnableForFileType(self
, fileName
):
2290 show
= fileName
.endswith(self
._pyext
)
2291 self
._startEntry
.Enable(show
)
2292 self
._findDir
.Enable(show
)
2293 self
._argsEntry
.Enable(show
)
2296 self
._lastStartIn
= self
._startEntry
.GetValue()
2297 self
._startEntry
.SetValue("")
2298 self
._lastArguments
= self
._argsEntry
.GetValue()
2299 self
._argsEntry
.SetValue("")
2301 self
._startEntry
.SetValue(self
._lastStartIn
)
2302 self
._argsEntry
.SetValue(self
._lastArguments
)
2305 def OnFindDirClick(self
, event
):
2306 dlg
= wx
.DirDialog(self
, "Choose a starting directory:", self
._startEntry
.GetValue(),
2307 style
=wx
.DD_DEFAULT_STYLE|wx
.DD_NEW_DIR_BUTTON
)
2309 dlg
.CenterOnParent()
2310 if dlg
.ShowModal() == wx
.ID_OK
:
2311 self
._startEntry
.SetValue(dlg
.GetPath())
2316 def EvtListBox(self
, event
):
2317 if event
.GetString():
2318 index
= self
._projectNameList
.index(event
.GetString())
2319 self
._selectedProjectDocument
= self
._projectDocumentList
[index
]
2320 self
._selectedProjectIndex
= index
2321 self
.PopulateFileList(self
._selectedProjectDocument
)
2323 def FilterFileList(self
, list):
2324 if self
._pythonOnly
:
2325 files
= filter(lambda f
: f
.endswith(self
._pyext
), list)
2327 files
= filter(lambda f
: (self
._pmext
and f
.endswith(self
._pmext
)) or f
.endswith(self
._pyext
), list)
2330 def PopulateFileList(self
, project
, shortNameToSelect
=None):
2331 self
._fileNameList
= self
.FilterFileList(project
.GetFiles()[:])
2332 self
._fileList
.Clear()
2333 if not self
._fileNameList
:
2335 self
._fileNameList
.sort(lambda a
, b
: cmp(os
.path
.basename(a
).lower(), os
.path
.basename(b
).lower()))
2336 strings
= map(lambda file: os
.path
.basename(file), self
._fileNameList
)
2337 for index
in range(0, len(strings
)):
2338 if shortNameToSelect
== strings
[index
]:
2339 self
._selectedFileIndex
= index
2341 self
._fileList
.Hide()
2342 self
._fileList
.AppendItems(strings
)
2343 self
._fileList
.Show()
2344 if self
._selectedFileIndex
not in range(0, len(strings
)) : self
._selectedFileIndex
= 0
2345 self
._fileList
.SetSelection(self
._selectedFileIndex
)
2346 self
.EnableForFileType(strings
[self
._selectedFileIndex
])
2348 def GetProjectList(self
):
2354 for document
in self
._projService
.GetDocumentManager().GetDocuments():
2355 if document
.GetDocumentTemplate().GetDocumentType() == ProjectEditor
.ProjectDocument
and len(document
.GetFiles()):
2356 docList
.append(document
)
2357 nameList
.append(os
.path
.basename(document
.GetFilename()))
2358 if document
== self
._currentProj
:
2362 #Check for open files not in any of these projects and add them to a default project
2363 def AlreadyInProject(fileName
):
2364 for projectDocument
in docList
:
2365 if projectDocument
.IsFileInProject(fileName
):
2369 unprojectedFiles
= []
2370 for document
in self
._projService
.GetDocumentManager().GetDocuments():
2371 if not ACTIVEGRID_BASE_IDE
and type(document
) == ProcessModelEditor
.ProcessModelDocument
:
2372 if not AlreadyInProject(document
.GetFilename()):
2373 unprojectedFiles
.append(document
.GetFilename())
2374 if type(document
) == PythonEditor
.PythonDocument
:
2375 if not AlreadyInProject(document
.GetFilename()):
2376 unprojectedFiles
.append(document
.GetFilename())
2378 if unprojectedFiles
:
2379 unprojProj
= ProjectEditor
.ProjectDocument()
2380 unprojProj
.SetFilename(_("Not in any Project"))
2381 unprojProj
.AddFiles(unprojectedFiles
)
2382 docList
.append(unprojProj
)
2383 nameList
.append(_("Not in any Project"))
2385 return nameList
, docList
, index
2388 #----------------------------------------------------------------------
2389 from wx
import ImageFromStream
, BitmapFromImage
2392 #----------------------------------------------------------------------
2395 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x02\
2396 \x00\x00\x00\x90\x91h6\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\
2397 \x00\x85IDAT(\x91\xbd\x92A\x16\x03!\x08CI\xdf\xdc\x0b\x8e\xe6\xd1\xe0d\xe9\
2398 \x82\xd6\xc7(\x9di7\xfd\xab<\x14\x13Q\xb8\xbb\xfc\xc2\xe3\xd3\x82\x99\xb9\
2399 \xe9\xaeq\xe1`f)HF\xc4\x8dC2\x06\xbf\x8a4\xcf\x1e\x03K\xe5h\x1bH\x02\x98\xc7\
2400 \x03\x98\xa9z\x07\x00%\xd6\xa9\xd27\x90\xac\xbbk\xe5\x15I\xcdD$\xdc\xa7\xceT\
2401 5a\xce\xf3\xe4\xa0\xaa\x8bO\x12\x11\xabC\xcb\x9c}\xd57\xef\xb0\xf3\xb7\x86p\
2402 \x97\xf7\xb5\xaa\xde\xb9\xfa|-O\xbdjN\x9b\xf8\x06A\xcb\x00\x00\x00\x00IEND\
2405 def getBreakBitmap():
2406 return BitmapFromImage(getBreakImage())
2408 def getBreakImage():
2409 stream
= cStringIO
.StringIO(getBreakData())
2410 return ImageFromStream(stream
)
2413 return wx
.IconFromBitmap(getBreakBitmap())
2415 #----------------------------------------------------------------------
2417 def getClearOutputData():
2419 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2420 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2421 \x00\x00\xb7IDAT8\x8d\xa5\x93\xdd\x11\xc3 \x0c\x83%`\xa3\xee\xd4\xaeA\xc6\
2422 \xe8N\xedF%\xea\x03\t\x81\xf0\x97\xbb\xf8%G\xce\xfe\x90eC\x1a\x8b;\xe1\xf2\
2423 \x83\xd6\xa0Q2\x8de\xf5oW\xa05H\xea\xd7\x93\x84$\x18\xeb\n\x88;\'.\xd5\x1d\
2424 \x80\x07\xe1\xa1\x1d\xa2\x1cbF\x92\x0f\x80\xe0\xd1 \xb7\x14\x8c \x00*\x15\
2425 \x97\x14\x8c\x8246\x1a\xf8\x98\'/\xdf\xd8Jn\xe65\xc0\xa7\x90_L"\x01\xde\x9d\
2426 \xda\xa7\x92\xfb\xc5w\xdf\t\x07\xc4\x05ym{\xd0\x1a\xe3\xb9xS\x81\x04\x18\x05\
2427 \xc9\x04\xc9a\x00Dc9\x9d\x82\xa4\xbc\xe8P\xb2\xb5P\xac\xf2\x0c\xd4\xf5\x00\
2428 \x88>\xac\xe17\x84\xe4\xb9G\x8b7\x9f\xf3\x1fsUl^\x7f\xe7y\x0f\x00\x00\x00\
2431 def getClearOutputBitmap():
2432 return BitmapFromImage(getClearOutputImage())
2434 def getClearOutputImage():
2435 stream
= cStringIO
.StringIO(getClearOutputData())
2436 return ImageFromStream(stream
)
2438 def getClearOutputIcon():
2439 return wx
.IconFromBitmap(getClearOutputBitmap())
2441 #----------------------------------------------------------------------
2444 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x02\
2445 \x00\x00\x00\x90\x91h6\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\
2446 \x00\xedIDAT(\x91\xa5\x90!\xae\x840\x10\x86g_\xd6"*kz\x82j\xb0h\x1c\t\' x\
2447 \x92Z\xc2\x05\x10\x95\x18\x0e\x00\x02M\x82 \xe1\nMF#jz\x80\xea&+\x9a\x10\x96\
2448 \xdd}\xfb\xc8\x1b\xd7?\xdf\x97\xfe3\xb7u]\xe1\xca\xfc\\\xa2\xff- \xe24M\xc7\
2449 \xc49wJ\xee\xc7G]\xd7\x8c1\xc6\x18\xe7\xdc\'B\x08k\xed1y\xfaa\x1cG\xad\xb5\
2450 \x94\x12\x11\x9dsy\x9e+\xa5\x84\x10;\r\x00\xb7\xd3\x95\x8c1UU\x05A\x00\x00\
2451 \xd6\xda,\xcb\x92$\xf9\xb8\x03\x00PJ\x85\x10Zk\xa5\xd4+\xfdF\x00\x80\xae\xeb\
2452 \x08!\x84\x90y\x9e\x11\xf1\x8bP\x96\xa5\xef\xdd\xb6\xad\xb5VJ\xf9\x9b\xe0\
2453 \xe9\xa6i8\xe7\xbe\xdb\xb6mi\x9a\x0e\xc3\xf0F\x88\xe3\x18\x00\xfa\xbe\x0f\
2454 \xc3\xd0\'\x9c\xf3eY\xa2(*\x8ab\xc7\x9e\xaed\x8c\xa1\x94\xben\xf5\xb1\xd2W\
2455 \xfa,\xfce.\x0b\x0f\xb8\x96e\x90gS\xe0v\x00\x00\x00\x00IEND\xaeB`\x82'
2457 def getCloseBitmap():
2458 return BitmapFromImage(getCloseImage())
2460 def getCloseImage():
2461 stream
= cStringIO
.StringIO(getCloseData())
2462 return ImageFromStream(stream
)
2465 return wx
.IconFromBitmap(getCloseBitmap())
2467 #----------------------------------------------------------------------
2468 def getContinueData():
2470 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2471 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2472 \x00\x00\xcdIDAT8\x8d\xa5\x93\xd1\r\xc20\x0cD\xef\xec,\xc0b\x88\x8d`$\x06Cb\
2473 \x81\xc6\xc7GI\xeb\x94RZq?U"\xdby\xe7SIs\xfc#\xfbU\xa0\xa8\xba\xc6\xa0og\xee\
2474 !P\xd4y\x80\x04\xf3\xc2U\x82{\x9ct\x8f\x93\xb0\xa2\xdbm\xf5\xba\'h\xcdg=`\
2475 \xeeTT\xd1\xc6o& \t\x9a\x13\x00J\x9ev\xb1\'\xa3~\x14+\xbfN\x12\x92\x00@\xe6\
2476 \x85\xdd\x00\x000w\xe6\xe2\xde\xc7|\xdf\x08\xba\x1d(\xaa2n+\xca\xcd\x8d,\xea\
2477 \x98\xc4\x07\x01\x00D\x1dd^\xa8\xa8j\x9ew\xed`\xa9\x16\x99\xde\xa6G\x8b\xd3Y\
2478 \xe6\x85]\n\r\x7f\x99\xf5\x96Jnlz#\xab\xdb\xc1\x17\x19\xb0XV\xc2\xdf\xa3)\
2479 \x85<\xe4\x88\x85.F\x9a\xf3H3\xb0\xf3g\xda\xd2\x0b\xc5_|\x17\xe8\xf5R\xd6\
2480 \x00\x00\x00\x00IEND\xaeB`\x82'
2482 def getContinueBitmap():
2483 return BitmapFromImage(getContinueImage())
2485 def getContinueImage():
2486 stream
= cStringIO
.StringIO(getContinueData())
2487 return ImageFromStream(stream
)
2489 def getContinueIcon():
2490 return wx
.IconFromBitmap(getContinueBitmap())
2492 #----------------------------------------------------------------------
2495 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2496 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2497 \x00\x00\x8eIDAT8\x8d\xa5SA\x12\xc4 \x08K\xb0\xff\xde\xe9\xbf\xb7\xa6\x87\
2498 \x1d:\xba\xa2tZn(\x84`"i\x05obk\x13\xd5CmN+\xcc\x00l\xd6\x0c\x00\xf5\xf8\x0e\
2499 gK\x06\x00 \xa5=k\x00\x00\xb0\xb2]\xd4?5f\xb1\xdb\xaf\xc6\xa2\xcb\xa8\xf0?\
2500 \x1c\x98\xae\x82\xbf\x81\xa4\x8eA\x16\xe1\n\xd1\xa4\x19\xb3\xe9\n\xce\xe8\
2501 \xf1\n\x9eg^\x18\x18\x90\xec<\x11\xf9#\x04XMZ\x19\xaac@+\x94\xd4\x99)SeP\xa1\
2502 )\xd6\x1dI\xe7*\xdc\xf4\x03\xdf~\xe7\x13T^Q?:X\x19d\x00\x00\x00\x00IEND\xaeB\
2505 def getNextBitmap():
2506 return BitmapFromImage(getNextImage())
2509 stream
= cStringIO
.StringIO(getNextData())
2510 return ImageFromStream(stream
)
2513 return wx
.IconFromBitmap(getNextBitmap())
2515 #----------------------------------------------------------------------
2516 def getStepInData():
2518 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2519 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2520 \x00\x00\x87IDAT8\x8d\xadSA\x12\x84 \x0ck\x8a\xffv\xfc\xb74{X\xeb0P@\x07s\
2521 \x84\xa4$\x01\x00M\xb2\x02]R\x8b\xc86\xda\xdc\xedd\xb4~\xe8\x86\xc6\x01-\x93\
2522 \x96\xd9#\xf6\x06\xc3;p1I\xd1\x14\x0b#|\x17aF\xec\r\xeeF\xa0eB\xd34\xca\xd0A\
2523 ]j\x84\xa6\x03\x00""\xb7\xb0tRZ\xf7x\xb7\x83\x91]\xcb\x7fa\xd9\x89\x0fC\xfd\
2524 \x94\x9d|9\x99^k\x13\xa1 \xb3\x16\x0f#\xd4\x88N~\x14\xe1-\x96\x7f\xe3\x0f\
2525 \x11\x91UC\x0cX\'\x1e\x00\x00\x00\x00IEND\xaeB`\x82'
2527 def getStepInBitmap():
2528 return BitmapFromImage(getStepInImage())
2530 def getStepInImage():
2531 stream
= cStringIO
.StringIO(getStepInData())
2532 return ImageFromStream(stream
)
2534 def getStepInIcon():
2535 return wx
.IconFromBitmap(getStepInBitmap())
2537 #----------------------------------------------------------------------
2540 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2541 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2542 \x00\x00QIDAT8\x8d\xdd\x93A\n\xc00\x08\x04g\xb5\xff\x7fq\x13sn\xda&\x01\x0b\
2543 \xa5]\xf0"\xec(.J\xe6dd)\xf7\x13\x80\xadoD-12\xc8\\\xd3\r\xe2\xa6\x00j\xd9\
2544 \x0f\x03\xde\xbf\xc1\x0f\x00\xa7\x18\x01t\xd5\\\x05\xc8\\}T#\xe9\xfb\xbf\x90\
2545 \x064\xd8\\\x12\x1fQM\xf5\xd9\x00\x00\x00\x00IEND\xaeB`\x82'
2547 def getStopBitmap():
2548 return BitmapFromImage(getStopImage())
2551 stream
= cStringIO
.StringIO(getStopData())
2552 return ImageFromStream(stream
)
2555 return wx
.IconFromBitmap(getStopBitmap())
2557 #----------------------------------------------------------------------
2558 def getStepReturnData():
2560 "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2561 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2562 \x00\x00\x8dIDAT8\x8d\xa5S\xd1\x0e\xc4 \x08\xa3\xb0\xff\xbe\xdc\x7fO\xba'6\
2563 \xf1\xf44\xb3O$Phk\x04\xd4d\x07\xba\xc5\x16\x91#\nza\xdb\x84\x1a\xa2\xfe\xf8\
2564 \x99\xfa_=p+\xe8\x91ED\xbc<\xa4 \xb4\x0b\x01\xb5{\x01\xf9\xbbG-\x13\x87\x16f\
2565 \x84\xbf\x16V\xb0l\x01@\no\x86\xae\x82Q\xa8=\xa4\x0c\x80\xe70\xbd\x10jh\xbd\
2566 \x07R\x06#\xc9^N\xb6\xde\x03)\x83\x18\xaeU\x90\x9c>a\xb2P\r\xb3&/Y\xa8\xd1^^\
2567 \xb6\xf0\x16\xdb\xbf\xf1\x02\x81\xa5TK\x1d\x07\xde\x92\x00\x00\x00\x00IEND\
2570 def getStepReturnBitmap():
2571 return BitmapFromImage(getStepReturnImage())
2573 def getStepReturnImage():
2574 stream
= cStringIO
.StringIO(getStepReturnData())
2575 return ImageFromStream(stream
)
2577 def getStepReturnIcon():
2578 return wx
.IconFromBitmap(getStepReturnBitmap())
2580 #----------------------------------------------------------------------
2581 def getAddWatchData():
2583 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2584 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2585 \x00\x00\x85IDAT8\x8dc`\x18h\xc0\x88.\xd0\xc0\xf0\xff?*\x9f\x11C\rN\x80\xae\
2586 \x19\x97\x18\xd1\x9a\x896\x84\x18[p\xa9aA\xe6\xfc7f\xc0P\xc4x\x163\x9cp\x1a0\
2587 \xeb,!w\x100 \x1dK\xac\x10\r\x08\x05".yFL\x85\x8c\x18b\xa8|Ty\xa2\x13\x92\'\
2588 \xc3\xe4\xff\x9f\x18\x1e3\xb82t\xa2\x88\x13\xedg.\x06aa&\x06VV\x7f\x86\xb9\
2589 \xcfU\x19\xbc\xb0\xba\x86h\xe0\xc8\xd0\xfc\xbf\x80\xe1>q)\x94\xe6\x00\x00\
2590 \x85\x923_\xd22\xa4\xcd\x00\x00\x00\x00IEND\xaeB`\x82'
2592 def getAddWatchBitmap():
2593 return BitmapFromImage(getAddWatchImage())
2595 def getAddWatchImage():
2596 stream
= cStringIO
.StringIO(getAddWatchData())
2597 return ImageFromStream(stream
)
2599 def getAddWatchIcon():
2600 return wx
.IconFromBitmap(getAddWatchBitmap())
2602 #----------------------------------------------------------------------
2603 def getRunningManData():
2605 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2606 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2607 \x00\x01\x86IDAT8\x8d\xa5\x93\xb1K\x02Q\x1c\xc7\xbf\xcf\x9a\x1bZl\x88\xb4\
2608 \x04\x83\x10\xa2\x96\xc0A\xa8\x96\x96\xf4h\xe9\xf0\x1f\xd0\xcd(Bpi\x13nH\xb2\
2609 %\x9d\x1a"\xb9)\xb4\x16i\x10\n\x13MA\x84\xa3&\xa1\xa1A\xa1E\xbdw\x97\xa2\xbd\
2610 \x06\xf1(\xef,\xac\xef\xf6x\xdf\xf7}\x9f\xdf\x97\xf7\x081M\xe0?\x9a\xfc\xcd \
2611 \\\xdc2\x99\xb6A[\x14\x91C\x9e\x8c\x1d\x00\x00\xd5\xa7*\x9a\x8a\xfa7\x82u\
2612 \xfb\x14dj\x03mQ\xc3}\xf2\xb5\x83\xc7B\x9e\x89\xf7/\xda\xba\xd1\x94\x01\x00j\
2613 CF\xe2t\xef\x1b>\x1f\x8c3Q\xf0\x11\xd3p\xa2yf\x1a\xbc\xcb\n\xdee\x85\xdd>\
2614 \x07\xb5!C\xe9\xb4\xb1\xe9=b\x03\x8fc\xc3\xcf\xbcN\xb3\x9e`@\x11\xb9\xaa`\
2615 \x7fg\x19\'\x97y\xd8\x96\xfa\xf8\x95\xf23d\xa5O4\xbfh\x87(\xf8\x88a\xc0 $|~\
2616 \x87n\xf7\x03\xaa\xf2\x8e\xc0\xee\n\x00 \x91\xab\xc3\xeb4\xc3\xed\xe1\xb4qF\
2617 \x96\xb8`\xb3h\xb7\xa6Jo\xa0\x9d\x1eD\xc1G\xc4!\x9f\xae\x03\x00\xa8\xd5jh4e\
2618 \r\xb9\xf0P\x82T,\x83\xf3\x0bl\xd8k\x18\xe0\xf6p\x84vz\xa0M\x8aB\xf2\x98\x84\
2619 \x03[\xb0.XP\xcafu^m\x04>\x18\xd7\x9aM\xe4\xea\xba\xc0x\xec\x8c\xa9\xca*^\
2620 \xa5\x1b}\xc0u*\xc9B\xd14\x12\xe8\x97%\x15\xcbF`\xdaH\xba\x80P4\r)\x13#R\xc6\
2621 \xf0\xdc\x8f2\x01\x80\x94\x89\xe9>\xc9(\xcd:\xb6\xd9\x1aw\xa0\x95i\xf8\x0e\
2622 \xc6\xd1\'\'\x86\xa2\xd5\x8d \xbe@\x00\x00\x00\x00IEND\xaeB`\x82'
2624 def getRunningManBitmap():
2625 return BitmapFromImage(getRunningManImage())
2627 def getRunningManImage():
2628 stream
= cStringIO
.StringIO(getRunningManData())
2629 return ImageFromStream(stream
)
2631 def getRunningManIcon():
2633 icon
.CopyFromBitmap(getRunningManBitmap())
2636 #----------------------------------------------------------------------
2637 def getDebuggingManData():
2639 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2640 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2641 \x00\x01\xafIDAT8\x8d\x8d\x93\xbfK[Q\x14\xc7?7\n:\t\xb5SA\xc1?@\xc1A\x9c,%\
2642 \xd0\xa9\x83\xb5\x98!(b\t\xbc\xa7q("m\x1c\n5V]D\xd4-\xf8\x83\xa7\xa2\t\xa1\
2643 \xa6\xed$8\x08\x92\xa1\x8b\x14A\xd0YB"\xa4\xf4\x87\x90\x97K\xa8\xcb\xed\xf0\
2644 \xc8m\xae\xfa\xd4\x03\x07.\xe7\x9e\xf3\xfd\x9e\x9f\x88@\x1d\xb5\xba\x94\xca\
2645 \xaa\xeb\xb6\xbb4\xc0\x03d&\xb1\xa7\xfc\xfe\x0c\x80L\xdaQ\xd2\xad\x90I;F\x80\
2646 ++\xbe\xe0bve\xdf\xd7y\xfemH\xc4\x162\xaa\xbb\xa5D(\x1c\x11\xb7\x02\x88@\x9d\
2647 f?*4\xd1\xf6\xa2\x0f\x80\x93\xf4\x8e\xe1\xb8\xf2\xf1\xb5\x18\x9cH(\x80\xe4bT\
2648 \x83\xd5W\x1f\xa1pD\x8c|\xd8T\x00\xdf\xd6\xd7\xe8\x1f\xb3tp\xf1\n^\xfe\xf8\
2649 \xa5^u7\x00P\x1eYP\xd2\x95\x1c\xa4\xa6\x84\x18\x8do\xab*C&\xed\xa8\xafG\x7f\
2650 \xe9\x1f\xb3x\xdc\x08\xad\x8f \x7f\tg%\xf8Y\x82\xe3\x8de\x86\x82\xcdF9\xba\
2651 \x84\xc1\x89\x84*K\t\xc0\xf0\xbbq:\x9f\xfcO\x7f?\xe7\x01\x9c\xff\x86Br\x8e\
2652 \x83\xd4\x94\x06\xd0SH.F\xc5P\xb0\x19\xe9z \xf9KOmkN\x07\x03\x14/r\xb4?\x8b\
2653 \xe8\xc6\xeb\x1e\x00l\x1f\xfe\xd15\x17\xaf<\xdb\xd37\xef\xd9\x9d\xb4\xe9\x8a\
2654 \xadj\xbfx\xb4\x878(#\x03\x00\xe9JF{[\xf92\xeb\xb1V\x99\xbbb\xab|\x9f\xb7\
2655 \x8d\xa9\x9cf\x1dq\x9au\xc4\x8dM\x0c\x85#\xa2x\x91cw\xd2\xd6i\x83\trk\x13\
2656 \x9f\x0fL\xab\xda\xe6\xd4\xd6Y+\xf1h\x8f\xb9T~G\xd2\x11\xb4\xd4\xe7O[\xf7\
2657 \x1e\xd6\x9d\xc7\xe4\xb7\xbe\x86\xf8\xb1?\xf4\x9c\xff\x01\xbe\xe9\xaf\x96\
2658 \xf0\x7fPA\x00\x00\x00\x00IEND\xaeB`\x82'
2660 def getDebuggingManBitmap():
2661 return BitmapFromImage(getDebuggingManImage())
2663 def getDebuggingManImage():
2664 stream
= cStringIO
.StringIO(getDebuggingManData())
2665 return ImageFromStream(stream
)
2667 def getDebuggingManIcon():
2669 icon
.CopyFromBitmap(getDebuggingManBitmap())
2672 #----------------------------------------------------------------------