src/eric7/Project/ProjectFormsBrowser.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9387
ce743c468d09
--- a/src/eric7/Project/ProjectFormsBrowser.py	Wed Jul 13 11:16:20 2022 +0200
+++ b/src/eric7/Project/ProjectFormsBrowser.py	Wed Jul 13 14:55:47 2022 +0200
@@ -21,8 +21,10 @@
 from EricWidgets.EricProgressDialog import EricProgressDialog
 
 from .ProjectBrowserModel import (
-    ProjectBrowserFileItem, ProjectBrowserSimpleDirectoryItem,
-    ProjectBrowserDirectoryItem, ProjectBrowserFormType
+    ProjectBrowserFileItem,
+    ProjectBrowserSimpleDirectoryItem,
+    ProjectBrowserDirectoryItem,
+    ProjectBrowserFormType,
 )
 from .ProjectBaseBrowser import ProjectBaseBrowser
 
@@ -39,7 +41,7 @@
 class ProjectFormsBrowser(ProjectBaseBrowser):
     """
     A class used to display the forms part of the project.
-    
+
     @signal appendStderr(str) emitted after something was received from
         a QProcess on stderr
     @signal uipreview(str) emitted to preview a forms file
@@ -48,46 +50,62 @@
     @signal menusAboutToBeCreated() emitted when the context menus are about to
         be created. This is the right moment to add or remove hook methods.
     """
+
     appendStderr = pyqtSignal(str)
     uipreview = pyqtSignal(str)
     showMenu = pyqtSignal(str, QMenu)
     menusAboutToBeCreated = pyqtSignal()
-    
+
     Pyuic5IndentDefault = 4
     Pyuic6IndentDefault = 4
-    
+
     def __init__(self, project, parent=None):
         """
         Constructor
-        
+
         @param project reference to the project object
         @param parent parent widget of this browser (QWidget)
         """
-        ProjectBaseBrowser.__init__(self, project, ProjectBrowserFormType,
-                                    parent)
-        
-        self.selectedItemsFilter = [ProjectBrowserFileItem,
-                                    ProjectBrowserSimpleDirectoryItem]
-        
-        self.setWindowTitle(self.tr('Forms'))
+        ProjectBaseBrowser.__init__(self, project, ProjectBrowserFormType, parent)
+
+        self.selectedItemsFilter = [
+            ProjectBrowserFileItem,
+            ProjectBrowserSimpleDirectoryItem,
+        ]
+
+        self.setWindowTitle(self.tr("Forms"))
 
-        self.setWhatsThis(self.tr(
-            """<b>Project Forms Browser</b>"""
-            """<p>This allows to easily see all forms contained in the"""
-            """ current project. Several actions can be executed via the"""
-            """ context menu.</p>"""
-        ))
-        
+        self.setWhatsThis(
+            self.tr(
+                """<b>Project Forms Browser</b>"""
+                """<p>This allows to easily see all forms contained in the"""
+                """ current project. Several actions can be executed via the"""
+                """ context menu.</p>"""
+            )
+        )
+
         # templates for Qt
         # these two lists have to stay in sync
         self.templates4 = [
-            'dialog4.tmpl', 'widget4.tmpl', 'mainwindow4.tmpl',
-            'dialogbuttonboxbottom4.tmpl', 'dialogbuttonboxright4.tmpl',
-            'dialogbuttonsbottom4.tmpl', 'dialogbuttonsbottomcenter4.tmpl',
-            'dialogbuttonsright4.tmpl', '', 'wizard4.tmpl', 'wizardpage4.tmpl',
-            'qdockwidget4.tmpl', 'qframe4.tmpl', 'qgroupbox4.tmpl',
-            'qscrollarea4.tmpl', 'qmdiarea4.tmpl', 'qtabwidget4.tmpl',
-            'qtoolbox4.tmpl', 'qstackedwidget4.tmpl'
+            "dialog4.tmpl",
+            "widget4.tmpl",
+            "mainwindow4.tmpl",
+            "dialogbuttonboxbottom4.tmpl",
+            "dialogbuttonboxright4.tmpl",
+            "dialogbuttonsbottom4.tmpl",
+            "dialogbuttonsbottomcenter4.tmpl",
+            "dialogbuttonsright4.tmpl",
+            "",
+            "wizard4.tmpl",
+            "wizardpage4.tmpl",
+            "qdockwidget4.tmpl",
+            "qframe4.tmpl",
+            "qgroupbox4.tmpl",
+            "qscrollarea4.tmpl",
+            "qmdiarea4.tmpl",
+            "qtabwidget4.tmpl",
+            "qtoolbox4.tmpl",
+            "qstackedwidget4.tmpl",
         ]
         self.templateTypes4 = [
             self.tr("Dialog"),
@@ -98,7 +116,7 @@
             self.tr("Dialog with Buttons (Bottom)"),
             self.tr("Dialog with Buttons (Bottom-Center)"),
             self.tr("Dialog with Buttons (Right)"),
-            '',
+            "",
             self.tr("QWizard"),
             self.tr("QWizardPage"),
             self.tr("QDockWidget"),
@@ -110,13 +128,13 @@
             self.tr("QToolBox"),
             self.tr("QStackedWidget"),
         ]
-        
+
         self.compileProc = None
         self.__uicompiler = ""
-        
+
         self.project.projectClosed.connect(self.__resetUiCompiler)
         self.project.projectPropertiesChanged.connect(self.__resetUiCompiler)
-        
+
     def _createPopupMenus(self):
         """
         Protected overloaded method to generate the popup menu.
@@ -125,286 +143,274 @@
         self.multiMenuActions = []
         self.dirMenuActions = []
         self.dirMultiMenuActions = []
-        
+
         self.menusAboutToBeCreated.emit()
-        
+
         projectType = self.project.getProjectType()
-        
+
         self.menu = QMenu(self)
         if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]:
-            self.menu.addAction(
-                self.tr('Compile form'), self.__compileForm)
+            self.menu.addAction(self.tr("Compile form"), self.__compileForm)
+            self.menu.addAction(self.tr("Compile all forms"), self.__compileAllForms)
             self.menu.addAction(
-                self.tr('Compile all forms'),
-                self.__compileAllForms)
-            self.menu.addAction(
-                self.tr('Generate Dialog Code...'),
-                self.__generateDialogCode)
+                self.tr("Generate Dialog Code..."), self.__generateDialogCode
+            )
             self.menu.addSeparator()
             self.__pyuicConfigAct = self.menu.addAction(
-                self.tr('Configure uic Compiler'),
-                self.__configureUicCompiler)
+                self.tr("Configure uic Compiler"), self.__configureUicCompiler
+            )
             self.menu.addSeparator()
-            self.menu.addAction(
-                self.tr('Open in Qt-Designer'), self.__openFile)
-            self.menu.addAction(
-                self.tr('Open in Editor'), self.__openFileInEditor)
+            self.menu.addAction(self.tr("Open in Qt-Designer"), self.__openFile)
+            self.menu.addAction(self.tr("Open in Editor"), self.__openFileInEditor)
             self.menu.addSeparator()
-            self.menu.addAction(self.tr('Preview form'), self.__UIPreview)
-            self.menu.addAction(
-                self.tr('Preview translations'), self.__TRPreview)
+            self.menu.addAction(self.tr("Preview form"), self.__UIPreview)
+            self.menu.addAction(self.tr("Preview translations"), self.__TRPreview)
         else:
             if self.hooks["compileForm"] is not None:
                 self.menu.addAction(
-                    self.hooksMenuEntries.get(
-                        "compileForm",
-                        self.tr('Compile form')), self.__compileForm)
+                    self.hooksMenuEntries.get("compileForm", self.tr("Compile form")),
+                    self.__compileForm,
+                )
             if self.hooks["compileAllForms"] is not None:
                 self.menu.addAction(
                     self.hooksMenuEntries.get(
-                        "compileAllForms",
-                        self.tr('Compile all forms')),
-                    self.__compileAllForms)
+                        "compileAllForms", self.tr("Compile all forms")
+                    ),
+                    self.__compileAllForms,
+                )
             if self.hooks["generateDialogCode"] is not None:
                 self.menu.addAction(
                     self.hooksMenuEntries.get(
-                        "generateDialogCode",
-                        self.tr('Generate Dialog Code...')),
-                    self.__generateDialogCode)
+                        "generateDialogCode", self.tr("Generate Dialog Code...")
+                    ),
+                    self.__generateDialogCode,
+                )
             if (
-                self.hooks["compileForm"] is not None or
-                self.hooks["compileAllForms"] is not None or
-                self.hooks["generateDialogCode"] is not None
+                self.hooks["compileForm"] is not None
+                or self.hooks["compileAllForms"] is not None
+                or self.hooks["generateDialogCode"] is not None
             ):
                 self.menu.addSeparator()
             if self.hooks["open"] is not None:
                 self.menu.addAction(
-                    self.hooksMenuEntries.get("open", self.tr('Open')),
-                    self.__openFile)
-            self.menu.addAction(self.tr('Open'), self.__openFileInEditor)
+                    self.hooksMenuEntries.get("open", self.tr("Open")), self.__openFile
+                )
+            self.menu.addAction(self.tr("Open"), self.__openFileInEditor)
         self.menu.addSeparator()
-        act = self.menu.addAction(self.tr('Rename file'), self._renameFile)
+        act = self.menu.addAction(self.tr("Rename file"), self._renameFile)
         self.menuActions.append(act)
-        act = self.menu.addAction(
-            self.tr('Remove from project'), self._removeFile)
+        act = self.menu.addAction(self.tr("Remove from project"), self._removeFile)
         self.menuActions.append(act)
-        act = self.menu.addAction(self.tr('Delete'), self.__deleteFile)
+        act = self.menu.addAction(self.tr("Delete"), self.__deleteFile)
         self.menuActions.append(act)
         self.menu.addSeparator()
         if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]:
-            self.menu.addAction(self.tr('New form...'), self.__newForm)
+            self.menu.addAction(self.tr("New form..."), self.__newForm)
         else:
             if self.hooks["newForm"] is not None:
                 self.menu.addAction(
-                    self.hooksMenuEntries.get(
-                        "newForm", self.tr('New form...')), self.__newForm)
-        self.menu.addAction(self.tr('Add forms...'), self.__addFormFiles)
-        self.menu.addAction(
-            self.tr('Add forms directory...'), self.__addFormsDirectory)
+                    self.hooksMenuEntries.get("newForm", self.tr("New form...")),
+                    self.__newForm,
+                )
+        self.menu.addAction(self.tr("Add forms..."), self.__addFormFiles)
+        self.menu.addAction(self.tr("Add forms directory..."), self.__addFormsDirectory)
         self.menu.addSeparator()
-        self.menu.addAction(
-            self.tr('Copy Path to Clipboard'), self._copyToClipboard)
+        self.menu.addAction(self.tr("Copy Path to Clipboard"), self._copyToClipboard)
         self.menu.addSeparator()
-        self.menu.addAction(
-            self.tr('Expand all directories'), self._expandAllDirs)
-        self.menu.addAction(
-            self.tr('Collapse all directories'), self._collapseAllDirs)
+        self.menu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
+        self.menu.addAction(self.tr("Collapse all directories"), self._collapseAllDirs)
         self.menu.addSeparator()
-        self.menu.addAction(self.tr('Configure...'), self._configure)
+        self.menu.addAction(self.tr("Configure..."), self._configure)
 
         self.backMenu = QMenu(self)
         if (
-            projectType in [
-                "PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"
-            ] or self.hooks["compileAllForms"] is not None
+            projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]
+            or self.hooks["compileAllForms"] is not None
         ):
             self.backMenu.addAction(
-                self.tr('Compile all forms'), self.__compileAllForms)
+                self.tr("Compile all forms"), self.__compileAllForms
+            )
             self.backMenu.addSeparator()
             self.__pyuicBackConfigAct = self.backMenu.addAction(
-                self.tr('Configure uic Compiler'),
-                self.__configureUicCompiler)
+                self.tr("Configure uic Compiler"), self.__configureUicCompiler
+            )
             self.backMenu.addSeparator()
-            self.backMenu.addAction(self.tr('New form...'), self.__newForm)
+            self.backMenu.addAction(self.tr("New form..."), self.__newForm)
         else:
             if self.hooks["newForm"] is not None:
                 self.backMenu.addAction(
-                    self.hooksMenuEntries.get(
-                        "newForm", self.tr('New form...')), self.__newForm)
+                    self.hooksMenuEntries.get("newForm", self.tr("New form...")),
+                    self.__newForm,
+                )
+        self.backMenu.addAction(self.tr("Add forms..."), self.project.addUiFiles)
         self.backMenu.addAction(
-            self.tr('Add forms...'), self.project.addUiFiles)
-        self.backMenu.addAction(
-            self.tr('Add forms directory...'), self.project.addUiDir)
+            self.tr("Add forms directory..."), self.project.addUiDir
+        )
         self.backMenu.addSeparator()
-        self.backMenu.addAction(
-            self.tr('Expand all directories'), self._expandAllDirs)
+        self.backMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
         self.backMenu.addAction(
-            self.tr('Collapse all directories'), self._collapseAllDirs)
+            self.tr("Collapse all directories"), self._collapseAllDirs
+        )
         self.backMenu.addSeparator()
-        self.backMenu.addAction(self.tr('Configure...'), self._configure)
+        self.backMenu.addAction(self.tr("Configure..."), self._configure)
         self.backMenu.setEnabled(False)
 
         # create the menu for multiple selected files
         self.multiMenu = QMenu(self)
         if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]:
             self.multiMenu.addAction(
-                self.tr('Compile forms'), self.__compileSelectedForms)
+                self.tr("Compile forms"), self.__compileSelectedForms
+            )
             self.multiMenu.addSeparator()
             self.__pyuicMultiConfigAct = self.multiMenu.addAction(
-                self.tr('Configure uic Compiler'),
-                self.__configureUicCompiler)
+                self.tr("Configure uic Compiler"), self.__configureUicCompiler
+            )
             self.multiMenu.addSeparator()
-            self.multiMenu.addAction(
-                self.tr('Open in Qt-Designer'), self.__openFile)
-            self.multiMenu.addAction(
-                self.tr('Open in Editor'), self.__openFileInEditor)
+            self.multiMenu.addAction(self.tr("Open in Qt-Designer"), self.__openFile)
+            self.multiMenu.addAction(self.tr("Open in Editor"), self.__openFileInEditor)
             self.multiMenu.addSeparator()
-            self.multiMenu.addAction(
-                self.tr('Preview translations'), self.__TRPreview)
+            self.multiMenu.addAction(self.tr("Preview translations"), self.__TRPreview)
         else:
             if self.hooks["compileSelectedForms"] is not None:
                 act = self.multiMenu.addAction(
                     self.hooksMenuEntries.get(
-                        "compileSelectedForms",
-                        self.tr('Compile forms')),
-                    self.__compileSelectedForms)
+                        "compileSelectedForms", self.tr("Compile forms")
+                    ),
+                    self.__compileSelectedForms,
+                )
                 self.multiMenu.addSeparator()
             if self.hooks["open"] is not None:
                 self.multiMenu.addAction(
-                    self.hooksMenuEntries.get("open", self.tr('Open')),
-                    self.__openFile)
-            self.multiMenu.addAction(
-                self.tr('Open'), self.__openFileInEditor)
+                    self.hooksMenuEntries.get("open", self.tr("Open")), self.__openFile
+                )
+            self.multiMenu.addAction(self.tr("Open"), self.__openFileInEditor)
         self.multiMenu.addSeparator()
-        act = self.multiMenu.addAction(
-            self.tr('Remove from project'), self._removeFile)
+        act = self.multiMenu.addAction(self.tr("Remove from project"), self._removeFile)
         self.multiMenuActions.append(act)
-        act = self.multiMenu.addAction(
-            self.tr('Delete'), self.__deleteFile)
+        act = self.multiMenu.addAction(self.tr("Delete"), self.__deleteFile)
         self.multiMenuActions.append(act)
         self.multiMenu.addSeparator()
-        self.multiMenu.addAction(
-            self.tr('Expand all directories'), self._expandAllDirs)
+        self.multiMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
         self.multiMenu.addAction(
-            self.tr('Collapse all directories'), self._collapseAllDirs)
+            self.tr("Collapse all directories"), self._collapseAllDirs
+        )
         self.multiMenu.addSeparator()
-        self.multiMenu.addAction(self.tr('Configure...'), self._configure)
+        self.multiMenu.addAction(self.tr("Configure..."), self._configure)
 
         self.dirMenu = QMenu(self)
         if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]:
-            self.dirMenu.addAction(
-                self.tr('Compile all forms'), self.__compileAllForms)
+            self.dirMenu.addAction(self.tr("Compile all forms"), self.__compileAllForms)
             self.dirMenu.addSeparator()
             self.__pyuicDirConfigAct = self.dirMenu.addAction(
-                self.tr('Configure uic Compiler'),
-                self.__configureUicCompiler)
+                self.tr("Configure uic Compiler"), self.__configureUicCompiler
+            )
             self.dirMenu.addSeparator()
         else:
             if self.hooks["compileAllForms"] is not None:
                 self.dirMenu.addAction(
                     self.hooksMenuEntries.get(
-                        "compileAllForms",
-                        self.tr('Compile all forms')),
-                    self.__compileAllForms)
+                        "compileAllForms", self.tr("Compile all forms")
+                    ),
+                    self.__compileAllForms,
+                )
                 self.dirMenu.addSeparator()
-        act = self.dirMenu.addAction(
-            self.tr('Remove from project'), self._removeDir)
+        act = self.dirMenu.addAction(self.tr("Remove from project"), self._removeDir)
         self.dirMenuActions.append(act)
-        act = self.dirMenu.addAction(
-            self.tr('Delete'), self._deleteDirectory)
+        act = self.dirMenu.addAction(self.tr("Delete"), self._deleteDirectory)
         self.dirMenuActions.append(act)
         self.dirMenu.addSeparator()
         if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]:
-            self.dirMenu.addAction(self.tr('New form...'), self.__newForm)
+            self.dirMenu.addAction(self.tr("New form..."), self.__newForm)
         else:
             if self.hooks["newForm"] is not None:
                 self.dirMenu.addAction(
-                    self.hooksMenuEntries.get(
-                        "newForm",
-                        self.tr('New form...')), self.__newForm)
-        self.dirMenu.addAction(
-            self.tr('Add forms...'), self.__addFormFiles)
-        self.dirMenu.addAction(
-            self.tr('Add forms directory...'), self.__addFormsDirectory)
-        self.dirMenu.addSeparator()
+                    self.hooksMenuEntries.get("newForm", self.tr("New form...")),
+                    self.__newForm,
+                )
+        self.dirMenu.addAction(self.tr("Add forms..."), self.__addFormFiles)
         self.dirMenu.addAction(
-            self.tr('Copy Path to Clipboard'), self._copyToClipboard)
+            self.tr("Add forms directory..."), self.__addFormsDirectory
+        )
         self.dirMenu.addSeparator()
-        self.dirMenu.addAction(
-            self.tr('Expand all directories'), self._expandAllDirs)
+        self.dirMenu.addAction(self.tr("Copy Path to Clipboard"), self._copyToClipboard)
+        self.dirMenu.addSeparator()
+        self.dirMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
         self.dirMenu.addAction(
-            self.tr('Collapse all directories'), self._collapseAllDirs)
+            self.tr("Collapse all directories"), self._collapseAllDirs
+        )
         self.dirMenu.addSeparator()
-        self.dirMenu.addAction(self.tr('Configure...'), self._configure)
-        
+        self.dirMenu.addAction(self.tr("Configure..."), self._configure)
+
         self.dirMultiMenu = QMenu(self)
         if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]:
             self.dirMultiMenu.addAction(
-                self.tr('Compile all forms'), self.__compileAllForms)
+                self.tr("Compile all forms"), self.__compileAllForms
+            )
             self.dirMultiMenu.addSeparator()
             self.__pyuicDirMultiConfigAct = self.dirMultiMenu.addAction(
-                self.tr('Configure uic Compiler'),
-                self.__configureUicCompiler)
+                self.tr("Configure uic Compiler"), self.__configureUicCompiler
+            )
             self.dirMultiMenu.addSeparator()
         else:
             if self.hooks["compileAllForms"] is not None:
                 self.dirMultiMenu.addAction(
                     self.hooksMenuEntries.get(
-                        "compileAllForms",
-                        self.tr('Compile all forms')),
-                    self.__compileAllForms)
+                        "compileAllForms", self.tr("Compile all forms")
+                    ),
+                    self.__compileAllForms,
+                )
                 self.dirMultiMenu.addSeparator()
+        self.dirMultiMenu.addAction(self.tr("Add forms..."), self.project.addUiFiles)
         self.dirMultiMenu.addAction(
-            self.tr('Add forms...'), self.project.addUiFiles)
-        self.dirMultiMenu.addAction(
-            self.tr('Add forms directory...'), self.project.addUiDir)
+            self.tr("Add forms directory..."), self.project.addUiDir
+        )
         self.dirMultiMenu.addSeparator()
         self.dirMultiMenu.addAction(
-            self.tr('Expand all directories'), self._expandAllDirs)
+            self.tr("Expand all directories"), self._expandAllDirs
+        )
         self.dirMultiMenu.addAction(
-            self.tr('Collapse all directories'), self._collapseAllDirs)
+            self.tr("Collapse all directories"), self._collapseAllDirs
+        )
         self.dirMultiMenu.addSeparator()
-        self.dirMultiMenu.addAction(
-            self.tr('Configure...'), self._configure)
-        
+        self.dirMultiMenu.addAction(self.tr("Configure..."), self._configure)
+
         self.menu.aboutToShow.connect(self.__showContextMenu)
         self.multiMenu.aboutToShow.connect(self.__showContextMenuMulti)
         self.dirMenu.aboutToShow.connect(self.__showContextMenuDir)
         self.dirMultiMenu.aboutToShow.connect(self.__showContextMenuDirMulti)
         self.backMenu.aboutToShow.connect(self.__showContextMenuBack)
         self.mainMenu = self.menu
-        
+
     def _contextMenuRequested(self, coord):
         """
         Protected slot to show the context menu.
-        
+
         @param coord the position of the mouse pointer (QPoint)
         """
         if not self.project.isOpen():
             return
-        
-        enable = (
-            self.project.getProjectType() in ("PyQt5", "PyQt6", "E7Plugin")
-        )
+
+        enable = self.project.getProjectType() in ("PyQt5", "PyQt6", "E7Plugin")
         self.__pyuicConfigAct.setEnabled(enable)
         self.__pyuicMultiConfigAct.setEnabled(enable)
         self.__pyuicDirConfigAct.setEnabled(enable)
         self.__pyuicDirMultiConfigAct.setEnabled(enable)
         self.__pyuicBackConfigAct.setEnabled(enable)
-        
+
         with contextlib.suppress(Exception):
             categories = self.getSelectedItemsCountCategorized(
-                [ProjectBrowserFileItem, ProjectBrowserSimpleDirectoryItem])
+                [ProjectBrowserFileItem, ProjectBrowserSimpleDirectoryItem]
+            )
             cnt = categories["sum"]
             if cnt <= 1:
                 index = self.indexAt(coord)
                 if index.isValid():
                     self._selectSingleItem(index)
                     categories = self.getSelectedItemsCountCategorized(
-                        [ProjectBrowserFileItem,
-                         ProjectBrowserSimpleDirectoryItem])
+                        [ProjectBrowserFileItem, ProjectBrowserSimpleDirectoryItem]
+                    )
                     cnt = categories["sum"]
-            
+
             bfcnt = categories[str(ProjectBrowserFileItem)]
             sdcnt = categories[str(ProjectBrowserSimpleDirectoryItem)]
             if cnt > 1 and cnt == bfcnt:
@@ -422,47 +428,47 @@
                         self.backMenu.popup(self.mapToGlobal(coord))
                 else:
                     self.backMenu.popup(self.mapToGlobal(coord))
-        
+
     def __showContextMenu(self):
         """
         Private slot called by the menu aboutToShow signal.
         """
         ProjectBaseBrowser._showContextMenu(self, self.menu)
-        
+
         self.showMenu.emit("Main", self.menu)
-        
+
     def __showContextMenuMulti(self):
         """
         Private slot called by the multiMenu aboutToShow signal.
         """
         ProjectBaseBrowser._showContextMenuMulti(self, self.multiMenu)
-        
+
         self.showMenu.emit("MainMulti", self.multiMenu)
-        
+
     def __showContextMenuDir(self):
         """
         Private slot called by the dirMenu aboutToShow signal.
         """
         ProjectBaseBrowser._showContextMenuDir(self, self.dirMenu)
-        
+
         self.showMenu.emit("MainDir", self.dirMenu)
-        
+
     def __showContextMenuDirMulti(self):
         """
         Private slot called by the dirMultiMenu aboutToShow signal.
         """
         ProjectBaseBrowser._showContextMenuDirMulti(self, self.dirMultiMenu)
-        
+
         self.showMenu.emit("MainDirMulti", self.dirMultiMenu)
-        
+
     def __showContextMenuBack(self):
         """
         Private slot called by the backMenu aboutToShow signal.
         """
         ProjectBaseBrowser._showContextMenuBack(self, self.backMenu)
-        
+
         self.showMenu.emit("MainBack", self.backMenu)
-        
+
     def __addFormFiles(self):
         """
         Private method to add form files to the project.
@@ -471,14 +477,13 @@
         if isinstance(itm, ProjectBrowserFileItem):
             dn = os.path.dirname(itm.fileName())
         elif isinstance(
-            itm,
-            (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem)
+            itm, (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem)
         ):
             dn = itm.dirName()
         else:
             dn = None
-        self.project.addFiles('form', dn)
-        
+        self.project.addFiles("form", dn)
+
     def __addFormsDirectory(self):
         """
         Private method to add form files of a directory to the project.
@@ -487,14 +492,13 @@
         if isinstance(itm, ProjectBrowserFileItem):
             dn = os.path.dirname(itm.fileName())
         elif isinstance(
-            itm,
-            (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem)
+            itm, (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem)
         ):
             dn = itm.dirName()
         else:
             dn = None
-        self.project.addDirectory('form', dn)
-        
+        self.project.addDirectory("form", dn)
+
     def __openFile(self):
         """
         Private slot to handle the Open menu action.
@@ -508,7 +512,7 @@
                         self.hooks["open"](itm.fileName())
                     else:
                         self.designerFile.emit(itm.fileName())
-        
+
     def __openFileInEditor(self):
         """
         Private slot to handle the Open in Editor menu action.
@@ -516,7 +520,7 @@
         itmList = self.getSelectedItems()
         for itm in itmList[:]:
             self.sourceFile.emit(itm.fileName())
-        
+
     def _openItem(self):
         """
         Protected slot to handle the open popup menu entry.
@@ -528,14 +532,14 @@
                     self.designerFile.emit(itm.fileName())
                 else:
                     self.sourceFile.emit(itm.fileName())
-        
+
     def __UIPreview(self):
         """
         Private slot to handle the Preview menu action.
         """
         itmList = self.getSelectedItems()
         self.uipreview.emit(itmList[0].fileName())
-        
+
     def __TRPreview(self):
         """
         Private slot to handle the Preview translations action.
@@ -544,11 +548,15 @@
         for itm in self.getSelectedItems():
             fileNames.append(itm.fileName())
         trfiles = sorted(self.project.pdata["TRANSLATIONS"][:])
-        fileNames.extend([os.path.join(self.project.ppath, trfile)
-                          for trfile in trfiles
-                          if trfile.endswith('.qm')])
+        fileNames.extend(
+            [
+                os.path.join(self.project.ppath, trfile)
+                for trfile in trfiles
+                if trfile.endswith(".qm")
+            ]
+        )
         self.trpreview[list].emit(fileNames)
-        
+
     def __newForm(self):
         """
         Private slot to handle the New Form menu action.
@@ -564,20 +572,24 @@
                     path = itm.dirName()
                 except AttributeError:
                     path = os.path.join(self.project.ppath, itm.data(0))
-        
+
         if self.hooks["newForm"] is not None:
             self.hooks["newForm"](path)
         else:
             if self.project.getProjectType() in [
-                "PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"
+                "PyQt5",
+                "PyQt6",
+                "E7Plugin",
+                "PySide2",
+                "PySide6",
             ]:
                 self.__newUiForm(path)
-        
+
     def __newUiForm(self, path):
         """
         Private slot to handle the New Form menu action for Qt-related
         projects.
-        
+
         @param path full directory path for the new form file (string)
         """
         selectedForm, ok = QInputDialog.getItem(
@@ -585,27 +597,31 @@
             self.tr("New Form"),
             self.tr("Select a form type:"),
             self.templateTypes4,
-            0, False)
+            0,
+            False,
+        )
         if not ok or not selectedForm:
             # user pressed cancel
             return
-        
+
         templateIndex = self.templateTypes4.index(selectedForm)
         templateFile = os.path.join(
-            getConfig('ericTemplatesDir'), self.templates4[templateIndex])
-        
+            getConfig("ericTemplatesDir"), self.templates4[templateIndex]
+        )
+
         fname, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
             self,
             self.tr("New Form"),
             path,
             self.tr("Qt User-Interface Files (*.ui);;All Files (*)"),
             "",
-            EricFileDialog.DontConfirmOverwrite)
-        
+            EricFileDialog.DontConfirmOverwrite,
+        )
+
         if not fname:
             # user aborted or didn't enter a filename
             return
-        
+
         fpath = pathlib.Path(fname)
         if not fpath.suffix:
             ex = selectedFilter.split("(*")[1].split(")")[0]
@@ -616,11 +632,12 @@
                 self,
                 self.tr("New Form"),
                 self.tr("The file already exists! Overwrite it?"),
-                icon=EricMessageBox.Warning)
+                icon=EricMessageBox.Warning,
+            )
             if not res:
                 # user selected to not overwrite
                 return
-        
+
         try:
             shutil.copy(templateFile, fpath)
         except OSError as err:
@@ -629,18 +646,20 @@
                 self.tr("New Form"),
                 self.tr(
                     "<p>The new form file <b>{0}</b> could not be created.<br>"
-                    "Problem: {1}</p>").format(fpath, str(err)))
+                    "Problem: {1}</p>"
+                ).format(fpath, str(err)),
+            )
             return
-        
+
         self.project.appendFile(str(fpath))
         self.designerFile.emit(str(fpath))
-        
+
     def __deleteFile(self):
         """
         Private method to delete a form file from the project.
         """
         itmList = self.getSelectedItems()
-        
+
         files = []
         fullNames = []
         for itm in itmList:
@@ -648,64 +667,65 @@
             fullNames.append(fn2)
             fn = self.project.getRelativePath(fn2)
             files.append(fn)
-        
-        from UI.DeleteFilesConfirmationDialog import (
-            DeleteFilesConfirmationDialog
-        )
+
+        from UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
+
         dlg = DeleteFilesConfirmationDialog(
             self.parent(),
             self.tr("Delete forms"),
-            self.tr(
-                "Do you really want to delete these forms from the project?"),
-            files)
-        
+            self.tr("Do you really want to delete these forms from the project?"),
+            files,
+        )
+
         if dlg.exec() == QDialog.DialogCode.Accepted:
             for fn2, fn in zip(fullNames, files):
                 self.closeSourceWindow.emit(fn2)
                 self.project.deleteFile(fn)
-    
+
     ###########################################################################
     ##  Methods to handle the various compile commands
     ###########################################################################
-    
+
     def __resetUiCompiler(self):
         """
         Private slot to reset the determined UI compiler executable.
         """
         self.__uicompiler = ""
-    
+
     def __determineUiCompiler(self):
         """
         Private method to determine the UI compiler for the project.
         """
         self.__resetUiCompiler()
-        
+
         if self.project.getProjectLanguage() == "Python3":
             if self.project.getProjectType() in ["PyQt5"]:
                 self.__uicompiler = Utilities.generatePyQtToolPath(
-                    'pyuic5', ["py3uic5"])
+                    "pyuic5", ["py3uic5"]
+                )
             elif self.project.getProjectType() in ["PyQt6", "E7Plugin"]:
-                self.__uicompiler = Utilities.generatePyQtToolPath(
-                    'pyuic6')
+                self.__uicompiler = Utilities.generatePyQtToolPath("pyuic6")
             elif self.project.getProjectType() == "PySide2":
                 self.__uicompiler = Utilities.generatePySideToolPath(
-                    'pyside2-uic', variant=2)
+                    "pyside2-uic", variant=2
+                )
             elif self.project.getProjectType() == "PySide6":
                 self.__uicompiler = Utilities.generatePySideToolPath(
-                    'pyside6-uic', variant=6)
-    
+                    "pyside6-uic", variant=6
+                )
+
     def getUiCompiler(self):
         """
         Public method to get the UI compiler executable of the project.
-        
+
         @return UI compiler executable
         @rtype str
         """
         if not self.__uicompiler:
             self.__determineUiCompiler()
-        
+
         return self.__uicompiler
-    
+
     def __readStdout(self):
         """
         Private slot to handle the readyReadStandardOutput signal of the
@@ -714,11 +734,10 @@
         if self.compileProc is None:
             return
         self.compileProc.setReadChannel(QProcess.ProcessChannel.StandardOutput)
-        
+
         while self.compileProc and self.compileProc.canReadLine():
-            self.buf += str(self.compileProc.readLine(),
-                            "utf-8", 'replace')
-        
+            self.buf += str(self.compileProc.readLine(), "utf-8", "replace")
+
     def __readStderr(self):
         """
         Private slot to handle the readyReadStandardError signal of the
@@ -726,36 +745,32 @@
         """
         if self.compileProc is None:
             return
-        
+
         ioEncoding = Preferences.getSystem("IOEncoding")
-        
+
         self.compileProc.setReadChannel(QProcess.ProcessChannel.StandardError)
         while self.compileProc and self.compileProc.canReadLine():
-            s = self.__uicompiler + ': '
-            error = str(self.compileProc.readLine(),
-                        ioEncoding, 'replace')
+            s = self.__uicompiler + ": "
+            error = str(self.compileProc.readLine(), ioEncoding, "replace")
             s += error
             self.appendStderr.emit(s)
-        
+
     def __compileUIDone(self, exitCode, exitStatus):
         """
         Private slot to handle the finished signal of the pyuic/rbuic process.
-        
+
         @param exitCode exit code of the process (integer)
         @param exitStatus exit status of the process (QProcess.ExitStatus)
         """
         self.compileRunning = False
         ericApp().getObject("ViewManager").enableEditorsCheckFocusIn(True)
         ui = ericApp().getObject("UserInterface")
-        if (
-            exitStatus == QProcess.ExitStatus.NormalExit and
-            exitCode == 0 and
-            self.buf
-        ):
+        if exitStatus == QProcess.ExitStatus.NormalExit and exitCode == 0 and self.buf:
             ofn = os.path.join(self.project.ppath, self.compiledFile)
             try:
-                newline = (None if self.project.useSystemEol()
-                           else self.project.getEolString())
+                newline = (
+                    None if self.project.useSystemEol() else self.project.getEolString()
+                )
                 with open(ofn, "w", encoding="utf-8", newline=newline) as f:
                     for line in self.buf.splitlines():
                         f.write(line + "\n")
@@ -764,8 +779,8 @@
                 ui.showNotification(
                     UI.PixmapCache.getPixmap("designer48"),
                     self.tr("Form Compilation"),
-                    self.tr("The compilation of the form file"
-                            " was successful."))
+                    self.tr("The compilation of the form file" " was successful."),
+                )
                 self.project.projectFormCompiled.emit(self.compiledFile)
             except OSError as msg:
                 ui.showNotification(
@@ -773,22 +788,25 @@
                     self.tr("Form Compilation"),
                     self.tr(
                         "<p>The compilation of the form file failed.</p>"
-                        "<p>Reason: {0}</p>").format(str(msg)),
+                        "<p>Reason: {0}</p>"
+                    ).format(str(msg)),
                     kind=NotificationTypes.CRITICAL,
-                    timeout=0)
+                    timeout=0,
+                )
         else:
             ui.showNotification(
                 UI.PixmapCache.getPixmap("designer48"),
                 self.tr("Form Compilation"),
                 self.tr("The compilation of the form file failed."),
                 kind=NotificationTypes.CRITICAL,
-                timeout=0)
+                timeout=0,
+            )
         self.compileProc = None
-        
+
     def __compileUI(self, fn, noDialog=False, progress=None):
         """
         Private method to compile a .ui file to a .py/.rb file.
-        
+
         @param fn filename of the .ui file to be compiled
         @param noDialog flag indicating silent operations
         @param progress reference to the progress dialog
@@ -797,18 +815,18 @@
         self.compileProc = QProcess()
         args = []
         self.buf = ""
-        
+
         uicompiler = self.getUiCompiler()
         if not uicompiler:
             return None
-        
+
         ofn, ext = os.path.splitext(fn)
         fn = os.path.join(self.project.ppath, fn)
-        
+
         if self.project.getProjectLanguage() == "Python3":
             dirname, filename = os.path.split(ofn)
             self.compiledFile = os.path.join(dirname, "Ui_" + filename + ".py")
-            
+
             if self.project.getProjectType() == "PySide2":
                 # PySide2
                 if Preferences.getQt("PySide2FromImports"):
@@ -831,26 +849,29 @@
                 indentWidth = Preferences.getQt("PyuicIndent")
                 if indentWidth != self.Pyuic5IndentDefault:
                     args.append("--indent={0}".format(indentWidth))
-                if (
-                    'uic5' in uicompiler and
-                    self.project.pdata["UICPARAMS"]["Package"]
-                ):
-                    args.append("--import-from={0}".format(
-                        self.project.pdata["UICPARAMS"]["Package"]))
+                if "uic5" in uicompiler and self.project.pdata["UICPARAMS"]["Package"]:
+                    args.append(
+                        "--import-from={0}".format(
+                            self.project.pdata["UICPARAMS"]["Package"]
+                        )
+                    )
                 elif Preferences.getQt("PyuicFromImports"):
                     args.append("--from-imports")
                 if self.project.pdata["UICPARAMS"]["RcSuffix"]:
-                    args.append("--resource-suffix={0}".format(
-                        self.project.pdata["UICPARAMS"]["RcSuffix"]))
+                    args.append(
+                        "--resource-suffix={0}".format(
+                            self.project.pdata["UICPARAMS"]["RcSuffix"]
+                        )
+                    )
         elif self.project.getProjectLanguage() == "Ruby":
-            self.compiledFile = ofn + '.rb'
-            args.append('-x')
-        
+            self.compiledFile = ofn + ".rb"
+            args.append("-x")
+
         args.append(fn)
         self.compileProc.finished.connect(self.__compileUIDone)
         self.compileProc.readyReadStandardOutput.connect(self.__readStdout)
         self.compileProc.readyReadStandardError.connect(self.__readStderr)
-        
+
         self.noDialog = noDialog
         self.compileProc.setWorkingDirectory(self.project.getProjectPath())
         self.compileProc.start(uicompiler, args)
@@ -865,38 +886,38 @@
                 progress.cancel()
             EricMessageBox.critical(
                 self,
-                self.tr('Process Generation Error'),
+                self.tr("Process Generation Error"),
                 self.tr(
-                    'Could not start {0}.<br>'
-                    'Ensure that it is in the search path.'
-                ).format(uicompiler))
+                    "Could not start {0}.<br>" "Ensure that it is in the search path."
+                ).format(uicompiler),
+            )
             return None
-        
+
     def __generateDialogCode(self):
         """
         Private method to generate dialog code for the form (Qt only).
         """
         itm = self.model().item(self.currentIndex())
         fn = itm.fileName()
-        
+
         if self.hooks["generateDialogCode"] is not None:
             self.hooks["generateDialogCode"](fn)
         else:
             from .CreateDialogCodeDialog import CreateDialogCodeDialog
-            
+
             # change environment
             sys.path.insert(0, self.project.getProjectPath())
             cwd = os.getcwd()
             os.chdir(os.path.dirname(os.path.abspath(fn)))
-            
+
             dlg = CreateDialogCodeDialog(fn, self.project, self)
             if not dlg.initError():
                 dlg.exec()
-            
+
             # reset the environment
             os.chdir(cwd)
             del sys.path[0]
-        
+
     def __compileForm(self):
         """
         Private method to compile a form to a source file.
@@ -908,7 +929,7 @@
             self.hooks["compileForm"](fn)
         else:
             self.__compileUI(fn)
-        
+
     def __compileAllForms(self):
         """
         Private method to compile all forms to source files.
@@ -919,17 +940,21 @@
             numForms = len(self.project.pdata["FORMS"])
             progress = EricProgressDialog(
                 self.tr("Compiling forms..."),
-                self.tr("Abort"), 0, numForms,
-                self.tr("%v/%m Forms"), self)
+                self.tr("Abort"),
+                0,
+                numForms,
+                self.tr("%v/%m Forms"),
+                self,
+            )
             progress.setModal(True)
             progress.setMinimumDuration(0)
             progress.setWindowTitle(self.tr("Forms"))
-            
+
             for prog, fn in enumerate(self.project.pdata["FORMS"]):
                 progress.setValue(prog)
                 if progress.wasCanceled():
                     break
-                
+
                 proc = self.__compileUI(fn, True, progress)
                 if proc is not None:
                     while proc.state() == QProcess.ProcessState.Running:
@@ -938,32 +963,35 @@
                 else:
                     break
             progress.setValue(numForms)
-        
+
     def __compileSelectedForms(self):
         """
         Private method to compile selected forms to source files.
         """
         items = self.getSelectedItems()
-        files = [self.project.getRelativePath(itm.fileName())
-                 for itm in items]
-        
+        files = [self.project.getRelativePath(itm.fileName()) for itm in items]
+
         if self.hooks["compileSelectedForms"] is not None:
             self.hooks["compileSelectedForms"](files)
         else:
             numForms = len(files)
             progress = EricProgressDialog(
                 self.tr("Compiling forms..."),
-                self.tr("Abort"), 0, numForms,
-                self.tr("%v/%m Forms"), self)
+                self.tr("Abort"),
+                0,
+                numForms,
+                self.tr("%v/%m Forms"),
+                self,
+            )
             progress.setModal(True)
             progress.setMinimumDuration(0)
             progress.setWindowTitle(self.tr("Forms"))
-            
+
             for prog, fn in enumerate(files):
                 progress.setValue(prog)
                 if progress.wasCanceled():
                     break
-                
+
                 proc = self.__compileUI(fn, True, progress)
                 if proc is not None:
                     while proc.state() == QProcess.ProcessState.Running:
@@ -972,7 +1000,7 @@
                 else:
                     break
             progress.setValue(numForms)
-        
+
     def compileChangedForms(self):
         """
         Public method to compile all changed forms to source files.
@@ -981,45 +1009,53 @@
             self.hooks["compileChangedForms"](self.project.pdata["FORMS"])
         else:
             if self.project.getProjectType() not in [
-                "PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"
+                "PyQt5",
+                "PyQt6",
+                "E7Plugin",
+                "PySide2",
+                "PySide6",
             ]:
                 # ignore the request for non Qt GUI projects
                 return
-            
+
             if len(self.project.pdata["FORMS"]) == 0:
                 # The project does not contain form files.
                 return
-            
+
             progress = EricProgressDialog(
                 self.tr("Determining changed forms..."),
-                self.tr("Abort"), 0, 100, self.tr("%v/%m Forms"), self)
+                self.tr("Abort"),
+                0,
+                100,
+                self.tr("%v/%m Forms"),
+                self,
+            )
             progress.setMinimumDuration(0)
             progress.setWindowTitle(self.tr("Forms"))
-            
+
             # get list of changed forms
             changedForms = []
             progress.setMaximum(len(self.project.pdata["FORMS"]))
             for prog, fn in enumerate(self.project.pdata["FORMS"]):
                 progress.setValue(prog)
                 QApplication.processEvents()
-                
+
                 ifn = os.path.join(self.project.ppath, fn)
                 if self.project.getProjectLanguage() == "Python3":
                     dirname, filename = os.path.split(os.path.splitext(ifn)[0])
                     ofn = os.path.join(dirname, "Ui_" + filename + ".py")
                 elif self.project.getProjectLanguage() == "Ruby":
-                    ofn = os.path.splitext(ifn)[0] + '.rb'
+                    ofn = os.path.splitext(ifn)[0] + ".rb"
                 if (
-                    not os.path.exists(ofn) or
-                    os.stat(ifn).st_mtime > os.stat(ofn).st_mtime
+                    not os.path.exists(ofn)
+                    or os.stat(ifn).st_mtime > os.stat(ofn).st_mtime
                 ):
                     changedForms.append(fn)
             progress.setValue(len(self.project.pdata["FORMS"]))
             QApplication.processEvents()
-            
+
             if changedForms:
-                progress.setLabelText(
-                    self.tr("Compiling changed forms..."))
+                progress.setLabelText(self.tr("Compiling changed forms..."))
                 progress.setMaximum(len(changedForms))
                 progress.setValue(prog)
                 QApplication.processEvents()
@@ -1027,7 +1063,7 @@
                     progress.setValue(prog)
                     if progress.wasCanceled():
                         break
-                    
+
                     proc = self.__compileUI(fn, True, progress)
                     if proc is not None:
                         while proc.state() == QProcess.ProcessState.Running:
@@ -1038,23 +1074,23 @@
                         break
                 progress.setValue(len(changedForms))
                 QApplication.processEvents()
-        
+
     def handlePreferencesChanged(self):
         """
         Public slot used to handle the preferencesChanged signal.
         """
         ProjectBaseBrowser.handlePreferencesChanged(self)
-        
+
         self.__resetUiCompiler()
-    
+
     def __configureUicCompiler(self):
         """
         Private slot to configure some non-common uic compiler options.
         """
         from .UicCompilerOptionsDialog import UicCompilerOptionsDialog
-        
+
         params = self.project.pdata["UICPARAMS"]
-        
+
         if self.project.getProjectType() in ["PyQt5", "PyQt6", "E7Plugin"]:
             dlg = UicCompilerOptionsDialog(params, self.getUiCompiler())
             if dlg.exec() == QDialog.DialogCode.Accepted:
@@ -1068,15 +1104,15 @@
                 if root != params["PackagesRoot"]:
                     params["PackagesRoot"] = root
                     self.project.setDirty(True)
-    
+
     ###########################################################################
     ## Support for hooks below
     ###########################################################################
-    
+
     def _initHookMethods(self):
         """
         Protected method to initialize the hooks dictionary.
-        
+
         Supported hook methods are:
         <ul>
         <li>compileForm: takes filename as parameter</li>
@@ -1087,7 +1123,7 @@
         <li>newForm: takes full directory path of new file as parameter</li>
         <li>open: takes a filename as parameter</li>
         </ul>
-        
+
         <b>Note</b>: Filenames are relative to the project directory, if not
         specified differently.
         """

eric ide

mercurial