123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- # Command Handlers for the debugger.
- # Not in the debugger package, as I always want these interfaces to be
- # available, even if the debugger has not yet been (or can not be)
- # imported
- import win32ui, win32con
- from . import scriptutils
- import warnings
- from pywin.scintilla.control import CScintillaEditInterface
- IdToBarNames = {
- win32ui.IDC_DBG_STACK : ("Stack",0),
- win32ui.IDC_DBG_BREAKPOINTS : ("Breakpoints",0),
- win32ui.IDC_DBG_WATCH : ("Watch",1),
- }
- class DebuggerCommandHandler:
- def HookCommands(self):
- commands = ( (self.OnStep, None, win32ui.IDC_DBG_STEP),
- (self.OnStepOut, self.OnUpdateOnlyBreak, win32ui.IDC_DBG_STEPOUT),
- (self.OnStepOver, None, win32ui.IDC_DBG_STEPOVER),
- (self.OnGo, None, win32ui.IDC_DBG_GO),
- (self.OnClose, self.OnUpdateClose, win32ui.IDC_DBG_CLOSE),
- (self.OnAdd, self.OnUpdateAddBreakpoints, win32ui.IDC_DBG_ADD),
- (self.OnClearAll, self.OnUpdateClearAllBreakpoints, win32ui.IDC_DBG_CLEAR),
- # (self.OnDebuggerToolbar, self.OnUpdateDebuggerToolbar, win32ui.ID_DEBUGGER_TOOLBAR),
- )
- frame = win32ui.GetMainFrame()
- for methHandler, methUpdate, id in commands:
- frame.HookCommand(methHandler, id);
- if not methUpdate is None:
- frame.HookCommandUpdate(methUpdate, id)
- for id in list(IdToBarNames.keys()):
- frame.HookCommand( self.OnDebuggerBar, id)
- frame.HookCommandUpdate(self.OnUpdateDebuggerBar, id)
- def OnDebuggerToolbar(self, id, code):
- if code==0:
- return not win32ui.GetMainFrame().OnBarCheck(id)
- def OnUpdateDebuggerToolbar(self, cmdui):
- win32ui.GetMainFrame().OnUpdateControlBarMenu(cmdui)
- cmdui.Enable(1)
- def _GetDebugger(self):
- try:
- import pywin.debugger
- return pywin.debugger.currentDebugger
- except ImportError:
- return None
- def _DoOrStart(self, doMethod, startFlag):
- d=self._GetDebugger()
- if d is not None and d.IsDebugging():
- method = getattr(d, doMethod)
- method()
- else:
- scriptutils.RunScript(defName=None, defArgs=None, bShowDialog = 0, debuggingType=startFlag)
- def OnStep(self, msg, code):
- self._DoOrStart("do_set_step", scriptutils.RS_DEBUGGER_STEP)
- def OnStepOver(self, msg, code):
- self._DoOrStart("do_set_next", scriptutils.RS_DEBUGGER_STEP)
- def OnStepOut(self, msg, code):
- d=self._GetDebugger()
- if d is not None and d.IsDebugging():
- d.do_set_return()
- def OnGo(self, msg, code):
- self._DoOrStart("do_set_continue", scriptutils.RS_DEBUGGER_GO)
- def OnClose(self, msg, code):
- d=self._GetDebugger()
- if d is not None:
- if d.IsDebugging():
- d.set_quit()
- else:
- d.close()
- def OnUpdateClose(self, cmdui):
- d=self._GetDebugger()
- if d is not None and d.inited:
- cmdui.Enable(1)
- else:
- cmdui.Enable(0)
- def OnAdd(self, msg, code):
- doc, view = scriptutils.GetActiveEditorDocument()
- if doc is None:
- ## Don't do a messagebox, as this could be triggered from the app's
- ## idle loop whenever the debug toolbar is visible, giving a never-ending
- ## series of dialogs. This can happen when the OnUpdate handler
- ## for the toolbar button IDC_DBG_ADD fails, since MFC falls back to
- ## sending a normal command if the UI update command fails.
- ## win32ui.MessageBox('There is no active window - no breakpoint can be added')
- warnings.warn('There is no active window - no breakpoint can be added')
- return None
- pathName = doc.GetPathName()
- lineNo = view.LineFromChar(view.GetSel()[0])+1
- # If I have a debugger, then tell it, otherwise just add a marker
- d=self._GetDebugger()
- if d is None:
- import pywin.framework.editor.color.coloreditor
- doc.MarkerToggle(lineNo, pywin.framework.editor.color.coloreditor.MARKER_BREAKPOINT)
- else:
- if d.get_break(pathName, lineNo):
- win32ui.SetStatusText('Clearing breakpoint',1)
- rc = d.clear_break(pathName, lineNo)
- else:
- win32ui.SetStatusText('Setting breakpoint',1)
- rc = d.set_break(pathName, lineNo)
- if rc:
- win32ui.MessageBox(rc)
- d.GUIRespondDebuggerData()
- def OnClearAll(self, msg, code):
- win32ui.SetStatusText('Clearing all breakpoints')
- d=self._GetDebugger()
- if d is None:
- import pywin.framework.editor
- import pywin.framework.editor.color.coloreditor
- for doc in pywin.framework.editor.editorTemplate.GetDocumentList():
- doc.MarkerDeleteAll(pywin.framework.editor.color.coloreditor.MARKER_BREAKPOINT)
- else:
- d.clear_all_breaks()
- d.UpdateAllLineStates()
- d.GUIRespondDebuggerData()
- def OnUpdateOnlyBreak(self, cmdui):
- d=self._GetDebugger()
- ok = d is not None and d.IsBreak()
- cmdui.Enable(ok)
- def OnUpdateAddBreakpoints(self, cmdui):
- doc, view = scriptutils.GetActiveEditorDocument()
- if doc is None or not isinstance(view, CScintillaEditInterface):
- enabled = 0
- else:
- enabled = 1
- lineNo = view.LineFromChar(view.GetSel()[0])+1
- import pywin.framework.editor.color.coloreditor
- cmdui.SetCheck(doc.MarkerAtLine(lineNo, pywin.framework.editor.color.coloreditor.MARKER_BREAKPOINT) != 0)
- cmdui.Enable(enabled)
- def OnUpdateClearAllBreakpoints(self, cmdui):
- d=self._GetDebugger()
- cmdui.Enable(d is None or len(d.breaks)!=0)
- def OnUpdateDebuggerBar(self, cmdui):
- name, always = IdToBarNames.get(cmdui.m_nID)
- enabled = always
- d=self._GetDebugger()
- if d is not None and d.IsDebugging() and name is not None:
- enabled = 1
- bar = d.GetDebuggerBar(name)
- cmdui.SetCheck(bar.IsWindowVisible())
- cmdui.Enable(enabled)
- def OnDebuggerBar(self, id, code):
- name = IdToBarNames.get(id)[0]
- d=self._GetDebugger()
- if d is not None and name is not None:
- bar = d.GetDebuggerBar(name)
- newState = not bar.IsWindowVisible()
- win32ui.GetMainFrame().ShowControlBar(bar, newState, 1)
|