--- a/src/eric7/Debugger/BreakPointViewer.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/Debugger/BreakPointViewer.py Wed Jul 13 14:55:47 2022 +0200 @@ -9,12 +9,8 @@ import pathlib -from PyQt6.QtCore import ( - pyqtSignal, Qt, QItemSelectionModel, QSortFilterProxyModel -) -from PyQt6.QtWidgets import ( - QTreeView, QAbstractItemView, QHeaderView, QMenu, QDialog -) +from PyQt6.QtCore import pyqtSignal, Qt, QItemSelectionModel, QSortFilterProxyModel +from PyQt6.QtWidgets import QTreeView, QAbstractItemView, QHeaderView, QMenu, QDialog from EricWidgets.EricApplication import ericApp @@ -26,71 +22,70 @@ class BreakPointViewer(QTreeView): """ Class implementing the Breakpoint viewer widget. - + Breakpoints will be shown with all their details. They can be modified through the context menu of this widget. - + @signal sourceFile(str, int) emitted to show the source of a breakpoint """ + sourceFile = pyqtSignal(str, int) - + def __init__(self, parent=None): """ Constructor - + @param parent the parent (QWidget) """ super().__init__(parent) self.setObjectName("BreakPointViewer") - + self.__model = None - + self.setItemsExpandable(False) self.setRootIsDecorated(False) self.setAlternatingRowColors(True) - self.setSelectionMode( - QAbstractItemView.SelectionMode.ExtendedSelection) - self.setSelectionBehavior( - QAbstractItemView.SelectionBehavior.SelectRows) - + self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection) + self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows) + self.setWindowTitle(self.tr("Breakpoints")) - + self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.customContextMenuRequested.connect(self.__showContextMenu) self.doubleClicked.connect(self.__doubleClicked) - + self.__createPopupMenus() - + def setModel(self, model): """ Public slot to set the breakpoint model. - + @param model reference to the breakpoint model @type BreakPointModel """ self.__model = model - + self.sortingModel = QSortFilterProxyModel() self.sortingModel.setDynamicSortFilter(True) self.sortingModel.setSourceModel(self.__model) super().setModel(self.sortingModel) - + header = self.header() header.setSortIndicator(0, Qt.SortOrder.AscendingOrder) header.setSortIndicatorShown(True) header.setSectionsClickable(True) - + self.setSortingEnabled(True) - + self.__layoutDisplay() - + def __layoutDisplay(self): """ Private slot to perform a layout operation. """ self.__resizeColumns() self.__resort() - + def __resizeColumns(self): """ Private slot to resize the view when items get added, edited or @@ -98,40 +93,41 @@ """ self.header().resizeSections(QHeaderView.ResizeMode.ResizeToContents) self.header().setStretchLastSection(True) - + def __resort(self): """ Private slot to resort the tree. """ - self.model().sort(self.header().sortIndicatorSection(), - self.header().sortIndicatorOrder()) - + self.model().sort( + self.header().sortIndicatorSection(), self.header().sortIndicatorOrder() + ) + def __toSourceIndex(self, index): """ Private slot to convert an index to a source index. - + @param index index to be converted @type QModelIndex @return mapped index @rtype QModelIndex """ return self.sortingModel.mapToSource(index) - + def __fromSourceIndex(self, sindex): """ Private slot to convert a source index to an index. - + @param sindex source index to be converted @type QModelIndex @return mapped index @rtype QModelIndex """ return self.sortingModel.mapFromSource(sindex) - + def __setRowSelected(self, index, selected=True): """ Private slot to select a complete row. - + @param index index determining the row to be selected @type QModelIndex @param selected flag indicating the action @@ -139,16 +135,20 @@ """ if not index.isValid(): return - + flags = ( - (QItemSelectionModel.SelectionFlag.ClearAndSelect | - QItemSelectionModel.SelectionFlag.Rows) - if selected else - (QItemSelectionModel.SelectionFlag.Deselect | - QItemSelectionModel.SelectionFlag.Rows) + ( + QItemSelectionModel.SelectionFlag.ClearAndSelect + | QItemSelectionModel.SelectionFlag.Rows + ) + if selected + else ( + QItemSelectionModel.SelectionFlag.Deselect + | QItemSelectionModel.SelectionFlag.Rows + ) ) self.selectionModel().select(index, flags) - + def __createPopupMenus(self): """ Private method to generate the popup menus. @@ -161,16 +161,14 @@ self.menu.addAction(self.tr("Enable all"), self.__enableAllBreaks) self.menu.addSeparator() self.menu.addAction(self.tr("Disable"), self.__disableBreak) - self.menu.addAction(self.tr("Disable all"), - self.__disableAllBreaks) + self.menu.addAction(self.tr("Disable all"), self.__disableAllBreaks) self.menu.addSeparator() self.menu.addAction(self.tr("Delete"), self.__deleteBreak) self.menu.addAction(self.tr("Delete all"), self.__deleteAllBreaks) self.menu.addSeparator() self.menu.addAction(self.tr("Goto"), self.__showSource) self.menu.addSeparator() - self.menu.addAction(self.tr("Clear Histories"), - self.clearHistories) + self.menu.addAction(self.tr("Clear Histories"), self.clearHistories) self.menu.addSeparator() self.menu.addAction(self.tr("Configure..."), self.__configure) @@ -178,17 +176,16 @@ self.backMenu = QMenu() self.backMenu.addAction(self.tr("Add"), self.__addBreak) self.backMenuActions["EnableAll"] = self.backMenu.addAction( - self.tr("Enable all"), - self.__enableAllBreaks) + self.tr("Enable all"), self.__enableAllBreaks + ) self.backMenuActions["DisableAll"] = self.backMenu.addAction( - self.tr("Disable all"), - self.__disableAllBreaks) + self.tr("Disable all"), self.__disableAllBreaks + ) self.backMenuActions["DeleteAll"] = self.backMenu.addAction( - self.tr("Delete all"), - self.__deleteAllBreaks) + self.tr("Delete all"), self.__deleteAllBreaks + ) self.backMenu.addSeparator() - self.backMenu.addAction(self.tr("Clear Histories"), - self.clearHistories) + self.backMenu.addAction(self.tr("Clear Histories"), self.clearHistories) self.backMenu.addSeparator() self.backMenu.addAction(self.tr("Configure..."), self.__configure) self.backMenu.aboutToShow.connect(self.__showBackMenu) @@ -196,30 +193,29 @@ self.multiMenu = QMenu() self.multiMenu.addAction(self.tr("Add"), self.__addBreak) self.multiMenu.addSeparator() - self.multiMenu.addAction(self.tr("Enable selected"), - self.__enableSelectedBreaks) - self.multiMenu.addAction(self.tr("Enable all"), - self.__enableAllBreaks) + self.multiMenu.addAction( + self.tr("Enable selected"), self.__enableSelectedBreaks + ) + self.multiMenu.addAction(self.tr("Enable all"), self.__enableAllBreaks) self.multiMenu.addSeparator() - self.multiMenu.addAction(self.tr("Disable selected"), - self.__disableSelectedBreaks) - self.multiMenu.addAction(self.tr("Disable all"), - self.__disableAllBreaks) + self.multiMenu.addAction( + self.tr("Disable selected"), self.__disableSelectedBreaks + ) + self.multiMenu.addAction(self.tr("Disable all"), self.__disableAllBreaks) self.multiMenu.addSeparator() - self.multiMenu.addAction(self.tr("Delete selected"), - self.__deleteSelectedBreaks) - self.multiMenu.addAction(self.tr("Delete all"), - self.__deleteAllBreaks) + self.multiMenu.addAction( + self.tr("Delete selected"), self.__deleteSelectedBreaks + ) + self.multiMenu.addAction(self.tr("Delete all"), self.__deleteAllBreaks) self.multiMenu.addSeparator() - self.multiMenu.addAction(self.tr("Clear Histories"), - self.clearHistories) + self.multiMenu.addAction(self.tr("Clear Histories"), self.clearHistories) self.multiMenu.addSeparator() self.multiMenu.addAction(self.tr("Configure..."), self.__configure) - + def __showContextMenu(self, coord): """ Private slot to show the context menu. - + @param coord the position of the mouse pointer @type QPoint """ @@ -236,47 +232,53 @@ self.menu.popup(coord) else: self.backMenu.popup(coord) - + def __clearSelection(self): """ Private slot to clear the selection. """ for index in self.selectedIndexes(): self.__setRowSelected(index, False) - + def __addBreak(self): """ Private slot to handle the add breakpoint context menu entry. """ from .EditBreakpointDialog import EditBreakpointDialog - + fnHistory, condHistory = self.__loadRecent() - - dlg = EditBreakpointDialog((fnHistory[0], None), None, - condHistory, self, modal=1, - addMode=1, filenameHistory=fnHistory) + + dlg = EditBreakpointDialog( + (fnHistory[0], None), + None, + condHistory, + self, + modal=1, + addMode=1, + filenameHistory=fnHistory, + ) if dlg.exec() == QDialog.DialogCode.Accepted: fn, line, cond, temp, enabled, count = dlg.getAddData() if fn is not None: if fn in fnHistory: fnHistory.remove(fn) fnHistory.insert(0, fn) - + if cond: if cond in condHistory: condHistory.remove(cond) condHistory.insert(0, cond) - + self.__saveRecent(fnHistory, condHistory) - + self.__model.addBreakPoint(fn, line, (cond, temp, enabled, count)) self.__resizeColumns() self.__resort() - + def __doubleClicked(self, index): """ Private slot to handle the double clicked signal. - + @param index index of the entry that was double clicked @type QModelIndex """ @@ -285,7 +287,7 @@ bp = self.__model.getBreakPointByIndex(sindex) if not bp: return - + fn, line = bp[:2] self.sourceFile.emit(fn, line) @@ -296,11 +298,11 @@ index = self.currentIndex() if index.isValid(): self.__editBreakpoint(index) - + def __editBreakpoint(self, index): """ Private slot to edit a breakpoint. - + @param index index of breakpoint to be edited @type QModelIndex """ @@ -309,32 +311,34 @@ bp = self.__model.getBreakPointByIndex(sindex) if not bp: return - + fn, line, cond, temp, enabled, count = bp[:6] fnHistory, condHistory = self.__loadRecent() - + from .EditBreakpointDialog import EditBreakpointDialog + dlg = EditBreakpointDialog( - (fn, line), (cond, temp, enabled, count), - condHistory, self, modal=True) + (fn, line), (cond, temp, enabled, count), condHistory, self, modal=True + ) if dlg.exec() == QDialog.DialogCode.Accepted: cond, temp, enabled, count = dlg.getData() if cond: if cond in condHistory: condHistory.remove(cond) condHistory.insert(0, cond) - + self.__saveRecent(fnHistory, condHistory) - + self.__model.setBreakPointByIndex( - sindex, fn, line, (cond, temp, enabled, count)) + sindex, fn, line, (cond, temp, enabled, count) + ) self.__resizeColumns() self.__resort() def __setBpEnabled(self, index, enabled): """ Private method to set the enabled status of a breakpoint. - + @param index index of breakpoint to be enabled/disabled @type QModelIndex @param enabled flag indicating the enabled status to be set @@ -343,7 +347,7 @@ sindex = self.__toSourceIndex(index) if sindex.isValid(): self.__model.setBreakPointEnabledByIndex(sindex, enabled) - + def __enableBreak(self): """ Private slot to handle the enable breakpoint context menu entry. @@ -414,7 +418,7 @@ sindex = self.__toSourceIndex(index) if sindex.isValid(): self.__model.deleteBreakPointByIndex(sindex) - + def __deleteAllBreaks(self): """ Private slot to handle the delete all breakpoints context menu entry. @@ -442,14 +446,14 @@ bp = self.__model.getBreakPointByIndex(sindex) if not bp: return - + fn, line = bp[:2] self.sourceFile.emit(fn, line) - + def highlightBreakpoint(self, fn, lineno): """ Public slot to handle the clientLine signal. - + @param fn filename of the breakpoint @type str @param lineno line number of the breakpoint @@ -458,18 +462,18 @@ sindex = self.__model.getBreakPointIndex(fn, lineno) if sindex.isValid(): return - + index = self.__fromSourceIndex(sindex) if index.isValid(): self.__clearSelection() self.__setRowSelected(index, True) - + def handleResetUI(self): """ Public slot to reset the breakpoint viewer. """ self.__clearSelection() - + def __showBackMenu(self): """ Private slot to handle the aboutToShow signal of the background menu. @@ -486,57 +490,54 @@ def __getSelectedItemsCount(self): """ Private method to get the count of items selected. - + @return count of items selected @rtype int """ count = len(self.selectedIndexes()) // (self.__model.columnCount() - 1) # column count is 1 greater than selectable return count - + def __configure(self): """ Private method to open the configuration dialog. """ - ericApp().getObject("UserInterface").showPreferences( - "debuggerGeneralPage") - + ericApp().getObject("UserInterface").showPreferences("debuggerGeneralPage") + def __loadRecent(self): """ Private method to load the recently used file names and breakpoint conditions. - + @return tuple containing the recently used file names and breakpoint conditions @rtype tuple of (list of str, list of str) """ Preferences.Prefs.rsettings.sync() - + # load recently used file names fnHistory = [] - fnHistory.append('') + fnHistory.append("") rs = Preferences.Prefs.rsettings.value(recentNameBreakpointFiles) if rs is not None: - recent = [f - for f in Preferences.toList(rs) - if pathlib.Path(f).exists()] - fnHistory.extend( - recent[:Preferences.getDebugger("RecentNumber")]) - + recent = [f for f in Preferences.toList(rs) if pathlib.Path(f).exists()] + fnHistory.extend(recent[: Preferences.getDebugger("RecentNumber")]) + # load recently entered condition expressions condHistory = [] rs = Preferences.Prefs.rsettings.value(recentNameBreakpointConditions) if rs is not None: condHistory = Preferences.toList(rs)[ - :Preferences.getDebugger("RecentNumber")] - + : Preferences.getDebugger("RecentNumber") + ] + return fnHistory, condHistory - + def __saveRecent(self, fnHistory, condHistory): """ Private method to save the list of recently used file names and breakpoint conditions. - + @param fnHistory list of recently used file names @type list of str @param condHistory list of recently used breakpoint conditions @@ -544,10 +545,11 @@ """ recent = [f for f in fnHistory if f] Preferences.Prefs.rsettings.setValue(recentNameBreakpointFiles, recent) - Preferences.Prefs.rsettings.setValue(recentNameBreakpointConditions, - condHistory) + Preferences.Prefs.rsettings.setValue( + recentNameBreakpointConditions, condHistory + ) Preferences.Prefs.rsettings.sync() - + def clearHistories(self): """ Public method to clear the recently used file names and breakpoint