📄 debuggerservice.py
字号:
self.DeleteCurrentLineMarkers() except: pass try: PythonDebuggerUI.ReturnPortToPool(self._debuggerPort) PythonDebuggerUI.ReturnPortToPool(self._guiPort) PythonDebuggerUI.ReturnPortToPool(self._debuggerBreakPort) except: pass try: if self._executor: self._executor.DoStopExecution() self._executor = None except: tp,val,tb = sys.exc_info() traceback.print_exception(tp, val, tb) def MakeFramesUI(self, parent, id, debugger): panel = PythonFramesUI(parent, id, self) return panelclass BreakpointsUI(wx.Panel): def __init__(self, parent, id, ui): wx.Panel.__init__(self, parent, id) self._ui = ui self.currentItem = None self.clearBPID = wx.NewId() self.Bind(wx.EVT_MENU, self.ClearBreakPoint, id=self.clearBPID) self.syncLineID = wx.NewId() self.Bind(wx.EVT_MENU, self.SyncBPLine, id=self.syncLineID) sizer = wx.BoxSizer(wx.VERTICAL) p1 = self self._bpListCtrl = wx.ListCtrl(p1, -1, pos=wx.DefaultPosition, size=(1000,1000), style=wx.LC_REPORT) sizer.Add(self._bpListCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1) self._bpListCtrl.InsertColumn(0, "File") self._bpListCtrl.InsertColumn(1, "Line") self._bpListCtrl.InsertColumn(2, "Path") self._bpListCtrl.SetColumnWidth(0, 150) self._bpListCtrl.SetColumnWidth(1, 50) self._bpListCtrl.SetColumnWidth(2, 450) self._bpListCtrl.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnListRightClick) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.ListItemSelected, self._bpListCtrl) self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.ListItemDeselected, self._bpListCtrl) def OnLeftDoubleClick(event): self.SyncBPLine(event) wx.EVT_LEFT_DCLICK(self._bpListCtrl, OnLeftDoubleClick) self.PopulateBPList() p1.SetSizer(sizer) sizer.Fit(p1) p1.Layout() def PopulateBPList(self): list = self._bpListCtrl list.DeleteAllItems() bps = wx.GetApp().GetService(DebuggerService).GetMasterBreakpointDict() index = 0 for fileName in bps.keys(): shortFile = os.path.basename(fileName) lines = bps[fileName] if lines: for line in lines: list.InsertStringItem(index, shortFile) list.SetStringItem(index, 1, str(line)) list.SetStringItem(index, 2, fileName) def OnListRightClick(self, event): menu = wx.Menu() item = wx.MenuItem(menu, self.clearBPID, "Clear Breakpoint") menu.AppendItem(item) item = wx.MenuItem(menu, self.syncLineID, "Goto Source Line") menu.AppendItem(item) self.PopupMenu(menu, event.GetPosition()) menu.Destroy() def SyncBPLine(self, event): if self.currentItem != -1: list = self._bpListCtrl fileName = list.GetItem(self.currentItem, 2).GetText() lineNumber = list.GetItem(self.currentItem, 1).GetText() self._ui.SynchCurrentLine( fileName, int(lineNumber) , noArrow=True) def ClearBreakPoint(self, event): if self.currentItem >= 0: list = self._bpListCtrl fileName = list.GetItem(self.currentItem, 2).GetText() lineNumber = list.GetItem(self.currentItem, 1).GetText() wx.GetApp().GetService(DebuggerService).OnToggleBreakpoint(None, line=int(lineNumber) -1, fileName=fileName ) def ListItemSelected(self, event): self.currentItem = event.m_itemIndex def ListItemDeselected(self, event): self.currentItem = -1class Watch: CODE_ALL_FRAMES = 1 CODE_THIS_BLOCK = 2 CODE_THIS_LINE = 4 CODE_RUN_ONCE = 8 def __init__(self, name, command, show_code=CODE_ALL_FRAMES): self._name = name self._command = command self._show_code = show_codeclass WatchDialog(wx.Dialog): WATCH_ALL_FRAMES = "Watch in all frames" WATCH_THIS_FRAME = "Watch in this frame only" WATCH_ONCE = "Watch once and delete" def __init__(self, parent, title, chain): wx.Dialog.__init__(self, parent, -1, title, style=wx.DEFAULT_DIALOG_STYLE) self._chain = chain self.label_2 = wx.StaticText(self, -1, "Watch Name:") self._watchNameTextCtrl = wx.TextCtrl(self, -1, "") self.label_3 = wx.StaticText(self, -1, "eval(", style=wx.ALIGN_RIGHT) self._watchValueTextCtrl = wx.TextCtrl(self, -1, "") self.label_4 = wx.StaticText(self, -1, ",frame.f_globals, frame.f_locals)") 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) self._okButton = wx.Button(self, wx.ID_OK, "OK") self._okButton.SetDefault() self._okButton.SetHelpText(_("The OK button completes the dialog")) def OnOkClick(event): if self._watchNameTextCtrl.GetValue() == "": wx.MessageBox(_("You must enter a name for the watch."), _("Add Watch")) return if self._watchValueTextCtrl.GetValue() == "": wx.MessageBox(_("You must enter some code to run for the watch."), _("Add Watch")) return self.EndModal(wx.ID_OK) self.Bind(wx.EVT_BUTTON, OnOkClick, self._okButton) self._cancelButton = wx.Button(self, wx.ID_CANCEL, _("Cancel")) self._cancelButton.SetHelpText(_("The Cancel button cancels the dialog.")) self.__set_properties() self.__do_layout() def GetSettings(self): return self._watchNameTextCtrl.GetValue(), self._watchValueTextCtrl.GetValue(), self.GetSendFrame(), self.GetRunOnce() def GetSendFrame(self): return (WatchDialog.WATCH_ALL_FRAMES != self.radio_box_1.GetStringSelection()) def GetRunOnce(self): return (WatchDialog.WATCH_ONCE == self.radio_box_1.GetStringSelection()) def __set_properties(self): self.SetTitle("Add a Watch") #self.SetSize((400, 250)) self.radio_box_1.SetSelection(0) def __do_layout(self): sizer_1 = wx.BoxSizer(wx.VERTICAL) grid_sizer_4 = wx.FlexGridSizer(1, 3, 5, 5) grid_sizer_2 = wx.FlexGridSizer(1, 2, 5, 5) grid_sizer_2.Add(self.label_2, 0, wx.ALIGN_CENTER_VERTICAL|wx.FIXED_MINSIZE, 0) grid_sizer_2.Add(self._watchNameTextCtrl, 0, wx.EXPAND, 0) grid_sizer_2.AddGrowableCol(1) sizer_1.Add(grid_sizer_2, 1, wx.EXPAND, 0) grid_sizer_4.Add(self.label_3, 0, wx.ALIGN_CENTER_VERTICAL|wx.FIXED_MINSIZE, 0) grid_sizer_4.Add(self._watchValueTextCtrl, 0, wx.EXPAND, 0) grid_sizer_4.AddGrowableCol(1) grid_sizer_4.Add(self.label_4, 0, wx.ALIGN_CENTER_VERTICAL|wx.FIXED_MINSIZE, 0) sizer_1.Add(grid_sizer_4, 0, wx.EXPAND, 0) sizer_1.Add(self.radio_box_1, 0, wx.EXPAND, 0) box = wx.BoxSizer(wx.HORIZONTAL) box.Add(self._okButton, 0, wx.ALIGN_RIGHT|wx.ALL, 5) box.Add(self._cancelButton, 0, wx.ALIGN_RIGHT|wx.ALL, 5) sizer_1.Add(box, 1, wx.EXPAND, 0) self.SetSizer(sizer_1) self.Layout()class BaseFramesUI(wx.SplitterWindow): def __init__(self, parent, id, ui): wx.SplitterWindow.__init__(self, parent, id, style = wx.SP_3D) self._ui = ui self._p1 = p1 = wx.ScrolledWindow(self, -1) sizer = wx.BoxSizer(wx.HORIZONTAL) framesLabel = wx.StaticText(self, -1, "Stack Frame:") sizer.Add(framesLabel, 0, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.LEFT, border=2) self._framesChoiceCtrl = wx.Choice(p1, -1, choices=[" "]) sizer.Add(self._framesChoiceCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1) self._framesChoiceCtrl.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnListRightClick) self.Bind(wx.EVT_CHOICE, self.ListItemSelected, self._framesChoiceCtrl) sizer2 = wx.BoxSizer(wx.VERTICAL) p1.SetSizer(sizer2) self._treeCtrl = wx.gizmos.TreeListCtrl(p1, -1, style=wx.TR_DEFAULT_STYLE| wx.TR_FULL_ROW_HIGHLIGHT) self._treeCtrl.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnRightClick) sizer2.Add(sizer, 0, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1) sizer2.Add(self._treeCtrl,1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1) tree = self._treeCtrl tree.AddColumn("Thing") tree.AddColumn("Value") tree.SetMainColumn(0) # the one with the tree in it... tree.SetColumnWidth(0, 175) tree.SetColumnWidth(1, 355) self._root = tree.AddRoot("Frame") tree.SetPyData(self._root, "root") tree.SetItemText(self._root, "", 1) tree.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.IntrospectCallback) self._p2 = p2 = wx.Window(self, -1) sizer3 = wx.BoxSizer(wx.HORIZONTAL) p2.SetSizer(sizer3) p2.Bind(wx.EVT_SIZE, self.OnSize) self._notebook = wx.Notebook(p2, -1, size=(20,20)) self._notebook.Hide() sizer3.Add(self._notebook, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1) self.consoleTab = self.MakeConsoleTab(self._notebook, wx.NewId()) self.inspectConsoleTab = self.MakeInspectConsoleTab(self._notebook, wx.NewId()) self.breakPointsTab = self.MakeBreakPointsTab(self._notebook, wx.NewId()) self._notebook.AddPage(self.consoleTab, "Output") self._notebook.AddPage(self.inspectConsoleTab, "Interact") self._notebook.AddPage(self.breakPointsTab, "Break Points") self.SetMinimumPaneSize(20) self.SplitVertically(p1, p2, 550) self.currentItem = None self._notebook.Show(True) def PopulateBPList(self): self.breakPointsTab.PopulateBPList() def OnSize(self, event): self._notebook.SetSize(self._p2.GetSize()) def OnDoubleClick(self, event): # Looking for a stack trace line. lineText, pos = self._textCtrl.GetCurLine() fileBegin = lineText.find("File \"") fileEnd = lineText.find("\", line ") lineEnd = lineText.find(", in ") if lineText == "\n" or fileBegin == -1 or fileEnd == -1 or lineEnd == -1: # Check the line before the one that was clicked on lineNumber = self._textCtrl.GetCurrentLine() if(lineNumber == 0): return lineText = self._textCtrl.GetLine(lineNumber - 1) fileBegin = lineText.find("File \"") fileEnd = lineText.find("\", line ") lineEnd = lineText.find(", in ") if lineText == "\n" or fileBegin == -1 or fileEnd == -1 or lineEnd == -1: return filename = lineText[fileBegin + 6:fileEnd] lineNum = int(lineText[fileEnd + 8:lineEnd]) foundView = None openDocs = wx.GetApp().GetDocumentManager().GetDocuments() for openDoc in openDocs: if openDoc.GetFilename() == filename: foundView = openDoc.GetFirstView() break if not foundView: doc = wx.GetApp().GetDocumentManager().CreateDocument(filename, wx.lib.docview.DOC_SILENT) foundView = doc.GetFirstView() if foundView: foundView.GetFrame().SetFocus() foundView.Activate() foundView.GotoLine(lineNum) startPos = foundView.PositionFromLine(lineNum) lineText = foundView.GetCtrl().GetLine(lineNum - 1) foundView.SetSelection(startPos, startPos + len(lineText.rstrip("\n"))) import OutlineService wx.GetApp().GetService(OutlineService.OutlineService).LoadOutline(foundView, position=startPos) def MakeConsoleTab(self, parent, id): panel = wx.Panel(parent, id) sizer = wx.BoxSizer(wx.HORIZONTAL) self._textCtrl = STCTextEditor.TextCtrl(panel, wx.NewId()) sizer.Add(self._textCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 2) self._textCtrl.SetViewLineNumbers(False) self._textCtrl.SetReadOnly(True) if wx.Platform == '__WXMSW__': font = "Courier New" else: font = "Courier" self._textCtrl.SetFont(wx.Font(9, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = font)) self._textCtrl.SetFontColor(wx.BLACK) self._textCtrl.StyleClearAll() wx.stc.EVT_STC_DOUBLECLICK(self._textCtrl, self._textCtrl.GetId(), self.OnDoubleClick) panel.SetSizer(sizer) #sizer.Fit(panel) return panel def ExecuteCommand(self, command): assert False, "ExecuteCommand not overridden" def MakeInspectConsoleTab(self, parent, id): def handleCommand(): cmdStr = self._cmdInput.GetValue() if cmdStr: self._cmdList.append(cmdStr) self._cmdIndex = len(self._cmdList) self._cmdInput.Clear() self._cmdOutput.SetDefaultStyle(style=self._cmdOutputTextStyle) self._cmdOutput.AppendText(">>> " + cmdStr + "\n") self._cmdOutput.SetDefaultStyle(style=self._defaultOutputTextStyle) self.ExecuteCommand(cmdStr) return def OnCmdButtonPressed(event): handleCommand() return def OnKeyPressed(event): key = event.KeyCode() if key == wx.WXK_RETURN: handleCommand() elif key == wx.WXK_UP: if len(self._cmdList) < 1 or self._cmdIndex < 1: return self._cmdInput.Clear() self._cmdInput.AppendText(self._cmdList[self._cmdIndex - 1]) self._cmdIndex = self._cmdIndex - 1 elif key == wx.WXK_DOWN: if len(self._cmdList) < 1 or self._cmdIndex >= len(self._cmdList): return self._cmdInput.Clear() self._cmdInput.AppendText(self._cmdList[self._cmdIndex - 1]) self._cmdIndex = self._cmdIndex + 1 else: event.Skip()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -