Debugger/DebugUI.py

changeset 5141
bc64243b7672
parent 5126
d28b92dabc2b
parent 5140
01484c0afbc6
child 5373
7826884089fd
equal deleted inserted replaced
5126:d28b92dabc2b 5141:bc64243b7672
11 11
12 import os 12 import os
13 13
14 from PyQt5.QtCore import pyqtSignal, QObject, Qt 14 from PyQt5.QtCore import pyqtSignal, QObject, Qt
15 from PyQt5.QtGui import QKeySequence 15 from PyQt5.QtGui import QKeySequence
16 from PyQt5.QtWidgets import QMenu, QToolBar, QApplication, QDialog, \ 16 from PyQt5.QtWidgets import QMenu, QToolBar, QApplication, QDialog
17 QInputDialog
18 17
19 from UI.Info import Program 18 from UI.Info import Program
20 19
21 from .DebugClientCapabilities import HasDebugger, HasInterpreter, \ 20 from .DebugClientCapabilities import HasDebugger, HasInterpreter, \
22 HasProfiler, HasCoverage 21 HasProfiler, HasCoverage
102 Preferences.Prefs.settings.value( 101 Preferences.Prefs.settings.value(
103 'DebugInfo/ForkAutomatically', False)) 102 'DebugInfo/ForkAutomatically', False))
104 self.forkIntoChild = Preferences.toBool( 103 self.forkIntoChild = Preferences.toBool(
105 Preferences.Prefs.settings.value('DebugInfo/ForkIntoChild', False)) 104 Preferences.Prefs.settings.value('DebugInfo/ForkIntoChild', False))
106 105
107 self.evalHistory = []
108 self.execHistory = []
109 self.lastDebuggedFile = None 106 self.lastDebuggedFile = None
110 self.lastStartAction = 0 # 0=None, 1=Script, 2=Project 107 self.lastStartAction = 0 # 0=None, 1=Script, 2=Project
111 self.clientType = "" 108 self.clientType = ""
112 self.lastAction = -1 109 self.lastAction = -1
113 self.debugActions = [ 110 self.debugActions = [
426 """<p>Stop the running debugging session.</p>""" 423 """<p>Stop the running debugging session.</p>"""
427 )) 424 ))
428 act.triggered.connect(self.__stepQuit) 425 act.triggered.connect(self.__stepQuit)
429 self.actions.append(act) 426 self.actions.append(act)
430 427
431 self.debugActGrp2 = createActionGroup(self)
432
433 act = E5Action(
434 self.tr('Evaluate'),
435 self.tr('E&valuate...'),
436 0, 0, self.debugActGrp2, 'dbg_evaluate')
437 act.setStatusTip(self.tr('Evaluate in current context'))
438 act.setWhatsThis(self.tr(
439 """<b>Evaluate</b>"""
440 """<p>Evaluate an expression in the current context of the"""
441 """ debugged program. The result is displayed in the"""
442 """ shell window.</p>"""
443 ))
444 act.triggered.connect(self.__eval)
445 self.actions.append(act)
446
447 act = E5Action(
448 self.tr('Execute'),
449 self.tr('E&xecute...'),
450 0, 0, self.debugActGrp2, 'dbg_execute')
451 act.setStatusTip(
452 self.tr('Execute a one line statement in the current context'))
453 act.setWhatsThis(self.tr(
454 """<b>Execute</b>"""
455 """<p>Execute a one line statement in the current context"""
456 """ of the debugged program.</p>"""
457 ))
458 act.triggered.connect(self.__exec)
459 self.actions.append(act)
460
461 self.dbgFilterAct = E5Action( 428 self.dbgFilterAct = E5Action(
462 self.tr('Variables Type Filter'), 429 self.tr('Variables Type Filter'),
463 self.tr('Varia&bles Type Filter...'), 0, 0, self, 430 self.tr('Varia&bles Type Filter...'), 0, 0, self,
464 'dbg_variables_filter') 431 'dbg_variables_filter')
465 self.dbgFilterAct.setStatusTip(self.tr( 432 self.dbgFilterAct.setStatusTip(self.tr(
583 )) 550 ))
584 act.triggered.connect(self.__clearBreakpoints) 551 act.triggered.connect(self.__clearBreakpoints)
585 self.actions.append(act) 552 self.actions.append(act)
586 553
587 self.debugActGrp.setEnabled(False) 554 self.debugActGrp.setEnabled(False)
588 self.debugActGrp2.setEnabled(False)
589 self.dbgSetBpActGrp.setEnabled(False) 555 self.dbgSetBpActGrp.setEnabled(False)
590 self.runAct.setEnabled(False) 556 self.runAct.setEnabled(False)
591 self.runProjectAct.setEnabled(False) 557 self.runProjectAct.setEnabled(False)
592 self.profileAct.setEnabled(False) 558 self.profileAct.setEnabled(False)
593 self.profileProjectAct.setEnabled(False) 559 self.profileProjectAct.setEnabled(False)
625 smenu.addAction(self.coverageAct) 591 smenu.addAction(self.coverageAct)
626 smenu.addAction(self.coverageProjectAct) 592 smenu.addAction(self.coverageProjectAct)
627 593
628 dmenu.addActions(self.debugActGrp.actions()) 594 dmenu.addActions(self.debugActGrp.actions())
629 dmenu.addSeparator() 595 dmenu.addSeparator()
630 dmenu.addActions(self.debugActGrp2.actions())
631 dmenu.addSeparator()
632 dmenu.addActions(self.dbgSetBpActGrp.actions()) 596 dmenu.addActions(self.dbgSetBpActGrp.actions())
633 self.menuBreakpointsAct = dmenu.addMenu(self.breakpointsMenu) 597 self.menuBreakpointsAct = dmenu.addMenu(self.breakpointsMenu)
634 dmenu.addSeparator() 598 dmenu.addSeparator()
635 dmenu.addAction(self.dbgFilterAct) 599 dmenu.addAction(self.dbgFilterAct)
636 dmenu.addAction(self.excFilterAct) 600 dmenu.addAction(self.excFilterAct)
804 self.debugAct.setEnabled(False) 768 self.debugAct.setEnabled(False)
805 self.runAct.setEnabled(False) 769 self.runAct.setEnabled(False)
806 self.profileAct.setEnabled(False) 770 self.profileAct.setEnabled(False)
807 self.coverageAct.setEnabled(False) 771 self.coverageAct.setEnabled(False)
808 self.debugActGrp.setEnabled(False) 772 self.debugActGrp.setEnabled(False)
809 self.debugActGrp2.setEnabled(False)
810 self.dbgSetBpActGrp.setEnabled(False) 773 self.dbgSetBpActGrp.setEnabled(False)
811 self.lastAction = -1 774 self.lastAction = -1
812 if not self.projectOpen: 775 if not self.projectOpen:
813 self.restartAct.setEnabled(False) 776 self.restartAct.setEnabled(False)
814 self.lastDebuggedFile = None 777 self.lastDebuggedFile = None
976 """ 939 """
977 Private slot to reset the user interface. 940 Private slot to reset the user interface.
978 """ 941 """
979 self.lastAction = -1 942 self.lastAction = -1
980 self.debugActGrp.setEnabled(False) 943 self.debugActGrp.setEnabled(False)
981 self.debugActGrp2.setEnabled(False)
982 if not self.passive: 944 if not self.passive:
983 if self.editorOpen: 945 if self.editorOpen:
984 editor = self.viewmanager.activeWindow() 946 editor = self.viewmanager.activeWindow()
985 else: 947 else:
986 editor = None 948 editor = None
1014 if not forStack: 976 if not forStack:
1015 self.__getThreadList() 977 self.__getThreadList()
1016 self.__getClientVariables() 978 self.__getClientVariables()
1017 979
1018 self.debugActGrp.setEnabled(True) 980 self.debugActGrp.setEnabled(True)
1019 self.debugActGrp2.setEnabled(True) 981
1020 982 def __clientExit(self, status, message):
1021 def __clientExit(self, status):
1022 """ 983 """
1023 Private method to handle the debugged program terminating. 984 Private method to handle the debugged program terminating.
1024 985
1025 @param status exit code of the debugged program (int) 986 @param status exit code of the debugged program
987 @type int
988 @param message exit message of the debugged program
989 @type str
1026 """ 990 """
1027 self.viewmanager.exit() 991 self.viewmanager.exit()
1028 992
1029 self.__resetUI() 993 self.__resetUI()
1030 994
1031 if not Preferences.getDebugger("SuppressClientExit") or status != 0: 995 if not Preferences.getDebugger("SuppressClientExit") or status != 0:
996 if message:
997 info = self.tr("<p>Message: {0}</p>").format(
998 Utilities.html_uencode(message))
999 else:
1000 info = ""
1032 if self.ui.currentProg is None: 1001 if self.ui.currentProg is None:
1033 E5MessageBox.information( 1002 E5MessageBox.information(
1034 self.ui, Program, 1003 self.ui, Program,
1035 self.tr('<p>The program has terminated with an exit' 1004 self.tr('<p>The program has terminated with an exit'
1036 ' status of {0}.</p>').format(status)) 1005 ' status of {0}.</p>{1}').format(status, info))
1037 else: 1006 else:
1038 E5MessageBox.information( 1007 E5MessageBox.information(
1039 self.ui, Program, 1008 self.ui, Program,
1040 self.tr('<p><b>{0}</b> has terminated with an exit' 1009 self.tr('<p><b>{0}</b> has terminated with an exit'
1041 ' status of {1}.</p>') 1010 ' status of {1}.</p>{2}')
1042 .format(Utilities.normabspath(self.ui.currentProg), 1011 .format(Utilities.normabspath(self.ui.currentProg),
1043 status)) 1012 status, info))
1044 else: 1013 else:
1014 if message:
1015 info = self.tr("Message: {0}").format(
1016 Utilities.html_uencode(message))
1017 else:
1018 info = ""
1045 if self.ui.notificationsEnabled(): 1019 if self.ui.notificationsEnabled():
1046 if self.ui.currentProg is None: 1020 if self.ui.currentProg is None:
1047 msg = self.tr('The program has terminated with an exit' 1021 msg = self.tr('The program has terminated with an exit'
1048 ' status of {0}.').format(status) 1022 ' status of {0}.\n{1}').format(status, info)
1049 else: 1023 else:
1050 msg = self.tr('"{0}" has terminated with an exit' 1024 msg = self.tr('"{0}" has terminated with an exit'
1051 ' status of {1}.')\ 1025 ' status of {1}.\n{2}')\
1052 .format(os.path.basename(self.ui.currentProg), 1026 .format(os.path.basename(self.ui.currentProg),
1053 status) 1027 status, info)
1054 self.ui.showNotification( 1028 self.ui.showNotification(
1055 UI.PixmapCache.getPixmap("debug48.png"), 1029 UI.PixmapCache.getPixmap("debug48.png"),
1056 self.tr("Program terminated"), msg) 1030 self.tr("Program terminated"), msg)
1057 else: 1031 else:
1058 if self.ui.currentProg is None: 1032 if self.ui.currentProg is None:
1059 self.appendStdout.emit( 1033 self.appendStdout.emit(
1060 self.tr('The program has terminated with an exit' 1034 self.tr('The program has terminated with an exit'
1061 ' status of {0}.\n').format(status)) 1035 ' status of {0}.\n{1}\n').format(status, info))
1062 else: 1036 else:
1063 self.appendStdout.emit( 1037 self.appendStdout.emit(
1064 self.tr('"{0}" has terminated with an exit' 1038 self.tr('"{0}" has terminated with an exit'
1065 ' status of {1}.\n') 1039 ' status of {1}.\n{2}\n')
1066 .format(Utilities.normabspath(self.ui.currentProg), 1040 .format(Utilities.normabspath(self.ui.currentProg),
1067 status)) 1041 status, info))
1068 1042
1069 def __clientSyntaxError(self, message, filename, lineNo, characterNo): 1043 def __clientSyntaxError(self, message, filename, lineNo, characterNo):
1070 """ 1044 """
1071 Private method to handle a syntax error in the debugged program. 1045 Private method to handle a syntax error in the debugged program.
1072 1046
1190 stack.append((fn, ln, func, args)) 1164 stack.append((fn, ln, func, args))
1191 self.clientStack.emit(stack) 1165 self.clientStack.emit(stack)
1192 self.__getClientVariables() 1166 self.__getClientVariables()
1193 self.ui.setDebugProfile() 1167 self.ui.setDebugProfile()
1194 self.debugActGrp.setEnabled(True) 1168 self.debugActGrp.setEnabled(True)
1195 self.debugActGrp2.setEnabled(True)
1196 return 1169 return
1197 elif res == E5MessageBox.Ignore: 1170 elif res == E5MessageBox.Ignore:
1198 if exceptionType not in self.excIgnoreList: 1171 if exceptionType not in self.excIgnoreList:
1199 self.excIgnoreList.append(exceptionType) 1172 self.excIgnoreList.append(exceptionType)
1200 1173
2190 self.__enterRemote() 2163 self.__enterRemote()
2191 self.debugServer.remoteBreakpoint( 2164 self.debugServer.remoteBreakpoint(
2192 aw.getFileName(), line, 1, None, 1) 2165 aw.getFileName(), line, 1, None, 1)
2193 self.debugServer.remoteContinue() 2166 self.debugServer.remoteContinue()
2194 2167
2195 def __eval(self):
2196 """
2197 Private method to handle the Eval action.
2198 """
2199 # Get the command line arguments.
2200 if len(self.evalHistory) > 0:
2201 curr = 0
2202 else:
2203 curr = -1
2204
2205 arg, ok = QInputDialog.getItem(
2206 self.ui,
2207 self.tr("Evaluate"),
2208 self.tr("Enter the statement to evaluate"),
2209 self.evalHistory,
2210 curr, True)
2211
2212 if ok:
2213 if not arg:
2214 return
2215
2216 # This moves any previous occurrence of this expression to the head
2217 # of the list.
2218 if arg in self.evalHistory:
2219 self.evalHistory.remove(arg)
2220 self.evalHistory.insert(0, arg)
2221
2222 self.debugServer.remoteEval(arg)
2223
2224 def __exec(self):
2225 """
2226 Private method to handle the Exec action.
2227 """
2228 # Get the command line arguments.
2229 if len(self.execHistory) > 0:
2230 curr = 0
2231 else:
2232 curr = -1
2233
2234 stmt, ok = QInputDialog.getItem(
2235 self.ui,
2236 self.tr("Execute"),
2237 self.tr("Enter the statement to execute"),
2238 self.execHistory,
2239 curr, True)
2240
2241 if ok:
2242 if not stmt:
2243 return
2244
2245 # This moves any previous occurrence of this statement to the head
2246 # of the list.
2247 if stmt in self.execHistory:
2248 self.execHistory.remove(stmt)
2249 self.execHistory.insert(0, stmt)
2250
2251 self.debugServer.remoteExec(stmt)
2252
2253 def __enterRemote(self): 2168 def __enterRemote(self):
2254 """ 2169 """
2255 Private method to update the user interface. 2170 Private method to update the user interface.
2256 2171
2257 This method is called just prior to executing some of 2172 This method is called just prior to executing some of
2258 the program being debugged. 2173 the program being debugged.
2259 """ 2174 """
2260 # Disable further debug commands from the user. 2175 # Disable further debug commands from the user.
2261 self.debugActGrp.setEnabled(False) 2176 self.debugActGrp.setEnabled(False)
2262 self.debugActGrp2.setEnabled(False)
2263 2177
2264 self.viewmanager.unhighlight(True) 2178 self.viewmanager.unhighlight(True)
2265 2179
2266 def getActions(self): 2180 def getActions(self):
2267 """ 2181 """

eric ide

mercurial