+ 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()
+ return
+
+ def OnClrButtonPressed(event):
+ self._cmdOutput.Clear()
+
+ panel = wx.Panel(parent, id)
+
+ cmdLabel = wx.StaticText(panel, -1, "Cmd: ")
+ self._cmdInput = wx.TextCtrl(panel)
+ cmdButton = wx.Button(panel, label="Execute")
+ clrButton = wx.Button(panel, label="Clear")
+ self._cmdOutput = wx.TextCtrl(panel, style=wx.TE_MULTILINE | wx.HSCROLL | wx.TE_READONLY | wx.TE_RICH2)
+
+ hbox = wx.BoxSizer()
+ hbox.Add(cmdLabel, proportion=0, flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL)
+ hbox.Add(self._cmdInput, proportion=1, flag=wx.EXPAND)
+ hbox.Add(cmdButton, proportion=0, flag=wx.RIGHT)
+ hbox.Add(clrButton, proportion=0, flag=wx.RIGHT)
+
+ vbox = wx.BoxSizer(wx.VERTICAL)
+ vbox.Add(hbox, proportion=0, flag=wx.EXPAND | wx.ALL, border=2)
+ vbox.Add(self._cmdOutput, proportion=1, flag=wx.EXPAND | wx.LEFT, border=2)
+
+ panel.SetSizer(vbox)
+ cmdButton.Bind(wx.EVT_BUTTON, OnCmdButtonPressed)
+ clrButton.Bind(wx.EVT_BUTTON, OnClrButtonPressed)
+ wx.EVT_KEY_DOWN(self._cmdInput, OnKeyPressed)
+
+ fixedFont = wx.Font(self._cmdInput.GetFont().GetPointSize(), family=wx.TELETYPE, style=wx.NORMAL, weight=wx.NORMAL)
+ self._defaultOutputTextStyle = wx.TextAttr("BLACK", wx.NullColour, fixedFont)
+ self._cmdOutputTextStyle = wx.TextAttr("RED", wx.NullColour, fixedFont)
+ self._cmdOutput.SetDefaultStyle(style=self._defaultOutputTextStyle)
+ self._cmdList = []
+ self._cmdIndex = 0
+
+ panel.Show()
+ return panel
+
+ def MakeBreakPointsTab(self, parent, id):
+ panel = BreakpointsUI(parent, id, self._ui)
+ return panel
+
+ def OnRightClick(self, event):
+ assert False, "OnRightClick not overridden"
+
+ def ClearWhileRunning(self):
+ list = self._framesChoiceCtrl
+ list.Clear()
+ list.Enable(False)
+ tree = self._treeCtrl
+ root = self._root
+ tree.DeleteChildren(root)
+ self._cmdInput.Enable(False)
+ self._cmdOutput.Enable(False)
+
+ def OnListRightClick(self, event):
+ if not hasattr(self, "syncFrameID"):
+ self.syncFrameID = wx.NewId()
+ self.Bind(wx.EVT_MENU, self.OnSyncFrame, id=self.syncFrameID)
+ menu = wx.Menu()
+ item = wx.MenuItem(menu, self.syncFrameID, "Goto Source Line")
+ menu.AppendItem(item)
+ self.PopupMenu(menu, event.GetPosition())
+ menu.Destroy()
+
+ def OnSyncFrame(self, event):
+ assert False, "OnSyncFrame not overridden"
+
+ def LoadFramesList(self, framesXML):
+ assert False, "LoadFramesList not overridden"
+
+ def ListItemSelected(self, event):
+ assert False, "ListItemSelected not overridden"
+
+ def PopulateTreeFromFrameMessage(self, message):
+ assert False, "PopulateTreeFromFrameMessage not overridden"
+
+ def IntrospectCallback(self, event):
+ assert False, "IntrospectCallback not overridden"
+
+ def AppendText(self, text):
+ self._textCtrl.SetReadOnly(False)
+ self._textCtrl.AddText(text)
+ self._textCtrl.ScrollToLine(self._textCtrl.GetLineCount())
+ self._textCtrl.SetReadOnly(True)
+
+ def AppendErrorText(self, text):
+ self._textCtrl.SetReadOnly(False)
+ self._textCtrl.SetFontColor(wx.RED)
+ self._textCtrl.StyleClearAll()
+ self._textCtrl.AddText(text)
+ self._textCtrl.ScrollToLine(self._textCtrl.GetLineCount())
+ self._textCtrl.SetFontColor(wx.BLACK)
+ self._textCtrl.StyleClearAll()
+ self._textCtrl.SetReadOnly(True)
+
+ def ClearOutput(self, event):
+ self._textCtrl.SetReadOnly(False)
+ self._textCtrl.ClearAll()
+ self._textCtrl.SetReadOnly(True)
+
+ def SwitchToOutputTab(self):
+ self._notebook.SetSelection(0)
+
+class PHPFramesUI(BaseFramesUI):
+ def __init__(self, parent, id, ui):
+ BaseFramesUI.__init__(self, parent, id, ui)
+
+ def LoadFramesList(self, stackList):
+ wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
+
+ self._cmdInput.Enable(True)
+ self._cmdOutput.Enable(True)
+ index = 0
+ self._stack = stackList
+ list = self._framesChoiceCtrl
+ list.Clear()
+
+ if len(stackList) > 0:
+ self._displayVariableTreeRootNode()
+
+ for stackFrame in stackList:
+ message = stackFrame.getDisplayStr(stackList)
+ list.Append(message)
+
+ self.currentItem = index
+ list.SetSelection(index)
+ list.Enable(True)
+ self.OnSyncFrame(None)
+ self._p1.FitInside()
+
+ wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
+
+ def PopulateTreeFromStackFrame(self, frameNode):
+ vars = frameNode.getVariables()
+ tree = self._treeCtrl
+ rootTreeNode = self._root
+
+ #
+ # Build a new sub variable tree from the root node.
+ #
+ tree.DeleteChildren(rootTreeNode)
+ for var in vars:
+ aTreeNode = self.AppendSubTreeFromAVariable(tree, var, rootTreeNode)
+
+ #
+ # No need to expand the node here, as the IntrospectCallback() has
+ # already called it.
+ #
+ self._p2.FitInside()
+
+ def AppendSubTreeFromAVariable(self, tree, var, parentTreeNode, previousOne = None):
+ varName = var.getName()
+ varValueStr = var.getValueString()
+
+ #
+ # If previously we already have this item in the tree, replace it.
+ # Otherwise, insert a new one.
+ #
+ if previousOne:
+ newNode = tree.InsertItem(parentTreeNode, previousOne, varName)
+ else:
+ newNode = tree.AppendItem(parentTreeNode, varName)
+
+ #
+ # Associate this variable object with this newNode.
+ #
+ tree.SetPyData(newNode, var)
+
+ #
+ # Set this variable's value string (for displaying).
+ #
+ if varValueStr and len(varValueStr) > 0:
+ tree.SetItemText(newNode, varValueStr, 1)
+
+ #
+ # If this variable has child variables, recursively build the sub
+ # variable tree.
+ #
+ if var.hasChildren():
+ childrenVarList = var.getChildrenVariables()
+ for childVar in childrenVarList:
+ self.AppendSubTreeFromAVariable(tree, childVar, newNode)
+
+ #
+ # If its child variables are sortable, sort it.
+ #
+ if var.childrenIsSortable():
+ tree.SortChildren(newNode)
+
+ return newNode
+
+ def IntrospectCallback(self, event):
+ tree = self._treeCtrl
+ item = event.GetItem()
+
+ #
+ # Only when the introspection happens to root, we get the whole
+ # variable tree. For all the individual nodes, we have populated
+ # the subtree already, so don't need to do anything.
+ #
+ if tree.GetPyData(item) == "root" and self._stack and self._stack[self.currentItem]:
+ stackFrame = self._stack[self.currentItem]
+ self.PopulateTreeFromStackFrame(stackFrame)
+
+ event.Skip()
+
+ def OnSyncFrame(self, event):
+ stackFrame = self._stack[self.currentItem]
+ fileName = stackFrame.getFileName()
+ lineNo = stackFrame.getLineNo()
+ if _VERBOSE:
+ print "OnSyncFrame(): about to sync: fileName: %s, lineNo: %d" % (fileName, lineNo)
+ self._ui.SynchCurrentLine(fileName, lineNo)
+ if _VERBOSE:
+ print "OnSyncFrame(): sync done"
+
+ def ListItemSelected(self, event):
+ selectedStackFrameStr = event.GetString()
+
+ if not self._stack or len(self._stack) < 1:
+ return
+
+ found = False
+ for stackFrame in self._stack:
+ if stackFrame.getDisplayStr() == selectedStackFrameStr:
+ self.currentItem = stackFrame.getFrameIndex()
+ found = True
+ break
+
+ if found:
+ self._displayVariableTreeRootNode()
+ self.OnSyncFrame(None)
+
+ return
+
+ def _displayVariableTreeRootNode(self):
+ #
+ # Add a dummy item to rootTreeNode so that it will be shown as
+ # expandable. Only do real tree population on the fly when the
+ # rootTreeNode is expanded in OnIntrospection().
+ #
+ tree = self._treeCtrl
+ rootTreeNode = self._root
+ dummyNode = tree.AppendItem(rootTreeNode, "dummy")
+ tree.Collapse(rootTreeNode)
+
+ return
+
+
+class PythonFramesUI(BaseFramesUI):
+ def __init__(self, parent, id, ui):
+ BaseFramesUI.__init__(self, parent, id, ui)
+
+ def ExecuteCommand(self, command):
+ retval = self._ui._callback._debuggerServer.execute_in_frame(self._framesChoiceCtrl.GetStringSelection(), command)
+ self._cmdOutput.AppendText(str(retval) + "\n")
+ # Refresh the tree view in case this command resulted in changes there. TODO: Need to reopen tree items.
+ self.PopulateTreeFromFrameMessage(self._framesChoiceCtrl.GetStringSelection())
+