src/eric7/UI/UserInterface.py

branch
eric7-maintenance
changeset 11248
1a9dbea918e4
parent 11194
1bfb44d3bedc
parent 11230
8a15b05eeee3
--- a/src/eric7/UI/UserInterface.py	Wed Apr 02 10:51:50 2025 +0200
+++ b/src/eric7/UI/UserInterface.py	Thu May 01 12:09:22 2025 +0200
@@ -49,7 +49,6 @@
 )
 from PyQt6.QtNetwork import QNetworkAccessManager, QNetworkProxyFactory
 from PyQt6.QtWidgets import (
-    QAbstractItemView,
     QApplication,
     QDialog,
     QDockWidget,
@@ -80,7 +79,6 @@
 from eric7.EricWidgets import EricErrorMessage, EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricClickableLabel import EricClickableLabel
-from eric7.EricWidgets.EricListSelectionDialog import EricListSelectionDialog
 from eric7.EricWidgets.EricMainWindow import EricMainWindow
 from eric7.EricWidgets.EricSingleApplication import EricSingleApplicationServer
 from eric7.EricWidgets.EricToolBarManager import EricToolBarManager
@@ -94,6 +92,7 @@
 from eric7.Project.Project import Project
 from eric7.QScintilla.SpellChecker import SpellChecker
 from eric7.RemoteServerInterface.EricServerInterface import EricServerInterface
+from eric7.Sessions.CrashedSessionsSelectionDialog import CrashedSessionsSelectionDialog
 from eric7.Sessions.SessionFile import SessionFile
 from eric7.SystemUtilities import (
     DesktopUtilities,
@@ -145,6 +144,7 @@
         password has been changed with the old and the new password
     @signal onlineStateChanged(online) emitted to indicate a change of the
         network state
+    @signal shutdown() emitted to indicate a shutdown of the application
     """
 
     appendStderr = pyqtSignal(str)
@@ -154,6 +154,7 @@
     showMenu = pyqtSignal(str, QMenu)
     mainPasswordChanged = pyqtSignal(str, str)
     onlineStateChanged = pyqtSignal(bool)
+    shutdown = pyqtSignal()
 
     maxFilePathLen = 100
     maxMenuFilePathLen = 75
@@ -280,6 +281,12 @@
         # register it early because it is needed very soon
         ericApp().registerObject("EricServer", self.__ericServerInterface)
 
+        # Generate the virtual environment manager
+        logging.getLogger(__name__).debug("Creating Virtual Environments Manager...")
+        self.virtualenvManager = VirtualenvManager(self)
+        # register it early because it is needed very soon
+        ericApp().registerObject("VirtualEnvManager", self.virtualenvManager)
+
         # Generate the conda interface
         logging.getLogger(__name__).debug("Creating Conda Interface...")
         self.condaInterface = Conda(self)
@@ -292,12 +299,6 @@
         # register it early because it is needed very soon
         ericApp().registerObject("Pip", self.pipInterface)
 
-        # Generate the virtual environment manager
-        logging.getLogger(__name__).debug("Creating Virtual Environments Manager...")
-        self.virtualenvManager = VirtualenvManager(self)
-        # register it early because it is needed very soon
-        ericApp().registerObject("VirtualEnvManager", self.virtualenvManager)
-
         # Generate an empty project object
         logging.getLogger(__name__).debug("Creating Project Manager...")
         self.project = Project(self, remoteServer=self.__ericServerInterface)
@@ -556,9 +557,6 @@
         if self.numbersViewer is not None:
             self.numbersViewer.insertNumber.connect(self.viewmanager.insertNumber)
 
-        if self.irc is not None:
-            self.irc.autoConnected.connect(self.__ircAutoConnected)
-
         if self.pipWidget is not None:
             self.preferencesChanged.connect(self.pipWidget.preferencesChanged)
 
@@ -620,8 +618,6 @@
         ericApp().registerObject("ToolbarManager", self.toolbarManager)
         if self.cooperation is not None:
             ericApp().registerObject("Cooperation", self.cooperation)
-        if self.irc is not None:
-            ericApp().registerObject("IRC", self.irc)
         if self.symbolsViewer is not None:
             ericApp().registerObject("Symbols", self.symbolsViewer)
         if self.numbersViewer is not None:
@@ -665,7 +661,7 @@
 
         self.currentProfile = None
 
-        self.shutdownCalled = False
+        self.__shutdownCalled = False
         self.inCloseEvent = False
 
         # now fire up the single application server
@@ -810,11 +806,11 @@
 
         # Create previewer
         logging.getLogger(__name__).debug("Creating Previewer...")
-        self.__previewer = Previewer(self.viewmanager)
+        self.__previewer = Previewer(viewmanager=self.viewmanager, ui=self)
 
         # Create AST viewer
         logging.getLogger(__name__).debug("Creating Python AST Viewer")
-        self.__astViewer = PythonAstViewer(self.viewmanager)
+        self.__astViewer = PythonAstViewer(viewmanager=self.viewmanager, ui=self)
 
         # Create DIS viewer
         logging.getLogger(__name__).debug("Creating Python Disassembly Viewer")
@@ -852,7 +848,7 @@
             logging.getLogger(__name__).debug("Creating Template Viewer...")
             from eric7.Templates.TemplateViewer import TemplateViewer  # noqa: I-101
 
-            self.templateViewer = TemplateViewer(None, self.viewmanager)
+            self.templateViewer = TemplateViewer(self, self.viewmanager)
         else:
             logging.getLogger(__name__).debug("Template Viewer disabled")
             self.templateViewer = None
@@ -921,16 +917,6 @@
             logging.getLogger(__name__).debug("Chat Widget disabled")
             self.cooperation = None
 
-        if Preferences.getUI("ShowIrc"):
-            # Create the IRC part of the user interface
-            logging.getLogger(__name__).debug("Creating IRC Widget...")
-            from eric7.Network.IRC.IrcWidget import IrcWidget  # noqa: I-101
-
-            self.irc = IrcWidget(self)
-        else:
-            logging.getLogger(__name__).debug("IRC Widget disabled")
-            self.irc = None
-
         if Preferences.getUI("ShowMicroPython"):
             # Create the MicroPython part of the user interface
             logging.getLogger(__name__).debug("Creating MicroPython Widget...")
@@ -1233,11 +1219,6 @@
                 self.tr("Cooperation"),
             )
 
-        if self.irc:
-            self.rToolbox.addItem(
-                self.irc, EricPixmapCache.getIcon("irc"), self.tr("IRC")
-            )
-
         if self.microPythonWidget:
             self.rToolbox.addItem(
                 self.microPythonWidget,
@@ -1433,9 +1414,6 @@
                 self.tr("Cooperation"),
             )
 
-        if self.irc:
-            sidebar.addTab(self.irc, EricPixmapCache.getIcon("sbIrc96"), self.tr("IRC"))
-
         if self.microPythonWidget:
             sidebar.addTab(
                 self.microPythonWidget,
@@ -2371,28 +2349,6 @@
             self.actions.append(self.cooperationViewerActivateAct)
             self.addAction(self.cooperationViewerActivateAct)
 
-        if self.irc is not None:
-            self.ircActivateAct = EricAction(
-                self.tr("IRC"),
-                self.tr("&IRC"),
-                QKeySequence(self.tr("Ctrl+Alt+Shift+I")),
-                0,
-                self,
-                "irc_widget_activate",
-            )
-            self.ircActivateAct.setStatusTip(
-                self.tr("Switch the input focus to the IRC window.")
-            )
-            self.ircActivateAct.setWhatsThis(
-                self.tr(
-                    """<b>Activate IRC</b>"""
-                    """<p>This switches the input focus to the IRC window.</p>"""
-                )
-            )
-            self.ircActivateAct.triggered.connect(self.__activateIRC)
-            self.actions.append(self.ircActivateAct)
-            self.addAction(self.ircActivateAct)
-
         if self.symbolsViewer is not None:
             self.symbolsViewerActivateAct = EricAction(
                 self.tr("Symbols-Viewer"),
@@ -3647,27 +3603,6 @@
         """
         Private slot to initialize the action to show the Qt documentation.
         """
-        self.qt5DocAct = EricAction(
-            self.tr("Qt5 Documentation"),
-            self.tr("Qt5 Documentation"),
-            0,
-            0,
-            self,
-            "qt5_documentation",
-        )
-        self.qt5DocAct.setStatusTip(self.tr("Open Qt5 Documentation"))
-        self.qt5DocAct.setWhatsThis(
-            self.tr(
-                """<b>Qt5 Documentation</b>"""
-                """<p>Display the Qt5 Documentation. Dependent upon your"""
-                """ settings, this will either show the help in Eric's internal"""
-                """ help viewer/web browser, or execute a web browser or Qt"""
-                """ Assistant. </p>"""
-            )
-        )
-        self.qt5DocAct.triggered.connect(lambda: self.__showQtDoc(5))
-        self.actions.append(self.qt5DocAct)
-
         self.qt6DocAct = EricAction(
             self.tr("Qt6 Documentation"),
             self.tr("Qt6 Documentation"),
@@ -3689,27 +3624,6 @@
         self.qt6DocAct.triggered.connect(lambda: self.__showQtDoc(6))
         self.actions.append(self.qt6DocAct)
 
-        self.pyqt5DocAct = EricAction(
-            self.tr("PyQt5 Documentation"),
-            self.tr("PyQt5 Documentation"),
-            0,
-            0,
-            self,
-            "pyqt5_documentation",
-        )
-        self.pyqt5DocAct.setStatusTip(self.tr("Open PyQt5 Documentation"))
-        self.pyqt5DocAct.setWhatsThis(
-            self.tr(
-                """<b>PyQt5 Documentation</b>"""
-                """<p>Display the PyQt5 Documentation. Dependent upon your"""
-                """ settings, this will either show the help in Eric's"""
-                """ internal help viewer/web browser, or execute a web"""
-                """ browser or Qt Assistant. </p>"""
-            )
-        )
-        self.pyqt5DocAct.triggered.connect(lambda: self.__showPyQtDoc(variant=5))
-        self.actions.append(self.pyqt5DocAct)
-
         self.pyqt6DocAct = EricAction(
             self.tr("PyQt6 Documentation"),
             self.tr("PyQt6 Documentation"),
@@ -3788,32 +3702,6 @@
         Private slot to initialize the actions to show the PySide
         documentation.
         """
-        if QtUtilities.checkPyside(variant=2):
-            self.pyside2DocAct = EricAction(
-                self.tr("PySide2 Documentation"),
-                self.tr("PySide2 Documentation"),
-                0,
-                0,
-                self,
-                "pyside2_documentation",
-            )
-            self.pyside2DocAct.setStatusTip(self.tr("Open PySide2 Documentation"))
-            self.pyside2DocAct.setWhatsThis(
-                self.tr(
-                    """<b>PySide2 Documentation</b>"""
-                    """<p>Display the PySide2 Documentation. Dependent upon your"""
-                    """ settings, this will either show the help in Eric's"""
-                    """ internal help viewer/web browser, or execute a web"""
-                    """ browser or Qt Assistant. </p>"""
-                )
-            )
-            self.pyside2DocAct.triggered.connect(
-                lambda: self.__showPySideDoc(variant=2)
-            )
-            self.actions.append(self.pyside2DocAct)
-        else:
-            self.pyside2DocAct = None
-
         if QtUtilities.checkPyside(variant=6):
             self.pyside6DocAct = EricAction(
                 self.tr("PySide6 Documentation"),
@@ -4098,8 +3986,6 @@
             self.__menus["subwindow"].addAction(self.condaWidgetActivateAct)
         if self.cooperation is not None:
             self.__menus["subwindow"].addAction(self.cooperationViewerActivateAct)
-        if self.irc is not None:
-            self.__menus["subwindow"].addAction(self.ircActivateAct)
         if self.microPythonWidget is not None:
             self.__menus["subwindow"].addAction(self.microPythonWidgetActivateAct)
 
@@ -4139,12 +4025,8 @@
             self.__menus["help"].addSeparator()
         self.__menus["help"].addAction(self.ericDocAct)
         self.__menus["help"].addAction(self.pythonDocAct)
-        self.__menus["help"].addAction(self.qt5DocAct)
         self.__menus["help"].addAction(self.qt6DocAct)
-        self.__menus["help"].addAction(self.pyqt5DocAct)
         self.__menus["help"].addAction(self.pyqt6DocAct)
-        if self.pyside2DocAct is not None:
-            self.__menus["help"].addAction(self.pyside2DocAct)
         if self.pyside6DocAct is not None:
             self.__menus["help"].addAction(self.pyside6DocAct)
         self.__menus["help"].addSeparator()
@@ -5928,18 +5810,6 @@
                 self.activateLeftRightSidebarWidget(self.cooperation)
             self.cooperation.setFocus(Qt.FocusReason.ActiveWindowFocusReason)
 
-    def __activateIRC(self):
-        """
-        Private slot to handle the activation of the IRC window.
-        """
-        if self.irc is not None:
-            if self.__layoutType == "Toolboxes":
-                self.rToolboxDock.show()
-                self.rToolbox.setCurrentWidget(self.irc)
-            elif self.__layoutType == "Sidebars":
-                self.activateLeftRightSidebarWidget(self.irc)
-            self.irc.setFocus(Qt.FocusReason.ActiveWindowFocusReason)
-
     def __activateSymbolsViewer(self):
         """
         Private slot to handle the activation of the Symbols Viewer.
@@ -6954,11 +6824,11 @@
         else:
             self.__customViewer(home)
 
-    def __showPyQtDoc(self, variant=5):
-        """
-        Private slot to show the PyQt5/6 documentation.
-
-        @param variant PyQt variant to show documentation for (5 or 6)
+    def __showPyQtDoc(self, variant=6):
+        """
+        Private slot to show the PyQt documentation.
+
+        @param variant PyQt variant to show documentation for
         @type int or str
         """
         pyqtDocDir = Preferences.getHelp("PyQt{0}DocDir".format(variant))
@@ -7072,11 +6942,11 @@
         else:
             self.__customViewer(home)
 
-    def __showPySideDoc(self, variant=2):
-        """
-        Private slot to show the PySide2/PySide6 documentation.
-
-        @param variant PySide variant (2 or 6)
+    def __showPySideDoc(self, variant=6):
+        """
+        Private slot to show the PySide documentation.
+
+        @param variant PySide variant
         @type int or str
         """
         pysideDocDir = Preferences.getHelp("PySide{0}DocDir".format(variant))
@@ -7958,19 +7828,11 @@
         selectedCrashSessionFile = ""
         crashedSessionsList = self.__getCrashedSessions()
         if crashedSessionsList:
-            dlg = EricListSelectionDialog(
-                sorted(crashedSessionsList),
-                selectionMode=QAbstractItemView.SelectionMode.SingleSelection,
-                title=self.tr("Found Crash Sessions"),
-                message=self.tr(
-                    "These crash session files were found. Select the one to"
-                    " open. Select 'Cancel' to not open a crash session."
-                ),
-                doubleClickOk=True,
-                parent=self,
+            dlg = CrashedSessionsSelectionDialog(
+                sorted(crashedSessionsList), parent=self
             )
             if dlg.exec() == QDialog.DialogCode.Accepted:
-                selectedCrashSessionFile = dlg.getSelection()[0]
+                selectedCrashSessionFile = dlg.getSelectedCrashSession()
 
         return selectedCrashSessionFile
 
@@ -8029,20 +7891,14 @@
         """
         Private slot to clean all stale crash sessions.
         """
-        from .DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
-
         crashedSessionsList = self.__getCrashedSessions()
         if crashedSessionsList:
-            dlg = DeleteFilesConfirmationDialog(
-                parent=self,
-                caption=self.tr("Clean stale crash sessions"),
-                message=self.tr(
-                    "Do you really want to delete these stale crash session files?"
-                ),
-                files=sorted(crashedSessionsList),
+            dlg = CrashedSessionsSelectionDialog(
+                sorted(crashedSessionsList), deleteMode=True, parent=self
             )
             if dlg.exec() == QDialog.DialogCode.Accepted:
-                for crashSession in crashedSessionsList:
+                selectedCrashSessionFiles = dlg.getSelectedCrashSessions()
+                for crashSession in selectedCrashSessionFiles:
                     os.remove(crashSession)
 
     def showFindFileByNameDialog(self):
@@ -8448,7 +8304,7 @@
         @return flag indicating success
         @rtype bool
         """
-        if self.shutdownCalled:
+        if self.__shutdownCalled:
             return True
 
         if not self.viewmanager.checkAllDirty():
@@ -8457,13 +8313,8 @@
         if self.__webBrowserProcess is not None:
             self.__webBrowserShutdown()
 
-        if self.irc is not None and not self.irc.shutdown():
-            return False
-
         sessionCreated = self.__writeSession()
 
-        self.__astViewer.hide()
-
         self.shell.closeShell()
 
         if not self.project.closeProject(shutdown=True):
@@ -8482,37 +8333,12 @@
         if sessionCreated and not self.__disableCrashSession:
             self.__deleteCrashSession()
 
-        if self.codeDocumentationViewer is not None:
-            self.codeDocumentationViewer.shutdown()
-
-        self.__previewer.shutdown()
-
-        self.__astViewer.shutdown()
-
         self.__writeTasks()
 
-        if self.templateViewer is not None:
-            self.templateViewer.save()
-
         if not self.debuggerUI.shutdownServer():
             return False
-        self.debuggerUI.shutdown()
-
-        self.backgroundService.shutdown()
-
-        if self.cooperation is not None:
-            self.cooperation.shutdown()
-
-        if self.__helpViewerWidget is not None:
-            self.__helpViewerWidget.shutdown()
-
-        if self.microPythonWidget is not None:
-            self.microPythonWidget.shutdown()
-
-        self.pipInterface.shutdown()
-
-        self.pluginManager.doShutdown()
-
+
+        # stop the single application server
         if self.SAServer is not None:
             self.SAServer.shutdown()
             self.SAServer = None
@@ -8531,7 +8357,10 @@
         self.__saveCurrentViewProfile(True)
         Preferences.saveToolGroups(self.toolGroups, self.currentToolGroup)
         Preferences.syncPreferences()
-        self.shutdownCalled = True
+
+        # emit the shutdown() signal to allow connected parts to perform their
+        # individual shutdown actions
+        self.shutdown.emit()
 
         # shut down the global file system watcher
         EricFileSystemWatcher.instance().shutdown()
@@ -8540,6 +8369,8 @@
         sys.stdout = sys.__stdout__
         sys.stderr = sys.__stderr__
 
+        self.__shutdownCalled = True
+
         return True
 
     def isOnline(self):
@@ -8746,7 +8577,7 @@
     def getOriginalPathString(self):
         """
         Public method to get the original PATH environment variable
-        (i.e. before modifications by eric and PyQt5).
+        (i.e. before modifications by eric).
 
         @return original PATH environment variable
         @rtype str
@@ -8804,23 +8635,6 @@
             icon, heading, text, kind=kind, timeout=timeout
         )
 
-    #########################
-    ## Support for IRC  below
-    #########################
-
-    def autoConnectIrc(self):
-        """
-        Public method to initiate the IRC auto connection.
-        """
-        if self.irc is not None:
-            self.irc.autoConnect()
-
-    def __ircAutoConnected(self):
-        """
-        Private slot handling the automatic connection of the IRC client.
-        """
-        self.__activateIRC()
-
     ##############################################
     ## Support for Code Documentation Viewer below
     ##############################################

eric ide

mercurial