diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/DataViews/CodeMetricsDialog.py --- a/src/eric7/DataViews/CodeMetricsDialog.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/DataViews/CodeMetricsDialog.py Wed Jul 13 14:55:47 2022 +0200 @@ -14,8 +14,12 @@ from PyQt6.QtCore import pyqtSlot, Qt, QLocale from PyQt6.QtWidgets import ( - QDialog, QDialogButtonBox, QMenu, QHeaderView, QTreeWidgetItem, - QApplication + QDialog, + QDialogButtonBox, + QMenu, + QHeaderView, + QTreeWidgetItem, + QApplication, ) from EricWidgets.EricApplication import ericApp @@ -30,55 +34,49 @@ """ Class implementing a dialog to display the code metrics. """ + def __init__(self, parent=None): """ Constructor - + @param parent parent widget (QWidget) """ super().__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.WindowType.Window) - - self.buttonBox.button( - QDialogButtonBox.StandardButton.Close).setEnabled(False) - self.buttonBox.button( - QDialogButtonBox.StandardButton.Cancel).setDefault(True) - - self.summaryList.headerItem().setText( - self.summaryList.columnCount(), "") + + self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False) + self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True) + + self.summaryList.headerItem().setText(self.summaryList.columnCount(), "") self.summaryList.header().resizeSection(0, 200) self.summaryList.header().resizeSection(1, 100) - + self.resultList.headerItem().setText(self.resultList.columnCount(), "") - + self.cancelled = False - + self.__menu = QMenu(self) - self.__menu.addAction(self.tr("Collapse All"), - self.__resultCollapse) + self.__menu.addAction(self.tr("Collapse All"), self.__resultCollapse) self.__menu.addAction(self.tr("Expand All"), self.__resultExpand) - self.resultList.setContextMenuPolicy( - Qt.ContextMenuPolicy.CustomContextMenu) - self.resultList.customContextMenuRequested.connect( - self.__showContextMenu) - + self.resultList.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) + self.resultList.customContextMenuRequested.connect(self.__showContextMenu) + self.__fileList = [] self.__project = ericApp().getObject("Project") self.filterFrame.setVisible(False) - + def __resizeResultColumns(self): """ Private method to resize the list columns. """ - self.resultList.header().resizeSections( - QHeaderView.ResizeMode.ResizeToContents) + self.resultList.header().resizeSections(QHeaderView.ResizeMode.ResizeToContents) self.resultList.header().setStretchLastSection(True) - + def __createResultItem(self, parent, values): """ Private slot to create a new item in the result list. - + @param parent parent of the new item (QTreeWidget or QTreeWidgetItem) @param values values to be displayed (list) @return the generated item @@ -91,72 +89,66 @@ data.append(value) itm = QTreeWidgetItem(parent, data) for col in range(1, 7): - itm.setTextAlignment( - col, Qt.AlignmentFlag.AlignRight) + itm.setTextAlignment(col, Qt.AlignmentFlag.AlignRight) return itm - + def __resizeSummaryColumns(self): """ Private method to resize the list columns. """ self.summaryList.header().resizeSections( - QHeaderView.ResizeMode.ResizeToContents) + QHeaderView.ResizeMode.ResizeToContents + ) self.summaryList.header().setStretchLastSection(True) - + def __createSummaryItem(self, col0, col1): """ Private slot to create a new item in the summary list. - + @param col0 string for column 0 (string) @param col1 string for column 1 (string) """ itm = QTreeWidgetItem(self.summaryList, [col0, col1]) itm.setTextAlignment(1, Qt.AlignmentFlag.AlignRight) - + def prepare(self, fileList): """ Public method to prepare the dialog with a list of filenames. - + @param fileList list of filenames @type list of str """ self.__fileList = fileList[:] - - self.buttonBox.button( - QDialogButtonBox.StandardButton.Close).setEnabled(True) - self.buttonBox.button( - QDialogButtonBox.StandardButton.Cancel).setEnabled(False) - self.buttonBox.button( - QDialogButtonBox.StandardButton.Close).setDefault(True) - + + self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True) + self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(False) + self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True) + self.filterFrame.setVisible(True) - + self.__data = self.__project.getData("OTHERTOOLSPARMS", "CodeMetrics") if self.__data is None or "ExcludeFiles" not in self.__data: self.__data = {"ExcludeFiles": ""} self.excludeFilesEdit.setText(self.__data["ExcludeFiles"]) - + def start(self, fn): """ Public slot to start the code metrics determination. - + @param fn file or list of files or directory to show the code metrics for (string or list of strings) """ self.cancelled = False - self.buttonBox.button( - QDialogButtonBox.StandardButton.Close).setEnabled(False) - self.buttonBox.button( - QDialogButtonBox.StandardButton.Cancel).setEnabled(True) - self.buttonBox.button( - QDialogButtonBox.StandardButton.Cancel).setDefault(True) + self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False) + self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(True) + self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True) QApplication.processEvents() - + loc = QLocale() if isinstance(fn, list): files = fn elif os.path.isdir(fn): - files = Utilities.direntries(fn, True, '*.py', False) + files = Utilities.direntries(fn, True, "*.py", False) else: files = [fn] files.sort() @@ -164,40 +156,39 @@ for f in files[:]: if not os.path.exists(f): files.remove(f) - + self.checkProgress.setMaximum(len(files)) QApplication.processEvents() - + total = collections.defaultdict(int) - CodeMetrics.summarize(total, 'files', len(files)) - + CodeMetrics.summarize(total, "files", len(files)) + try: # disable updates of the list for speed self.resultList.setUpdatesEnabled(False) self.resultList.setSortingEnabled(False) - + # now go through all the files now = time.monotonic() for progress, file in enumerate(files, start=1): if self.cancelled: return - + stats = CodeMetrics.analyze(file, total) - - v = self.__getValues(loc, stats, 'TOTAL ') + + v = self.__getValues(loc, stats, "TOTAL ") # make the file name project relative fitm = self.__createResultItem( - self.resultList, - [self.__project.getRelativePath(file)] + v + self.resultList, [self.__project.getRelativePath(file)] + v ) - + identifiers = stats.identifiers for identifier in identifiers: v = self.__getValues(loc, stats, identifier) - + self.__createResultItem(fitm, [identifier] + v) self.resultList.expandItem(fitm) - + self.checkProgress.setValue(progress) if time.monotonic() - now > 0.01: QApplication.processEvents() @@ -207,29 +198,28 @@ self.resultList.setSortingEnabled(True) self.resultList.setUpdatesEnabled(True) self.__resizeResultColumns() - + # now do the summary stuff - self.__createSummaryItem(self.tr("files"), - loc.toString(total['files'])) - self.__createSummaryItem(self.tr("lines"), - loc.toString(total['lines'])) - self.__createSummaryItem(self.tr("bytes"), - loc.toString(total['bytes'])) - self.__createSummaryItem(self.tr("comments"), - loc.toString(total['comments'])) - self.__createSummaryItem(self.tr("comment lines"), - loc.toString(total['commentlines'])) - self.__createSummaryItem(self.tr("empty lines"), - loc.toString(total['empty lines'])) - self.__createSummaryItem(self.tr("non-commentary lines"), - loc.toString(total['non-commentary lines'])) + self.__createSummaryItem(self.tr("files"), loc.toString(total["files"])) + self.__createSummaryItem(self.tr("lines"), loc.toString(total["lines"])) + self.__createSummaryItem(self.tr("bytes"), loc.toString(total["bytes"])) + self.__createSummaryItem(self.tr("comments"), loc.toString(total["comments"])) + self.__createSummaryItem( + self.tr("comment lines"), loc.toString(total["commentlines"]) + ) + self.__createSummaryItem( + self.tr("empty lines"), loc.toString(total["empty lines"]) + ) + self.__createSummaryItem( + self.tr("non-commentary lines"), loc.toString(total["non-commentary lines"]) + ) self.__resizeSummaryColumns() self.__finish() - + def __getValues(self, loc, stats, identifier): """ Private method to extract the code metric values. - + @param loc reference to the locale object (QLocale) @param stats reference to the code metric statistics object @param identifier identifier to get values for @@ -237,85 +227,82 @@ """ counters = stats.counters.get(identifier, {}) v = [] - for key in ('start', 'end', 'lines', 'nloc', 'commentlines', 'empty'): + for key in ("start", "end", "lines", "nloc", "commentlines", "empty"): if counters.get(key, 0): v.append(loc.toString(counters[key])) else: - v.append('') + v.append("") return v - + def __finish(self): """ Private slot called when the action finished or the user pressed the button. """ self.cancelled = True - self.buttonBox.button( - QDialogButtonBox.StandardButton.Close).setEnabled(True) - self.buttonBox.button( - QDialogButtonBox.StandardButton.Cancel).setEnabled(False) - self.buttonBox.button( - QDialogButtonBox.StandardButton.Close).setDefault(True) - + self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True) + self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(False) + self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True) + self.resultList.header().setSectionResizeMode( - QHeaderView.ResizeMode.Interactive) + QHeaderView.ResizeMode.Interactive + ) self.summaryList.header().setSectionResizeMode( - QHeaderView.ResizeMode.Interactive) - + QHeaderView.ResizeMode.Interactive + ) + def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. - + @param button button that was clicked (QAbstractButton) """ - if button == self.buttonBox.button( - QDialogButtonBox.StandardButton.Close - ): + if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Close): self.close() - elif button == self.buttonBox.button( - QDialogButtonBox.StandardButton.Cancel - ): + elif button == self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel): self.__finish() - + @pyqtSlot() def on_startButton_clicked(self): """ Private slot to start a code metrics run. """ fileList = self.__fileList[:] - + filterString = self.excludeFilesEdit.text() - if ("ExcludeFiles" not in self.__data or - filterString != self.__data["ExcludeFiles"]): + if ( + "ExcludeFiles" not in self.__data + or filterString != self.__data["ExcludeFiles"] + ): self.__data["ExcludeFiles"] = filterString - self.__project.setData("OTHERTOOLSPARMS", "CodeMetrics", - self.__data) + self.__project.setData("OTHERTOOLSPARMS", "CodeMetrics", self.__data) filterList = filterString.split(",") if filterList: for filterString in filterList: - fileList = [f for f in fileList - if not fnmatch.fnmatch(f, filterString.strip())] - + fileList = [ + f for f in fileList if not fnmatch.fnmatch(f, filterString.strip()) + ] + self.resultList.clear() self.summaryList.clear() self.start(fileList) - + def __showContextMenu(self, coord): """ Private slot to show the context menu of the listview. - + @param coord the position of the mouse pointer (QPoint) """ if self.resultList.topLevelItemCount() > 0: self.__menu.popup(self.mapToGlobal(coord)) - + def __resultCollapse(self): """ Private slot to collapse all entries of the resultlist. """ for index in range(self.resultList.topLevelItemCount()): self.resultList.topLevelItem(index).setExpanded(False) - + def __resultExpand(self): """ Private slot to expand all entries of the resultlist.