1 #----------------------------------------------------------------------------
2 # Name: DebuggerService.py
3 # Purpose: Debugger Service for Python.
9 # Copyright: (c) 2004-2005 ActiveGrid, Inc.
10 # License: wxWindows License
11 #----------------------------------------------------------------------------
19 import wx
.lib
.pydocview
24 from IDE
import ACTIVEGRID_BASE_IDE
25 if not ACTIVEGRID_BASE_IDE
:
26 import ProcessModelEditor
27 import wx
.lib
.scrolledpanel
as scrolled
30 import SimpleXMLRPCServer
38 from xml
.dom
.minidom
import parse
, parseString
41 import DebuggerHarness
44 if wx
.Platform
== '__WXMSW__':
47 _PYWIN32_INSTALLED
= True
49 _PYWIN32_INSTALLED
= False
54 if not _WINDOWS
or _PYWIN32_INSTALLED
:
62 # Class to read from stdout or stderr and write the result to a text control.
63 # Args: file=file-like object
64 # callback_function= function that takes a single argument, the line of text
66 class OutputReaderThread(threading
.Thread
):
67 def __init__(self
, file, callback_function
, callbackOnExit
=None, accumulate
=True):
68 threading
.Thread
.__init
__(self
)
70 self
._callback
_function
= callback_function
71 self
._keepGoing
= True
73 self
._accumulate
= accumulate
74 self
._callbackOnExit
= callbackOnExit
80 while self
._keepGoing
:
82 # This could block--how to handle that?
83 text
= file.readline()
84 if text
== '' or text
== None:
85 self
._keepGoing
= False
86 elif not self
._accumulate
:
87 self
._callback
_function
(text
)
89 # Should use a buffer? StringIO?
91 # Seems as though the read blocks if we got an error, so, to be
92 # sure that at least some of the exception gets printed, always
93 # send the first hundred lines back as they come in.
94 if self
._lineCount
< 100:
95 self
._callback
_function
(output
)
98 elif time
.time() - start
> 0.25:
100 self
._callback
_function
(output
)
101 except wx
._core
.PyDeadObjectError
:
102 # GUI was killed while we were blocked.
103 self
._keepGoing
= False
109 tp
, val
, tb
= sys
.exc_info()
110 print "Exception in OutputReaderThread.run():", tp
, val
111 self
._keepGoing
= False
112 if self
._callbackOnExit
:
114 self
._callbackOnExit
()
115 except wx
._core
.PyDeadObjectError
:
117 if _VERBOSE
: print "Exiting OutputReaderThread"
120 self
._keepGoing
= False
122 import wx
.lib
.newevent
123 (UpdateTextEvent
, EVT_UPDATE_STDTEXT
) = wx
.lib
.newevent
.NewEvent()
124 (UpdateErrorEvent
, EVT_UPDATE_ERRTEXT
) = wx
.lib
.newevent
.NewEvent()
128 def GetPythonExecutablePath():
129 config
= wx
.ConfigBase_Get()
130 path
= config
.Read("ActiveGridPythonLocation")
133 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"))
135 GetPythonExecutablePath
= staticmethod(GetPythonExecutablePath
)
137 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):
138 self
._fileName
= fileName
139 self
._stdOutCallback
= self
.OutCall
140 self
._stdErrCallback
= self
.ErrCall
141 self
._callbackOnExit
= callbackOnExit
142 self
._wxComponent
= wxComponent
143 path
= Executor
.GetPythonExecutablePath()
144 self
._cmd
= '"' + path
+ '" -u \"' + fileName
+ '\"'
145 #Better way to do this? Quotes needed for windows file paths.
147 self
._cmd
+= ' \"' + arg1
+ '\"'
149 self
._cmd
+= ' \"' + arg2
+ '\"'
151 self
._cmd
+= ' \"' + arg3
+ '\"'
153 self
._cmd
+= ' \"' + arg4
+ '\"'
155 self
._cmd
+= ' \"' + arg5
+ '\"'
157 self
._cmd
+= ' \"' + arg6
+ '\"'
159 self
._cmd
+= ' \"' + arg7
+ '\"'
161 self
._cmd
+= ' \"' + arg8
+ '\"'
163 self
._cmd
+= ' \"' + arg9
+ '\"'
165 self
._stdOutReader
= None
166 self
._stdErrReader
= None
168 DebuggerService
.executors
.append(self
)
170 def OutCall(self
, text
):
171 evt
= UpdateTextEvent(value
= text
)
172 wx
.PostEvent(self
._wxComponent
, evt
)
174 def ErrCall(self
, text
):
175 evt
= UpdateErrorEvent(value
= text
)
176 wx
.PostEvent(self
._wxComponent
, evt
)
178 def Execute(self
, arguments
, startIn
=None, environment
=None):
180 startIn
= str(os
.getcwd())
181 startIn
= os
.path
.abspath(startIn
)
182 command
= self
._cmd
+ ' ' + arguments
183 #stdinput = process.IOBuffer()
184 #self._process = process.ProcessProxy(command, mode='b', cwd=startIn, stdin=stdinput)
185 self
._process
= process
.ProcessOpen(command
, mode
='b', cwd
=startIn
, env
=environment
)
186 # Kick off threads to read stdout and stderr and write them
187 # to our text control.
188 self
._stdOutReader
= OutputReaderThread(self
._process
.stdout
, self
._stdOutCallback
, callbackOnExit
=self
._callbackOnExit
)
189 self
._stdOutReader
.start()
190 self
._stdErrReader
= OutputReaderThread(self
._process
.stderr
, self
._stdErrCallback
, accumulate
=False)
191 self
._stdErrReader
.start()
194 def DoStopExecution(self
):
195 if(self
._process
!= None):
197 self
._process
.close()
199 if(self
._stdOutReader
!= None):
200 self
._stdOutReader
.AskToStop()
201 if(self
._stdErrReader
!= None):
202 self
._stdErrReader
.AskToStop()
203 DebuggerService
.executors
.remove(self
)
205 class RunCommandUI(wx
.Panel
):
207 def __init__(self
, parent
, id, fileName
):
208 wx
.Panel
.__init
__(self
, parent
, id)
209 self
._noteBook
= parent
211 self
.KILL_PROCESS_ID
= wx
.NewId()
212 self
.CLOSE_TAB_ID
= wx
.NewId()
214 self
.Bind(wx
.EVT_END_PROCESS
, self
.OnProcessEnded
)
216 # GUI Initialization follows
217 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
218 self
._tb
= tb
= wx
.ToolBar(self
, -1, wx
.DefaultPosition
, (30,1000), wx
.TB_VERTICAL| wx
.TB_FLAT
, "Runner" )
219 tb
.SetToolBitmapSize((16,16))
220 sizer
.Add(tb
, 0, wx
.EXPAND |wx
.ALIGN_LEFT|wx
.ALL
, 1)
222 close_bmp
= getCloseBitmap()
223 tb
.AddSimpleTool( self
.CLOSE_TAB_ID
, close_bmp
, _('Close Window'))
224 wx
.EVT_TOOL(self
, self
.CLOSE_TAB_ID
, self
.OnToolClicked
)
226 stop_bmp
= getStopBitmap()
227 tb
.AddSimpleTool(self
.KILL_PROCESS_ID
, stop_bmp
, _("Stop the Run."))
228 wx
.EVT_TOOL(self
, self
.KILL_PROCESS_ID
, self
.OnToolClicked
)
231 self
._textCtrl
= STCTextEditor
.TextCtrl(self
, wx
.NewId()) #id)
232 sizer
.Add(self
._textCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
233 self
._textCtrl
.SetViewLineNumbers(False)
234 self
._textCtrl
.SetReadOnly(True)
235 if wx
.Platform
== '__WXMSW__':
239 self
._textCtrl
.SetFont(wx
.Font(9, wx
.DEFAULT
, wx
.NORMAL
, wx
.NORMAL
, faceName
= font
))
240 self
._textCtrl
.SetFontColor(wx
.BLACK
)
241 self
._textCtrl
.StyleClearAll()
243 #Disabling for now...may interfere with file open. wx.stc.EVT_STC_DOUBLECLICK(self._textCtrl, self._textCtrl.GetId(), self.OnDoubleClick)
248 # Executor initialization
249 self
._executor
= Executor(fileName
, self
, callbackOnExit
=self
.ExecutorFinished
)
250 self
.Bind(EVT_UPDATE_STDTEXT
, self
.AppendText
)
251 self
.Bind(EVT_UPDATE_ERRTEXT
, self
.AppendErrorText
)
254 self
._executor
.DoStopExecution()
256 def Execute(self
, initialArgs
, startIn
, environment
):
257 self
._executor
.Execute(initialArgs
, startIn
, environment
)
259 def ExecutorFinished(self
):
260 self
._tb
.EnableTool(self
.KILL_PROCESS_ID
, False)
261 nb
= self
.GetParent()
262 for i
in range(0,nb
.GetPageCount()):
263 if self
== nb
.GetPage(i
):
264 text
= nb
.GetPageText(i
)
265 newText
= text
.replace("Running", "Finished")
266 nb
.SetPageText(i
, newText
)
269 def StopExecution(self
):
270 self
.Unbind(EVT_UPDATE_STDTEXT
)
271 self
.Unbind(EVT_UPDATE_ERRTEXT
)
272 self
._executor
.DoStopExecution()
274 def AppendText(self
, event
):
275 self
._textCtrl
.SetReadOnly(False)
276 self
._textCtrl
.AddText(event
.value
)
277 self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount())
278 self
._textCtrl
.SetReadOnly(True)
280 def AppendErrorText(self
, event
):
281 self
._textCtrl
.SetReadOnly(False)
282 self
._textCtrl
.SetFontColor(wx
.RED
)
283 self
._textCtrl
.StyleClearAll()
284 self
._textCtrl
.AddText(event
.value
)
285 self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount())
286 self
._textCtrl
.SetFontColor(wx
.BLACK
)
287 self
._textCtrl
.StyleClearAll()
288 self
._textCtrl
.SetReadOnly(True)
290 #------------------------------------------------------------------------------
292 #-----------------------------------------------------------------------------
294 def OnToolClicked(self
, event
):
297 if id == self
.KILL_PROCESS_ID
:
298 self
._executor
.DoStopExecution()
300 elif id == self
.CLOSE_TAB_ID
:
301 self
._executor
.DoStopExecution()
302 index
= self
._noteBook
.GetSelection()
303 self
._noteBook
.GetPage(index
).Show(False)
304 self
._noteBook
.RemovePage(index
)
306 def OnDoubleClick(self
, event
):
307 # Looking for a stack trace line.
308 lineText
, pos
= self
._textCtrl
.GetCurLine()
309 fileBegin
= lineText
.find("File \"")
310 fileEnd
= lineText
.find("\", line ")
311 lineEnd
= lineText
.find(", in ")
312 if lineText
== "\n" or fileBegin
== -1 or fileEnd
== -1 or lineEnd
== -1:
313 # Check the line before the one that was clicked on
314 lineNumber
= self
._textCtrl
.GetCurrentLine()
317 lineText
= self
._textCtrl
.GetLine(lineNumber
- 1)
318 fileBegin
= lineText
.find("File \"")
319 fileEnd
= lineText
.find("\", line ")
320 lineEnd
= lineText
.find(", in ")
321 if lineText
== "\n" or fileBegin
== -1 or fileEnd
== -1 or lineEnd
== -1:
324 filename
= lineText
[fileBegin
+ 6:fileEnd
]
325 lineNum
= int(lineText
[fileEnd
+ 8:lineEnd
])
328 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
329 for openDoc
in openDocs
:
330 if openDoc
.GetFilename() == filename
:
331 foundView
= openDoc
.GetFirstView()
335 doc
= wx
.GetApp().GetDocumentManager().CreateDocument(filename
, wx
.lib
.docview
.DOC_SILENT
)
336 foundView
= doc
.GetFirstView()
339 foundView
.GetFrame().SetFocus()
341 foundView
.GotoLine(lineNum
)
342 startPos
= foundView
.PositionFromLine(lineNum
)
344 # FACTOR THIS INTO DocManager
345 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
346 for openDoc
in openDocs
:
347 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
348 openDoc
.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
350 foundView
.GetCtrl().MarkerAdd(lineNum
-1, CodeEditor
.CodeCtrl
.CURRENT_LINE_MARKER_NUM
)
352 def OnProcessEnded(self
, evt
):
353 self
._executor
.DoStopExecution()
356 DEFAULT_HOST
= 'localhost'
359 class DebugCommandUI(wx
.Panel
):
360 debuggerPortList
= None
363 def NotifyDebuggersOfBreakpointChange():
364 for debugger
in DebugCommandUI
.debuggers
:
365 debugger
.BreakPointChange()
367 NotifyDebuggersOfBreakpointChange
= staticmethod(NotifyDebuggersOfBreakpointChange
)
369 def DebuggerRunning():
370 for debugger
in DebugCommandUI
.debuggers
:
371 if debugger
._executor
:
374 DebuggerRunning
= staticmethod(DebuggerRunning
)
376 def ShutdownAllDebuggers():
377 for debugger
in DebugCommandUI
.debuggers
:
378 debugger
.StopExecution(None)
380 ShutdownAllDebuggers
= staticmethod(ShutdownAllDebuggers
)
382 def GetAvailablePort():
383 for index
in range( 0, len(DebugCommandUI
.debuggerPortList
)):
384 port
= DebugCommandUI
.debuggerPortList
[index
]
385 if DebugCommandUI
.PortAvailable(port
):
386 DebugCommandUI
.debuggerPortList
.pop(index
)
388 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"))
389 assert False, "Out of ports for debugger."
391 GetAvailablePort
= staticmethod(GetAvailablePort
)
393 def ReturnPortToPool(port
):
394 config
= wx
.ConfigBase_Get()
395 startingPort
= config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
)
396 if port
in range(startingPort
, startingPort
+ PORT_COUNT
):
397 DebugCommandUI
.debuggerPortList
.append(port
)
399 ReturnPortToPool
= staticmethod(ReturnPortToPool
)
401 def PortAvailable(port
):
402 config
= wx
.ConfigBase_Get()
403 hostname
= config
.Read("DebuggerHostName", DEFAULT_HOST
)
405 server
= AGXMLRPCServer((hostname
, port
))
406 server
.server_close()
407 if _VERBOSE
: print "Port ", str(port
), " available."
410 tp
,val
,tb
= sys
.exc_info()
411 if _VERBOSE
: traceback
.print_exception(tp
, val
, tb
)
412 if _VERBOSE
: print "Port ", str(port
), " unavailable."
415 PortAvailable
= staticmethod(PortAvailable
)
418 config
= wx
.ConfigBase_Get()
419 startingPort
= config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
)
420 DebugCommandUI
.debuggerPortList
= range(startingPort
, startingPort
+ PORT_COUNT
)
421 NewPortRange
= staticmethod(NewPortRange
)
423 def __init__(self
, parent
, id, command
, service
):
424 # Check for ports before creating the panel.
425 if not DebugCommandUI
.debuggerPortList
:
426 DebugCommandUI
.NewPortRange()
427 self
._debuggerPort
= str(DebugCommandUI
.GetAvailablePort())
428 self
._guiPort
= str(DebugCommandUI
.GetAvailablePort())
429 self
._debuggerBreakPort
= str(DebugCommandUI
.GetAvailablePort())
431 wx
.Panel
.__init
__(self
, parent
, id)
433 self
._parentNoteBook
= parent
434 self
._command
= command
435 self
._service
= service
436 self
._executor
= None
437 self
.STEP_ID
= wx
.NewId()
438 self
.CONTINUE_ID
= wx
.NewId()
439 self
.STEP_OUT_ID
= wx
.NewId()
440 self
.NEXT_ID
= wx
.NewId()
441 self
.KILL_PROCESS_ID
= wx
.NewId()
442 self
.CLOSE_WINDOW_ID
= wx
.NewId()
443 self
.BREAK_INTO_DEBUGGER_ID
= wx
.NewId()
444 self
.CLEAR_ID
= wx
.NewId()
445 self
.ADD_WATCH_ID
= wx
.NewId()
446 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
447 self
._tb
= tb
= wx
.ToolBar(self
, -1, wx
.DefaultPosition
, (1000,30), wx
.TB_HORIZONTAL| wx
.NO_BORDER| wx
.TB_FLAT| wx
.TB_TEXT
, "Debugger" )
448 sizer
.Add(tb
, 0, wx
.EXPAND |wx
.ALIGN_LEFT|wx
.ALL
, 1)
449 tb
.SetToolBitmapSize((16,16))
451 close_bmp
= getCloseBitmap()
452 tb
.AddSimpleTool( self
.CLOSE_WINDOW_ID
, close_bmp
, _('Close Window'))
453 wx
.EVT_TOOL(self
, self
.CLOSE_WINDOW_ID
, self
.StopAndRemoveUI
)
455 stop_bmp
= getStopBitmap()
456 tb
.AddSimpleTool( self
.KILL_PROCESS_ID
, stop_bmp
, _("Stop Debugging"))
457 wx
.EVT_TOOL(self
, self
.KILL_PROCESS_ID
, self
.StopExecution
)
461 break_bmp
= getBreakBitmap()
462 tb
.AddSimpleTool( self
.BREAK_INTO_DEBUGGER_ID
, break_bmp
, _("Break into Debugger"))
463 wx
.EVT_TOOL(self
, self
.BREAK_INTO_DEBUGGER_ID
, self
.BreakExecution
)
467 continue_bmp
= getContinueBitmap()
468 tb
.AddSimpleTool( self
.CONTINUE_ID
, continue_bmp
, _("Continue Execution"))
469 wx
.EVT_TOOL(self
, self
.CONTINUE_ID
, self
.OnContinue
)
473 next_bmp
= getNextBitmap()
474 tb
.AddSimpleTool( self
.NEXT_ID
, next_bmp
, _("Step to next line"))
475 wx
.EVT_TOOL(self
, self
.NEXT_ID
, self
.OnNext
)
477 step_bmp
= getStepInBitmap()
478 tb
.AddSimpleTool( self
.STEP_ID
, step_bmp
, _("Step in"))
479 wx
.EVT_TOOL(self
, self
.STEP_ID
, self
.OnSingleStep
)
481 stepOut_bmp
= getStepReturnBitmap()
482 tb
.AddSimpleTool(self
.STEP_OUT_ID
, stepOut_bmp
, _("Stop at function return"))
483 wx
.EVT_TOOL(self
, self
.STEP_OUT_ID
, self
.OnStepOut
)
487 watch_bmp
= getAddWatchBitmap()
488 tb
.AddSimpleTool(self
.ADD_WATCH_ID
, watch_bmp
, _("Add a watch"))
489 wx
.EVT_TOOL(self
, self
.ADD_WATCH_ID
, self
.OnAddWatch
)
492 clear_bmp
= getClearOutputBitmap()
493 tb
.AddSimpleTool(self
.CLEAR_ID
, clear_bmp
, _("Clear output pane"))
494 wx
.EVT_TOOL(self
, self
.CLEAR_ID
, self
.OnClearOutput
)
496 self
.framesTab
= None
497 self
.DisableWhileDebuggerRunning()
498 self
.framesTab
= self
.MakeFramesUI(self
, wx
.NewId(), None)
499 sizer
.Add(self
.framesTab
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
500 self
._statusBar
= wx
.StatusBar( self
, -1)
501 self
._statusBar
.SetFieldsCount(1)
502 sizer
.Add(self
._statusBar
, 0, wx
.EXPAND |wx
.ALIGN_LEFT|wx
.ALL
, 1)
504 self
.SetStatusText("Starting debug...")
509 config
= wx
.ConfigBase_Get()
510 self
._debuggerHost
= self
._guiHost
= config
.Read("DebuggerHostName", DEFAULT_HOST
)
511 url
= 'http://' + self
._debuggerHost
+ ':' + self
._debuggerPort
+ '/'
512 self
._breakURL
= 'http://' + self
._debuggerHost
+ ':' + self
._debuggerBreakPort
+ '/'
513 self
._callback
= DebuggerCallback(self
._guiHost
, self
._guiPort
, url
, self
._breakURL
, self
)
514 if DebuggerHarness
.__file
__.find('library.zip') > 0:
516 fname
= DebuggerHarness
.__file
__
517 parts
= fname
.split('library.zip')
518 path
= os
.path
.join(parts
[0],'activegrid', 'tool', 'DebuggerHarness.py')
520 tp
, val
, tb
= sys
.exc_info()
521 traceback
.print_exception(tp
, val
, tb
)
524 print "Starting debugger on these ports: %s, %s, %s" % (str(self
._debuggerPort
) , str(self
._guiPort
) , str(self
._debuggerBreakPort
))
525 path
= DebuggerService
.ExpandPath(DebuggerHarness
.__file
__)
526 self
._executor
= Executor(path
, self
, self
._debuggerHost
, \
527 self
._debuggerPort
, self
._debuggerBreakPort
, self
._guiHost
, self
._guiPort
, self
._command
, callbackOnExit
=self
.ExecutorFinished
)
529 self
.Bind(EVT_UPDATE_STDTEXT
, self
.AppendText
)
530 self
.Bind(EVT_UPDATE_ERRTEXT
, self
.AppendErrorText
)
531 DebugCommandUI
.debuggers
.append(self
)
532 self
._stopped
= False
534 def OnSingleStep(self
, event
):
535 self
._callback
.SingleStep()
537 def OnContinue(self
, event
):
538 self
._callback
.Continue()
540 def OnStepOut(self
, event
):
541 self
._callback
.Return()
543 def OnNext(self
, event
):
544 self
._callback
.Next()
546 def BreakPointChange(self
):
547 if not self
._stopped
:
548 self
._callback
.pushBreakpoints()
549 self
.framesTab
.PopulateBPList()
552 if self
in DebugCommandUI
.debuggers
:
553 DebugCommandUI
.debuggers
.remove(self
)
556 def DisableWhileDebuggerRunning(self
):
557 self
._tb
.EnableTool(self
.STEP_ID
, False)
558 self
._tb
.EnableTool(self
.CONTINUE_ID
, False)
559 self
._tb
.EnableTool(self
.STEP_OUT_ID
, False)
560 self
._tb
.EnableTool(self
.NEXT_ID
, False)
561 self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, True)
563 self
._tb
.EnableTool(self
.ADD_WATCH_ID
, False)
564 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
565 for openDoc
in openDocs
:
566 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
567 openDoc
.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
569 self
.framesTab
.ClearWhileRunning()
571 def EnableWhileDebuggerStopped(self
):
572 self
._tb
.EnableTool(self
.STEP_ID
, True)
573 self
._tb
.EnableTool(self
.CONTINUE_ID
, True)
574 self
._tb
.EnableTool(self
.STEP_OUT_ID
, True)
575 self
._tb
.EnableTool(self
.NEXT_ID
, True)
577 self
._tb
.EnableTool(self
.ADD_WATCH_ID
, True)
578 self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, False)
580 def ExecutorFinished(self
):
581 if _VERBOSE
: print "In ExectorFinished"
583 self
.DisableAfterStop()
584 except wx
._core
.PyDeadObjectError
:
587 nb
= self
.GetParent()
588 for i
in range(0, nb
.GetPageCount()):
589 if self
== nb
.GetPage(i
):
590 text
= nb
.GetPageText(i
)
591 newText
= text
.replace("Debugging", "Finished")
592 nb
.SetPageText(i
, newText
)
593 if _VERBOSE
: print "In ExectorFinished, changed tab title."
596 if _VERBOSE
: print "In ExectorFinished, got exception"
598 def DisableAfterStop(self
):
599 self
.DisableWhileDebuggerRunning()
600 self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, False)
601 self
._tb
.EnableTool(self
.KILL_PROCESS_ID
, False)
603 def SynchCurrentLine(self
, filename
, lineNum
):
604 # FACTOR THIS INTO DocManager
605 self
.DeleteCurrentLineMarkers()
607 # Filename will be <string> if we're in a bit of code that was executed from
608 # a string (rather than a file). I haven't been able to get the original string
610 if filename
== '<string>':
613 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
614 for openDoc
in openDocs
:
615 # This ugliness to prevent comparison failing because the drive letter
616 # gets lowercased occasionally. Don't know why that happens or why it
617 # only happens occasionally.
618 if DebuggerService
.ComparePaths(openDoc
.GetFilename(),filename
):
619 foundView
= openDoc
.GetFirstView()
624 print "filename=", filename
625 doc
= wx
.GetApp().GetDocumentManager().CreateDocument(DebuggerService
.ExpandPath(filename
), wx
.lib
.docview
.DOC_SILENT
)
626 foundView
= doc
.GetFirstView()
629 foundView
.GetFrame().SetFocus()
631 foundView
.GotoLine(lineNum
)
632 startPos
= foundView
.PositionFromLine(lineNum
)
634 foundView
.GetCtrl().MarkerAdd(lineNum
-1, CodeEditor
.CodeCtrl
.CURRENT_LINE_MARKER_NUM
)
636 def DeleteCurrentLineMarkers(self
):
637 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
638 for openDoc
in openDocs
:
639 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
640 openDoc
.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
642 def LoadFramesListXML(self
, framesXML
):
643 self
.framesTab
.LoadFramesListXML(framesXML
)
645 def SetStatusText(self
, text
):
646 self
._statusBar
.SetStatusText(text
,0)
648 def Execute(self
, initialArgs
, startIn
, environment
):
649 self
._callback
.start()
650 self
._executor
.Execute(initialArgs
, startIn
, environment
)
651 self
._callback
.waitForRPC()
653 def BreakExecution(self
, event
):
654 self
._callback
.BreakExecution()
657 def StopExecution(self
, event
):
659 self
.DisableAfterStop()
661 self
._callback
.ServerClose()
666 self
._executor
.DoStopExecution()
667 self
._executor
= None
670 self
.DeleteCurrentLineMarkers()
671 DebugCommandUI
.ReturnPortToPool(self
._debuggerPort
)
672 DebugCommandUI
.ReturnPortToPool(self
._guiPort
)
673 DebugCommandUI
.ReturnPortToPool(self
._debuggerBreakPort
)
675 def StopAndRemoveUI(self
, event
):
676 self
.StopExecution(None)
677 if self
in DebugCommandUI
.debuggers
:
678 DebugCommandUI
.debuggers
.remove(self
)
679 index
= self
._parentNoteBook
.GetSelection()
680 self
._parentNoteBook
.GetPage(index
).Show(False)
681 self
._parentNoteBook
.RemovePage(index
)
683 def OnAddWatch(self
, event
):
685 self
.framesTab
.OnWatch(event
)
687 def MakeFramesUI(self
, parent
, id, debugger
):
688 panel
= FramesUI(parent
, id, self
)
691 def AppendText(self
, event
):
692 self
.framesTab
.AppendText(event
.value
)
694 def AppendErrorText(self
, event
):
695 self
.framesTab
.AppendErrorText(event
.value
)
697 def OnClearOutput(self
, event
):
698 self
.framesTab
.ClearOutput()
700 def SwitchToOutputTab(self
):
701 self
.framesTab
.SwitchToOutputTab()
703 class BreakpointsUI(wx
.Panel
):
704 def __init__(self
, parent
, id, ui
):
705 wx
.Panel
.__init
__(self
, parent
, id)
707 self
.currentItem
= None
708 self
.clearBPID
= wx
.NewId()
709 self
.Bind(wx
.EVT_MENU
, self
.ClearBreakPoint
, id=self
.clearBPID
)
710 self
.syncLineID
= wx
.NewId()
711 self
.Bind(wx
.EVT_MENU
, self
.SyncBPLine
, id=self
.syncLineID
)
712 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
714 self
._bpListCtrl
= wx
.ListCtrl(p1
, -1, pos
=wx
.DefaultPosition
, size
=(1000,1000), style
=wx
.LC_REPORT
)
715 sizer
.Add(self
._bpListCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
716 self
._bpListCtrl
.InsertColumn(0, "File")
717 self
._bpListCtrl
.InsertColumn(1, "Line")
718 self
._bpListCtrl
.InsertColumn(2, "Path")
719 self
._bpListCtrl
.SetColumnWidth(0, 150)
720 self
._bpListCtrl
.SetColumnWidth(1, 50)
721 self
._bpListCtrl
.SetColumnWidth(2, 450)
722 self
._bpListCtrl
.Bind(wx
.EVT_LIST_ITEM_RIGHT_CLICK
, self
.OnListRightClick
)
723 self
.Bind(wx
.EVT_LIST_ITEM_SELECTED
, self
.ListItemSelected
, self
._bpListCtrl
)
724 self
.Bind(wx
.EVT_LIST_ITEM_DESELECTED
, self
.ListItemDeselected
, self
._bpListCtrl
)
726 def OnLeftDoubleClick(event
):
727 self
.SyncBPLine(event
)
729 wx
.EVT_LEFT_DCLICK(self
._bpListCtrl
, OnLeftDoubleClick
)
731 self
.PopulateBPList()
737 def PopulateBPList(self
):
738 list = self
._bpListCtrl
739 list.DeleteAllItems()
741 bps
= wx
.GetApp().GetService(DebuggerService
).GetMasterBreakpointDict()
743 for fileName
in bps
.keys():
744 shortFile
= os
.path
.basename(fileName
)
745 lines
= bps
[fileName
]
748 list.InsertStringItem(index
, shortFile
)
749 list.SetStringItem(index
, 1, str(line
))
750 list.SetStringItem(index
, 2, fileName
)
752 def OnListRightClick(self
, event
):
754 item
= wx
.MenuItem(menu
, self
.clearBPID
, "Clear Breakpoint")
755 menu
.AppendItem(item
)
756 item
= wx
.MenuItem(menu
, self
.syncLineID
, "Goto Source Line")
757 menu
.AppendItem(item
)
758 self
.PopupMenu(menu
, event
.GetPosition())
761 def SyncBPLine(self
, event
):
762 if self
.currentItem
!= -1:
763 list = self
._bpListCtrl
764 fileName
= list.GetItem(self
.currentItem
, 2).GetText()
765 lineNumber
= list.GetItem(self
.currentItem
, 1).GetText()
766 self
._ui
.SynchCurrentLine( fileName
, int(lineNumber
) )
768 def ClearBreakPoint(self
, event
):
769 if self
.currentItem
>= 0:
770 list = self
._bpListCtrl
771 fileName
= list.GetItem(self
.currentItem
, 2).GetText()
772 lineNumber
= list.GetItem(self
.currentItem
, 1).GetText()
773 wx
.GetApp().GetService(DebuggerService
).OnToggleBreakpoint(None, line
=int(lineNumber
) -1, fileName
=fileName
)
775 def ListItemSelected(self
, event
):
776 self
.currentItem
= event
.m_itemIndex
778 def ListItemDeselected(self
, event
):
779 self
.currentItem
= -1
787 def __init__(self
, name
, command
, show_code
=CODE_ALL_FRAMES
):
789 self
._command
= command
790 self
._show
_code
= show_code
792 class WatchDialog(wx
.Dialog
):
793 WATCH_ALL_FRAMES
= "Watch in all frames"
794 WATCH_THIS_FRAME
= "Watch in this frame only"
795 WATCH_ONCE
= "Watch once and delete"
796 def __init__(self
, parent
, title
, chain
):
797 wx
.Dialog
.__init
__(self
, parent
, -1, title
, style
=wx
.DEFAULT_DIALOG_STYLE
)
799 self
.label_2
= wx
.StaticText(self
, -1, "Watch Name:")
800 self
._watchNameTextCtrl
= wx
.TextCtrl(self
, -1, "")
801 self
.label_3
= wx
.StaticText(self
, -1, "eval(", style
=wx
.ALIGN_RIGHT
)
802 self
._watchValueTextCtrl
= wx
.TextCtrl(self
, -1, "")
803 self
.label_4
= wx
.StaticText(self
, -1, ",frame.f_globals, frame.f_locals)")
804 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
)
806 self
._okButton
= wx
.Button(self
, wx
.ID_OK
, "OK", size
=(75,-1))
807 self
._okButton
.SetDefault()
808 self
._okButton
.SetHelpText(_("The OK button completes the dialog"))
809 def OnOkClick(event
):
810 if self
._watchNameTextCtrl
.GetValue() == "":
811 wx
.MessageBox(_("You must enter a name for the watch."), _("Add Watch"))
813 if self
._watchValueTextCtrl
.GetValue() == "":
814 wx
.MessageBox(_("You must enter some code to run for the watch."), _("Add Watch"))
816 self
.EndModal(wx
.ID_OK
)
817 self
.Bind(wx
.EVT_BUTTON
, OnOkClick
, self
._okButton
)
819 self
._cancelButton
= wx
.Button(self
, wx
.ID_CANCEL
, _("Cancel"), size
=(75,-1))
820 self
._cancelButton
.SetHelpText(_("The Cancel button cancels the dialog."))
822 self
.__set
_properties
()
825 def GetSettings(self
):
826 return self
._watchNameTextCtrl
.GetValue(), self
._watchValueTextCtrl
.GetValue(), self
.GetSendFrame(), self
.GetRunOnce()
828 def GetSendFrame(self
):
829 return (WatchDialog
.WATCH_ALL_FRAMES
!= self
.radio_box_1
.GetStringSelection())
831 def GetRunOnce(self
):
832 return (WatchDialog
.WATCH_ONCE
== self
.radio_box_1
.GetStringSelection())
834 def __set_properties(self
):
835 self
.SetTitle("Add a Watch")
836 #self.SetSize((400, 250))
837 self
.radio_box_1
.SetSelection(0)
839 def __do_layout(self
):
840 sizer_1
= wx
.BoxSizer(wx
.VERTICAL
)
841 grid_sizer_4
= wx
.FlexGridSizer(1, 3, 5, 5)
842 grid_sizer_2
= wx
.FlexGridSizer(1, 2, 5, 5)
843 grid_sizer_2
.Add(self
.label_2
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0)
844 grid_sizer_2
.Add(self
._watchNameTextCtrl
, 0, wx
.EXPAND
, 0)
845 grid_sizer_2
.AddGrowableCol(1)
846 sizer_1
.Add(grid_sizer_2
, 1, wx
.EXPAND
, 0)
847 grid_sizer_4
.Add(self
.label_3
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0)
848 grid_sizer_4
.Add(self
._watchValueTextCtrl
, 0, wx
.EXPAND
, 0)
849 grid_sizer_4
.AddGrowableCol(1)
850 grid_sizer_4
.Add(self
.label_4
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0)
851 sizer_1
.Add(grid_sizer_4
, 0, wx
.EXPAND
, 0)
852 sizer_1
.Add(self
.radio_box_1
, 0, wx
.EXPAND
, 0)
854 box
= wx
.BoxSizer(wx
.HORIZONTAL
)
855 box
.Add(self
._okButton
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5)
856 box
.Add(self
._cancelButton
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5)
857 sizer_1
.Add(box
, 1, wx
.EXPAND
, 0)
858 self
.SetAutoLayout(True)
859 self
.SetSizer(sizer_1
)
862 class FramesUI(wx
.SplitterWindow
):
863 def __init__(self
, parent
, id, ui
):
864 wx
.SplitterWindow
.__init
__(self
, parent
, id, style
= wx
.SP_3D
)
866 self
._p
1 = p1
= wx
.ScrolledWindow(self
, -1)
868 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
869 framesLabel
= wx
.StaticText(self
, -1, "Stack Frame:")
870 sizer
.Add(framesLabel
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT|wx
.LEFT
, border
=2)
872 self
._framesChoiceCtrl
= wx
.Choice(p1
, -1, choices
=[" "])
873 sizer
.Add(self
._framesChoiceCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
874 self
._framesChoiceCtrl
.Bind(wx
.EVT_LIST_ITEM_RIGHT_CLICK
, self
.OnListRightClick
)
875 self
.Bind(wx
.EVT_CHOICE
, self
.ListItemSelected
, self
._framesChoiceCtrl
)
877 sizer2
= wx
.BoxSizer(wx
.VERTICAL
)
880 self
._treeCtrl
= wx
.gizmos
.TreeListCtrl(p1
, -1, style
=wx
.TR_DEFAULT_STYLE| wx
.TR_FULL_ROW_HIGHLIGHT
)
881 self
._treeCtrl
.Bind(wx
.EVT_TREE_ITEM_RIGHT_CLICK
, self
.OnRightClick
)
882 sizer2
.Add(sizer
, 0, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
883 sizer2
.Add(self
._treeCtrl
,1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
884 tree
= self
._treeCtrl
885 tree
.AddColumn("Thing")
886 tree
.AddColumn("Value")
887 tree
.SetMainColumn(0) # the one with the tree in it...
888 tree
.SetColumnWidth(0, 175)
889 tree
.SetColumnWidth(1, 355)
890 self
._root
= tree
.AddRoot("Frame")
891 tree
.SetItemText(self
._root
, "", 1)
892 tree
.Bind(wx
.EVT_TREE_ITEM_EXPANDING
, self
.IntrospectCallback
)
894 self
._p
2 = p2
= wx
.Window(self
, -1)
895 sizer3
= wx
.BoxSizer(wx
.HORIZONTAL
)
897 p2
.Bind(wx
.EVT_SIZE
, self
.OnSize
)
898 self
._notebook
= wx
.Notebook(p2
, -1, size
=(20,20))
899 self
._notebook
.Hide()
900 sizer3
.Add(self
._notebook
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1)
901 self
.consoleTab
= self
.MakeConsoleTab(self
._notebook
, wx
.NewId())
902 #self.inspectConsoleTab = self.MakeInspectConsoleTab(self._notebook, wx.NewId())
903 self
.breakPointsTab
= self
.MakeBreakPointsTab(self
._notebook
, wx
.NewId())
904 self
._notebook
.AddPage(self
.consoleTab
, "Output")
905 #self._notebook.AddPage(self.inspectConsoleTab, "Interact")
906 self
._notebook
.AddPage(self
.breakPointsTab
, "Break Points")
908 self
.SetMinimumPaneSize(20)
909 self
.SplitVertically(p1
, p2
, 550)
910 self
.currentItem
= None
911 self
._notebook
.Show(True)
913 def PopulateBPList(self
):
914 self
.breakPointsTab
.PopulateBPList()
916 def OnSize(self
, event
):
917 self
._notebook
.SetSize(self
._p
2.GetSize())
919 def MakeConsoleTab(self
, parent
, id):
920 panel
= wx
.Panel(parent
, id)
921 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
922 self
._textCtrl
= STCTextEditor
.TextCtrl(panel
, wx
.NewId())
923 sizer
.Add(self
._textCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 2)
924 self
._textCtrl
.SetViewLineNumbers(False)
925 self
._textCtrl
.SetReadOnly(True)
926 if wx
.Platform
== '__WXMSW__':
930 self
._textCtrl
.SetFont(wx
.Font(9, wx
.DEFAULT
, wx
.NORMAL
, wx
.NORMAL
, faceName
= font
))
931 self
._textCtrl
.SetFontColor(wx
.BLACK
)
932 self
._textCtrl
.StyleClearAll()
933 panel
.SetSizer(sizer
)
938 def MakeInspectConsoleTab(self
, parent
, id):
939 def OnEnterPressed(event
):
940 print "Enter text was %s" % event
.GetString()
942 print "Command was %s" % event
.GetString()
944 panel
= wx
.Panel(parent
, id)
946 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
947 self
._ictextCtrl
= wx
.TextCtrl(panel
, wx
.NewId(), style
=wx
.TE_MULTILINE|wx
.TE_RICH|wx
.HSCROLL
)
948 sizer
.Add(self
._ictextCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 2)
949 self
._ictextCtrl
.Bind(wx
.EVT_TEXT_ENTER
, OnEnterPressed
)
950 self
._ictextCtrl
.Bind(wx
.EVT_TEXT
, OnText
)
951 if wx
.Platform
== '__WXMSW__':
955 self
._ictextCtrl
.SetDefaultStyle(wx
.TextAttr(font
=wx
.Font(9, wx
.DEFAULT
, wx
.NORMAL
, wx
.NORMAL
, faceName
= font
)))
956 panel
.SetSizer(sizer
)
958 tp
, val
, tb
= sys
.exc_info()
959 traceback
.print_exception(tp
, val
, tb
)
963 def MakeBreakPointsTab(self
, parent
, id):
964 panel
= BreakpointsUI(parent
, id, self
._ui
)
967 def OnRightClick(self
, event
):
969 self
._introspectItem
= event
.GetItem()
970 self
._parentChain
= self
.GetItemChain(event
.GetItem())
971 watchOnly
= len(self
._parentChain
) < 1
972 if not _WATCHES_ON
and watchOnly
:
976 if not hasattr(self
, "watchID"):
977 self
.watchID
= wx
.NewId()
978 self
.Bind(wx
.EVT_MENU
, self
.OnWatch
, id=self
.watchID
)
979 item
= wx
.MenuItem(menu
, self
.watchID
, "Create a Watch")
980 menu
.AppendItem(item
)
981 menu
.AppendSeparator()
983 if not hasattr(self
, "viewID"):
984 self
.viewID
= wx
.NewId()
985 self
.Bind(wx
.EVT_MENU
, self
.OnView
, id=self
.viewID
)
986 item
= wx
.MenuItem(menu
, self
.viewID
, "View in Dialog")
987 menu
.AppendItem(item
)
988 offset
= wx
.Point(x
=0, y
=20)
989 menuSpot
= event
.GetPoint() + offset
990 self
._treeCtrl
.PopupMenu(menu
, menuSpot
)
992 self
._parentChain
= None
993 self
._introspectItem
= None
995 def GetItemChain(self
, item
):
998 if _VERBOSE
: print 'Exploding: %s' % self
._treeCtrl
.GetItemText(item
, 0)
999 while item
!= self
._root
:
1000 text
= self
._treeCtrl
.GetItemText(item
, 0)
1001 if _VERBOSE
: print "Appending ", text
1002 parentChain
.append(text
)
1003 item
= self
._treeCtrl
.GetItemParent(item
)
1004 parentChain
.reverse()
1007 def OnView(self
, event
):
1008 title
= self
._treeCtrl
.GetItemText(self
._introspectItem
,0)
1009 value
= self
._treeCtrl
.GetItemText(self
._introspectItem
,1)
1010 dlg
= wx
.lib
.dialogs
.ScrolledMessageDialog(self
, value
, title
, style
=wx
.DD_DEFAULT_STYLE | wx
.RESIZE_BORDER
)
1013 def OnWatch(self
, event
):
1015 if hasattr(self
, '_parentChain'):
1016 wd
= WatchDialog(wx
.GetApp().GetTopWindow(), "Add a Watch", self
._parentChain
)
1018 wd
= WatchDialog(wx
.GetApp().GetTopWindow(), "Add a Watch", None)
1019 if wd
.ShowModal() == wx
.ID_OK
:
1020 name
, text
, send_frame
, run_once
= wd
.GetSettings()
1022 frameNode
= self
._stack
[int(self
.currentItem
)]
1023 message
= frameNode
.getAttribute("message")
1026 binType
= self
._ui
._callback
._debuggerServer
.add_watch(name
, text
, message
, run_once
)
1027 xmldoc
= bz2
.decompress(binType
.data
)
1028 domDoc
= parseString(xmldoc
)
1029 nodeList
= domDoc
.getElementsByTagName('watch')
1030 if len(nodeList
) == 1:
1031 watchValue
= nodeList
.item(0).getAttribute("message")
1033 tp
, val
, tb
= sys
.exc_info()
1034 traceback
.print_exception(tp
, val
, tb
)
1036 def OnIntrospect(self
, event
):
1037 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
))
1040 list = self
._framesChoiceCtrl
1041 frameNode
= self
._stack
[int(self
.currentItem
)]
1042 message
= frameNode
.getAttribute("message")
1043 binType
= self
._ui
._callback
._debuggerServer
.attempt_introspection(message
, self
._parentChain
)
1044 xmldoc
= bz2
.decompress(binType
.data
)
1045 domDoc
= parseString(xmldoc
)
1046 #wx.MessageBox(xmldoc, "result of introspection")
1047 nodeList
= domDoc
.getElementsByTagName('replacement')
1048 replacementNode
= nodeList
.item(0)
1049 if len(replacementNode
.childNodes
):
1050 thingToWalk
= replacementNode
.childNodes
.item(0)
1051 tree
= self
._treeCtrl
1052 parent
= tree
.GetItemParent(self
._introspectItem
)
1053 treeNode
= self
.AppendSubTreeFromNode(thingToWalk
, thingToWalk
.getAttribute('name'), parent
, insertBefore
=self
._introspectItem
)
1054 self
._treeCtrl
.Expand(treeNode
)
1055 tree
.Delete(self
._introspectItem
)
1057 tp
,val
,tb
= sys
.exc_info()
1058 traceback
.print_exception(tp
, val
, tb
)
1060 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
))
1062 def ClearWhileRunning(self
):
1063 list = self
._framesChoiceCtrl
1066 tree
= self
._treeCtrl
1068 tree
.DeleteChildren(root
)
1072 def OnListRightClick(self
, event
):
1073 if not hasattr(self
, "syncFrameID"):
1074 self
.syncFrameID
= wx
.NewId()
1075 self
.Bind(wx
.EVT_MENU
, self
.OnSyncFrame
, id=self
.syncFrameID
)
1077 item
= wx
.MenuItem(menu
, self
.syncFrameID
, "Goto Source Line")
1078 menu
.AppendItem(item
)
1079 self
.PopupMenu(menu
, event
.GetPosition())
1082 def OnSyncFrame(self
, event
):
1083 list = self
._framesChoiceCtrl
1084 frameNode
= self
._stack
[int(self
.currentItem
)]
1085 file = frameNode
.getAttribute("file")
1086 line
= frameNode
.getAttribute("line")
1087 self
._ui
.SynchCurrentLine( file, int(line
) )
1089 def LoadFramesListXML(self
, framesXML
):
1090 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
))
1092 domDoc
= parseString(framesXML
)
1093 list = self
._framesChoiceCtrl
1096 nodeList
= domDoc
.getElementsByTagName('frame')
1098 for index
in range(0, nodeList
.length
):
1099 frameNode
= nodeList
.item(index
)
1100 message
= frameNode
.getAttribute("message")
1101 list.Append(message
)
1102 self
._stack
.append(frameNode
)
1104 index
= len(self
._stack
) - 1
1105 list.SetSelection(index
)
1106 node
= self
._stack
[index
]
1107 self
.currentItem
= index
1108 self
.PopulateTreeFromFrameNode(node
)
1109 self
.OnSyncFrame(None)
1111 self
._p
1.FitInside()
1112 frameNode
= nodeList
.item(index
)
1113 file = frameNode
.getAttribute("file")
1114 line
= frameNode
.getAttribute("line")
1115 self
._ui
.SynchCurrentLine( file, int(line
) )
1117 tp
,val
,tb
=sys
.exc_info()
1118 traceback
.print_exception(tp
, val
, tb
)
1120 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
))
1123 def ListItemSelected(self
, event
):
1124 message
= event
.GetString()
1126 for node
in self
._stack
:
1127 if node
.getAttribute("message") == message
:
1128 self
.currentItem
= index
1129 self
.PopulateTreeFromFrameNode(node
)
1130 self
.OnSyncFrame(None)
1134 def PopulateTreeFromFrameNode(self
, frameNode
):
1135 list = self
._framesChoiceCtrl
1137 tree
= self
._treeCtrl
1140 tree
.DeleteChildren(root
)
1141 children
= frameNode
.childNodes
1143 for index
in range(0, children
.length
):
1144 subNode
= children
.item(index
)
1145 treeNode
= self
.AppendSubTreeFromNode(subNode
, subNode
.getAttribute('name'), root
)
1147 firstChild
= treeNode
1149 tree
.Expand(firstChild
)
1150 self
._p
2.FitInside()
1152 def IntrospectCallback(self
, event
):
1153 tree
= self
._treeCtrl
1154 item
= event
.GetItem()
1156 print "In introspectCallback item is %s, pydata is %s" % (event
.GetItem(), tree
.GetPyData(item
))
1157 if tree
.GetPyData(item
) != "Introspect":
1160 self
._introspectItem
= item
1161 self
._parentChain
= self
.GetItemChain(item
)
1162 self
.OnIntrospect(event
)
1165 def AppendSubTreeFromNode(self
, node
, name
, parent
, insertBefore
=None):
1166 tree
= self
._treeCtrl
1167 if insertBefore
!= None:
1168 treeNode
= tree
.InsertItem(parent
, insertBefore
, name
)
1170 treeNode
= tree
.AppendItem(parent
, name
)
1171 children
= node
.childNodes
1172 intro
= node
.getAttribute('intro')
1175 tree
.SetItemHasChildren(treeNode
, True)
1176 tree
.SetPyData(treeNode
, "Introspect")
1177 if node
.getAttribute("value"):
1178 tree
.SetItemText(treeNode
, self
.StripOuterSingleQuotes(node
.getAttribute("value")), 1)
1179 for index
in range(0, children
.length
):
1180 subNode
= children
.item(index
)
1181 if self
.HasChildren(subNode
):
1182 self
.AppendSubTreeFromNode(subNode
, subNode
.getAttribute("name"), treeNode
)
1184 name
= subNode
.getAttribute("name")
1185 value
= self
.StripOuterSingleQuotes(subNode
.getAttribute("value"))
1186 n
= tree
.AppendItem(treeNode
, name
)
1187 tree
.SetItemText(n
, value
, 1)
1188 intro
= subNode
.getAttribute('intro')
1190 tree
.SetItemHasChildren(n
, True)
1191 tree
.SetPyData(n
, "Introspect")
1195 def StripOuterSingleQuotes(self
, string
):
1196 if string
.startswith("'") and string
.endswith("'"):
1197 retval
= string
[1:-1]
1198 elif string
.startswith("\"") and string
.endswith("\""):
1199 retval
= string
[1:-1]
1202 if retval
.startswith("u'") and retval
.endswith("'"):
1206 def HasChildren(self
, node
):
1208 return node
.childNodes
.length
> 0
1210 tp
,val
,tb
=sys
.exc_info()
1213 def AppendText(self
, text
):
1214 self
._textCtrl
.SetReadOnly(False)
1215 self
._textCtrl
.AddText(text
)
1216 self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount())
1217 self
._textCtrl
.SetReadOnly(True)
1219 def AppendErrorText(self
, text
):
1220 self
._textCtrl
.SetReadOnly(False)
1221 self
._textCtrl
.SetFontColor(wx
.RED
)
1222 self
._textCtrl
.StyleClearAll()
1223 self
._textCtrl
.AddText(text
)
1224 self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount())
1225 self
._textCtrl
.SetFontColor(wx
.BLACK
)
1226 self
._textCtrl
.StyleClearAll()
1227 self
._textCtrl
.SetReadOnly(True)
1229 def ClearOutput(self
, event
):
1230 self
._textCtrl
.SetReadOnly(False)
1231 self
._textCtrl
.ClearAll()
1232 self
._textCtrl
.SetReadOnly(True)
1234 def SwitchToOutputTab(self
):
1235 self
._notebook
.SetSelection(0)
1237 class DebuggerView(Service
.ServiceView
):
1239 #----------------------------------------------------------------------------
1240 # Overridden methods
1241 #----------------------------------------------------------------------------
1243 def __init__(self
, service
):
1244 Service
.ServiceView
.__init
__(self
, service
)
1246 def _CreateControl(self
, parent
, id):
1249 #------------------------------------------------------------------------------
1251 #-----------------------------------------------------------------------------
1253 def OnToolClicked(self
, event
):
1254 self
.GetFrame().ProcessEvent(event
)
1256 #------------------------------------------------------------------------------
1258 #-----------------------------------------------------------------------------
1261 def __init__(self
, message
, framesXML
, info
=None, quit
=False):
1262 self
._framesXML
= framesXML
1263 self
._message
= message
1267 def getFramesXML(self
):
1268 return self
._framesXML
1270 def getMessage(self
):
1271 return self
._message
1279 class AGXMLRPCServer(SimpleXMLRPCServer
.SimpleXMLRPCServer
):
1280 def __init__(self
, address
, logRequests
=0):
1281 SimpleXMLRPCServer
.SimpleXMLRPCServer
.__init
__(self
, address
, logRequests
=logRequests
)
1283 class RequestHandlerThread(threading
.Thread
):
1284 def __init__(self
, queue
, address
):
1285 threading
.Thread
.__init
__(self
)
1286 self
._keepGoing
= True
1288 self
._address
= address
1289 self
._server
= AGXMLRPCServer(self
._address
,logRequests
=0)
1290 self
._server
.register_function(self
.interaction
)
1291 self
._server
.register_function(self
.quit
)
1292 self
._server
.register_function(self
.dummyOperation
)
1293 if _VERBOSE
: print "RequestHandlerThread on fileno %s" % str(self
._server
.fileno())
1296 while self
._keepGoing
:
1298 self
._server
.handle_request()
1300 tp
, val
, tb
= sys
.exc_info()
1301 traceback
.print_exception(tp
, val
, tb
)
1302 self
._keepGoing
= False
1303 if _VERBOSE
: print "Exiting Request Handler Thread."
1305 def interaction(self
, message
, frameXML
, info
):
1306 if _VERBOSE
: print "In RequestHandlerThread.interaction -- adding to queue"
1307 interaction
= Interaction(message
, frameXML
, info
)
1308 self
._queue
.put(interaction
)
1312 interaction
= Interaction(None, None, info
=None, quit
=True)
1313 self
._queue
.put(interaction
)
1316 def dummyOperation(self
):
1319 def AskToStop(self
):
1320 self
._keepGoing
= False
1321 if type(self
._server
) is not types
.NoneType
:
1323 # This is a really ugly way to make sure this thread isn't blocked in
1325 url
= 'http://' + self
._address
[0] + ':' + str(self
._address
[1]) + '/'
1326 tempServer
= xmlrpclib
.ServerProxy(url
, allow_none
=1)
1327 tempServer
.dummyOperation()
1329 tp
, val
, tb
= sys
.exc_info()
1330 traceback
.print_exception(tp
, val
, tb
)
1331 self
._server
.server_close()
1334 class RequestBreakThread(threading
.Thread
):
1335 def __init__(self
, server
, interrupt
=False, pushBreakpoints
=False, breakDict
=None, kill
=False):
1336 threading
.Thread
.__init
__(self
)
1337 self
._server
= server
1339 self
._interrupt
= interrupt
1340 self
._pushBreakpoints
= pushBreakpoints
1341 self
._breakDict
= breakDict
1346 if _VERBOSE
: print "RequestBreakThread, before call"
1348 self
._server
.break_requested()
1349 if self
._pushBreakpoints
:
1350 self
._server
.update_breakpoints(xmlrpclib
.Binary(pickle
.dumps(self
._breakDict
)))
1356 if _VERBOSE
: print "RequestBreakThread, after call"
1358 tp
,val
,tb
= sys
.exc_info()
1359 traceback
.print_exception(tp
, val
, tb
)
1361 class DebuggerOperationThread(threading
.Thread
):
1362 def __init__(self
, function
):
1363 threading
.Thread
.__init
__(self
)
1364 self
._function
= function
1367 if _VERBOSE
: print "In DOT, before call"
1371 tp
,val
,tb
= sys
.exc_info()
1372 traceback
.print_exception(tp
, val
, tb
)
1373 if _VERBOSE
: print "In DOT, after call"
1375 class DebuggerCallback
:
1377 def __init__(self
, host
, port
, debugger_url
, break_url
, debuggerUI
):
1378 if _VERBOSE
: print "+++++++ Creating server on port, ", str(port
)
1380 self
._queue
= Queue
.Queue(50)
1382 self
._port
= int(port
)
1383 threading
._VERBOSE
= _VERBOSE
1384 self
._serverHandlerThread
= RequestHandlerThread(self
._queue
, (self
._host
, self
._port
))
1386 self
._debugger
_url
= debugger_url
1387 self
._debuggerServer
= None
1388 self
._waiting
= False
1389 self
._service
= wx
.GetApp().GetService(DebuggerService
)
1390 self
._debuggerUI
= debuggerUI
1391 self
._break
_url
= break_url
1392 self
._breakServer
= None
1393 self
._firstInteraction
= True
1394 self
._pendingBreak
= False
1397 self
._serverHandlerThread
.start()
1399 def ServerClose(self
):
1400 rbt
= RequestBreakThread(self
._breakServer
, kill
=True)
1402 self
.setWaiting(False)
1403 if self
._serverHandlerThread
:
1404 self
._serverHandlerThread
.AskToStop()
1405 self
._serverHandlerThread
= None
1407 def BreakExecution(self
):
1408 rbt
= RequestBreakThread(self
._breakServer
, interrupt
=True)
1411 def SingleStep(self
):
1412 self
._debuggerUI
.DisableWhileDebuggerRunning()
1413 #dot = DebuggerOperationThread(self._debuggerServer.set_step)
1415 self
._debuggerServer
.set_step() # Figure out where to set allowNone
1419 self
._debuggerUI
.DisableWhileDebuggerRunning()
1420 #dot = DebuggerOperationThread(self._debuggerServer.set_next)
1422 self
._debuggerServer
.set_next()
1426 self
._debuggerUI
.DisableWhileDebuggerRunning()
1427 #dot = DebuggerOperationThread(self._debuggerServer.set_continue)
1429 self
._debuggerServer
.set_continue()
1433 self
._debuggerUI
.DisableWhileDebuggerRunning()
1434 #dot = DebuggerOperationThread(self._debuggerServer.set_return)
1436 self
._debuggerServer
.set_return()
1439 def setWaiting(self
, value
):
1440 self
._waiting
= value
1442 def getWaiting(self
):
1443 return self
._waiting
1445 def readQueue(self
):
1446 if self
._queue
.qsize():
1448 item
= self
._queue
.get_nowait()
1450 self
.interaction(None, None, None, True)
1452 data
= bz2
.decompress(item
.getFramesXML().data
)
1453 self
.interaction(item
.getMessage().data
, data
, item
.getInfo(), False)
1457 def pushBreakpoints(self
):
1458 rbt
= RequestBreakThread(self
._breakServer
, pushBreakpoints
=True, breakDict
=self
._service
.GetMasterBreakpointDict())
1462 def waitForRPC(self
):
1463 self
.setWaiting(True)
1464 while self
.getWaiting():
1470 tp
, val
, tb
= sys
.exc_info()
1471 traceback
.print_exception(tp
, val
, tb
)
1472 wx
.GetApp().Yield(True)
1473 if _VERBOSE
: print "Exiting waitForRPC."
1475 def interaction(self
, message
, frameXML
, info
, quit
):
1477 #This method should be hit as the debugger starts.
1478 if self
._firstInteraction
:
1479 self
._firstInteraction
= False
1480 self
._debuggerServer
= xmlrpclib
.ServerProxy(self
._debugger
_url
, allow_none
=1)
1481 self
._breakServer
= xmlrpclib
.ServerProxy(self
._break
_url
, allow_none
=1)
1482 self
.pushBreakpoints()
1483 self
.setWaiting(False)
1484 if _VERBOSE
: print "+"*40
1486 self
._debuggerUI
.StopExecution(None)
1489 if _VERBOSE
: print "Hit interaction with exception"
1490 #self._debuggerUI.StopExecution(None)
1491 #self._debuggerUI.SetStatusText("Got exception: " + str(info))
1492 self
._debuggerUI
.SwitchToOutputTab()
1494 if _VERBOSE
: print "Hit interaction no exception"
1495 self
._debuggerUI
.SetStatusText(message
)
1496 self
._debuggerUI
.LoadFramesListXML(frameXML
)
1497 self
._debuggerUI
.EnableWhileDebuggerStopped()
1498 if _VERBOSE
: print "+"*40
1500 class DebuggerService(Service
.Service
):
1503 #----------------------------------------------------------------------------
1505 #----------------------------------------------------------------------------
1506 TOGGLE_BREAKPOINT_ID
= wx
.NewId()
1507 CLEAR_ALL_BREAKPOINTS
= wx
.NewId()
1509 DEBUG_ID
= wx
.NewId()
1510 DEBUG_WEBSERVER_ID
= wx
.NewId()
1512 def KillAllRunningProcesses():
1513 execs
= DebuggerService
.executors
1514 for executor
in execs
:
1515 executor
.DoStopExecution()
1516 KillAllRunningProcesses
= staticmethod(KillAllRunningProcesses
)
1518 def ComparePaths(first
, second
):
1519 one
= DebuggerService
.ExpandPath(first
)
1520 two
= DebuggerService
.ExpandPath(second
)
1522 return one
.lower() == two
.lower()
1525 ComparePaths
= staticmethod(ComparePaths
)
1527 # Make sure we're using an expanded path on windows.
1528 def ExpandPath(path
):
1531 return win32api
.GetLongPathName(path
)
1533 print "Cannot get long path for %s" % path
1537 ExpandPath
= staticmethod(ExpandPath
)
1539 #----------------------------------------------------------------------------
1540 # Overridden methods
1541 #----------------------------------------------------------------------------
1543 def __init__(self
, serviceName
, embeddedWindowLocation
= wx
.lib
.pydocview
.EMBEDDED_WINDOW_LEFT
):
1544 Service
.Service
.__init
__(self
, serviceName
, embeddedWindowLocation
)
1545 self
.BREAKPOINT_DICT_STRING
= "MasterBreakpointDict"
1546 config
= wx
.ConfigBase_Get()
1547 pickledbps
= config
.Read(self
.BREAKPOINT_DICT_STRING
)
1550 self
._masterBPDict
= pickle
.loads(pickledbps
.encode('ascii'))
1552 tp
, val
, tb
= sys
.exc_info()
1553 traceback
.print_exception(tp
,val
,tb
)
1554 self
._masterBPDict
= {}
1556 self
._masterBPDict
= {}
1558 def OnCloseFrame(self
, event
):
1559 # IS THIS THE RIGHT PLACE?
1561 config
= wx
.ConfigBase_Get()
1562 config
.Write(self
.BREAKPOINT_DICT_STRING
, pickle
.dumps(self
._masterBPDict
))
1564 tp
,val
,tb
= sys
.exc_info()
1565 traceback
.print_exception(tp
, val
, tb
)
1568 def _CreateView(self
):
1569 return DebuggerView(self
)
1572 #----------------------------------------------------------------------------
1573 # Service specific methods
1574 #----------------------------------------------------------------------------
1576 def InstallControls(self
, frame
, menuBar
= None, toolBar
= None, statusBar
= None, document
= None):
1577 #Service.Service.InstallControls(self, frame, menuBar, toolBar, statusBar, document)
1579 config
= wx
.ConfigBase_Get()
1581 debuggerMenu
= wx
.Menu()
1582 if not menuBar
.FindItemById(DebuggerService
.CLEAR_ALL_BREAKPOINTS
):
1584 debuggerMenu
.Append(DebuggerService
.RUN_ID
, _("&Run...\tCtrl+R"), _("Runs a file"))
1585 wx
.EVT_MENU(frame
, DebuggerService
.RUN_ID
, frame
.ProcessEvent
)
1586 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.RUN_ID
, frame
.ProcessUpdateUIEvent
)
1588 debuggerMenu
.Append(DebuggerService
.DEBUG_ID
, _("&Debug...\tCtrl+D"), _("Debugs a file"))
1589 wx
.EVT_MENU(frame
, DebuggerService
.DEBUG_ID
, frame
.ProcessEvent
)
1590 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.DEBUG_ID
, frame
.ProcessUpdateUIEvent
)
1592 if not ACTIVEGRID_BASE_IDE
:
1593 debuggerMenu
.AppendSeparator()
1594 debuggerMenu
.Append(DebuggerService
.DEBUG_WEBSERVER_ID
, _("Debug Internal Web Server"), _("Debugs the internal webservier"))
1595 wx
.EVT_MENU(frame
, DebuggerService
.DEBUG_WEBSERVER_ID
, frame
.ProcessEvent
)
1596 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.DEBUG_WEBSERVER_ID
, frame
.ProcessUpdateUIEvent
)
1598 debuggerMenu
.AppendSeparator()
1600 debuggerMenu
.Append(DebuggerService
.TOGGLE_BREAKPOINT_ID
, _("&Toggle Breakpoint...\tCtrl+B"), _("Toggle a breakpoint"))
1601 wx
.EVT_MENU(frame
, DebuggerService
.TOGGLE_BREAKPOINT_ID
, self
.ProcessEvent
)
1602 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.TOGGLE_BREAKPOINT_ID
, self
.ProcessUpdateUIEvent
)
1604 debuggerMenu
.Append(DebuggerService
.CLEAR_ALL_BREAKPOINTS
, _("&Clear All Breakpoints"), _("Clear All Breakpoints"))
1605 wx
.EVT_MENU(frame
, DebuggerService
.CLEAR_ALL_BREAKPOINTS
, self
.ProcessEvent
)
1606 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.CLEAR_ALL_BREAKPOINTS
, self
.ProcessUpdateUIEvent
)
1609 viewMenuIndex
= menuBar
.FindMenu(_("&Project"))
1610 menuBar
.Insert(viewMenuIndex
+ 1, debuggerMenu
, _("&Run"))
1616 #----------------------------------------------------------------------------
1617 # Event Processing Methods
1618 #----------------------------------------------------------------------------
1620 def ProcessEventBeforeWindows(self
, event
):
1624 def ProcessEvent(self
, event
):
1625 if Service
.Service
.ProcessEvent(self
, event
):
1628 an_id
= event
.GetId()
1629 if an_id
== DebuggerService
.TOGGLE_BREAKPOINT_ID
:
1630 self
.OnToggleBreakpoint(event
)
1632 elif an_id
== DebuggerService
.CLEAR_ALL_BREAKPOINTS
:
1633 self
.ClearAllBreakpoints()
1635 elif an_id
== DebuggerService
.RUN_ID
:
1636 self
.OnRunProject(event
)
1638 elif an_id
== DebuggerService
.DEBUG_ID
:
1639 self
.OnDebugProject(event
)
1641 elif an_id
== DebuggerService
.DEBUG_WEBSERVER_ID
:
1642 self
.OnDebugWebServer(event
)
1646 def ProcessUpdateUIEvent(self
, event
):
1647 if Service
.Service
.ProcessUpdateUIEvent(self
, event
):
1650 an_id
= event
.GetId()
1651 if an_id
== DebuggerService
.TOGGLE_BREAKPOINT_ID
:
1652 currentView
= self
.GetDocumentManager().GetCurrentView()
1653 event
.Enable(isinstance(currentView
, PythonEditor
.PythonView
))
1655 elif an_id
== DebuggerService
.CLEAR_ALL_BREAKPOINTS
:
1656 event
.Enable(self
.HasBreakpointsSet())
1658 elif (an_id
== DebuggerService
.RUN_ID
1659 or an_id
== DebuggerService
.DEBUG_ID
):
1660 event
.Enable(self
.HasAnyFiles())
1665 #----------------------------------------------------------------------------
1667 #----------------------------------------------------------------------------
1669 def OnDebugProject(self
, event
):
1670 if _WINDOWS
and not _PYWIN32_INSTALLED
:
1671 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."))
1673 if not Executor
.GetPythonExecutablePath():
1675 if DebugCommandUI
.DebuggerRunning():
1676 wx
.MessageBox(_("A debugger is already running. Please shut down the other debugger first."), _("Debugger Running"))
1678 self
.ShowWindow(True)
1679 projectService
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
)
1680 project
= projectService
.GetView().GetDocument()
1682 dlg
= CommandPropertiesDialog(self
.GetView().GetFrame(), 'Debug Python File', projectService
, None, pythonOnly
=True, okButtonName
="Debug", debugging
=True)
1685 if dlg
.ShowModal() == wx
.ID_OK
:
1686 fileToDebug
, initialArgs
, startIn
, isPython
, environment
= dlg
.GetSettings()
1691 self
.PromptToSaveFiles()
1693 shortFile
= os
.path
.basename(fileToDebug
)
1694 fileToDebug
= DebuggerService
.ExpandPath(fileToDebug
)
1696 page
= DebugCommandUI(Service
.ServiceView
.bottomTab
, -1, str(fileToDebug
), self
)
1697 count
= Service
.ServiceView
.bottomTab
.GetPageCount()
1698 Service
.ServiceView
.bottomTab
.AddPage(page
, _("Debugging: ") + shortFile
)
1699 Service
.ServiceView
.bottomTab
.SetSelection(count
)
1700 page
.Execute(initialArgs
, startIn
, environment
)
1704 def OnDebugWebServer(self
, event
):
1705 if _WINDOWS
and not _PYWIN32_INSTALLED
:
1706 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."))
1708 if not Executor
.GetPythonExecutablePath():
1710 if DebugCommandUI
.DebuggerRunning():
1711 wx
.MessageBox(_("A debugger is already running. Please shut down the other debugger first."), _("Debugger Running"))
1713 import WebServerService
1714 wsService
= wx
.GetApp().GetService(WebServerService
.WebServerService
)
1715 fileName
, args
= wsService
.StopAndPrepareToDebug()
1717 page
= DebugCommandUI(Service
.ServiceView
.bottomTab
, -1, str(fileName
), self
)
1718 count
= Service
.ServiceView
.bottomTab
.GetPageCount()
1719 Service
.ServiceView
.bottomTab
.AddPage(page
, _("Debugging: Internal WebServer"))
1720 Service
.ServiceView
.bottomTab
.SetSelection(count
)
1721 page
.Execute(args
, startIn
=os
.getcwd(), environment
=os
.environ
)
1726 def HasAnyFiles(self
):
1727 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1728 return len(docs
) > 0
1730 def PromptToSaveFiles(self
, running
=True):
1731 filesModified
= False
1732 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1734 if doc
.IsModified():
1735 filesModified
= True
1738 frame
= self
.GetView().GetFrame()
1740 yesNoMsg
= wx
.MessageDialog(frame
,
1741 _("Files have been modified.\nWould you like to save all files before running?"),
1743 wx
.YES_NO|wx
.ICON_QUESTION
1746 yesNoMsg
= wx
.MessageDialog(frame
,
1747 _("Files have been modified.\nWould you like to save all files before debugging?"),
1749 wx
.YES_NO|wx
.ICON_QUESTION
1751 if yesNoMsg
.ShowModal() == wx
.ID_YES
:
1752 docs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1757 DebugCommandUI
.ShutdownAllDebuggers()
1759 def OnRunProject(self
, event
):
1760 if _WINDOWS
and not _PYWIN32_INSTALLED
:
1761 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."))
1763 if not Executor
.GetPythonExecutablePath():
1765 projectService
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
)
1766 project
= projectService
.GetView().GetDocument()
1768 dlg
= CommandPropertiesDialog(self
.GetView().GetFrame(), 'Run', projectService
, None)
1771 if dlg
.ShowModal() == wx
.ID_OK
:
1772 fileToRun
, initialArgs
, startIn
, isPython
, environment
= dlg
.GetSettings()
1779 self
.PromptToSaveFiles()
1780 # This will need to change when we can run more than .py and .bpel files.
1782 projectService
.RunProcessModel(fileToRun
)
1785 self
.ShowWindow(True)
1786 shortFile
= os
.path
.basename(fileToRun
)
1787 page
= RunCommandUI(Service
.ServiceView
.bottomTab
, -1, str(fileToRun
))
1788 count
= Service
.ServiceView
.bottomTab
.GetPageCount()
1789 Service
.ServiceView
.bottomTab
.AddPage(page
, "Running: " + shortFile
)
1790 Service
.ServiceView
.bottomTab
.SetSelection(count
)
1791 page
.Execute(initialArgs
, startIn
, environment
)
1793 def OnToggleBreakpoint(self
, event
, line
=-1, fileName
=None):
1795 view
= wx
.GetApp().GetDocumentManager().GetCurrentView()
1796 # Test to make sure we aren't the project view.
1797 if not hasattr(view
, 'MarkerExists'):
1799 fileName
= wx
.GetApp().GetDocumentManager().GetCurrentDocument().GetFilename()
1801 line
= view
.GetCtrl().GetCurrentLine()
1802 if self
.BreakpointSet(fileName
, line
+ 1):
1803 self
.ClearBreak(fileName
, line
+ 1)
1805 self
.SetBreak(fileName
, line
+ 1)
1806 # Now refresh all the markers icons in all the open views.
1807 self
.ClearAllBreakpointMarkers()
1808 self
.SetAllBreakpointMarkers()
1810 def SilentToggleBreakpoint(self
, fileName
, line
):
1812 for lineNumber
in self
.GetBreakpointList(fileName
):
1813 if int(lineNumber
) == int(line
):
1817 self
.SetBreak(fileName
, line
)
1819 self
.ClearBreak(fileName
, line
)
1821 def SetBreak(self
, fileName
, line
):
1822 expandedName
= DebuggerService
.ExpandPath(fileName
)
1823 if not self
._masterBPDict
.has_key(expandedName
):
1824 self
._masterBPDict
[expandedName
] = [line
]
1826 self
._masterBPDict
[expandedName
] += [line
]
1827 # If we're already debugging, pass this bp off to the DebuggerCallback
1828 self
.NotifyDebuggersOfBreakpointChange()
1830 def NotifyDebuggersOfBreakpointChange(self
):
1831 DebugCommandUI
.NotifyDebuggersOfBreakpointChange()
1833 def GetBreakpointList(self
, fileName
):
1834 expandedName
= DebuggerService
.ExpandPath(fileName
)
1835 if not self
._masterBPDict
.has_key(expandedName
):
1838 return self
._masterBPDict
[expandedName
]
1840 def BreakpointSet(self
, fileName
, line
):
1841 expandedName
= DebuggerService
.ExpandPath(fileName
)
1842 if not self
._masterBPDict
.has_key(expandedName
):
1846 for number
in self
._masterBPDict
[expandedName
]:
1847 if(int(number
) == int(line
)):
1851 def ClearBreak(self
, fileName
, line
):
1852 expandedName
= DebuggerService
.ExpandPath(fileName
)
1853 if not self
._masterBPDict
.has_key(expandedName
):
1854 print "In ClearBreak: no key"
1858 for number
in self
._masterBPDict
[expandedName
]:
1859 if(int(number
) != int(line
)):
1860 newList
.append(number
)
1861 self
._masterBPDict
[expandedName
] = newList
1862 self
.NotifyDebuggersOfBreakpointChange()
1864 def HasBreakpointsSet(self
):
1865 for key
, value
in self
._masterBPDict
.items():
1870 def ClearAllBreakpoints(self
):
1871 self
._masterBPDict
= {}
1872 self
.NotifyDebuggersOfBreakpointChange()
1873 self
.ClearAllBreakpointMarkers()
1875 def ClearAllBreakpointMarkers(self
):
1876 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1877 for openDoc
in openDocs
:
1878 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
1879 openDoc
.GetFirstView().MarkerDeleteAll(CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
)
1881 def GetMasterBreakpointDict(self
):
1882 return self
._masterBPDict
1884 def SetAllBreakpointMarkers(self
):
1885 openDocs
= wx
.GetApp().GetDocumentManager().GetDocuments()
1886 for openDoc
in openDocs
:
1887 if(isinstance(openDoc
.GetFirstView(), CodeEditor
.CodeView
)):
1888 self
.SetCurrentBreakpointMarkers(openDoc
.GetFirstView())
1890 def SetCurrentBreakpointMarkers(self
, view
):
1891 if isinstance(view
, CodeEditor
.CodeView
) and hasattr(view
, 'GetDocument'):
1892 view
.MarkerDeleteAll(CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
)
1893 for linenum
in self
.GetBreakpointList(view
.GetDocument().GetFilename()):
1894 view
.MarkerAdd(lineNum
=int(linenum
) - 1, marker_index
=CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
)
1896 class DebuggerOptionsPanel(wx
.Panel
):
1899 def __init__(self
, parent
, id):
1900 wx
.Panel
.__init
__(self
, parent
, id)
1902 config
= wx
.ConfigBase_Get()
1903 localHostStaticText
= wx
.StaticText(self
, -1, _("Local Host Name:"))
1904 self
._LocalHostTextCtrl
= wx
.TextCtrl(self
, -1, config
.Read("DebuggerHostName", DEFAULT_HOST
), size
= (150, -1))
1905 portNumberStaticText
= wx
.StaticText(self
, -1, _("Port Range:"))
1906 dashStaticText
= wx
.StaticText(self
, -1, _("through to"))
1907 startingPort
=config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
)
1908 self
._PortNumberTextCtrl
= wx
.lib
.intctrl
.IntCtrl(self
, -1, startingPort
, size
= (50, -1))
1909 self
._PortNumberTextCtrl
.SetMin(1)#What are real values?
1910 self
._PortNumberTextCtrl
.SetMax(65514) #What are real values?
1911 self
.Bind(wx
.lib
.intctrl
.EVT_INT
, self
.MinPortChange
, self
._PortNumberTextCtrl
)
1913 self
._EndPortNumberTextCtrl
= wx
.lib
.intctrl
.IntCtrl(self
, -1, startingPort
+ PORT_COUNT
, size
= (50, -1))
1914 self
._EndPortNumberTextCtrl
.SetMin(22)#What are real values?
1915 self
._EndPortNumberTextCtrl
.SetMax(65535)#What are real values?
1916 self
._EndPortNumberTextCtrl
.Enable( False )
1917 debuggerPanelBorderSizer
= wx
.BoxSizer(wx
.VERTICAL
)
1918 debuggerPanelSizer
= wx
.GridBagSizer(hgap
= 5, vgap
= 5)
1919 debuggerPanelSizer
.Add( localHostStaticText
, (0,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
1920 debuggerPanelSizer
.Add( self
._LocalHostTextCtrl
, (0,1), (1,3), flag
=wx
.EXPAND|wx
.ALIGN_CENTER
)
1921 debuggerPanelSizer
.Add( portNumberStaticText
, (1,0), flag
=wx
.ALIGN_LEFT|wx
.ALIGN_CENTER_VERTICAL
)
1922 debuggerPanelSizer
.Add( self
._PortNumberTextCtrl
, (1,1), flag
=wx
.ALIGN_CENTER
)
1923 debuggerPanelSizer
.Add( dashStaticText
, (1,2), flag
=wx
.ALIGN_CENTER
)
1924 debuggerPanelSizer
.Add( self
._EndPortNumberTextCtrl
, (1,3), flag
=wx
.ALIGN_CENTER
)
1925 FLUSH_PORTS_ID
= wx
.NewId()
1926 self
._flushPortsButton
= wx
.Button(self
, FLUSH_PORTS_ID
, "Reset Port List")
1927 wx
.EVT_BUTTON(parent
, FLUSH_PORTS_ID
, self
.FlushPorts
)
1928 debuggerPanelSizer
.Add(self
._flushPortsButton
, (2,2), (1,2), flag
=wx
.ALIGN_RIGHT
)
1930 debuggerPanelBorderSizer
.Add(debuggerPanelSizer
, 0, wx
.ALL
, SPACE
)
1931 self
.SetSizer(debuggerPanelBorderSizer
)
1933 parent
.AddPage(self
, _("Debugger"))
1935 def FlushPorts(self
, event
):
1936 if self
._PortNumberTextCtrl
.IsInBounds():
1937 config
= wx
.ConfigBase_Get()
1938 config
.WriteInt("DebuggerStartingPort", self
._PortNumberTextCtrl
.GetValue())
1939 DebugCommandUI
.NewPortRange()
1941 wx
.MessageBox(_("The starting port is not valid. Please change the value and try again.", "Invalid Starting Port Number"))
1943 def MinPortChange(self
, event
):
1944 self
._EndPortNumberTextCtrl
.Enable( True )
1945 self
._EndPortNumberTextCtrl
.SetValue( self
._PortNumberTextCtrl
.GetValue() + PORT_COUNT
)
1946 self
._EndPortNumberTextCtrl
.Enable( False )
1948 def OnOK(self
, optionsDialog
):
1949 config
= wx
.ConfigBase_Get()
1950 config
.Write("DebuggerHostName", self
._LocalHostTextCtrl
.GetValue())
1951 if self
._PortNumberTextCtrl
.IsInBounds():
1952 config
.WriteInt("DebuggerStartingPort", self
._PortNumberTextCtrl
.GetValue())
1954 class CommandPropertiesDialog(wx
.Dialog
):
1956 def __init__(self
, parent
, title
, projectService
, currentProjectDocument
, pythonOnly
=False, okButtonName
="Run", debugging
=False):
1957 self
._projService
= projectService
1960 for template
in self
._projService
.GetDocumentManager().GetTemplates():
1961 if not ACTIVEGRID_BASE_IDE
and template
.GetDocumentType() == ProcessModelEditor
.ProcessModelDocument
:
1962 self
._pmext
= template
.GetDefaultExtension()
1963 if template
.GetDocumentType() == PythonEditor
.PythonDocument
:
1964 self
._pyext
= template
.GetDefaultExtension()
1965 self
._pythonOnly
= pythonOnly
1966 self
._currentProj
= currentProjectDocument
1967 self
._projectNameList
, self
._projectDocumentList
, selectedIndex
= self
.GetProjectList()
1968 if not self
._projectNameList
:
1969 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"))
1972 wx
.Dialog
.__init
__(self
, parent
, -1, title
)
1974 wx
.Dialog
.__init
__(self
, parent
, -1, title
, size
=(390,270))
1976 projStaticText
= wx
.StaticText(self
, -1, _("Project:"))
1977 fileStaticText
= wx
.StaticText(self
, -1, _("File:"))
1978 argsStaticText
= wx
.StaticText(self
, -1, _("Arguments:"))
1979 startInStaticText
= wx
.StaticText(self
, -1, _("Start in:"))
1980 pythonPathStaticText
= wx
.StaticText(self
, -1, _("PYTHONPATH:"))
1981 postpendStaticText
= _("Postpend win32api path")
1982 cpPanelBorderSizer
= wx
.BoxSizer(wx
.VERTICAL
)
1983 self
._projList
= wx
.Choice(self
, -1, (200,-1), choices
=self
._projectNameList
)
1984 self
.Bind(wx
.EVT_CHOICE
, self
.EvtListBox
, self
._projList
)
1986 flexGridSizer
= wx
.FlexGridSizer(cols
= 3, vgap
= 10, hgap
= 10)
1988 flexGridSizer
.Add(projStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
1989 flexGridSizer
.Add(self
._projList
, 1, flag
=wx
.EXPAND
)
1990 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
1992 flexGridSizer
.Add(fileStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
1993 self
._fileList
= wx
.Choice(self
, -1, (200,-1))
1994 self
.Bind(wx
.EVT_CHOICE
, self
.OnFileSelected
, self
._fileList
)
1995 flexGridSizer
.Add(self
._fileList
, 1, flag
=wx
.EXPAND
)
1996 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
1998 config
= wx
.ConfigBase_Get()
1999 self
._lastArguments
= config
.Read("LastRunArguments")
2000 self
._argsEntry
= wx
.TextCtrl(self
, -1, str(self
._lastArguments
))
2001 self
._argsEntry
.SetToolTipString(str(self
._lastArguments
))
2003 flexGridSizer
.Add(argsStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2004 flexGridSizer
.Add(self
._argsEntry
, 1, flag
=wx
.EXPAND
)
2005 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
2007 flexGridSizer
.Add(startInStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2008 self
._lastStartIn
= config
.Read("LastRunStartIn")
2009 if not self
._lastStartIn
:
2010 self
._lastStartIn
= str(os
.getcwd())
2011 self
._startEntry
= wx
.TextCtrl(self
, -1, self
._lastStartIn
)
2012 self
._startEntry
.SetToolTipString(self
._lastStartIn
)
2013 def TextChanged2(event
):
2014 self
._startEntry
.SetToolTipString(event
.GetString())
2015 self
.Bind(wx
.EVT_TEXT
, TextChanged2
, self
._startEntry
)
2017 flexGridSizer
.Add(self
._startEntry
, 1, wx
.EXPAND
)
2018 self
._findDir
= wx
.Button(self
, -1, _("Browse..."))
2019 self
.Bind(wx
.EVT_BUTTON
, self
.OnFindDirClick
, self
._findDir
)
2020 flexGridSizer
.Add(self
._findDir
, 0, wx
.RIGHT
, 10)
2022 flexGridSizer
.Add(pythonPathStaticText
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
)
2023 if os
.environ
.has_key('PYTHONPATH'):
2024 startval
= os
.environ
['PYTHONPATH']
2027 self
._lastPythonPath
= config
.Read("LastPythonPath", startval
)
2028 self
._pythonPathEntry
= wx
.TextCtrl(self
, -1, self
._lastPythonPath
)
2029 self
._pythonPathEntry
.SetToolTipString(self
._lastPythonPath
)
2030 flexGridSizer
.Add(self
._pythonPathEntry
, 1, wx
.EXPAND
)
2031 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
2032 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
2034 self
._postpendCheckBox
= wx
.CheckBox(self
, -1, postpendStaticText
)
2035 checked
= bool(config
.ReadInt("PythonPathPostpend", 1))
2036 self
._postpendCheckBox
.SetValue(checked
)
2037 flexGridSizer
.Add(self
._postpendCheckBox
, 1, wx
.EXPAND
)
2038 flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0)
2039 cpPanelBorderSizer
.Add(flexGridSizer
, 0, wx
.ALL
, 10)
2041 box
= wx
.BoxSizer(wx
.HORIZONTAL
)
2042 self
._okButton
= wx
.Button(self
, wx
.ID_OK
, okButtonName
)
2043 self
._okButton
.SetDefault()
2044 self
._okButton
.SetHelpText(_("The ") + okButtonName
+ _(" button completes the dialog"))
2045 box
.Add(self
._okButton
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5)
2046 self
.Bind(wx
.EVT_BUTTON
, self
.OnOKClick
, self
._okButton
)
2047 btn
= wx
.Button(self
, wx
.ID_CANCEL
, _("Cancel"))
2048 btn
.SetHelpText(_("The Cancel button cancels the dialog."))
2049 box
.Add(btn
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5)
2050 cpPanelBorderSizer
.Add(box
, 0, wx
.ALIGN_RIGHT|wx
.BOTTOM
, 5)
2052 self
.SetSizer(cpPanelBorderSizer
)
2054 self
.GetSizer().Fit(self
)
2058 # Set up selections based on last values used.
2059 self
._fileNameList
= None
2060 self
._selectedFileIndex
= 0
2061 lastProject
= config
.Read("LastRunProject")
2062 lastFile
= config
.Read("LastRunFile")
2064 if lastProject
in self
._projectNameList
:
2065 selectedIndex
= self
._projectNameList
.index(lastProject
)
2066 elif selectedIndex
< 0:
2068 self
._projList
.Select(selectedIndex
)
2069 self
._selectedProjectIndex
= selectedIndex
2070 self
._selectedProjectDocument
= self
._projectDocumentList
[selectedIndex
]
2071 self
.PopulateFileList(self
._selectedProjectDocument
, lastFile
)
2073 def OnOKClick(self
, event
):
2074 startIn
= self
._startEntry
.GetValue()
2075 fileToRun
= self
._fileList
.GetStringSelection()
2077 wx
.MessageBox(_("You must select a file to proceed. Note that not all projects have files that can be run or debugged."))
2079 isPython
= fileToRun
.endswith(self
._pyext
)
2080 if isPython
and not os
.path
.exists(startIn
):
2081 wx
.MessageBox(_("Starting directory does not exist. Please change this value."))
2083 config
= wx
.ConfigBase_Get()
2084 config
.Write("LastRunProject", self
._projectNameList
[self
._selectedProjectIndex
])
2085 config
.Write("LastRunFile", fileToRun
)
2086 # Don't update the arguments or starting directory unless we're runing python.
2088 config
.Write("LastRunArguments", self
._argsEntry
.GetValue())
2089 config
.Write("LastRunStartIn", self
._startEntry
.GetValue())
2090 config
.Write("LastPythonPath",self
._pythonPathEntry
.GetValue())
2091 if hasattr(self
, "_postpendCheckBox"):
2092 config
.WriteInt("PythonPathPostpend", int(self
._postpendCheckBox
.GetValue()))
2094 self
.EndModal(wx
.ID_OK
)
2096 def GetSettings(self
):
2097 filename
= self
._fileNameList
[self
._selectedFileIndex
]
2098 args
= self
._argsEntry
.GetValue()
2099 startIn
= self
._startEntry
.GetValue()
2100 isPython
= filename
.endswith(self
._pyext
)
2102 if hasattr(self
, "_postpendCheckBox"):
2103 postpend
= self
._postpendCheckBox
.GetValue()
2107 env
['PYTHONPATH'] = self
._pythonPathEntry
.GetValue() + os
.pathsep
+ os
.path
.join(os
.getcwd(), "3rdparty", "pywin32")
2109 env
['PYTHONPATH'] = self
._pythonPathEntry
.GetValue()
2111 return filename
, args
, startIn
, isPython
, env
2113 def OnFileSelected(self
, event
):
2114 self
._selectedFileIndex
= self
._fileList
.GetSelection()
2115 self
.EnableForFileType(event
.GetString())
2117 def EnableForFileType(self
, fileName
):
2118 show
= fileName
.endswith(self
._pyext
)
2119 self
._startEntry
.Enable(show
)
2120 self
._findDir
.Enable(show
)
2121 self
._argsEntry
.Enable(show
)
2124 self
._lastStartIn
= self
._startEntry
.GetValue()
2125 self
._startEntry
.SetValue("")
2126 self
._lastArguments
= self
._argsEntry
.GetValue()
2127 self
._argsEntry
.SetValue("")
2129 self
._startEntry
.SetValue(self
._lastStartIn
)
2130 self
._argsEntry
.SetValue(self
._lastArguments
)
2134 def OnFindDirClick(self
, event
):
2135 dlg
= wx
.DirDialog(self
, "Choose a starting directory:", self
._startEntry
.GetValue(),
2136 style
=wx
.DD_DEFAULT_STYLE|wx
.DD_NEW_DIR_BUTTON
)
2138 if dlg
.ShowModal() == wx
.ID_OK
:
2139 self
._startEntry
.SetValue(dlg
.GetPath())
2143 def EvtListBox(self
, event
):
2144 if event
.GetString():
2145 index
= self
._projectNameList
.index(event
.GetString())
2146 self
._selectedProjectDocument
= self
._projectDocumentList
[index
]
2147 self
._selectedProjectIndex
= index
2148 self
.PopulateFileList(self
._selectedProjectDocument
)
2150 def FilterFileList(self
, list):
2151 if self
._pythonOnly
:
2152 files
= filter(lambda f
: f
.endswith(self
._pyext
), list)
2154 files
= filter(lambda f
: (self
._pmext
and f
.endswith(self
._pmext
)) or f
.endswith(self
._pyext
), list)
2157 def PopulateFileList(self
, project
, shortNameToSelect
=None):
2158 self
._fileNameList
= self
.FilterFileList(project
.GetFiles()[:])
2159 self
._fileList
.Clear()
2160 if not self
._fileNameList
:
2162 self
._fileNameList
.sort(lambda a
, b
: cmp(os
.path
.basename(a
).lower(), os
.path
.basename(b
).lower()))
2163 strings
= map(lambda file: os
.path
.basename(file), self
._fileNameList
)
2164 for index
in range(0, len(strings
)):
2165 if shortNameToSelect
== strings
[index
]:
2166 self
._selectedFileIndex
= index
2168 self
._fileList
.Hide()
2169 self
._fileList
.AppendItems(strings
)
2170 self
._fileList
.Show()
2171 if self
._selectedFileIndex
not in range(0, len(strings
)) : self
._selectedFileIndex
= 0
2172 self
._fileList
.SetSelection(self
._selectedFileIndex
)
2173 self
.EnableForFileType(strings
[self
._selectedFileIndex
])
2175 def GetProjectList(self
):
2181 for document
in self
._projService
.GetDocumentManager().GetDocuments():
2182 if document
.GetDocumentTemplate().GetDocumentType() == ProjectEditor
.ProjectDocument
and len(document
.GetFiles()):
2183 docList
.append(document
)
2184 nameList
.append(os
.path
.basename(document
.GetFilename()))
2185 if document
== self
._currentProj
:
2189 #Check for open files not in any of these projects and add them to a default project
2190 def AlreadyInProject(fileName
):
2191 for projectDocument
in docList
:
2192 if projectDocument
.IsFileInProject(fileName
):
2196 unprojectedFiles
= []
2197 for document
in self
._projService
.GetDocumentManager().GetDocuments():
2198 if not ACTIVEGRID_BASE_IDE
and type(document
) == ProcessModelEditor
.ProcessModelDocument
:
2199 if not AlreadyInProject(document
.GetFilename()):
2200 unprojectedFiles
.append(document
.GetFilename())
2201 if type(document
) == PythonEditor
.PythonDocument
:
2202 if not AlreadyInProject(document
.GetFilename()):
2203 unprojectedFiles
.append(document
.GetFilename())
2205 if unprojectedFiles
:
2206 unprojProj
= ProjectEditor
.ProjectDocument()
2207 unprojProj
.SetFilename(_("Not in any Project"))
2208 unprojProj
.AddFiles(unprojectedFiles
)
2209 docList
.append(unprojProj
)
2210 nameList
.append(_("Not in any Project"))
2212 return nameList
, docList
, index
2215 #----------------------------------------------------------------------
2216 from wx
import ImageFromStream
, BitmapFromImage
2219 #----------------------------------------------------------------------
2222 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x02\
2223 \x00\x00\x00\x90\x91h6\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\
2224 \x00\x85IDAT(\x91\xbd\x92A\x16\x03!\x08CI\xdf\xdc\x0b\x8e\xe6\xd1\xe0d\xe9\
2225 \x82\xd6\xc7(\x9di7\xfd\xab<\x14\x13Q\xb8\xbb\xfc\xc2\xe3\xd3\x82\x99\xb9\
2226 \xe9\xaeq\xe1`f)HF\xc4\x8dC2\x06\xbf\x8a4\xcf\x1e\x03K\xe5h\x1bH\x02\x98\xc7\
2227 \x03\x98\xa9z\x07\x00%\xd6\xa9\xd27\x90\xac\xbbk\xe5\x15I\xcdD$\xdc\xa7\xceT\
2228 5a\xce\xf3\xe4\xa0\xaa\x8bO\x12\x11\xabC\xcb\x9c}\xd57\xef\xb0\xf3\xb7\x86p\
2229 \x97\xf7\xb5\xaa\xde\xb9\xfa|-O\xbdjN\x9b\xf8\x06A\xcb\x00\x00\x00\x00IEND\
2232 def getBreakBitmap():
2233 return BitmapFromImage(getBreakImage())
2235 def getBreakImage():
2236 stream
= cStringIO
.StringIO(getBreakData())
2237 return ImageFromStream(stream
)
2240 return wx
.IconFromBitmap(getBreakBitmap())
2242 #----------------------------------------------------------------------
2243 def getClearOutputData():
2245 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2246 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2247 \x00\x00\xb4IDAT8\x8d\xa5\x92\xdd\r\x03!\x0c\x83\xbf\xa0n\xd4\x9d\xda5\xb81\
2248 \xbaS\xbb\x12\xee\x03?\xe5\x08\xe5N\xba\xbc Db\xec\xd8p\xb1l\xb8\xa7\x83\xfe\
2249 \xb0\x02H\x92F\xc0_\xa3\x99$\x99\x99\xedznc\xe36\x81\x88\x98"\xb2\x02\xa2\
2250 \x1e\xc4Q\x9aUD\x161\xcd\xde\x1c\x83\x15\x084)\x8d\xc5)\x06\xab\xaaZ\x92\xee\
2251 \xce\x11W\xdbGD\x0cIT\x06\xe7\x00\xdeY\xfe\xcc\x89\x06\xf0\xf2\x99\x00\xe0\
2252 \x91\x7f\xab\x83\xed\xa4\xc8\xafK\x0c\xcf\x92\x83\x99\x8d\xe3p\xef\xe4\xa1\
2253 \x0b\xe57j\xc8:\x06\t\x08\x87.H\xb2n\xa8\xc9\xa9\x12vQ\xfeG"\xe3\xacw\x00\
2254 \x10$M\xd3\x86_\xf0\xe5\xfc\xb4\xfa\x02\xcb\x13j\x10\xc5\xd7\x92D\x00\x00\
2255 \x00\x00IEND\xaeB`\x82'
2257 def getClearOutputBitmap():
2258 return BitmapFromImage(getClearOutputImage())
2260 def getClearOutputImage():
2261 stream
= cStringIO
.StringIO(getClearOutputData())
2262 return ImageFromStream(stream
)
2264 def getClearOutputIcon():
2265 return wx
.IconFromBitmap(getClearOutputBitmap())
2267 #----------------------------------------------------------------------
2270 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x02\
2271 \x00\x00\x00\x90\x91h6\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\
2272 \x00\xedIDAT(\x91\xa5\x90!\xae\x840\x10\x86g_\xd6"*kz\x82j\xb0h\x1c\t\' x\
2273 \x92Z\xc2\x05\x10\x95\x18\x0e\x00\x02M\x82 \xe1\nMF#jz\x80\xea&+\x9a\x10\x96\
2274 \xdd}\xfb\xc8\x1b\xd7?\xdf\x97\xfe3\xb7u]\xe1\xca\xfc\\\xa2\xff- \xe24M\xc7\
2275 \xc49wJ\xee\xc7G]\xd7\x8c1\xc6\x18\xe7\xdc\'B\x08k\xed1y\xfaa\x1cG\xad\xb5\
2276 \x94\x12\x11\x9dsy\x9e+\xa5\x84\x10;\r\x00\xb7\xd3\x95\x8c1UU\x05A\x00\x00\
2277 \xd6\xda,\xcb\x92$\xf9\xb8\x03\x00PJ\x85\x10Zk\xa5\xd4+\xfdF\x00\x80\xae\xeb\
2278 \x08!\x84\x90y\x9e\x11\xf1\x8bP\x96\xa5\xef\xdd\xb6\xad\xb5VJ\xf9\x9b\xe0\
2279 \xe9\xa6i8\xe7\xbe\xdb\xb6mi\x9a\x0e\xc3\xf0F\x88\xe3\x18\x00\xfa\xbe\x0f\
2280 \xc3\xd0\'\x9c\xf3eY\xa2(*\x8ab\xc7\x9e\xaed\x8c\xa1\x94\xben\xf5\xb1\xd2W\
2281 \xfa,\xfce.\x0b\x0f\xb8\x96e\x90gS\xe0v\x00\x00\x00\x00IEND\xaeB`\x82'
2283 def getCloseBitmap():
2284 return BitmapFromImage(getCloseImage())
2286 def getCloseImage():
2287 stream
= cStringIO
.StringIO(getCloseData())
2288 return ImageFromStream(stream
)
2291 return wx
.IconFromBitmap(getCloseBitmap())
2293 #----------------------------------------------------------------------
2294 def getContinueData():
2296 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2297 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2298 \x00\x00\x9eIDAT8\x8d\xbd\x92\xd1\r\x83@\x0cC\xed\x8a\x11X\xac\x1b\xddF,\xd6\
2299 \x11\x90\xdc\x0f\x9a\x93s)\x14Z\xa9\x91\x10\n\x97\xbc\xd89\x80?\x84\x1a\xa4\
2300 \x83\xfc\x1c$\x1e)7\xdf<Y0\xaf\x0b\xe6\xf5\x1d\xa1\xb5\x13C\x03 !\xaa\xfd\
2301 \xed\n:mr\xc0\x1d\x8f\xc9\x9a!\t$\xe5\xd3I\xe2\xe5B$\x99\x00[\x01\xe8\xc5\
2302 \xd9G\xfaN`\xd8\x81I\xed\x8c\xb19\x94\x8d\xcbL\x00;t\xcf\x9fwPh\xdb\x0e\xe8\
2303 \xd3,\x17\x8b\xc7\x9d\xbb>\x8a \xec5\x94\tc\xc4\x12\xab\x94\xeb\x7fkWr\xc9B%\
2304 \xfc\xd2\xfcM<\x01\xf6tn\x12O3c\xe6\x00\x00\x00\x00IEND\xaeB`\x82'
2306 def getContinueBitmap():
2307 return BitmapFromImage(getContinueImage())
2309 def getContinueImage():
2310 stream
= cStringIO
.StringIO(getContinueData())
2311 return ImageFromStream(stream
)
2313 def getContinueIcon():
2314 return wx
.IconFromBitmap(getContinueBitmap())
2316 #----------------------------------------------------------------------
2319 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2320 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2321 \x00\x00\x8eIDAT8\x8d\xa5SA\x12\xc4 \x08K\xb0\xff\xde\xe9\xbf\xb7\xa6\x87\
2322 \x1d:\xba\xa2tZn(\x84`"i\x05obk\x13\xd5CmN+\xcc\x00l\xd6\x0c\x00\xf5\xf8\x0e\
2323 gK\x06\x00 \xa5=k\x00\x00\xb0\xb2]\xd4?5f\xb1\xdb\xaf\xc6\xa2\xcb\xa8\xf0?\
2324 \x1c\x98\xae\x82\xbf\x81\xa4\x8eA\x16\xe1\n\xd1\xa4\x19\xb3\xe9\n\xce\xe8\
2325 \xf1\n\x9eg^\x18\x18\x90\xec<\x11\xf9#\x04XMZ\x19\xaac@+\x94\xd4\x99)SeP\xa1\
2326 )\xd6\x1dI\xe7*\xdc\xf4\x03\xdf~\xe7\x13T^Q?:X\x19d\x00\x00\x00\x00IEND\xaeB\
2329 def getNextBitmap():
2330 return BitmapFromImage(getNextImage())
2333 stream
= cStringIO
.StringIO(getNextData())
2334 return ImageFromStream(stream
)
2337 return wx
.IconFromBitmap(getNextBitmap())
2339 #----------------------------------------------------------------------
2340 def getStepInData():
2342 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2343 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2344 \x00\x00\x87IDAT8\x8d\xadSA\x12\x84 \x0ck\x8a\xffv\xfc\xb74{X\xeb0P@\x07s\
2345 \x84\xa4$\x01\x00M\xb2\x02]R\x8b\xc86\xda\xdc\xedd\xb4~\xe8\x86\xc6\x01-\x93\
2346 \x96\xd9#\xf6\x06\xc3;p1I\xd1\x14\x0b#|\x17aF\xec\r\xeeF\xa0eB\xd34\xca\xd0A\
2347 ]j\x84\xa6\x03\x00""\xb7\xb0tRZ\xf7x\xb7\x83\x91]\xcb\x7fa\xd9\x89\x0fC\xfd\
2348 \x94\x9d|9\x99^k\x13\xa1 \xb3\x16\x0f#\xd4\x88N~\x14\xe1-\x96\x7f\xe3\x0f\
2349 \x11\x91UC\x0cX\'\x1e\x00\x00\x00\x00IEND\xaeB`\x82'
2351 def getStepInBitmap():
2352 return BitmapFromImage(getStepInImage())
2354 def getStepInImage():
2355 stream
= cStringIO
.StringIO(getStepInData())
2356 return ImageFromStream(stream
)
2358 def getStepInIcon():
2359 return wx
.IconFromBitmap(getStepInBitmap())
2361 #----------------------------------------------------------------------
2364 "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2365 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2366 \x00\x00FIDAT8\x8d\xed\x91\xc1\t\xc00\x0c\x03O!\x0b\xa9\xfb\xef\xa6\xfcB\xa1\
2367 N\t\xf4Wr\xa0\x8f\xb1\x0f\x81\xe1\x97\xe4-\xb6}_V%\xc8\xc2, \t\x92\xe6]\xfbZ\
2368 \xf7\x08\xa0W\xc3\xea5\xdb\rl_IX\xe5\xf0d\x00\xfa\x8d#\x7f\xc4\xf7'\xab\x00\
2369 \x00\x00\x00IEND\xaeB`\x82"
2371 def getStopBitmap():
2372 return BitmapFromImage(getStopImage())
2375 stream
= cStringIO
.StringIO(getStopData())
2376 return ImageFromStream(stream
)
2379 return wx
.IconFromBitmap(getStopBitmap())
2381 #----------------------------------------------------------------------
2382 def getStepReturnData():
2384 "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2385 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2386 \x00\x00\x8dIDAT8\x8d\xa5S\xd1\x0e\xc4 \x08\xa3\xb0\xff\xbe\xdc\x7fO\xba'6\
2387 \xf1\xf44\xb3O$Phk\x04\xd4d\x07\xba\xc5\x16\x91#\nza\xdb\x84\x1a\xa2\xfe\xf8\
2388 \x99\xfa_=p+\xe8\x91ED\xbc<\xa4 \xb4\x0b\x01\xb5{\x01\xf9\xbbG-\x13\x87\x16f\
2389 \x84\xbf\x16V\xb0l\x01@\no\x86\xae\x82Q\xa8=\xa4\x0c\x80\xe70\xbd\x10jh\xbd\
2390 \x07R\x06#\xc9^N\xb6\xde\x03)\x83\x18\xaeU\x90\x9c>a\xb2P\r\xb3&/Y\xa8\xd1^^\
2391 \xb6\xf0\x16\xdb\xbf\xf1\x02\x81\xa5TK\x1d\x07\xde\x92\x00\x00\x00\x00IEND\
2394 def getStepReturnBitmap():
2395 return BitmapFromImage(getStepReturnImage())
2397 def getStepReturnImage():
2398 stream
= cStringIO
.StringIO(getStepReturnData())
2399 return ImageFromStream(stream
)
2401 def getStepReturnIcon():
2402 return wx
.IconFromBitmap(getStepReturnBitmap())
2404 #----------------------------------------------------------------------
2405 def getAddWatchData():
2407 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2408 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2409 \x00\x00\x85IDAT8\x8dc`\x18h\xc0\x88.\xd0\xc0\xf0\xff?*\x9f\x11C\rN\x80\xae\
2410 \x19\x97\x18\xd1\x9a\x896\x84\x18[p\xa9aA\xe6\xfc7f\xc0P\xc4x\x163\x9cp\x1a0\
2411 \xeb,!w\x100 \x1dK\xac\x10\r\x08\x05".yFL\x85\x8c\x18b\xa8|Ty\xa2\x13\x92\'\
2412 \xc3\xe4\xff\x9f\x18\x1e3\xb82t\xa2\x88\x13\xedg.\x06aa&\x06VV\x7f\x86\xb9\
2413 \xcfU\x19\xbc\xb0\xba\x86h\xe0\xc8\xd0\xfc\xbf\x80\xe1>q)\x94\xe6\x00\x00\
2414 \x85\x923_\xd22\xa4\xcd\x00\x00\x00\x00IEND\xaeB`\x82'
2416 def getAddWatchBitmap():
2417 return BitmapFromImage(getAddWatchImage())
2419 def getAddWatchImage():
2420 stream
= cStringIO
.StringIO(getAddWatchData())
2421 return ImageFromStream(stream
)
2423 def getAddWatchIcon():
2424 return wx
.IconFromBitmap(getAddWatchBitmap())