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 #------------------------------------------------------------------------------
316 #-----------------------------------------------------------------------------
318 def OnToolClicked(self
, event
):
321 if id == self
.KILL_PROCESS_ID
:
324 elif id == self
.CLOSE_TAB_ID
:
326 index
= self
._noteBook
.GetSelection()
327 self
._noteBook
.GetPage(index
).Show(False)
328 self
._noteBook
.RemovePage(index
)
330 def OnDoubleClick(self
, event
):
331 # Looking for a stack trace line.
332 lineText
, pos
= self
._textCtrl
.GetCurLine()
333 fileBegin
= lineText
.find("File \"")
334 fileEnd
= lineText
.find("\", line ")
335 lineEnd
= lineText
.find(", in ")
336 if lineText
== "\n" or fileBegin
== -1 or fileEnd
== -1 or lineEnd
== -1:
337 # Check the line before the one that was clicked on
338 lineNumber
= self
._textCtrl
.GetCurrentLine()
341 lineText
= self
._textCtrl
.GetLine(lineNumber
- 1)
342 fileBegin
= lineText
.find("File \"")
343 fileEnd
= lineText
.find("\", line ")
344 lineEnd
= lineText
.find(", in ")
345 if lineText
== "\n" or fileBegin
== -1 or fileEnd
== -1 or lineEnd
== -1:
348 filename
= lineText
[fileBegin
+ 6:fileEnd
]
349 lineNum
= int(lineText
[fileEnd
+ 8:lineEnd
])
352 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
353 for openDoc
in openDocs
:
354 if openDoc
.GetFilename() == filename
:
355 foundView
= openDoc
.GetFirstView()
359 doc
= wx
.GetApp().GetDocumentManager().CreateDocument(filename
, wx
.lib
.docview
.DOC_SILENT
)
360 foundView
= doc
.GetFirstView()
363 foundView
.GetFrame().SetFocus()
365 foundView
.GotoLine(lineNum
)
366 startPos
= foundView
.PositionFromLine(lineNum
)
368 # FACTOR THIS INTO DocManager
369 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
370 for openDoc
in openDocs
:
371 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
372 openDoc
.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
374 foundView
.GetCtrl().MarkerAdd(lineNum
-1, CodeEditor
.CodeCtrl
.CURRENT_LINE_MARKER_NUM
)
378 DEFAULT_HOST
= 'localhost'
381 class DebugCommandUI(wx
.Panel
):
382 debuggerPortList
= None
385 def NotifyDebuggersOfBreakpointChange():
386 for debugger
in DebugCommandUI
.debuggers
:
387 debugger
.BreakPointChange()
389 NotifyDebuggersOfBreakpointChange
= staticmethod(NotifyDebuggersOfBreakpointChange
)
391 def DebuggerRunning():
392 for debugger
in DebugCommandUI
.debuggers
:
393 if debugger
._executor
:
396 DebuggerRunning
= staticmethod(DebuggerRunning
)
398 def ShutdownAllDebuggers():
399 # See comment on DebugCommandUI.StopExecution
400 for debugger
in DebugCommandUI
.debuggers
:
402 debugger
.StopExecution(None)
403 except wx
._core
.PyDeadObjectError
:
405 DebugCommandUI
.debuggers
= []
406 ShutdownAllDebuggers
= staticmethod(ShutdownAllDebuggers
)
408 def GetAvailablePort():
409 for index
in range( 0, len(DebugCommandUI
.debuggerPortList
)):
410 port
= DebugCommandUI
.debuggerPortList
[index
]
411 if DebugCommandUI
.PortAvailable(port
):
412 DebugCommandUI
.debuggerPortList
.pop(index
)
414 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"))
415 assert False, "Out of ports for debugger."
417 GetAvailablePort
= staticmethod(GetAvailablePort
)
419 def ReturnPortToPool(port
):
420 config
= wx
.ConfigBase_Get()
421 startingPort
= config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
)
422 if port
in range(startingPort
, startingPort
+ PORT_COUNT
):
423 DebugCommandUI
.debuggerPortList
.append(port
)
425 ReturnPortToPool
= staticmethod(ReturnPortToPool
)
427 def PortAvailable(port
):
428 config
= wx
.ConfigBase_Get()
429 hostname
= config
.Read("DebuggerHostName", DEFAULT_HOST
)
431 server
= AGXMLRPCServer((hostname
, port
))
432 server
.server_close()
433 if _VERBOSE
: print "Port ", str(port
), " available."
436 tp
,val
,tb
= sys
.exc_info()
437 if _VERBOSE
: traceback
.print_exception(tp
, val
, tb
)
438 if _VERBOSE
: print "Port ", str(port
), " unavailable."
441 PortAvailable
= staticmethod(PortAvailable
)
444 config
= wx
.ConfigBase_Get()
445 startingPort
= config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
)
446 DebugCommandUI
.debuggerPortList
= range(startingPort
, startingPort
+ PORT_COUNT
)
447 NewPortRange
= staticmethod(NewPortRange
)
449 def __init__(self
, parent
, id, command
, service
):
450 # Check for ports before creating the panel.
451 if not DebugCommandUI
.debuggerPortList
:
452 DebugCommandUI
.NewPortRange()
453 self
._debuggerPort
= str(DebugCommandUI
.GetAvailablePort())
454 self
._guiPort
= str(DebugCommandUI
.GetAvailablePort())
455 self
._debuggerBreakPort
= str(DebugCommandUI
.GetAvailablePort())
457 wx
.Panel
.__init
__(self
, parent
, id)
459 self
._parentNoteBook
= parent
460 self
._command
= command
461 self
._service
= service
462 self
._executor
= None
463 self
.STEP_ID
= wx
.NewId()
464 self
.CONTINUE_ID
= wx
.NewId()
465 self
.STEP_OUT_ID
= wx
.NewId()
466 self
.NEXT_ID
= wx
.NewId()
467 self
.KILL_PROCESS_ID
= wx
.NewId()
468 self
.CLOSE_WINDOW_ID
= wx
.NewId()
469 self
.BREAK_INTO_DEBUGGER_ID
= wx
.NewId()
470 self
.CLEAR_ID
= wx
.NewId()
471 self
.ADD_WATCH_ID
= wx
.NewId()
472 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
473 self
._tb
= tb
= wx
.ToolBar(self
, -1, wx
.DefaultPosition
, (1000,30), wx
.TB_HORIZONTAL| wx
.NO_BORDER| wx
.TB_FLAT| wx
.TB_TEXT
, "Debugger" )
474 sizer
.Add(tb
, 0, wx
.EXPAND |wx
.ALIGN_LEFT|wx
.ALL
, 1)
475 tb
.SetToolBitmapSize((16,16))
477 close_bmp
= getCloseBitmap()
478 tb
.AddSimpleTool( self
.CLOSE_WINDOW_ID
, close_bmp
, _('Close Window'))
479 wx
.EVT_TOOL(self
, self
.CLOSE_WINDOW_ID
, self
.StopAndRemoveUI
)
481 stop_bmp
= getStopBitmap()
482 tb
.AddSimpleTool( self
.KILL_PROCESS_ID
, stop_bmp
, _("Stop Debugging"))
483 wx
.EVT_TOOL(self
, self
.KILL_PROCESS_ID
, self
.StopExecution
)
487 break_bmp
= getBreakBitmap()
488 tb
.AddSimpleTool( self
.BREAK_INTO_DEBUGGER_ID
, break_bmp
, _("Break into Debugger"))
489 wx
.EVT_TOOL(self
, self
.BREAK_INTO_DEBUGGER_ID
, self
.BreakExecution
)
493 continue_bmp
= getContinueBitmap()
494 tb
.AddSimpleTool( self
.CONTINUE_ID
, continue_bmp
, _("Continue Execution"))
495 wx
.EVT_TOOL(self
, self
.CONTINUE_ID
, self
.OnContinue
)
499 next_bmp
= getNextBitmap()
500 tb
.AddSimpleTool( self
.NEXT_ID
, next_bmp
, _("Step to next line"))
501 wx
.EVT_TOOL(self
, self
.NEXT_ID
, self
.OnNext
)
503 step_bmp
= getStepInBitmap()
504 tb
.AddSimpleTool( self
.STEP_ID
, step_bmp
, _("Step in"))
505 wx
.EVT_TOOL(self
, self
.STEP_ID
, self
.OnSingleStep
)
507 stepOut_bmp
= getStepReturnBitmap()
508 tb
.AddSimpleTool(self
.STEP_OUT_ID
, stepOut_bmp
, _("Stop at function return"))
509 wx
.EVT_TOOL(self
, self
.STEP_OUT_ID
, self
.OnStepOut
)
513 watch_bmp
= getAddWatchBitmap()
514 tb
.AddSimpleTool(self
.ADD_WATCH_ID
, watch_bmp
, _("Add a watch"))
515 wx
.EVT_TOOL(self
, self
.ADD_WATCH_ID
, self
.OnAddWatch
)
518 clear_bmp
= getClearOutputBitmap()
519 tb
.AddSimpleTool(self
.CLEAR_ID
, clear_bmp
, _("Clear output pane"))
520 wx
.EVT_TOOL(self
, self
.CLEAR_ID
, self
.OnClearOutput
)
522 self
.framesTab
= None
523 self
.DisableWhileDebuggerRunning()
524 self
.framesTab
= self
.MakeFramesUI(self
, wx
.NewId(), None)
525 sizer
.Add(self
.framesTab
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
526 self
._statusBar
= wx
.StatusBar( self
, -1)
527 self
._statusBar
.SetFieldsCount(1)
528 sizer
.Add(self
._statusBar
, 0, wx
.EXPAND |wx
.ALIGN_LEFT|wx
.ALL
, 1)
530 self
.SetStatusText("Starting debug...")
535 config
= wx
.ConfigBase_Get()
536 self
._debuggerHost
= self
._guiHost
= config
.Read("DebuggerHostName", DEFAULT_HOST
)
537 url
= 'http://' + self
._debuggerHost
+ ':' + self
._debuggerPort
+ '/'
538 self
._breakURL
= 'http://' + self
._debuggerHost
+ ':' + self
._debuggerBreakPort
+ '/'
539 self
._callback
= DebuggerCallback(self
._guiHost
, self
._guiPort
, url
, self
._breakURL
, self
)
540 if DebuggerHarness
.__file
__.find('library.zip') > 0:
542 fname
= DebuggerHarness
.__file
__
543 parts
= fname
.split('library.zip')
544 path
= os
.path
.join(parts
[0],'activegrid', 'tool', 'DebuggerHarness.py')
546 tp
, val
, tb
= sys
.exc_info()
547 traceback
.print_exception(tp
, val
, tb
)
550 print "Starting debugger on these ports: %s, %s, %s" % (str(self
._debuggerPort
) , str(self
._guiPort
) , str(self
._debuggerBreakPort
))
551 path
= DebuggerService
.ExpandPath(DebuggerHarness
.__file
__)
552 self
._executor
= Executor(path
, self
, self
._debuggerHost
, \
553 self
._debuggerPort
, self
._debuggerBreakPort
, self
._guiHost
, self
._guiPort
, self
._command
, callbackOnExit
=self
.ExecutorFinished
)
555 self
.Bind(EVT_UPDATE_STDTEXT
, self
.AppendText
)
556 self
.Bind(EVT_UPDATE_ERRTEXT
, self
.AppendErrorText
)
557 DebugCommandUI
.debuggers
.append(self
)
558 self
._stopped
= False
560 def OnSingleStep(self
, event
):
561 self
._callback
.SingleStep()
563 def OnContinue(self
, event
):
564 self
._callback
.Continue()
566 def OnStepOut(self
, event
):
567 self
._callback
.Return()
569 def OnNext(self
, event
):
570 self
._callback
.Next()
572 def BreakPointChange(self
):
573 if not self
._stopped
:
574 self
._callback
.pushBreakpoints()
575 self
.framesTab
.PopulateBPList()
578 # See comment on DebugCommandUI.StopExecution
579 self
.StopExecution(None)
581 def DisableWhileDebuggerRunning(self
):
582 self
._tb
.EnableTool(self
.STEP_ID
, False)
583 self
._tb
.EnableTool(self
.CONTINUE_ID
, False)
584 self
._tb
.EnableTool(self
.STEP_OUT_ID
, False)
585 self
._tb
.EnableTool(self
.NEXT_ID
, False)
586 self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, True)
588 self
._tb
.EnableTool(self
.ADD_WATCH_ID
, False)
589 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
590 for openDoc
in openDocs
:
591 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
592 openDoc
.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
594 self
.framesTab
.ClearWhileRunning()
596 def EnableWhileDebuggerStopped(self
):
597 self
._tb
.EnableTool(self
.STEP_ID
, True)
598 self
._tb
.EnableTool(self
.CONTINUE_ID
, True)
599 self
._tb
.EnableTool(self
.STEP_OUT_ID
, True)
600 self
._tb
.EnableTool(self
.NEXT_ID
, True)
602 self
._tb
.EnableTool(self
.ADD_WATCH_ID
, True)
603 self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, False)
605 def ExecutorFinished(self
):
606 if _VERBOSE
: print "In ExectorFinished"
608 self
.DisableAfterStop()
609 except wx
._core
.PyDeadObjectError
:
612 nb
= self
.GetParent()
613 for i
in range(0, nb
.GetPageCount()):
614 if self
== nb
.GetPage(i
):
615 text
= nb
.GetPageText(i
)
616 newText
= text
.replace("Debugging", "Finished")
617 nb
.SetPageText(i
, newText
)
618 if _VERBOSE
: print "In ExectorFinished, changed tab title."
621 if _VERBOSE
: print "In ExectorFinished, got exception"
623 def DisableAfterStop(self
):
624 self
.DisableWhileDebuggerRunning()
625 self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, False)
626 self
._tb
.EnableTool(self
.KILL_PROCESS_ID
, False)
628 def SynchCurrentLine(self
, filename
, lineNum
, noArrow
=False):
629 # FACTOR THIS INTO DocManager
630 self
.DeleteCurrentLineMarkers()
632 # Filename will be <string> if we're in a bit of code that was executed from
633 # a string (rather than a file). I haven't been able to get the original string
635 if filename
== '<string>':
638 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
639 for openDoc
in openDocs
:
640 # This ugliness to prevent comparison failing because the drive letter
641 # gets lowercased occasionally. Don't know why that happens or why it
642 # only happens occasionally.
643 if DebuggerService
.ComparePaths(openDoc
.GetFilename(),filename
):
644 foundView
= openDoc
.GetFirstView()
649 print "filename=", filename
650 doc
= wx
.GetApp().GetDocumentManager().CreateDocument(DebuggerService
.ExpandPath(filename
), wx
.lib
.docview
.DOC_SILENT
)
651 foundView
= doc
.GetFirstView()
654 foundView
.GetFrame().SetFocus()
656 foundView
.GotoLine(lineNum
)
657 startPos
= foundView
.PositionFromLine(lineNum
)
660 foundView
.GetCtrl().MarkerAdd(lineNum
-1, CodeEditor
.CodeCtrl
.CURRENT_LINE_MARKER_NUM
)
662 def DeleteCurrentLineMarkers(self
):
663 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
664 for openDoc
in openDocs
:
665 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
666 openDoc
.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
668 def LoadFramesListXML(self
, framesXML
):
669 self
.framesTab
.LoadFramesListXML(framesXML
)
671 def SetStatusText(self
, text
):
672 self
._statusBar
.SetStatusText(text
,0)
674 def Execute(self
, initialArgs
, startIn
, environment
):
675 self
._callback
.start()
676 self
._executor
.Execute(initialArgs
, startIn
, environment
)
677 self
._callback
.waitForRPC()
679 def BreakExecution(self
, event
):
680 self
._callback
.BreakExecution()
683 def StopExecution(self
, event
):
684 # This is a general comment on shutdown for the running and debugged processes. Basically, the
685 # current state of this is the result of trial and error coding. The common problems were memory
686 # access violations and threads that would not exit. Making the OutputReaderThreads daemons seems
687 # to have side-stepped the hung thread issue. Being very careful not to touch things after calling
688 # process.py:ProcessOpen.kill() also seems to have fixed the memory access violations, but if there
689 # were more ugliness discovered I would not be surprised. If anyone has any help/advice, please send
690 # it on to mfryer@activegrid.com.
691 if not self
._stopped
:
694 self
.DisableAfterStop()
695 except wx
._core
.PyDeadObjectError
:
698 self
._callback
.ShutdownServer()
700 tp
,val
,tb
= sys
.exc_info()
701 traceback
.print_exception(tp
, val
, tb
)
704 self
.DeleteCurrentLineMarkers()
708 DebugCommandUI
.ReturnPortToPool(self
._debuggerPort
)
709 DebugCommandUI
.ReturnPortToPool(self
._guiPort
)
710 DebugCommandUI
.ReturnPortToPool(self
._debuggerBreakPort
)
715 self
._executor
.DoStopExecution()
716 self
._executor
= None
718 tp
,val
,tb
= sys
.exc_info()
719 traceback
.print_exception(tp
, val
, tb
)
720 def StopAndRemoveUI(self
, event
):
721 self
.StopExecution(None)
722 if self
in DebugCommandUI
.debuggers
:
723 DebugCommandUI
.debuggers
.remove(self
)
724 index
= self
._parentNoteBook
.GetSelection()
725 self
._parentNoteBook
.GetPage(index
).Show(False)
726 self
._parentNoteBook
.RemovePage(index
)
728 def OnAddWatch(self
, event
):
730 self
.framesTab
.OnWatch(event
)
732 def MakeFramesUI(self
, parent
, id, debugger
):
733 panel
= FramesUI(parent
, id, self
)
736 def AppendText(self
, event
):
737 self
.framesTab
.AppendText(event
.value
)
739 def AppendErrorText(self
, event
):
740 self
.framesTab
.AppendErrorText(event
.value
)
742 def OnClearOutput(self
, event
):
743 self
.framesTab
.ClearOutput(None)
745 def SwitchToOutputTab(self
):
746 self
.framesTab
.SwitchToOutputTab()
748 class BreakpointsUI(wx
.Panel
):
749 def __init__(self
, parent
, id, ui
):
750 wx
.Panel
.__init
__(self
, parent
, id)
752 self
.currentItem
= None
753 self
.clearBPID
= wx
.NewId()
754 self
.Bind(wx
.EVT_MENU
, self
.ClearBreakPoint
, id=self
.clearBPID
)
755 self
.syncLineID
= wx
.NewId()
756 self
.Bind(wx
.EVT_MENU
, self
.SyncBPLine
, id=self
.syncLineID
)
757 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
759 self
._bpListCtrl
= wx
.ListCtrl(p1
, -1, pos
=wx
.DefaultPosition
, size
=(1000,1000), style
=wx
.LC_REPORT
)
760 sizer
.Add(self
._bpListCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
761 self
._bpListCtrl
.InsertColumn(0, "File")
762 self
._bpListCtrl
.InsertColumn(1, "Line")
763 self
._bpListCtrl
.InsertColumn(2, "Path")
764 self
._bpListCtrl
.SetColumnWidth(0, 150)
765 self
._bpListCtrl
.SetColumnWidth(1, 50)
766 self
._bpListCtrl
.SetColumnWidth(2, 450)
767 self
._bpListCtrl
.Bind(wx
.EVT_LIST_ITEM_RIGHT_CLICK
, self
.OnListRightClick
)
768 self
.Bind(wx
.EVT_LIST_ITEM_SELECTED
, self
.ListItemSelected
, self
._bpListCtrl
)
769 self
.Bind(wx
.EVT_LIST_ITEM_DESELECTED
, self
.ListItemDeselected
, self
._bpListCtrl
)
771 def OnLeftDoubleClick(event
):
772 self
.SyncBPLine(event
)
774 wx
.EVT_LEFT_DCLICK(self
._bpListCtrl
, OnLeftDoubleClick
)
776 self
.PopulateBPList()
782 def PopulateBPList(self
):
783 list = self
._bpListCtrl
784 list.DeleteAllItems()
786 bps
= wx
.GetApp().GetService(DebuggerService
).GetMasterBreakpointDict()
788 for fileName
in bps
.keys():
789 shortFile
= os
.path
.basename(fileName
)
790 lines
= bps
[fileName
]
793 list.InsertStringItem(index
, shortFile
)
794 list.SetStringItem(index
, 1, str(line
))
795 list.SetStringItem(index
, 2, fileName
)
797 def OnListRightClick(self
, event
):
799 item
= wx
.MenuItem(menu
, self
.clearBPID
, "Clear Breakpoint")
800 menu
.AppendItem(item
)
801 item
= wx
.MenuItem(menu
, self
.syncLineID
, "Goto Source Line")
802 menu
.AppendItem(item
)
803 self
.PopupMenu(menu
, event
.GetPosition())
806 def SyncBPLine(self
, event
):
807 if self
.currentItem
!= -1:
808 list = self
._bpListCtrl
809 fileName
= list.GetItem(self
.currentItem
, 2).GetText()
810 lineNumber
= list.GetItem(self
.currentItem
, 1).GetText()
811 self
._ui
.SynchCurrentLine( fileName
, int(lineNumber
) , noArrow
=True)
813 def ClearBreakPoint(self
, event
):
814 if self
.currentItem
>= 0:
815 list = self
._bpListCtrl
816 fileName
= list.GetItem(self
.currentItem
, 2).GetText()
817 lineNumber
= list.GetItem(self
.currentItem
, 1).GetText()
818 wx
.GetApp().GetService(DebuggerService
).OnToggleBreakpoint(None, line
=int(lineNumber
) -1, fileName
=fileName
)
820 def ListItemSelected(self
, event
):
821 self
.currentItem
= event
.m_itemIndex
823 def ListItemDeselected(self
, event
):
824 self
.currentItem
= -1
832 def __init__(self
, name
, command
, show_code
=CODE_ALL_FRAMES
):
834 self
._command
= command
835 self
._show
_code
= show_code
837 class WatchDialog(wx
.Dialog
):
838 WATCH_ALL_FRAMES
= "Watch in all frames"
839 WATCH_THIS_FRAME
= "Watch in this frame only"
840 WATCH_ONCE
= "Watch once and delete"
841 def __init__(self
, parent
, title
, chain
):
842 wx
.Dialog
.__init
__(self
, parent
, -1, title
, style
=wx
.DEFAULT_DIALOG_STYLE
)
844 self
.label_2
= wx
.StaticText(self
, -1, "Watch Name:")
845 self
._watchNameTextCtrl
= wx
.TextCtrl(self
, -1, "")
846 self
.label_3
= wx
.StaticText(self
, -1, "eval(", style
=wx
.ALIGN_RIGHT
)
847 self
._watchValueTextCtrl
= wx
.TextCtrl(self
, -1, "")
848 self
.label_4
= wx
.StaticText(self
, -1, ",frame.f_globals, frame.f_locals)")
849 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
)
851 self
._okButton
= wx
.Button(self
, wx
.ID_OK
, "OK", size
=(75,-1))
852 self
._okButton
.SetDefault()
853 self
._okButton
.SetHelpText(_("The OK button completes the dialog"))
854 def OnOkClick(event
):
855 if self
._watchNameTextCtrl
.GetValue() == "":
856 wx
.MessageBox(_("You must enter a name for the watch."), _("Add Watch"))
858 if self
._watchValueTextCtrl
.GetValue() == "":
859 wx
.MessageBox(_("You must enter some code to run for the watch."), _("Add Watch"))
861 self
.EndModal(wx
.ID_OK
)
862 self
.Bind(wx
.EVT_BUTTON
, OnOkClick
, self
._okButton
)
864 self
._cancelButton
= wx
.Button(self
, wx
.ID_CANCEL
, _("Cancel"), size
=(75,-1))
865 self
._cancelButton
.SetHelpText(_("The Cancel button cancels the dialog."))
867 self
.__set
_properties
()
870 def GetSettings(self
):
871 return self
._watchNameTextCtrl
.GetValue(), self
._watchValueTextCtrl
.GetValue(), self
.GetSendFrame(), self
.GetRunOnce()
873 def GetSendFrame(self
):
874 return (WatchDialog
.WATCH_ALL_FRAMES
!= self
.radio_box_1
.GetStringSelection())
876 def GetRunOnce(self
):
877 return (WatchDialog
.WATCH_ONCE
== self
.radio_box_1
.GetStringSelection())
879 def __set_properties(self
):
880 self
.SetTitle("Add a Watch")
881 #self.SetSize((400, 250))
882 self
.radio_box_1
.SetSelection(0)
884 def __do_layout(self
):
885 sizer_1
= wx
.BoxSizer(wx
.VERTICAL
)
886 grid_sizer_4
= wx
.FlexGridSizer(1, 3, 5, 5)
887 grid_sizer_2
= wx
.FlexGridSizer(1, 2, 5, 5)
888 grid_sizer_2
.Add(self
.label_2
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0)
889 grid_sizer_2
.Add(self
._watchNameTextCtrl
, 0, wx
.EXPAND
, 0)
890 grid_sizer_2
.AddGrowableCol(1)
891 sizer_1
.Add(grid_sizer_2
, 1, wx
.EXPAND
, 0)
892 grid_sizer_4
.Add(self
.label_3
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0)
893 grid_sizer_4
.Add(self
._watchValueTextCtrl
, 0, wx
.EXPAND
, 0)
894 grid_sizer_4
.AddGrowableCol(1)
895 grid_sizer_4
.Add(self
.label_4
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0)
896 sizer_1
.Add(grid_sizer_4
, 0, wx
.EXPAND
, 0)
897 sizer_1
.Add(self
.radio_box_1
, 0, wx
.EXPAND
, 0)
899 box
= wx
.BoxSizer(wx
.HORIZONTAL
)
900 box
.Add(self
._okButton
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5)
901 box
.Add(self
._cancelButton
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5)
902 sizer_1
.Add(box
, 1, wx
.EXPAND
, 0)
903 self
.SetAutoLayout(True)
904 self
.SetSizer(sizer_1
)
907 class FramesUI(wx
.SplitterWindow
):
908 def __init__(self
, parent
, id, ui
):
909 wx
.SplitterWindow
.__init
__(self
, parent
, id, style
= wx
.SP_3D
)
911 self
._p
1 = p1
= wx
.ScrolledWindow(self
, -1)
913 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
914 framesLabel
= wx
.StaticText(self
, -1, "Stack Frame:")
915 sizer
.Add(framesLabel
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT|wx
.LEFT
, border
=2)
917 self
._framesChoiceCtrl
= wx
.Choice(p1
, -1, choices
=[" "])
918 sizer
.Add(self
._framesChoiceCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
919 self
._framesChoiceCtrl
.Bind(wx
.EVT_LIST_ITEM_RIGHT_CLICK
, self
.OnListRightClick
)
920 self
.Bind(wx
.EVT_CHOICE
, self
.ListItemSelected
, self
._framesChoiceCtrl
)
922 sizer2
= wx
.BoxSizer(wx
.VERTICAL
)
925 self
._treeCtrl
= wx
.gizmos
.TreeListCtrl(p1
, -1, style
=wx
.TR_DEFAULT_STYLE| wx
.TR_FULL_ROW_HIGHLIGHT
)
926 self
._treeCtrl
.Bind(wx
.EVT_TREE_ITEM_RIGHT_CLICK
, self
.OnRightClick
)
927 sizer2
.Add(sizer
, 0, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
928 sizer2
.Add(self
._treeCtrl
,1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
929 tree
= self
._treeCtrl
930 tree
.AddColumn("Thing")
931 tree
.AddColumn("Value")
932 tree
.SetMainColumn(0) # the one with the tree in it...
933 tree
.SetColumnWidth(0, 175)
934 tree
.SetColumnWidth(1, 355)
935 self
._root
= tree
.AddRoot("Frame")
936 tree
.SetItemText(self
._root
, "", 1)
937 tree
.Bind(wx
.EVT_TREE_ITEM_EXPANDING
, self
.IntrospectCallback
)
939 self
._p
2 = p2
= wx
.Window(self
, -1)
940 sizer3
= wx
.BoxSizer(wx
.HORIZONTAL
)
942 p2
.Bind(wx
.EVT_SIZE
, self
.OnSize
)
943 self
._notebook
= wx
.Notebook(p2
, -1, size
=(20,20))
944 self
._notebook
.Hide()
945 sizer3
.Add(self
._notebook
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
946 self
.consoleTab
= self
.MakeConsoleTab(self
._notebook
, wx
.NewId())
947 self
.inspectConsoleTab
= self
.MakeInspectConsoleTab(self
._notebook
, wx
.NewId())
948 self
.breakPointsTab
= self
.MakeBreakPointsTab(self
._notebook
, wx
.NewId())
949 self
._notebook
.AddPage(self
.consoleTab
, "Output")
950 self
._notebook
.AddPage(self
.inspectConsoleTab
, "Interact")
951 self
._notebook
.AddPage(self
.breakPointsTab
, "Break Points")
953 self
.SetMinimumPaneSize(20)
954 self
.SplitVertically(p1
, p2
, 550)
955 self
.currentItem
= None
956 self
._notebook
.Show(True)
958 def PopulateBPList(self
):
959 self
.breakPointsTab
.PopulateBPList()
961 def OnSize(self
, event
):
962 self
._notebook
.SetSize(self
._p
2.GetSize())
964 def MakeConsoleTab(self
, parent
, id):
965 panel
= wx
.Panel(parent
, id)
966 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
967 self
._textCtrl
= STCTextEditor
.TextCtrl(panel
, wx
.NewId())
968 sizer
.Add(self
._textCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 2)
969 self
._textCtrl
.SetViewLineNumbers(False)
970 self
._textCtrl
.SetReadOnly(True)
971 if wx
.Platform
== '__WXMSW__':
975 self
._textCtrl
.SetFont(wx
.Font(9, wx
.DEFAULT
, wx
.NORMAL
, wx
.NORMAL
, faceName
= font
))
976 self
._textCtrl
.SetFontColor(wx
.BLACK
)
977 self
._textCtrl
.StyleClearAll()
978 panel
.SetSizer(sizer
)
983 def MakeInspectConsoleTab(self
, parent
, id):
984 self
.command_list
= []
985 self
.command_index
= 0
986 def ExecuteCommand(command
):
987 if not len(self
.command_list
) or not command
== self
.command_list
[len(self
.command_list
) -1]:
988 self
.command_list
.append(command
)
989 self
.command_index
= len(self
.command_list
) - 1
990 retval
= self
._ui
._callback
._debuggerServer
.execute_in_frame(self
._framesChoiceCtrl
.GetStringSelection(), command
)
991 self
._interCtrl
.AddText("\n" + str(retval
))
992 self
._interCtrl
.ScrollToLine(self
._interCtrl
.GetLineCount())
993 # Refresh the tree view in case this command resulted in changes there. TODO: Need to reopen tree items.
994 self
.PopulateTreeFromFrameMessage(self
._framesChoiceCtrl
.GetStringSelection())
996 def ReplaceLastLine(command
):
997 line
= self
._interCtrl
.GetLineCount() - 1
998 self
._interCtrl
.GotoLine(line
)
999 start
= self
._interCtrl
.GetCurrentPos()
1000 self
._interCtrl
.SetTargetStart(start
)
1001 end
= self
._interCtrl
.GetLineEndPosition(line
)
1002 self
._interCtrl
.SetTargetEnd(end
)
1003 self
._interCtrl
.ReplaceTarget(">>> " + command
)
1004 self
._interCtrl
.GotoLine(line
)
1005 self
._interCtrl
.SetSelectionStart(self
._interCtrl
.GetLineEndPosition(line
))
1007 def OnKeyPressed(event
):
1008 key
= event
.KeyCode()
1009 if key
== wx
.WXK_DELETE
or key
== wx
.WXK_BACK
:
1010 if self
._interCtrl
.GetLine(self
._interCtrl
.GetCurrentLine()) == ">>> ":
1012 elif key
== wx
.WXK_RETURN
:
1013 command
= self
._interCtrl
.GetLine(self
._interCtrl
.GetCurrentLine())[4:]
1014 ExecuteCommand(command
)
1015 self
._interCtrl
.AddText("\n>>> ")
1017 elif key
== wx
.WXK_UP
:
1018 if not len(self
.command_list
):
1020 ReplaceLastLine(self
.command_list
[self
.command_index
])
1021 if self
.command_index
== 0:
1022 self
.command_index
= len(self
.command_list
) - 1
1024 self
.command_index
= self
.command_index
- 1
1026 elif key
== wx
.WXK_DOWN
:
1027 if not len(self
.command_list
):
1029 if self
.command_index
< len(self
.command_list
) - 1:
1030 self
.command_index
= self
.command_index
+ 1
1032 self
.command_index
= 0
1033 ReplaceLastLine(self
.command_list
[self
.command_index
])
1038 panel
= wx
.Panel(parent
, id)
1039 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
1040 self
._interCtrl
= STCTextEditor
.TextCtrl(panel
, wx
.NewId())
1041 sizer
.Add(self
._interCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 2)
1042 self
._interCtrl
.SetViewLineNumbers(False)
1043 if wx
.Platform
== '__WXMSW__':
1044 font
= "Courier New"
1047 self
._interCtrl
.SetFont(wx
.Font(9, wx
.DEFAULT
, wx
.NORMAL
, wx
.NORMAL
, faceName
= font
))
1048 self
._interCtrl
.SetFontColor(wx
.BLACK
)
1049 self
._interCtrl
.StyleClearAll()
1050 wx
.EVT_KEY_DOWN(self
._interCtrl
, OnKeyPressed
)
1051 self
._interCtrl
.AddText(">>> ")
1052 panel
.SetSizer(sizer
)
1054 tp
, val
, tb
= sys
.exc_info()
1055 traceback
.print_exception(tp
, val
, tb
)
1059 def MakeBreakPointsTab(self
, parent
, id):
1060 panel
= BreakpointsUI(parent
, id, self
._ui
)
1063 def OnRightClick(self
, event
):
1065 self
._introspectItem
= event
.GetItem()
1066 self
._parentChain
= self
.GetItemChain(event
.GetItem())
1067 watchOnly
= len(self
._parentChain
) < 1
1068 if not _WATCHES_ON
and watchOnly
:
1072 if not hasattr(self
, "watchID"):
1073 self
.watchID
= wx
.NewId()
1074 self
.Bind(wx
.EVT_MENU
, self
.OnWatch
, id=self
.watchID
)
1075 item
= wx
.MenuItem(menu
, self
.watchID
, "Create a Watch")
1076 menu
.AppendItem(item
)
1077 menu
.AppendSeparator()
1079 if not hasattr(self
, "viewID"):
1080 self
.viewID
= wx
.NewId()
1081 self
.Bind(wx
.EVT_MENU
, self
.OnView
, id=self
.viewID
)
1082 item
= wx
.MenuItem(menu
, self
.viewID
, "View in Dialog")
1083 menu
.AppendItem(item
)
1084 offset
= wx
.Point(x
=0, y
=20)
1085 menuSpot
= event
.GetPoint() + offset
1086 self
._treeCtrl
.PopupMenu(menu
, menuSpot
)
1088 self
._parentChain
= None
1089 self
._introspectItem
= None
1091 def GetItemChain(self
, item
):
1094 if _VERBOSE
: print 'Exploding: %s' % self
._treeCtrl
.GetItemText(item
, 0)
1095 while item
!= self
._root
:
1096 text
= self
._treeCtrl
.GetItemText(item
, 0)
1097 if _VERBOSE
: print "Appending ", text
1098 parentChain
.append(text
)
1099 item
= self
._treeCtrl
.GetItemParent(item
)
1100 parentChain
.reverse()
1103 def OnView(self
, event
):
1104 title
= self
._treeCtrl
.GetItemText(self
._introspectItem
,0)
1105 value
= self
._treeCtrl
.GetItemText(self
._introspectItem
,1)
1106 dlg
= wx
.lib
.dialogs
.ScrolledMessageDialog(self
, value
, title
, style
=wx
.DD_DEFAULT_STYLE | wx
.RESIZE_BORDER
)
1109 def OnWatch(self
, event
):
1111 if hasattr(self
, '_parentChain'):
1112 wd
= WatchDialog(wx
.GetApp().GetTopWindow(), "Add a Watch", self
._parentChain
)
1114 wd
= WatchDialog(wx
.GetApp().GetTopWindow(), "Add a Watch", None)
1115 if wd
.ShowModal() == wx
.ID_OK
:
1116 name
, text
, send_frame
, run_once
= wd
.GetSettings()
1118 frameNode
= self
._stack
[int(self
.currentItem
)]
1119 message
= frameNode
.getAttribute("message")
1122 binType
= self
._ui
._callback
._debuggerServer
.add_watch(name
, text
, message
, run_once
)
1123 xmldoc
= bz2
.decompress(binType
.data
)
1124 domDoc
= parseString(xmldoc
)
1125 nodeList
= domDoc
.getElementsByTagName('watch')
1126 if len(nodeList
) == 1:
1127 watchValue
= nodeList
.item(0).getAttribute("message")
1129 tp
, val
, tb
= sys
.exc_info()
1130 traceback
.print_exception(tp
, val
, tb
)
1132 def OnIntrospect(self
, event
):
1133 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
))
1136 list = self
._framesChoiceCtrl
1137 frameNode
= self
._stack
[int(self
.currentItem
)]
1138 message
= frameNode
.getAttribute("message")
1139 binType
= self
._ui
._callback
._debuggerServer
.attempt_introspection(message
, self
._parentChain
)
1140 xmldoc
= bz2
.decompress(binType
.data
)
1141 domDoc
= parseString(xmldoc
)
1142 #wx.MessageBox(xmldoc, "result of introspection")
1143 nodeList
= domDoc
.getElementsByTagName('replacement')
1144 replacementNode
= nodeList
.item(0)
1145 if len(replacementNode
.childNodes
):
1146 thingToWalk
= replacementNode
.childNodes
.item(0)
1147 tree
= self
._treeCtrl
1148 parent
= tree
.GetItemParent(self
._introspectItem
)
1149 treeNode
= self
.AppendSubTreeFromNode(thingToWalk
, thingToWalk
.getAttribute('name'), parent
, insertBefore
=self
._introspectItem
)
1150 self
._treeCtrl
.Expand(treeNode
)
1151 tree
.Delete(self
._introspectItem
)
1153 tp
,val
,tb
= sys
.exc_info()
1154 traceback
.print_exception(tp
, val
, tb
)
1156 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
))
1158 def ClearWhileRunning(self
):
1159 list = self
._framesChoiceCtrl
1162 tree
= self
._treeCtrl
1164 tree
.DeleteChildren(root
)
1165 self
._interCtrl
.Enable(False)
1169 def OnListRightClick(self
, event
):
1170 if not hasattr(self
, "syncFrameID"):
1171 self
.syncFrameID
= wx
.NewId()
1172 self
.Bind(wx
.EVT_MENU
, self
.OnSyncFrame
, id=self
.syncFrameID
)
1174 item
= wx
.MenuItem(menu
, self
.syncFrameID
, "Goto Source Line")
1175 menu
.AppendItem(item
)
1176 self
.PopupMenu(menu
, event
.GetPosition())
1179 def OnSyncFrame(self
, event
):
1180 list = self
._framesChoiceCtrl
1181 frameNode
= self
._stack
[int(self
.currentItem
)]
1182 file = frameNode
.getAttribute("file")
1183 line
= frameNode
.getAttribute("line")
1184 self
._ui
.SynchCurrentLine( file, int(line
) )
1186 def LoadFramesListXML(self
, framesXML
):
1187 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
))
1188 self
._interCtrl
.Enable(True)
1191 domDoc
= parseString(framesXML
)
1192 list = self
._framesChoiceCtrl
1195 nodeList
= domDoc
.getElementsByTagName('frame')
1197 for index
in range(0, nodeList
.length
):
1198 frameNode
= nodeList
.item(index
)
1199 message
= frameNode
.getAttribute("message")
1200 list.Append(message
)
1201 self
._stack
.append(frameNode
)
1203 index
= len(self
._stack
) - 1
1204 list.SetSelection(index
)
1206 node
= self
._stack
[index
]
1207 self
.currentItem
= index
1208 self
.PopulateTreeFromFrameNode(node
)
1209 self
.OnSyncFrame(None)
1211 self
._p
1.FitInside()
1212 frameNode
= nodeList
.item(index
)
1213 file = frameNode
.getAttribute("file")
1214 line
= frameNode
.getAttribute("line")
1215 self
._ui
.SynchCurrentLine( file, int(line
) )
1217 tp
,val
,tb
=sys
.exc_info()
1218 traceback
.print_exception(tp
, val
, tb
)
1220 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
))
1223 def ListItemSelected(self
, event
):
1224 self
.PopulateTreeFromFrameMessage(event
.GetString())
1225 self
.OnSyncFrame(None)
1227 def PopulateTreeFromFrameMessage(self
, message
):
1229 for node
in self
._stack
:
1230 if node
.getAttribute("message") == message
:
1231 binType
= self
._ui
._callback
._debuggerServer
.request_frame_document(message
)
1232 xmldoc
= bz2
.decompress(binType
.data
)
1233 domDoc
= parseString(xmldoc
)
1234 nodeList
= domDoc
.getElementsByTagName('frame')
1235 self
.currentItem
= index
1237 self
.PopulateTreeFromFrameNode(nodeList
[0])
1241 def PopulateTreeFromFrameNode(self
, frameNode
):
1242 list = self
._framesChoiceCtrl
1244 tree
= self
._treeCtrl
1247 tree
.DeleteChildren(root
)
1248 children
= frameNode
.childNodes
1250 for index
in range(0, children
.length
):
1251 subNode
= children
.item(index
)
1252 treeNode
= self
.AppendSubTreeFromNode(subNode
, subNode
.getAttribute('name'), root
)
1254 firstChild
= treeNode
1257 tree
.Expand(firstChild
)
1258 self
._p
2.FitInside()
1260 def IntrospectCallback(self
, event
):
1261 tree
= self
._treeCtrl
1262 item
= event
.GetItem()
1264 print "In introspectCallback item is %s, pydata is %s" % (event
.GetItem(), tree
.GetPyData(item
))
1265 if tree
.GetPyData(item
) != "Introspect":
1268 self
._introspectItem
= item
1269 self
._parentChain
= self
.GetItemChain(item
)
1270 self
.OnIntrospect(event
)
1273 def AppendSubTreeFromNode(self
, node
, name
, parent
, insertBefore
=None):
1274 tree
= self
._treeCtrl
1275 if insertBefore
!= None:
1276 treeNode
= tree
.InsertItem(parent
, insertBefore
, name
)
1278 treeNode
= tree
.AppendItem(parent
, name
)
1279 children
= node
.childNodes
1280 intro
= node
.getAttribute('intro')
1283 tree
.SetItemHasChildren(treeNode
, True)
1284 tree
.SetPyData(treeNode
, "Introspect")
1285 if node
.getAttribute("value"):
1286 tree
.SetItemText(treeNode
, self
.StripOuterSingleQuotes(node
.getAttribute("value")), 1)
1287 for index
in range(0, children
.length
):
1288 subNode
= children
.item(index
)
1289 if self
.HasChildren(subNode
):
1290 self
.AppendSubTreeFromNode(subNode
, subNode
.getAttribute("name"), treeNode
)
1292 name
= subNode
.getAttribute("name")
1293 value
= self
.StripOuterSingleQuotes(subNode
.getAttribute("value"))
1294 n
= tree
.AppendItem(treeNode
, name
)
1295 tree
.SetItemText(n
, value
, 1)
1296 intro
= subNode
.getAttribute('intro')
1298 tree
.SetItemHasChildren(n
, True)
1299 tree
.SetPyData(n
, "Introspect")
1303 def StripOuterSingleQuotes(self
, string
):
1304 if string
.startswith("'") and string
.endswith("'"):
1305 retval
= string
[1:-1]
1306 elif string
.startswith("\"") and string
.endswith("\""):
1307 retval
= string
[1:-1]
1310 if retval
.startswith("u'") and retval
.endswith("'"):
1314 def HasChildren(self
, node
):
1316 return node
.childNodes
.length
> 0
1318 tp
,val
,tb
=sys
.exc_info()
1321 def AppendText(self
, text
):
1322 self
._textCtrl
.SetReadOnly(False)
1323 self
._textCtrl
.AddText(text
)
1324 self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount())
1325 self
._textCtrl
.SetReadOnly(True)
1327 def AppendErrorText(self
, text
):
1328 self
._textCtrl
.SetReadOnly(False)
1329 self
._textCtrl
.SetFontColor(wx
.RED
)
1330 self
._textCtrl
.StyleClearAll()
1331 self
._textCtrl
.AddText(text
)
1332 self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount())
1333 self
._textCtrl
.SetFontColor(wx
.BLACK
)
1334 self
._textCtrl
.StyleClearAll()
1335 self
._textCtrl
.SetReadOnly(True)
1337 def ClearOutput(self
, event
):
1338 self
._textCtrl
.SetReadOnly(False)
1339 self
._textCtrl
.ClearAll()
1340 self
._textCtrl
.SetReadOnly(True)
1342 def SwitchToOutputTab(self
):
1343 self
._notebook
.SetSelection(0)
1345 class DebuggerView(Service
.ServiceView
):
1347 #----------------------------------------------------------------------------
1348 # Overridden methods
1349 #----------------------------------------------------------------------------
1351 def __init__(self
, service
):
1352 Service
.ServiceView
.__init
__(self
, service
)
1354 def _CreateControl(self
, parent
, id):
1357 #------------------------------------------------------------------------------
1359 #-----------------------------------------------------------------------------
1361 def OnToolClicked(self
, event
):
1362 self
.GetFrame().ProcessEvent(event
)
1364 def ProcessUpdateUIEvent(self
, event
):
1367 def ProcessEvent(self
, event
):
1370 #------------------------------------------------------------------------------
1372 #-----------------------------------------------------------------------------
1375 def __init__(self
, message
, framesXML
, info
=None, quit
=False):
1376 self
._framesXML
= framesXML
1377 self
._message
= message
1381 def getFramesXML(self
):
1382 return self
._framesXML
1384 def getMessage(self
):
1385 return self
._message
1393 class AGXMLRPCServer(SimpleXMLRPCServer
.SimpleXMLRPCServer
):
1394 def __init__(self
, address
, logRequests
=0):
1395 SimpleXMLRPCServer
.SimpleXMLRPCServer
.__init
__(self
, address
, logRequests
=logRequests
)
1397 class RequestHandlerThread(threading
.Thread
):
1398 def __init__(self
, queue
, address
):
1399 threading
.Thread
.__init
__(self
)
1400 self
._keepGoing
= True
1402 self
._address
= address
1403 self
._server
= AGXMLRPCServer(self
._address
,logRequests
=0)
1404 self
._server
.register_function(self
.interaction
)
1405 self
._server
.register_function(self
.quit
)
1406 self
._server
.register_function(self
.dummyOperation
)
1407 if _VERBOSE
: print "RequestHandlerThread on fileno %s" % str(self
._server
.fileno())
1410 while self
._keepGoing
:
1412 self
._server
.handle_request()
1414 tp
, val
, tb
= sys
.exc_info()
1415 traceback
.print_exception(tp
, val
, tb
)
1416 self
._keepGoing
= False
1417 if _VERBOSE
: print "Exiting Request Handler Thread."
1419 def interaction(self
, message
, frameXML
, info
):
1420 if _VERBOSE
: print "In RequestHandlerThread.interaction -- adding to queue"
1421 interaction
= Interaction(message
, frameXML
, info
)
1422 self
._queue
.put(interaction
)
1426 interaction
= Interaction(None, None, info
=None, quit
=True)
1427 self
._queue
.put(interaction
)
1430 def dummyOperation(self
):
1433 def AskToStop(self
):
1434 self
._keepGoing
= False
1435 if type(self
._server
) is not types
.NoneType
:
1437 # This is a really ugly way to make sure this thread isn't blocked in
1439 url
= 'http://' + self
._address
[0] + ':' + str(self
._address
[1]) + '/'
1440 tempServer
= xmlrpclib
.ServerProxy(url
, allow_none
=1)
1441 tempServer
.dummyOperation()
1443 tp
, val
, tb
= sys
.exc_info()
1444 traceback
.print_exception(tp
, val
, tb
)
1445 self
._server
.server_close()
1448 class RequestBreakThread(threading
.Thread
):
1449 def __init__(self
, server
, interrupt
=False, pushBreakpoints
=False, breakDict
=None, kill
=False):
1450 threading
.Thread
.__init
__(self
)
1451 self
._server
= server
1453 self
._interrupt
= interrupt
1454 self
._pushBreakpoints
= pushBreakpoints
1455 self
._breakDict
= breakDict
1460 if _VERBOSE
: print "RequestBreakThread, before call"
1462 self
._server
.break_requested()
1463 if self
._pushBreakpoints
:
1464 self
._server
.update_breakpoints(xmlrpclib
.Binary(pickle
.dumps(self
._breakDict
)))
1470 if _VERBOSE
: print "RequestBreakThread, after call"
1472 tp
,val
,tb
= sys
.exc_info()
1473 traceback
.print_exception(tp
, val
, tb
)
1475 class DebuggerOperationThread(threading
.Thread
):
1476 def __init__(self
, function
):
1477 threading
.Thread
.__init
__(self
)
1478 self
._function
= function
1481 if _VERBOSE
: print "In DOT, before call"
1485 tp
,val
,tb
= sys
.exc_info()
1486 traceback
.print_exception(tp
, val
, tb
)
1487 if _VERBOSE
: print "In DOT, after call"
1489 class DebuggerCallback
:
1491 def __init__(self
, host
, port
, debugger_url
, break_url
, debuggerUI
):
1492 if _VERBOSE
: print "+++++++ Creating server on port, ", str(port
)
1494 self
._queue
= Queue
.Queue(50)
1496 self
._port
= int(port
)
1497 threading
._VERBOSE
= _VERBOSE
1498 self
._serverHandlerThread
= RequestHandlerThread(self
._queue
, (self
._host
, self
._port
))
1500 self
._debugger
_url
= debugger_url
1501 self
._debuggerServer
= None
1502 self
._waiting
= False
1503 self
._service
= wx
.GetApp().GetService(DebuggerService
)
1504 self
._debuggerUI
= debuggerUI
1505 self
._break
_url
= break_url
1506 self
._breakServer
= None
1507 self
._firstInteraction
= True
1508 self
._pendingBreak
= False
1511 self
._serverHandlerThread
.start()
1513 def ShutdownServer(self
):
1514 #rbt = RequestBreakThread(self._breakServer, kill=True)
1516 self
.setWaiting(False)
1517 if self
._serverHandlerThread
:
1518 self
._serverHandlerThread
.AskToStop()
1519 self
._serverHandlerThread
= None
1521 def BreakExecution(self
):
1522 rbt
= RequestBreakThread(self
._breakServer
, interrupt
=True)
1525 def SingleStep(self
):
1526 self
._debuggerUI
.DisableWhileDebuggerRunning()
1527 self
._debuggerServer
.set_step() # Figure out where to set allowNone
1531 self
._debuggerUI
.DisableWhileDebuggerRunning()
1532 self
._debuggerServer
.set_next()
1536 self
._debuggerUI
.DisableWhileDebuggerRunning()
1537 self
._debuggerServer
.set_continue()
1541 self
._debuggerUI
.DisableWhileDebuggerRunning()
1542 self
._debuggerServer
.set_return()
1545 def setWaiting(self
, value
):
1546 self
._waiting
= value
1548 def getWaiting(self
):
1549 return self
._waiting
1551 def readQueue(self
):
1552 if self
._queue
.qsize():
1554 item
= self
._queue
.get_nowait()
1556 self
.interaction(None, None, None, True)
1558 data
= bz2
.decompress(item
.getFramesXML().data
)
1559 self
.interaction(item
.getMessage().data
, data
, item
.getInfo(), False)
1563 def pushBreakpoints(self
):
1564 rbt
= RequestBreakThread(self
._breakServer
, pushBreakpoints
=True, breakDict
=self
._service
.GetMasterBreakpointDict())
1568 def waitForRPC(self
):
1569 self
.setWaiting(True)
1570 while self
.getWaiting():
1576 tp
, val
, tb
= sys
.exc_info()
1577 traceback
.print_exception(tp
, val
, tb
)
1578 wx
.GetApp().Yield(True)
1579 if _VERBOSE
: print "Exiting waitForRPC."
1581 def interaction(self
, message
, frameXML
, info
, quit
):
1583 #This method should be hit as the debugger starts.
1584 if self
._firstInteraction
:
1585 self
._firstInteraction
= False
1586 self
._debuggerServer
= xmlrpclib
.ServerProxy(self
._debugger
_url
, allow_none
=1)
1587 self
._breakServer
= xmlrpclib
.ServerProxy(self
._break
_url
, allow_none
=1)
1588 self
.pushBreakpoints()
1589 self
.setWaiting(False)
1590 if _VERBOSE
: print "+"*40
1592 self
._debuggerUI
.StopExecution(None)
1595 if _VERBOSE
: print "Hit interaction with exception"
1596 #self._debuggerUI.StopExecution(None)
1597 #self._debuggerUI.SetStatusText("Got exception: " + str(info))
1598 self
._debuggerUI
.SwitchToOutputTab()
1600 if _VERBOSE
: print "Hit interaction no exception"
1601 self
._debuggerUI
.SetStatusText(message
)
1602 self
._debuggerUI
.LoadFramesListXML(frameXML
)
1603 self
._debuggerUI
.EnableWhileDebuggerStopped()
1604 if _VERBOSE
: print "+"*40
1606 class DebuggerService(Service
.Service
):
1608 #----------------------------------------------------------------------------
1610 #----------------------------------------------------------------------------
1611 TOGGLE_BREAKPOINT_ID
= wx
.NewId()
1612 CLEAR_ALL_BREAKPOINTS
= wx
.NewId()
1614 DEBUG_ID
= wx
.NewId()
1615 DEBUG_WEBSERVER_ID
= wx
.NewId()
1618 def ComparePaths(first
, second
):
1619 one
= DebuggerService
.ExpandPath(first
)
1620 two
= DebuggerService
.ExpandPath(second
)
1622 return one
.lower() == two
.lower()
1625 ComparePaths
= staticmethod(ComparePaths
)
1627 # Make sure we're using an expanded path on windows.
1628 def ExpandPath(path
):
1631 return win32api
.GetLongPathName(path
)
1634 print "Cannot get long path for %s" % path
1638 ExpandPath
= staticmethod(ExpandPath
)
1640 #----------------------------------------------------------------------------
1641 # Overridden methods
1642 #----------------------------------------------------------------------------
1644 def __init__(self
, serviceName
, embeddedWindowLocation
= wx
.lib
.pydocview
.EMBEDDED_WINDOW_LEFT
):
1645 Service
.Service
.__init
__(self
, serviceName
, embeddedWindowLocation
)
1646 self
.BREAKPOINT_DICT_STRING
= "MasterBreakpointDict"
1647 config
= wx
.ConfigBase_Get()
1648 pickledbps
= config
.Read(self
.BREAKPOINT_DICT_STRING
)
1651 self
._masterBPDict
= pickle
.loads(pickledbps
.encode('ascii'))
1653 tp
, val
, tb
= sys
.exc_info()
1654 traceback
.print_exception(tp
,val
,tb
)
1655 self
._masterBPDict
= {}
1657 self
._masterBPDict
= {}
1659 def OnCloseFrame(self
, event
):
1660 # IS THIS THE RIGHT PLACE?
1662 config
= wx
.ConfigBase_Get()
1663 config
.Write(self
.BREAKPOINT_DICT_STRING
, pickle
.dumps(self
._masterBPDict
))
1665 tp
,val
,tb
= sys
.exc_info()
1666 traceback
.print_exception(tp
, val
, tb
)
1669 def _CreateView(self
):
1670 return DebuggerView(self
)
1673 #----------------------------------------------------------------------------
1674 # Service specific methods
1675 #----------------------------------------------------------------------------
1677 def InstallControls(self
, frame
, menuBar
= None, toolBar
= None, statusBar
= None, document
= None):
1678 #Service.Service.InstallControls(self, frame, menuBar, toolBar, statusBar, document)
1680 config
= wx
.ConfigBase_Get()
1682 debuggerMenu
= wx
.Menu()
1683 if not menuBar
.FindItemById(DebuggerService
.CLEAR_ALL_BREAKPOINTS
):
1685 debuggerMenu
.Append(DebuggerService
.RUN_ID
, _("&Run...\tCtrl+R"), _("Runs a file"))
1686 wx
.EVT_MENU(frame
, DebuggerService
.RUN_ID
, frame
.ProcessEvent
)
1687 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.RUN_ID
, frame
.ProcessUpdateUIEvent
)
1689 debuggerMenu
.Append(DebuggerService
.DEBUG_ID
, _("&Debug...\tCtrl+D"), _("Debugs a file"))
1690 wx
.EVT_MENU(frame
, DebuggerService
.DEBUG_ID
, frame
.ProcessEvent
)
1691 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.DEBUG_ID
, frame
.ProcessUpdateUIEvent
)
1693 if not ACTIVEGRID_BASE_IDE
:
1694 debuggerMenu
.AppendSeparator()
1695 debuggerMenu
.Append(DebuggerService
.DEBUG_WEBSERVER_ID
, _("Debug Internal Web Server"), _("Debugs the internal webservier"))
1696 wx
.EVT_MENU(frame
, DebuggerService
.DEBUG_WEBSERVER_ID
, frame
.ProcessEvent
)
1697 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.DEBUG_WEBSERVER_ID
, frame
.ProcessUpdateUIEvent
)
1699 debuggerMenu
.AppendSeparator()
1701 debuggerMenu
.Append(DebuggerService
.TOGGLE_BREAKPOINT_ID
, _("&Toggle Breakpoint...\tCtrl+B"), _("Toggle a breakpoint"))
1702 wx
.EVT_MENU(frame
, DebuggerService
.TOGGLE_BREAKPOINT_ID
, self
.ProcessEvent
)
1703 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.TOGGLE_BREAKPOINT_ID
, self
.ProcessUpdateUIEvent
)
1705 debuggerMenu
.Append(DebuggerService
.CLEAR_ALL_BREAKPOINTS
, _("&Clear All Breakpoints"), _("Clear All Breakpoints"))
1706 wx
.EVT_MENU(frame
, DebuggerService
.CLEAR_ALL_BREAKPOINTS
, self
.ProcessEvent
)
1707 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.CLEAR_ALL_BREAKPOINTS
, self
.ProcessUpdateUIEvent
)
1710 viewMenuIndex
= menuBar
.FindMenu(_("&Project"))
1711 menuBar
.Insert(viewMenuIndex
+ 1, debuggerMenu
, _("&Run"))
1717 #----------------------------------------------------------------------------
1718 # Event Processing Methods
1719 #----------------------------------------------------------------------------
1721 def ProcessEventBeforeWindows(self
, event
):
1725 def ProcessEvent(self
, event
):
1726 if Service
.Service
.ProcessEvent(self
, event
):
1729 an_id
= event
.GetId()
1730 if an_id
== DebuggerService
.TOGGLE_BREAKPOINT_ID
:
1731 self
.OnToggleBreakpoint(event
)
1733 elif an_id
== DebuggerService
.CLEAR_ALL_BREAKPOINTS
:
1734 self
.ClearAllBreakpoints()
1736 elif an_id
== DebuggerService
.RUN_ID
:
1737 self
.OnRunProject(event
)
1739 elif an_id
== DebuggerService
.DEBUG_ID
:
1740 self
.OnDebugProject(event
)
1742 elif an_id
== DebuggerService
.DEBUG_WEBSERVER_ID
:
1743 self
.OnDebugWebServer(event
)
1747 def ProcessUpdateUIEvent(self
, event
):
1748 if Service
.Service
.ProcessUpdateUIEvent(self
, event
):
1751 an_id
= event
.GetId()
1752 if an_id
== DebuggerService
.TOGGLE_BREAKPOINT_ID
:
1753 currentView
= self
.GetDocumentManager().GetCurrentView()
1754 event
.Enable(isinstance(currentView
, PythonEditor
.PythonView
))
1756 elif an_id
== DebuggerService
.CLEAR_ALL_BREAKPOINTS
:
1757 event
.Enable(self
.HasBreakpointsSet())
1759 elif (an_id
== DebuggerService
.RUN_ID
1760 or an_id
== DebuggerService
.DEBUG_ID
):
1761 event
.Enable(self
.HasAnyFiles())
1766 #----------------------------------------------------------------------------
1768 #----------------------------------------------------------------------------
1770 def OnDebugProject(self
, event
):
1771 if _WINDOWS
and not _PYWIN32_INSTALLED
:
1772 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."))
1774 if not Executor
.GetPythonExecutablePath():
1776 if DebugCommandUI
.DebuggerRunning():
1777 wx
.MessageBox(_("A debugger is already running. Please shut down the other debugger first."), _("Debugger Running"))
1779 self
.ShowWindow(True)
1780 projectService
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
)
1781 project
= projectService
.GetView().GetDocument()
1783 dlg
= CommandPropertiesDialog(self
.GetView().GetFrame(), 'Debug Python File', projectService
, None, pythonOnly
=True, okButtonName
="Debug", debugging
=True)
1786 if dlg
.ShowModal() == wx
.ID_OK
:
1787 fileToDebug
, initialArgs
, startIn
, isPython
, environment
= dlg
.GetSettings()
1792 self
.PromptToSaveFiles()
1794 shortFile
= os
.path
.basename(fileToDebug
)
1795 fileToDebug
= DebuggerService
.ExpandPath(fileToDebug
)
1797 page
= DebugCommandUI(Service
.ServiceView
.bottomTab
, -1, str(fileToDebug
), self
)
1798 count
= Service
.ServiceView
.bottomTab
.GetPageCount()
1799 Service
.ServiceView
.bottomTab
.AddPage(page
, _("Debugging: ") + shortFile
)
1800 Service
.ServiceView
.bottomTab
.SetSelection(count
)
1801 page
.Execute(initialArgs
, startIn
, environment
)
1805 def OnDebugWebServer(self
, event
):
1806 if _WINDOWS
and not _PYWIN32_INSTALLED
:
1807 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."))
1809 if not Executor
.GetPythonExecutablePath():
1811 if DebugCommandUI
.DebuggerRunning():
1812 wx
.MessageBox(_("A debugger is already running. Please shut down the other debugger first."), _("Debugger Running"))
1814 import WebServerService
1815 wsService
= wx
.GetApp().GetService(WebServerService
.WebServerService
)
1816 fileName
, args
= wsService
.StopAndPrepareToDebug()
1818 page
= DebugCommandUI(Service
.ServiceView
.bottomTab
, -1, fileName
, self
)
1819 count
= Service
.ServiceView
.bottomTab
.GetPageCount()
1820 Service
.ServiceView
.bottomTab
.AddPage(page
, _("Debugging: Internal WebServer"))
1821 Service
.ServiceView
.bottomTab
.SetSelection(count
)
1822 page
.Execute(args
, startIn
=os
.getcwd(), environment
=os
.environ
)
1827 def HasAnyFiles(self
):
1828 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1829 return len(docs
) > 0
1831 def PromptToSaveFiles(self
, running
=True):
1832 filesModified
= False
1833 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1835 if doc
.IsModified():
1836 filesModified
= True
1839 frame
= self
.GetView().GetFrame()
1841 yesNoMsg
= wx
.MessageDialog(frame
,
1842 _("Files have been modified.\nWould you like to save all files before running?"),
1844 wx
.YES_NO|wx
.ICON_QUESTION
1847 yesNoMsg
= wx
.MessageDialog(frame
,
1848 _("Files have been modified.\nWould you like to save all files before debugging?"),
1850 wx
.YES_NO|wx
.ICON_QUESTION
1852 if yesNoMsg
.ShowModal() == wx
.ID_YES
:
1853 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1858 DebugCommandUI
.ShutdownAllDebuggers()
1859 RunCommandUI
.ShutdownAllRunners()
1861 def OnRunProject(self
, event
):
1862 if _WINDOWS
and not _PYWIN32_INSTALLED
:
1863 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."))
1865 if not Executor
.GetPythonExecutablePath():
1867 projectService
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
)
1868 project
= projectService
.GetView().GetDocument()
1870 dlg
= CommandPropertiesDialog(self
.GetView().GetFrame(), 'Run', projectService
, None)
1873 if dlg
.ShowModal() == wx
.ID_OK
:
1874 fileToRun
, initialArgs
, startIn
, isPython
, environment
= dlg
.GetSettings()
1881 self
.PromptToSaveFiles()
1882 # This will need to change when we can run more than .py and .bpel files.
1884 projectService
.RunProcessModel(fileToRun
)
1887 self
.ShowWindow(True)
1888 shortFile
= os
.path
.basename(fileToRun
)
1889 page
= RunCommandUI(Service
.ServiceView
.bottomTab
, -1, str(fileToRun
))
1890 count
= Service
.ServiceView
.bottomTab
.GetPageCount()
1891 Service
.ServiceView
.bottomTab
.AddPage(page
, "Running: " + shortFile
)
1892 Service
.ServiceView
.bottomTab
.SetSelection(count
)
1893 page
.Execute(initialArgs
, startIn
, environment
)
1895 def OnToggleBreakpoint(self
, event
, line
=-1, fileName
=None):
1897 view
= wx
.GetApp().GetDocumentManager().GetCurrentView()
1898 # Test to make sure we aren't the project view.
1899 if not hasattr(view
, 'MarkerExists'):
1901 fileName
= wx
.GetApp().GetDocumentManager().GetCurrentDocument().GetFilename()
1903 line
= view
.GetCtrl().GetCurrentLine()
1904 if self
.BreakpointSet(fileName
, line
+ 1):
1905 self
.ClearBreak(fileName
, line
+ 1)
1907 self
.SetBreak(fileName
, line
+ 1)
1908 # Now refresh all the markers icons in all the open views.
1909 self
.ClearAllBreakpointMarkers()
1910 self
.SetAllBreakpointMarkers()
1912 def SilentToggleBreakpoint(self
, fileName
, line
):
1914 for lineNumber
in self
.GetBreakpointList(fileName
):
1915 if int(lineNumber
) == int(line
):
1919 self
.SetBreak(fileName
, line
)
1921 self
.ClearBreak(fileName
, line
)
1923 def SetBreak(self
, fileName
, line
):
1924 expandedName
= DebuggerService
.ExpandPath(fileName
)
1925 if not self
._masterBPDict
.has_key(expandedName
):
1926 self
._masterBPDict
[expandedName
] = [line
]
1928 self
._masterBPDict
[expandedName
] += [line
]
1929 # If we're already debugging, pass this bp off to the DebuggerCallback
1930 self
.NotifyDebuggersOfBreakpointChange()
1932 def NotifyDebuggersOfBreakpointChange(self
):
1933 DebugCommandUI
.NotifyDebuggersOfBreakpointChange()
1935 def GetBreakpointList(self
, fileName
):
1936 expandedName
= DebuggerService
.ExpandPath(fileName
)
1937 if not self
._masterBPDict
.has_key(expandedName
):
1940 return self
._masterBPDict
[expandedName
]
1942 def BreakpointSet(self
, fileName
, line
):
1943 expandedName
= DebuggerService
.ExpandPath(fileName
)
1944 if not self
._masterBPDict
.has_key(expandedName
):
1948 for number
in self
._masterBPDict
[expandedName
]:
1949 if(int(number
) == int(line
)):
1953 def ClearBreak(self
, fileName
, line
):
1954 expandedName
= DebuggerService
.ExpandPath(fileName
)
1955 if not self
._masterBPDict
.has_key(expandedName
):
1956 print "In ClearBreak: no key"
1960 for number
in self
._masterBPDict
[expandedName
]:
1961 if(int(number
) != int(line
)):
1962 newList
.append(number
)
1963 self
._masterBPDict
[expandedName
] = newList
1964 self
.NotifyDebuggersOfBreakpointChange()
1966 def HasBreakpointsSet(self
):
1967 for key
, value
in self
._masterBPDict
.items():
1972 def ClearAllBreakpoints(self
):
1973 self
._masterBPDict
= {}
1974 self
.NotifyDebuggersOfBreakpointChange()
1975 self
.ClearAllBreakpointMarkers()
1977 def ClearAllBreakpointMarkers(self
):
1978 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1979 for openDoc
in openDocs
:
1980 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
1981 openDoc
.GetFirstView().MarkerDeleteAll(CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
)
1983 def GetMasterBreakpointDict(self
):
1984 return self
._masterBPDict
1986 def SetAllBreakpointMarkers(self
):
1987 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1988 for openDoc
in openDocs
:
1989 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
1990 self
.SetCurrentBreakpointMarkers(openDoc
.GetFirstView())
1992 def SetCurrentBreakpointMarkers(self
, view
):
1993 if isinstance(view
, CodeEditor
.CodeView
) and hasattr(view
, 'GetDocument'):
1994 view
.MarkerDeleteAll(CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
)
1995 for linenum
in self
.GetBreakpointList(view
.GetDocument().GetFilename()):
1996 view
.MarkerAdd(lineNum
=int(linenum
) - 1, marker_index
=CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
)
1998 class DebuggerOptionsPanel(wx
.Panel
):
2001 def __init__(self
, parent
, id):
2002 wx
.Panel
.__init
__(self
, parent
, id)
2004 config
= wx
.ConfigBase_Get()
2005 localHostStaticText
= wx
.StaticText(self
, -1, _("Local Host Name:"))
2006 self
._LocalHostTextCtrl
= wx
.TextCtrl(self
, -1, config
.Read("DebuggerHostName", DEFAULT_HOST
), size
= (150, -1))
2007 portNumberStaticText
= wx
.StaticText(self
, -1, _("Port Range:"))
2008 dashStaticText
= wx
.StaticText(self
, -1, _("through to"))
2009 startingPort
=config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
)
2010 self
._PortNumberTextCtrl
= wx
.lib
.intctrl
.IntCtrl(self
, -1, startingPort
, size
= (50, -1))
2011 self
._PortNumberTextCtrl
.SetMin(1)#What are real values?
2012 self
._PortNumberTextCtrl
.SetMax(65514) #What are real values?
2013 self
.Bind(wx
.lib
.intctrl
.EVT_INT
, self
.MinPortChange
, self
._PortNumberTextCtrl
)
2015 self
._EndPortNumberTextCtrl
= wx
.lib
.intctrl
.IntCtrl(self
, -1, startingPort
+ PORT_COUNT
, size
= (50, -1))
2016 self
._EndPortNumberTextCtrl
.SetMin(22)#What are real values?
2017 self
._EndPortNumberTextCtrl
.SetMax(65535)#What are real values?
2018 self
._EndPortNumberTextCtrl
.Enable( False )
2019 debuggerPanelBorderSizer
= wx
.BoxSizer(wx
.VERTICAL
)
2020 debuggerPanelSizer
= wx
.GridBagSizer(hgap
= 5, vgap
= 5)
2021 debuggerPanelSizer
.Add( localHostStaticText
, (0,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2022 debuggerPanelSizer
.Add( self
._LocalHostTextCtrl
, (0,1), (1,3), flag
=wx
.EXPAND|wx
.ALIGN_CENTER
)
2023 debuggerPanelSizer
.Add( portNumberStaticText
, (1,0), flag
=wx
.ALIGN_LEFT|wx
.ALIGN_CENTER_VERTICAL
)
2024 debuggerPanelSizer
.Add( self
._PortNumberTextCtrl
, (1,1), flag
=wx
.ALIGN_CENTER
)
2025 debuggerPanelSizer
.Add( dashStaticText
, (1,2), flag
=wx
.ALIGN_CENTER
)
2026 debuggerPanelSizer
.Add( self
._EndPortNumberTextCtrl
, (1,3), flag
=wx
.ALIGN_CENTER
)
2027 FLUSH_PORTS_ID
= wx
.NewId()
2028 self
._flushPortsButton
= wx
.Button(self
, FLUSH_PORTS_ID
, "Reset Port List")
2029 wx
.EVT_BUTTON(parent
, FLUSH_PORTS_ID
, self
.FlushPorts
)
2030 debuggerPanelSizer
.Add(self
._flushPortsButton
, (2,2), (1,2), flag
=wx
.ALIGN_RIGHT
)
2032 debuggerPanelBorderSizer
.Add(debuggerPanelSizer
, 0, wx
.ALL
, SPACE
)
2033 self
.SetSizer(debuggerPanelBorderSizer
)
2035 parent
.AddPage(self
, _("Debugger"))
2037 def FlushPorts(self
, event
):
2038 if self
._PortNumberTextCtrl
.IsInBounds():
2039 config
= wx
.ConfigBase_Get()
2040 config
.WriteInt("DebuggerStartingPort", self
._PortNumberTextCtrl
.GetValue())
2041 DebugCommandUI
.NewPortRange()
2043 wx
.MessageBox(_("The starting port is not valid. Please change the value and try again.", "Invalid Starting Port Number"))
2045 def MinPortChange(self
, event
):
2046 self
._EndPortNumberTextCtrl
.Enable( True )
2047 self
._EndPortNumberTextCtrl
.SetValue( self
._PortNumberTextCtrl
.GetValue() + PORT_COUNT
)
2048 self
._EndPortNumberTextCtrl
.Enable( False )
2050 def OnOK(self
, optionsDialog
):
2051 config
= wx
.ConfigBase_Get()
2052 config
.Write("DebuggerHostName", self
._LocalHostTextCtrl
.GetValue())
2053 if self
._PortNumberTextCtrl
.IsInBounds():
2054 config
.WriteInt("DebuggerStartingPort", self
._PortNumberTextCtrl
.GetValue())
2056 class CommandPropertiesDialog(wx
.Dialog
):
2058 def __init__(self
, parent
, title
, projectService
, currentProjectDocument
, pythonOnly
=False, okButtonName
="Run", debugging
=False):
2059 self
._projService
= projectService
2062 for template
in self
._projService
.GetDocumentManager().GetTemplates():
2063 if not ACTIVEGRID_BASE_IDE
and template
.GetDocumentType() == ProcessModelEditor
.ProcessModelDocument
:
2064 self
._pmext
= template
.GetDefaultExtension()
2065 if template
.GetDocumentType() == PythonEditor
.PythonDocument
:
2066 self
._pyext
= template
.GetDefaultExtension()
2067 self
._pythonOnly
= pythonOnly
2068 self
._currentProj
= currentProjectDocument
2069 self
._projectNameList
, self
._projectDocumentList
, selectedIndex
= self
.GetProjectList()
2070 if not self
._projectNameList
:
2071 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"))
2074 wx
.Dialog
.__init
__(self
, parent
, -1, title
)
2076 wx
.Dialog
.__init
__(self
, parent
, -1, title
, size
=(390,270))
2078 projStaticText
= wx
.StaticText(self
, -1, _("Project:"))
2079 fileStaticText
= wx
.StaticText(self
, -1, _("File:"))
2080 argsStaticText
= wx
.StaticText(self
, -1, _("Arguments:"))
2081 startInStaticText
= wx
.StaticText(self
, -1, _("Start in:"))
2082 pythonPathStaticText
= wx
.StaticText(self
, -1, _("PYTHONPATH:"))
2083 postpendStaticText
= _("Postpend win32api path")
2084 cpPanelBorderSizer
= wx
.BoxSizer(wx
.VERTICAL
)
2085 self
._projList
= wx
.Choice(self
, -1, (200,-1), choices
=self
._projectNameList
)
2086 self
.Bind(wx
.EVT_CHOICE
, self
.EvtListBox
, self
._projList
)
2088 flexGridSizer
= wx
.FlexGridSizer(cols
= 3, vgap
= 10, hgap
= 10)
2090 flexGridSizer
.Add(projStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2091 flexGridSizer
.Add(self
._projList
, 1, flag
=wx
.EXPAND
)
2092 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
2094 flexGridSizer
.Add(fileStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2095 self
._fileList
= wx
.Choice(self
, -1, (200,-1))
2096 self
.Bind(wx
.EVT_CHOICE
, self
.OnFileSelected
, self
._fileList
)
2097 flexGridSizer
.Add(self
._fileList
, 1, flag
=wx
.EXPAND
)
2098 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
2100 config
= wx
.ConfigBase_Get()
2101 self
._lastArguments
= config
.Read("LastRunArguments")
2102 self
._argsEntry
= wx
.TextCtrl(self
, -1, str(self
._lastArguments
))
2103 self
._argsEntry
.SetToolTipString(str(self
._lastArguments
))
2105 flexGridSizer
.Add(argsStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2106 flexGridSizer
.Add(self
._argsEntry
, 1, flag
=wx
.EXPAND
)
2107 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
2109 flexGridSizer
.Add(startInStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2110 self
._lastStartIn
= config
.Read("LastRunStartIn")
2111 if not self
._lastStartIn
:
2112 self
._lastStartIn
= str(os
.getcwd())
2113 self
._startEntry
= wx
.TextCtrl(self
, -1, self
._lastStartIn
)
2114 self
._startEntry
.SetToolTipString(self
._lastStartIn
)
2116 flexGridSizer
.Add(self
._startEntry
, 1, wx
.EXPAND
)
2117 self
._findDir
= wx
.Button(self
, -1, _("Browse..."))
2118 self
.Bind(wx
.EVT_BUTTON
, self
.OnFindDirClick
, self
._findDir
)
2119 flexGridSizer
.Add(self
._findDir
, 0, wx
.RIGHT
, 10)
2121 flexGridSizer
.Add(pythonPathStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2122 if os
.environ
.has_key('PYTHONPATH'):
2123 startval
= os
.environ
['PYTHONPATH']
2126 self
._lastPythonPath
= config
.Read("LastPythonPath", startval
)
2127 self
._pythonPathEntry
= wx
.TextCtrl(self
, -1, self
._lastPythonPath
)
2128 self
._pythonPathEntry
.SetToolTipString(self
._lastPythonPath
)
2129 flexGridSizer
.Add(self
._pythonPathEntry
, 1, wx
.EXPAND
)
2130 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
2131 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
2132 if debugging
and _WINDOWS
:
2133 self
._postpendCheckBox
= wx
.CheckBox(self
, -1, postpendStaticText
)
2134 checked
= bool(config
.ReadInt("PythonPathPostpend", 1))
2135 self
._postpendCheckBox
.SetValue(checked
)
2136 flexGridSizer
.Add(self
._postpendCheckBox
, 1, wx
.EXPAND
)
2137 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
2138 cpPanelBorderSizer
.Add(flexGridSizer
, 0, wx
.ALL
, 10)
2140 box
= wx
.BoxSizer(wx
.HORIZONTAL
)
2141 self
._okButton
= wx
.Button(self
, wx
.ID_OK
, okButtonName
)
2142 self
._okButton
.SetDefault()
2143 self
._okButton
.SetHelpText(_("The ") + okButtonName
+ _(" button completes the dialog"))
2144 box
.Add(self
._okButton
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5)
2145 self
.Bind(wx
.EVT_BUTTON
, self
.OnOKClick
, self
._okButton
)
2146 btn
= wx
.Button(self
, wx
.ID_CANCEL
, _("Cancel"))
2147 btn
.SetHelpText(_("The Cancel button cancels the dialog."))
2148 box
.Add(btn
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5)
2149 cpPanelBorderSizer
.Add(box
, 0, wx
.ALIGN_RIGHT|wx
.BOTTOM
, 5)
2151 self
.SetSizer(cpPanelBorderSizer
)
2153 self
.GetSizer().Fit(self
)
2157 # Set up selections based on last values used.
2158 self
._fileNameList
= None
2159 self
._selectedFileIndex
= 0
2160 lastProject
= config
.Read("LastRunProject")
2161 lastFile
= config
.Read("LastRunFile")
2163 if lastProject
in self
._projectNameList
:
2164 selectedIndex
= self
._projectNameList
.index(lastProject
)
2165 elif selectedIndex
< 0:
2167 self
._projList
.Select(selectedIndex
)
2168 self
._selectedProjectIndex
= selectedIndex
2169 self
._selectedProjectDocument
= self
._projectDocumentList
[selectedIndex
]
2170 self
.PopulateFileList(self
._selectedProjectDocument
, lastFile
)
2172 def OnOKClick(self
, event
):
2173 startIn
= self
._startEntry
.GetValue()
2174 fileToRun
= self
._fileList
.GetStringSelection()
2176 wx
.MessageBox(_("You must select a file to proceed. Note that not all projects have files that can be run or debugged."))
2178 isPython
= fileToRun
.endswith(self
._pyext
)
2179 if isPython
and not os
.path
.exists(startIn
):
2180 wx
.MessageBox(_("Starting directory does not exist. Please change this value."))
2182 config
= wx
.ConfigBase_Get()
2183 config
.Write("LastRunProject", self
._projectNameList
[self
._selectedProjectIndex
])
2184 config
.Write("LastRunFile", fileToRun
)
2185 # Don't update the arguments or starting directory unless we're runing python.
2187 config
.Write("LastRunArguments", self
._argsEntry
.GetValue())
2188 config
.Write("LastRunStartIn", self
._startEntry
.GetValue())
2189 config
.Write("LastPythonPath",self
._pythonPathEntry
.GetValue())
2190 if hasattr(self
, "_postpendCheckBox"):
2191 config
.WriteInt("PythonPathPostpend", int(self
._postpendCheckBox
.GetValue()))
2193 self
.EndModal(wx
.ID_OK
)
2195 def GetSettings(self
):
2196 filename
= self
._fileNameList
[self
._selectedFileIndex
]
2197 args
= self
._argsEntry
.GetValue()
2198 startIn
= self
._startEntry
.GetValue()
2199 isPython
= filename
.endswith(self
._pyext
)
2201 if hasattr(self
, "_postpendCheckBox"):
2202 postpend
= self
._postpendCheckBox
.GetValue()
2206 env
['PYTHONPATH'] = self
._pythonPathEntry
.GetValue() + os
.pathsep
+ os
.path
.join(os
.getcwd(), "3rdparty", "pywin32")
2208 env
['PYTHONPATH'] = self
._pythonPathEntry
.GetValue()
2210 return filename
, args
, startIn
, isPython
, env
2212 def OnFileSelected(self
, event
):
2213 self
._selectedFileIndex
= self
._fileList
.GetSelection()
2214 self
.EnableForFileType(event
.GetString())
2216 def EnableForFileType(self
, fileName
):
2217 show
= fileName
.endswith(self
._pyext
)
2218 self
._startEntry
.Enable(show
)
2219 self
._findDir
.Enable(show
)
2220 self
._argsEntry
.Enable(show
)
2223 self
._lastStartIn
= self
._startEntry
.GetValue()
2224 self
._startEntry
.SetValue("")
2225 self
._lastArguments
= self
._argsEntry
.GetValue()
2226 self
._argsEntry
.SetValue("")
2228 self
._startEntry
.SetValue(self
._lastStartIn
)
2229 self
._argsEntry
.SetValue(self
._lastArguments
)
2233 def OnFindDirClick(self
, event
):
2234 dlg
= wx
.DirDialog(self
, "Choose a starting directory:", self
._startEntry
.GetValue(),
2235 style
=wx
.DD_DEFAULT_STYLE|wx
.DD_NEW_DIR_BUTTON
)
2237 if dlg
.ShowModal() == wx
.ID_OK
:
2238 self
._startEntry
.SetValue(dlg
.GetPath())
2242 def EvtListBox(self
, event
):
2243 if event
.GetString():
2244 index
= self
._projectNameList
.index(event
.GetString())
2245 self
._selectedProjectDocument
= self
._projectDocumentList
[index
]
2246 self
._selectedProjectIndex
= index
2247 self
.PopulateFileList(self
._selectedProjectDocument
)
2249 def FilterFileList(self
, list):
2250 if self
._pythonOnly
:
2251 files
= filter(lambda f
: f
.endswith(self
._pyext
), list)
2253 files
= filter(lambda f
: (self
._pmext
and f
.endswith(self
._pmext
)) or f
.endswith(self
._pyext
), list)
2256 def PopulateFileList(self
, project
, shortNameToSelect
=None):
2257 self
._fileNameList
= self
.FilterFileList(project
.GetFiles()[:])
2258 self
._fileList
.Clear()
2259 if not self
._fileNameList
:
2261 self
._fileNameList
.sort(lambda a
, b
: cmp(os
.path
.basename(a
).lower(), os
.path
.basename(b
).lower()))
2262 strings
= map(lambda file: os
.path
.basename(file), self
._fileNameList
)
2263 for index
in range(0, len(strings
)):
2264 if shortNameToSelect
== strings
[index
]:
2265 self
._selectedFileIndex
= index
2267 self
._fileList
.Hide()
2268 self
._fileList
.AppendItems(strings
)
2269 self
._fileList
.Show()
2270 if self
._selectedFileIndex
not in range(0, len(strings
)) : self
._selectedFileIndex
= 0
2271 self
._fileList
.SetSelection(self
._selectedFileIndex
)
2272 self
.EnableForFileType(strings
[self
._selectedFileIndex
])
2274 def GetProjectList(self
):
2280 for document
in self
._projService
.GetDocumentManager().GetDocuments():
2281 if document
.GetDocumentTemplate().GetDocumentType() == ProjectEditor
.ProjectDocument
and len(document
.GetFiles()):
2282 docList
.append(document
)
2283 nameList
.append(os
.path
.basename(document
.GetFilename()))
2284 if document
== self
._currentProj
:
2288 #Check for open files not in any of these projects and add them to a default project
2289 def AlreadyInProject(fileName
):
2290 for projectDocument
in docList
:
2291 if projectDocument
.IsFileInProject(fileName
):
2295 unprojectedFiles
= []
2296 for document
in self
._projService
.GetDocumentManager().GetDocuments():
2297 if not ACTIVEGRID_BASE_IDE
and type(document
) == ProcessModelEditor
.ProcessModelDocument
:
2298 if not AlreadyInProject(document
.GetFilename()):
2299 unprojectedFiles
.append(document
.GetFilename())
2300 if type(document
) == PythonEditor
.PythonDocument
:
2301 if not AlreadyInProject(document
.GetFilename()):
2302 unprojectedFiles
.append(document
.GetFilename())
2304 if unprojectedFiles
:
2305 unprojProj
= ProjectEditor
.ProjectDocument()
2306 unprojProj
.SetFilename(_("Not in any Project"))
2307 unprojProj
.AddFiles(unprojectedFiles
)
2308 docList
.append(unprojProj
)
2309 nameList
.append(_("Not in any Project"))
2311 return nameList
, docList
, index
2314 #----------------------------------------------------------------------
2315 from wx
import ImageFromStream
, BitmapFromImage
2318 #----------------------------------------------------------------------
2321 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x02\
2322 \x00\x00\x00\x90\x91h6\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\
2323 \x00\x85IDAT(\x91\xbd\x92A\x16\x03!\x08CI\xdf\xdc\x0b\x8e\xe6\xd1\xe0d\xe9\
2324 \x82\xd6\xc7(\x9di7\xfd\xab<\x14\x13Q\xb8\xbb\xfc\xc2\xe3\xd3\x82\x99\xb9\
2325 \xe9\xaeq\xe1`f)HF\xc4\x8dC2\x06\xbf\x8a4\xcf\x1e\x03K\xe5h\x1bH\x02\x98\xc7\
2326 \x03\x98\xa9z\x07\x00%\xd6\xa9\xd27\x90\xac\xbbk\xe5\x15I\xcdD$\xdc\xa7\xceT\
2327 5a\xce\xf3\xe4\xa0\xaa\x8bO\x12\x11\xabC\xcb\x9c}\xd57\xef\xb0\xf3\xb7\x86p\
2328 \x97\xf7\xb5\xaa\xde\xb9\xfa|-O\xbdjN\x9b\xf8\x06A\xcb\x00\x00\x00\x00IEND\
2331 def getBreakBitmap():
2332 return BitmapFromImage(getBreakImage())
2334 def getBreakImage():
2335 stream
= cStringIO
.StringIO(getBreakData())
2336 return ImageFromStream(stream
)
2339 return wx
.IconFromBitmap(getBreakBitmap())
2341 #----------------------------------------------------------------------
2343 def getClearOutputData():
2345 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2346 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2347 \x00\x00\xb7IDAT8\x8d\xa5\x93\xdd\x11\xc3 \x0c\x83%`\xa3\xee\xd4\xaeA\xc6\
2348 \xe8N\xedF%\xea\x03\t\x81\xf0\x97\xbb\xf8%G\xce\xfe\x90eC\x1a\x8b;\xe1\xf2\
2349 \x83\xd6\xa0Q2\x8de\xf5oW\xa05H\xea\xd7\x93\x84$\x18\xeb\n\x88;\'.\xd5\x1d\
2350 \x80\x07\xe1\xa1\x1d\xa2\x1cbF\x92\x0f\x80\xe0\xd1 \xb7\x14\x8c \x00*\x15\
2351 \x97\x14\x8c\x8246\x1a\xf8\x98\'/\xdf\xd8Jn\xe65\xc0\xa7\x90_L"\x01\xde\x9d\
2352 \xda\xa7\x92\xfb\xc5w\xdf\t\x07\xc4\x05ym{\xd0\x1a\xe3\xb9xS\x81\x04\x18\x05\
2353 \xc9\x04\xc9a\x00Dc9\x9d\x82\xa4\xbc\xe8P\xb2\xb5P\xac\xf2\x0c\xd4\xf5\x00\
2354 \x88>\xac\xe17\x84\xe4\xb9G\x8b7\x9f\xf3\x1fsUl^\x7f\xe7y\x0f\x00\x00\x00\
2357 def getClearOutputBitmap():
2358 return BitmapFromImage(getClearOutputImage())
2360 def getClearOutputImage():
2361 stream
= cStringIO
.StringIO(getClearOutputData())
2362 return ImageFromStream(stream
)
2364 def getClearOutputIcon():
2365 return wx
.IconFromBitmap(getClearOutputBitmap())
2367 #----------------------------------------------------------------------
2370 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x02\
2371 \x00\x00\x00\x90\x91h6\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\
2372 \x00\xedIDAT(\x91\xa5\x90!\xae\x840\x10\x86g_\xd6"*kz\x82j\xb0h\x1c\t\' x\
2373 \x92Z\xc2\x05\x10\x95\x18\x0e\x00\x02M\x82 \xe1\nMF#jz\x80\xea&+\x9a\x10\x96\
2374 \xdd}\xfb\xc8\x1b\xd7?\xdf\x97\xfe3\xb7u]\xe1\xca\xfc\\\xa2\xff- \xe24M\xc7\
2375 \xc49wJ\xee\xc7G]\xd7\x8c1\xc6\x18\xe7\xdc\'B\x08k\xed1y\xfaa\x1cG\xad\xb5\
2376 \x94\x12\x11\x9dsy\x9e+\xa5\x84\x10;\r\x00\xb7\xd3\x95\x8c1UU\x05A\x00\x00\
2377 \xd6\xda,\xcb\x92$\xf9\xb8\x03\x00PJ\x85\x10Zk\xa5\xd4+\xfdF\x00\x80\xae\xeb\
2378 \x08!\x84\x90y\x9e\x11\xf1\x8bP\x96\xa5\xef\xdd\xb6\xad\xb5VJ\xf9\x9b\xe0\
2379 \xe9\xa6i8\xe7\xbe\xdb\xb6mi\x9a\x0e\xc3\xf0F\x88\xe3\x18\x00\xfa\xbe\x0f\
2380 \xc3\xd0\'\x9c\xf3eY\xa2(*\x8ab\xc7\x9e\xaed\x8c\xa1\x94\xben\xf5\xb1\xd2W\
2381 \xfa,\xfce.\x0b\x0f\xb8\x96e\x90gS\xe0v\x00\x00\x00\x00IEND\xaeB`\x82'
2383 def getCloseBitmap():
2384 return BitmapFromImage(getCloseImage())
2386 def getCloseImage():
2387 stream
= cStringIO
.StringIO(getCloseData())
2388 return ImageFromStream(stream
)
2391 return wx
.IconFromBitmap(getCloseBitmap())
2393 #----------------------------------------------------------------------
2394 def getContinueData():
2396 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2397 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2398 \x00\x00\xcdIDAT8\x8d\xa5\x93\xd1\r\xc20\x0cD\xef\xec,\xc0b\x88\x8d`$\x06Cb\
2399 \x81\xc6\xc7GI\xeb\x94RZq?U"\xdby\xe7SIs\xfc#\xfbU\xa0\xa8\xba\xc6\xa0og\xee\
2400 !P\xd4y\x80\x04\xf3\xc2U\x82{\x9ct\x8f\x93\xb0\xa2\xdbm\xf5\xba\'h\xcdg=`\
2401 \xeeTT\xd1\xc6o& \t\x9a\x13\x00J\x9ev\xb1\'\xa3~\x14+\xbfN\x12\x92\x00@\xe6\
2402 \x85\xdd\x00\x000w\xe6\xe2\xde\xc7|\xdf\x08\xba\x1d(\xaa2n+\xca\xcd\x8d,\xea\
2403 \x98\xc4\x07\x01\x00D\x1dd^\xa8\xa8j\x9ew\xed`\xa9\x16\x99\xde\xa6G\x8b\xd3Y\
2404 \xe6\x85]\n\r\x7f\x99\xf5\x96Jnlz#\xab\xdb\xc1\x17\x19\xb0XV\xc2\xdf\xa3)\
2405 \x85<\xe4\x88\x85.F\x9a\xf3H3\xb0\xf3g\xda\xd2\x0b\xc5_|\x17\xe8\xf5R\xd6\
2406 \x00\x00\x00\x00IEND\xaeB`\x82'
2408 def getContinueBitmap():
2409 return BitmapFromImage(getContinueImage())
2411 def getContinueImage():
2412 stream
= cStringIO
.StringIO(getContinueData())
2413 return ImageFromStream(stream
)
2415 def getContinueIcon():
2416 return wx
.IconFromBitmap(getContinueBitmap())
2418 #----------------------------------------------------------------------
2421 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2422 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2423 \x00\x00\x8eIDAT8\x8d\xa5SA\x12\xc4 \x08K\xb0\xff\xde\xe9\xbf\xb7\xa6\x87\
2424 \x1d:\xba\xa2tZn(\x84`"i\x05obk\x13\xd5CmN+\xcc\x00l\xd6\x0c\x00\xf5\xf8\x0e\
2425 gK\x06\x00 \xa5=k\x00\x00\xb0\xb2]\xd4?5f\xb1\xdb\xaf\xc6\xa2\xcb\xa8\xf0?\
2426 \x1c\x98\xae\x82\xbf\x81\xa4\x8eA\x16\xe1\n\xd1\xa4\x19\xb3\xe9\n\xce\xe8\
2427 \xf1\n\x9eg^\x18\x18\x90\xec<\x11\xf9#\x04XMZ\x19\xaac@+\x94\xd4\x99)SeP\xa1\
2428 )\xd6\x1dI\xe7*\xdc\xf4\x03\xdf~\xe7\x13T^Q?:X\x19d\x00\x00\x00\x00IEND\xaeB\
2431 def getNextBitmap():
2432 return BitmapFromImage(getNextImage())
2435 stream
= cStringIO
.StringIO(getNextData())
2436 return ImageFromStream(stream
)
2439 return wx
.IconFromBitmap(getNextBitmap())
2441 #----------------------------------------------------------------------
2442 def getStepInData():
2444 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2445 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2446 \x00\x00\x87IDAT8\x8d\xadSA\x12\x84 \x0ck\x8a\xffv\xfc\xb74{X\xeb0P@\x07s\
2447 \x84\xa4$\x01\x00M\xb2\x02]R\x8b\xc86\xda\xdc\xedd\xb4~\xe8\x86\xc6\x01-\x93\
2448 \x96\xd9#\xf6\x06\xc3;p1I\xd1\x14\x0b#|\x17aF\xec\r\xeeF\xa0eB\xd34\xca\xd0A\
2449 ]j\x84\xa6\x03\x00""\xb7\xb0tRZ\xf7x\xb7\x83\x91]\xcb\x7fa\xd9\x89\x0fC\xfd\
2450 \x94\x9d|9\x99^k\x13\xa1 \xb3\x16\x0f#\xd4\x88N~\x14\xe1-\x96\x7f\xe3\x0f\
2451 \x11\x91UC\x0cX\'\x1e\x00\x00\x00\x00IEND\xaeB`\x82'
2453 def getStepInBitmap():
2454 return BitmapFromImage(getStepInImage())
2456 def getStepInImage():
2457 stream
= cStringIO
.StringIO(getStepInData())
2458 return ImageFromStream(stream
)
2460 def getStepInIcon():
2461 return wx
.IconFromBitmap(getStepInBitmap())
2463 #----------------------------------------------------------------------
2466 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2467 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2468 \x00\x00QIDAT8\x8d\xdd\x93A\n\xc00\x08\x04g\xb5\xff\x7fq\x13sn\xda&\x01\x0b\
2469 \xa5]\xf0"\xec(.J\xe6dd)\xf7\x13\x80\xadoD-12\xc8\\\xd3\r\xe2\xa6\x00j\xd9\
2470 \x0f\x03\xde\xbf\xc1\x0f\x00\xa7\x18\x01t\xd5\\\x05\xc8\\}T#\xe9\xfb\xbf\x90\
2471 \x064\xd8\\\x12\x1fQM\xf5\xd9\x00\x00\x00\x00IEND\xaeB`\x82'
2473 def getStopBitmap():
2474 return BitmapFromImage(getStopImage())
2477 stream
= cStringIO
.StringIO(getStopData())
2478 return ImageFromStream(stream
)
2481 return wx
.IconFromBitmap(getStopBitmap())
2483 #----------------------------------------------------------------------
2484 def getStepReturnData():
2486 "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2487 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2488 \x00\x00\x8dIDAT8\x8d\xa5S\xd1\x0e\xc4 \x08\xa3\xb0\xff\xbe\xdc\x7fO\xba'6\
2489 \xf1\xf44\xb3O$Phk\x04\xd4d\x07\xba\xc5\x16\x91#\nza\xdb\x84\x1a\xa2\xfe\xf8\
2490 \x99\xfa_=p+\xe8\x91ED\xbc<\xa4 \xb4\x0b\x01\xb5{\x01\xf9\xbbG-\x13\x87\x16f\
2491 \x84\xbf\x16V\xb0l\x01@\no\x86\xae\x82Q\xa8=\xa4\x0c\x80\xe70\xbd\x10jh\xbd\
2492 \x07R\x06#\xc9^N\xb6\xde\x03)\x83\x18\xaeU\x90\x9c>a\xb2P\r\xb3&/Y\xa8\xd1^^\
2493 \xb6\xf0\x16\xdb\xbf\xf1\x02\x81\xa5TK\x1d\x07\xde\x92\x00\x00\x00\x00IEND\
2496 def getStepReturnBitmap():
2497 return BitmapFromImage(getStepReturnImage())
2499 def getStepReturnImage():
2500 stream
= cStringIO
.StringIO(getStepReturnData())
2501 return ImageFromStream(stream
)
2503 def getStepReturnIcon():
2504 return wx
.IconFromBitmap(getStepReturnBitmap())
2506 #----------------------------------------------------------------------
2507 def getAddWatchData():
2509 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2510 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2511 \x00\x00\x85IDAT8\x8dc`\x18h\xc0\x88.\xd0\xc0\xf0\xff?*\x9f\x11C\rN\x80\xae\
2512 \x19\x97\x18\xd1\x9a\x896\x84\x18[p\xa9aA\xe6\xfc7f\xc0P\xc4x\x163\x9cp\x1a0\
2513 \xeb,!w\x100 \x1dK\xac\x10\r\x08\x05".yFL\x85\x8c\x18b\xa8|Ty\xa2\x13\x92\'\
2514 \xc3\xe4\xff\x9f\x18\x1e3\xb82t\xa2\x88\x13\xedg.\x06aa&\x06VV\x7f\x86\xb9\
2515 \xcfU\x19\xbc\xb0\xba\x86h\xe0\xc8\xd0\xfc\xbf\x80\xe1>q)\x94\xe6\x00\x00\
2516 \x85\x923_\xd22\xa4\xcd\x00\x00\x00\x00IEND\xaeB`\x82'
2518 def getAddWatchBitmap():
2519 return BitmapFromImage(getAddWatchImage())
2521 def getAddWatchImage():
2522 stream
= cStringIO
.StringIO(getAddWatchData())
2523 return ImageFromStream(stream
)
2525 def getAddWatchIcon():
2526 return wx
.IconFromBitmap(getAddWatchBitmap())