--- a/src/eric7/QScintilla/Editor.py Mon Jul 11 16:09:04 2022 +0200 +++ b/src/eric7/QScintilla/Editor.py Mon Jul 11 16:42:50 2022 +0200 @@ -48,6 +48,8 @@ from UI import PythonDisViewer +from CodeFormatting.BlackFormattingAction import BlackFormattingAction + EditorAutoCompletionListID = 1 TemplateCompletionListID = 2 ReferencesListID = 3 @@ -816,10 +818,12 @@ self.menuShow = self.__initContextMenuShow() self.graphicsMenu = self.__initContextMenuGraphics() self.autocompletionMenu = self.__initContextMenuAutocompletion() + self.codeFormattingMenu = self.__initContextMenuFormatting() self.__menus["Checks"] = self.checksMenu self.__menus["Show"] = self.menuShow self.__menus["Graphics"] = self.graphicsMenu self.__menus["Autocompletion"] = self.autocompletionMenu + self.__menus["Formatting"] = self.codeFormattingMenu self.toolsMenu = self.__initContextMenuTools() self.__menus["Tools"] = self.toolsMenu self.eolMenu = self.__initContextMenuEol() @@ -917,9 +921,8 @@ self.menu.addMenu(self.resourcesMenu) else: self.menuActs["Check"] = self.menu.addMenu(self.checksMenu) - self.menu.addSeparator() + self.menuActs["Formatting"] = self.menu.addMenu(self.codeFormattingMenu) self.menuActs["Show"] = self.menu.addMenu(self.menuShow) - self.menu.addSeparator() self.menuActs["Diagrams"] = self.menu.addMenu(self.graphicsMenu) self.menu.addSeparator() self.menuActs["Tools"] = self.menu.addMenu(self.toolsMenu) @@ -992,6 +995,32 @@ menu.aboutToShow.connect(self.__showContextMenuChecks) return menu + def __initContextMenuFormatting(self): + """ + Private method used to setup the Code Formatting context sub menu. + + @return reference to the generated menu + @rtype QMenu + """ + menu = QMenu(self.tr("Code Formatting")) + + menu.addAction( + self.tr("Format Code"), + lambda: self.__performFormatWithBlack(BlackFormattingAction.Format) + ) + menu.addAction( + self.tr("Check Formatting"), + lambda: self.__performFormatWithBlack(BlackFormattingAction.Check) + ) + menu.addAction( + self.tr("Formatting Diff"), + lambda: self.__performFormatWithBlack(BlackFormattingAction.Diff) + ) + + menu.aboutToShow.connect(self.__showContextMenuFormatting) + + return menu + def __initContextMenuTools(self): """ Private method used to setup the Tools context sub menu. @@ -5799,7 +5828,14 @@ menu. """ self.showMenu.emit("Tools", self.toolsMenu, self) - + + def __showContextMenuFormatting(self): + """ + Private slot handling the aboutToShow signal of the code formatting context + menu. + """ + self.showMenu.emit("Formatting", self.codeFormattingMenu, self) + def __reopenWithEncodingMenuTriggered(self, act): """ Private method to handle the rereading of the file with a selected @@ -8874,7 +8910,12 @@ @param y y-value of mouse screen position @type int """ - if not self.isCallTipActive() and not self.isListActive(): + if ( + not self.isCallTipActive() + and not self.isListActive() + and not self.menu.isVisible() + and not self.spellingMenu.isVisible() + ): if self.__mouseHoverHelp is not None and pos > 0 and y > 0: line, index = self.lineIndexFromPosition(pos) if index > 0: @@ -8934,3 +8975,44 @@ self.__showingMouseHoverHelp = True else: self.__cancelMouseHoverHelp() + + ####################################################################### + ## Methods implementing the Black code formatting interface + ####################################################################### + + def __performFormatWithBlack(self, action): + """ + Private method to format the source code 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 + + if not self.isModified() or self.saveFile(): + withProject = ( + self.fileName and + self.project.isOpen() and + self.project.isProjectSource(self.fileName) + ) + dlg = BlackConfigurationDialog(withProject=withProject) + if dlg.exec() == QDialog.DialogCode.Accepted: + config = dlg.getConfiguration() + + formattingDialog = BlackFormattingDialog( + config, + [self.fileName], + project=self.project, + action=action + ) + formattingDialog.exec()