--- a/PluginMetricsRadon.py Fri Sep 18 19:51:37 2015 +0200 +++ b/PluginMetricsRadon.py Sat Sep 19 11:54:33 2015 +0200 @@ -16,6 +16,7 @@ from E5Gui.E5Application import e5App from E5Gui.E5Action import E5Action +from E5Gui import E5MessageBox from Project.ProjectBrowserModel import ProjectBrowserFileItem @@ -260,24 +261,21 @@ """ Private slot to (re)initialize the plugin. """ - self.__projectRawMetricsAct = None self.__projectRawMetricsDialog = None - self.__projectMIAct = None self.__projectMIDialog = None + self.__projectMetricsActs = [] self.__projectSeparatorActs = [] + self.__projectBrowserRawMetricsDialog = None + self.__projectBrowserMIDialog = None self.__projectBrowserMenu = None - self.__projectBrowserRawMetricsAct = None - self.__projectBrowserRawMetricsDialog = None - self.__projectBrowserMIAct = None - self.__projectBrowserMIDialog = None + self.__projectBrowserMetricsActs = [] self.__projectBrowserSeparatorActs = [] self.__editors = [] - self.__editorRawMetricsAct = None self.__editorRawMetricsDialog = None - self.__editorMIAct = None self.__editorMIDialog = None + self.__editorMetricsActs = [] self.__editorSeparatorActs = [] def rawMetrics(self, lang, filename, source): @@ -402,87 +400,106 @@ global error error = "" # clear previous error + # Project menu actions menu = e5App().getObject("Project").getMenu("Show") if menu: if not menu.isEmpty(): act = menu.addSeparator() - # TODO: change this to a 'header' action with bold text - act.setText(self.tr("Radon")) self.__projectSeparatorActs.append(act) - self.__projectRawMetricsAct = E5Action( + # header action + act = QAction(self.tr("Radon"), self) + font = act.font() + font.setBold(True) + act.setFont(font) + act.triggered.connect(self.__showRadonVersion) + menu.addAction(act) + self.__projectMetricsActs.append(act) + + act = E5Action( self.tr('Code Metrics'), self.tr('Code &Metrics...'), 0, 0, self, 'project_show_radon_raw') - self.__projectRawMetricsAct.setStatusTip( + act.setStatusTip( self.tr('Show raw code metrics.')) - self.__projectRawMetricsAct.setWhatsThis(self.tr( + act.setWhatsThis(self.tr( """<b>Code Metrics...</b>""" """<p>This calculates raw code metrics of Python files""" """ and shows the amount of lines of code, logical lines""" """ of code, source lines of code, comment lines,""" """ multi-line strings and blank lines.</p>""" )) - self.__projectRawMetricsAct.triggered.connect( - self.__projectRawMetrics) - menu.addAction(self.__projectRawMetricsAct) + act.triggered.connect(self.__projectRawMetrics) + menu.addAction(act) + self.__projectMetricsActs.append(act) - self.__projectMIAct = E5Action( + act = E5Action( self.tr('Maintainability Index'), self.tr('Maintainability &Index...'), 0, 0, self, 'project_show_radon_mi') - self.__projectMIAct.setStatusTip( + act.setStatusTip( self.tr('Show the maintainability index for Python files.')) - self.__projectMIAct.setWhatsThis(self.tr( + act.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.triggered.connect(self.__projectMaintainabilityIndex) + menu.addAction(act) + self.__projectMetricsActs.append(act) act = menu.addSeparator() self.__projectSeparatorActs.append(act) - e5App().getObject("Project").addE5Actions([ - self.__projectRawMetricsAct, - self.__projectMIAct - ]) + e5App().getObject("Project").addE5Actions( + self.__projectMetricsActs[1:]) - act = QAction("Radon", self) + # Editor menu actions + act = QAction(self) act.setSeparator(True) self.__editorSeparatorActs.append(act) act = QAction(self) act.setSeparator(True) self.__editorSeparatorActs.append(act) - self.__editorRawMetricsAct = E5Action( + # header action + act = QAction(self.tr("Radon"), self) + font = act.font() + font.setBold(True) + act.setFont(font) + act.triggered.connect(self.__showRadonVersion) + menu.addAction(act) + self.__editorMetricsActs.append(act) + + act = E5Action( self.tr('Code Metrics'), self.tr('Code &Metrics...'), 0, 0, self, "") - self.__editorRawMetricsAct.setWhatsThis(self.tr( + act.setStatusTip( + self.tr('Show raw code metrics.')) + act.setWhatsThis(self.tr( """<b>Code Metrics...</b>""" """<p>This calculates raw code metrics of Python files""" """ and shows the amount of lines of code, logical lines""" """ of code, source lines of code, comment lines,""" """ multi-line strings and blank lines.</p>""" )) - self.__editorRawMetricsAct.triggered.connect(self.__editorRawMetrics) + act.triggered.connect(self.__editorRawMetrics) + self.__editorMetricsActs.append(act) - self.__editorMIAct = E5Action( + act = E5Action( self.tr('Maintainability Index'), self.tr('Maintainability &Index...'), 0, 0, self, "") - self.__editorMIAct.setStatusTip( + act.setStatusTip( self.tr('Show the maintainability index for Python files.')) - self.__projectMIAct.setWhatsThis(self.tr( + act.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) + act.triggered.connect(self.__editorMaintainabilityIndex) + self.__editorMetricsActs.append(act) e5App().getObject("Project").showMenu.connect(self.__projectShowMenu) e5App().getObject("ProjectBrowser").getProjectBrowser("sources")\ @@ -514,22 +531,16 @@ if menu: for sep in self.__projectSeparatorActs: menu.removeAction(sep) - menu.removeAction(self.__projectRawMetricsAct) - menu.removeAction(self.__projectMIAct) - e5App().getObject("Project").removeE5Actions([ - self.__projectRawMetricsAct, - self.__projectMIAct - ]) + for act in self.__projectMetricsActs: + menu.removeAction(act) + e5App().getObject("Project").removeE5Actions( + self.__projectMetricsActs[1:]) if self.__projectBrowserMenu: for sep in self.__projectBrowserSeparatorActs: self.__projectBrowserMenu.removeAction(sep) - if self.__projectBrowserRawMetricsAct: - self.__projectBrowserMenu.removeAction( - self.__projectBrowserRawMetricsAct) - if self.__projectBrowserMIAct: - self.__projectBrowserMenu.removeAction( - self.__projectBrowserMIAct) + for act in self.__projectBrowserMetricsActs: + self.__projectBrowserMenu.removeAction(act) for editor in self.__editors: editor.showMenu.disconnect(self.__editorShowMenu) @@ -537,8 +548,8 @@ if menu is not None: for sep in self.__editorSeparatorActs: menu.removeAction(sep) - menu.removeAction(self.__editorRawMetricsAct) - menu.removeAction(self.__editorMIAct) + for act in self.__editorMetricsActs: + menu.removeAction(act) self.__initialize() @@ -573,11 +584,10 @@ @type QMenu """ if menuName == "Show": - for act in [self.__projectRawMetricsAct, self.__projectMIAct]: - if act is not None: - act.setEnabled( - e5App().getObject("Project").getProjectLanguage() in - ["Python3", "Python2", "Python"]) + for act in self.__projectMetricsActs[1:]: + act.setEnabled( + e5App().getObject("Project").getProjectLanguage() in + ["Python3", "Python2", "Python"]) def __projectBrowserShowMenu(self, menuName, menu): """ @@ -592,43 +602,56 @@ ["Python3", "Python2", "Python"]: if self.__projectBrowserMenu is None: self.__projectBrowserMenu = menu + act = menu.addSeparator() - act.setText(self.tr("Radon")) self.__projectBrowserSeparatorActs.append(act) - self.__projectBrowserRawMetricsAct = E5Action( + # header action + act = QAction(self.tr("Radon"), self) + font = act.font() + font.setBold(True) + act.setFont(font) + act.triggered.connect(self.__showRadonVersion) + menu.addAction(act) + self.__projectBrowserMetricsActs.append(act) + + act = E5Action( self.tr('Code Metrics'), self.tr('Code &Metrics...'), 0, 0, self, '') - self.__projectBrowserRawMetricsAct.setStatusTip( + act.setStatusTip( self.tr('Show raw code metrics.')) - self.__projectBrowserRawMetricsAct.setWhatsThis(self.tr( + act.setWhatsThis(self.tr( """<b>Code Metrics...</b>""" """<p>This calculates raw code metrics of Python files""" """ and shows the amount of lines of code, logical lines""" """ of code, source lines of code, comment lines,""" """ multi-line strings and blank lines.</p>""" )) - self.__projectBrowserRawMetricsAct.triggered.connect( - self.__projectBrowserRawMetrics) - menu.addAction(self.__projectBrowserRawMetricsAct) + act.triggered.connect(self.__projectBrowserRawMetrics) + menu.addAction(act) + self.__projectBrowserMetricsActs.append(act) - self.__projectBrowserMIAct = E5Action( + act = E5Action( self.tr('Maintainability Index'), self.tr('Maintainability &Index...'), 0, 0, self, 'project_show_radon_mi') - self.__projectBrowserMIAct.setStatusTip( + act.setStatusTip( self.tr('Show the maintainability index for Python' ' files.')) - self.__projectBrowserMIAct.setWhatsThis(self.tr( + act.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( + act.triggered.connect( self.__projectBrowserMaintainabilityIndex) - menu.addAction(self.__projectBrowserMIAct) + menu.addAction(act) + self.__projectBrowserMetricsActs.append(act) + + act = menu.addSeparator() + self.__projectBrowserSeparatorActs.append(act) def __editorOpened(self, editor): """ @@ -640,8 +663,7 @@ menu = editor.getMenu("Show") if menu is not None: menu.addAction(self.__editorSeparatorActs[0]) - menu.addAction(self.__editorRawMetricsAct) - menu.addAction(self.__editorMIAct) + menu.addActions(self.__editorMetricsActs) menu.addAction(self.__editorSeparatorActs[1]) editor.showMenu.connect(self.__editorShowMenu) self.__editors.append(editor) @@ -668,8 +690,8 @@ """ if menuName == "Show": enable = editor.isPyFile() - self.__editorRawMetricsAct.setEnabled(enable) - self.__editorMIAct.setEnabled(enable) + for act in self.__editorMetricsActs: + act.setEnabled(enable) ################################################################## ## Raw code metrics calculations @@ -790,3 +812,26 @@ self.__editorMIDialog = MaintainabilityIndexDialog(self) self.__editorMIDialog.show() self.__editorMIDialog.start(editor.getFileName()) + + def __showRadonVersion(self): + """ + Private slot to show the version number of the used radon library. + """ + from RadonMetrics.radon import __version__ + E5MessageBox.information( + None, + self.tr("Radon"), + self.tr( + """<p><b>Radon Version {0}</b></p>""" + """<p>Radon is a Python tool that computes various metrics""" + """ from the source code. Radon can compute:""" + """<ul>""" + """<li><b>Raw</b> metrics (these include SLOC, comment""" + """ lines, blank lines, multi line strings, ...)</li>""" + """<li><b>Maintainability Index</b> (the one used in Visual""" + """ Studio)</li>""" + """<li><b>McCabe's complexity</b>, i.e. cyclomatic""" + """ complexity</li>""" + """</ul></p>""" + ).format(__version__)) +