RadonMetrics/RawMetricsDialog.py

changeset 5
db25d1d5cc3a
parent 4
9ac53bf21182
child 7
3eb5fb0ae72c
--- a/RadonMetrics/RawMetricsDialog.py	Tue Sep 15 19:22:38 2015 +0200
+++ b/RadonMetrics/RawMetricsDialog.py	Wed Sep 16 18:51:27 2015 +0200
@@ -9,13 +9,18 @@
 
 from __future__ import unicode_literals
 
+try:
+    str = unicode       # __IGNORE_EXCEPTION __IGNORE_WARNING__
+except NameError:
+    pass
+
 import os
 import fnmatch
 
-from PyQt5.QtCore import pyqtSlot, qVersion, Qt, QTimer
+from PyQt5.QtCore import pyqtSlot, qVersion, Qt, QTimer, QLocale
 from PyQt5.QtWidgets import (
-    QDialog, QDialogButtonBox, QAbstractButton, QMenu, QHeaderView,
-    QTreeWidgetItem, QApplication
+    QDialog, QDialogButtonBox, QAbstractButton, QHeaderView, QTreeWidgetItem,
+    QApplication
 )
 
 from .Ui_RawMetricsDialog import Ui_RawMetricsDialog
@@ -25,8 +30,6 @@
 import Preferences
 import Utilities
 
-# TODO: add summary table
-# TODO: add column explanations
 class RawMetricsDialog(QDialog, Ui_RawMetricsDialog):
     """
     Class implementing a dialog to show raw code metrics.
@@ -47,6 +50,11 @@
         self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
         self.buttonBox.button(QDialogButtonBox.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.radonService = radonService
@@ -57,17 +65,29 @@
         self.cancelled = False
         
         self.__project = e5App().getObject("Project")
-        
-        self.__menu = QMenu(self)
-        self.__menu.addAction(self.tr("Collapse all"),
-                              self.__resultCollapse)
-        self.__menu.addAction(self.tr("Expand all"), self.__resultExpand)
-        self.resultList.setContextMenuPolicy(Qt.CustomContextMenu)
-        self.resultList.customContextMenuRequested.connect(
-            self.__showContextMenu)
+        self.__locale = QLocale()
         
         self.__fileList = []
         self.filterFrame.setVisible(False)
+        
+        self.explanationLabel.setText(self.tr(
+            "<table>"
+            "<tr><td><b>LOC</b></td>"
+            "<td>Lines of code (LOC = SLOC + Empty)</td></tr>"
+            "<tr><td><b>SLOC</b></td><td>Source lines of code</td></tr>"
+            "<tr><td><b>LLOC</b></td><td>Logical lines of code</td></tr>"
+            "<tr><td><b>Comments</b></td><td>Comment lines</td></tr>"
+            "<tr><td><b>Multi</b></td>"
+            "<td>Lines in multi line strings</td></tr>"
+            "<tr><td><b>Empty</b></td><td>Blank lines</td></tr>"
+            "<tr><td colspan=2><b>Comment Statistics:</b></td</tr>"
+            "<tr><td><b>C % L</b></td><td>Comments to lines ratio</td></tr>"
+            "<tr><td><b>C % S</b></td>"
+            "<td>Comments to source lines ratio</td></tr>"
+            "<tr><td><b>C + M % L</b></td>"
+            "<td>Comments plus multi line strings to lines ratio</td></tr>"
+            "</table>"
+        ))
     
     def __resizeResultColumns(self):
         """
@@ -86,13 +106,11 @@
         @type dict
         """
         data = [self.__project.getRelativePath(filename)]
-        for key in ['loc', 'sloc', 'lloc', 'comments', 'multi', 'blank']:
+        for value in self.__getValues(values):
             try:
-                data.append("{0:5}".format(int(values[key])))
+                data.append("{0:5}".format(int(value)))
             except ValueError:
-                data.append(values[key])
-            except KeyError:
-                data.append("")
+                data.append(value)
         data.append("{0:3.0%}".format(
             values["comments"] / (float(values["loc"]) or 1)))
         data.append("{0:3.0%}".format(
@@ -113,7 +131,13 @@
         @param message error message
         @type str
         """
-        # TODO: implement this
+        itm = QTreeWidgetItem(self.resultList, [
+            "{0} ({1})".format(self.__project.getRelativePath(filename),
+                               message)])
+        itm.setFirstColumnSpanned(True)
+        font = itm.font(0)
+        font.setItalic(True)
+        itm.setFont(0, font)
     
     def prepare(self, fileList, project):
         """
@@ -169,6 +193,10 @@
             if not os.path.exists(f):
                 self.files.remove(f)
         
+        self.__summary = {"files": 0}
+        for key in ['loc', 'sloc', 'lloc', 'comments', 'multi', 'blank']:
+            self.__summary[key] = 0
+        
         if len(self.files) > 0:
             # disable updates of the list for speed
             self.resultList.setUpdatesEnabled(False)
@@ -217,10 +245,7 @@
             self.source = Utilities.readEncodedFile(self.filename)[0]
             self.source = Utilities.normalizeCode(self.source)
         except (UnicodeError, IOError) as msg:
-            # TODO: adjust this
-            self.__createResultItem(
-                self.filename, 1,
-                "Error: {0}".format(str(msg)).rstrip())
+            self.__createErrorItem(self.filename, str(msg).rstrip())
             self.progress += 1
             # Continue with next file
             self.rawMetrics()
@@ -251,10 +276,7 @@
                 source = Utilities.readEncodedFile(filename)[0]
                 source = Utilities.normalizeCode(source)
             except (UnicodeError, IOError) as msg:
-                # TODO: adjust this
-                self.__createResultItem(
-                    filename, 1,
-                    "Error: {0}".format(str(msg)).rstrip())
+                self.__createErrorItem(filename, str(msg).rstrip())
                 continue
             
             argumentsList.append((filename, source))
@@ -276,8 +298,15 @@
         self.__finish()
     
     def __processError(self, fn, msg):
-        # TODO: implement this
-        print("Error", fn, msg)
+        """
+        Private slot to process an error indication from the service.
+        
+        @param fn filename of the file
+        @type str
+        @param msg error message
+        @type str
+        """
+        self.__createErrorItem(fn, msg)
     
     def __processResult(self, fn, result):
         """
@@ -310,7 +339,27 @@
         
         if not self.__batch:
             self.rawMetrics()
-
+    
+    def __getValues(self, result):
+        """
+        Private method to extract the code metric values.
+        
+        @param result result dict
+        @type dict
+        @return list of values suitable for display
+        @rtype list of str
+        """
+        v = []
+        for key in ['loc', 'sloc', 'lloc', 'comments', 'multi', 'blank']:
+            val = result.get(key, 0)
+            if val:
+                v.append(self.__locale.toString(val))
+            else:
+                v.append('')
+            self.__summary[key] += int(val)
+        self.__summary["files"] += 1
+        return v
+    
     def __finish(self):
         """
         Private slot called when the action or the user pressed the button.
@@ -322,6 +371,8 @@
             self.resultList.setSortingEnabled(True)
             self.resultList.setUpdatesEnabled(True)
             
+            self.__createSummary()
+            
             self.cancelled = True
             self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
             self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
@@ -339,6 +390,39 @@
             self.checkProgress.setVisible(False)
             self.checkProgressLabel.setVisible(False)
     
+    def __createSummary(self):
+        """
+        Private method to create the code metrics summary.
+        """
+        self.__createSummaryItem(
+            self.tr("Files"), self.__locale.toString(self.__summary["files"]))
+        self.__createSummaryItem(
+            self.tr("LOC"), self.__locale.toString(self.__summary["loc"]))
+        self.__createSummaryItem(
+            self.tr("SLOC"), self.__locale.toString(self.__summary["sloc"]))
+        self.__createSummaryItem(
+            self.tr("LLOC"), self.__locale.toString(self.__summary["lloc"]))
+        self.__createSummaryItem(
+            self.tr("Comments"),
+            self.__locale.toString(self.__summary["comments"]))
+        self.__createSummaryItem(
+            self.tr("Multi"), self.__locale.toString(self.__summary["multi"]))
+        self.__createSummaryItem(
+            self.tr("Empty"), self.__locale.toString(self.__summary["blank"]))
+        
+        self.summaryList.header().resizeSections(QHeaderView.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.Alignment(Qt.AlignRight))
+    
     @pyqtSlot(QAbstractButton)
     def on_buttonBox_clicked(self, button):
         """
@@ -379,27 +463,3 @@
         self.resultList.clear()
         self.cancelled = False
         self.start(fileList)
-    
-    def __showContextMenu(self, coord):
-        """
-        Private slot to show the context menu of the result list.
-        
-        @param coord position of the mouse pointer
-        @type QPoint
-        """
-        if self.resultList.topLevelItemCount() > 0:
-            self.__menu.popup(self.mapToGlobal(coord))
-    
-    def __resultCollapse(self):
-        """
-        Private slot to collapse all entries of the result list.
-        """
-        for index in range(self.resultList.topLevelItemCount()):
-            self.resultList.topLevelItem(index).setExpanded(False)
-    
-    def __resultExpand(self):
-        """
-        Private slot to expand all entries of the result list.
-        """
-        for index in range(self.resultList.topLevelItemCount()):
-            self.resultList.topLevelItem(index).setExpanded(True)

eric ide

mercurial