1 #---------------------------------------------------------------------------- 
   2 # Name:         DebuggerService.py 
   3 # Purpose:      Debugger Service for Python and PHP 
   9 # Copyright:    (c) 2004-2005 ActiveGrid, Inc. 
  10 # License:      wxWindows License 
  11 #---------------------------------------------------------------------------- 
  19 import wx
.lib
.pydocview
 
  26 import activegrid
.model
.projectmodel 
as projectmodel
 
  27 from IDE 
import ACTIVEGRID_BASE_IDE
 
  28 if not ACTIVEGRID_BASE_IDE
: 
  29     import ProcessModelEditor
 
  30 import wx
.lib
.scrolledpanel 
as scrolled
 
  33 import SimpleXMLRPCServer
 
  41 from xml
.dom
.minidom 
import parse
, parseString
 
  44 import DebuggerHarness
 
  48 import activegrid
.util
.sysutils 
as sysutilslib
 
  52 if wx
.Platform 
== '__WXMSW__': 
  55         _PYWIN32_INSTALLED 
= True 
  57         _PYWIN32_INSTALLED 
= False 
  62 if not _WINDOWS 
or _PYWIN32_INSTALLED
: 
  70 import  wx
.lib
.newevent
 
  71 (UpdateTextEvent
, EVT_UPDATE_STDTEXT
) = wx
.lib
.newevent
.NewEvent() 
  72 (UpdateErrorEvent
, EVT_UPDATE_ERRTEXT
) = wx
.lib
.newevent
.NewEvent() 
  73 (DebugInternalWebServer
, EVT_DEBUG_INTERNAL
) = wx
.lib
.newevent
.NewEvent() 
  75 # Class to read from stdout or stderr and write the result to a text control. 
  76 # Args: file=file-like object 
  77 #       callback_function= function that takes a single argument, the line of text 
  79 class OutputReaderThread(threading
.Thread
): 
  80     def __init__(self
, file, callback_function
, callbackOnExit
=None, accumulate
=True): 
  81         threading
.Thread
.__init
__(self
) 
  83         self
._callback
_function 
= callback_function
 
  84         self
._keepGoing 
= True 
  86         self
._accumulate 
= accumulate
 
  87         self
._callbackOnExit 
= callbackOnExit
 
  91         # See comment on PythonDebuggerUI.StopExecution 
  92         self
._keepGoing 
= False 
  98         while self
._keepGoing
: 
 100                 # This could block--how to handle that? 
 101                 text 
= file.readline() 
 102                 if text 
== '' or text 
== None: 
 103                     self
._keepGoing 
= False 
 104                 elif not self
._accumulate 
and self
._keepGoing
: 
 105                     self
._callback
_function
(text
) 
 107                     # Should use a buffer? StringIO? 
 109                 # Seems as though the read blocks if we got an error, so, to be 
 110                 # sure that at least some of the exception gets printed, always 
 111                 # send the first hundred lines back as they come in. 
 112                 if self
._lineCount 
< 100 and self
._keepGoing
: 
 113                     self
._callback
_function
(output
) 
 116                 elif time
.time() - start 
> 0.25 and self
._keepGoing
: 
 118                         self
._callback
_function
(output
) 
 119                     except wx
._core
.PyDeadObjectError
: 
 120                         # GUI was killed while we were blocked. 
 121                         self
._keepGoing 
= False 
 127                 tp
, val
, tb 
= sys
.exc_info() 
 128                 print "Exception in OutputReaderThread.run():", tp
, val
 
 129                 self
._keepGoing 
= False 
 130         if self
._callbackOnExit
: 
 132                 self
._callbackOnExit
() 
 133             except wx
._core
.PyDeadObjectError
: 
 135         if _VERBOSE
: print "Exiting OutputReaderThread" 
 138         self
._keepGoing 
= False 
 142     PHP_CGI_BIN_PATH_WIN  
= "../../3rdparty/php" 
 143     PHP_CGI_BIN_PATH_UNIX 
= "../../../3rdparty/php/bin" 
 144     PHP_CGI_BIN_PATH_OSX  
= "../3rdparty/php/bin" 
 145     PHP_CGI_EXEC_WIN      
= "php-cgi.exe" 
 146     PHP_CGI_EXEC_UNIX     
= "php" 
 147     PHP_CGI_EXEC_OSX      
= "php-cgi" 
 149     def GetPythonExecutablePath(): 
 150         path 
= UICommon
.GetPythonExecPath() 
 153         wx
.MessageBox(_("To proceed we 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")) 
 155     GetPythonExecutablePath 
= staticmethod(GetPythonExecutablePath
) 
 157     def GetPHPExecutablePath(): 
 158         if sysutilslib
.isWindows(): 
 159             phpCgiBinPath 
= Executor
.PHP_CGI_BIN_PATH_WIN
 
 160             phpCgiExec    
= Executor
.PHP_CGI_EXEC_WIN
 
 161         elif sys
.platform 
== "darwin": 
 162             phpCgiBinPath 
= Executor
.PHP_CGI_BIN_PATH_OSX
 
 163             phpCgiExec    
= Executor
.PHP_CGI_EXEC_OSX
 
 165             phpCgiBinPath 
= Executor
.PHP_CGI_BIN_PATH_UNIX
 
 166             phpCgiExec    
= Executor
.PHP_CGI_EXEC_UNIX
 
 168         if sysutilslib
.isRelease(): 
 169             phpCgiExecFullPath 
= os
.path
.normpath(os
.path
.join(sysutilslib
.mainModuleDir
, phpCgiBinPath
, phpCgiExec
)) 
 171             phpCgiExecFullPath 
= phpCgiExec
 
 174             print "php cgi executable full path is: %s" % phpCgiExecFullPath
 
 176         return phpCgiExecFullPath
 
 177     GetPHPExecutablePath 
= staticmethod(GetPHPExecutablePath
) 
 179     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): 
 180         self
._fileName 
= fileName
 
 181         self
._stdOutCallback 
= self
.OutCall
 
 182         self
._stdErrCallback 
= self
.ErrCall
 
 183         self
._callbackOnExit 
= callbackOnExit
 
 184         self
._wxComponent 
= wxComponent
 
 185         if fileName
.endswith('.py') or fileName
.endswith('.pyc'): 
 186             self
._path 
= Executor
.GetPythonExecutablePath() 
 187             self
._cmd 
= '"' + self
._path 
+ '" -u \"' + fileName 
+ '\"' 
 189             self
._path 
= Executor
.GetPHPExecutablePath() 
 190             self
._cmd 
= '"' + self
._path 
+ '"' 
 191         #Better way to do this? Quotes needed for windows file paths. 
 192         def spaceAndQuote(text
): 
 193             if text
.startswith("\"") and text
.endswith("\""): 
 196                 return ' \"' + text 
+ '\"' 
 198             self
._cmd 
+= spaceAndQuote(arg1
) 
 200             self
._cmd 
+= spaceAndQuote(arg2
) 
 202             self
._cmd 
+= spaceAndQuote(arg3
) 
 204             self
._cmd 
+= spaceAndQuote(arg4
) 
 206             self
._cmd 
+= spaceAndQuote(arg5
) 
 208             self
._cmd 
+= spaceAndQuote(arg6
) 
 210             self
._cmd 
+= spaceAndQuote(arg7
) 
 212             self
._cmd 
+= spaceAndQuote(arg8
) 
 214             self
._cmd 
+= spaceAndQuote(arg9
) 
 216         self
._stdOutReader 
= None 
 217         self
._stdErrReader 
= None 
 220     def OutCall(self
, text
): 
 221         evt 
= UpdateTextEvent(value 
= text
) 
 222         wx
.PostEvent(self
._wxComponent
, evt
) 
 224     def ErrCall(self
, text
): 
 225         evt 
= UpdateErrorEvent(value 
= text
) 
 226         wx
.PostEvent(self
._wxComponent
, evt
) 
 228     def Execute(self
, arguments
, startIn
=None, environment
=None): 
 230             startIn 
= str(os
.getcwd()) 
 231         startIn 
= os
.path
.abspath(startIn
) 
 233         if arguments 
and arguments 
!= " ": 
 234             command 
= self
._cmd 
+ ' ' + arguments
 
 238         if _VERBOSE
: print "start debugger executable: " + command 
+ "\n" 
 239         self
._process 
= process
.ProcessOpen(command
, mode
='b', cwd
=startIn
, env
=environment
) 
 240         # Kick off threads to read stdout and stderr and write them 
 241         # to our text control. 
 242         self
._stdOutReader 
= OutputReaderThread(self
._process
.stdout
, self
._stdOutCallback
, callbackOnExit
=self
._callbackOnExit
) 
 243         self
._stdOutReader
.start() 
 244         self
._stdErrReader 
= OutputReaderThread(self
._process
.stderr
, self
._stdErrCallback
, accumulate
=False) 
 245         self
._stdErrReader
.start() 
 247     def DoStopExecution(self
): 
 248         # See comment on PythonDebuggerUI.StopExecution 
 249         if(self
._process 
!= None): 
 250             self
._stdOutReader
.AskToStop() 
 251             self
._stdErrReader
.AskToStop() 
 253                 self
._process
.kill(gracePeriod
=2.0) 
 258     def GetExecPath(self
): 
 261 class RunCommandUI(wx
.Panel
): 
 264     def ShutdownAllRunners(): 
 265         # See comment on PythonDebuggerUI.StopExecution 
 266         for runner 
in RunCommandUI
.runners
: 
 268                 runner
.StopExecution(None) 
 269             except wx
._core
.PyDeadObjectError
: 
 271         RunCommandUI
.runners 
= [] 
 272     ShutdownAllRunners 
= staticmethod(ShutdownAllRunners
) 
 274     def __init__(self
, parent
, id, fileName
): 
 275         wx
.Panel
.__init
__(self
, parent
, id) 
 276         self
._noteBook 
= parent
 
 278         threading
._VERBOSE 
= _VERBOSE
 
 280         self
.KILL_PROCESS_ID 
= wx
.NewId() 
 281         self
.CLOSE_TAB_ID 
= wx
.NewId() 
 284         # GUI Initialization follows 
 285         sizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 286         self
._tb 
= tb 
= wx
.ToolBar(self
,  -1, wx
.DefaultPosition
, (30,1000), wx
.TB_VERTICAL| wx
.TB_FLAT
, "Runner" ) 
 287         tb
.SetToolBitmapSize((16,16)) 
 288         sizer
.Add(tb
, 0, wx
.EXPAND|wx
.ALIGN_LEFT|wx
.ALL
, 1) 
 290         close_bmp 
= getCloseBitmap() 
 291         tb
.AddSimpleTool( self
.CLOSE_TAB_ID
, close_bmp
, _('Close Window')) 
 292         wx
.EVT_TOOL(self
, self
.CLOSE_TAB_ID
, self
.OnToolClicked
) 
 294         stop_bmp 
= getStopBitmap() 
 295         tb
.AddSimpleTool(self
.KILL_PROCESS_ID
, stop_bmp
, _("Stop the Run.")) 
 296         wx
.EVT_TOOL(self
, self
.KILL_PROCESS_ID
, self
.OnToolClicked
) 
 299         self
._textCtrl 
= STCTextEditor
.TextCtrl(self
, wx
.NewId()) #id) 
 300         sizer
.Add(self
._textCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1) 
 301         self
._textCtrl
.SetViewLineNumbers(False) 
 302         self
._textCtrl
.SetReadOnly(True) 
 303         if wx
.Platform 
== '__WXMSW__': 
 307         self
._textCtrl
.SetFont(wx
.Font(9, wx
.DEFAULT
, wx
.NORMAL
, wx
.NORMAL
, faceName 
= font
)) 
 308         self
._textCtrl
.SetFontColor(wx
.BLACK
) 
 309         self
._textCtrl
.StyleClearAll() 
 311         wx
.stc
.EVT_STC_DOUBLECLICK(self
._textCtrl
, self
._textCtrl
.GetId(), self
.OnDoubleClick
) 
 316         self
._stopped 
= False 
 317         # Executor initialization 
 318         self
._executor 
= Executor(fileName
, self
, callbackOnExit
=self
.ExecutorFinished
) 
 319         self
.Bind(EVT_UPDATE_STDTEXT
, self
.AppendText
) 
 320         self
.Bind(EVT_UPDATE_ERRTEXT
, self
.AppendErrorText
) 
 322         RunCommandUI
.runners
.append(self
) 
 325         # See comment on PythonDebuggerUI.StopExecution 
 326         self
._executor
.DoStopExecution() 
 328     def Execute(self
, initialArgs
, startIn
, environment
, onWebServer 
= False): 
 329         self
._executor
.Execute(initialArgs
, startIn
, environment
) 
 331     def ExecutorFinished(self
): 
 332         self
._tb
.EnableTool(self
.KILL_PROCESS_ID
, False) 
 333         nb 
= self
.GetParent() 
 334         for i 
in range(0,nb
.GetPageCount()): 
 335             if self 
== nb
.GetPage(i
): 
 336                 text 
= nb
.GetPageText(i
) 
 337                 newText 
= text
.replace("Running", "Finished") 
 338                 nb
.SetPageText(i
, newText
) 
 341     def StopExecution(self
): 
 342         if not self
._stopped
: 
 344             self
.Unbind(EVT_UPDATE_STDTEXT
) 
 345             self
.Unbind(EVT_UPDATE_ERRTEXT
) 
 346             self
._executor
.DoStopExecution() 
 348     def AppendText(self
, event
): 
 349         self
._textCtrl
.SetReadOnly(False) 
 350         self
._textCtrl
.AddText(event
.value
) 
 351         self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount()) 
 352         self
._textCtrl
.SetReadOnly(True) 
 354     def AppendErrorText(self
, event
): 
 355         self
._textCtrl
.SetReadOnly(False) 
 356         self
._textCtrl
.SetFontColor(wx
.RED
) 
 357         self
._textCtrl
.StyleClearAll() 
 358         self
._textCtrl
.AddText(event
.value
) 
 359         self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount()) 
 360         self
._textCtrl
.SetFontColor(wx
.BLACK
) 
 361         self
._textCtrl
.StyleClearAll() 
 362         self
._textCtrl
.SetReadOnly(True) 
 364     def StopAndRemoveUI(self
, event
): 
 367         index 
= self
._noteBook
.GetSelection() 
 368         self
._noteBook
.GetPage(index
).Show(False) 
 369         self
._noteBook
.RemovePage(index
) 
 371     #------------------------------------------------------------------------------ 
 373     #----------------------------------------------------------------------------- 
 375     def OnToolClicked(self
, event
): 
 378         if id == self
.KILL_PROCESS_ID
: 
 381         elif id == self
.CLOSE_TAB_ID
: 
 382             self
.StopAndRemoveUI(event
) 
 384     def OnDoubleClick(self
, event
): 
 385         # Looking for a stack trace line. 
 386         lineText
, pos 
= self
._textCtrl
.GetCurLine() 
 387         fileBegin 
= lineText
.find("File \"") 
 388         fileEnd 
= lineText
.find("\", line ") 
 389         lineEnd 
= lineText
.find(", in ") 
 390         if lineText 
== "\n" or  fileBegin 
== -1 or fileEnd 
== -1 or lineEnd 
== -1: 
 391             # Check the line before the one that was clicked on 
 392             lineNumber 
= self
._textCtrl
.GetCurrentLine() 
 395             lineText 
= self
._textCtrl
.GetLine(lineNumber 
- 1) 
 396             fileBegin 
= lineText
.find("File \"") 
 397             fileEnd 
= lineText
.find("\", line ") 
 398             lineEnd 
= lineText
.find(", in ") 
 399             if lineText 
== "\n" or  fileBegin 
== -1 or fileEnd 
== -1 or lineEnd 
== -1: 
 402         filename 
= lineText
[fileBegin 
+ 6:fileEnd
] 
 403         lineNum 
= int(lineText
[fileEnd 
+ 8:lineEnd
]) 
 406         openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
 407         for openDoc 
in openDocs
: 
 408             if openDoc
.GetFilename() == filename
: 
 409                 foundView 
= openDoc
.GetFirstView() 
 413             doc 
= wx
.GetApp().GetDocumentManager().CreateDocument(filename
, wx
.lib
.docview
.DOC_SILENT
) 
 414             foundView 
= doc
.GetFirstView() 
 417             foundView
.GetFrame().SetFocus() 
 419             foundView
.GotoLine(lineNum
) 
 420             startPos 
= foundView
.PositionFromLine(lineNum
) 
 421             lineText 
= foundView
.GetCtrl().GetLine(lineNum 
- 1) 
 422             foundView
.SetSelection(startPos
, startPos 
+ len(lineText
.rstrip("\n"))) 
 423             import OutlineService
 
 424             wx
.GetApp().GetService(OutlineService
.OutlineService
).LoadOutline(foundView
, position
=startPos
) 
 428 DEFAULT_HOST 
= 'localhost' 
 431 class BaseDebuggerUI(wx
.Panel
): 
 434     def NotifyDebuggersOfBreakpointChange(): 
 435         for debugger 
in BaseDebuggerUI
.debuggers
: 
 436             debugger
.BreakPointChange() 
 438     NotifyDebuggersOfBreakpointChange 
= staticmethod(NotifyDebuggersOfBreakpointChange
) 
 440     def DebuggerRunning(): 
 441         for debugger 
in BaseDebuggerUI
.debuggers
: 
 442             if debugger
._executor
: 
 445     DebuggerRunning 
= staticmethod(DebuggerRunning
) 
 447     def DebuggerInWait(): 
 448         for debugger 
in BaseDebuggerUI
.debuggers
: 
 449             if debugger
._executor
: 
 450                 if debugger
._callback
._waiting
: 
 453     DebuggerInWait 
= staticmethod(DebuggerInWait
) 
 455     def DebuggerPastAutoContinue(): 
 456         for debugger 
in BaseDebuggerUI
.debuggers
: 
 457             if debugger
._executor
: 
 458                 if debugger
._callback
._waiting 
and not debugger
._callback
._autoContinue
: 
 461     DebuggerPastAutoContinue 
= staticmethod(DebuggerPastAutoContinue
) 
 463     def ShutdownAllDebuggers(): 
 464         for debugger 
in BaseDebuggerUI
.debuggers
: 
 466                 debugger
.StopExecution(None) 
 467             except wx
._core
.PyDeadObjectError
: 
 469         BaseDebuggerUI
.debuggers 
= [] 
 470     ShutdownAllDebuggers 
= staticmethod(ShutdownAllDebuggers
) 
 472     def __init__(self
, parent
, id): 
 473         wx
.Panel
.__init
__(self
, parent
, id) 
 474         self
._parentNoteBook 
= parent
 
 477         self
._executor 
= None 
 478         self
._callback 
= None 
 479         self
._stopped 
= False 
 481         BaseDebuggerUI
.debuggers
.append(self
) 
 483         self
.Bind(EVT_UPDATE_STDTEXT
, self
.AppendText
) 
 484         self
.Bind(EVT_UPDATE_ERRTEXT
, self
.AppendErrorText
) 
 485         self
._executor 
= None 
 487         self
.STEP_ID 
= wx
.NewId() 
 488         self
.CONTINUE_ID 
= wx
.NewId() 
 489         self
.STEP_OUT_ID 
= wx
.NewId() 
 490         self
.NEXT_ID 
= wx
.NewId() 
 491         self
.KILL_PROCESS_ID 
= wx
.NewId() 
 492         self
.CLOSE_WINDOW_ID 
= wx
.NewId() 
 493         self
.BREAK_INTO_DEBUGGER_ID 
= wx
.NewId() 
 494         self
.CLEAR_ID 
= wx
.NewId() 
 495         self
.ADD_WATCH_ID 
= wx
.NewId() 
 496         sizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 497         self
._tb 
= tb 
= wx
.ToolBar(self
,  -1, wx
.DefaultPosition
, (1000,30), wx
.TB_HORIZONTAL| wx
.NO_BORDER| wx
.TB_FLAT| wx
.TB_TEXT
, "Debugger" ) 
 498         sizer
.Add(tb
, 0, wx
.EXPAND |wx
.ALIGN_LEFT|wx
.ALL
, 1) 
 499         tb
.SetToolBitmapSize((16,16)) 
 501         close_bmp 
= getCloseBitmap() 
 502         tb
.AddSimpleTool( self
.CLOSE_WINDOW_ID
, close_bmp
, _('Close Window')) 
 503         wx
.EVT_TOOL(self
, self
.CLOSE_WINDOW_ID
, self
.StopAndRemoveUI
) 
 505         stop_bmp 
= getStopBitmap() 
 506         tb
.AddSimpleTool( self
.KILL_PROCESS_ID
, stop_bmp
, _("Stop Debugging")) 
 507         wx
.EVT_TOOL(self
, self
.KILL_PROCESS_ID
, self
.StopExecution
) 
 511         break_bmp 
= getBreakBitmap() 
 512         tb
.AddSimpleTool( self
.BREAK_INTO_DEBUGGER_ID
, break_bmp
, _("Break into Debugger")) 
 513         wx
.EVT_TOOL(self
, self
.BREAK_INTO_DEBUGGER_ID
, self
.BreakExecution
) 
 517         continue_bmp 
= getContinueBitmap() 
 518         tb
.AddSimpleTool( self
.CONTINUE_ID
, continue_bmp
, _("Continue Execution")) 
 519         wx
.EVT_TOOL(self
, self
.CONTINUE_ID
, self
.OnContinue
) 
 520         self
.Bind(EVT_DEBUG_INTERNAL
, self
.OnContinue
) 
 523         next_bmp 
= getNextBitmap() 
 524         tb
.AddSimpleTool( self
.NEXT_ID
, next_bmp
, _("Step to next line")) 
 525         wx
.EVT_TOOL(self
, self
.NEXT_ID
, self
.OnNext
) 
 527         step_bmp 
= getStepInBitmap() 
 528         tb
.AddSimpleTool( self
.STEP_ID
, step_bmp
, _("Step in")) 
 529         wx
.EVT_TOOL(self
, self
.STEP_ID
, self
.OnSingleStep
) 
 531         stepOut_bmp 
= getStepReturnBitmap() 
 532         tb
.AddSimpleTool(self
.STEP_OUT_ID
, stepOut_bmp
, _("Stop at function return")) 
 533         wx
.EVT_TOOL(self
, self
.STEP_OUT_ID
, self
.OnStepOut
) 
 537             watch_bmp 
= getAddWatchBitmap() 
 538             tb
.AddSimpleTool(self
.ADD_WATCH_ID
, watch_bmp
, _("Add a watch")) 
 539             wx
.EVT_TOOL(self
, self
.ADD_WATCH_ID
, self
.OnAddWatch
) 
 542         clear_bmp 
= getClearOutputBitmap() 
 543         tb
.AddSimpleTool(self
.CLEAR_ID
, clear_bmp
, _("Clear output pane")) 
 544         wx
.EVT_TOOL(self
, self
.CLEAR_ID
, self
.OnClearOutput
) 
 546         self
._toolEnabled 
= True 
 547         self
.framesTab 
= None 
 548         self
.DisableWhileDebuggerRunning() 
 549         self
.framesTab 
= self
.MakeFramesUI(self
, wx
.NewId(), None) 
 550         sizer
.Add(self
.framesTab
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1) 
 551         self
._statusBar 
= wx
.StatusBar( self
, -1) 
 552         self
._statusBar
.SetFieldsCount(1) 
 553         sizer
.Add(self
._statusBar
, 0, wx
.EXPAND |wx
.ALIGN_LEFT|wx
.ALL
, 1) 
 554         self
.SetStatusText("Starting debug...") 
 559     def OnSingleStep(self
, event
): 
 560         self
._callback
.SingleStep() 
 562     def OnContinue(self
, event
): 
 563         self
._callback
.Continue() 
 565     def OnStepOut(self
, event
): 
 566         self
._callback
.Return() 
 568     def OnNext(self
, event
): 
 569         self
._callback
.Next() 
 571     def BreakPointChange(self
): 
 572         if not self
._stopped
: 
 573             self
._callback
.PushBreakpoints() 
 574         self
.framesTab
.PopulateBPList() 
 577         # See comment on PythonDebuggerUI.StopExecution 
 578         self
.StopExecution(None) 
 580     def DisableWhileDebuggerRunning(self
): 
 581         if self
._toolEnabled
: 
 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) 
 589                 self
._tb
.EnableTool(self
.ADD_WATCH_ID
, False) 
 591             self
.DeleteCurrentLineMarkers() 
 594                 self
.framesTab
.ClearWhileRunning() 
 596             self
._toolEnabled 
= False 
 598     def EnableWhileDebuggerStopped(self
): 
 599         self
._tb
.EnableTool(self
.STEP_ID
, True) 
 600         self
._tb
.EnableTool(self
.CONTINUE_ID
, True) 
 601         self
._tb
.EnableTool(self
.STEP_OUT_ID
, True) 
 602         self
._tb
.EnableTool(self
.NEXT_ID
, True) 
 603         self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, False) 
 604         self
._tb
.EnableTool(self
.KILL_PROCESS_ID
, True) 
 607             self
._tb
.EnableTool(self
.ADD_WATCH_ID
, True) 
 609         self
._toolEnabled 
= True 
 611     def DisableAfterStop(self
): 
 612         if self
._toolEnabled
: 
 613             self
.DisableWhileDebuggerRunning() 
 614             self
._tb
.EnableTool(self
.BREAK_INTO_DEBUGGER_ID
, False) 
 615             self
._tb
.EnableTool(self
.KILL_PROCESS_ID
, False) 
 617     def ExecutorFinished(self
): 
 618         if _VERBOSE
: print "In ExectorFinished" 
 620             self
.DisableAfterStop() 
 621         except wx
._core
.PyDeadObjectError
: 
 624             nb 
= self
.GetParent() 
 625             for i 
in range(0, nb
.GetPageCount()): 
 626                 if self 
== nb
.GetPage(i
): 
 627                     text 
= nb
.GetPageText(i
) 
 628                     newText 
= text
.replace("Debugging", "Finished") 
 629                     nb
.SetPageText(i
, newText
) 
 630                     if _VERBOSE
: print "In ExectorFinished, changed tab title." 
 633             if _VERBOSE
: print "In ExectorFinished, got exception" 
 635     def SetStatusText(self
, text
): 
 636         self
._statusBar
.SetStatusText(text
,0) 
 638     def BreakExecution(self
, event
): 
 639         self
._callback
.BreakExecution() 
 641     def StopExecution(self
, event
): 
 642         self
._callback
.ShutdownServer() 
 644     def Execute(self
, initialArgs
, startIn
, environment
, onWebServer 
= False): 
 645         assert False, "Execute not overridden" 
 647     def SynchCurrentLine(self
, filename
, lineNum
, noArrow
=False): 
 648         self
.DeleteCurrentLineMarkers() 
 650         # Filename will be <string> if we're in a bit of code that was executed from 
 651         # a string (rather than a file). I haven't been able to get the original string 
 653         if filename 
== '<string>': 
 656         openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
 657         for openDoc 
in openDocs
: 
 658             # This ugliness to prevent comparison failing because the drive letter 
 659             # gets lowercased occasionally. Don't know why that happens or why  it 
 660             # only happens occasionally. 
 661             if DebuggerService
.ComparePaths(openDoc
.GetFilename(),filename
): 
 662                 foundView 
= openDoc
.GetFirstView() 
 667                 print "filename=", filename
 
 668             doc 
= wx
.GetApp().GetDocumentManager().CreateDocument(DebuggerService
.ExpandPath(filename
), wx
.lib
.docview
.DOC_SILENT
) 
 669             foundView 
= doc
.GetFirstView() 
 672             foundView
.GetFrame().SetFocus() 
 674             foundView
.GotoLine(lineNum
) 
 675             startPos 
= foundView
.PositionFromLine(lineNum
) 
 678             foundView
.GetCtrl().MarkerAdd(lineNum 
-1, CodeEditor
.CodeCtrl
.CURRENT_LINE_MARKER_NUM
) 
 680     def DeleteCurrentLineMarkers(self
): 
 681         openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
 682         for openDoc 
in openDocs
: 
 683             if(isinstance(openDoc
, CodeEditor
.CodeDocument
)): 
 684                 openDoc
.GetFirstView().GetCtrl().ClearCurrentLineMarkers() 
 686     def StopAndRemoveUI(self
, event
): 
 687         self
.StopExecution(None) 
 688         if self 
in BaseDebuggerUI
.debuggers
: 
 689             BaseDebuggerUI
.debuggers
.remove(self
) 
 690         index 
= self
._parentNoteBook
.GetSelection() 
 691         self
._parentNoteBook
.GetPage(index
).Show(False) 
 692         self
._parentNoteBook
.RemovePage(index
) 
 694     def OnAddWatch(self
, event
): 
 696             self
.framesTab
.OnWatch(event
) 
 698     def MakeFramesUI(self
, parent
, id, debugger
): 
 699         assert False, "MakeFramesUI not overridden" 
 701     def AppendText(self
, event
): 
 702         self
.framesTab
.AppendText(event
.value
) 
 704     def AppendErrorText(self
, event
): 
 705         self
.framesTab
.AppendErrorText(event
.value
) 
 707     def OnClearOutput(self
, event
): 
 708         self
.framesTab
.ClearOutput(None) 
 710     def SwitchToOutputTab(self
): 
 711         self
.framesTab
.SwitchToOutputTab() 
 714 class PHPDebuggerUI(BaseDebuggerUI
): 
 715     DEFAULT_LISTENER_HOST     
= "127.0.0.1" 
 716     DEFAULT_LISTENER_PORT     
= 10001 
 717     DEFAULT_DBG_MOD_TIMEOUT   
= 300 
 718     DEFAULT_DBG_MAX_EXEC_TIME 
= 240 
 721     def __init__(self
, parent
, id, command
, service
): 
 722         BaseDebuggerUI
.__init
__(self
, parent
, id) 
 723         #Note host and port need to come out of options or a pool. 
 724         self
._dbgHost        
= PHPDebuggerUI
.DEFAULT_LISTENER_HOST
 
 725         self
._dbgPort        
= PHPDebuggerUI
.DEFAULT_LISTENER_PORT
 
 726         self
._dbgTimeout     
= PHPDebuggerUI
.DEFAULT_DBG_MOD_TIMEOUT
 
 727         self
._dbgMaxExecTime 
= PHPDebuggerUI
.DEFAULT_DBG_MAX_EXEC_TIME
 
 728         self
._dbgSessId      
= None 
 729         self
._dbgSessParam   
= None 
 730         self
._dbgPhpIniFile  
= None 
 731         self
._callback       
= PHPDebugger
.PHPDebuggerCallback(self
, service
, self
._dbgHost
, self
._dbgPort
) 
 732         self
._executor       
= Executor(command
, self
) 
 733         self
._service        
= service
 
 734         self
._stopped        
= False 
 735         self
._allStopped     
= False 
 737         self
._createPhpDbgSess
() 
 739     def showErrorDialog(self
, message
, title
): 
 740         wx
.MessageBox(_(message
), _(title
)) 
 743     def _createPhpDbgSess(self
): 
 744         currTimeStr                
= str(time
.time()) 
 745         (secStr
, usecStr
)          = currTimeStr
.split('.') 
 746         secLongInt                 
= long(secStr
) 
 747         usecLongInt                
= long(usecStr
) 
 748         self
._dbgSessId            
= "%06ld%06ld%04d" % (secLongInt
, usecLongInt
, PHPDebuggerUI
.dbgSessSeqId
) 
 749         PHPDebuggerUI
.dbgSessSeqId 
= PHPDebuggerUI
.dbgSessSeqId 
+ 1 
 750         self
._dbgSessParam         
= "DBGSESSID=%s@clienthost:%d" % (self
._dbgSessId
, self
._dbgPort
) 
 753             print "phpDbgParam=%s" % self
._dbgSessParam
 
 755         self
._service
.SetPhpDbgParam(self
._dbgSessParam
) 
 757     def _preparePhpIniFile(self
): 
 760         phpCgiExec 
= Executor
.GetPHPExecutablePath() 
 761         phpExec    
= phpCgiExec
.replace("php-cgi", "php") 
 762         iniPath    
= self
._getPhpIniFromRunningPhp
(phpExec
) 
 765             iniDbgPath 
= os
.path
.normpath(iniPath 
+ ".ag_debug_enabled") 
 766             dbgFile    
= open(iniDbgPath
, "w") 
 767             oriFile    
= open(iniPath
, "r") 
 770                 oneOriLine 
= oriFile
.readline() 
 774                 if not oneOriLine
.startswith("debugger.") and not oneOriLine
.startswith("max_execution_time="): 
 775                     dbgFile
.write(oneOriLine
) 
 780                 dbgExtFile 
= "php_dbg.dll" 
 782                 dbgExtFile 
= "dbg.so" 
 785             # TODO: we should make all of these options configurable. 
 787             configStr 
= "\n; ===============================================================\n; The followings are added by ActiveGrid IDE PHP Debugger Runtime\n; ===============================================================\n\n; As we are running with the dbg module, it takes a much longer time for each script to run.\nmax_execution_time=%d\n\n[debugger]\nextension=%s\ndebugger.enabled=On\ndebugger.JIT_enabled=On\ndebugger.JIT_host=%s\ndebugger.JIT_port=%d\ndebugger.fail_silently=Off\ndebugger.timeout_seconds=%d\ndebugger.ignore_nops=Off\ndebugger.enable_session_cookie=On\ndebugger.session_nocache=On\ndebugger.profiler_enabled=Off\n" % (self
._dbgMaxExecTime
, dbgExtFile
, self
._dbgHost
, self
._dbgPort
, self
._dbgTimeout
) 
 788             dbgFile
.write(configStr
) 
 792             #TODO: print stack trace. 
 793             print "Caught exceptions while minipulating php.ini files" 
 796             self
._dbgPhpIniFile 
= iniDbgPath
 
 798             self
._dbgPhpIniFile 
= None 
 800     def _getPhpIniFromRunningPhp(self
, phpExec
): 
 804         if cmdEnv
.has_key('PYTHONPATH'): 
 805             del cmdEnv
['PYTHONPATH'] 
 807         cmdLine 
= [phpExec
, "-r", "phpinfo();"] 
 808         phpProc 
= subprocess
.Popen(args
=cmdLine
, bufsize
=0, executable
=None, stdin
=subprocess
.PIPE
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, preexec_fn
=None, close_fds
=False, shell
=False, cwd
=None, env
=os
.environ
, universal_newlines
=False, startupinfo
=None, creationflags
=0) 
 809         phpOutput 
= phpProc
.stdout
 
 811         phpIniPattern 
= "Configuration File (php.ini) Path => " 
 813             oneLine 
= phpOutput
.readline() 
 817             if oneLine
.startswith(phpIniPattern
): 
 818                 if oneLine
.endswith("\n"): 
 819                     endIndex   
= oneLine
.index("\n") 
 820                     phpIniPath 
= oneLine
[len(phpIniPattern
):endIndex
] 
 822                     phpIniPath 
= oneLine
[len(phpIniPattern
):] 
 824                 if phpIniPath 
and len(phpIniPath
) > 0: 
 825                     phpIniPath 
= os
.path
.normpath(phpIniPath
) 
 831             print "php.ini path is: %s" % repr(phpIniPath
) 
 835     def Execute(self
, initialArgs
, startIn
, environment
, onWebServer 
= False): 
 836         self
._preparePhpIniFile
() 
 837         self
._callback
.Start() 
 840             if self
._dbgPhpIniFile
: 
 841                 args 
= '-c "' + self
._dbgPhpIniFile 
+ '" ' + initialArgs
 
 845             self
._executor
.Execute(args
, startIn
, environment
) 
 847     def StopExecution(self
, event
): 
 848         # This is a general comment on shutdown for the running and debugged processes. Basically, the 
 849         # current state of this is the result of trial and error coding. The common problems were memory 
 850         # access violations and threads that would not exit. Making the OutputReaderThreads daemons seems 
 851         # to have side-stepped the hung thread issue. Being very careful not to touch things after calling 
 852         # process.py:ProcessOpen.kill() also seems to have fixed the memory access violations, but if there 
 853         # were more ugliness discovered I would not be surprised. If anyone has any help/advice, please send 
 854         # it on to mfryer@activegrid.com. 
 855         if not self
._allStopped
: 
 858                 self
.DisableAfterStop() 
 859             except wx
._core
.PyDeadObjectError
: 
 864                 # If this is called by clicking the "Stop" button, we only stop 
 865                 # the current running php script, and keep the listener 
 869                     self
._callback
.ShutdownServer(stopLsnr 
= False) 
 871                     self
._callback
.ShutdownServer(stopLsnr 
= True) 
 872                     self
._allStopped 
= True 
 874                 tp
,val
,tb 
= sys
.exc_info() 
 875                 traceback
.print_exception(tp
, val
, tb
) 
 878                 self
.DeleteCurrentLineMarkers() 
 884                     self
._executor
.DoStopExecution() 
 885                     self
._executor 
= None 
 887                 tp
,val
,tb 
= sys
.exc_info() 
 888                 traceback
.print_exception(tp
, val
, tb
) 
 890     def MakeFramesUI(self
, parent
, id, debugger
): 
 891         return PHPFramesUI(parent
, id, self
) 
 893     def LoadPHPFramesList(self
, stackList
): 
 894         self
.framesTab
.LoadFramesList(stackList
) 
 897     # TODO: this is a hack to overwrite BaseDebuggerUI's function.  The purpose 
 898     # is to always push breakpoints no matter if a php is running or not.  If 
 899     # no php is running, an exception will be thrown and handled like nothing 
 902     def BreakPointChange(self
): 
 903         self
._callback
.PushBreakpoints() 
 904         self
.framesTab
.PopulateBPList() 
 907 class PythonDebuggerUI(BaseDebuggerUI
): 
 908     debuggerPortList 
= None 
 910     def GetAvailablePort(): 
 911         for index 
in range( 0, len(PythonDebuggerUI
.debuggerPortList
)): 
 912             port 
= PythonDebuggerUI
.debuggerPortList
[index
] 
 913             if PythonDebuggerUI
.PortAvailable(port
): 
 914                 PythonDebuggerUI
.debuggerPortList
.pop(index
) 
 916         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")) 
 917         assert False, "Out of ports for debugger." 
 919     GetAvailablePort 
= staticmethod(GetAvailablePort
) 
 921     def ReturnPortToPool(port
): 
 922         config 
= wx
.ConfigBase_Get() 
 923         startingPort 
= config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
) 
 924         val 
= int(startingPort
) + int(PORT_COUNT
) 
 925         if int(port
) >= startingPort 
and (int(port
) <= val
): 
 926             PythonDebuggerUI
.debuggerPortList
.append(int(port
)) 
 928     ReturnPortToPool 
= staticmethod(ReturnPortToPool
) 
 930     def PortAvailable(port
): 
 931         config 
= wx
.ConfigBase_Get() 
 932         hostname 
= config
.Read("DebuggerHostName", DEFAULT_HOST
) 
 934             server 
= AGXMLRPCServer((hostname
, port
)) 
 935             server
.server_close() 
 936             if _VERBOSE
: print "Port ", str(port
), " available." 
 939             tp
,val
,tb 
= sys
.exc_info() 
 940             if _VERBOSE
: traceback
.print_exception(tp
, val
, tb
) 
 941             if _VERBOSE
: print "Port ", str(port
), " unavailable." 
 944     PortAvailable 
= staticmethod(PortAvailable
) 
 947         config 
= wx
.ConfigBase_Get() 
 948         startingPort 
= config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
) 
 949         PythonDebuggerUI
.debuggerPortList 
= range(startingPort
, startingPort 
+ PORT_COUNT
) 
 950     NewPortRange 
= staticmethod(NewPortRange
) 
 952     def __init__(self
, parent
, id, command
, service
, autoContinue
=True): 
 953         # Check for ports before creating the panel. 
 954         if not PythonDebuggerUI
.debuggerPortList
: 
 955             PythonDebuggerUI
.NewPortRange() 
 956         self
._debuggerPort 
= str(PythonDebuggerUI
.GetAvailablePort()) 
 957         self
._guiPort 
= str(PythonDebuggerUI
.GetAvailablePort()) 
 958         self
._debuggerBreakPort 
= str(PythonDebuggerUI
.GetAvailablePort()) 
 959         BaseDebuggerUI
.__init
__(self
, parent
, id) 
 960         self
._command 
= command
 
 961         self
._service 
= service
 
 962         config 
= wx
.ConfigBase_Get() 
 963         self
._debuggerHost 
= self
._guiHost 
= config
.Read("DebuggerHostName", DEFAULT_HOST
) 
 965         url 
= 'http://' + self
._debuggerHost 
+ ':' + self
._debuggerPort 
+ '/' 
 966         self
._breakURL 
= 'http://' + self
._debuggerHost 
+ ':' + self
._debuggerBreakPort 
+ '/' 
 967         self
._callback 
= PythonDebuggerCallback(self
._guiHost
, self
._guiPort
, url
, self
._breakURL
, self
, autoContinue
) 
 968         if DebuggerHarness
.__file
__.find('library.zip') > 0: 
 970                 fname 
= DebuggerHarness
.__file
__ 
 971                 parts 
= fname
.split('library.zip') 
 972                 path 
= os
.path
.join(parts
[0],'activegrid', 'tool', 'DebuggerHarness.py') 
 974                 tp
, val
, tb 
= sys
.exc_info() 
 975                 traceback
.print_exception(tp
, val
, tb
) 
 978             print "Starting debugger on these ports: %s, %s, %s" % (str(self
._debuggerPort
) , str(self
._guiPort
) , str(self
._debuggerBreakPort
)) 
 979             path 
= DebuggerService
.ExpandPath(DebuggerHarness
.__file
__) 
 980         self
._executor 
= Executor(path
, self
, self
._debuggerHost
, \
 
 981                                                 self
._debuggerPort
, self
._debuggerBreakPort
, self
._guiHost
, self
._guiPort
, self
._command
, callbackOnExit
=self
.ExecutorFinished
) 
 983         self
._stopped 
= False 
 985     def LoadPythonFramesList(self
, framesXML
): 
 986         self
.framesTab
.LoadFramesList(framesXML
) 
 988     def Execute(self
, initialArgs
, startIn
, environment
, onWebServer 
= False): 
 989         self
._callback
.Start() 
 990         self
._executor
.Execute(initialArgs
, startIn
, environment
) 
 991         self
._callback
.WaitForRPC() 
 994     def StopExecution(self
, event
): 
 995         # This is a general comment on shutdown for the running and debugged processes. Basically, the 
 996         # current state of this is the result of trial and error coding. The common problems were memory 
 997         # access violations and threads that would not exit. Making the OutputReaderThreads daemons seems 
 998         # to have side-stepped the hung thread issue. Being very careful not to touch things after calling 
 999         # process.py:ProcessOpen.kill() also seems to have fixed the memory access violations, but if there 
1000         # were more ugliness discovered I would not be surprised. If anyone has any help/advice, please send 
1001         # it on to mfryer@activegrid.com. 
1002         if not self
._stopped
: 
1003             self
._stopped 
= True 
1005                 self
.DisableAfterStop() 
1006             except wx
._core
.PyDeadObjectError
: 
1009                 self
._callback
.ShutdownServer() 
1011                 tp
,val
,tb 
= sys
.exc_info() 
1012                 traceback
.print_exception(tp
, val
, tb
) 
1015                 self
.DeleteCurrentLineMarkers() 
1019                 PythonDebuggerUI
.ReturnPortToPool(self
._debuggerPort
) 
1020                 PythonDebuggerUI
.ReturnPortToPool(self
._guiPort
) 
1021                 PythonDebuggerUI
.ReturnPortToPool(self
._debuggerBreakPort
) 
1026                     self
._executor
.DoStopExecution() 
1027                     self
._executor 
= None 
1029                 tp
,val
,tb 
= sys
.exc_info() 
1030                 traceback
.print_exception(tp
, val
, tb
) 
1033     def MakeFramesUI(self
, parent
, id, debugger
): 
1034         panel 
= PythonFramesUI(parent
, id, self
) 
1038 class BreakpointsUI(wx
.Panel
): 
1039     def __init__(self
, parent
, id, ui
): 
1040         wx
.Panel
.__init
__(self
, parent
, id) 
1042         self
.currentItem 
= None 
1043         self
.clearBPID 
= wx
.NewId() 
1044         self
.Bind(wx
.EVT_MENU
, self
.ClearBreakPoint
, id=self
.clearBPID
) 
1045         self
.syncLineID 
= wx
.NewId() 
1046         self
.Bind(wx
.EVT_MENU
, self
.SyncBPLine
, id=self
.syncLineID
) 
1047         sizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
1049         self
._bpListCtrl 
= wx
.ListCtrl(p1
, -1, pos
=wx
.DefaultPosition
, size
=(1000,1000), style
=wx
.LC_REPORT
) 
1050         sizer
.Add(self
._bpListCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1) 
1051         self
._bpListCtrl
.InsertColumn(0, "File") 
1052         self
._bpListCtrl
.InsertColumn(1, "Line") 
1053         self
._bpListCtrl
.InsertColumn(2, "Path") 
1054         self
._bpListCtrl
.SetColumnWidth(0, 150) 
1055         self
._bpListCtrl
.SetColumnWidth(1, 50) 
1056         self
._bpListCtrl
.SetColumnWidth(2, 450) 
1057         self
._bpListCtrl
.Bind(wx
.EVT_LIST_ITEM_RIGHT_CLICK
, self
.OnListRightClick
) 
1058         self
.Bind(wx
.EVT_LIST_ITEM_SELECTED
, self
.ListItemSelected
, self
._bpListCtrl
) 
1059         self
.Bind(wx
.EVT_LIST_ITEM_DESELECTED
, self
.ListItemDeselected
, self
._bpListCtrl
) 
1061         def OnLeftDoubleClick(event
): 
1062             self
.SyncBPLine(event
) 
1064         wx
.EVT_LEFT_DCLICK(self
._bpListCtrl
, OnLeftDoubleClick
) 
1066         self
.PopulateBPList() 
1072     def PopulateBPList(self
): 
1073         list = self
._bpListCtrl
 
1074         list.DeleteAllItems() 
1076         bps 
= wx
.GetApp().GetService(DebuggerService
).GetMasterBreakpointDict() 
1078         for fileName 
in bps
.keys(): 
1079             shortFile 
= os
.path
.basename(fileName
) 
1080             lines 
= bps
[fileName
] 
1083                     list.InsertStringItem(index
, shortFile
) 
1084                     list.SetStringItem(index
, 1, str(line
)) 
1085                     list.SetStringItem(index
, 2, fileName
) 
1087     def OnListRightClick(self
, event
): 
1089         item 
= wx
.MenuItem(menu
, self
.clearBPID
, "Clear Breakpoint") 
1090         menu
.AppendItem(item
) 
1091         item 
= wx
.MenuItem(menu
, self
.syncLineID
, "Goto Source Line") 
1092         menu
.AppendItem(item
) 
1093         self
.PopupMenu(menu
, event
.GetPosition()) 
1096     def SyncBPLine(self
, event
): 
1097         if self
.currentItem 
!= -1: 
1098             list = self
._bpListCtrl
 
1099             fileName 
= list.GetItem(self
.currentItem
, 2).GetText() 
1100             lineNumber 
= list.GetItem(self
.currentItem
, 1).GetText() 
1101             self
._ui
.SynchCurrentLine( fileName
, int(lineNumber
) , noArrow
=True) 
1103     def ClearBreakPoint(self
, event
): 
1104         if self
.currentItem 
>= 0: 
1105             list = self
._bpListCtrl
 
1106             fileName 
= list.GetItem(self
.currentItem
, 2).GetText() 
1107             lineNumber 
= list.GetItem(self
.currentItem
, 1).GetText() 
1108             wx
.GetApp().GetService(DebuggerService
).OnToggleBreakpoint(None, line
=int(lineNumber
) -1, fileName
=fileName 
) 
1110     def ListItemSelected(self
, event
): 
1111         self
.currentItem 
= event
.m_itemIndex
 
1113     def ListItemDeselected(self
, event
): 
1114         self
.currentItem 
= -1 
1122     def __init__(self
, name
, command
, show_code
=CODE_ALL_FRAMES
): 
1124         self
._command 
= command
 
1125         self
._show
_code 
= show_code
 
1127 class WatchDialog(wx
.Dialog
): 
1128     WATCH_ALL_FRAMES 
= "Watch in all frames" 
1129     WATCH_THIS_FRAME 
= "Watch in this frame only" 
1130     WATCH_ONCE 
= "Watch once and delete" 
1131     def __init__(self
, parent
, title
, chain
): 
1132         wx
.Dialog
.__init
__(self
, parent
, -1, title
, style
=wx
.DEFAULT_DIALOG_STYLE
) 
1134         self
.label_2 
= wx
.StaticText(self
, -1, "Watch Name:") 
1135         self
._watchNameTextCtrl 
= wx
.TextCtrl(self
, -1, "") 
1136         self
.label_3 
= wx
.StaticText(self
, -1, "eval(", style
=wx
.ALIGN_RIGHT
) 
1137         self
._watchValueTextCtrl 
= wx
.TextCtrl(self
, -1, "") 
1138         self
.label_4 
= wx
.StaticText(self
, -1, ",frame.f_globals, frame.f_locals)") 
1139         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
) 
1141         self
._okButton 
= wx
.Button(self
, wx
.ID_OK
, "OK") 
1142         self
._okButton
.SetDefault() 
1143         self
._okButton
.SetHelpText(_("The OK button completes the dialog")) 
1144         def OnOkClick(event
): 
1145             if self
._watchNameTextCtrl
.GetValue() == "": 
1146                 wx
.MessageBox(_("You must enter a name for the watch."), _("Add Watch")) 
1148             if self
._watchValueTextCtrl
.GetValue() == "": 
1149                 wx
.MessageBox(_("You must enter some code to run for the watch."), _("Add Watch")) 
1151             self
.EndModal(wx
.ID_OK
) 
1152         self
.Bind(wx
.EVT_BUTTON
, OnOkClick
, self
._okButton
) 
1154         self
._cancelButton 
= wx
.Button(self
, wx
.ID_CANCEL
, _("Cancel")) 
1155         self
._cancelButton
.SetHelpText(_("The Cancel button cancels the dialog.")) 
1157         self
.__set
_properties
() 
1160     def GetSettings(self
): 
1161         return self
._watchNameTextCtrl
.GetValue(), self
._watchValueTextCtrl
.GetValue(), self
.GetSendFrame(), self
.GetRunOnce() 
1163     def GetSendFrame(self
): 
1164         return (WatchDialog
.WATCH_ALL_FRAMES 
!= self
.radio_box_1
.GetStringSelection()) 
1166     def GetRunOnce(self
): 
1167         return (WatchDialog
.WATCH_ONCE 
== self
.radio_box_1
.GetStringSelection()) 
1169     def __set_properties(self
): 
1170         self
.SetTitle("Add a Watch") 
1171         #self.SetSize((400, 250)) 
1172         self
.radio_box_1
.SetSelection(0) 
1174     def __do_layout(self
): 
1175         sizer_1 
= wx
.BoxSizer(wx
.VERTICAL
) 
1176         grid_sizer_4 
= wx
.FlexGridSizer(1, 3, 5, 5) 
1177         grid_sizer_2 
= wx
.FlexGridSizer(1, 2, 5, 5) 
1178         grid_sizer_2
.Add(self
.label_2
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0) 
1179         grid_sizer_2
.Add(self
._watchNameTextCtrl
, 0, wx
.EXPAND
, 0) 
1180         grid_sizer_2
.AddGrowableCol(1) 
1181         sizer_1
.Add(grid_sizer_2
, 1, wx
.EXPAND
, 0) 
1182         grid_sizer_4
.Add(self
.label_3
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0) 
1183         grid_sizer_4
.Add(self
._watchValueTextCtrl
, 0, wx
.EXPAND
, 0) 
1184         grid_sizer_4
.AddGrowableCol(1) 
1185         grid_sizer_4
.Add(self
.label_4
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.FIXED_MINSIZE
, 0) 
1186         sizer_1
.Add(grid_sizer_4
, 0, wx
.EXPAND
, 0) 
1187         sizer_1
.Add(self
.radio_box_1
, 0, wx
.EXPAND
, 0) 
1189         box 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
1190         box
.Add(self
._okButton
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5) 
1191         box
.Add(self
._cancelButton
, 0, wx
.ALIGN_RIGHT|wx
.ALL
, 5) 
1192         sizer_1
.Add(box
, 1, wx
.EXPAND
, 0) 
1193         self
.SetSizer(sizer_1
) 
1196 class BaseFramesUI(wx
.SplitterWindow
): 
1197     def __init__(self
, parent
, id, ui
): 
1198         wx
.SplitterWindow
.__init
__(self
, parent
, id, style 
= wx
.SP_3D
) 
1200         self
._p
1 = p1 
= wx
.ScrolledWindow(self
, -1) 
1202         sizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
1203         framesLabel 
= wx
.StaticText(self
, -1, "Stack Frame:") 
1204         sizer
.Add(framesLabel
, 0, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT|wx
.LEFT
, border
=2) 
1206         self
._framesChoiceCtrl 
= wx
.Choice(p1
, -1, choices
=["                                           "]) 
1207         sizer
.Add(self
._framesChoiceCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1) 
1208         self
._framesChoiceCtrl
.Bind(wx
.EVT_LIST_ITEM_RIGHT_CLICK
, self
.OnListRightClick
) 
1209         self
.Bind(wx
.EVT_CHOICE
, self
.ListItemSelected
, self
._framesChoiceCtrl
) 
1211         sizer2 
= wx
.BoxSizer(wx
.VERTICAL
) 
1213         self
._treeCtrl 
= wx
.gizmos
.TreeListCtrl(p1
, -1, style
=wx
.TR_DEFAULT_STYLE| wx
.TR_FULL_ROW_HIGHLIGHT
) 
1214         self
._treeCtrl
.Bind(wx
.EVT_TREE_ITEM_RIGHT_CLICK
, self
.OnRightClick
) 
1215         sizer2
.Add(sizer
, 0, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1) 
1216         sizer2
.Add(self
._treeCtrl
,1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1) 
1217         tree 
= self
._treeCtrl
 
1218         tree
.AddColumn("Thing") 
1219         tree
.AddColumn("Value") 
1220         tree
.SetMainColumn(0) # the one with the tree in it... 
1221         tree
.SetColumnWidth(0, 175) 
1222         tree
.SetColumnWidth(1, 355) 
1223         self
._root 
= tree
.AddRoot("Frame") 
1224         tree
.SetPyData(self
._root
, "root") 
1225         tree
.SetItemText(self
._root
, "", 1) 
1226         tree
.Bind(wx
.EVT_TREE_ITEM_EXPANDING
, self
.IntrospectCallback
) 
1227         self
._p
2 = p2 
= wx
.Window(self
, -1) 
1228         sizer3 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
1230         p2
.Bind(wx
.EVT_SIZE
, self
.OnSize
) 
1231         self
._notebook 
= wx
.Notebook(p2
, -1, size
=(20,20)) 
1232         self
._notebook
.Hide() 
1233         sizer3
.Add(self
._notebook
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 1) 
1234         self
.consoleTab 
= self
.MakeConsoleTab(self
._notebook
, wx
.NewId()) 
1235         self
.inspectConsoleTab 
= self
.MakeInspectConsoleTab(self
._notebook
, wx
.NewId()) 
1236         self
.breakPointsTab 
= self
.MakeBreakPointsTab(self
._notebook
, wx
.NewId()) 
1237         self
._notebook
.AddPage(self
.consoleTab
, "Output") 
1238         self
._notebook
.AddPage(self
.inspectConsoleTab
, "Interact") 
1239         self
._notebook
.AddPage(self
.breakPointsTab
, "Break Points") 
1240         self
.SetMinimumPaneSize(20) 
1241         self
.SplitVertically(p1
, p2
, 550) 
1242         self
.currentItem 
= None 
1243         self
._notebook
.Show(True) 
1245     def PopulateBPList(self
): 
1246         self
.breakPointsTab
.PopulateBPList() 
1248     def OnSize(self
, event
): 
1249         self
._notebook
.SetSize(self
._p
2.GetSize()) 
1251     def OnDoubleClick(self
, event
): 
1252         # Looking for a stack trace line. 
1253         lineText
, pos 
= self
._textCtrl
.GetCurLine() 
1254         fileBegin 
= lineText
.find("File \"") 
1255         fileEnd 
= lineText
.find("\", line ") 
1256         lineEnd 
= lineText
.find(", in ") 
1257         if lineText 
== "\n" or  fileBegin 
== -1 or fileEnd 
== -1 or lineEnd 
== -1: 
1258             # Check the line before the one that was clicked on 
1259             lineNumber 
= self
._textCtrl
.GetCurrentLine() 
1260             if(lineNumber 
== 0): 
1262             lineText 
= self
._textCtrl
.GetLine(lineNumber 
- 1) 
1263             fileBegin 
= lineText
.find("File \"") 
1264             fileEnd 
= lineText
.find("\", line ") 
1265             lineEnd 
= lineText
.find(", in ") 
1266             if lineText 
== "\n" or  fileBegin 
== -1 or fileEnd 
== -1 or lineEnd 
== -1: 
1269         filename 
= lineText
[fileBegin 
+ 6:fileEnd
] 
1270         lineNum 
= int(lineText
[fileEnd 
+ 8:lineEnd
]) 
1273         openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
1274         for openDoc 
in openDocs
: 
1275             if openDoc
.GetFilename() == filename
: 
1276                 foundView 
= openDoc
.GetFirstView() 
1280             doc 
= wx
.GetApp().GetDocumentManager().CreateDocument(filename
, wx
.lib
.docview
.DOC_SILENT
) 
1281             foundView 
= doc
.GetFirstView() 
1284             foundView
.GetFrame().SetFocus() 
1285             foundView
.Activate() 
1286             foundView
.GotoLine(lineNum
) 
1287             startPos 
= foundView
.PositionFromLine(lineNum
) 
1288             lineText 
= foundView
.GetCtrl().GetLine(lineNum 
- 1) 
1289             foundView
.SetSelection(startPos
, startPos 
+ len(lineText
.rstrip("\n"))) 
1290             import OutlineService
 
1291             wx
.GetApp().GetService(OutlineService
.OutlineService
).LoadOutline(foundView
, position
=startPos
) 
1293     def MakeConsoleTab(self
, parent
, id): 
1294         panel 
= wx
.Panel(parent
, id) 
1295         sizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
1296         self
._textCtrl 
= STCTextEditor
.TextCtrl(panel
, wx
.NewId()) 
1297         sizer
.Add(self
._textCtrl
, 1, wx
.ALIGN_LEFT|wx
.ALL|wx
.EXPAND
, 2) 
1298         self
._textCtrl
.SetViewLineNumbers(False) 
1299         self
._textCtrl
.SetReadOnly(True) 
1300         if wx
.Platform 
== '__WXMSW__': 
1301             font 
= "Courier New" 
1304         self
._textCtrl
.SetFont(wx
.Font(9, wx
.DEFAULT
, wx
.NORMAL
, wx
.NORMAL
, faceName 
= font
)) 
1305         self
._textCtrl
.SetFontColor(wx
.BLACK
) 
1306         self
._textCtrl
.StyleClearAll() 
1307         wx
.stc
.EVT_STC_DOUBLECLICK(self
._textCtrl
, self
._textCtrl
.GetId(), self
.OnDoubleClick
) 
1309         panel
.SetSizer(sizer
) 
1313     def ExecuteCommand(self
, command
): 
1314         assert False, "ExecuteCommand not overridden" 
1316     def MakeInspectConsoleTab(self
, parent
, id): 
1317         def handleCommand(): 
1318             cmdStr 
= self
._cmdInput
.GetValue() 
1320                 self
._cmdList
.append(cmdStr
) 
1321                 self
._cmdIndex 
= len(self
._cmdList
) 
1322             self
._cmdInput
.Clear() 
1323             self
._cmdOutput
.SetDefaultStyle(style
=self
._cmdOutputTextStyle
) 
1324             self
._cmdOutput
.AppendText(">>> " + cmdStr 
+ "\n") 
1325             self
._cmdOutput
.SetDefaultStyle(style
=self
._defaultOutputTextStyle
) 
1326             self
.ExecuteCommand(cmdStr
) 
1329         def OnCmdButtonPressed(event
): 
1333         def OnKeyPressed(event
): 
1334             key 
= event
.KeyCode() 
1335             if key 
== wx
.WXK_RETURN
: 
1337             elif key 
== wx
.WXK_UP
: 
1338                 if len(self
._cmdList
) < 1 or self
._cmdIndex 
< 1: 
1341                 self
._cmdInput
.Clear() 
1342                 self
._cmdInput
.AppendText(self
._cmdList
[self
._cmdIndex 
- 1]) 
1343                 self
._cmdIndex 
= self
._cmdIndex 
- 1 
1344             elif key 
== wx
.WXK_DOWN
: 
1345                 if len(self
._cmdList
) < 1 or self
._cmdIndex 
>= len(self
._cmdList
): 
1348                 self
._cmdInput
.Clear() 
1349                 self
._cmdInput
.AppendText(self
._cmdList
[self
._cmdIndex 
- 1]) 
1350                 self
._cmdIndex 
= self
._cmdIndex 
+ 1 
1355         def OnClrButtonPressed(event
): 
1356             self
._cmdOutput
.Clear() 
1358         panel           
= wx
.Panel(parent
, id) 
1360         cmdLabel        
= wx
.StaticText(panel
, -1, "Cmd: ") 
1361         self
._cmdInput  
= wx
.TextCtrl(panel
) 
1362         cmdButton       
= wx
.Button(panel
, label
="Execute") 
1363         clrButton       
= wx
.Button(panel
, label
="Clear") 
1364         self
._cmdOutput 
= wx
.TextCtrl(panel
, style
=wx
.TE_MULTILINE | wx
.HSCROLL | wx
.TE_READONLY | wx
.TE_RICH2
) 
1366         hbox            
= wx
.BoxSizer() 
1367         hbox
.Add(cmdLabel
, proportion
=0, flag
=wx
.LEFT|wx
.ALIGN_CENTER_VERTICAL
) 
1368         hbox
.Add(self
._cmdInput
, proportion
=1, flag
=wx
.EXPAND
) 
1369         hbox
.Add(cmdButton
, proportion
=0, flag
=wx
.RIGHT
) 
1370         hbox
.Add(clrButton
, proportion
=0, flag
=wx
.RIGHT
) 
1372         vbox            
= wx
.BoxSizer(wx
.VERTICAL
) 
1373         vbox
.Add(hbox
, proportion
=0, flag
=wx
.EXPAND | wx
.ALL
, border
=2) 
1374         vbox
.Add(self
._cmdOutput
, proportion
=1, flag
=wx
.EXPAND | wx
.LEFT
, border
=2) 
1376         panel
.SetSizer(vbox
) 
1377         cmdButton
.Bind(wx
.EVT_BUTTON
, OnCmdButtonPressed
) 
1378         clrButton
.Bind(wx
.EVT_BUTTON
, OnClrButtonPressed
) 
1379         wx
.EVT_KEY_DOWN(self
._cmdInput
, OnKeyPressed
) 
1381         fixedFont 
= wx
.Font(self
._cmdInput
.GetFont().GetPointSize(), family
=wx
.TELETYPE
, style
=wx
.NORMAL
, weight
=wx
.NORMAL
) 
1382         self
._defaultOutputTextStyle 
= wx
.TextAttr("BLACK", wx
.NullColour
, fixedFont
) 
1383         self
._cmdOutputTextStyle 
= wx
.TextAttr("RED", wx
.NullColour
, fixedFont
) 
1384         self
._cmdOutput
.SetDefaultStyle(style
=self
._defaultOutputTextStyle
) 
1391     def MakeBreakPointsTab(self
, parent
, id): 
1392         panel 
= BreakpointsUI(parent
, id, self
._ui
) 
1395     def OnRightClick(self
, event
): 
1396         assert False, "OnRightClick not overridden" 
1398     def ClearWhileRunning(self
): 
1399         list = self
._framesChoiceCtrl
 
1402         tree 
= self
._treeCtrl
 
1404         tree
.DeleteChildren(root
) 
1405         self
._cmdInput
.Enable(False) 
1406         self
._cmdOutput
.Enable(False) 
1408     def OnListRightClick(self
, event
): 
1409         if not hasattr(self
, "syncFrameID"): 
1410             self
.syncFrameID 
= wx
.NewId() 
1411             self
.Bind(wx
.EVT_MENU
, self
.OnSyncFrame
, id=self
.syncFrameID
) 
1413         item 
= wx
.MenuItem(menu
, self
.syncFrameID
, "Goto Source Line") 
1414         menu
.AppendItem(item
) 
1415         self
.PopupMenu(menu
, event
.GetPosition()) 
1418     def OnSyncFrame(self
, event
): 
1419         assert False, "OnSyncFrame not overridden" 
1421     def LoadFramesList(self
, framesXML
): 
1422         assert False, "LoadFramesList not overridden" 
1424     def ListItemSelected(self
, event
): 
1425         assert False, "ListItemSelected not overridden" 
1427     def PopulateTreeFromFrameMessage(self
, message
): 
1428         assert False, "PopulateTreeFromFrameMessage not overridden" 
1430     def IntrospectCallback(self
, event
): 
1431         assert False, "IntrospectCallback not overridden" 
1433     def AppendText(self
, text
): 
1434         self
._textCtrl
.SetReadOnly(False) 
1435         self
._textCtrl
.AddText(text
) 
1436         self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount()) 
1437         self
._textCtrl
.SetReadOnly(True) 
1439     def AppendErrorText(self
, text
): 
1440         self
._textCtrl
.SetReadOnly(False) 
1441         self
._textCtrl
.SetFontColor(wx
.RED
) 
1442         self
._textCtrl
.StyleClearAll() 
1443         self
._textCtrl
.AddText(text
) 
1444         self
._textCtrl
.ScrollToLine(self
._textCtrl
.GetLineCount()) 
1445         self
._textCtrl
.SetFontColor(wx
.BLACK
) 
1446         self
._textCtrl
.StyleClearAll() 
1447         self
._textCtrl
.SetReadOnly(True) 
1449     def ClearOutput(self
, event
): 
1450         self
._textCtrl
.SetReadOnly(False) 
1451         self
._textCtrl
.ClearAll() 
1452         self
._textCtrl
.SetReadOnly(True) 
1454     def SwitchToOutputTab(self
): 
1455         self
._notebook
.SetSelection(0) 
1457 class PHPFramesUI(BaseFramesUI
): 
1458     def __init__(self
, parent
, id, ui
): 
1459         BaseFramesUI
.__init
__(self
, parent
, id, ui
) 
1461     def LoadFramesList(self
, stackList
): 
1462         wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
)) 
1464         self
._cmdInput
.Enable(True) 
1465         self
._cmdOutput
.Enable(True) 
1467         self
._stack 
= stackList
 
1468         list        = self
._framesChoiceCtrl
 
1471         if len(stackList
) > 0: 
1472             self
._displayVariableTreeRootNode
() 
1474             for stackFrame 
in stackList
: 
1475                 message 
= stackFrame
.getDisplayStr(stackList
) 
1476                 list.Append(message
) 
1478             self
.currentItem 
= index
 
1479             list.SetSelection(index
) 
1481             self
.OnSyncFrame(None) 
1482             self
._p
1.FitInside() 
1484         wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
)) 
1486     def PopulateTreeFromStackFrame(self
, frameNode
): 
1487         vars         = frameNode
.getVariables() 
1488         tree         
= self
._treeCtrl
 
1489         rootTreeNode 
= self
._root
 
1492         # Build a new sub variable tree from the root node. 
1494         tree
.DeleteChildren(rootTreeNode
) 
1496             aTreeNode 
= self
.AppendSubTreeFromAVariable(tree
, var
, rootTreeNode
) 
1499         # No need to expand the node here, as the IntrospectCallback() has 
1500         # already called it. 
1502         self
._p
2.FitInside() 
1504     def AppendSubTreeFromAVariable(self
, tree
, var
, parentTreeNode
, previousOne 
= None): 
1505         varName     
= var
.getName() 
1506         varValueStr 
= var
.getValueString() 
1509         # If previously we already have this item in the tree, replace it. 
1510         # Otherwise, insert a new one. 
1513             newNode 
= tree
.InsertItem(parentTreeNode
, previousOne
, varName
) 
1515             newNode 
= tree
.AppendItem(parentTreeNode
, varName
) 
1518         # Associate this variable object with this newNode. 
1520         tree
.SetPyData(newNode
, var
) 
1523         # Set this variable's value string (for displaying). 
1525         if varValueStr 
and len(varValueStr
) > 0: 
1526             tree
.SetItemText(newNode
, varValueStr
, 1) 
1529         # If this variable has child variables, recursively build the sub 
1532         if var
.hasChildren(): 
1533             childrenVarList 
= var
.getChildrenVariables() 
1534             for childVar 
in childrenVarList
: 
1535                 self
.AppendSubTreeFromAVariable(tree
, childVar
, newNode
) 
1538             # If its child variables are sortable, sort it. 
1540             if var
.childrenIsSortable(): 
1541                 tree
.SortChildren(newNode
) 
1545     def IntrospectCallback(self
, event
): 
1546         tree 
= self
._treeCtrl
 
1547         item 
= event
.GetItem() 
1550         # Only when the introspection happens to root, we get the whole 
1551         # variable tree.  For all the individual nodes, we have populated 
1552         # the subtree already, so don't need to do anything. 
1554         if tree
.GetPyData(item
) == "root" and self
._stack 
and self
._stack
[self
.currentItem
]: 
1555             stackFrame 
= self
._stack
[self
.currentItem
] 
1556             self
.PopulateTreeFromStackFrame(stackFrame
) 
1560     def OnSyncFrame(self
, event
): 
1561         stackFrame 
= self
._stack
[self
.currentItem
] 
1562         fileName   
= stackFrame
.getFileName() 
1563         lineNo     
= stackFrame
.getLineNo() 
1565             print "OnSyncFrame(): about to sync: fileName: %s, lineNo: %d" % (fileName
, lineNo
) 
1566         self
._ui
.SynchCurrentLine(fileName
, lineNo
) 
1568             print "OnSyncFrame(): sync done" 
1570     def ListItemSelected(self
, event
): 
1571         selectedStackFrameStr 
= event
.GetString() 
1573         if not self
._stack 
or len(self
._stack
) < 1: 
1577         for stackFrame 
in self
._stack
: 
1578             if stackFrame
.getDisplayStr() == selectedStackFrameStr
: 
1579                 self
.currentItem 
= stackFrame
.getFrameIndex() 
1584             self
._displayVariableTreeRootNode
() 
1585             self
.OnSyncFrame(None) 
1589     def _displayVariableTreeRootNode(self
): 
1591         # Add a dummy item to rootTreeNode so that it will be shown as 
1592         # expandable.  Only do real tree population on the fly when the 
1593         # rootTreeNode is expanded in OnIntrospection(). 
1595         tree         
= self
._treeCtrl
 
1596         rootTreeNode 
= self
._root
 
1597         dummyNode    
= tree
.AppendItem(rootTreeNode
, "dummy") 
1598         tree
.Collapse(rootTreeNode
) 
1603 class PythonFramesUI(BaseFramesUI
): 
1604     def __init__(self
, parent
, id, ui
): 
1605         BaseFramesUI
.__init
__(self
, parent
, id, ui
) 
1607     def ExecuteCommand(self
, command
): 
1608         retval 
= self
._ui
._callback
._debuggerServer
.execute_in_frame(self
._framesChoiceCtrl
.GetStringSelection(), command
) 
1609         self
._cmdOutput
.AppendText(str(retval
) + "\n") 
1610         # Refresh the tree view in case this command resulted in changes there. TODO: Need to reopen tree items. 
1611         self
.PopulateTreeFromFrameMessage(self
._framesChoiceCtrl
.GetStringSelection()) 
1613     def OnRightClick(self
, event
): 
1615         self
._introspectItem 
= event
.GetItem() 
1616         self
._parentChain 
= self
.GetItemChain(event
.GetItem()) 
1617         watchOnly 
= len(self
._parentChain
) < 1 
1618         if not _WATCHES_ON 
and watchOnly
: 
1622             if not hasattr(self
, "watchID"): 
1623                 self
.watchID 
= wx
.NewId() 
1624                 self
.Bind(wx
.EVT_MENU
, self
.OnWatch
, id=self
.watchID
) 
1625             item 
= wx
.MenuItem(menu
, self
.watchID
, "Create a Watch") 
1626             menu
.AppendItem(item
) 
1627             menu
.AppendSeparator() 
1629             if not hasattr(self
, "viewID"): 
1630                 self
.viewID 
= wx
.NewId() 
1631                 self
.Bind(wx
.EVT_MENU
, self
.OnView
, id=self
.viewID
) 
1632             item 
= wx
.MenuItem(menu
, self
.viewID
, "View in Dialog") 
1633             menu
.AppendItem(item
) 
1634             if not hasattr(self
, "toInteractID"): 
1635                 self
.toInteractID 
= wx
.NewId() 
1636                 self
.Bind(wx
.EVT_MENU
, self
.OnSendToInteract
, id=self
.toInteractID
) 
1637             item 
= wx
.MenuItem(menu
, self
.toInteractID
, "Send to Interact") 
1638             menu
.AppendItem(item
) 
1640         offset 
= wx
.Point(x
=0, y
=20) 
1641         menuSpot 
= event
.GetPoint() + offset
 
1642         self
._treeCtrl
.PopupMenu(menu
, menuSpot
) 
1644         self
._parentChain 
= None 
1645         self
._introspectItem 
= None 
1647     def GetItemChain(self
, item
): 
1650             if _VERBOSE
: print 'Exploding: %s' % self
._treeCtrl
.GetItemText(item
, 0) 
1651             while item 
!= self
._root
: 
1652                 text 
= self
._treeCtrl
.GetItemText(item
, 0) 
1653                 if _VERBOSE
: print "Appending ", text
 
1654                 parentChain
.append(text
) 
1655                 item 
= self
._treeCtrl
.GetItemParent(item
) 
1656             parentChain
.reverse() 
1659     def OnView(self
, event
): 
1660         title 
= self
._treeCtrl
.GetItemText(self
._introspectItem
,0) 
1661         value 
= self
._treeCtrl
.GetItemText(self
._introspectItem
,1) 
1662         dlg 
= wx
.lib
.dialogs
.ScrolledMessageDialog(self
, value
, title
, style
=wx
.DD_DEFAULT_STYLE | wx
.RESIZE_BORDER
) 
1665     def OnSendToInteract(self
, event
): 
1668         for item 
in self
._parentChain
: 
1670             if item
.find(prevItem 
+ '[') != -1: 
1671                value 
+= item
[item
.find('['):] 
1675             if item 
== 'globals': 
1677             if item 
!= 'locals': 
1681         self
.ExecuteCommand(value
) 
1683     def OnWatch(self
, event
): 
1685             if hasattr(self
, '_parentChain'): 
1686                 wd 
= WatchDialog(wx
.GetApp().GetTopWindow(), "Add a Watch", self
._parentChain
) 
1688                 wd 
= WatchDialog(wx
.GetApp().GetTopWindow(), "Add a Watch", None) 
1690             if wd
.ShowModal() == wx
.ID_OK
: 
1691                 name
, text
, send_frame
, run_once 
= wd
.GetSettings() 
1693                     frameNode 
= self
._stack
[int(self
.currentItem
)] 
1694                     message 
= frameNode
.getAttribute("message") 
1697                 binType 
= self
._ui
._callback
._debuggerServer
.add_watch(name
, text
, message
, run_once
) 
1698                 xmldoc 
= bz2
.decompress(binType
.data
) 
1699                 domDoc 
= parseString(xmldoc
) 
1700                 nodeList 
= domDoc
.getElementsByTagName('watch') 
1701                 if len(nodeList
) == 1: 
1702                     watchValue 
= nodeList
.item(0).getAttribute("message") 
1705             tp
, val
, tb 
= sys
.exc_info() 
1706             traceback
.print_exception(tp
, val
, tb
) 
1708     def OnIntrospect(self
, event
): 
1709         wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
)) 
1714                 list = self
._framesChoiceCtrl
 
1715                 frameNode 
= self
._stack
[int(self
.currentItem
)] 
1716                 message 
= frameNode
.getAttribute("message") 
1717                 binType 
= self
._ui
._callback
._debuggerServer
.attempt_introspection(message
, self
._parentChain
) 
1718                 xmldoc 
= bz2
.decompress(binType
.data
) 
1719                 domDoc 
= parseString(xmldoc
) 
1720                 nodeList 
= domDoc
.getElementsByTagName('replacement') 
1721                 replacementNode 
= nodeList
.item(0) 
1722                 if len(replacementNode
.childNodes
): 
1723                     thingToWalk 
= replacementNode
.childNodes
.item(0) 
1724                     tree 
= self
._treeCtrl
 
1725                     parent 
= tree
.GetItemParent(self
._introspectItem
) 
1726                     treeNode 
= self
.AppendSubTreeFromNode(thingToWalk
, thingToWalk
.getAttribute('name'), parent
, insertBefore
=self
._introspectItem
) 
1727                     if thingToWalk
.getAttribute('name').find('[') == -1: 
1728                         self
._treeCtrl
.SortChildren(treeNode
) 
1729                     self
._treeCtrl
.Expand(treeNode
) 
1730                     tree
.Delete(self
._introspectItem
) 
1732                 tp
,val
,tb 
= sys
.exc_info() 
1733                 traceback
.print_exception(tp
, val
, tb
) 
1736             wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
)) 
1738     def OnSyncFrame(self
, event
): 
1739         list = self
._framesChoiceCtrl
 
1740         frameNode 
= self
._stack
[int(self
.currentItem
)] 
1741         file = frameNode
.getAttribute("file") 
1742         line 
= frameNode
.getAttribute("line") 
1743         self
._ui
.SynchCurrentLine( file, int(line
) ) 
1745     def LoadFramesList(self
, framesXML
): 
1746         wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
)) 
1748             self
._cmdInput
.Enable(True) 
1749             self
._cmdOutput
.Enable(True) 
1752                 domDoc 
= parseString(framesXML
) 
1753                 list = self
._framesChoiceCtrl
 
1756                 nodeList 
= domDoc
.getElementsByTagName('frame') 
1758                 for index 
in range(0, nodeList
.length
): 
1759                     frameNode 
= nodeList
.item(index
) 
1760                     message 
= frameNode
.getAttribute("message") 
1761                     list.Append(message
) 
1762                     self
._stack
.append(frameNode
) 
1764                 index 
= len(self
._stack
) - 1 
1765                 list.SetSelection(index
) 
1767                 node 
= self
._stack
[index
] 
1768                 self
.currentItem 
= index
 
1769                 self
.PopulateTreeFromFrameNode(node
) 
1770                 self
.OnSyncFrame(None) 
1772                 self
._p
1.FitInside() 
1773                 frameNode 
= nodeList
.item(index
) 
1774                 file = frameNode
.getAttribute("file") 
1775                 line 
= frameNode
.getAttribute("line") 
1776                 self
._ui
.SynchCurrentLine( file, int(line
) ) 
1778                 tp
,val
,tb
=sys
.exc_info() 
1779                 traceback
.print_exception(tp
, val
, tb
) 
1782             wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
)) 
1785     def ListItemSelected(self
, event
): 
1786         self
.PopulateTreeFromFrameMessage(event
.GetString()) 
1787         self
.OnSyncFrame(None) 
1789     def PopulateTreeFromFrameMessage(self
, message
): 
1791         for node 
in self
._stack
: 
1792             if node
.getAttribute("message") == message
: 
1793                 binType 
= self
._ui
._callback
._debuggerServer
.request_frame_document(message
) 
1794                 xmldoc 
= bz2
.decompress(binType
.data
) 
1795                 domDoc 
= parseString(xmldoc
) 
1796                 nodeList 
= domDoc
.getElementsByTagName('frame') 
1797                 self
.currentItem 
= index
 
1799                     self
.PopulateTreeFromFrameNode(nodeList
[0]) 
1803     def PopulateTreeFromFrameNode(self
, frameNode
): 
1804         list = self
._framesChoiceCtrl
 
1806         tree 
= self
._treeCtrl
 
1809         tree
.DeleteChildren(root
) 
1810         children 
= frameNode
.childNodes
 
1812         for index 
in range(0, children
.length
): 
1813             subNode 
= children
.item(index
) 
1814             treeNode 
= self
.AppendSubTreeFromNode(subNode
, subNode
.getAttribute('name'), root
) 
1816                 firstChild 
= treeNode
 
1819             tree
.Expand(firstChild
) 
1820         self
._p
2.FitInside() 
1822     def IntrospectCallback(self
, event
): 
1823         tree 
= self
._treeCtrl
 
1824         item 
= event
.GetItem() 
1826             print "In introspectCallback item is %s, pydata is %s" % (event
.GetItem(), tree
.GetPyData(item
)) 
1827         if tree
.GetPyData(item
) != "Introspect": 
1830         self
._introspectItem 
= item
 
1831         self
._parentChain 
= self
.GetItemChain(item
) 
1832         self
.OnIntrospect(event
) 
1835     def AppendSubTreeFromNode(self
, node
, name
, parent
, insertBefore
=None): 
1836         tree 
= self
._treeCtrl
 
1837         if insertBefore 
!= None: 
1838             treeNode 
= tree
.InsertItem(parent
, insertBefore
, name
) 
1840             treeNode 
= tree
.AppendItem(parent
, name
) 
1841         children 
= node
.childNodes
 
1842         intro 
= node
.getAttribute('intro') 
1845             tree
.SetItemHasChildren(treeNode
, True) 
1846             tree
.SetPyData(treeNode
, "Introspect") 
1847         if node
.getAttribute("value"): 
1848             tree
.SetItemText(treeNode
, self
.StripOuterSingleQuotes(node
.getAttribute("value")), 1) 
1849         for index 
in range(0, children
.length
): 
1850             subNode 
= children
.item(index
) 
1851             if self
.HasChildren(subNode
): 
1852                 self
.AppendSubTreeFromNode(subNode
, subNode
.getAttribute("name"), treeNode
) 
1854                 name 
= subNode
.getAttribute("name") 
1855                 value 
= self
.StripOuterSingleQuotes(subNode
.getAttribute("value")) 
1856                 n 
= tree
.AppendItem(treeNode
, name
) 
1857                 tree
.SetItemText(n
, value
, 1) 
1858                 intro 
= subNode
.getAttribute('intro') 
1860                     tree
.SetItemHasChildren(n
, True) 
1861                     tree
.SetPyData(n
, "Introspect") 
1862         if name
.find('[') == -1: 
1863             self
._treeCtrl
.SortChildren(treeNode
) 
1866     def StripOuterSingleQuotes(self
, string
): 
1867         if string
.startswith("'") and string
.endswith("'"): 
1868             retval 
=  string
[1:-1] 
1869         elif string
.startswith("\"") and string
.endswith("\""): 
1870             retval 
= string
[1:-1] 
1873         if retval
.startswith("u'") and retval
.endswith("'"): 
1877     def HasChildren(self
, node
): 
1879             return node
.childNodes
.length 
> 0 
1881             tp
,val
,tb
=sys
.exc_info() 
1885 class DebuggerView(Service
.ServiceView
): 
1887     #---------------------------------------------------------------------------- 
1888     # Overridden methods 
1889     #---------------------------------------------------------------------------- 
1891     def __init__(self
, service
): 
1892         Service
.ServiceView
.__init
__(self
, service
) 
1894     def _CreateControl(self
, parent
, id): 
1897     #------------------------------------------------------------------------------ 
1899     #----------------------------------------------------------------------------- 
1901     def OnToolClicked(self
, event
): 
1902         self
.GetFrame().ProcessEvent(event
) 
1904     #------------------------------------------------------------------------------ 
1906     #----------------------------------------------------------------------------- 
1909     def __init__(self
, message
, framesXML
,  info
=None, quit
=False): 
1910         self
._framesXML 
= framesXML
 
1911         self
._message 
= message
 
1915     def getFramesXML(self
): 
1916         return self
._framesXML
 
1918     def getMessage(self
): 
1919         return self
._message
 
1927 class AGXMLRPCServer(SimpleXMLRPCServer
.SimpleXMLRPCServer
): 
1928     def __init__(self
, address
, logRequests
=0): 
1929         SimpleXMLRPCServer
.SimpleXMLRPCServer
.__init
__(self
, address
, logRequests
=logRequests
) 
1931 class RequestHandlerThread(threading
.Thread
): 
1932     def __init__(self
, queue
, address
): 
1933         threading
.Thread
.__init
__(self
) 
1934         self
._keepGoing 
= True 
1936         self
._address 
= address
 
1937         self
._server 
= AGXMLRPCServer(self
._address
,logRequests
=0) 
1938         self
._server
.register_function(self
.interaction
) 
1939         self
._server
.register_function(self
.quit
) 
1940         self
._server
.register_function(self
.dummyOperation
) 
1941         if _VERBOSE
: print "RequestHandlerThread on fileno %s" % str(self
._server
.fileno()) 
1944         while self
._keepGoing
: 
1946                 self
._server
.handle_request() 
1948                 tp
, val
, tb 
= sys
.exc_info() 
1949                 traceback
.print_exception(tp
, val
, tb
) 
1950                 self
._keepGoing 
= False 
1951         if _VERBOSE
: print "Exiting Request Handler Thread." 
1953     def interaction(self
, message
, frameXML
, info
): 
1954         if _VERBOSE
: print "In RequestHandlerThread.interaction -- adding to queue" 
1955         interaction 
= Interaction(message
, frameXML
, info
) 
1956         self
._queue
.put(interaction
) 
1960         interaction 
= Interaction(None, None, info
=None, quit
=True) 
1961         self
._queue
.put(interaction
) 
1964     def dummyOperation(self
): 
1967     def AskToStop(self
): 
1968         self
._keepGoing 
= False 
1969         if type(self
._server
) is not types
.NoneType
: 
1971                 # This is a really ugly way to make sure this thread isn't blocked in 
1973                 url 
= 'http://' + self
._address
[0] + ':' + str(self
._address
[1]) + '/' 
1974                 tempServer 
= xmlrpclib
.ServerProxy(url
, allow_none
=1) 
1975                 tempServer
.dummyOperation() 
1977                 tp
, val
, tb 
= sys
.exc_info() 
1978                 traceback
.print_exception(tp
, val
, tb
) 
1979             self
._server
.server_close() 
1982 class RequestBreakThread(threading
.Thread
): 
1983         def __init__(self
, server
, interrupt
=False, pushBreakpoints
=False, breakDict
=None, kill
=False): 
1984             threading
.Thread
.__init
__(self
) 
1985             self
._server 
= server
 
1987             self
._interrupt 
= interrupt
 
1988             self
._pushBreakpoints 
= pushBreakpoints
 
1989             self
._breakDict 
= breakDict
 
1994                 if _VERBOSE
: print "RequestBreakThread, before call" 
1996                     self
._server
.break_requested() 
1997                 if self
._pushBreakpoints
: 
1998                     self
._server
.update_breakpoints(xmlrpclib
.Binary(pickle
.dumps(self
._breakDict
))) 
2004                 if _VERBOSE
: print "RequestBreakThread, after call" 
2006                 tp
,val
,tb 
= sys
.exc_info() 
2007                 traceback
.print_exception(tp
, val
, tb
) 
2009 class DebuggerOperationThread(threading
.Thread
): 
2010         def __init__(self
, function
): 
2011             threading
.Thread
.__init
__(self
) 
2012             self
._function 
= function
 
2015             if _VERBOSE
: print "In DOT, before call" 
2019                 tp
,val
,tb 
= sys
.exc_info() 
2020                 traceback
.print_exception(tp
, val
, tb
) 
2022                 print "In DOT, after call" 
2024 class BaseDebuggerCallback(object): 
2027         assert False, "Start not overridden" 
2029     def ShutdownServer(self
): 
2030         assert False, "ShutdownServer not overridden" 
2032     def BreakExecution(self
): 
2033         assert False, "BreakExecution not overridden" 
2035     def SingleStep(self
): 
2036         assert False, "SingleStep not overridden" 
2039         assert False, "Next not overridden" 
2042         assert False, "Start not overridden" 
2045         assert False, "Return not overridden" 
2047     def PushBreakpoints(self
): 
2048         assert False, "PushBreakpoints not overridden" 
2050 class PythonDebuggerCallback(BaseDebuggerCallback
): 
2052     def __init__(self
, host
, port
, debugger_url
, break_url
, debuggerUI
, autoContinue
=False): 
2053         if _VERBOSE
: print "+++++++ Creating server on port, ", str(port
) 
2055         self
._queue 
= Queue
.Queue(50) 
2057         self
._port 
= int(port
) 
2058         threading
._VERBOSE 
= _VERBOSE
 
2059         self
._serverHandlerThread 
= RequestHandlerThread(self
._queue
, (self
._host
, self
._port
)) 
2061         self
._debugger
_url 
= debugger_url
 
2062         self
._debuggerServer 
= None 
2063         self
._waiting 
= False 
2064         self
._service 
= wx
.GetApp().GetService(DebuggerService
) 
2065         self
._debuggerUI 
= debuggerUI
 
2066         self
._break
_url 
= break_url
 
2067         self
._breakServer 
= None 
2068         self
._firstInteraction 
= True 
2069         self
._pendingBreak 
= False 
2070         self
._autoContinue 
= autoContinue
 
2073         self
._serverHandlerThread
.start() 
2075     def ShutdownServer(self
): 
2076         #rbt = RequestBreakThread(self._breakServer, kill=True) 
2078         self
._waiting 
= False 
2079         if self
._serverHandlerThread
: 
2080             self
._serverHandlerThread
.AskToStop() 
2081             self
._serverHandlerThread 
= None 
2083     def BreakExecution(self
): 
2084         rbt 
= RequestBreakThread(self
._breakServer
, interrupt
=True) 
2087     def SingleStep(self
): 
2088         self
._debuggerUI
.DisableWhileDebuggerRunning() 
2089         self
._debuggerServer
.set_step() # Figure out where to set allowNone 
2093         self
._debuggerUI
.DisableWhileDebuggerRunning() 
2094         self
._debuggerServer
.set_next() 
2098         self
._debuggerUI
.DisableWhileDebuggerRunning() 
2099         self
._debuggerServer
.set_continue() 
2103         self
._debuggerUI
.DisableWhileDebuggerRunning() 
2104         self
._debuggerServer
.set_return() 
2107     def ReadQueue(self
): 
2108         if self
._queue
.qsize(): 
2110                 item 
= self
._queue
.get_nowait() 
2112                     self
.interaction(None, None, None, True) 
2114                     data 
= bz2
.decompress(item
.getFramesXML().data
) 
2115                     self
.interaction(item
.getMessage().data
, data
, item
.getInfo(), False) 
2119     def PushBreakpoints(self
): 
2120         rbt 
= RequestBreakThread(self
._breakServer
, pushBreakpoints
=True, breakDict
=self
._service
.GetMasterBreakpointDict()) 
2124     def WaitForRPC(self
): 
2125         self
._waiting 
= True 
2126         while self
._waiting
: 
2132                 tp
, val
, tb 
= sys
.exc_info() 
2133                 traceback
.print_exception(tp
, val
, tb
) 
2134             wx
.GetApp().Yield(True) 
2135         if _VERBOSE
: print "Exiting WaitForRPC." 
2137     def interaction(self
, message
, frameXML
, info
, quit
): 
2139         #This method should be hit as the debugger starts. 
2140         if self
._firstInteraction
: 
2141             self
._firstInteraction 
= False 
2142             self
._debuggerServer 
= xmlrpclib
.ServerProxy(self
._debugger
_url
,  allow_none
=1) 
2143             self
._breakServer 
= xmlrpclib
.ServerProxy(self
._break
_url
, allow_none
=1) 
2144             self
.PushBreakpoints() 
2145         self
._waiting 
= False 
2146         if _VERBOSE
: print "+"*40 
2148             self
._debuggerUI
.StopExecution(None) 
2151             if _VERBOSE
: print "Hit interaction with exception" 
2152             #self._debuggerUI.StopExecution(None) 
2153             #self._debuggerUI.SetStatusText("Got exception: " + str(info)) 
2154             self
._debuggerUI
.SwitchToOutputTab() 
2156             if _VERBOSE
: print "Hit interaction no exception" 
2157         #if not self._autoContinue: 
2158         self
._debuggerUI
.SetStatusText(message
) 
2159         if not self
._autoContinue
: 
2160             self
._debuggerUI
.LoadPythonFramesList(frameXML
) 
2161             self
._debuggerUI
.EnableWhileDebuggerStopped() 
2163         if self
._autoContinue
: 
2164             self
._timer 
= wx
.PyTimer(self
.DoContinue
) 
2165             self
._autoContinue 
= False 
2166             self
._timer
.Start(250) 
2167         if _VERBOSE
: print "+"*40 
2169     def DoContinue(self
): 
2171         dbgService 
= wx
.GetApp().GetService(DebuggerService
) 
2172         evt 
= DebugInternalWebServer() 
2173         evt
.SetId(self
._debuggerUI
.CONTINUE_ID
) 
2174         wx
.PostEvent(self
._debuggerUI
, evt
) 
2175         if _VERBOSE
: print "Event Continue posted" 
2177         evt 
= DebugInternalWebServer() 
2178         evt
.SetId(DebuggerService
.DEBUG_WEBSERVER_NOW_RUN_PROJECT_ID
) 
2179         wx
.PostEvent(dbgService
._frame
, evt
) 
2180         if _VERBOSE
: print "Event RunProject posted" 
2182     def SendRunEvent(self
): 
2183         class SendEventThread(threading
.Thread
): 
2185                 threading
.Thread
.__init
__(self
) 
2188                 dbgService 
= wx
.GetApp().GetService(DebuggerService
) 
2189                 evt 
= DebugInternalWebServer() 
2190                 evt
.SetId(DebuggerService
.DEBUG_WEBSERVER_NOW_RUN_PROJECT_ID
) 
2191                 wx
.PostEvent(dbgService
._frame
, evt
) 
2192                 print "Event posted" 
2193         set = SendEventThread() 
2196 class DebuggerService(Service
.Service
): 
2198     #---------------------------------------------------------------------------- 
2200     #---------------------------------------------------------------------------- 
2201     TOGGLE_BREAKPOINT_ID 
= wx
.NewId() 
2202     CLEAR_ALL_BREAKPOINTS 
= wx
.NewId() 
2204     DEBUG_ID 
= wx
.NewId() 
2205     RUN_LAST_ID 
= wx
.NewId() 
2206     DEBUG_LAST_ID 
= wx
.NewId() 
2207     DEBUG_WEBSERVER_ID 
= wx
.NewId() 
2208     RUN_WEBSERVER_ID 
= wx
.NewId() 
2209     DEBUG_WEBSERVER_CONTINUE_ID 
= wx
.NewId() 
2210     DEBUG_WEBSERVER_NOW_RUN_PROJECT_ID 
= wx
.NewId() 
2211     def ComparePaths(first
, second
): 
2212         one 
= DebuggerService
.ExpandPath(first
) 
2213         two 
= DebuggerService
.ExpandPath(second
) 
2215             return one
.lower() == two
.lower() 
2218     ComparePaths 
= staticmethod(ComparePaths
) 
2220     # Make sure we're using an expanded path on windows. 
2221     def ExpandPath(path
): 
2224                 return win32api
.GetLongPathName(path
) 
2227                     print "Cannot get long path for %s" % path
 
2231     ExpandPath 
= staticmethod(ExpandPath
) 
2233     #---------------------------------------------------------------------------- 
2234     # Overridden methods 
2235     #---------------------------------------------------------------------------- 
2237     def __init__(self
, serviceName
, embeddedWindowLocation 
= wx
.lib
.pydocview
.EMBEDDED_WINDOW_LEFT
): 
2238         Service
.Service
.__init
__(self
, serviceName
, embeddedWindowLocation
) 
2239         self
.BREAKPOINT_DICT_STRING 
= "MasterBreakpointDict" 
2240         config 
= wx
.ConfigBase_Get() 
2241         pickledbps 
= config
.Read(self
.BREAKPOINT_DICT_STRING
) 
2244                 self
._masterBPDict 
= pickle
.loads(pickledbps
.encode('ascii')) 
2246                 tp
, val
, tb 
= sys
.exc_info() 
2247                 traceback
.print_exception(tp
,val
,tb
) 
2248                 self
._masterBPDict 
= {} 
2250             self
._masterBPDict 
= {} 
2252         self
.projectPath 
= None 
2253         self
.fileToDebug 
= None 
2254         self
.phpDbgParam 
= None 
2255         self
.dbgLanguage 
= projectmodel
.LANGUAGE_DEFAULT
 
2257     def OnCloseFrame(self
, event
): 
2258         # IS THIS THE RIGHT PLACE? 
2260             config 
= wx
.ConfigBase_Get() 
2261             config
.Write(self
.BREAKPOINT_DICT_STRING
, pickle
.dumps(self
._masterBPDict
)) 
2263             tp
,val
,tb 
= sys
.exc_info() 
2264             traceback
.print_exception(tp
, val
, tb
) 
2267     def _CreateView(self
): 
2268         return DebuggerView(self
) 
2271     #---------------------------------------------------------------------------- 
2272     # Service specific methods 
2273     #---------------------------------------------------------------------------- 
2275     def InstallControls(self
, frame
, menuBar 
= None, toolBar 
= None, statusBar 
= None, document 
= None): 
2276         #Service.Service.InstallControls(self, frame, menuBar, toolBar, statusBar, document) 
2278         config 
= wx
.ConfigBase_Get() 
2280         debuggerMenu 
= wx
.Menu() 
2281         if not menuBar
.FindItemById(DebuggerService
.CLEAR_ALL_BREAKPOINTS
): 
2283             debuggerMenu
.Append(DebuggerService
.RUN_ID
, _("&Run...\tCtrl+R"), _("Runs a file")) 
2284             wx
.EVT_MENU(frame
, DebuggerService
.RUN_ID
, frame
.ProcessEvent
) 
2285             wx
.EVT_UPDATE_UI(frame
, DebuggerService
.RUN_ID
, frame
.ProcessUpdateUIEvent
) 
2287             debuggerMenu
.Append(DebuggerService
.DEBUG_ID
, _("&Debug...\tCtrl+D"), _("Debugs a file")) 
2288             wx
.EVT_MENU(frame
, DebuggerService
.DEBUG_ID
, frame
.ProcessEvent
) 
2289             wx
.EVT_UPDATE_UI(frame
, DebuggerService
.DEBUG_ID
, frame
.ProcessUpdateUIEvent
) 
2291             debuggerMenu
.Append(DebuggerService
.RUN_LAST_ID
, _("&Run Using Last Settings\tF5"), _("Runs a file using previous settings")) 
2292             wx
.EVT_MENU(frame
, DebuggerService
.RUN_LAST_ID
, frame
.ProcessEvent
) 
2293             wx
.EVT_UPDATE_UI(frame
, DebuggerService
.RUN_LAST_ID
, frame
.ProcessUpdateUIEvent
) 
2295             debuggerMenu
.Append(DebuggerService
.DEBUG_LAST_ID
, _("&Debug Using Last Settings\tF8"), _("Debugs a file using previous settings")) 
2296             wx
.EVT_MENU(frame
, DebuggerService
.DEBUG_LAST_ID
, frame
.ProcessEvent
) 
2297             wx
.EVT_UPDATE_UI(frame
, DebuggerService
.DEBUG_LAST_ID
, frame
.ProcessUpdateUIEvent
) 
2299             if not ACTIVEGRID_BASE_IDE
: 
2300                 debuggerMenu
.AppendSeparator() 
2301                 debuggerMenu
.Append(DebuggerService
.DEBUG_WEBSERVER_ID
, _("Debug Internal Web Server"), _("Debugs the internal webservier")) 
2302                 wx
.EVT_MENU(frame
, DebuggerService
.DEBUG_WEBSERVER_ID
, frame
.ProcessEvent
) 
2303                 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.DEBUG_WEBSERVER_ID
, frame
.ProcessUpdateUIEvent
) 
2304                 debuggerMenu
.Append(DebuggerService
.RUN_WEBSERVER_ID
, _("Restart Internal Web Server"), _("Restarts the internal webservier")) 
2305                 wx
.EVT_MENU(frame
, DebuggerService
.RUN_WEBSERVER_ID
, frame
.ProcessEvent
) 
2306                 wx
.EVT_UPDATE_UI(frame
, DebuggerService
.RUN_WEBSERVER_ID
, frame
.ProcessUpdateUIEvent
) 
2308                 frame
.Bind(EVT_DEBUG_INTERNAL
, frame
.ProcessEvent
) 
2309             debuggerMenu
.AppendSeparator() 
2311             debuggerMenu
.Append(DebuggerService
.TOGGLE_BREAKPOINT_ID
, _("&Toggle Breakpoint\tCtrl+B"), _("Toggle a breakpoint")) 
2312             wx
.EVT_MENU(frame
, DebuggerService
.TOGGLE_BREAKPOINT_ID
, self
.ProcessEvent
) 
2313             wx
.EVT_UPDATE_UI(frame
, DebuggerService
.TOGGLE_BREAKPOINT_ID
, self
.ProcessUpdateUIEvent
) 
2315             debuggerMenu
.Append(DebuggerService
.CLEAR_ALL_BREAKPOINTS
, _("&Clear All Breakpoints"), _("Clear All Breakpoints")) 
2316             wx
.EVT_MENU(frame
, DebuggerService
.CLEAR_ALL_BREAKPOINTS
, self
.ProcessEvent
) 
2317             wx
.EVT_UPDATE_UI(frame
, DebuggerService
.CLEAR_ALL_BREAKPOINTS
, self
.ProcessUpdateUIEvent
) 
2320         viewMenuIndex 
= menuBar
.FindMenu(_("&Project")) 
2321         menuBar
.Insert(viewMenuIndex 
+ 1, debuggerMenu
, _("&Run")) 
2323         toolBar
.AddSeparator() 
2324         toolBar
.AddTool(DebuggerService
.RUN_LAST_ID
, getRunningManBitmap(), shortHelpString 
= _("Run Using Last Settings"), longHelpString 
= _("Run Using Last Settings")) 
2325         toolBar
.AddTool(DebuggerService
.DEBUG_LAST_ID
, getDebuggingManBitmap(), shortHelpString 
= _("Debug Using Last Settings"), longHelpString 
= _("Debug Using Last Settings")) 
2332     #---------------------------------------------------------------------------- 
2333     # Event Processing Methods 
2334     #---------------------------------------------------------------------------- 
2336     def ProcessEventBeforeWindows(self
, event
): 
2340     def ProcessEvent(self
, event
): 
2341         if Service
.Service
.ProcessEvent(self
, event
): 
2344         an_id 
= event
.GetId() 
2345         if an_id 
== DebuggerService
.TOGGLE_BREAKPOINT_ID
: 
2346             self
.OnToggleBreakpoint(event
) 
2348         elif an_id 
== DebuggerService
.CLEAR_ALL_BREAKPOINTS
: 
2349             self
.ClearAllBreakpoints() 
2351         elif an_id 
== DebuggerService
.RUN_ID
: 
2352             self
.OnRunProject(event
) 
2354         elif an_id 
== DebuggerService
.DEBUG_ID
: 
2355             self
.OnDebugProject(event
) 
2357         elif an_id 
== DebuggerService
.RUN_LAST_ID
: 
2358             self
.OnRunProject(event
, showDialog
=False) 
2360         elif an_id 
== DebuggerService
.DEBUG_LAST_ID
: 
2361             self
.OnDebugProject(event
, showDialog
=False) 
2363         elif an_id 
== DebuggerService
.DEBUG_WEBSERVER_ID
: 
2364             self
.OnDebugWebServer(event
) 
2366         elif an_id 
== DebuggerService
.DEBUG_WEBSERVER_CONTINUE_ID
: 
2367             self
.OnDebugWebServerContinue(event
) 
2369         elif an_id 
== DebuggerService
.DEBUG_WEBSERVER_NOW_RUN_PROJECT_ID
: 
2370             self
.WaitDebuggerThenRunProject() 
2372         elif an_id 
== DebuggerService
.RUN_WEBSERVER_ID
: 
2373             self
.OnRunWebServer(event
) 
2377     def ProcessUpdateUIEvent(self
, event
): 
2378         if Service
.Service
.ProcessUpdateUIEvent(self
, event
): 
2381         an_id 
= event
.GetId() 
2382         if an_id 
== DebuggerService
.TOGGLE_BREAKPOINT_ID
: 
2383             currentView 
= self
.GetDocumentManager().GetCurrentView() 
2384             event
.Enable(isinstance(currentView
, PythonEditor
.PythonView
)) 
2386         elif an_id 
== DebuggerService
.CLEAR_ALL_BREAKPOINTS
: 
2387             event
.Enable(self
.HasBreakpointsSet()) 
2389         elif (an_id 
== DebuggerService
.RUN_ID
 
2390         or an_id 
== DebuggerService
.RUN_LAST_ID
 
2391         or an_id 
== DebuggerService
.DEBUG_ID
 
2392         or an_id 
== DebuggerService
.DEBUG_LAST_ID
): 
2393             event
.Enable(self
.HasAnyFiles()) 
2398     #---------------------------------------------------------------------------- 
2400     #---------------------------------------------------------------------------- 
2402     def OnDebugProject(self
, event
, showDialog
=True): 
2403         if _WINDOWS 
and not _PYWIN32_INSTALLED
: 
2404             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.")) 
2406         if not Executor
.GetPythonExecutablePath(): 
2408         if BaseDebuggerUI
.DebuggerRunning(): 
2409             wx
.MessageBox(_("A debugger is already running. Please shut down the other debugger first."), _("Debugger Running")) 
2411         config 
= wx
.ConfigBase_Get() 
2412         host 
= config
.Read("DebuggerHostName", DEFAULT_HOST
) 
2414             wx
.MessageBox(_("No debugger host set. Please go to Tools->Options->Debugger and set one."), _("No Debugger Host")) 
2417         self
.ShowWindow(True) 
2418         projectService 
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
) 
2420             dlg 
= CommandPropertiesDialog(self
.GetView().GetFrame(), 'Debug File', projectService
, None, okButtonName
="Debug", debugging
=True) 
2423         dlg
.CenterOnParent() 
2425             showDialog 
= dlg
.MustShowDialog() 
2426         if showDialog 
and dlg
.ShowModal() == wx
.ID_OK
: 
2427             projectPath
, fileToDebug
, initialArgs
, startIn
, isPython
, environment 
= dlg
.GetSettings() 
2428         elif not showDialog
: 
2429             projectPath
, fileToDebug
, initialArgs
, startIn
, isPython
, environment 
= dlg
.GetSettings() 
2434         self
.PromptToSaveFiles() 
2435         shortFile 
= os
.path
.basename(fileToDebug
) 
2436         fileToDebug 
= DebuggerService
.ExpandPath(fileToDebug
) 
2437         if fileToDebug
.endswith('.bpel'): 
2438             self
.projectPath 
= projectPath
 
2439             self
.fileToDebug 
= fileToDebug
 
2442             # TODO: merge getting project stuff and save the results for 
2443             # WaitDebuggerThenRunProject() which currently does it again. 
2445             projects 
= projectService
.FindProjectByFile(projectPath
) 
2448             project 
= projects
[0] 
2449             lang    
= project
.GetAppInfo().language
 
2451                 self
.dbgLanguage 
= lang
 
2453             dbgService 
= wx
.GetApp().GetService(DebuggerService
) 
2455             evt 
= DebugInternalWebServer() 
2456             evt
.SetId(DebuggerService
.DEBUG_WEBSERVER_CONTINUE_ID
) 
2457             wx
.PostEvent(dbgService
._frame
, evt
) 
2459             if lang 
== projectmodel
.LANGUAGE_PHP
: 
2460                 evt 
= DebugInternalWebServer() 
2461                 evt
.SetId(DebuggerService
.DEBUG_WEBSERVER_NOW_RUN_PROJECT_ID
) 
2462                 wx
.PostEvent(dbgService
._frame
, evt
) 
2466         elif fileToDebug
.endswith('.php'): 
2467             page 
= PHPDebuggerUI(Service
.ServiceView
.bottomTab
, -1, str(fileToDebug
), self
) 
2468             count 
= Service
.ServiceView
.bottomTab
.GetPageCount() 
2469             Service
.ServiceView
.bottomTab
.AddPage(page
, _("Debugging: ") + shortFile
) 
2470             Service
.ServiceView
.bottomTab
.SetSelection(count
) 
2472             fullPhpScriptPath 
= os
.path
.normpath(fileToDebug
) 
2473             environment
["REDIRECT_STATUS"] = "200" 
2474             environment
["REDIRECT_URL"] = fullPhpScriptPath
 
2475             environment
["SERVER_SOFTWARE"] = "AG PHP Debugger 1.7" 
2476             environment
["SERVER_NAME"] = "localhost" 
2477             environment
["SERVER_ADDR"] = "127.0.0.1" 
2478             environment
["SERVER_PORT"] = "80" 
2479             environment
["REMOTE_ADDR"] = "127.0.0.1" 
2480             environment
["SCRIPT_FILENAME"] = "php" 
2481             environment
["GATEWAY_INTERFACE"] = "CGI/1.1" 
2482             environment
["SERVER_PROTOCOL"] = "HTTP/1.1" 
2483             environment
["REQUEST_METHOD"] = "GET" 
2484             environment
["REQUEST_URI"] = fullPhpScriptPath
 
2485             environment
["PATH_INFO"] = fullPhpScriptPath
 
2486             environment
["PATH_TRANSLATED"] = fullPhpScriptPath
 
2487             environment
["HTTP_COOKIE"] = "DBGSESSID=11439636363807700001@clienthost:10001" 
2489             page
.Execute(initialArgs
, startIn
, environment
) 
2492                 page 
= PythonDebuggerUI(Service
.ServiceView
.bottomTab
, -1, str(fileToDebug
), self
) 
2493                 count 
= Service
.ServiceView
.bottomTab
.GetPageCount() 
2494                 Service
.ServiceView
.bottomTab
.AddPage(page
, _("Debugging: ") + shortFile
) 
2495                 Service
.ServiceView
.bottomTab
.SetSelection(count
) 
2496                 page
.Execute(initialArgs
, startIn
, environment
) 
2500     def WaitDebuggerThenRunProject(self
): 
2502         #while not BaseDebuggerUI.DebuggerPastAutoContinue(): 
2504         #    wx.GetApp().Yield(True) 
2505         #    print "After Yield" 
2507         projectService 
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
) 
2508         projects 
= projectService
.FindProjectByFile(self
.projectPath
) 
2511         project 
= projects
[0] 
2513             deployFilePath 
= project
.GenerateDeployment() 
2514         except ProjectEditor
.DataServiceExistenceException
, e
: 
2515             dataSourceName 
= str(e
) 
2516             projectService
.PromptForMissingDataSource(dataSourceName
) 
2518         projectService
.RunProcessModel(self
.fileToDebug
, project
.GetAppInfo().language
, deployFilePath
) 
2520     def OnDebugWebServerContinue(self
, event
): 
2521         self
.OnDebugWebServer(event
, autoContinue
=True) 
2523     def OnDebugWebServer(self
, event
, autoContinue
=False): 
2524         #print "xxxxx debugging OnDebugWebServer" 
2525         if _WINDOWS 
and not _PYWIN32_INSTALLED
: 
2526             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.")) 
2528         if not Executor
.GetPythonExecutablePath(): 
2530         if BaseDebuggerUI
.DebuggerRunning(): 
2531             wx
.MessageBox(_("A debugger is already running. Please shut down the other debugger first."), _("Debugger Running")) 
2533         import WebServerService
 
2534         wsService 
= wx
.GetApp().GetService(WebServerService
.WebServerService
) 
2535         fileName
, args 
= wsService
.StopAndPrepareToDebug() 
2536         #print "xxxxx OnDebugWebServer: fileName=%s, args=%s" % (repr(fileName), repr(args)) 
2537         config 
= wx
.ConfigBase_Get() 
2538         host 
= config
.Read("DebuggerHostName", DEFAULT_HOST
) 
2540             wx
.MessageBox(_("No debugger host set. Please go to Tools->Options->Debugger and set one."), _("No Debugger Host")) 
2543             if self
.dbgLanguage 
== projectmodel
.LANGUAGE_PHP
: 
2544                 page 
= PHPDebuggerUI(Service
.ServiceView
.bottomTab
, -1, fileName
, self
) 
2546                 page 
= PythonDebuggerUI(Service
.ServiceView
.bottomTab
, -1, fileName
, self
, autoContinue
) 
2548             count 
= Service
.ServiceView
.bottomTab
.GetPageCount() 
2549             Service
.ServiceView
.bottomTab
.AddPage(page
, _("Debugging: Internal WebServer")) 
2550             Service
.ServiceView
.bottomTab
.SetSelection(count
) 
2551             page
.Execute(args
, startIn
=sysutilslib
.mainModuleDir
, environment
=os
.environ
, onWebServer 
= True) 
2555     def OnRunWebServer(self
, event
): 
2556         if not Executor
.GetPythonExecutablePath(): 
2558         import WebServerService
 
2559         wsService 
= wx
.GetApp().GetService(WebServerService
.WebServerService
) 
2560         wsService
.ShutDownAndRestart() 
2562     def HasAnyFiles(self
): 
2563         docs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
2564         return len(docs
) > 0 
2566     def PromptToSaveFiles(self
, running
=True): 
2567         filesModified 
= False 
2568         docs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
2570             if doc
.IsModified(): 
2571                 filesModified 
= True 
2574             frame 
= self
.GetView().GetFrame() 
2576                 yesNoMsg 
= wx
.MessageDialog(frame
, 
2577                           _("Files have been modified.\nWould you like to save all files before running?"), 
2579                           wx
.YES_NO|wx
.ICON_QUESTION
 
2582                 yesNoMsg 
= wx
.MessageDialog(frame
, 
2583                           _("Files have been modified.\nWould you like to save all files before debugging?"), 
2585                           wx
.YES_NO|wx
.ICON_QUESTION
 
2587             yesNoMsg
.CenterOnParent() 
2588             if yesNoMsg
.ShowModal() == wx
.ID_YES
: 
2589                 docs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
2595         BaseDebuggerUI
.ShutdownAllDebuggers() 
2596         RunCommandUI
.ShutdownAllRunners() 
2598     def OnRunProject(self
, event
, showDialog
=True): 
2599         if _WINDOWS 
and not _PYWIN32_INSTALLED
: 
2600             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.")) 
2602         if not Executor
.GetPythonExecutablePath(): 
2604         projectService 
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
) 
2606             dlg 
= CommandPropertiesDialog(self
.GetView().GetFrame(), 'Run', projectService
, None) 
2609         dlg
.CenterOnParent() 
2611             showDialog 
= dlg
.MustShowDialog() 
2612         if showDialog 
and dlg
.ShowModal() == wx
.ID_OK
: 
2613             projectPath
, fileToRun
, initialArgs
, startIn
, isPython
, environment 
= dlg
.GetSettings() 
2614         elif not showDialog
: 
2615             projectPath
, fileToRun
, initialArgs
, startIn
, isPython
, environment 
= dlg
.GetSettings() 
2620         self
.PromptToSaveFiles() 
2621         if fileToRun
.endswith('bpel'): 
2622             projects 
= projectService
.FindProjectByFile(projectPath
) 
2625             project 
= projects
[0] 
2627                 deployFilePath 
= project
.GenerateDeployment() 
2628             except ProjectEditor
.DataServiceExistenceException
, e
: 
2629                 dataSourceName 
= str(e
) 
2630                 projectService
.PromptForMissingDataSource(dataSourceName
) 
2632             projectService
.RunProcessModel(fileToRun
, project
.GetAppInfo().language
, deployFilePath
) 
2635         self
.ShowWindow(True) 
2636         shortFile 
= os
.path
.basename(fileToRun
) 
2637         page 
= RunCommandUI(Service
.ServiceView
.bottomTab
, -1, str(fileToRun
)) 
2638         count 
= Service
.ServiceView
.bottomTab
.GetPageCount() 
2639         Service
.ServiceView
.bottomTab
.AddPage(page
, "Running: " + shortFile
) 
2640         Service
.ServiceView
.bottomTab
.SetSelection(count
) 
2641         page
.Execute(initialArgs
, startIn
, environment
, onWebServer 
= True) 
2643     def OnToggleBreakpoint(self
, event
, line
=-1, fileName
=None): 
2645             view 
= wx
.GetApp().GetDocumentManager().GetCurrentView() 
2646             # Test to make sure we aren't the project view. 
2647             if not hasattr(view
, 'MarkerExists'): 
2649             fileName 
= wx
.GetApp().GetDocumentManager().GetCurrentDocument().GetFilename() 
2651                 line 
= view
.GetCtrl().GetCurrentLine() 
2654         if  self
.BreakpointSet(fileName
, line 
+ 1): 
2655             self
.ClearBreak(fileName
, line 
+ 1) 
2657                 view
.GetCtrl().Refresh() 
2659             self
.SetBreak(fileName
, line 
+ 1) 
2661                 view
.GetCtrl().Refresh() 
2662         # Now refresh all the markers icons in all the open views. 
2663         self
.ClearAllBreakpointMarkers() 
2664         self
.SetAllBreakpointMarkers() 
2666     def SilentToggleBreakpoint(self
, fileName
, line
): 
2668         for lineNumber 
in self
.GetBreakpointList(fileName
): 
2669             if int(lineNumber
) == int(line
): 
2673             self
.SetBreak(fileName
, line
) 
2675             self
.ClearBreak(fileName
, line
) 
2677     def SetBreak(self
, fileName
, line
): 
2678         expandedName 
= DebuggerService
.ExpandPath(fileName
) 
2679         if not self
._masterBPDict
.has_key(expandedName
): 
2680             self
._masterBPDict
[expandedName
] = [line
] 
2682             self
._masterBPDict
[expandedName
] += [line
] 
2683         # If we're already debugging, pass this bp off to the PythonDebuggerCallback 
2684         self
.NotifyDebuggersOfBreakpointChange() 
2686     def NotifyDebuggersOfBreakpointChange(self
): 
2687         BaseDebuggerUI
.NotifyDebuggersOfBreakpointChange() 
2689     def GetBreakpointList(self
, fileName
): 
2690         expandedName 
= DebuggerService
.ExpandPath(fileName
) 
2691         if not self
._masterBPDict
.has_key(expandedName
): 
2694             return self
._masterBPDict
[expandedName
] 
2696     def SetBreakpointList(self
, fileName
, bplist
): 
2697         expandedName 
= DebuggerService
.ExpandPath(fileName
) 
2698         self
._masterBPDict
[expandedName
] = bplist
 
2700     def BreakpointSet(self
, fileName
, line
): 
2701         expandedName 
= DebuggerService
.ExpandPath(fileName
) 
2702         if not self
._masterBPDict
.has_key(expandedName
): 
2706             for number 
in self
._masterBPDict
[expandedName
]: 
2707                 if(int(number
) == int(line
)): 
2711     def ClearBreak(self
, fileName
, line
): 
2712         expandedName 
= DebuggerService
.ExpandPath(fileName
) 
2713         if not self
._masterBPDict
.has_key(expandedName
): 
2714             print "In ClearBreak: no key" 
2718             for number 
in self
._masterBPDict
[expandedName
]: 
2719                 if(int(number
) != int(line
)): 
2720                     newList
.append(number
) 
2721             self
._masterBPDict
[expandedName
] = newList
 
2722         self
.NotifyDebuggersOfBreakpointChange() 
2724     def HasBreakpointsSet(self
): 
2725         for key
, value 
in self
._masterBPDict
.items(): 
2730     def ClearAllBreakpoints(self
): 
2731         self
._masterBPDict 
= {} 
2732         self
.NotifyDebuggersOfBreakpointChange() 
2733         self
.ClearAllBreakpointMarkers() 
2735     def ClearAllBreakpointMarkers(self
): 
2736         openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
2737         for openDoc 
in openDocs
: 
2738             if isinstance(openDoc
, CodeEditor
.CodeDocument
): 
2739                 openDoc
.GetFirstView().MarkerDeleteAll(CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
) 
2741     def UpdateBreakpointsFromMarkers(self
, view
, fileName
): 
2742         newbpLines 
= view
.GetMarkerLines(CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
) 
2743         self
.SetBreakpointList(fileName
, newbpLines
) 
2745     def GetMasterBreakpointDict(self
): 
2746         return self
._masterBPDict
 
2748     def SetAllBreakpointMarkers(self
): 
2749         openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
2750         for openDoc 
in openDocs
: 
2751             if(isinstance(openDoc
, CodeEditor
.CodeDocument
)): 
2752                 self
.SetCurrentBreakpointMarkers(openDoc
.GetFirstView()) 
2754     def SetCurrentBreakpointMarkers(self
, view
): 
2755         if isinstance(view
, CodeEditor
.CodeView
) and hasattr(view
, 'GetDocument'): 
2756             view
.MarkerDeleteAll(CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
) 
2757             for linenum 
in self
.GetBreakpointList(view
.GetDocument().GetFilename()): 
2758                 view
.MarkerAdd(lineNum
=int(linenum
) - 1, marker_index
=CodeEditor
.CodeCtrl
.BREAKPOINT_MARKER_NUM
) 
2760     def GetPhpDbgParam(self
): 
2761         return self
.phpDbgParam
 
2763     def SetPhpDbgParam(self
, value 
= None): 
2764         self
.phpDbgParam 
= value
 
2766 class DebuggerOptionsPanel(wx
.Panel
): 
2769     def __init__(self
, parent
, id): 
2770         wx
.Panel
.__init
__(self
, parent
, id) 
2772         config 
= wx
.ConfigBase_Get() 
2773         localHostStaticText 
= wx
.StaticText(self
, -1, _("Local Host Name:")) 
2774         self
._LocalHostTextCtrl 
= wx
.TextCtrl(self
, -1, config
.Read("DebuggerHostName", DEFAULT_HOST
), size 
= (150, -1)) 
2775         portNumberStaticText 
= wx
.StaticText(self
, -1, _("Port Range:")) 
2776         dashStaticText 
= wx
.StaticText(self
, -1, _("through to")) 
2777         startingPort
=config
.ReadInt("DebuggerStartingPort", DEFAULT_PORT
) 
2778         self
._PortNumberTextCtrl 
= wx
.lib
.intctrl
.IntCtrl(self
, -1, startingPort
, size 
= (50, -1)) 
2779         self
._PortNumberTextCtrl
.SetMin(1)#What are real values? 
2780         self
._PortNumberTextCtrl
.SetMax(65514) #What are real values? 
2781         self
.Bind(wx
.lib
.intctrl
.EVT_INT
, self
.MinPortChange
, self
._PortNumberTextCtrl
) 
2783         self
._EndPortNumberTextCtrl 
= wx
.lib
.intctrl
.IntCtrl(self
, -1, startingPort 
+ PORT_COUNT
, size 
= (50, -1)) 
2784         self
._EndPortNumberTextCtrl
.SetMin(22)#What are real values? 
2785         self
._EndPortNumberTextCtrl
.SetMax(65535)#What are real values? 
2786         self
._EndPortNumberTextCtrl
.Enable( False ) 
2787         debuggerPanelBorderSizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
2788         debuggerPanelSizer 
= wx
.GridBagSizer(hgap 
= 5, vgap 
= 5) 
2789         debuggerPanelSizer
.Add( localHostStaticText
, (0,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
) 
2790         debuggerPanelSizer
.Add( self
._LocalHostTextCtrl
, (0,1), (1,3), flag
=wx
.EXPAND|wx
.ALIGN_CENTER
) 
2791         debuggerPanelSizer
.Add( portNumberStaticText
, (1,0), flag
=wx
.ALIGN_LEFT|wx
.ALIGN_CENTER_VERTICAL
) 
2792         debuggerPanelSizer
.Add( self
._PortNumberTextCtrl
, (1,1), flag
=wx
.ALIGN_CENTER
) 
2793         debuggerPanelSizer
.Add( dashStaticText
, (1,2), flag
=wx
.ALIGN_CENTER
) 
2794         debuggerPanelSizer
.Add( self
._EndPortNumberTextCtrl
, (1,3), flag
=wx
.ALIGN_CENTER
) 
2795         FLUSH_PORTS_ID 
= wx
.NewId() 
2796         self
._flushPortsButton 
= wx
.Button(self
, FLUSH_PORTS_ID
, "Reset Port List") 
2797         wx
.EVT_BUTTON(parent
, FLUSH_PORTS_ID
, self
.FlushPorts
) 
2798         debuggerPanelSizer
.Add(self
._flushPortsButton
, (2,2), (1,2), flag
=wx
.ALIGN_RIGHT
) 
2800         debuggerPanelBorderSizer
.Add(debuggerPanelSizer
, 0, wx
.ALL
, SPACE
) 
2801         self
.SetSizer(debuggerPanelBorderSizer
) 
2803         parent
.AddPage(self
, _("Debugger")) 
2805     def FlushPorts(self
, event
): 
2806         if self
._PortNumberTextCtrl
.IsInBounds(): 
2807             config 
= wx
.ConfigBase_Get() 
2808             config
.WriteInt("DebuggerStartingPort", self
._PortNumberTextCtrl
.GetValue()) 
2809             PythonDebuggerUI
.NewPortRange() 
2811             wx
.MessageBox(_("The starting port is not valid. Please change the value and try again.", "Invalid Starting Port Number")) 
2813     def MinPortChange(self
, event
): 
2814         self
._EndPortNumberTextCtrl
.Enable( True ) 
2815         self
._EndPortNumberTextCtrl
.SetValue( self
._PortNumberTextCtrl
.GetValue() + PORT_COUNT
) 
2816         self
._EndPortNumberTextCtrl
.Enable( False ) 
2818     def OnOK(self
, optionsDialog
): 
2819         config 
= wx
.ConfigBase_Get() 
2820         config
.Write("DebuggerHostName", self
._LocalHostTextCtrl
.GetValue()) 
2821         if self
._PortNumberTextCtrl
.IsInBounds(): 
2822             config
.WriteInt("DebuggerStartingPort", self
._PortNumberTextCtrl
.GetValue()) 
2826         return getContinueIcon() 
2829 class CommandPropertiesDialog(wx
.Dialog
): 
2830     def __init__(self
, parent
, title
, projectService
, currentProjectDocument
, okButtonName
="Run", debugging
=False): 
2831         self
._projService 
= projectService
 
2834         self
._phpext 
= '.php' 
2835         for template 
in self
._projService
.GetDocumentManager().GetTemplates(): 
2836             if not ACTIVEGRID_BASE_IDE 
and template
.GetDocumentType() == ProcessModelEditor
.ProcessModelDocument
: 
2837                 self
._pmext 
= template
.GetDefaultExtension() 
2839         self
._currentProj 
= projectService
.GetCurrentProject() 
2840         self
._projectNameList
, self
._projectDocumentList
, selectedIndex 
= self
.GetProjectList() 
2841         if not self
._projectNameList
: 
2842             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")) 
2843             raise Exception("Nothing to Run or Debug.") 
2845         wx
.Dialog
.__init
__(self
, parent
, -1, title
) 
2847         projStaticText 
= wx
.StaticText(self
, -1, _("Project:")) 
2848         fileStaticText 
= wx
.StaticText(self
, -1, _("File:")) 
2849         argsStaticText 
= wx
.StaticText(self
, -1, _("Arguments:")) 
2850         startInStaticText 
= wx
.StaticText(self
, -1, _("Start in:")) 
2851         pythonPathStaticText 
= wx
.StaticText(self
, -1, _("PYTHONPATH:")) 
2852         postpendStaticText 
= _("Postpend win32api path") 
2853         cpPanelBorderSizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
2854         self
._projList 
= wx
.Choice(self
, -1, choices
=self
._projectNameList
) 
2855         self
.Bind(wx
.EVT_CHOICE
, self
.EvtListBox
, self
._projList
) 
2858         if wx
.Platform 
== "__WXMAC__": 
2860         flexGridSizer 
= wx
.GridBagSizer(GAP
, GAP
) 
2862         flexGridSizer
.Add(projStaticText
, (0,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
) 
2863         flexGridSizer
.Add(self
._projList
, (0,1), (1,2), flag
=wx
.EXPAND
) 
2865         flexGridSizer
.Add(fileStaticText
, (1,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
) 
2866         self
._fileList 
= wx
.Choice(self
, -1) 
2867         self
.Bind(wx
.EVT_CHOICE
, self
.OnFileSelected
, self
._fileList
) 
2868         flexGridSizer
.Add(self
._fileList
, (1,1), (1,2), flag
=wx
.EXPAND
) 
2870         config 
= wx
.ConfigBase_Get() 
2871         self
._lastArguments 
= config
.Read(self
.GetKey("LastRunArguments")) 
2872         self
._argsEntry 
= wx
.TextCtrl(self
, -1, str(self
._lastArguments
)) 
2873         self
._argsEntry
.SetToolTipString(str(self
._lastArguments
)) 
2875         flexGridSizer
.Add(argsStaticText
, (2,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
) 
2876         flexGridSizer
.Add(self
._argsEntry
, (2,1), (1,2), flag
=wx
.EXPAND
) 
2878         flexGridSizer
.Add(startInStaticText
, (3,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
) 
2879         self
._lastStartIn 
= config
.Read(self
.GetKey("LastRunStartIn")) 
2880         if not self
._lastStartIn
: 
2881             self
._lastStartIn 
= str(os
.getcwd()) 
2882         self
._startEntry 
= wx
.TextCtrl(self
, -1, self
._lastStartIn
) 
2883         self
._startEntry
.SetToolTipString(self
._lastStartIn
) 
2885         flexGridSizer
.Add(self
._startEntry
, (3,1), flag
=wx
.EXPAND
) 
2886         self
._findDir 
= wx
.Button(self
, -1, _("Browse...")) 
2887         self
.Bind(wx
.EVT_BUTTON
, self
.OnFindDirClick
, self
._findDir
) 
2888         flexGridSizer
.Add(self
._findDir
, (3,2)) 
2890         flexGridSizer
.Add(pythonPathStaticText
, (4,0), flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
) 
2891         if os
.environ
.has_key('PYTHONPATH'): 
2892             startval 
= os
.environ
['PYTHONPATH'] 
2895         self
._lastPythonPath 
= config
.Read(self
.GetKey("LastPythonPath"), startval
) 
2896         self
._pythonPathEntry 
= wx
.TextCtrl(self
, -1, self
._lastPythonPath
) 
2897         self
._pythonPathEntry
.SetToolTipString(self
._lastPythonPath
) 
2898         flexGridSizer
.Add(self
._pythonPathEntry
, (4,1), (1,2), flag
=wx
.EXPAND
) 
2900         if debugging 
and _WINDOWS
: 
2901             self
._postpendCheckBox 
= wx
.CheckBox(self
, -1, postpendStaticText
) 
2902             checked 
= bool(config
.ReadInt(self
.GetKey("PythonPathPostpend"), 1)) 
2903             self
._postpendCheckBox
.SetValue(checked
) 
2904             flexGridSizer
.Add(self
._postpendCheckBox
, (5,1), flag
=wx
.EXPAND
) 
2905         cpPanelBorderSizer
.Add(flexGridSizer
, 0, flag
=wx
.ALL
, border
=10) 
2907         box 
= wx
.StdDialogButtonSizer() 
2908         self
._okButton 
= wx
.Button(self
, wx
.ID_OK
, okButtonName
) 
2909         self
._okButton
.SetDefault() 
2910         self
._okButton
.SetHelpText(_("The ") + okButtonName 
+ _(" button completes the dialog")) 
2911         box
.AddButton(self
._okButton
) 
2912         self
.Bind(wx
.EVT_BUTTON
, self
.OnOKClick
, self
._okButton
) 
2913         btn 
= wx
.Button(self
, wx
.ID_CANCEL
, _("Cancel")) 
2914         btn
.SetHelpText(_("The Cancel button cancels the dialog.")) 
2917         cpPanelBorderSizer
.Add(box
, 0, flag
=wx
.ALIGN_RIGHT|wx
.ALL
, border
=5) 
2919         self
.SetSizer(cpPanelBorderSizer
) 
2921         # Set up selections based on last values used. 
2922         self
._fileNameList 
= None 
2923         self
._selectedFileIndex 
= -1 
2924         lastProject 
= config
.Read(self
.GetKey("LastRunProject")) 
2925         lastFile 
= config
.Read(self
.GetKey("LastRunFile")) 
2926         self
._mustShow 
= not lastFile
 
2928         if lastProject 
in self
._projectNameList
: 
2929             selectedIndex 
= self
._projectNameList
.index(lastProject
) 
2930         elif selectedIndex 
< 0: 
2932         self
._projList
.Select(selectedIndex
) 
2933         self
._selectedProjectIndex 
= selectedIndex
 
2934         self
._selectedProjectDocument 
= self
._projectDocumentList
[selectedIndex
] 
2935         self
.PopulateFileList(self
._selectedProjectDocument
, lastFile
) 
2937         cpPanelBorderSizer
.Fit(self
) 
2939     def MustShowDialog(self
): 
2940         return self
._mustShow
 
2942     def GetKey(self
, lastPart
): 
2943         if self
._currentProj
: 
2944             return "%s/%s/%s" % (ProjectEditor
.PROJECT_KEY
, self
._currentProj
.GetFilename().replace(os
.sep
, '|'), lastPart
) 
2947     def OnOKClick(self
, event
): 
2948         startIn 
= self
._startEntry
.GetValue() 
2949         fileToRun 
= self
._fileList
.GetStringSelection() 
2951             wx
.MessageBox(_("You must select a file to proceed. Note that not all projects have files that can be run or debugged.")) 
2953         isPython 
= fileToRun
.endswith(self
._pyext
) 
2954         if isPython 
and not os
.path
.exists(startIn
): 
2955             wx
.MessageBox(_("Starting directory does not exist. Please change this value.")) 
2957         config 
= wx
.ConfigBase_Get() 
2958         config
.Write(self
.GetKey("LastRunProject"), self
._projectNameList
[self
._selectedProjectIndex
]) 
2959         config
.Write(self
.GetKey("LastRunFile"), fileToRun
) 
2960         # Don't update the arguments or starting directory unless we're runing python. 
2962             config
.Write(self
.GetKey("LastRunArguments"), self
._argsEntry
.GetValue()) 
2963             config
.Write(self
.GetKey("LastRunStartIn"), self
._startEntry
.GetValue()) 
2964             config
.Write(self
.GetKey("LastPythonPath"),self
._pythonPathEntry
.GetValue()) 
2965             if hasattr(self
, "_postpendCheckBox"): 
2966                 config
.WriteInt(self
.GetKey("PythonPathPostpend"), int(self
._postpendCheckBox
.GetValue())) 
2968         self
.EndModal(wx
.ID_OK
) 
2970     def GetSettings(self
): 
2971         projectPath 
= self
._selectedProjectDocument
.GetFilename() 
2972         filename 
= self
._fileNameList
[self
._selectedFileIndex
] 
2973         args 
= self
._argsEntry
.GetValue() 
2974         startIn 
= self
._startEntry
.GetValue() 
2975         isPython 
= filename
.endswith(self
._pyext
) 
2977         if hasattr(self
, "_postpendCheckBox"): 
2978             postpend 
= self
._postpendCheckBox
.GetValue() 
2982             env
['PYTHONPATH'] = self
._pythonPathEntry
.GetValue() + os
.pathsep 
+ os
.path
.join(os
.getcwd(), "3rdparty", "pywin32") 
2984             env
['PYTHONPATH'] = self
._pythonPathEntry
.GetValue() 
2986         return projectPath
, filename
, args
, startIn
, isPython
, env
 
2988     def OnFileSelected(self
, event
): 
2989         self
._selectedFileIndex 
= self
._fileList
.GetSelection() 
2990         self
.EnableForFileType(event
.GetString()) 
2992     def EnableForFileType(self
, fileName
): 
2993         show 
= fileName
.endswith(self
._pyext
) or fileName
.endswith(self
._phpext
) 
2994         self
._startEntry
.Enable(show
) 
2995         self
._findDir
.Enable(show
) 
2996         self
._argsEntry
.Enable(show
) 
2999             self
._lastStartIn 
= self
._startEntry
.GetValue() 
3000             self
._startEntry
.SetValue("") 
3001             self
._lastArguments 
= self
._argsEntry
.GetValue() 
3002             self
._argsEntry
.SetValue("") 
3004             if fileName
.endswith(self
._phpext
): 
3005                 self
._startEntry
.SetValue(os
.path
.dirname(fileName
)) 
3007                 self
._startEntry
.SetValue(self
._lastStartIn
) 
3008             self
._argsEntry
.SetValue(self
._lastArguments
) 
3012     def OnFindDirClick(self
, event
): 
3013         dlg 
= wx
.DirDialog(self
, "Choose a starting directory:", self
._startEntry
.GetValue(), 
3014                           style
=wx
.DD_DEFAULT_STYLE|wx
.DD_NEW_DIR_BUTTON
) 
3016         dlg
.CenterOnParent() 
3017         if dlg
.ShowModal() == wx
.ID_OK
: 
3018             self
._startEntry
.SetValue(dlg
.GetPath()) 
3023     def EvtListBox(self
, event
): 
3024         if event
.GetString(): 
3025             index 
= self
._projectNameList
.index(event
.GetString()) 
3026             self
._selectedProjectDocument 
= self
._projectDocumentList
[index
] 
3027             self
._selectedProjectIndex 
= index
 
3028             self
.PopulateFileList(self
._selectedProjectDocument
) 
3030     def FilterFileList(self
, list): 
3031         files 
= filter(lambda f
: (self
._phpext 
and f
.endswith(self
._phpext
)) or (self
._pmext 
and f
.endswith(self
._pmext
)) or f
.endswith(self
._pyext
), list) 
3034     def PopulateFileList(self
, project
, shortNameToSelect
=None): 
3035         self
._fileNameList 
= self
.FilterFileList(project
.GetFiles()[:]) 
3036         self
._fileList
.Clear() 
3037         if not self
._fileNameList
: 
3039         self
._fileNameList
.sort(lambda a
, b
: cmp(os
.path
.basename(a
).lower(), os
.path
.basename(b
).lower())) 
3040         strings 
= map(lambda file: os
.path
.basename(file), self
._fileNameList
) 
3041         for index 
in range(0, len(strings
)): 
3042             if shortNameToSelect 
== strings
[index
]: 
3043                 self
._selectedFileIndex 
= index
 
3045         self
._fileList
.Hide() 
3046         self
._fileList
.AppendItems(strings
) 
3047         self
._fileList
.Show() 
3048         if self
._selectedFileIndex 
not in range(0, len(strings
)): 
3049             # Pick first bpel file if there is one. 
3050             for index 
in range(0, len(strings
)): 
3051                 if strings
[index
].endswith('.bpel'): 
3052                     self
._selectedFileIndex 
= index
 
3054         # Still no selected file, use first file.       
3055         if self
._selectedFileIndex 
not in range(0, len(strings
)): 
3056             self
._selectedFileIndex 
= 0 
3057         self
._fileList
.SetSelection(self
._selectedFileIndex
) 
3058         self
.EnableForFileType(strings
[self
._selectedFileIndex
]) 
3060     def GetProjectList(self
): 
3066         for document 
in self
._projService
.GetDocumentManager().GetDocuments(): 
3067             if document
.GetDocumentTemplate().GetDocumentType() == ProjectEditor
.ProjectDocument 
and len(document
.GetFiles()): 
3068                 docList
.append(document
) 
3069                 nameList
.append(os
.path
.basename(document
.GetFilename())) 
3070                 if document 
== self
._currentProj
: 
3074         #Check for open files not in any of these projects and add them to a default project 
3075         def AlreadyInProject(fileName
): 
3076             for projectDocument 
in docList
: 
3077                 if projectDocument
.IsFileInProject(fileName
): 
3081         unprojectedFiles 
= [] 
3082         for document 
in self
._projService
.GetDocumentManager().GetDocuments(): 
3083             if not ACTIVEGRID_BASE_IDE 
and type(document
) == ProcessModelEditor
.ProcessModelDocument
: 
3084                 if not AlreadyInProject(document
.GetFilename()): 
3085                     unprojectedFiles
.append(document
.GetFilename()) 
3086             if type(document
) == PythonEditor
.PythonDocument 
or type(document
) == PHPEditor
.PHPDocument
: 
3087                 if not AlreadyInProject(document
.GetFilename()): 
3088                     unprojectedFiles
.append(document
.GetFilename()) 
3090         if unprojectedFiles
: 
3091             unprojProj 
= ProjectEditor
.ProjectDocument() 
3092             unprojProj
.SetFilename(_("Not in any Project")) 
3093             unprojProj
.AddFiles(unprojectedFiles
) 
3094             docList
.append(unprojProj
) 
3095             nameList
.append(_("Not in any Project")) 
3097         return nameList
, docList
, index
 
3100 #---------------------------------------------------------------------- 
3101 from wx 
import ImageFromStream
, BitmapFromImage
 
3104 #---------------------------------------------------------------------- 
3107 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x02\ 
3108 \x00\x00\x00\x90\x91h6\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\ 
3109 \x00\x85IDAT(\x91\xbd\x92A\x16\x03!\x08CI\xdf\xdc\x0b\x8e\xe6\xd1\xe0d\xe9\ 
3110 \x82\xd6\xc7(\x9di7\xfd\xab<\x14\x13Q\xb8\xbb\xfc\xc2\xe3\xd3\x82\x99\xb9\ 
3111 \xe9\xaeq\xe1`f)HF\xc4\x8dC2\x06\xbf\x8a4\xcf\x1e\x03K\xe5h\x1bH\x02\x98\xc7\ 
3112 \x03\x98\xa9z\x07\x00%\xd6\xa9\xd27\x90\xac\xbbk\xe5\x15I\xcdD$\xdc\xa7\xceT\ 
3113 5a\xce\xf3\xe4\xa0\xaa\x8bO\x12\x11\xabC\xcb\x9c}\xd57\xef\xb0\xf3\xb7\x86p\ 
3114 \x97\xf7\xb5\xaa\xde\xb9\xfa|-O\xbdjN\x9b\xf8\x06A\xcb\x00\x00\x00\x00IEND\ 
3117 def getBreakBitmap(): 
3118     return BitmapFromImage(getBreakImage()) 
3120 def getBreakImage(): 
3121     stream 
= cStringIO
.StringIO(getBreakData()) 
3122     return ImageFromStream(stream
) 
3125     return wx
.IconFromBitmap(getBreakBitmap()) 
3127 #---------------------------------------------------------------------- 
3129 def getClearOutputData(): 
3131 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
3132 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
3133 \x00\x00\xb7IDAT8\x8d\xa5\x93\xdd\x11\xc3 \x0c\x83%`\xa3\xee\xd4\xaeA\xc6\ 
3134 \xe8N\xedF%\xea\x03\t\x81\xf0\x97\xbb\xf8%G\xce\xfe\x90eC\x1a\x8b;\xe1\xf2\ 
3135 \x83\xd6\xa0Q2\x8de\xf5oW\xa05H\xea\xd7\x93\x84$\x18\xeb\n\x88;\'.\xd5\x1d\ 
3136 \x80\x07\xe1\xa1\x1d\xa2\x1cbF\x92\x0f\x80\xe0\xd1 \xb7\x14\x8c \x00*\x15\ 
3137 \x97\x14\x8c\x8246\x1a\xf8\x98\'/\xdf\xd8Jn\xe65\xc0\xa7\x90_L"\x01\xde\x9d\ 
3138 \xda\xa7\x92\xfb\xc5w\xdf\t\x07\xc4\x05ym{\xd0\x1a\xe3\xb9xS\x81\x04\x18\x05\ 
3139 \xc9\x04\xc9a\x00Dc9\x9d\x82\xa4\xbc\xe8P\xb2\xb5P\xac\xf2\x0c\xd4\xf5\x00\ 
3140 \x88>\xac\xe17\x84\xe4\xb9G\x8b7\x9f\xf3\x1fsUl^\x7f\xe7y\x0f\x00\x00\x00\ 
3143 def getClearOutputBitmap(): 
3144     return BitmapFromImage(getClearOutputImage()) 
3146 def getClearOutputImage(): 
3147     stream 
= cStringIO
.StringIO(getClearOutputData()) 
3148     return ImageFromStream(stream
) 
3150 def getClearOutputIcon(): 
3151     return wx
.IconFromBitmap(getClearOutputBitmap()) 
3153 #---------------------------------------------------------------------- 
3156 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x02\ 
3157 \x00\x00\x00\x90\x91h6\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\ 
3158 \x00\xedIDAT(\x91\xa5\x90!\xae\x840\x10\x86g_\xd6"*kz\x82j\xb0h\x1c\t\' x\ 
3159 \x92Z\xc2\x05\x10\x95\x18\x0e\x00\x02M\x82 \xe1\nMF#jz\x80\xea&+\x9a\x10\x96\ 
3160 \xdd}\xfb\xc8\x1b\xd7?\xdf\x97\xfe3\xb7u]\xe1\xca\xfc\\\xa2\xff- \xe24M\xc7\ 
3161 \xc49wJ\xee\xc7G]\xd7\x8c1\xc6\x18\xe7\xdc\'B\x08k\xed1y\xfaa\x1cG\xad\xb5\ 
3162 \x94\x12\x11\x9dsy\x9e+\xa5\x84\x10;\r\x00\xb7\xd3\x95\x8c1UU\x05A\x00\x00\ 
3163 \xd6\xda,\xcb\x92$\xf9\xb8\x03\x00PJ\x85\x10Zk\xa5\xd4+\xfdF\x00\x80\xae\xeb\ 
3164 \x08!\x84\x90y\x9e\x11\xf1\x8bP\x96\xa5\xef\xdd\xb6\xad\xb5VJ\xf9\x9b\xe0\ 
3165 \xe9\xa6i8\xe7\xbe\xdb\xb6mi\x9a\x0e\xc3\xf0F\x88\xe3\x18\x00\xfa\xbe\x0f\ 
3166 \xc3\xd0\'\x9c\xf3eY\xa2(*\x8ab\xc7\x9e\xaed\x8c\xa1\x94\xben\xf5\xb1\xd2W\ 
3167 \xfa,\xfce.\x0b\x0f\xb8\x96e\x90gS\xe0v\x00\x00\x00\x00IEND\xaeB`\x82' 
3169 def getCloseBitmap(): 
3170     return BitmapFromImage(getCloseImage()) 
3172 def getCloseImage(): 
3173     stream 
= cStringIO
.StringIO(getCloseData()) 
3174     return ImageFromStream(stream
) 
3177     return wx
.IconFromBitmap(getCloseBitmap()) 
3179 #---------------------------------------------------------------------- 
3180 def getContinueData(): 
3182 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
3183 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
3184 \x00\x00\xcdIDAT8\x8d\xa5\x93\xd1\r\xc20\x0cD\xef\xec,\xc0b\x88\x8d`$\x06Cb\ 
3185 \x81\xc6\xc7GI\xeb\x94RZq?U"\xdby\xe7SIs\xfc#\xfbU\xa0\xa8\xba\xc6\xa0og\xee\ 
3186 !P\xd4y\x80\x04\xf3\xc2U\x82{\x9ct\x8f\x93\xb0\xa2\xdbm\xf5\xba\'h\xcdg=`\ 
3187 \xeeTT\xd1\xc6o& \t\x9a\x13\x00J\x9ev\xb1\'\xa3~\x14+\xbfN\x12\x92\x00@\xe6\ 
3188 \x85\xdd\x00\x000w\xe6\xe2\xde\xc7|\xdf\x08\xba\x1d(\xaa2n+\xca\xcd\x8d,\xea\ 
3189 \x98\xc4\x07\x01\x00D\x1dd^\xa8\xa8j\x9ew\xed`\xa9\x16\x99\xde\xa6G\x8b\xd3Y\ 
3190 \xe6\x85]\n\r\x7f\x99\xf5\x96Jnlz#\xab\xdb\xc1\x17\x19\xb0XV\xc2\xdf\xa3)\ 
3191 \x85<\xe4\x88\x85.F\x9a\xf3H3\xb0\xf3g\xda\xd2\x0b\xc5_|\x17\xe8\xf5R\xd6\ 
3192 \x00\x00\x00\x00IEND\xaeB`\x82' 
3194 def getContinueBitmap(): 
3195     return BitmapFromImage(getContinueImage()) 
3197 def getContinueImage(): 
3198     stream 
= cStringIO
.StringIO(getContinueData()) 
3199     return ImageFromStream(stream
) 
3201 def getContinueIcon(): 
3202     return wx
.IconFromBitmap(getContinueBitmap()) 
3204 #---------------------------------------------------------------------- 
3207 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
3208 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
3209 \x00\x00\x8eIDAT8\x8d\xa5SA\x12\xc4 \x08K\xb0\xff\xde\xe9\xbf\xb7\xa6\x87\ 
3210 \x1d:\xba\xa2tZn(\x84`"i\x05obk\x13\xd5CmN+\xcc\x00l\xd6\x0c\x00\xf5\xf8\x0e\ 
3211 gK\x06\x00 \xa5=k\x00\x00\xb0\xb2]\xd4?5f\xb1\xdb\xaf\xc6\xa2\xcb\xa8\xf0?\ 
3212 \x1c\x98\xae\x82\xbf\x81\xa4\x8eA\x16\xe1\n\xd1\xa4\x19\xb3\xe9\n\xce\xe8\ 
3213 \xf1\n\x9eg^\x18\x18\x90\xec<\x11\xf9#\x04XMZ\x19\xaac@+\x94\xd4\x99)SeP\xa1\ 
3214 )\xd6\x1dI\xe7*\xdc\xf4\x03\xdf~\xe7\x13T^Q?:X\x19d\x00\x00\x00\x00IEND\xaeB\ 
3217 def getNextBitmap(): 
3218     return BitmapFromImage(getNextImage()) 
3221     stream 
= cStringIO
.StringIO(getNextData()) 
3222     return ImageFromStream(stream
) 
3225     return wx
.IconFromBitmap(getNextBitmap()) 
3227 #---------------------------------------------------------------------- 
3228 def getStepInData(): 
3230 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
3231 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
3232 \x00\x00\x87IDAT8\x8d\xadSA\x12\x84 \x0ck\x8a\xffv\xfc\xb74{X\xeb0P@\x07s\ 
3233 \x84\xa4$\x01\x00M\xb2\x02]R\x8b\xc86\xda\xdc\xedd\xb4~\xe8\x86\xc6\x01-\x93\ 
3234 \x96\xd9#\xf6\x06\xc3;p1I\xd1\x14\x0b#|\x17aF\xec\r\xeeF\xa0eB\xd34\xca\xd0A\ 
3235 ]j\x84\xa6\x03\x00""\xb7\xb0tRZ\xf7x\xb7\x83\x91]\xcb\x7fa\xd9\x89\x0fC\xfd\ 
3236 \x94\x9d|9\x99^k\x13\xa1 \xb3\x16\x0f#\xd4\x88N~\x14\xe1-\x96\x7f\xe3\x0f\ 
3237 \x11\x91UC\x0cX\'\x1e\x00\x00\x00\x00IEND\xaeB`\x82' 
3239 def getStepInBitmap(): 
3240     return BitmapFromImage(getStepInImage()) 
3242 def getStepInImage(): 
3243     stream 
= cStringIO
.StringIO(getStepInData()) 
3244     return ImageFromStream(stream
) 
3246 def getStepInIcon(): 
3247     return wx
.IconFromBitmap(getStepInBitmap()) 
3249 #---------------------------------------------------------------------- 
3252 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
3253 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
3254 \x00\x00QIDAT8\x8d\xdd\x93A\n\xc00\x08\x04g\xb5\xff\x7fq\x13sn\xda&\x01\x0b\ 
3255 \xa5]\xf0"\xec(.J\xe6dd)\xf7\x13\x80\xadoD-12\xc8\\\xd3\r\xe2\xa6\x00j\xd9\ 
3256 \x0f\x03\xde\xbf\xc1\x0f\x00\xa7\x18\x01t\xd5\\\x05\xc8\\}T#\xe9\xfb\xbf\x90\ 
3257 \x064\xd8\\\x12\x1fQM\xf5\xd9\x00\x00\x00\x00IEND\xaeB`\x82' 
3259 def getStopBitmap(): 
3260     return BitmapFromImage(getStopImage()) 
3263     stream 
= cStringIO
.StringIO(getStopData()) 
3264     return ImageFromStream(stream
) 
3267     return wx
.IconFromBitmap(getStopBitmap()) 
3269 #---------------------------------------------------------------------- 
3270 def getStepReturnData(): 
3272 "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
3273 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
3274 \x00\x00\x8dIDAT8\x8d\xa5S\xd1\x0e\xc4 \x08\xa3\xb0\xff\xbe\xdc\x7fO\xba'6\ 
3275 \xf1\xf44\xb3O$Phk\x04\xd4d\x07\xba\xc5\x16\x91#\nza\xdb\x84\x1a\xa2\xfe\xf8\ 
3276 \x99\xfa_=p+\xe8\x91ED\xbc<\xa4 \xb4\x0b\x01\xb5{\x01\xf9\xbbG-\x13\x87\x16f\ 
3277 \x84\xbf\x16V\xb0l\x01@\no\x86\xae\x82Q\xa8=\xa4\x0c\x80\xe70\xbd\x10jh\xbd\ 
3278 \x07R\x06#\xc9^N\xb6\xde\x03)\x83\x18\xaeU\x90\x9c>a\xb2P\r\xb3&/Y\xa8\xd1^^\ 
3279 \xb6\xf0\x16\xdb\xbf\xf1\x02\x81\xa5TK\x1d\x07\xde\x92\x00\x00\x00\x00IEND\ 
3282 def getStepReturnBitmap(): 
3283     return BitmapFromImage(getStepReturnImage()) 
3285 def getStepReturnImage(): 
3286     stream 
= cStringIO
.StringIO(getStepReturnData()) 
3287     return ImageFromStream(stream
) 
3289 def getStepReturnIcon(): 
3290     return wx
.IconFromBitmap(getStepReturnBitmap()) 
3292 #---------------------------------------------------------------------- 
3293 def getAddWatchData(): 
3295 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
3296 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
3297 \x00\x00\x85IDAT8\x8dc`\x18h\xc0\x88.\xd0\xc0\xf0\xff?*\x9f\x11C\rN\x80\xae\ 
3298 \x19\x97\x18\xd1\x9a\x896\x84\x18[p\xa9aA\xe6\xfc7f\xc0P\xc4x\x163\x9cp\x1a0\ 
3299 \xeb,!w\x100 \x1dK\xac\x10\r\x08\x05".yFL\x85\x8c\x18b\xa8|Ty\xa2\x13\x92\'\ 
3300 \xc3\xe4\xff\x9f\x18\x1e3\xb82t\xa2\x88\x13\xedg.\x06aa&\x06VV\x7f\x86\xb9\ 
3301 \xcfU\x19\xbc\xb0\xba\x86h\xe0\xc8\xd0\xfc\xbf\x80\xe1>q)\x94\xe6\x00\x00\ 
3302 \x85\x923_\xd22\xa4\xcd\x00\x00\x00\x00IEND\xaeB`\x82' 
3304 def getAddWatchBitmap(): 
3305     return BitmapFromImage(getAddWatchImage()) 
3307 def getAddWatchImage(): 
3308     stream 
= cStringIO
.StringIO(getAddWatchData()) 
3309     return ImageFromStream(stream
) 
3311 def getAddWatchIcon(): 
3312     return wx
.IconFromBitmap(getAddWatchBitmap()) 
3314 #---------------------------------------------------------------------- 
3315 def getRunningManData(): 
3317 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
3318 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
3319 \x00\x01\x86IDAT8\x8d\xa5\x93\xb1K\x02Q\x1c\xc7\xbf\xcf\x9a\x1bZl\x88\xb4\ 
3320 \x04\x83\x10\xa2\x96\xc0A\xa8\x96\x96\xf4h\xe9\xf0\x1f\xd0\xcd(Bpi\x13nH\xb2\ 
3321 %\x9d\x1a"\xb9)\xb4\x16i\x10\n\x13MA\x84\xa3&\xa1\xa1A\xa1E\xbdw\x97\xa2\xbd\ 
3322 \x06\xf1(\xef,\xac\xef\xf6x\xdf\xf7}\x9f\xdf\x97\xf7\x081M\xe0?\x9a\xfc\xcd \ 
3323 \\\xdc2\x99\xb6A[\x14\x91C\x9e\x8c\x1d\x00\x00\xd5\xa7*\x9a\x8a\xfa7\x82u\ 
3324 \xfb\x14dj\x03mQ\xc3}\xf2\xb5\x83\xc7B\x9e\x89\xf7/\xda\xba\xd1\x94\x01\x00j\ 
3325 CF\xe2t\xef\x1b>\x1f\x8c3Q\xf0\x11\xd3p\xa2yf\x1a\xbc\xcb\n\xdee\x85\xdd>\ 
3326 \x07\xb5!C\xe9\xb4\xb1\xe9=b\x03\x8fc\xc3\xcf\xbcN\xb3\x9e`@\x11\xb9\xaa`\ 
3327 \x7fg\x19\'\x97y\xd8\x96\xfa\xf8\x95\xf23d\xa5O4\xbfh\x87(\xf8\x88a\xc0 $|~\ 
3328 \x87n\xf7\x03\xaa\xf2\x8e\xc0\xee\n\x00 \x91\xab\xc3\xeb4\xc3\xed\xe1\xb4qF\ 
3329 \x96\xb8`\xb3h\xb7\xa6Jo\xa0\x9d\x1eD\xc1G\xc4!\x9f\xae\x03\x00\xa8\xd5jh4e\ 
3330 \r\xb9\xf0P\x82T,\x83\xf3\x0bl\xd8k\x18\xe0\xf6p\x84vz\xa0M\x8aB\xf2\x98\x84\ 
3331 \x03[\xb0.XP\xcafu^m\x04>\x18\xd7\x9aM\xe4\xea\xba\xc0x\xec\x8c\xa9\xca*^\ 
3332 \xa5\x1b}\xc0u*\xc9B\xd14\x12\xe8\x97%\x15\xcbF`\xdaH\xba\x80P4\r)\x13#R\xc6\ 
3333 \xf0\xdc\x8f2\x01\x80\x94\x89\xe9>\xc9(\xcd:\xb6\xd9\x1aw\xa0\x95i\xf8\x0e\ 
3334 \xc6\xd1\'\'\x86\xa2\xd5\x8d \xbe@\x00\x00\x00\x00IEND\xaeB`\x82' 
3336 def getRunningManBitmap(): 
3337     return BitmapFromImage(getRunningManImage()) 
3339 def getRunningManImage(): 
3340     stream 
= cStringIO
.StringIO(getRunningManData()) 
3341     return ImageFromStream(stream
) 
3343 def getRunningManIcon(): 
3345     icon
.CopyFromBitmap(getRunningManBitmap()) 
3348 #---------------------------------------------------------------------- 
3349 def getDebuggingManData(): 
3351 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
3352 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
3353 \x00\x01\xafIDAT8\x8d\x8d\x93\xbfK[Q\x14\xc7?7\n:\t\xb5SA\xc1?@\xc1A\x9c,%\ 
3354 \xd0\xa9\x83\xb5\x98!(b\t\xbc\xa7q("m\x1c\n5V]D\xd4-\xf8\x83\xa7\xa2\t\xa1\ 
3355 \xa6\xed$8\x08\x92\xa1\x8b\x14A\xd0YB"\xa4\xf4\x87\x90\x97K\xa8\xcb\xed\xf0\ 
3356 \xc8m\xae\xfa\xd4\x03\x07.\xe7\x9e\xf3\xfd\x9e\x9f\x88@\x1d\xb5\xba\x94\xca\ 
3357 \xaa\xeb\xb6\xbb4\xc0\x03d&\xb1\xa7\xfc\xfe\x0c\x80L\xdaQ\xd2\xad\x90I;F\x80\ 
3358 ++\xbe\xe0bve\xdf\xd7y\xfemH\xc4\x162\xaa\xbb\xa5D(\x1c\x11\xb7\x02\x88@\x9d\ 
3359 f?*4\xd1\xf6\xa2\x0f\x80\x93\xf4\x8e\xe1\xb8\xf2\xf1\xb5\x18\x9cH(\x80\xe4bT\ 
3360 \x83\xd5W\x1f\xa1pD\x8c|\xd8T\x00\xdf\xd6\xd7\xe8\x1f\xb3tp\xf1\n^\xfe\xf8\ 
3361 \xa5^u7\x00P\x1eYP\xd2\x95\x1c\xa4\xa6\x84\x18\x8do\xab*C&\xed\xa8\xafG\x7f\ 
3362 \xe9\x1f\xb3x\xdc\x08\xad\x8f \x7f\tg%\xf8Y\x82\xe3\x8de\x86\x82\xcdF9\xba\ 
3363 \x84\xc1\x89\x84*K\t\xc0\xf0\xbbq:\x9f\xfcO\x7f?\xe7\x01\x9c\xff\x86Br\x8e\ 
3364 \x83\xd4\x94\x06\xd0SH.F\xc5P\xb0\x19\xe9z \xf9KOmkN\x07\x03\x14/r\xb4?\x8b\ 
3365 \xe8\xc6\xeb\x1e\x00l\x1f\xfe\xd15\x17\xaf<\xdb\xd37\xef\xd9\x9d\xb4\xe9\x8a\ 
3366 \xadj\xbfx\xb4\x878(#\x03\x00\xe9JF{[\xf92\xeb\xb1V\x99\xbbb\xab|\x9f\xb7\ 
3367 \x8d\xa9\x9cf\x1dq\x9au\xc4\x8dM\x0c\x85#\xa2x\x91cw\xd2\xd6i\x83\trk\x13\ 
3368 \x9f\x0fL\xab\xda\xe6\xd4\xd6Y+\xf1h\x8f\xb9T~G\xd2\x11\xb4\xd4\xe7O[\xf7\ 
3369 \x1e\xd6\x9d\xc7\xe4\xb7\xbe\x86\xf8\xb1?\xf4\x9c\xff\x01\xbe\xe9\xaf\x96\ 
3370 \xf0\x7fPA\x00\x00\x00\x00IEND\xaeB`\x82' 
3372 def getDebuggingManBitmap(): 
3373     return BitmapFromImage(getDebuggingManImage()) 
3375 def getDebuggingManImage(): 
3376     stream 
= cStringIO
.StringIO(getDebuggingManData()) 
3377     return ImageFromStream(stream
) 
3379 def getDebuggingManIcon(): 
3381     icon
.CopyFromBitmap(getDebuggingManBitmap()) 
3384 #----------------------------------------------------------------------