--- a/src/eric7/Project/ProjectSourcesBrowser.py Mon Jul 11 16:09:04 2022 +0200 +++ b/src/eric7/Project/ProjectSourcesBrowser.py Mon Jul 11 16:42:50 2022 +0200 @@ -30,6 +30,8 @@ import Utilities import UI.PixmapCache +from CodeFormatting.BlackFormattingAction import BlackFormattingAction + class ProjectSourcesBrowser(ProjectBaseBrowser): """ @@ -118,6 +120,21 @@ self.checksMenu = QMenu(self.tr('Check')) self.checksMenu.aboutToShow.connect(self.__showContextMenuCheck) + self.formattingMenu = QMenu(self.tr("Code Formatting")) + self.formattingMenu.addAction( + self.tr("Format Code"), + lambda: self.__performFormatWithBlack(BlackFormattingAction.Format) + ) + self.formattingMenu.addAction( + self.tr("Check Formatting"), + lambda: self.__performFormatWithBlack(BlackFormattingAction.Check) + ) + self.formattingMenu.addAction( + self.tr("Formatting Diff"), + lambda: self.__performFormatWithBlack(BlackFormattingAction.Diff) + ) + self.formattingMenu.aboutToShow.connect(self.__showContextMenuFormatting) + self.menuShow = QMenu(self.tr('Show')) self.menuShow.addAction( self.tr('Code metrics...'), self.__showCodeMetrics) @@ -181,10 +198,9 @@ self.sourceMenu.addAction( self.tr('Add source directory...'), self.__addSourceDirectory) self.sourceMenu.addSeparator() - act = self.sourceMenu.addMenu(self.graphicsMenu) - self.sourceMenu.addSeparator() + self.sourceMenu.addMenu(self.graphicsMenu) self.sourceMenu.addMenu(self.checksMenu) - self.sourceMenu.addSeparator() + self.sourceMenu.addMenu(self.formattingMenu) self.sourceMenuActions["Show"] = self.sourceMenu.addMenu(self.menuShow) self.sourceMenu.addSeparator() self.__startAct = self.sourceMenu.addMenu(self.__startMenu) @@ -262,6 +278,7 @@ self.multiMenuActions.append(act) self.multiMenu.addSeparator() self.multiMenu.addMenu(self.checksMenu) + self.multiMenu.addMenu(self.formattingMenu) self.multiMenu.addSeparator() self.multiMenu.addAction( self.tr('Expand all directories'), self._expandAllDirs) @@ -286,7 +303,6 @@ self.tr('Add source directory...'), self.__addSourceDirectory) self.dirMenu.addSeparator() act = self.dirMenu.addMenu(self.graphicsMenu) - self.dirMenu.addSeparator() self.dirMenu.addMenu(self.checksMenu) self.dirMenu.addSeparator() self.dirMenu.addAction( @@ -1175,3 +1191,54 @@ """ fn = self.model().item(self.currentIndex()).fileName() ericApp().getObject("DebugUI").doCoverage(False, script=fn) + + ########################################################################### + ## Methods for the Code Formatting submenu + ########################################################################### + + def __showContextMenuFormatting(self): + """ + Private slot called before the Code Formatting menu is shown. + """ + self.showMenu.emit("Formatting", self.formattingMenu) + + def __performFormatWithBlack(self, action): + """ + Private method to format the selected project sources using the 'Black' tool. + + Following actions are supported. + <ul> + <li>BlackFormattingAction.Format - the code reformatting is performed</li> + <li>BlackFormattingAction.Check - a check is performed, if code formatting + is necessary</li> + <li>BlackFormattingAction.Diff - a unified diff of potential code formatting + changes is generated</li> + </ul> + + @param action formatting operation to be performed + @type BlackFormattingAction + """ + from CodeFormatting.BlackConfigurationDialog import BlackConfigurationDialog + from CodeFormatting.BlackFormattingDialog import BlackFormattingDialog + + files = [ + itm.fileName() + for itm in self.getSelectedItems( + [BrowserFileItem, BrowserClassItem, BrowserMethodItem, + BrowserClassAttributeItem, BrowserImportItem] + ) + if itm.isPython3File() + ] + + if ericApp().getObject("ViewManager").checkAllDirty(): + dlg = BlackConfigurationDialog(withProject=True) + if dlg.exec() == QDialog.DialogCode.Accepted: + config = dlg.getConfiguration() + + formattingDialog = BlackFormattingDialog( + config, + files, + project=self.project, + action=action + ) + formattingDialog.exec()