PluginMetricsRadon.py

changeset 6
13e9698a9981
parent 4
9ac53bf21182
child 9
7f6e04213998
--- a/PluginMetricsRadon.py	Wed Sep 16 18:51:27 2015 +0200
+++ b/PluginMetricsRadon.py	Wed Sep 16 19:36:25 2015 +0200
@@ -173,16 +173,22 @@
         """
         self.__projectRawMetricsAct = None
         self.__projectRawMetricsDialog = None
+        self.__projectMIAct = None
+        self.__projectMIDialog = None
         self.__projectSeparatorActs = []
         
         self.__projectBrowserMenu = None
         self.__projectBrowserRawMetricsAct = None
         self.__projectBrowserRawMetricsDialog = None
+        self.__projectBrowserMIAct = None
+        self.__projectBrowserMIDialog = None
         self.__projectBrowserSeparatorActs = []
         
         self.__editors = []
         self.__editorRawMetricsAct = None
         self.__editorRawMetricsDialog = None
+        self.__editorMIAct = None
+        self.__editorMIDialog = None
         self.__editorSeparatorActs = []
 
     def rawMetrics(self, lang, filename, source):
@@ -240,6 +246,62 @@
         """
         for lang in ['Python2', 'Python3']:
             self.backgroundService.requestCancel('batch_radon', lang)
+
+    def maintainabilityIndex(self, lang, filename, source):
+        """
+        Public method to prepare maintainability index calculation on one
+        Python source file.
+
+        @param lang language of the file or None to determine by internal
+            algorithm
+        @type str or None
+        @param filename source filename
+        @type str
+        @param source string containing the code
+        @type str
+        """
+        if lang is None:
+            lang = 'Python{0}'.format(determinePythonVersion(filename, source))
+        if lang not in ['Python2', 'Python3']:
+            return
+        
+        self.backgroundService.enqueueRequest(
+            'radon', lang, filename, [source, 'mi'])
+
+    def maintainabilityIndexBatch(self, argumentsList):
+        """
+        Public method to prepare maintainability index calculation on multiple
+        Python source files.
+        
+        @param argumentsList list of arguments tuples with each tuple
+            containing filename and source
+        @type (str, str)
+        """
+        data = {
+            "Python2": [],
+            "Python3": [],
+        }
+        for filename, source in argumentsList:
+            lang = 'Python{0}'.format(determinePythonVersion(filename, source))
+            if lang not in ['Python2', 'Python3']:
+                continue
+            else:
+                data[lang].append((filename, source, 'mi'))
+        
+        self.queuedBatches = []
+        for lang in ['Python2', 'Python3']:
+            if data[lang]:
+                self.queuedBatches.append(lang)
+                self.backgroundService.enqueueRequest('batch_radon', lang, "",
+                                                      data[lang])
+                self.batchesFinished = False
+    
+    def cancelMaintainabilityIndexBatch(self):
+        """
+        Public method to cancel all batch jobs.
+        """
+        for lang in ['Python2', 'Python3']:
+            self.backgroundService.requestCancel('batch_radon', lang)
     
     def activate(self):
         """
@@ -257,6 +319,7 @@
                 act = menu.addSeparator()
                 act.setText(self.tr("Radon"))
                 self.__projectSeparatorActs.append(act)
+            
             self.__projectRawMetricsAct = E5Action(
                 self.tr('Code Metrics'),
                 self.tr('Code &Metrics...'), 0, 0,
@@ -273,11 +336,28 @@
             self.__projectRawMetricsAct.triggered.connect(
                 self.__projectRawMetrics)
             menu.addAction(self.__projectRawMetricsAct)
+            
+            self.__projectMIAct = E5Action(
+                self.tr('Maintainability Index'),
+                self.tr('Maintainability &Index...'), 0, 0,
+                self, 'project_show_radon_mi')
+            self.__projectMIAct.setStatusTip(
+                self.tr('Show the maintainability index for Python files.'))
+            self.__projectMIAct.setWhatsThis(self.tr(
+                """<b>Maintainability Index...</b>"""
+                """<p>This calculates the maintainability index of Python"""
+                """ files and shows it together with a ranking.</p>"""
+            ))
+            self.__projectMIAct.triggered.connect(
+                self.__projectMaintainabilityIndex)
+            menu.addAction(self.__projectMIAct)
+            
             act = menu.addSeparator()
             self.__projectSeparatorActs.append(act)
             
             e5App().getObject("Project").addE5Actions([
                 self.__projectRawMetricsAct,
+                self.__projectMIAct
             ])
         
         act = QAction("Radon", self)
@@ -300,6 +380,20 @@
         ))
         self.__editorRawMetricsAct.triggered.connect(self.__editorRawMetrics)
         
+        self.__editorMIAct = E5Action(
+            self.tr('Maintainability Index'),
+            self.tr('Maintainability &Index...'), 0, 0,
+            self, "")
+        self.__editorMIAct.setStatusTip(
+            self.tr('Show the maintainability index for Python files.'))
+        self.__projectMIAct.setWhatsThis(self.tr(
+            """<b>Maintainability Index...</b>"""
+            """<p>This calculates the maintainability index of Python"""
+            """ files and shows it together with a ranking.</p>"""
+        ))
+        self.__editorMIAct.triggered.connect(
+            self.__editorMaintainabilityIndex)
+        
         e5App().getObject("Project").showMenu.connect(self.__projectShowMenu)
         e5App().getObject("ProjectBrowser").getProjectBrowser("sources")\
             .showMenu.connect(self.__projectBrowserShowMenu)
@@ -331,8 +425,11 @@
             for sep in self.__projectSeparatorActs:
                 menu.removeAction(sep)
             menu.removeAction(self.__projectRawMetricsAct)
-            e5App().getObject("Project").removeE5Actions(
-                [self.__projectRawMetricsAct])
+            menu.removeAction(self.__projectMIAct)
+            e5App().getObject("Project").removeE5Actions([
+                self.__projectRawMetricsAct,
+                self.__projectMIAct
+            ])
         
         if self.__projectBrowserMenu:
             for sep in self.__projectBrowserSeparatorActs:
@@ -340,6 +437,9 @@
             if self.__projectBrowserRawMetricsAct:
                 self.__projectBrowserMenu.removeAction(
                     self.__projectBrowserRawMetricsAct)
+            if self.__projectBrowserMIAct:
+                self.__projectBrowserMenu.removeAction(
+                    self.__projectBrowserMIAct)
         
         for editor in self.__editors:
             editor.showMenu.disconnect(self.__editorShowMenu)
@@ -348,6 +448,7 @@
                 for sep in self.__editorSeparatorActs:
                     menu.removeAction(sep)
                 menu.removeAction(self.__editorRawMetricsAct)
+                menu.removeAction(self.__editorMIAct)
         
         self.__initialize()
     
@@ -382,7 +483,7 @@
         @type QMenu
         """
         if menuName == "Show":
-            for act in [self.__projectRawMetricsAct]:
+            for act in [self.__projectRawMetricsAct, self.__projectMIAct]:
                 if act is not None:
                     act.setEnabled(
                         e5App().getObject("Project").getProjectLanguage() in
@@ -421,47 +522,23 @@
                 self.__projectBrowserRawMetricsAct.triggered.connect(
                     self.__projectBrowserRawMetrics)
                 menu.addAction(self.__projectBrowserRawMetricsAct)
-    
-    def __projectRawMetrics(self):
-        """
-        Private slot used to calculate raw code metrics for the project.
-        """
-        project = e5App().getObject("Project")
-        project.saveAllScripts()
-        ppath = project.getProjectPath()
-        files = [os.path.join(ppath, file)
-                 for file in project.pdata["SOURCES"]
-                 if file.endswith(
-                     tuple(Preferences.getPython("Python3Extensions")) +
-                     tuple(Preferences.getPython("PythonExtensions")))]
-        
-        from RadonMetrics.RawMetricsDialog import RawMetricsDialog
-        self.__projectRawMetricsDialog = RawMetricsDialog(self)
-        self.__projectRawMetricsDialog.show()
-        self.__projectRawMetricsDialog.prepare(files, project)
-    
-    def __projectBrowserRawMetrics(self):
-        """
-        Private method to handle the tabnanny context menu action of the
-        project sources browser.
-        """
-        browser = e5App().getObject("ProjectBrowser").getProjectBrowser(
-            "sources")
-        if browser.getSelectedItemsCount([ProjectBrowserFileItem]) > 1:
-            fn = []
-            for itm in browser.getSelectedItems([ProjectBrowserFileItem]):
-                fn.append(itm.fileName())
-        else:
-            itm = browser.model().item(browser.currentIndex())
-            try:
-                fn = itm.fileName()
-            except AttributeError:
-                fn = itm.dirName()
-        
-        from RadonMetrics.RawMetricsDialog import RawMetricsDialog
-        self.__projectBrowserRawMetricsDialog = RawMetricsDialog(self)
-        self.__projectBrowserRawMetricsDialog.show()
-        self.__projectBrowserRawMetricsDialog.start(fn)
+                
+                self.__projectBrowserMIAct = E5Action(
+                    self.tr('Maintainability Index'),
+                    self.tr('Maintainability &Index...'), 0, 0,
+                    self, 'project_show_radon_mi')
+                self.__projectBrowserMIAct.setStatusTip(
+                    self.tr('Show the maintainability index for Python'
+                            ' files.'))
+                self.__projectBrowserMIAct.setWhatsThis(self.tr(
+                    """<b>Maintainability Index...</b>"""
+                    """<p>This calculates the maintainability index of"""
+                    """ Python files and shows it together with a ranking."""
+                    """</p>"""
+                ))
+                self.__projectBrowserMIAct.triggered.connect(
+                    self.__projectBrowserMaintainabilityIndex)
+                menu.addAction(self.__projectBrowserMIAct)
     
     def __editorOpened(self, editor):
         """
@@ -474,6 +551,7 @@
         if menu is not None:
             menu.addAction(self.__editorSeparatorActs[0])
             menu.addAction(self.__editorRawMetricsAct)
+            menu.addAction(self.__editorMIAct)
             menu.addAction(self.__editorSeparatorActs[1])
             editor.showMenu.connect(self.__editorShowMenu)
             self.__editors.append(editor)
@@ -499,7 +577,54 @@
         @param editor reference to the editor
         """
         if menuName == "Show":
-            self.__editorRawMetricsAct.setEnabled(editor.isPyFile())
+            enable = editor.isPyFile()
+            self.__editorRawMetricsAct.setEnabled(enable)
+            self.__editorMIAct.setEnabled(enable)
+    
+    ##################################################################
+    ## Raw code metrics calculations
+    ##################################################################
+    
+    def __projectRawMetrics(self):
+        """
+        Private slot used to calculate raw code metrics for the project.
+        """
+        project = e5App().getObject("Project")
+        project.saveAllScripts()
+        ppath = project.getProjectPath()
+        files = [os.path.join(ppath, file)
+                 for file in project.pdata["SOURCES"]
+                 if file.endswith(
+                     tuple(Preferences.getPython("Python3Extensions")) +
+                     tuple(Preferences.getPython("PythonExtensions")))]
+        
+        from RadonMetrics.RawMetricsDialog import RawMetricsDialog
+        self.__projectRawMetricsDialog = RawMetricsDialog(self)
+        self.__projectRawMetricsDialog.show()
+        self.__projectRawMetricsDialog.prepare(files, project)
+    
+    def __projectBrowserRawMetrics(self):
+        """
+        Private method to handle the code metrics context menu action of the
+        project sources browser.
+        """
+        browser = e5App().getObject("ProjectBrowser").getProjectBrowser(
+            "sources")
+        if browser.getSelectedItemsCount([ProjectBrowserFileItem]) > 1:
+            fn = []
+            for itm in browser.getSelectedItems([ProjectBrowserFileItem]):
+                fn.append(itm.fileName())
+        else:
+            itm = browser.model().item(browser.currentIndex())
+            try:
+                fn = itm.fileName()
+            except AttributeError:
+                fn = itm.dirName()
+        
+        from RadonMetrics.RawMetricsDialog import RawMetricsDialog
+        self.__projectBrowserRawMetricsDialog = RawMetricsDialog(self)
+        self.__projectBrowserRawMetricsDialog.show()
+        self.__projectBrowserRawMetricsDialog.start(fn)
     
     def __editorRawMetrics(self):
         """
@@ -513,3 +638,65 @@
                 self.__editorRawMetricsDialog = RawMetricsDialog(self)
                 self.__editorRawMetricsDialog.show()
                 self.__editorRawMetricsDialog.start(editor.getFileName())
+    
+    ##################################################################
+    ## Maintainability index calculations
+    ##################################################################
+    
+    def __projectMaintainabilityIndex(self):
+        """
+        Private slot used to calculate the maintainability indexes for the
+        project.
+        """
+        project = e5App().getObject("Project")
+        project.saveAllScripts()
+        ppath = project.getProjectPath()
+        files = [os.path.join(ppath, file)
+                 for file in project.pdata["SOURCES"]
+                 if file.endswith(
+                     tuple(Preferences.getPython("Python3Extensions")) +
+                     tuple(Preferences.getPython("PythonExtensions")))]
+        
+        from RadonMetrics.MaintainabilityIndexDialog import \
+            MaintainabilityIndexDialog
+        self.__projectMIDialog = MaintainabilityIndexDialog(self)
+        self.__projectMIDialog.show()
+        self.__projectMIDialog.prepare(files, project)
+    
+    def __projectBrowserMaintainabilityIndex(self):
+        """
+        Private method to handle the maintainability index context menu action
+        of the project sources browser.
+        """
+        browser = e5App().getObject("ProjectBrowser").getProjectBrowser(
+            "sources")
+        if browser.getSelectedItemsCount([ProjectBrowserFileItem]) > 1:
+            fn = []
+            for itm in browser.getSelectedItems([ProjectBrowserFileItem]):
+                fn.append(itm.fileName())
+        else:
+            itm = browser.model().item(browser.currentIndex())
+            try:
+                fn = itm.fileName()
+            except AttributeError:
+                fn = itm.dirName()
+        
+        from RadonMetrics.MaintainabilityIndexDialog import \
+            MaintainabilityIndexDialog
+        self.__projectBrowserMIDialog = MaintainabilityIndexDialog(self)
+        self.__projectBrowserMIDialog.show()
+        self.__projectBrowserMIDialog.start(fn)
+    
+    def __editorMaintainabilityIndex(self):
+        """
+        Private slot to handle the maintainability index action of the editor
+        show menu.
+        """
+        editor = e5App().getObject("ViewManager").activeWindow()
+        if editor is not None:
+            if editor.checkDirty() and editor.getFileName() is not None:
+                from RadonMetrics.MaintainabilityIndexDialog import \
+                    MaintainabilityIndexDialog
+                self.__editorMIDialog = MaintainabilityIndexDialog(self)
+                self.__editorMIDialog.show()
+                self.__editorMIDialog.start(editor.getFileName())

eric ide

mercurial