src/eric7/QScintilla/Editor.py

branch
eric7
changeset 9214
bd28e56047d7
parent 9209
b99e7fd55fd3
child 9221
bf71ee032bb4
--- 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()

eric ide

mercurial