eric6/Debugger/DebugViewer.py

branch
multi_processing
changeset 7377
cc920e534ac0
parent 7376
21df384d6150
child 7379
72a72fd56494
equal deleted inserted replaced
7376:21df384d6150 7377:cc920e534ac0
21 """ 21 """
22 22
23 23
24 import os 24 import os
25 25
26 from PyQt5.QtCore import pyqtSignal 26 from PyQt5.QtCore import pyqtSignal, Qt
27 from PyQt5.QtWidgets import ( 27 from PyQt5.QtWidgets import (
28 QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QSizePolicy, QPushButton, 28 QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QSizePolicy, QPushButton,
29 QComboBox, QLabel, QTreeWidget, QTreeWidgetItem, QHeaderView, QFrame 29 QComboBox, QLabel, QTreeWidget, QTreeWidgetItem, QHeaderView, QFrame
30 ) 30 )
31 31
67 self.__mainLayout = QVBoxLayout() 67 self.__mainLayout = QVBoxLayout()
68 self.__mainLayout.setContentsMargins(0, 0, 0, 0) 68 self.__mainLayout.setContentsMargins(0, 0, 0, 0)
69 self.setLayout(self.__mainLayout) 69 self.setLayout(self.__mainLayout)
70 70
71 # add the viewer showing the connected debug backends 71 # add the viewer showing the connected debug backends
72 self.__debuggersLayout = QHBoxLayout(self) 72 self.__debuggersLayout = QHBoxLayout()
73 self.__debuggersLayout.addWidget(QLabel(self.tr("Debuggers:"))) 73 self.__debuggersLayout.addWidget(QLabel(self.tr("Debuggers:")))
74 self.__debuggersCombo = QComboBox(self) 74 self.__debuggersCombo = QComboBox(self)
75 self.__debuggersCombo.setSizePolicy( 75 self.__debuggersCombo.setSizePolicy(
76 QSizePolicy.Expanding, QSizePolicy.Fixed) 76 QSizePolicy.Expanding, QSizePolicy.Fixed)
77 self.__debuggersLayout.addWidget(self.__debuggersCombo) 77 self.__debuggersLayout.addWidget(self.__debuggersCombo)
78 self.__mainLayout.addLayout(self.__debuggersLayout) 78 self.__mainLayout.addLayout(self.__debuggersLayout)
79 79
80 self.__debuggersCombo.currentTextChanged.connect( 80 self.__debuggersCombo.currentIndexChanged[str].connect(
81 self.__debuggerSelected) 81 self.__debuggerSelected)
82 82
83 # add a line to separate debugger selector from debugger specific parts 83 # add a line to separate debugger selector from debugger specific parts
84 hline = QFrame(self) 84 hline = QFrame(self)
85 hline.setFrameStyle(QFrame.Sunken) 85 hline.setFrameStyle(QFrame.Sunken)
262 self.__mainLayout.setStretchFactor(self.__threadList, 1) 262 self.__mainLayout.setStretchFactor(self.__threadList, 1)
263 263
264 self.currentStack = None 264 self.currentStack = None
265 self.framenr = 0 265 self.framenr = 0
266 266
267 self.debugServer.clientStack.connect(self.handleClientStack)
268
269 self.__autoViewSource = Preferences.getDebugger("AutoViewSourceCode") 267 self.__autoViewSource = Preferences.getDebugger("AutoViewSourceCode")
270 self.sourceButton.setVisible(not self.__autoViewSource) 268 self.sourceButton.setVisible(not self.__autoViewSource)
271 269
270 # connect somer debug server signals
271 self.debugServer.clientStack.connect(
272 self.handleClientStack)
273 self.debugServer.clientThreadList.connect(
274 self.showThreadList)
275 self.debugServer.clientDebuggerIds.connect(
276 self.showDebuggersList)
277 self.debugServer.passiveDebugStarted.connect(
278 self.handleDebuggingStarted)
279 self.debugServer.clientLine.connect(
280 self.__clientLine)
281
282 self.debugServer.clientException.connect(
283 self.exceptionLogger.addException)
284 self.debugServer.passiveDebugStarted.connect(
285 self.exceptionLogger.debuggingStarted)
286
287 self.debugServer.clientLine.connect(
288 self.breakpointViewer.highlightBreakpoint)
289
272 def handlePreferencesChanged(self): 290 def handlePreferencesChanged(self):
273 """ 291 """
274 Public slot to handle the preferencesChanged signal. 292 Public slot to handle the preferencesChanged signal.
275 """ 293 """
276 self.__autoViewSource = Preferences.getDebugger("AutoViewSourceCode") 294 self.__autoViewSource = Preferences.getDebugger("AutoViewSourceCode")
281 Public method to set a reference to the Debug UI. 299 Public method to set a reference to the Debug UI.
282 300
283 @param debugUI reference to the DebugUI object (DebugUI) 301 @param debugUI reference to the DebugUI object (DebugUI)
284 """ 302 """
285 self.debugUI = debugUI 303 self.debugUI = debugUI
304 self.callStackViewer.setDebugger(debugUI)
305
306 # connect some debugUI signals
286 self.debugUI.clientStack.connect(self.handleClientStack) 307 self.debugUI.clientStack.connect(self.handleClientStack)
287 self.callStackViewer.setDebugger(debugUI) 308 self.debugUI.debuggingStarted.connect(
288 309 self.exceptionLogger.debuggingStarted)
310 self.debugUI.debuggingStarted.connect(
311 self.handleDebuggingStarted)
312
289 def handleResetUI(self): 313 def handleResetUI(self):
290 """ 314 """
291 Public method to reset the SBVviewer. 315 Public method to reset the SBVviewer.
292 """ 316 """
293 self.globalsViewer.handleResetUI() 317 self.globalsViewer.handleResetUI()
369 if showGlobals: 393 if showGlobals:
370 self.__tabWidget.setCurrentWidget(self.glvWidget) 394 self.__tabWidget.setCurrentWidget(self.glvWidget)
371 else: 395 else:
372 self.__tabWidget.setCurrentWidget(self.lvWidget) 396 self.__tabWidget.setCurrentWidget(self.lvWidget)
373 397
374 def handleClientStack(self, stack): 398 def handleClientStack(self, stack, debuggerId):
375 """ 399 """
376 Public slot to show the call stack of the program being debugged. 400 Public slot to show the call stack of the program being debugged.
377 401
378 @param stack list of tuples with call stack data (file name, 402 @param stack list of tuples with call stack data (file name,
379 line number, function name, formatted argument/values list) 403 line number, function name, formatted argument/values list)
380 """ 404 @type list of tuples of (str, str, str, str)
381 block = self.stackComboBox.blockSignals(True) 405 @param debuggerId ID of the debugger backend
382 self.framenr = 0 406 @type str
383 self.stackComboBox.clear() 407 """
384 self.currentStack = stack 408 if debuggerId == self.__debuggersCombo.currentText():
385 self.sourceButton.setEnabled(len(stack) > 0) 409 block = self.stackComboBox.blockSignals(True)
386 for s in stack: 410 self.framenr = 0
387 # just show base filename to make it readable 411 self.stackComboBox.clear()
388 s = (os.path.basename(s[0]), s[1], s[2]) 412 self.currentStack = stack
389 self.stackComboBox.addItem('{0}:{1}:{2}'.format(*s)) 413 self.sourceButton.setEnabled(len(stack) > 0)
390 self.stackComboBox.blockSignals(block) 414 for s in stack:
391 415 # just show base filename to make it readable
416 s = (os.path.basename(s[0]), s[1], s[2])
417 self.stackComboBox.addItem('{0}:{1}:{2}'.format(*s))
418 self.stackComboBox.blockSignals(block)
419
420 def __clientLine(self, fn, line, debuggerId):
421 """
422 Private method to handle a change to the current line.
423
424 @param fn filename
425 @type str
426 @param line linenumber
427 @type int
428 @param debuggerId ID of the debugger backend
429 @type str
430 """
431 if debuggerId:
432 index = self.__debuggersCombo.findText(debuggerId, Qt.MatchExactly)
433 if index >= 0:
434 self.__debuggersCombo.setItemIcon(
435 index, UI.PixmapCache.getIcon("exceptions.png"))
436
392 def setVariablesFilter(self, globalsFilter, localsFilter): 437 def setVariablesFilter(self, globalsFilter, localsFilter):
393 """ 438 """
394 Public slot to set the local variables filter. 439 Public slot to set the local variables filter.
395 440
396 @param globalsFilter filter list for global variable types 441 @param globalsFilter filter list for global variable types
469 514
470 @param widget reference to the widget (QWidget) 515 @param widget reference to the widget (QWidget)
471 """ 516 """
472 self.__tabWidget.setCurrentWidget(widget) 517 self.__tabWidget.setCurrentWidget(widget)
473 518
474 def showThreadList(self, currentID, threadList): 519 def showThreadList(self, currentID, threadList, debuggerId):
475 """ 520 """
476 Public method to show the thread list. 521 Public method to show the thread list.
477 522
478 @param currentID id of the current thread (integer) 523 @param currentID id of the current thread
524 @type int
479 @param threadList list of dictionaries containing the thread data 525 @param threadList list of dictionaries containing the thread data
480 """ 526 @type list of dict
481 citm = None 527 @param debuggerId ID of the debugger backend
482 528 @type str
483 self.__threadList.clear() 529 """
484 for thread in threadList: 530 debugStatus = -1 # i.e. running
485 if thread.get('except', False): 531
486 state = self.tr("waiting at exception") 532 if debuggerId == self.__debuggersCombo.currentText():
487 icon = "exceptions.png" 533 citm = None
488 elif thread['broken']: 534
489 state = self.tr("waiting at breakpoint") 535 self.__threadList.clear()
490 icon = "mediaPlaybackPause.png" 536 for thread in threadList:
491 else: 537 if thread.get('except', False):
492 state = self.tr("running") 538 state = self.tr("waiting at exception")
493 icon = "mediaPlaybackStart.png" 539 icon = "exceptions.png"
494 itm = QTreeWidgetItem(self.__threadList, 540 debugStatus = 1
495 ["{0:d}".format(thread['id']), 541 elif thread['broken']:
496 thread['name'], state]) 542 state = self.tr("waiting at breakpoint")
497 itm.setIcon(0, UI.PixmapCache.getIcon(icon)) 543 icon = "mediaPlaybackPause.png"
498 if thread['id'] == currentID: 544 if debugStatus < 1:
499 citm = itm 545 debugStatus = 0
500 546 else:
501 self.__threadList.header().resizeSections(QHeaderView.ResizeToContents) 547 state = self.tr("running")
502 self.__threadList.header().setStretchLastSection(True) 548 icon = "mediaPlaybackStart.png"
503 549 itm = QTreeWidgetItem(self.__threadList,
504 if citm: 550 ["{0:d}".format(thread['id']),
505 self.__doThreadListUpdate = False 551 thread['name'], state])
506 self.__threadList.setCurrentItem(citm) 552 itm.setIcon(0, UI.PixmapCache.getIcon(icon))
507 self.__doThreadListUpdate = True 553 if thread['id'] == currentID:
508 554 citm = itm
555
556 self.__threadList.header().resizeSections(
557 QHeaderView.ResizeToContents)
558 self.__threadList.header().setStretchLastSection(True)
559
560 if citm:
561 self.__doThreadListUpdate = False
562 self.__threadList.setCurrentItem(citm)
563 self.__doThreadListUpdate = True
564 else:
565 for thread in threadList:
566 if thread.get('except', False):
567 debugStatus = 1
568 elif thread['broken']:
569 if debugStatus < 1:
570 debugStatus = 0
571
572 if debugStatus == -1:
573 icon = "mediaPlaybackStart.png"
574 elif debugStatus == 0:
575 icon = "mediaPlaybackPause.png"
576 else:
577 icon = "exceptions.png"
578 self.__debuggersCombo.setItemIcon(self.__debuggersCombo.currentIndex(),
579 UI.PixmapCache.getIcon(icon))
580
509 def __threadSelected(self, current, previous): 581 def __threadSelected(self, current, previous):
510 """ 582 """
511 Private slot to handle the selection of a thread in the thread list. 583 Private slot to handle the selection of a thread in the thread list.
512 584
513 @param current reference to the new current item (QTreeWidgetItem) 585 @param current reference to the new current item (QTreeWidgetItem)

eric ide

mercurial