]> git.saurik.com Git - wxWidgets.git/blob - wxPython/samples/ide/activegrid/tool/DebuggerService.py
Added the ActiveGrid IDE as a sample application
[wxWidgets.git] / wxPython / samples / ide / activegrid / tool / DebuggerService.py
1 #----------------------------------------------------------------------------
2 # Name: DebuggerService.py
3 # Purpose: Debugger Service for Python.
4 #
5 # Author: Matt Fryer
6 #
7 # Created: 12/9/04
8 # CVS-ID: $Id$
9 # Copyright: (c) 2004-2005 ActiveGrid, Inc.
10 # License: wxWindows License
11 #----------------------------------------------------------------------------
12
13 import wx
14 import wx.lib.intctrl
15 import wx.lib.docview
16 import wx.lib.dialogs
17 import wx.gizmos
18 import wx._core
19 import wx.lib.pydocview
20 import Service
21 import STCTextEditor
22 import CodeEditor
23 import PythonEditor
24 from IDE import ACTIVEGRID_BASE_IDE
25 if not ACTIVEGRID_BASE_IDE:
26 import ProcessModelEditor
27 import wx.lib.scrolledpanel as scrolled
28 import sys
29 import time
30 import SimpleXMLRPCServer
31 import xmlrpclib
32 import os
33 import threading
34 import process
35 import Queue
36 import SocketServer
37 import ProjectEditor
38 import types
39 from xml.dom.minidom import parse, parseString
40 import bz2
41 import pickle
42 import DebuggerHarness
43 import traceback
44 import StringIO
45 if wx.Platform == '__WXMSW__':
46 import win32api
47 _WINDOWS = True
48 else:
49 _WINDOWS = False
50 _ = wx.GetTranslation
51
52 _VERBOSE = False
53 _WATCHES_ON = False
54
55 # Class to read from stdout or stderr and write the result to a text control.
56 # Args: file=file-like object
57 # callback_function= function that takes a single argument, the line of text
58 # read.
59 class OutputReaderThread(threading.Thread):
60 def __init__(self, file, callback_function, callbackOnExit=None, accumulate=True):
61 threading.Thread.__init__(self)
62 self._file = file
63 self._callback_function = callback_function
64 self._keepGoing = True
65 self._lineCount = 0
66 self._accumulate = accumulate
67 self._callbackOnExit = callbackOnExit
68
69 def run(self):
70 file = self._file
71 start = time.time()
72 output = ""
73 while self._keepGoing:
74 try:
75 # This could block--how to handle that?
76 text = file.readline()
77 if text == '' or text == None:
78 self._keepGoing = False
79 elif not self._accumulate:
80 self._callback_function(text)
81 else:
82 # Should use a buffer? StringIO?
83 output += text
84 # Seems as though the read blocks if we got an error, so, to be
85 # sure that at least some of the exception gets printed, always
86 # send the first hundred lines back as they come in.
87 if self._lineCount < 100:
88 self._callback_function(output)
89 self._lineCount += 1
90 output = ""
91 elif time.time() - start > 0.25:
92 try:
93 self._callback_function(output)
94 except wx._core.PyDeadObjectError:
95 # GUI was killed while we were blocked.
96 self._keepGoing = False
97 start = time.time()
98 output = ""
99 except:
100 tp, val, tb = sys.exc_info()
101 print "Exception in OutputReaderThread.run():", tp, val
102 self._keepGoing = False
103 if self._callbackOnExit:
104 try:
105 self._callbackOnExit()
106 except wx._core.PyDeadObjectError:
107 pass
108 if _VERBOSE: print "Exiting OutputReaderThread"
109
110 def AskToStop(self):
111 self._keepGoing = False
112
113 import wx.lib.newevent
114 (UpdateTextEvent, EVT_UPDATE_STDTEXT) = wx.lib.newevent.NewEvent()
115 (UpdateErrorEvent, EVT_UPDATE_ERRTEXT) = wx.lib.newevent.NewEvent()
116
117 class Executor:
118
119 def GetPythonExecutablePath():
120 config = wx.ConfigBase_Get()
121 path = config.Read("ActiveGridPythonLocation")
122 if path:
123 return path
124 wx.MessageBox(_("To proceed I need to know the location of the python.exe you would like to use.\nTo set this, go to Tools-->Options and use the 'Python' tab to enter a value.\n"), _("Python Executable Location Unknown"))
125 return None
126 GetPythonExecutablePath = staticmethod(GetPythonExecutablePath)
127
128 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):
129 self._fileName = fileName
130 self._stdOutCallback = self.OutCall
131 self._stdErrCallback = self.ErrCall
132 self._callbackOnExit = callbackOnExit
133 self._wxComponent = wxComponent
134 path = Executor.GetPythonExecutablePath()
135 self._cmd = '"' + path + '" -u \"' + fileName + '\"'
136 #Better way to do this? Quotes needed for windows file paths.
137 if(arg1 != None):
138 self._cmd += ' \"' + arg1 + '\"'
139 if(arg2 != None):
140 self._cmd += ' \"' + arg2 + '\"'
141 if(arg3 != None):
142 self._cmd += ' \"' + arg3 + '\"'
143 if(arg4 != None):
144 self._cmd += ' \"' + arg4 + '\"'
145 if(arg5 != None):
146 self._cmd += ' \"' + arg5 + '\"'
147 if(arg6 != None):
148 self._cmd += ' \"' + arg6 + '\"'
149 if(arg7 != None):
150 self._cmd += ' \"' + arg7 + '\"'
151 if(arg8 != None):
152 self._cmd += ' \"' + arg8 + '\"'
153 if(arg9 != None):
154 self._cmd += ' \"' + arg9 + '\"'
155
156 self._stdOutReader = None
157 self._stdErrReader = None
158 self._process = None
159
160 def OutCall(self, text):
161 evt = UpdateTextEvent(value = text)
162 wx.PostEvent(self._wxComponent, evt)
163
164 def ErrCall(self, text):
165 evt = UpdateErrorEvent(value = text)
166 wx.PostEvent(self._wxComponent, evt)
167
168 def Execute(self, arguments, startIn=None, environment=None):
169 if not startIn:
170 startIn = str(os.getcwd())
171 startIn = os.path.abspath(startIn)
172 command = self._cmd + ' ' + arguments
173 #stdinput = process.IOBuffer()
174 #self._process = process.ProcessProxy(command, mode='b', cwd=startIn, stdin=stdinput)
175 self._process = process.ProcessOpen(command, mode='b', cwd=startIn, env=environment)
176 # Kick off threads to read stdout and stderr and write them
177 # to our text control.
178 self._stdOutReader = OutputReaderThread(self._process.stdout, self._stdOutCallback, callbackOnExit=self._callbackOnExit)
179 self._stdOutReader.start()
180 self._stdErrReader = OutputReaderThread(self._process.stderr, self._stdErrCallback, accumulate=False)
181 self._stdErrReader.start()
182
183
184 def DoStopExecution(self):
185 if(self._process != None):
186 self._process.kill()
187 self._process.close()
188 self._process = None
189 if(self._stdOutReader != None):
190 self._stdOutReader.AskToStop()
191 if(self._stdErrReader != None):
192 self._stdErrReader.AskToStop()
193
194 class RunCommandUI(wx.Panel):
195
196 def __init__(self, parent, id, fileName):
197 wx.Panel.__init__(self, parent, id)
198 self._noteBook = parent
199
200 self.KILL_PROCESS_ID = wx.NewId()
201 self.CLOSE_TAB_ID = wx.NewId()
202
203 self.Bind(wx.EVT_END_PROCESS, self.OnProcessEnded)
204
205 # GUI Initialization follows
206 sizer = wx.BoxSizer(wx.HORIZONTAL)
207 self._tb = tb = wx.ToolBar(self, -1, wx.DefaultPosition, (30,1000), wx.TB_VERTICAL| wx.TB_FLAT, "Runner" )
208 tb.SetToolBitmapSize((16,16))
209 sizer.Add(tb, 0, wx.EXPAND |wx.ALIGN_LEFT|wx.ALL, 1)
210
211 close_bmp = getCloseBitmap()
212 tb.AddSimpleTool( self.CLOSE_TAB_ID, close_bmp, _('Close Window'))
213 wx.EVT_TOOL(self, self.CLOSE_TAB_ID, self.OnToolClicked)
214
215 stop_bmp = getStopBitmap()
216 tb.AddSimpleTool(self.KILL_PROCESS_ID, stop_bmp, _("Stop the Run."))
217 wx.EVT_TOOL(self, self.KILL_PROCESS_ID, self.OnToolClicked)
218
219 tb.Realize()
220 self._textCtrl = STCTextEditor.TextCtrl(self, wx.NewId()) #id)
221 sizer.Add(self._textCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
222 self._textCtrl.SetViewLineNumbers(False)
223 self._textCtrl.SetReadOnly(True)
224 if wx.Platform == '__WXMSW__':
225 font = "Courier New"
226 else:
227 font = "Courier"
228 self._textCtrl.SetFont(wx.Font(9, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = font))
229 self._textCtrl.SetFontColor(wx.BLACK)
230 self._textCtrl.StyleClearAll()
231
232 #Disabling for now...may interfere with file open. wx.stc.EVT_STC_DOUBLECLICK(self._textCtrl, self._textCtrl.GetId(), self.OnDoubleClick)
233
234 self.SetSizer(sizer)
235 sizer.Fit(self)
236
237 # Executor initialization
238 self._executor = Executor(fileName, self, callbackOnExit=self.ExecutorFinished)
239 self.Bind(EVT_UPDATE_STDTEXT, self.AppendText)
240 self.Bind(EVT_UPDATE_ERRTEXT, self.AppendErrorText)
241
242 def __del__(self):
243 self._executor.DoStopExecution()
244
245 def Execute(self, initialArgs, startIn, environment):
246 self._executor.Execute(initialArgs, startIn, environment)
247
248 def ExecutorFinished(self):
249 self._tb.EnableTool(self.KILL_PROCESS_ID, False)
250 nb = self.GetParent()
251 for i in range(0,nb.GetPageCount()):
252 if self == nb.GetPage(i):
253 text = nb.GetPageText(i)
254 newText = text.replace("Running", "Finished")
255 nb.SetPageText(i, newText)
256 break
257
258 def StopExecution(self):
259 self.Unbind(EVT_UPDATE_STDTEXT)
260 self.Unbind(EVT_UPDATE_ERRTEXT)
261 self._executor.DoStopExecution()
262
263 def AppendText(self, event):
264 self._textCtrl.SetReadOnly(False)
265 self._textCtrl.AddText(event.value)
266 self._textCtrl.ScrollToLine(self._textCtrl.GetLineCount())
267 self._textCtrl.SetReadOnly(True)
268
269 def AppendErrorText(self, event):
270 self._textCtrl.SetReadOnly(False)
271 self._textCtrl.SetFontColor(wx.RED)
272 self._textCtrl.StyleClearAll()
273 self._textCtrl.AddText(event.value)
274 self._textCtrl.ScrollToLine(self._textCtrl.GetLineCount())
275 self._textCtrl.SetFontColor(wx.BLACK)
276 self._textCtrl.StyleClearAll()
277 self._textCtrl.SetReadOnly(True)
278
279 #------------------------------------------------------------------------------
280 # Event handling
281 #-----------------------------------------------------------------------------
282
283 def OnToolClicked(self, event):
284 id = event.GetId()
285
286 if id == self.KILL_PROCESS_ID:
287 self._executor.DoStopExecution()
288
289 elif id == self.CLOSE_TAB_ID:
290 self._executor.DoStopExecution()
291 index = self._noteBook.GetSelection()
292 self._noteBook.GetPage(index).Show(False)
293 self._noteBook.RemovePage(index)
294
295 def OnDoubleClick(self, event):
296 # Looking for a stack trace line.
297 lineText, pos = self._textCtrl.GetCurLine()
298 fileBegin = lineText.find("File \"")
299 fileEnd = lineText.find("\", line ")
300 lineEnd = lineText.find(", in ")
301 if lineText == "\n" or fileBegin == -1 or fileEnd == -1 or lineEnd == -1:
302 # Check the line before the one that was clicked on
303 lineNumber = self._textCtrl.GetCurrentLine()
304 if(lineNumber == 0):
305 return
306 lineText = self._textCtrl.GetLine(lineNumber - 1)
307 fileBegin = lineText.find("File \"")
308 fileEnd = lineText.find("\", line ")
309 lineEnd = lineText.find(", in ")
310 if lineText == "\n" or fileBegin == -1 or fileEnd == -1 or lineEnd == -1:
311 return
312
313 filename = lineText[fileBegin + 6:fileEnd]
314 lineNum = int(lineText[fileEnd + 8:lineEnd])
315
316 foundView = None
317 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
318 for openDoc in openDocs:
319 if openDoc.GetFilename() == filename:
320 foundView = openDoc.GetFirstView()
321 break
322
323 if not foundView:
324 doc = wx.GetApp().GetDocumentManager().CreateDocument(filename, wx.lib.docview.DOC_SILENT)
325 foundView = doc.GetFirstView()
326
327 if foundView:
328 foundView.GetFrame().SetFocus()
329 foundView.Activate()
330 foundView.GotoLine(lineNum)
331 startPos = foundView.PositionFromLine(lineNum)
332
333 # FACTOR THIS INTO DocManager
334 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
335 for openDoc in openDocs:
336 if(isinstance(openDoc.GetFirstView(), CodeEditor.CodeView)):
337 openDoc.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
338
339 foundView.GetCtrl().MarkerAdd(lineNum -1, CodeEditor.CodeCtrl.CURRENT_LINE_MARKER_NUM)
340
341 def OnProcessEnded(self, evt):
342 self._executor.DoStopExecution()
343
344 DEFAULT_PORT = 32032
345 DEFAULT_HOST = 'localhost'
346 PORT_COUNT = 21
347
348 class DebugCommandUI(wx.Panel):
349 debuggerPortList = None
350 debuggers = []
351
352 def NotifyDebuggersOfBreakpointChange():
353 for debugger in DebugCommandUI.debuggers:
354 debugger.BreakPointChange()
355
356 NotifyDebuggersOfBreakpointChange = staticmethod(NotifyDebuggersOfBreakpointChange)
357
358 def DebuggerRunning():
359 for debugger in DebugCommandUI.debuggers:
360 if debugger._executor:
361 return True
362 return False
363 DebuggerRunning = staticmethod(DebuggerRunning)
364
365 def ShutdownAllDebuggers():
366 for debugger in DebugCommandUI.debuggers:
367 debugger.StopExecution()
368
369 ShutdownAllDebuggers = staticmethod(ShutdownAllDebuggers)
370
371 def GetAvailablePort():
372 for index in range( 0, len(DebugCommandUI.debuggerPortList)):
373 port = DebugCommandUI.debuggerPortList[index]
374 if DebugCommandUI.PortAvailable(port):
375 DebugCommandUI.debuggerPortList.pop(index)
376 return port
377 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"))
378 assert False, "Out of ports for debugger."
379
380 GetAvailablePort = staticmethod(GetAvailablePort)
381
382 def ReturnPortToPool(port):
383 config = wx.ConfigBase_Get()
384 startingPort = config.ReadInt("DebuggerStartingPort", DEFAULT_PORT)
385 if port in range(startingPort, startingPort + PORT_COUNT):
386 DebugCommandUI.debuggerPortList.append(port)
387
388 ReturnPortToPool = staticmethod(ReturnPortToPool)
389
390 def PortAvailable(port):
391 config = wx.ConfigBase_Get()
392 hostname = config.Read("DebuggerHostName", DEFAULT_HOST)
393 try:
394 server = AGXMLRPCServer((hostname, port))
395 server.server_close()
396 if _VERBOSE: print "Port ", str(port), " available."
397 return True
398 except:
399 tp,val,tb = sys.exc_info()
400 if _VERBOSE: traceback.print_exception(tp, val, tb)
401 if _VERBOSE: print "Port ", str(port), " unavailable."
402 return False
403
404 PortAvailable = staticmethod(PortAvailable)
405
406 def NewPortRange():
407 config = wx.ConfigBase_Get()
408 startingPort = config.ReadInt("DebuggerStartingPort", DEFAULT_PORT)
409 DebugCommandUI.debuggerPortList = range(startingPort, startingPort + PORT_COUNT)
410 NewPortRange = staticmethod(NewPortRange)
411
412 def __init__(self, parent, id, command, service):
413 # Check for ports before creating the panel.
414 if not DebugCommandUI.debuggerPortList:
415 DebugCommandUI.NewPortRange()
416 self._debuggerPort = str(DebugCommandUI.GetAvailablePort())
417 self._guiPort = str(DebugCommandUI.GetAvailablePort())
418 self._debuggerBreakPort = str(DebugCommandUI.GetAvailablePort())
419
420 wx.Panel.__init__(self, parent, id)
421
422 self._parentNoteBook = parent
423 self._command = command
424 self._textCtrl = None
425 self._service = service
426 self._executor = None
427 self.STEP_ID = wx.NewId()
428 self.CONTINUE_ID = wx.NewId()
429 self.STEP_OUT_ID = wx.NewId()
430 self.NEXT_ID = wx.NewId()
431 self.KILL_PROCESS_ID = wx.NewId()
432 self.CLOSE_WINDOW_ID = wx.NewId()
433 self.BREAK_INTO_DEBUGGER_ID = wx.NewId()
434 self.CLEAR_ID = wx.NewId()
435 self.ADD_WATCH_ID = wx.NewId()
436 sizer = wx.BoxSizer(wx.VERTICAL)
437 self._tb = tb = wx.ToolBar(self, -1, wx.DefaultPosition, (1000,30), wx.TB_HORIZONTAL| wx.NO_BORDER| wx.TB_FLAT| wx.TB_TEXT, "Debugger" )
438 sizer.Add(tb, 0, wx.EXPAND |wx.ALIGN_LEFT|wx.ALL, 1)
439 tb.SetToolBitmapSize((16,16))
440
441 close_bmp = getCloseBitmap()
442 tb.AddSimpleTool( self.CLOSE_WINDOW_ID, close_bmp, _('Close Window'))
443 wx.EVT_TOOL(self, self.CLOSE_WINDOW_ID, self.StopAndRemoveUI)
444
445 stop_bmp = getStopBitmap()
446 tb.AddSimpleTool( self.KILL_PROCESS_ID, stop_bmp, _("Stop Debugging"))
447 wx.EVT_TOOL(self, self.KILL_PROCESS_ID, self.StopExecution)
448
449 tb.AddSeparator()
450
451 break_bmp = getBreakBitmap()
452 tb.AddSimpleTool( self.BREAK_INTO_DEBUGGER_ID, break_bmp, _("Break into Debugger"))
453 wx.EVT_TOOL(self, self.BREAK_INTO_DEBUGGER_ID, self.BreakExecution)
454
455 tb.AddSeparator()
456
457 continue_bmp = getContinueBitmap()
458 tb.AddSimpleTool( self.CONTINUE_ID, continue_bmp, _("Continue Execution"))
459 wx.EVT_TOOL(self, self.CONTINUE_ID, self.OnContinue)
460
461 tb.AddSeparator()
462
463 next_bmp = getNextBitmap()
464 tb.AddSimpleTool( self.NEXT_ID, next_bmp, _("Step to next line"))
465 wx.EVT_TOOL(self, self.NEXT_ID, self.OnNext)
466
467 step_bmp = getStepInBitmap()
468 tb.AddSimpleTool( self.STEP_ID, step_bmp, _("Step in"))
469 wx.EVT_TOOL(self, self.STEP_ID, self.OnSingleStep)
470
471 stepOut_bmp = getStepReturnBitmap()
472 tb.AddSimpleTool(self.STEP_OUT_ID, stepOut_bmp, _("Stop at function return"))
473 wx.EVT_TOOL(self, self.STEP_OUT_ID, self.OnStepOut)
474
475 tb.AddSeparator()
476 if _WATCHES_ON:
477 watch_bmp = getAddWatchBitmap()
478 tb.AddSimpleTool(self.ADD_WATCH_ID, watch_bmp, _("Add a watch"))
479 wx.EVT_TOOL(self, self.ADD_WATCH_ID, self.OnAddWatch)
480 tb.AddSeparator()
481
482 clear_bmp = getClearOutputBitmap()
483 tb.AddSimpleTool(self.CLEAR_ID, clear_bmp, _("Clear output pane"))
484 wx.EVT_TOOL(self, self.CLEAR_ID, self.OnClearOutput)
485
486 tb.Realize()
487 self.framesTab = None
488 self.DisableWhileDebuggerRunning()
489 self._notebook = wx.Notebook(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.LB_DEFAULT, "Debugger")
490 sizer.Add(self._notebook, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
491 self.consoleTab = self.MakeConsoleTab(self._notebook, wx.NewId(), None)
492 self.framesTab = self.MakeFramesTab(self._notebook, wx.NewId(), None)
493 self.breakPointsTab = self.MakeBreakPointsTab(self._notebook, wx.NewId(), None)
494 self._notebook.AddPage(self.consoleTab, "Output")
495 self._notebook.AddPage(self.framesTab, "Frames")
496 self._notebook.AddPage(self.breakPointsTab, "Break Points")
497
498 self._statusBar = wx.StatusBar( self, -1)
499 self._statusBar.SetFieldsCount(1)
500 sizer.Add(self._statusBar, 0, wx.EXPAND |wx.ALIGN_LEFT|wx.ALL, 1)
501
502 self.SetStatusText("Starting debug...")
503
504 self.SetSizer(sizer)
505 sizer.Fit(self)
506 config = wx.ConfigBase_Get()
507 self._debuggerHost = self._guiHost = config.Read("DebuggerHostName", DEFAULT_HOST)
508 url = 'http://' + self._debuggerHost + ':' + self._debuggerPort + '/'
509 self._breakURL = 'http://' + self._debuggerHost + ':' + self._debuggerBreakPort + '/'
510 self._callback = DebuggerCallback(self._guiHost, self._guiPort, url, self._breakURL, self)
511 if DebuggerHarness.__file__.find('library.zip') > 0:
512 try:
513 fname = DebuggerHarness.__file__
514 parts = fname.split('library.zip')
515 path = os.path.join(parts[0],'activegrid', 'tool', 'DebuggerHarness.py')
516 except:
517 tp, val, tb = sys.exc_info()
518 traceback.print_exception(tp, val, tb)
519
520 else:
521 print "Starting debugger on these ports: %s, %s, %s" % (str(self._debuggerPort) , str(self._guiPort) , str(self._debuggerBreakPort))
522 path = DebuggerService.ExpandPath(DebuggerHarness.__file__)
523 self._executor = Executor(path, self, self._debuggerHost, \
524 self._debuggerPort, self._debuggerBreakPort, self._guiHost, self._guiPort, self._command, callbackOnExit=self.ExecutorFinished)
525
526 self.Bind(EVT_UPDATE_STDTEXT, self.AppendText)
527 self.Bind(EVT_UPDATE_ERRTEXT, self.AppendErrorText)
528 DebugCommandUI.debuggers.append(self)
529 self._stopped = False
530
531 def OnSingleStep(self, event):
532 self._callback.SingleStep()
533
534 def OnContinue(self, event):
535 self._callback.Continue()
536
537 def OnStepOut(self, event):
538 self._callback.Return()
539
540 def OnNext(self, event):
541 self._callback.Next()
542
543 def BreakPointChange(self):
544 if not self._stopped:
545 self._callback.pushBreakpoints()
546 self.breakPointsTab.PopulateBPList()
547
548 def __del__(self):
549 if self in DebugCommandUI.debuggers:
550 DebugCommandUI.debuggers.remove(self)
551
552 def SwitchToOutputTab(self):
553 self._notebook.SetSelection(0)
554
555 def DisableWhileDebuggerRunning(self):
556 self._tb.EnableTool(self.STEP_ID, False)
557 self._tb.EnableTool(self.CONTINUE_ID, False)
558 self._tb.EnableTool(self.STEP_OUT_ID, False)
559 self._tb.EnableTool(self.NEXT_ID, False)
560 self._tb.EnableTool(self.BREAK_INTO_DEBUGGER_ID, True)
561 if _WATCHES_ON:
562 self._tb.EnableTool(self.ADD_WATCH_ID, False)
563 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
564 for openDoc in openDocs:
565 if(isinstance(openDoc.GetFirstView(), CodeEditor.CodeView)):
566 openDoc.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
567 if self.framesTab:
568 self.framesTab.ClearWhileRunning()
569 #wx.GetApp().ProcessPendingEvents() #Yield(True)
570
571 def EnableWhileDebuggerStopped(self):
572 self._tb.EnableTool(self.STEP_ID, True)
573 self._tb.EnableTool(self.CONTINUE_ID, True)
574 self._tb.EnableTool(self.STEP_OUT_ID, True)
575 self._tb.EnableTool(self.NEXT_ID, True)
576 if _WATCHES_ON:
577 self._tb.EnableTool(self.ADD_WATCH_ID, True)
578 self._tb.EnableTool(self.BREAK_INTO_DEBUGGER_ID, False)
579 #if _WINDOWS:
580 # wx.GetApp().GetTopWindow().RequestUserAttention()
581
582 def ExecutorFinished(self):
583 if _VERBOSE: print "In ExectorFinished"
584 try:
585 self.DisableAfterStop()
586 except wx._core.PyDeadObjectError:
587 pass
588 try:
589 nb = self.GetParent()
590 for i in range(0, nb.GetPageCount()):
591 if self == nb.GetPage(i):
592 text = nb.GetPageText(i)
593 newText = text.replace("Debugging", "Finished")
594 nb.SetPageText(i, newText)
595 if _VERBOSE: print "In ExectorFinished, changed tab title."
596 break
597 except:
598 if _VERBOSE: print "In ExectorFinished, got exception"
599
600 def DisableAfterStop(self):
601 self.DisableWhileDebuggerRunning()
602 self._tb.EnableTool(self.BREAK_INTO_DEBUGGER_ID, False)
603 self._tb.EnableTool(self.KILL_PROCESS_ID, False)
604
605 def SynchCurrentLine(self, filename, lineNum):
606 # FACTOR THIS INTO DocManager
607 self.DeleteCurrentLineMarkers()
608
609 # Filename will be <string> if we're in a bit of code that was executed from
610 # a string (rather than a file). I haven't been able to get the original string
611 # for display.
612 if filename == '<string>':
613 return
614 foundView = None
615 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
616 for openDoc in openDocs:
617 # This ugliness to prevent comparison failing because the drive letter
618 # gets lowercased occasionally. Don't know why that happens or why it
619 # only happens occasionally.
620 if DebuggerService.ComparePaths(openDoc.GetFilename(),filename):
621 foundView = openDoc.GetFirstView()
622 break
623
624 if not foundView:
625 if _VERBOSE:
626 print "filename=", filename
627 doc = wx.GetApp().GetDocumentManager().CreateDocument(DebuggerService.ExpandPath(filename), wx.lib.docview.DOC_SILENT)
628 foundView = doc.GetFirstView()
629
630 if foundView:
631 foundView.GetFrame().SetFocus()
632 foundView.Activate()
633 foundView.GotoLine(lineNum)
634 startPos = foundView.PositionFromLine(lineNum)
635
636 foundView.GetCtrl().MarkerAdd(lineNum -1, CodeEditor.CodeCtrl.CURRENT_LINE_MARKER_NUM)
637
638 def DeleteCurrentLineMarkers(self):
639 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
640 for openDoc in openDocs:
641 if(isinstance(openDoc.GetFirstView(), CodeEditor.CodeView)):
642 openDoc.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
643
644 def LoadFramesListXML(self, framesXML):
645 self.framesTab.LoadFramesListXML(framesXML)
646
647 def SetStatusText(self, text):
648 self._statusBar.SetStatusText(text,0)
649
650 def Execute(self, initialArgs, startIn, environment):
651 self._callback.start()
652 self._executor.Execute(initialArgs, startIn, environment)
653 self._callback.waitForRPC()
654
655 def BreakExecution(self, event):
656 self._callback.BreakExecution()
657
658
659 def StopExecution(self, event):
660 self._stopped = True
661 self.DisableAfterStop()
662 try:
663 self._callback.ServerClose()
664 except:
665 pass
666 try:
667 if self._executor:
668 self._executor.DoStopExecution()
669 self._executor = None
670 except:
671 pass
672 self.DeleteCurrentLineMarkers()
673 DebugCommandUI.ReturnPortToPool(self._debuggerPort)
674 DebugCommandUI.ReturnPortToPool(self._guiPort)
675 DebugCommandUI.ReturnPortToPool(self._debuggerBreakPort)
676
677 def StopAndRemoveUI(self, event):
678 self.StopExecution(None)
679 if self in DebugCommandUI.debuggers:
680 DebugCommandUI.debuggers.remove(self)
681 index = self._parentNoteBook.GetSelection()
682 self._parentNoteBook.GetPage(index).Show(False)
683 self._parentNoteBook.RemovePage(index)
684
685 def GetConsoleTextControl(self):
686 return self._textCtrl
687
688 def OnClearOutput(self, event):
689 self._textCtrl.SetReadOnly(False)
690 self._textCtrl.ClearAll()
691 self._textCtrl.SetReadOnly(True)
692
693 def OnAddWatch(self, event):
694 if self.framesTab:
695 self.framesTab.OnWatch(event)
696
697 def MakeConsoleTab(self, parent, id, debugger):
698 panel = wx.Panel(parent, id)
699 sizer = wx.BoxSizer(wx.HORIZONTAL)
700 self._textCtrl = STCTextEditor.TextCtrl(panel, wx.NewId())
701 sizer.Add(self._textCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
702 self._textCtrl.SetViewLineNumbers(False)
703 self._textCtrl.SetReadOnly(True)
704 if wx.Platform == '__WXMSW__':
705 font = "Courier New"
706 else:
707 font = "Courier"
708 self._textCtrl.SetFont(wx.Font(9, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = font))
709 self._textCtrl.SetFontColor(wx.BLACK)
710 self._textCtrl.StyleClearAll()
711 panel.SetSizer(sizer)
712 sizer.Fit(panel)
713
714 return panel
715
716 def MakeFramesTab(self, parent, id, debugger):
717 panel = FramesUI(parent, id, self)
718 return panel
719
720 def MakeBreakPointsTab(self, parent, id, debugger):
721 panel = BreakpointsUI(parent, id, self)
722 return panel
723
724 def AppendText(self, event):
725 self._textCtrl.SetReadOnly(False)
726 self._textCtrl.AddText(event.value)
727 self._textCtrl.ScrollToLine(self._textCtrl.GetLineCount())
728 self._textCtrl.SetReadOnly(True)
729
730 def AppendErrorText(self, event):
731 self._textCtrl.SetReadOnly(False)
732 self._textCtrl.SetFontColor(wx.RED)
733 self._textCtrl.StyleClearAll()
734 self._textCtrl.AddText(event.value)
735 self._textCtrl.ScrollToLine(self._textCtrl.GetLineCount())
736 self._textCtrl.SetFontColor(wx.BLACK)
737 self._textCtrl.StyleClearAll()
738 self._textCtrl.SetReadOnly(True)
739
740 class BreakpointsUI(wx.Panel):
741 def __init__(self, parent, id, ui):
742 wx.Panel.__init__(self, parent, id)
743 self._ui = ui
744 self.currentItem = None
745 self.clearBPID = wx.NewId()
746 self.Bind(wx.EVT_MENU, self.ClearBreakPoint, id=self.clearBPID)
747 self.syncLineID = wx.NewId()
748 self.Bind(wx.EVT_MENU, self.SyncBPLine, id=self.syncLineID)
749
750 sizer = wx.BoxSizer(wx.VERTICAL)
751 p1 = self
752 self._bpListCtrl = wx.ListCtrl(p1, -1, pos=wx.DefaultPosition, size=(1000,1000), style=wx.LC_REPORT)
753 sizer.Add(self._bpListCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
754 self._bpListCtrl.InsertColumn(0, "File")
755 self._bpListCtrl.InsertColumn(1, "Line")
756 self._bpListCtrl.InsertColumn(2, "Path")
757 self._bpListCtrl.SetColumnWidth(0, 150)
758 self._bpListCtrl.SetColumnWidth(1, 50)
759 self._bpListCtrl.SetColumnWidth(2, 450)
760 self._bpListCtrl.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnListRightClick)
761 self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.ListItemSelected, self._bpListCtrl)
762 self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.ListItemDeselected, self._bpListCtrl)
763
764 self.PopulateBPList()
765
766 p1.SetSizer(sizer)
767 sizer.Fit(p1)
768 p1.Layout()
769
770 def PopulateBPList(self):
771 list = self._bpListCtrl
772 list.DeleteAllItems()
773
774 bps = wx.GetApp().GetService(DebuggerService).GetMasterBreakpointDict()
775 index = 0
776 for fileName in bps.keys():
777 shortFile = os.path.basename(fileName)
778 lines = bps[fileName]
779 if lines:
780 for line in lines:
781 list.InsertStringItem(index, shortFile)
782 list.SetStringItem(index, 1, str(line))
783 list.SetStringItem(index, 2, fileName)
784
785 def OnListRightClick(self, event):
786 menu = wx.Menu()
787 item = wx.MenuItem(menu, self.clearBPID, "Clear Breakpoint")
788 menu.AppendItem(item)
789 item = wx.MenuItem(menu, self.syncLineID, "Goto Source Line")
790 menu.AppendItem(item)
791 self.PopupMenu(menu, event.GetPosition())
792 menu.Destroy()
793
794 def SyncBPLine(self, event):
795 if self.currentItem != -1:
796 list = self._bpListCtrl
797 fileName = list.GetItem(self.currentItem, 2).GetText()
798 lineNumber = list.GetItem(self.currentItem, 1).GetText()
799 self._ui.SynchCurrentLine( fileName, int(lineNumber) )
800
801 def ClearBreakPoint(self, event):
802 if self.currentItem >= 0:
803 list = self._bpListCtrl
804 fileName = list.GetItem(self.currentItem, 2).GetText()
805 lineNumber = list.GetItem(self.currentItem, 1).GetText()
806 wx.GetApp().GetService(DebuggerService).OnToggleBreakpoint(None, line=int(lineNumber) -1, fileName=fileName )
807
808 def ListItemSelected(self, event):
809 self.currentItem = event.m_itemIndex
810
811 def ListItemDeselected(self, event):
812 self.currentItem = -1
813
814 class Watch:
815 CODE_ALL_FRAMES = 1
816 CODE_THIS_BLOCK = 2
817 CODE_THIS_LINE = 4
818 CODE_RUN_ONCE = 8
819
820 def __init__(self, name, command, show_code=CODE_ALL_FRAMES):
821 self._name = name
822 self._command = command
823 self._show_code = show_code
824
825 class WatchDialog(wx.Dialog):
826 WATCH_ALL_FRAMES = "Watch in all frames"
827 WATCH_THIS_FRAME = "Watch in this frame only"
828 WATCH_ONCE = "Watch once and delete"
829 def __init__(self, parent, title, chain):
830 wx.Dialog.__init__(self, parent, -1, title, style=wx.DEFAULT_DIALOG_STYLE)
831 self._chain = chain
832 self.label_2 = wx.StaticText(self, -1, "Watch Name:")
833 self._watchNameTextCtrl = wx.TextCtrl(self, -1, "")
834 self.label_3 = wx.StaticText(self, -1, "eval(", style=wx.ALIGN_RIGHT)
835 self._watchValueTextCtrl = wx.TextCtrl(self, -1, "")
836 self.label_4 = wx.StaticText(self, -1, ",frame.f_globals, frame.f_locals)")
837 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)
838
839 self._okButton = wx.Button(self, wx.ID_OK, "OK", size=(75,-1))
840 self._okButton.SetDefault()
841 self._okButton.SetHelpText(_("The OK button completes the dialog"))
842 def OnOkClick(event):
843 if self._watchNameTextCtrl.GetValue() == "":
844 wx.MessageBox(_("You must enter a name for the watch."), _("Add Watch"))
845 return
846 if self._watchValueTextCtrl.GetValue() == "":
847 wx.MessageBox(_("You must enter some code to run for the watch."), _("Add Watch"))
848 return
849 self.EndModal(wx.ID_OK)
850 self.Bind(wx.EVT_BUTTON, OnOkClick, self._okButton)
851
852 self._cancelButton = wx.Button(self, wx.ID_CANCEL, _("Cancel"), size=(75,-1))
853 self._cancelButton.SetHelpText(_("The Cancel button cancels the dialog."))
854
855 self.__set_properties()
856 self.__do_layout()
857
858 def GetSettings(self):
859 return self._watchNameTextCtrl.GetValue(), self._watchValueTextCtrl.GetValue(), self.GetSendFrame(), self.GetRunOnce()
860
861 def GetSendFrame(self):
862 return (WatchDialog.WATCH_ALL_FRAMES != self.radio_box_1.GetStringSelection())
863
864 def GetRunOnce(self):
865 return (WatchDialog.WATCH_ONCE == self.radio_box_1.GetStringSelection())
866
867 def __set_properties(self):
868 self.SetTitle("Add a Watch")
869 #self.SetSize((400, 250))
870 self.radio_box_1.SetSelection(0)
871
872 def __do_layout(self):
873 sizer_1 = wx.BoxSizer(wx.VERTICAL)
874 grid_sizer_4 = wx.FlexGridSizer(1, 3, 5, 5)
875 grid_sizer_2 = wx.FlexGridSizer(1, 2, 5, 5)
876 grid_sizer_2.Add(self.label_2, 0, wx.ALIGN_CENTER_VERTICAL|wx.FIXED_MINSIZE, 0)
877 grid_sizer_2.Add(self._watchNameTextCtrl, 0, wx.EXPAND, 0)
878 grid_sizer_2.AddGrowableCol(1)
879 sizer_1.Add(grid_sizer_2, 1, wx.EXPAND, 0)
880 grid_sizer_4.Add(self.label_3, 0, wx.ALIGN_CENTER_VERTICAL|wx.FIXED_MINSIZE, 0)
881 grid_sizer_4.Add(self._watchValueTextCtrl, 0, wx.EXPAND, 0)
882 grid_sizer_4.AddGrowableCol(1)
883 grid_sizer_4.Add(self.label_4, 0, wx.ALIGN_CENTER_VERTICAL|wx.FIXED_MINSIZE, 0)
884 sizer_1.Add(grid_sizer_4, 0, wx.EXPAND, 0)
885 sizer_1.Add(self.radio_box_1, 0, wx.EXPAND, 0)
886
887 box = wx.BoxSizer(wx.HORIZONTAL)
888 box.Add(self._okButton, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
889 box.Add(self._cancelButton, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
890 sizer_1.Add(box, 1, wx.EXPAND, 0)
891 self.SetAutoLayout(True)
892 self.SetSizer(sizer_1)
893 self.Layout()
894
895 class FramesUI(wx.SplitterWindow):
896 def __init__(self, parent, id, ui):
897 wx.SplitterWindow.__init__(self, parent, id, style = wx.SP_3D)
898 self._ui = ui
899 sizer = wx.BoxSizer(wx.VERTICAL)
900 self._p1 = p1 = wx.ScrolledWindow(self, -1)
901 p1.Bind(wx.EVT_SIZE, self.OnSize)
902
903 self._framesListCtrl = wx.ListCtrl(p1, -1, pos=wx.DefaultPosition, size=(250,150), style=wx.LC_REPORT)
904 sizer.Add(self._framesListCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
905 self._framesListCtrl.InsertColumn(0, "Frame")
906 self._framesListCtrl.SetColumnWidth(0, 250)
907 self._framesListCtrl.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnListRightClick)
908 self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.ListItemSelected, self._framesListCtrl)
909 self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.ListItemDeselected, self._framesListCtrl)
910
911 sizer2 = wx.BoxSizer(wx.VERTICAL)
912 self._p2 = p2 = wx.ScrolledWindow(self, -1)
913 p2.Bind(wx.EVT_SIZE, self.OnSize)
914
915 self._treeCtrl = wx.gizmos.TreeListCtrl(p2, -1, size=(530,250), style=wx.TR_DEFAULT_STYLE| wx.TR_FULL_ROW_HIGHLIGHT)
916 self._treeCtrl.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnRightClick)
917 sizer2.Add(self._framesListCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
918 tree = self._treeCtrl
919 tree.AddColumn("Thing")
920 tree.AddColumn("Value")
921 tree.SetMainColumn(0) # the one with the tree in it...
922 tree.SetColumnWidth(0, 175)
923 tree.SetColumnWidth(1, 355)
924 self._root = tree.AddRoot("Frame")
925 tree.SetItemText(self._root, "", 1)
926
927 self.SetMinimumPaneSize(20)
928 self.SplitVertically(p1, p2, 250)
929 self.currentItem = None
930 self.Layout()
931
932 def OnRightClick(self, event):
933 #Refactor this...
934 self._introspectItem = event.GetItem()
935 self._parentChain = self.GetItemChain(event.GetItem())
936 watchOnly = len(self._parentChain) < 1
937 if not _WATCHES_ON and watchOnly:
938 return
939 menu = wx.Menu()
940 if not watchOnly:
941 if not hasattr(self, "introspectID"):
942 self.introspectID = wx.NewId()
943 self.Bind(wx.EVT_MENU, self.OnIntrospect, id=self.introspectID)
944 item = wx.MenuItem(menu, self.introspectID, "Attempt Introspection")
945 menu.AppendItem(item)
946 menu.AppendSeparator()
947 if _WATCHES_ON:
948 if not hasattr(self, "watchID"):
949 self.watchID = wx.NewId()
950 self.Bind(wx.EVT_MENU, self.OnWatch, id=self.watchID)
951 item = wx.MenuItem(menu, self.watchID, "Create a Watch")
952 menu.AppendItem(item)
953 menu.AppendSeparator()
954 if not watchOnly:
955 if not hasattr(self, "viewID"):
956 self.viewID = wx.NewId()
957 self.Bind(wx.EVT_MENU, self.OnView, id=self.viewID)
958 item = wx.MenuItem(menu, self.viewID, "View in Dialog")
959 menu.AppendItem(item)
960 offset = wx.Point(x=0, y=20)
961 menuSpot = event.GetPoint() + offset
962 self._treeCtrl.PopupMenu(menu, menuSpot)
963 menu.Destroy()
964 self._parentChain = None
965 self._introspectItem = None
966
967 def GetItemChain(self, item):
968 parentChain = []
969 if item:
970 if _VERBOSE: print 'Exploding: %s' % self._treeCtrl.GetItemText(item, 0)
971 while item != self._root:
972 text = self._treeCtrl.GetItemText(item, 0)
973 if _VERBOSE: print "Appending ", text
974 parentChain.append(text)
975 item = self._treeCtrl.GetItemParent(item)
976 parentChain.reverse()
977 return parentChain
978
979 def OnView(self, event):
980 title = self._treeCtrl.GetItemText(self._introspectItem,0)
981 value = self._treeCtrl.GetItemText(self._introspectItem,1)
982 dlg = wx.lib.dialogs.ScrolledMessageDialog(self, value, title, style=wx.DD_DEFAULT_STYLE | wx.RESIZE_BORDER)
983 dlg.Show()
984
985 def OnWatch(self, event):
986 try:
987 if hasattr(self, '_parentChain'):
988 wd = WatchDialog(wx.GetApp().GetTopWindow(), "Add a Watch", self._parentChain)
989 else:
990 wd = WatchDialog(wx.GetApp().GetTopWindow(), "Add a Watch", None)
991 if wd.ShowModal() == wx.ID_OK:
992 name, text, send_frame, run_once = wd.GetSettings()
993 if send_frame:
994 frameNode = self._stack[int(self.currentItem)]
995 message = frameNode.getAttribute("message")
996 else:
997 message = ""
998 binType = self._ui._callback._debuggerServer.add_watch(name, text, message, run_once)
999 xmldoc = bz2.decompress(binType.data)
1000 domDoc = parseString(xmldoc)
1001 nodeList = domDoc.getElementsByTagName('watch')
1002 if len(nodeList) == 1:
1003 watchValue = nodeList.item(0).getAttribute("message")
1004 except:
1005 tp, val, tb = sys.exc_info()
1006 traceback.print_exception(tp, val, tb)
1007
1008 def OnIntrospect(self, event):
1009 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
1010
1011 try:
1012 list = self._framesListCtrl
1013 frameNode = self._stack[int(self.currentItem)]
1014 message = frameNode.getAttribute("message")
1015 binType = self._ui._callback._debuggerServer.attempt_introspection(message, self._parentChain)
1016 xmldoc = bz2.decompress(binType.data)
1017
1018 domDoc = parseString(xmldoc)
1019 nodeList = domDoc.getElementsByTagName('replacement')
1020 replacementNode = nodeList.item(0)
1021 if len(replacementNode.childNodes):
1022 thingToWalk = replacementNode.childNodes.item(0)
1023 tree = self._treeCtrl
1024 parent = tree.GetItemParent(self._introspectItem)
1025 treeNode = self.AppendSubTreeFromNode(thingToWalk, thingToWalk.getAttribute('name'), parent, insertBefore=self._introspectItem)
1026 tree.Delete(self._introspectItem)
1027 except:
1028 tp,val,tb = sys.exc_info()
1029 traceback.print_exception(tp, val, tb)
1030
1031 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
1032
1033 def OnSize(self, event):
1034 self._treeCtrl.SetSize(self._p2.GetSize())
1035 w,h = self._p1.GetClientSizeTuple()
1036 self._framesListCtrl.SetDimensions(0, 0, w, h)
1037
1038 def ClearWhileRunning(self):
1039 list = self._framesListCtrl
1040 list.DeleteAllItems()
1041 tree = self._treeCtrl
1042 tree.Hide()
1043
1044 def OnListRightClick(self, event):
1045 if not hasattr(self, "syncFrameID"):
1046 self.syncFrameID = wx.NewId()
1047 self.Bind(wx.EVT_MENU, self.OnSyncFrame, id=self.syncFrameID)
1048 menu = wx.Menu()
1049 item = wx.MenuItem(menu, self.syncFrameID, "Goto Source Line")
1050 menu.AppendItem(item)
1051 self.PopupMenu(menu, event.GetPosition())
1052 menu.Destroy()
1053
1054 def OnSyncFrame(self, event):
1055 list = self._framesListCtrl
1056 frameNode = self._stack[int(self.currentItem)]
1057 file = frameNode.getAttribute("file")
1058 line = frameNode.getAttribute("line")
1059 self._ui.SynchCurrentLine( file, int(line) )
1060
1061 def LoadFramesListXML(self, framesXML):
1062 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
1063 try:
1064 domDoc = parseString(framesXML)
1065 list = self._framesListCtrl
1066 list.DeleteAllItems()
1067 self._stack = []
1068 nodeList = domDoc.getElementsByTagName('frame')
1069 frame_count = -1
1070 for index in range(0, nodeList.length):
1071 frameNode = nodeList.item(index)
1072 message = frameNode.getAttribute("message")
1073 list.InsertStringItem(index, message)
1074 self._stack.append(frameNode)
1075 frame_count += 1
1076 list.Select(frame_count)
1077 self._p1.FitInside()
1078 frameNode = nodeList.item(index)
1079 file = frameNode.getAttribute("file")
1080 line = frameNode.getAttribute("line")
1081 self._ui.SynchCurrentLine( file, int(line) )
1082 except:
1083 tp,val,tb=sys.exc_info()
1084 traceback.print_exception(tp, val, tb)
1085
1086 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
1087
1088 def ListItemDeselected(self, event):
1089 pass
1090
1091 def ListItemSelected(self, event):
1092 self.currentItem = event.m_itemIndex
1093 frameNode = self._stack[int(self.currentItem)]
1094 self.PopulateTreeFromFrameNode(frameNode)
1095 # Temporarily doing this to test out automatically swicting to source line.
1096 self.OnSyncFrame(None)
1097
1098 def PopulateTreeFromFrameNode(self, frameNode):
1099 tree = self._treeCtrl
1100 tree.Show(True)
1101 root = self._root
1102 tree.DeleteChildren(root)
1103 children = frameNode.childNodes
1104 firstChild = None
1105 for index in range(0, children.length):
1106 subNode = children.item(index)
1107 treeNode = self.AppendSubTreeFromNode(subNode, subNode.getAttribute('name'), root)
1108 if not firstChild:
1109 firstChild = treeNode
1110 tree.Expand(root)
1111 tree.Expand(firstChild)
1112 self._p2.FitInside()
1113
1114 def AppendSubTreeFromNode(self, node, name, parent, insertBefore=None):
1115 tree = self._treeCtrl
1116 if insertBefore != None:
1117 treeNode = tree.InsertItem(parent, insertBefore, name)
1118 else:
1119 treeNode = tree.AppendItem(parent, name)
1120 children = node.childNodes
1121 if children.length == 0:
1122 tree.SetItemText(treeNode, self.StripOuterSingleQuotes(node.getAttribute("value")), 1)
1123 for index in range(0, children.length):
1124 subNode = children.item(index)
1125 if self.HasChildren(subNode):
1126 self.AppendSubTreeFromNode(subNode, subNode.getAttribute("name"), treeNode)
1127 else:
1128 name = subNode.getAttribute("name")
1129 value = self.StripOuterSingleQuotes(subNode.getAttribute("value"))
1130 n = tree.AppendItem(treeNode, name)
1131 tree.SetItemText(n, value, 1)
1132 return treeNode
1133
1134 def StripOuterSingleQuotes(self, string):
1135 if string.startswith("'") and string.endswith("'"):
1136 return string[1:-1]
1137 elif type(string) == types.UnicodeType:
1138 return string[1:-1]
1139 else:
1140 return string
1141
1142 def HasChildren(self, node):
1143 try:
1144 return node.childNodes.length > 0
1145 except:
1146 tp,val,tb=sys.exc_info()
1147 return False
1148
1149 class DebuggerView(Service.ServiceView):
1150
1151 #----------------------------------------------------------------------------
1152 # Overridden methods
1153 #----------------------------------------------------------------------------
1154
1155 def __init__(self, service):
1156 Service.ServiceView.__init__(self, service)
1157
1158 def _CreateControl(self, parent, id):
1159 return None
1160
1161 #------------------------------------------------------------------------------
1162 # Event handling
1163 #-----------------------------------------------------------------------------
1164
1165 def OnToolClicked(self, event):
1166 self.GetFrame().ProcessEvent(event)
1167
1168 #------------------------------------------------------------------------------
1169 # Class methods
1170 #-----------------------------------------------------------------------------
1171
1172 class Interaction:
1173 def __init__(self, message, framesXML, info=None, quit=False):
1174 self._framesXML = framesXML
1175 self._message = message
1176 self._info = info
1177 self._quit = quit
1178
1179 def getFramesXML(self):
1180 return self._framesXML
1181
1182 def getMessage(self):
1183 return self._message
1184
1185 def getInfo(self):
1186 return self._info
1187
1188 def getQuit(self):
1189 return self._quit
1190
1191 class AGXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):
1192 def __init__(self, address, logRequests=0):
1193 SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self, address, logRequests=logRequests)
1194
1195 class RequestHandlerThread(threading.Thread):
1196 def __init__(self, queue, address):
1197 threading.Thread.__init__(self)
1198 self._keepGoing = True
1199 self._queue = queue
1200 self._address = address
1201 self._server = AGXMLRPCServer(self._address,logRequests=0)
1202 self._server.register_function(self.interaction)
1203 self._server.register_function(self.quit)
1204 self._server.register_function(self.dummyOperation)
1205 if _VERBOSE: print "RequestHandlerThread on fileno %s" % str(self._server.fileno())
1206
1207 def run(self):
1208 while self._keepGoing:
1209 try:
1210 self._server.handle_request()
1211 except:
1212 tp, val, tb = sys.exc_info()
1213 traceback.print_exception(tp, val, tb)
1214 self._keepGoing = False
1215 if _VERBOSE: print "Exiting Request Handler Thread."
1216
1217 def interaction(self, message, frameXML, info):
1218 if _VERBOSE: print "In RequestHandlerThread.interaction -- adding to queue"
1219 interaction = Interaction(message, frameXML, info)
1220 self._queue.put(interaction)
1221 return ""
1222
1223 def quit(self):
1224 interaction = Interaction(None, None, info=None, quit=True)
1225 self._queue.put(interaction)
1226 return ""
1227
1228 def dummyOperation(self):
1229 return ""
1230
1231 def AskToStop(self):
1232 self._keepGoing = False
1233 if type(self._server) is not types.NoneType:
1234 try:
1235 # This is a really ugly way to make sure this thread isn't blocked in
1236 # handle_request.
1237 url = 'http://' + self._address[0] + ':' + str(self._address[1]) + '/'
1238 tempServer = xmlrpclib.ServerProxy(url, allow_none=1)
1239 tempServer.dummyOperation()
1240 except:
1241 tp, val, tb = sys.exc_info()
1242 traceback.print_exception(tp, val, tb)
1243 self._server.server_close()
1244
1245
1246 class RequestBreakThread(threading.Thread):
1247 def __init__(self, server, interrupt=False, pushBreakpoints=False, breakDict=None, kill=False):
1248 threading.Thread.__init__(self)
1249 self._server = server
1250
1251 self._interrupt = interrupt
1252 self._pushBreakpoints = pushBreakpoints
1253 self._breakDict = breakDict
1254 self._kill = kill
1255
1256 def run(self):
1257 try:
1258 if _VERBOSE: print "RequestBreakThread, before call"
1259 if self._interrupt:
1260 self._server.break_requested()
1261 if self._pushBreakpoints:
1262 self._server.update_breakpoints(xmlrpclib.Binary(pickle.dumps(self._breakDict)))
1263 if self._kill:
1264 try:
1265 self._server.die()
1266 except:
1267 pass
1268 if _VERBOSE: print "RequestBreakThread, after call"
1269 except:
1270 tp,val,tb = sys.exc_info()
1271 traceback.print_exception(tp, val, tb)
1272
1273 class DebuggerOperationThread(threading.Thread):
1274 def __init__(self, function):
1275 threading.Thread.__init__(self)
1276 self._function = function
1277
1278 def run(self):
1279 if _VERBOSE: print "In DOT, before call"
1280 try:
1281 self._function()
1282 except:
1283 tp,val,tb = sys.exc_info()
1284 traceback.print_exception(tp, val, tb)
1285 if _VERBOSE: print "In DOT, after call"
1286
1287 class DebuggerCallback:
1288
1289 def __init__(self, host, port, debugger_url, break_url, debuggerUI):
1290 if _VERBOSE: print "+++++++ Creating server on port, ", str(port)
1291
1292 self._queue = Queue.Queue(50)
1293 self._host = host
1294 self._port = int(port)
1295 threading._VERBOSE = _VERBOSE
1296 self._serverHandlerThread = RequestHandlerThread(self._queue, (self._host, self._port))
1297
1298 self._debugger_url = debugger_url
1299 self._debuggerServer = None
1300 self._waiting = False
1301 self._service = wx.GetApp().GetService(DebuggerService)
1302 self._debuggerUI = debuggerUI
1303 self._break_url = break_url
1304 self._breakServer = None
1305 self._firstInteraction = True
1306 self._pendingBreak = False
1307
1308 def start(self):
1309 self._serverHandlerThread.start()
1310
1311 def ServerClose(self):
1312 rbt = RequestBreakThread(self._breakServer, kill=True)
1313 rbt.start()
1314 self.setWaiting(False)
1315 if self._serverHandlerThread:
1316 self._serverHandlerThread.AskToStop()
1317 self._serverHandlerThread = None
1318
1319 def BreakExecution(self):
1320 rbt = RequestBreakThread(self._breakServer, interrupt=True)
1321 rbt.start()
1322
1323 def SingleStep(self):
1324 self._debuggerUI.DisableWhileDebuggerRunning()
1325 #dot = DebuggerOperationThread(self._debuggerServer.set_step)
1326 #dot.start()
1327 self._debuggerServer.set_step() # Figure out where to set allowNone
1328 self.waitForRPC()
1329
1330 def Next(self):
1331 self._debuggerUI.DisableWhileDebuggerRunning()
1332 #dot = DebuggerOperationThread(self._debuggerServer.set_next)
1333 #dot.start()
1334 self._debuggerServer.set_next()
1335 self.waitForRPC()
1336
1337 def Continue(self):
1338 self._debuggerUI.DisableWhileDebuggerRunning()
1339 #dot = DebuggerOperationThread(self._debuggerServer.set_continue)
1340 #dot.start()
1341 self._debuggerServer.set_continue()
1342 self.waitForRPC()
1343
1344 def Return(self):
1345 self._debuggerUI.DisableWhileDebuggerRunning()
1346 #dot = DebuggerOperationThread(self._debuggerServer.set_return)
1347 #dot.start()
1348 self._debuggerServer.set_return()
1349 self.waitForRPC()
1350
1351 def setWaiting(self, value):
1352 self._waiting = value
1353
1354 def getWaiting(self):
1355 return self._waiting
1356
1357 def readQueue(self):
1358 if self._queue.qsize():
1359 try:
1360 item = self._queue.get_nowait()
1361 if item.getQuit():
1362 self.interaction(None, None, None, True)
1363 else:
1364 data = bz2.decompress(item.getFramesXML().data)
1365 self.interaction(item.getMessage().data, data, item.getInfo(), False)
1366 except Queue.Empty:
1367 pass
1368
1369 def pushBreakpoints(self):
1370 rbt = RequestBreakThread(self._breakServer, pushBreakpoints=True, breakDict=self._service.GetMasterBreakpointDict())
1371 rbt.start()
1372
1373
1374 def waitForRPC(self):
1375 self.setWaiting(True)
1376 while self.getWaiting():
1377 try:
1378 self.readQueue()
1379 import time
1380 time.sleep(0.02)
1381 except:
1382 tp, val, tb = sys.exc_info()
1383 traceback.print_exception(tp, val, tb)
1384 wx.GetApp().Yield(True)
1385 if _VERBOSE: print "Exiting waitForRPC."
1386
1387 def interaction(self, message, frameXML, info, quit):
1388
1389 #This method should be hit as the debugger starts.
1390 if self._firstInteraction:
1391 self._firstInteraction = False
1392 self._debuggerServer = xmlrpclib.ServerProxy(self._debugger_url, allow_none=1)
1393 self._breakServer = xmlrpclib.ServerProxy(self._break_url, allow_none=1)
1394 self.pushBreakpoints()
1395 self.setWaiting(False)
1396 if _VERBOSE: print "+"*40
1397 if(quit):
1398 self._debuggerUI.StopExecution(None)
1399 return ""
1400 if(info != ""):
1401 if _VERBOSE: print "Hit interaction with exception"
1402 #self._debuggerUI.StopExecution(None)
1403 #self._debuggerUI.SetStatusText("Got exception: " + str(info))
1404 self._debuggerUI.SwitchToOutputTab()
1405 else:
1406 if _VERBOSE: print "Hit interaction no exception"
1407 self._debuggerUI.SetStatusText(message)
1408 self._debuggerUI.LoadFramesListXML(frameXML)
1409 self._debuggerUI.EnableWhileDebuggerStopped()
1410 if _VERBOSE: print "+"*40
1411
1412 class DebuggerService(Service.Service):
1413
1414 #----------------------------------------------------------------------------
1415 # Constants
1416 #----------------------------------------------------------------------------
1417 TOGGLE_BREAKPOINT_ID = wx.NewId()
1418 CLEAR_ALL_BREAKPOINTS = wx.NewId()
1419 RUN_ID = wx.NewId()
1420 DEBUG_ID = wx.NewId()
1421
1422 def ComparePaths(first, second):
1423 one = DebuggerService.ExpandPath(first)
1424 two = DebuggerService.ExpandPath(second)
1425 if _WINDOWS:
1426 return one.lower() == two.lower()
1427 else:
1428 return one == two
1429 ComparePaths = staticmethod(ComparePaths)
1430
1431 # Make sure we're using an expanded path on windows.
1432 def ExpandPath(path):
1433 if _WINDOWS:
1434 try:
1435 return win32api.GetLongPathName(path)
1436 except:
1437 print "Cannot get long path for %s" % path
1438
1439 return path
1440
1441 ExpandPath = staticmethod(ExpandPath)
1442
1443 #----------------------------------------------------------------------------
1444 # Overridden methods
1445 #----------------------------------------------------------------------------
1446
1447 def __init__(self, serviceName, embeddedWindowLocation = wx.lib.pydocview.EMBEDDED_WINDOW_LEFT):
1448 Service.Service.__init__(self, serviceName, embeddedWindowLocation)
1449 self.BREAKPOINT_DICT_STRING = "MasterBreakpointDict"
1450 config = wx.ConfigBase_Get()
1451 pickledbps = config.Read(self.BREAKPOINT_DICT_STRING)
1452 if pickledbps:
1453 try:
1454 self._masterBPDict = pickle.loads(pickledbps.encode('ascii'))
1455 except:
1456 tp, val, tb = sys.exc_info()
1457 traceback.print_exception(tp,val,tb)
1458 self._masterBPDict = {}
1459 else:
1460 self._masterBPDict = {}
1461
1462 def OnCloseFrame(self, event):
1463 # IS THIS THE RIGHT PLACE?
1464 try:
1465 config = wx.ConfigBase_Get()
1466 config.Write(self.BREAKPOINT_DICT_STRING, pickle.dumps(self._masterBPDict))
1467 except:
1468 tp,val,tb = sys.exc_info()
1469 traceback.print_exception(tp, val, tb)
1470 return True
1471
1472 def _CreateView(self):
1473 return DebuggerView(self)
1474
1475
1476 #----------------------------------------------------------------------------
1477 # Service specific methods
1478 #----------------------------------------------------------------------------
1479
1480 def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
1481 #Service.Service.InstallControls(self, frame, menuBar, toolBar, statusBar, document)
1482
1483 config = wx.ConfigBase_Get()
1484
1485 debuggerMenu = wx.Menu()
1486 if not menuBar.FindItemById(DebuggerService.CLEAR_ALL_BREAKPOINTS):
1487
1488 debuggerMenu.Append(DebuggerService.RUN_ID, _("&Run...\tCtrl+R"), _("Runs a file"))
1489 wx.EVT_MENU(frame, DebuggerService.RUN_ID, frame.ProcessEvent)
1490 wx.EVT_UPDATE_UI(frame, DebuggerService.RUN_ID, frame.ProcessUpdateUIEvent)
1491
1492 debuggerMenu.Append(DebuggerService.DEBUG_ID, _("&Debug...\tCtrl+D"), _("Debugs a file"))
1493 wx.EVT_MENU(frame, DebuggerService.DEBUG_ID, frame.ProcessEvent)
1494 wx.EVT_UPDATE_UI(frame, DebuggerService.DEBUG_ID, frame.ProcessUpdateUIEvent)
1495
1496 debuggerMenu.AppendSeparator()
1497
1498 debuggerMenu.Append(DebuggerService.TOGGLE_BREAKPOINT_ID, _("&Toggle Breakpoint...\tCtrl+B"), _("Toggle a breakpoint"))
1499 wx.EVT_MENU(frame, DebuggerService.TOGGLE_BREAKPOINT_ID, self.ProcessEvent)
1500 wx.EVT_UPDATE_UI(frame, DebuggerService.TOGGLE_BREAKPOINT_ID, self.ProcessUpdateUIEvent)
1501
1502 debuggerMenu.Append(DebuggerService.CLEAR_ALL_BREAKPOINTS, _("&Clear All Breakpoints"), _("Clear All Breakpoints"))
1503 wx.EVT_MENU(frame, DebuggerService.CLEAR_ALL_BREAKPOINTS, self.ProcessEvent)
1504 wx.EVT_UPDATE_UI(frame, DebuggerService.CLEAR_ALL_BREAKPOINTS, self.ProcessUpdateUIEvent)
1505
1506
1507 viewMenuIndex = menuBar.FindMenu(_("&Project"))
1508 menuBar.Insert(viewMenuIndex + 1, debuggerMenu, _("&Run"))
1509
1510 return True
1511
1512
1513
1514 #----------------------------------------------------------------------------
1515 # Event Processing Methods
1516 #----------------------------------------------------------------------------
1517
1518 def ProcessEventBeforeWindows(self, event):
1519 return False
1520
1521
1522 def ProcessEvent(self, event):
1523 if Service.Service.ProcessEvent(self, event):
1524 return True
1525
1526 an_id = event.GetId()
1527 if an_id == DebuggerService.TOGGLE_BREAKPOINT_ID:
1528 self.OnToggleBreakpoint(event)
1529 return True
1530 elif an_id == DebuggerService.CLEAR_ALL_BREAKPOINTS:
1531 self.ClearAllBreakpoints()
1532 return True
1533 elif an_id == DebuggerService.RUN_ID:
1534 self.OnRunProject(event)
1535 return True
1536 elif an_id == DebuggerService.DEBUG_ID:
1537 self.OnDebugProject(event)
1538 return True
1539 return False
1540
1541 def ProcessUpdateUIEvent(self, event):
1542 if Service.Service.ProcessUpdateUIEvent(self, event):
1543 return True
1544
1545 an_id = event.GetId()
1546 if an_id == DebuggerService.TOGGLE_BREAKPOINT_ID:
1547 currentView = self.GetDocumentManager().GetCurrentView()
1548 event.Enable(isinstance(currentView, PythonEditor.PythonView))
1549 return True
1550 elif an_id == DebuggerService.CLEAR_ALL_BREAKPOINTS:
1551 event.Enable(self.HasBreakpointsSet())
1552 return True
1553 elif an_id == DebuggerService.RUN_ID:
1554 event.Enable(self.HasAnyFiles())
1555 return True
1556 elif an_id == DebuggerService.DEBUG_ID:
1557 event.Enable(self.HasAnyFiles())
1558 return True
1559 else:
1560 return False
1561
1562 #----------------------------------------------------------------------------
1563 # Class Methods
1564 #----------------------------------------------------------------------------
1565
1566 def OnDebugProject(self, event):
1567 if not Executor.GetPythonExecutablePath():
1568 return
1569 if DebugCommandUI.DebuggerRunning():
1570 wx.MessageBox(_("A debugger is already running. Please shut down the other debugger first."), _("Debugger Running"))
1571 return
1572 self.ShowWindow(True)
1573 projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
1574 project = projectService.GetView().GetDocument()
1575 dlg = CommandPropertiesDialog(self.GetView().GetFrame(), 'Debug Python File', projectService, None, pythonOnly=True, okButtonName="Debug", debugging=True)
1576 if dlg.ShowModal() == wx.ID_OK:
1577 fileToDebug, initialArgs, startIn, isPython, environment = dlg.GetSettings()
1578 dlg.Destroy()
1579 else:
1580 dlg.Destroy()
1581 return
1582 self.PromptToSaveFiles()
1583
1584 shortFile = os.path.basename(fileToDebug)
1585 fileToDebug = DebuggerService.ExpandPath(fileToDebug)
1586 try:
1587 page = DebugCommandUI(Service.ServiceView.bottomTab, -1, str(fileToDebug), self)
1588 count = Service.ServiceView.bottomTab.GetPageCount()
1589 Service.ServiceView.bottomTab.AddPage(page, "Debugging: " + shortFile)
1590 Service.ServiceView.bottomTab.SetSelection(count)
1591 page.Execute(initialArgs, startIn, environment)
1592 except:
1593 pass
1594
1595 def HasAnyFiles(self):
1596 docs = wx.GetApp().GetDocumentManager().GetDocuments()
1597 return len(docs) > 0
1598
1599 def PromptToSaveFiles(self, running=True):
1600 filesModified = False
1601 docs = wx.GetApp().GetDocumentManager().GetDocuments()
1602 for doc in docs:
1603 if doc.IsModified():
1604 filesModified = True
1605 break
1606 if filesModified:
1607 frame = self.GetView().GetFrame()
1608 if running:
1609 yesNoMsg = wx.MessageDialog(frame,
1610 _("Files have been modified.\nWould you like to save all files before running?"),
1611 _("Run"),
1612 wx.YES_NO
1613 )
1614 else:
1615 yesNoMsg = wx.MessageDialog(frame,
1616 _("Files have been modified.\nWould you like to save all files before debugging?"),
1617 _("Debug"),
1618 wx.YES_NO
1619 )
1620 if yesNoMsg.ShowModal() == wx.ID_YES:
1621 docs = wx.GetApp().GetDocumentManager().GetDocuments()
1622 for doc in docs:
1623 doc.Save()
1624
1625 def OnExit(self):
1626 DebugCommandUI.ShutdownAllDebuggers()
1627
1628 def OnRunProject(self, event):
1629 if not Executor.GetPythonExecutablePath():
1630 return
1631 projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
1632 project = projectService.GetView().GetDocument()
1633 dlg = CommandPropertiesDialog(self.GetView().GetFrame(), 'Run', projectService, None)
1634 if dlg.ShowModal() == wx.ID_OK:
1635 fileToRun, initialArgs, startIn, isPython, environment = dlg.GetSettings()
1636
1637
1638 dlg.Destroy()
1639 else:
1640 dlg.Destroy()
1641 return
1642 self.PromptToSaveFiles()
1643 # This will need to change when we can run more than .py and .bpel files.
1644 if not isPython:
1645 projectService.RunProcessModel(fileToRun)
1646 return
1647
1648 self.ShowWindow(True)
1649 shortFile = os.path.basename(fileToRun)
1650 page = RunCommandUI(Service.ServiceView.bottomTab, -1, str(fileToRun))
1651 count = Service.ServiceView.bottomTab.GetPageCount()
1652 Service.ServiceView.bottomTab.AddPage(page, "Running: " + shortFile)
1653 Service.ServiceView.bottomTab.SetSelection(count)
1654 page.Execute(initialArgs, startIn, environment)
1655
1656 def OnToggleBreakpoint(self, event, line=-1, fileName=None):
1657 if not fileName:
1658 view = wx.GetApp().GetDocumentManager().GetCurrentView()
1659 # Test to make sure we aren't the project view.
1660 if not hasattr(view, 'MarkerExists'):
1661 return
1662 fileName = wx.GetApp().GetDocumentManager().GetCurrentDocument().GetFilename()
1663 if line < 0:
1664 line = view.GetCtrl().GetCurrentLine()
1665 if self.BreakpointSet(fileName, line + 1):
1666 self.ClearBreak(fileName, line + 1)
1667 else:
1668 self.SetBreak(fileName, line + 1)
1669 # Now refresh all the markers icons in all the open views.
1670 self.ClearAllBreakpointMarkers()
1671 self.SetAllBreakpointMarkers()
1672
1673 def SilentToggleBreakpoint(self, fileName, line):
1674 found = False
1675 for lineNumber in self.GetBreakpointList(fileName):
1676 if int(lineNumber) == int(line):
1677 found = True
1678 break
1679 if found:
1680 self.SetBreak(fileName, line)
1681 else:
1682 self.ClearBreak(fileName, line)
1683
1684 def SetBreak(self, fileName, line):
1685 expandedName = DebuggerService.ExpandPath(fileName)
1686 if not self._masterBPDict.has_key(expandedName):
1687 self._masterBPDict[expandedName] = [line]
1688 else:
1689 self._masterBPDict[expandedName] += [line]
1690 # If we're already debugging, pass this bp off to the DebuggerCallback
1691 self.NotifyDebuggersOfBreakpointChange()
1692
1693 def NotifyDebuggersOfBreakpointChange(self):
1694 DebugCommandUI.NotifyDebuggersOfBreakpointChange()
1695
1696 def GetBreakpointList(self, fileName):
1697 expandedName = DebuggerService.ExpandPath(fileName)
1698 if not self._masterBPDict.has_key(expandedName):
1699 return []
1700 else:
1701 return self._masterBPDict[expandedName]
1702
1703 def BreakpointSet(self, fileName, line):
1704 expandedName = DebuggerService.ExpandPath(fileName)
1705 if not self._masterBPDict.has_key(expandedName):
1706 return False
1707 else:
1708 newList = []
1709 for number in self._masterBPDict[expandedName]:
1710 if(int(number) == int(line)):
1711 return True
1712 return False
1713
1714 def ClearBreak(self, fileName, line):
1715 expandedName = DebuggerService.ExpandPath(fileName)
1716 if not self._masterBPDict.has_key(expandedName):
1717 print "In ClearBreak: no key"
1718 return
1719 else:
1720 newList = []
1721 for number in self._masterBPDict[expandedName]:
1722 if(int(number) != int(line)):
1723 newList.append(number)
1724 self._masterBPDict[expandedName] = newList
1725 self.NotifyDebuggersOfBreakpointChange()
1726
1727 def HasBreakpointsSet(self):
1728 for key, value in self._masterBPDict.items():
1729 if len(value) > 0:
1730 return True
1731 return False
1732
1733 def ClearAllBreakpoints(self):
1734 self._masterBPDict = {}
1735 self.NotifyDebuggersOfBreakpointChange()
1736 self.ClearAllBreakpointMarkers()
1737
1738 def ClearAllBreakpointMarkers(self):
1739 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
1740 for openDoc in openDocs:
1741 if(isinstance(openDoc.GetFirstView(), CodeEditor.CodeView)):
1742 openDoc.GetFirstView().MarkerDeleteAll(CodeEditor.CodeCtrl.BREAKPOINT_MARKER_NUM)
1743
1744 def GetMasterBreakpointDict(self):
1745 return self._masterBPDict
1746
1747 def SetAllBreakpointMarkers(self):
1748 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
1749 for openDoc in openDocs:
1750 if(isinstance(openDoc.GetFirstView(), CodeEditor.CodeView)):
1751 self.SetCurrentBreakpointMarkers(openDoc.GetFirstView())
1752
1753 def SetCurrentBreakpointMarkers(self, view):
1754 if isinstance(view, CodeEditor.CodeView) and hasattr(view, 'GetDocument'):
1755 view.MarkerDeleteAll(CodeEditor.CodeCtrl.BREAKPOINT_MARKER_NUM)
1756 for linenum in self.GetBreakpointList(view.GetDocument().GetFilename()):
1757 view.MarkerAdd(lineNum=int(linenum) - 1, marker_index=CodeEditor.CodeCtrl.BREAKPOINT_MARKER_NUM)
1758
1759 class DebuggerOptionsPanel(wx.Panel):
1760
1761
1762 def __init__(self, parent, id):
1763 wx.Panel.__init__(self, parent, id)
1764 SPACE = 10
1765 config = wx.ConfigBase_Get()
1766 localHostStaticText = wx.StaticText(self, -1, _("Local Host Name:"))
1767 self._LocalHostTextCtrl = wx.TextCtrl(self, -1, config.Read("DebuggerHostName", DEFAULT_HOST), size = (150, -1))
1768 portNumberStaticText = wx.StaticText(self, -1, _("Port Range:"))
1769 dashStaticText = wx.StaticText(self, -1, _("through to"))
1770 startingPort=config.ReadInt("DebuggerStartingPort", DEFAULT_PORT)
1771 self._PortNumberTextCtrl = wx.lib.intctrl.IntCtrl(self, -1, startingPort, size = (50, -1))
1772 self._PortNumberTextCtrl.SetMin(1)#What are real values?
1773 self._PortNumberTextCtrl.SetMax(65514) #What are real values?
1774 self.Bind(wx.lib.intctrl.EVT_INT, self.MinPortChange, self._PortNumberTextCtrl)
1775
1776 self._EndPortNumberTextCtrl = wx.lib.intctrl.IntCtrl(self, -1, startingPort + PORT_COUNT, size = (50, -1))
1777 self._EndPortNumberTextCtrl.SetMin(22)#What are real values?
1778 self._EndPortNumberTextCtrl.SetMax(65535)#What are real values?
1779 self._EndPortNumberTextCtrl.Enable( False )
1780 debuggerPanelBorderSizer = wx.BoxSizer(wx.VERTICAL)
1781 debuggerPanelSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
1782 debuggerPanelSizer.Add( localHostStaticText, (0,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
1783 debuggerPanelSizer.Add( self._LocalHostTextCtrl, (0,1), (1,3), flag=wx.EXPAND|wx.ALIGN_CENTER)
1784 debuggerPanelSizer.Add( portNumberStaticText, (1,0), flag=wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL)
1785 debuggerPanelSizer.Add( self._PortNumberTextCtrl, (1,1), flag=wx.ALIGN_CENTER)
1786 debuggerPanelSizer.Add( dashStaticText, (1,2), flag=wx.ALIGN_CENTER)
1787 debuggerPanelSizer.Add( self._EndPortNumberTextCtrl, (1,3), flag=wx.ALIGN_CENTER)
1788 FLUSH_PORTS_ID = wx.NewId()
1789 self._flushPortsButton = wx.Button(self, FLUSH_PORTS_ID, "Reset Port List")
1790 wx.EVT_BUTTON(parent, FLUSH_PORTS_ID, self.FlushPorts)
1791 debuggerPanelSizer.Add(self._flushPortsButton, (2,2), (1,2), flag=wx.ALIGN_RIGHT)
1792
1793 debuggerPanelBorderSizer.Add(debuggerPanelSizer, 0, wx.ALL, SPACE)
1794 self.SetSizer(debuggerPanelBorderSizer)
1795 self.Layout()
1796 parent.AddPage(self, _("Debugger"))
1797
1798 def FlushPorts(self, event):
1799 if self._PortNumberTextCtrl.IsInBounds():
1800 config = wx.ConfigBase_Get()
1801 config.WriteInt("DebuggerStartingPort", self._PortNumberTextCtrl.GetValue())
1802 DebugCommandUI.NewPortRange()
1803 else:
1804 wx.MessageBox(_("The starting port is not valid. Please change the value and try again.", "Invalid Starting Port Number"))
1805
1806 def MinPortChange(self, event):
1807 self._EndPortNumberTextCtrl.Enable( True )
1808 self._EndPortNumberTextCtrl.SetValue( self._PortNumberTextCtrl.GetValue() + PORT_COUNT)
1809 self._EndPortNumberTextCtrl.Enable( False )
1810
1811 def OnOK(self, optionsDialog):
1812 config = wx.ConfigBase_Get()
1813 config.Write("DebuggerHostName", self._LocalHostTextCtrl.GetValue())
1814 if self._PortNumberTextCtrl.IsInBounds():
1815 config.WriteInt("DebuggerStartingPort", self._PortNumberTextCtrl.GetValue())
1816
1817 class CommandPropertiesDialog(wx.Dialog):
1818
1819 def __init__(self, parent, title, projectService, currentProjectDocument, pythonOnly=False, okButtonName="Run", debugging=False):
1820 if _WINDOWS:
1821 wx.Dialog.__init__(self, parent, -1, title)
1822 else:
1823 wx.Dialog.__init__(self, parent, -1, title, size=(390,270))
1824 self._projService = projectService
1825 self._pmext = None
1826 self._pyext = None
1827 for template in self._projService.GetDocumentManager().GetTemplates():
1828 if not ACTIVEGRID_BASE_IDE and template.GetDocumentType() == ProcessModelEditor.ProcessModelDocument:
1829 self._pmext = template.GetDefaultExtension()
1830 if template.GetDocumentType() == PythonEditor.PythonDocument:
1831 self._pyext = template.GetDefaultExtension()
1832 self._pythonOnly = pythonOnly
1833
1834 self._currentProj = currentProjectDocument
1835 projStaticText = wx.StaticText(self, -1, _("Project:"))
1836 fileStaticText = wx.StaticText(self, -1, _("File:"))
1837 argsStaticText = wx.StaticText(self, -1, _("Arguments:"))
1838 startInStaticText = wx.StaticText(self, -1, _("Start in:"))
1839 pythonPathStaticText = wx.StaticText(self, -1, _("PYTHONPATH:"))
1840 postpendStaticText = _("Postpend win32api path")
1841 cpPanelBorderSizer = wx.BoxSizer(wx.VERTICAL)
1842 self._projectNameList, self._projectDocumentList, selectedIndex = self.GetProjectList()
1843 self._projList = wx.Choice(self, -1, (200,-1), choices=self._projectNameList)
1844 self.Bind(wx.EVT_CHOICE, self.EvtListBox, self._projList)
1845 HALF_SPACE = 5
1846 flexGridSizer = wx.FlexGridSizer(cols = 3, vgap = 10, hgap = 10)
1847
1848 flexGridSizer.Add(projStaticText, 0, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
1849 flexGridSizer.Add(self._projList, 1, flag=wx.EXPAND)
1850 flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
1851
1852 flexGridSizer.Add(fileStaticText, 0, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
1853 self._fileList = wx.Choice(self, -1, (200,-1))
1854 self.Bind(wx.EVT_CHOICE, self.OnFileSelected, self._fileList)
1855 flexGridSizer.Add(self._fileList, 1, flag=wx.EXPAND)
1856 flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
1857
1858 config = wx.ConfigBase_Get()
1859 self._lastArguments = config.Read("LastRunArguments")
1860 self._argsEntry = wx.TextCtrl(self, -1, str(self._lastArguments))
1861 self._argsEntry.SetToolTipString(str(self._lastArguments))
1862 def TextChanged(event):
1863 self._argsEntry.SetToolTipString(event.GetString())
1864 self.Bind(wx.EVT_TEXT, TextChanged, self._argsEntry)
1865
1866 flexGridSizer.Add(argsStaticText, 0, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
1867 flexGridSizer.Add(self._argsEntry, 1, flag=wx.EXPAND)
1868 flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
1869
1870 flexGridSizer.Add(startInStaticText, 0, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
1871 self._lastStartIn = config.Read("LastRunStartIn")
1872 if not self._lastStartIn:
1873 self._lastStartIn = str(os.getcwd())
1874 self._startEntry = wx.TextCtrl(self, -1, self._lastStartIn)
1875 self._startEntry.SetToolTipString(self._lastStartIn)
1876 def TextChanged2(event):
1877 self._startEntry.SetToolTipString(event.GetString())
1878 self.Bind(wx.EVT_TEXT, TextChanged2, self._startEntry)
1879
1880 flexGridSizer.Add(self._startEntry, 1, wx.EXPAND)
1881 self._findDir = wx.Button(self, -1, _("Browse..."), size=(60,-1))
1882 self.Bind(wx.EVT_BUTTON, self.OnFindDirClick, self._findDir)
1883 flexGridSizer.Add(self._findDir, 0, wx.RIGHT, 10)
1884
1885 flexGridSizer.Add(pythonPathStaticText, 0, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
1886 if os.environ.has_key('PYTHONPATH'):
1887 startval = os.environ['PYTHONPATH']
1888 else:
1889 startval = ""
1890 self._lastPythonPath = config.Read("LastPythonPath", startval)
1891 self._pythonPathEntry = wx.TextCtrl(self, -1, self._lastPythonPath)
1892 self._pythonPathEntry.SetToolTipString(self._lastPythonPath)
1893 flexGridSizer.Add(self._pythonPathEntry, 1, wx.EXPAND)
1894 flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
1895 flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
1896 if debugging:
1897 self._postpendCheckBox = wx.CheckBox(self, -1, postpendStaticText)
1898 checked = bool(config.ReadInt("PythonPathPostpend", 1))
1899 self._postpendCheckBox.SetValue(checked)
1900 flexGridSizer.Add(self._postpendCheckBox, 1, wx.EXPAND)
1901 flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
1902 cpPanelBorderSizer.Add(flexGridSizer, 0, wx.ALL, 10)
1903
1904 box = wx.BoxSizer(wx.HORIZONTAL)
1905 self._okButton = wx.Button(self, wx.ID_OK, okButtonName, size=(75,-1))
1906 self._okButton.SetDefault()
1907 self._okButton.SetHelpText(_("The ") + okButtonName + _(" button completes the dialog"))
1908 box.Add(self._okButton, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
1909 self.Bind(wx.EVT_BUTTON, self.OnOKClick, self._okButton)
1910 btn = wx.Button(self, wx.ID_CANCEL, _("Cancel"), size=(75,-1))
1911 btn.SetHelpText(_("The Cancel button cancels the dialog."))
1912 box.Add(btn, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
1913 cpPanelBorderSizer.Add(box, 0, wx.ALIGN_RIGHT|wx.BOTTOM, 5)
1914
1915 self.SetSizer(cpPanelBorderSizer)
1916 if _WINDOWS:
1917 self.GetSizer().Fit(self)
1918
1919 self.Layout()
1920
1921 # Set up selections based on last values used.
1922 self._fileNameList = None
1923 self._selectedFileIndex = 0
1924 lastProject = config.Read("LastRunProject")
1925 lastFile = config.Read("LastRunFile")
1926
1927 if lastProject in self._projectNameList:
1928 selectedIndex = self._projectNameList.index(lastProject)
1929 elif selectedIndex < 0:
1930 selectedIndex = 0
1931 self._projList.Select(selectedIndex)
1932 self._selectedProjectIndex = selectedIndex
1933 self._selectedProjectDocument = self._projectDocumentList[selectedIndex]
1934 self.PopulateFileList(self._selectedProjectDocument, lastFile)
1935
1936 def OnOKClick(self, event):
1937 startIn = self._startEntry.GetValue()
1938 fileToRun = self._fileList.GetStringSelection()
1939 if not fileToRun:
1940 wx.MessageBox(_("You must select a file to proceed. Note that not all projects have files that can be run or debugged."))
1941 return
1942 isPython = fileToRun.endswith(self._pyext)
1943 if isPython and not os.path.exists(startIn):
1944 wx.MessageBox(_("Starting directory does not exist. Please change this value."))
1945 return
1946 config = wx.ConfigBase_Get()
1947 config.Write("LastRunProject", self._projectNameList[self._selectedProjectIndex])
1948 config.Write("LastRunFile", fileToRun)
1949 # Don't update the arguments or starting directory unless we're runing python.
1950 if isPython:
1951 config.Write("LastRunArguments", self._argsEntry.GetValue())
1952 config.Write("LastRunStartIn", self._startEntry.GetValue())
1953 config.Write("LastPythonPath",self._pythonPathEntry.GetValue())
1954 if hasattr(self, "_postpendCheckBox"):
1955 config.WriteInt("PythonPathPostpend", int(self._postpendCheckBox.GetValue()))
1956
1957 self.EndModal(wx.ID_OK)
1958
1959 def GetSettings(self):
1960 filename = self._fileNameList[self._selectedFileIndex]
1961 args = self._argsEntry.GetValue()
1962 startIn = self._startEntry.GetValue()
1963 isPython = filename.endswith(self._pyext)
1964 env = os.environ
1965 if hasattr(self, "_postpendCheckBox"):
1966 postpend = self._postpendCheckBox.GetValue()
1967 else:
1968 postpend = False
1969 if postpend:
1970 env['PYTHONPATH'] = self._pythonPathEntry.GetValue() + os.pathsep + os.path.join(os.getcwd(), "3rdparty", "pywin32")
1971 else:
1972 env['PYTHONPATH'] = self._pythonPathEntry.GetValue()
1973
1974 return filename, args, startIn, isPython, env
1975
1976 def OnFileSelected(self, event):
1977 self._selectedFileIndex = self._fileList.GetSelection()
1978 self.EnableForFileType(event.GetString())
1979
1980 def EnableForFileType(self, fileName):
1981 show = fileName.endswith(self._pyext)
1982 self._startEntry.Enable(show)
1983 self._findDir.Enable(show)
1984 self._argsEntry.Enable(show)
1985
1986 if not show:
1987 self._lastStartIn = self._startEntry.GetValue()
1988 self._startEntry.SetValue("")
1989 self._lastArguments = self._argsEntry.GetValue()
1990 self._argsEntry.SetValue("")
1991 else:
1992 self._startEntry.SetValue(self._lastStartIn)
1993 self._argsEntry.SetValue(self._lastArguments)
1994
1995
1996
1997 def OnFindDirClick(self, event):
1998 dlg = wx.DirDialog(self, "Choose a starting directory:", self._startEntry.GetValue(),
1999 style=wx.DD_DEFAULT_STYLE|wx.DD_NEW_DIR_BUTTON)
2000
2001 if dlg.ShowModal() == wx.ID_OK:
2002 self._startEntry.SetValue(dlg.GetPath())
2003
2004 dlg.Destroy()
2005
2006 def EvtListBox(self, event):
2007 if event.GetString():
2008 index = self._projectNameList.index(event.GetString())
2009 self._selectedProjectDocument = self._projectDocumentList[index]
2010 self._selectedProjectIndex = index
2011 self.PopulateFileList(self._selectedProjectDocument)
2012
2013 def FilterFileList(self, list):
2014 if self._pythonOnly:
2015 files = filter(lambda f: f.endswith(self._pyext), list)
2016 else:
2017 files = filter(lambda f: (self._pmext and f.endswith(self._pmext)) or f.endswith(self._pyext), list)
2018 return files
2019
2020 def PopulateFileList(self, project, shortNameToSelect=None):
2021 self._fileNameList = self.FilterFileList(project.GetFiles()[:])
2022 self._fileList.Clear()
2023 if not self._fileNameList:
2024 return
2025 self._fileNameList.sort(lambda a, b: cmp(os.path.basename(a).lower(), os.path.basename(b).lower()))
2026 strings = map(lambda file: os.path.basename(file), self._fileNameList)
2027 for index in range(0, len(strings)):
2028 if shortNameToSelect == strings[index]:
2029 self._selectedFileIndex = index
2030 break
2031 self._fileList.Hide()
2032 self._fileList.AppendItems(strings)
2033 self._fileList.Show()
2034 if self._selectedFileIndex not in range(0, len(strings)) : self._selectedFileIndex = 0
2035 self._fileList.SetSelection(self._selectedFileIndex)
2036 self.EnableForFileType(strings[self._selectedFileIndex])
2037
2038 def GetProjectList(self):
2039 docList = []
2040 nameList = []
2041 found = False
2042 index = -1
2043 count = 0
2044 for document in self._projService.GetDocumentManager().GetDocuments():
2045 if document.GetDocumentTemplate().GetDocumentType() == ProjectEditor.ProjectDocument and len(document.GetFiles()):
2046 docList.append(document)
2047 nameList.append(os.path.basename(document.GetFilename()))
2048 if document == self._currentProj:
2049 found = True
2050 index = count
2051 count += 1
2052 return nameList, docList, index
2053 #----------------------------------------------------------------------
2054 from wx import ImageFromStream, BitmapFromImage
2055 from wx import EmptyIcon
2056 import cStringIO
2057 #----------------------------------------------------------------------
2058 def getBreakData():
2059 return \
2060 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x11\x08\x06\
2061 \x00\x00\x00\xd4\xaf,\xc4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2062 \x00\x00\x97IDAT8\x8d\xbdSA\x0e\xc3 \x0c\x8b\x13\xfe=\x1e^\xe2\x1dF\xbb\x8c\
2063 \xd2\x0c\xa9\xda,q\x88\x05\x8e\x1d\x00P\x93;\xd0[\xa7W\x04\xe8\x8d\x0f\xdfxU\
2064 c%\x02\xbd\xbd\x05HQ+Xv\xb0\xa3VN\xf9\xd4\x01\xbd\x11j\x18\x1d\x00\x10\xa8AD\
2065 \xa4\xa4\xd6_\x9b\x19\xbb\x03\xd8c|\x8f\x00\xe0\x93\xa8g>\x15 C\xee:\xe7\x8f\
2066 \x08\xdesj\xcf\xe6\xde(\xddn\xec\x18f0w\xe0m;\x8d\x9b\xe4\xb1\xd4\n\xa6\x0e2\
2067 \xc4{\x1f\xeb\xdf?\xe5\xff\t\xa8\x1a$\x0cg\xac\xaf\xb0\xf4\x992<\x01\xec\xa0\
2068 U9V\xf9\x18\xc8\x00\x00\x00\x00IEND\xaeB`\x82'
2069
2070 def getBreakBitmap():
2071 return BitmapFromImage(getBreakImage())
2072
2073 def getBreakImage():
2074 stream = cStringIO.StringIO(getBreakData())
2075 return ImageFromStream(stream)
2076
2077 def getBreakIcon():
2078 icon = EmptyIcon()
2079 icon.CopyFromBitmap(getBreakBitmap())
2080 return icon
2081
2082 #----------------------------------------------------------------------
2083 def getClearOutputData():
2084 return \
2085 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2086 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2087 \x00\x00\xb4IDAT8\x8d\xa5\x92\xdd\r\x03!\x0c\x83\xbf\xa0n\xd4\x9d\xda5\xb81\
2088 \xbaS\xbb\x12\xee\x03?\xe5\x08\xe5N\xba\xbc Db\xec\xd8p\xb1l\xb8\xa7\x83\xfe\
2089 \xb0\x02H\x92F\xc0_\xa3\x99$\x99\x99\xedznc\xe36\x81\x88\x98"\xb2\x02\xa2\
2090 \x1e\xc4Q\x9aUD\x161\xcd\xde\x1c\x83\x15\x084)\x8d\xc5)\x06\xab\xaaZ\x92\xee\
2091 \xce\x11W\xdbGD\x0cIT\x06\xe7\x00\xdeY\xfe\xcc\x89\x06\xf0\xf2\x99\x00\xe0\
2092 \x91\x7f\xab\x83\xed\xa4\xc8\xafK\x0c\xcf\x92\x83\x99\x8d\xe3p\xef\xe4\xa1\
2093 \x0b\xe57j\xc8:\x06\t\x08\x87.H\xb2n\xa8\xc9\xa9\x12vQ\xfeG"\xe3\xacw\x00\
2094 \x10$M\xd3\x86_\xf0\xe5\xfc\xb4\xfa\x02\xcb\x13j\x10\xc5\xd7\x92D\x00\x00\
2095 \x00\x00IEND\xaeB`\x82'
2096
2097 def getClearOutputBitmap():
2098 return BitmapFromImage(getClearOutputImage())
2099
2100 def getClearOutputImage():
2101 stream = cStringIO.StringIO(getClearOutputData())
2102 return ImageFromStream(stream)
2103
2104 def getClearOutputIcon():
2105 icon = EmptyIcon()
2106 icon.CopyFromBitmap(getClearOutputBitmap())
2107 return icon
2108
2109 #----------------------------------------------------------------------
2110 def getCloseData():
2111 return \
2112 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x12\x00\x00\x00\x12\x08\x06\
2113 \x00\x00\x00V\xce\x8eW\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\
2114 \x00\x86IDAT8\x8d\xed\x90\xb1\r\x80 \x10E_"c\xd80\x02-\x138\x87;8\x8f\x8d\
2115 \x8b\xb0\x02\xa5\xad\rS\x88\xcd\x11) \x82\xb6\xbe\xea\xf2\xc9\xbd\xfc\x03~\
2116 \xdeb\x81\xb9\x90\xabJ^%\x00N\x849\x0e\xf0\x85\xbc\x8a\x12YZR2\xc7\x1eIB\xcb\
2117 \xb2\xcb\x9at\x9d\x95c\xa5Y|\x92\x0c\x0f\xa2\r8e\x1e\x81\x1d8z\xdb8\xee?Ig\
2118 \xfa\xb7\x92)\xcb\xacd\x01XZ$QD\xba\xf0\xa6\x80\xd5\x18cZ\x1b\x95$?\x1f\xb9\
2119 \x00\x1d\x94\x1e*e_\x8a~\x00\x00\x00\x00IEND\xaeB`\x82'
2120
2121 def getCloseBitmap():
2122 return BitmapFromImage(getCloseImage())
2123
2124 def getCloseImage():
2125 stream = cStringIO.StringIO(getCloseData())
2126 return ImageFromStream(stream)
2127
2128 def getCloseIcon():
2129 icon = EmptyIcon()
2130 icon.CopyFromBitmap(getCloseBitmap())
2131 return icon
2132
2133 #----------------------------------------------------------------------
2134 def getContinueData():
2135 return \
2136 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2137 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2138 \x00\x00\x9eIDAT8\x8d\xbd\x92\xd1\r\x83@\x0cC\xed\x8a\x11X\xac\x1b\xddF,\xd6\
2139 \x11\x90\xdc\x0f\x9a\x93s)\x14Z\xa9\x91\x10\n\x97\xbc\xd89\x80?\x84\x1a\xa4\
2140 \x83\xfc\x1c$\x1e)7\xdf<Y0\xaf\x0b\xe6\xf5\x1d\xa1\xb5\x13C\x03 !\xaa\xfd\
2141 \xed\n:mr\xc0\x1d\x8f\xc9\x9a!\t$\xe5\xd3I\xe2\xe5B$\x99\x00[\x01\xe8\xc5\
2142 \xd9G\xfaN`\xd8\x81I\xed\x8c\xb19\x94\x8d\xcbL\x00;t\xcf\x9fwPh\xdb\x0e\xe8\
2143 \xd3,\x17\x8b\xc7\x9d\xbb>\x8a \xec5\x94\tc\xc4\x12\xab\x94\xeb\x7fkWr\xc9B%\
2144 \xfc\xd2\xfcM<\x01\xf6tn\x12O3c\xe6\x00\x00\x00\x00IEND\xaeB`\x82'
2145
2146 def getContinueBitmap():
2147 return BitmapFromImage(getContinueImage())
2148
2149 def getContinueImage():
2150 stream = cStringIO.StringIO(getContinueData())
2151 return ImageFromStream(stream)
2152
2153 def getContinueIcon():
2154 icon = EmptyIcon()
2155 icon.CopyFromBitmap(getContinueBitmap())
2156 return icon
2157
2158 #----------------------------------------------------------------------
2159 def getNextData():
2160 return \
2161 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2162 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2163 \x00\x00\x8eIDAT8\x8d\xa5SA\x12\xc4 \x08K\xb0\xff\xde\xe9\xbf\xb7\xa6\x87\
2164 \x1d:\xba\xa2tZn(\x84`"i\x05obk\x13\xd5CmN+\xcc\x00l\xd6\x0c\x00\xf5\xf8\x0e\
2165 gK\x06\x00 \xa5=k\x00\x00\xb0\xb2]\xd4?5f\xb1\xdb\xaf\xc6\xa2\xcb\xa8\xf0?\
2166 \x1c\x98\xae\x82\xbf\x81\xa4\x8eA\x16\xe1\n\xd1\xa4\x19\xb3\xe9\n\xce\xe8\
2167 \xf1\n\x9eg^\x18\x18\x90\xec<\x11\xf9#\x04XMZ\x19\xaac@+\x94\xd4\x99)SeP\xa1\
2168 )\xd6\x1dI\xe7*\xdc\xf4\x03\xdf~\xe7\x13T^Q?:X\x19d\x00\x00\x00\x00IEND\xaeB\
2169 `\x82'
2170
2171 def getNextBitmap():
2172 return BitmapFromImage(getNextImage())
2173
2174 def getNextImage():
2175 stream = cStringIO.StringIO(getNextData())
2176 return ImageFromStream(stream)
2177
2178 def getNextIcon():
2179 icon = EmptyIcon()
2180 icon.CopyFromBitmap(getNextBitmap())
2181 return icon
2182
2183 #----------------------------------------------------------------------
2184 def getStepInData():
2185 return \
2186 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2187 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2188 \x00\x00\x87IDAT8\x8d\xadSA\x12\x84 \x0ck\x8a\xffv\xfc\xb74{X\xeb0P@\x07s\
2189 \x84\xa4$\x01\x00M\xb2\x02]R\x8b\xc86\xda\xdc\xedd\xb4~\xe8\x86\xc6\x01-\x93\
2190 \x96\xd9#\xf6\x06\xc3;p1I\xd1\x14\x0b#|\x17aF\xec\r\xeeF\xa0eB\xd34\xca\xd0A\
2191 ]j\x84\xa6\x03\x00""\xb7\xb0tRZ\xf7x\xb7\x83\x91]\xcb\x7fa\xd9\x89\x0fC\xfd\
2192 \x94\x9d|9\x99^k\x13\xa1 \xb3\x16\x0f#\xd4\x88N~\x14\xe1-\x96\x7f\xe3\x0f\
2193 \x11\x91UC\x0cX\'\x1e\x00\x00\x00\x00IEND\xaeB`\x82'
2194
2195 def getStepInBitmap():
2196 return BitmapFromImage(getStepInImage())
2197
2198 def getStepInImage():
2199 stream = cStringIO.StringIO(getStepInData())
2200 return ImageFromStream(stream)
2201
2202 def getStepInIcon():
2203 icon = EmptyIcon()
2204 icon.CopyFromBitmap(getStepInBitmap())
2205 return icon
2206
2207 #----------------------------------------------------------------------
2208 def getStopData():
2209 return \
2210 "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2211 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2212 \x00\x00FIDAT8\x8d\xed\x91\xc1\t\xc00\x0c\x03O!\x0b\xa9\xfb\xef\xa6\xfcB\xa1\
2213 N\t\xf4Wr\xa0\x8f\xb1\x0f\x81\xe1\x97\xe4-\xb6}_V%\xc8\xc2, \t\x92\xe6]\xfbZ\
2214 \xf7\x08\xa0W\xc3\xea5\xdb\rl_IX\xe5\xf0d\x00\xfa\x8d#\x7f\xc4\xf7'\xab\x00\
2215 \x00\x00\x00IEND\xaeB`\x82"
2216
2217 def getStopBitmap():
2218 return BitmapFromImage(getStopImage())
2219
2220 def getStopImage():
2221 stream = cStringIO.StringIO(getStopData())
2222 return ImageFromStream(stream)
2223
2224 def getStopIcon():
2225 icon = EmptyIcon()
2226 icon.CopyFromBitmap(getStopBitmap())
2227 return icon
2228
2229 #----------------------------------------------------------------------
2230 def getStepReturnData():
2231 return \
2232 "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2233 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2234 \x00\x00\x8dIDAT8\x8d\xa5S\xd1\x0e\xc4 \x08\xa3\xb0\xff\xbe\xdc\x7fO\xba'6\
2235 \xf1\xf44\xb3O$Phk\x04\xd4d\x07\xba\xc5\x16\x91#\nza\xdb\x84\x1a\xa2\xfe\xf8\
2236 \x99\xfa_=p+\xe8\x91ED\xbc<\xa4 \xb4\x0b\x01\xb5{\x01\xf9\xbbG-\x13\x87\x16f\
2237 \x84\xbf\x16V\xb0l\x01@\no\x86\xae\x82Q\xa8=\xa4\x0c\x80\xe70\xbd\x10jh\xbd\
2238 \x07R\x06#\xc9^N\xb6\xde\x03)\x83\x18\xaeU\x90\x9c>a\xb2P\r\xb3&/Y\xa8\xd1^^\
2239 \xb6\xf0\x16\xdb\xbf\xf1\x02\x81\xa5TK\x1d\x07\xde\x92\x00\x00\x00\x00IEND\
2240 \xaeB`\x82"
2241
2242 def getStepReturnBitmap():
2243 return BitmapFromImage(getStepReturnImage())
2244
2245 def getStepReturnImage():
2246 stream = cStringIO.StringIO(getStepReturnData())
2247 return ImageFromStream(stream)
2248
2249 def getStepReturnIcon():
2250 icon = EmptyIcon()
2251 icon.CopyFromBitmap(getStepReturnBitmap())
2252 return icon
2253
2254 def getAddWatchData():
2255 return \
2256 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2257 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2258 \x00\x00\x85IDAT8\x8dc`\x18h\xc0\x88.\xd0\xc0\xf0\xff?*\x9f\x11C\rN\x80\xae\
2259 \x19\x97\x18\xd1\x9a\x896\x84\x18[p\xa9aA\xe6\xfc7f\xc0P\xc4x\x163\x9cp\x1a0\
2260 \xeb,!w\x100 \x1dK\xac\x10\r\x08\x05".yFL\x85\x8c\x18b\xa8|Ty\xa2\x13\x92\'\
2261 \xc3\xe4\xff\x9f\x18\x1e3\xb82t\xa2\x88\x13\xedg.\x06aa&\x06VV\x7f\x86\xb9\
2262 \xcfU\x19\xbc\xb0\xba\x86h\xe0\xc8\xd0\xfc\xbf\x80\xe1>q)\x94\xe6\x00\x00\
2263 \x85\x923_\xd22\xa4\xcd\x00\x00\x00\x00IEND\xaeB`\x82'
2264
2265 def getAddWatchBitmap():
2266 return BitmapFromImage(getAddWatchImage())
2267
2268 def getAddWatchImage():
2269 stream = cStringIO.StringIO(getAddWatchData())
2270 return ImageFromStream(stream)
2271
2272 def getAddWatchIcon():
2273 icon = EmptyIcon()
2274 icon.CopyFromBitmap(getAddWatchBitmap())
2275 return icon