# -*- coding: utf-8 -*-

# Copyright (c) 2002 - 2024 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing a dialog for the configuration of eric.
"""

import contextlib
import enum
import importlib
import os
import time
import types

from PyQt6.QtCore import QMetaObject, QRect, Qt, pyqtSignal, pyqtSlot
from PyQt6.QtGui import QPixmap
from PyQt6.QtWidgets import (
    QAbstractScrollArea,
    QApplication,
    QDialog,
    QDialogButtonBox,
    QFrame,
    QLabel,
    QLineEdit,
    QScrollArea,
    QSizePolicy,
    QSpacerItem,
    QSplitter,
    QStackedWidget,
    QTreeWidget,
    QTreeWidgetItem,
    QVBoxLayout,
    QWidget,
)

from eric7 import Preferences
from eric7.EricGui import EricPixmapCache
from eric7.EricWidgets import EricMessageBox
from eric7.EricWidgets.EricApplication import ericApp
from eric7.EricWidgets.EricMainWindow import EricMainWindow
from eric7.Globals import getConfig, getWebBrowserSupport
from eric7.SystemUtilities import OSUtilities


class ConfigurationPageItem(QTreeWidgetItem):
    """
    Class implementing a QTreeWidgetItem holding the configuration page data.
    """

    def __init__(self, parent, text, pageName, iconFile):
        """
        Constructor

        @param parent parent widget of the item
        @type QTreeWidget or QTreeWidgetItem
        @param text text to be displayed
        @type str
        @param pageName name of the configuration page
        @type str
        @param iconFile file name of the icon to be shown
        @type str
        """
        super().__init__(parent, [text])
        self.setIcon(0, EricPixmapCache.getIcon(iconFile))

        self.__pageName = pageName

    def getPageName(self):
        """
        Public method to get the name of the associated configuration page.

        @return name of the configuration page
        @rtype str
        """
        return self.__pageName


class ConfigurationMode(enum.Enum):
    """
    Class defining the various modes of the configuration widget.
    """

    DEFAULTMODE = 0
    TRAYSTARTERMODE = 1
    HEXEDITORMODE = 2
    WEBBROWSERMODE = 3
    EDITORMODE = 4
    PDFVIEWERMODE = 5
    PIPMANAGERMODE = 6
    SHELLMODE = 7
    MICROPYTHONMODE = 8


class ConfigurationWidget(QWidget):
    """
    Class implementing a dialog for the configuration of eric.

    @signal preferencesChanged() emitted after settings have been changed
    @signal mainPasswordChanged(str, str) emitted after the main
        password has been changed with the old and the new password
    @signal accepted() emitted to indicate acceptance of the changes
    @signal rejected() emitted to indicate rejection of the changes
    """

    preferencesChanged = pyqtSignal()
    mainPasswordChanged = pyqtSignal(str, str)
    accepted = pyqtSignal()
    rejected = pyqtSignal()

    def __init__(
        self,
        parent=None,
        fromEric=True,
        displayMode=ConfigurationMode.DEFAULTMODE,
        expandedEntries=None,
        withApply=True,
    ):
        """
        Constructor

        @param parent reference to the parent widget (defaults to None)
        @type QWidget (optional)
        @param fromEric flag indicating a dialog generation from within the
            eric IDE (defaults to True)
        @type bool (optional)
        @param displayMode mode of the configuration dialog (defaults to
            ConfigurationMode.DEFAULTMODE)
        @type ConfigurationMode (optional)
        @param expandedEntries list of entries to be shown expanded (defaults to None)
        @type list of str (optional)
        @param withApply flag indicating to show the 'Apply' button (defaults to True)
        @type bool (optional)
        """
        super().__init__(parent)

        self.fromEric = fromEric
        self.displayMode = displayMode
        self.__webEngine = getWebBrowserSupport() == "QtWebEngine"
        expandedEntries = [] if expandedEntries is None else expandedEntries[:]

        self.__setupUi(withApply=withApply)

        self.itmDict = {}

        if not fromEric:
            from eric7.PluginManager.PluginManager import (  # __IGNORE_WARNING_I101__
                PluginManager,
            )

            try:
                self.pluginManager = ericApp().getObject("PluginManager")
            except KeyError:
                self.pluginManager = PluginManager(self)
                ericApp().registerObject("PluginManager", self.pluginManager)

            from eric7.VirtualEnv.VirtualenvManager import (  # __IGNORE_WARNING_I101__
                VirtualenvManager,
            )

            try:
                self.virtualenvManager = ericApp().getObject("VirtualEnvManager")
            except KeyError:
                self.virtualenvManager = VirtualenvManager(self)
                ericApp().registerObject("VirtualEnvManager", self.virtualenvManager)

            from eric7.PipInterface.Pip import Pip  # __IGNORE_WARNING_I101__

            try:
                self.pip = ericApp().getObject("Pip")
            except KeyError:
                self.pip = Pip(self)
                ericApp().registerObject("Pip", self.pip)

        if displayMode == ConfigurationMode.DEFAULTMODE:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "applicationPage": [
                    self.tr("Application"),
                    "preferences-application",
                    "ApplicationPage",
                    None,
                    None,
                ],
                "condaPage": [self.tr("Conda"), "miniconda", "CondaPage", None, None],
                "cooperationPage": [
                    self.tr("Cooperation"),
                    "preferences-cooperation",
                    "CooperationPage",
                    None,
                    None,
                ],
                "diffPage": [
                    self.tr("Diff"),
                    "diffFiles",
                    "DiffColoursPage",
                    None,
                    None,
                ],
                "emailPage": [
                    self.tr("Email"),
                    "preferences-mail_generic",
                    "EmailPage",
                    None,
                    None,
                ],
                "graphicsPage": [
                    self.tr("Graphics"),
                    "preferences-graphics",
                    "GraphicsPage",
                    None,
                    None,
                ],
                "hexEditorPage": [
                    self.tr("Hex Editor"),
                    "hexEditor",
                    "HexEditorPage",
                    None,
                    None,
                ],
                "iconsPage": [
                    self.tr("Icons"),
                    "preferences-icons",
                    "IconsPage",
                    None,
                    None,
                ],
                "ircPage": [self.tr("IRC"), "irc", "IrcPage", None, None],
                "logViewerPage": [
                    self.tr("Log-Viewer"),
                    "preferences-logviewer",
                    "LogViewerPage",
                    None,
                    None,
                ],
                "microPythonPage": [
                    self.tr("MicroPython"),
                    "micropython",
                    "MicroPythonPage",
                    None,
                    None,
                ],
                "mimeTypesPage": [
                    self.tr("MIME-Types"),
                    "preferences-mimetypes",
                    "MimeTypesPage",
                    None,
                    None,
                ],
                "networkPage": [
                    self.tr("Network"),
                    "preferences-network",
                    "NetworkPage",
                    None,
                    None,
                ],
                "notificationsPage": [
                    self.tr("Notifications"),
                    "preferences-notifications",
                    "NotificationsPage",
                    None,
                    None,
                ],
                "pdfViewerPage": [
                    self.tr("PDF Viewer"),
                    "ericPdf",
                    "PdfViewerPage",
                    None,
                    None,
                ],
                "pipPage": [
                    self.tr("Python Package Management"),
                    "pypi",
                    "PipPage",
                    None,
                    None,
                ],
                "pluginManagerPage": [
                    self.tr("Plugin Manager"),
                    "preferences-pluginmanager",
                    "PluginManagerPage",
                    None,
                    None,
                ],
                "printerPage": [
                    self.tr("Printer"),
                    "preferences-printer",
                    "PrinterPage",
                    None,
                    None,
                ],
                "pythonPage": [
                    self.tr("Python"),
                    "preferences-python",
                    "PythonPage",
                    None,
                    None,
                ],
                "qtPage": [self.tr("Qt"), "preferences-qtlogo", "QtPage", None, None],
                "securityPage": [
                    self.tr("Security"),
                    "preferences-security",
                    "SecurityPage",
                    None,
                    None,
                ],
                "shellPage": [
                    self.tr("Shell"),
                    "preferences-shell",
                    "ShellPage",
                    None,
                    None,
                ],
                "tasksPage": [self.tr("Tasks"), "task", "TasksPage", None, None],
                "templatesPage": [
                    self.tr("Templates"),
                    "preferences-template",
                    "TemplatesPage",
                    None,
                    None,
                ],
                "trayStarterPage": [
                    self.tr("Tray Starter"),
                    "erict",
                    "TrayStarterPage",
                    None,
                    None,
                ],
                "vcsPage": [
                    self.tr("Version Control Systems"),
                    "preferences-vcs",
                    "VcsPage",
                    None,
                    None,
                ],
                "0debuggerPage": [
                    self.tr("Debugger"),
                    "preferences-debugger",
                    None,
                    None,
                    None,
                ],
                "debuggerGeneralPage": [
                    self.tr("General"),
                    "preferences-debugger",
                    "DebuggerGeneralPage",
                    "0debuggerPage",
                    None,
                ],
                "debuggerPython3Page": [
                    self.tr("Python3"),
                    "preferences-pyDebugger",
                    "DebuggerPython3Page",
                    "0debuggerPage",
                    None,
                ],
                "0editorPage": [
                    self.tr("Editor"),
                    "preferences-editor",
                    None,
                    None,
                    None,
                ],
                "editorAPIsPage": [
                    self.tr("APIs"),
                    "preferences-api",
                    "EditorAPIsPage",
                    "0editorPage",
                    None,
                ],
                "editorDocViewerPage": [
                    self.tr("Documentation Viewer"),
                    "codeDocuViewer",
                    "EditorDocViewerPage",
                    "0editorPage",
                    None,
                ],
                "editorGeneralPage": [
                    self.tr("General"),
                    "preferences-general",
                    "EditorGeneralPage",
                    "0editorPage",
                    None,
                ],
                "editorFilePage": [
                    self.tr("Filehandling"),
                    "preferences-filehandling",
                    "EditorFilePage",
                    "0editorPage",
                    None,
                ],
                "editorSearchPage": [
                    self.tr("Searching"),
                    "preferences-search",
                    "EditorSearchPage",
                    "0editorPage",
                    None,
                ],
                "editorSpellCheckingPage": [
                    self.tr("Spell checking"),
                    "preferences-spellchecking",
                    "EditorSpellCheckingPage",
                    "0editorPage",
                    None,
                ],
                "editorStylesPage": [
                    self.tr("Style"),
                    "preferences-styles",
                    "EditorStylesPage",
                    "0editorPage",
                    None,
                ],
                "editorSyntaxPage": [
                    self.tr("Code Checkers"),
                    "preferences-debugger",
                    "EditorSyntaxPage",
                    "0editorPage",
                    None,
                ],
                "editorTypingPage": [
                    self.tr("Typing"),
                    "preferences-typing",
                    "EditorTypingPage",
                    "0editorPage",
                    None,
                ],
                "editorExportersPage": [
                    self.tr("Exporters"),
                    "preferences-exporters",
                    "EditorExportersPage",
                    "0editorPage",
                    None,
                ],
                "1editorAutocompletionPage": [
                    self.tr("Autocompletion"),
                    "preferences-autocompletion",
                    "EditorAutocompletionPage",
                    "0editorPage",
                    None,
                ],
                "editorAutocompletionQScintillaPage": [
                    self.tr("QScintilla"),
                    "qscintilla",
                    "EditorAutocompletionQScintillaPage",
                    "1editorAutocompletionPage",
                    None,
                ],
                "editorAutocompletionJediPage": [
                    self.tr("Jedi"),
                    "jedi",
                    "EditorAutoCompletionJediPage",
                    "1editorAutocompletionPage",
                    None,
                ],
                "1editorCalltipsPage": [
                    self.tr("Calltips"),
                    "preferences-calltips",
                    "EditorCalltipsPage",
                    "0editorPage",
                    None,
                ],
                "editorCalltipsQScintillaPage": [
                    self.tr("QScintilla"),
                    "qscintilla",
                    "EditorCalltipsQScintillaPage",
                    "1editorCalltipsPage",
                    None,
                ],
                "editorCalltipsJediPage": [
                    self.tr("Jedi"),
                    "jedi",
                    "EditorCallTipsJediPage",
                    "1editorCalltipsPage",
                    None,
                ],
                "1editorLexerPage": [
                    self.tr("Highlighters"),
                    "preferences-highlighting-styles",
                    None,
                    "0editorPage",
                    None,
                ],
                "editorHighlightersPage": [
                    self.tr("Filetype Associations"),
                    "preferences-highlighter-association",
                    "EditorHighlightersPage",
                    "1editorLexerPage",
                    None,
                ],
                "editorHighlightingStylesPage": [
                    self.tr("Styles"),
                    "preferences-highlighting-styles",
                    "EditorHighlightingStylesPage",
                    "1editorLexerPage",
                    None,
                ],
                "editorKeywordsPage": [
                    self.tr("Keywords"),
                    "preferences-keywords",
                    "EditorKeywordsPage",
                    "1editorLexerPage",
                    None,
                ],
                "editorPropertiesPage": [
                    self.tr("Properties"),
                    "preferences-properties",
                    "EditorPropertiesPage",
                    "1editorLexerPage",
                    None,
                ],
                "1editorMouseClickHandlers": [
                    self.tr("Mouse Click Handlers"),
                    "preferences-mouse-click-handler",
                    "EditorMouseClickHandlerPage",
                    "0editorPage",
                    None,
                ],
                "editorMouseClickHandlerJediPage": [
                    self.tr("Jedi"),
                    "jedi",
                    "EditorMouseClickHandlerJediPage",
                    "1editorMouseClickHandlers",
                    None,
                ],
                "0helpPage": [
                    self.tr("Help"),
                    "preferences-help",
                    None,
                    None,
                    None,
                ],
                "helpDocumentationPage": [
                    self.tr("Help Documentation"),
                    "preferences-helpdocumentation",
                    "HelpDocumentationPage",
                    "0helpPage",
                    None,
                ],
                "helpViewersPage": [
                    self.tr("Help Viewers"),
                    "preferences-helpviewers",
                    "HelpViewersPage",
                    "0helpPage",
                    None,
                ],
                "0projectPage": [
                    self.tr("Project"),
                    "preferences-project",
                    None,
                    None,
                    None,
                ],
                "projectBrowserPage": [
                    self.tr("Project Viewer"),
                    "preferences-project",
                    "ProjectBrowserPage",
                    "0projectPage",
                    None,
                ],
                "projectPage": [
                    self.tr("Project"),
                    "preferences-project",
                    "ProjectPage",
                    "0projectPage",
                    None,
                ],
                "multiProjectPage": [
                    self.tr("Multiproject"),
                    "preferences-multiproject",
                    "MultiProjectPage",
                    "0projectPage",
                    None,
                ],
                "0interfacePage": [
                    self.tr("Interface"),
                    "preferences-interface",
                    None,
                    None,
                    None,
                ],
                "interfacePage": [
                    self.tr("Interface"),
                    "preferences-interface",
                    "InterfacePage",
                    "0interfacePage",
                    None,
                ],
                "viewmanagerPage": [
                    self.tr("Viewmanager"),
                    "preferences-viewmanager",
                    "ViewmanagerPage",
                    "0interfacePage",
                    None,
                ],
            }
            if self.__webEngine:
                self.configItems.update(
                    {
                        "0webBrowserPage": [
                            self.tr("Web Browser"),
                            "ericWeb",
                            None,
                            None,
                            None,
                        ],
                        "webBrowserAppearancePage": [
                            self.tr("Appearance"),
                            "preferences-styles",
                            "WebBrowserAppearancePage",
                            "0webBrowserPage",
                            None,
                        ],
                        "webBrowserPage": [
                            self.tr("eric Web Browser"),
                            "ericWeb",
                            "WebBrowserPage",
                            "0webBrowserPage",
                            None,
                        ],
                        "webBrowserVirusTotalPage": [
                            self.tr("VirusTotal Interface"),
                            "virustotal",
                            "WebBrowserVirusTotalPage",
                            "0webBrowserPage",
                            None,
                        ],
                        "webBrowserSpellCheckingPage": [
                            self.tr("Spell checking"),
                            "preferences-spellchecking",
                            "WebBrowserSpellCheckingPage",
                            "0webBrowserPage",
                            None,
                        ],
                    }
                )

            self.configItems.update(
                ericApp().getObject("PluginManager").getPluginConfigData()
            )

        elif displayMode == ConfigurationMode.EDITORMODE:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "iconsPage": [
                    self.tr("Icons"),
                    "preferences-icons",
                    "IconsPage",
                    None,
                    None,
                ],
                "interfacePage": [
                    self.tr("Interface"),
                    "preferences-interface",
                    "InterfaceLightPage",
                    None,
                    None,
                ],
                "printerPage": [
                    self.tr("Printer"),
                    "preferences-printer",
                    "PrinterPage",
                    None,
                    None,
                ],
                "0editorPage": [
                    self.tr("Editor"),
                    "preferences-editor",
                    None,
                    None,
                    None,
                ],
                "editorGeneralPage": [
                    self.tr("General"),
                    "preferences-general",
                    "EditorGeneralPage",
                    "0editorPage",
                    None,
                ],
                "editorFilePage": [
                    self.tr("Filehandling"),
                    "preferences-filehandling",
                    "EditorFilePage",
                    "0editorPage",
                    None,
                ],
                "editorSearchPage": [
                    self.tr("Searching"),
                    "preferences-search",
                    "EditorSearchPage",
                    "0editorPage",
                    None,
                ],
                "editorSpellCheckingPage": [
                    self.tr("Spell checking"),
                    "preferences-spellchecking",
                    "EditorSpellCheckingPage",
                    "0editorPage",
                    None,
                ],
                "editorStylesPage": [
                    self.tr("Style"),
                    "preferences-styles",
                    "EditorStylesPage",
                    "0editorPage",
                    None,
                ],
                "editorTypingPage": [
                    self.tr("Typing"),
                    "preferences-typing",
                    "EditorTypingPage",
                    "0editorPage",
                    None,
                ],
                "1editorLexerPage": [
                    self.tr("Highlighters"),
                    "preferences-highlighting-styles",
                    None,
                    "0editorPage",
                    None,
                ],
                "editorHighlightersPage": [
                    self.tr("Filetype Associations"),
                    "preferences-highlighter-association",
                    "EditorHighlightersPage",
                    "1editorLexerPage",
                    None,
                ],
                "editorHighlightingStylesPage": [
                    self.tr("Styles"),
                    "preferences-highlighting-styles",
                    "EditorHighlightingStylesPage",
                    "1editorLexerPage",
                    None,
                ],
                "editorKeywordsPage": [
                    self.tr("Keywords"),
                    "preferences-keywords",
                    "EditorKeywordsPage",
                    "1editorLexerPage",
                    None,
                ],
                "editorPropertiesPage": [
                    self.tr("Properties"),
                    "preferences-properties",
                    "EditorPropertiesPage",
                    "1editorLexerPage",
                    None,
                ],
            }

        elif displayMode == ConfigurationMode.WEBBROWSERMODE:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "iconsPage": [
                    self.tr("Icons"),
                    "preferences-icons",
                    "IconsPage",
                    None,
                    None,
                ],
                "interfacePage": [
                    self.tr("Interface"),
                    "preferences-interface",
                    "InterfaceLightPage",
                    None,
                    None,
                ],
                "networkPage": [
                    self.tr("Network"),
                    "preferences-network",
                    "NetworkPage",
                    None,
                    None,
                ],
                "printerPage": [
                    self.tr("Printer"),
                    "preferences-printer",
                    "PrinterPage",
                    None,
                    None,
                ],
                "securityPage": [
                    self.tr("Security"),
                    "preferences-security",
                    "SecurityPage",
                    None,
                    None,
                ],
                "helpDocumentationPage": [
                    self.tr("Help Documentation"),
                    "preferences-helpdocumentation",
                    "HelpDocumentationPage",
                    None,
                    None,
                ],
                "webBrowserAppearancePage": [
                    self.tr("Appearance"),
                    "preferences-styles",
                    "WebBrowserAppearancePage",
                    None,
                    None,
                ],
                "webBrowserPage": [
                    self.tr("eric Web Browser"),
                    "ericWeb",
                    "WebBrowserPage",
                    None,
                    None,
                ],
                "webBrowserVirusTotalPage": [
                    self.tr("VirusTotal Interface"),
                    "virustotal",
                    "WebBrowserVirusTotalPage",
                    None,
                    None,
                ],
                "webBrowserSpellCheckingPage": [
                    self.tr("Spell checking"),
                    "preferences-spellchecking",
                    "WebBrowserSpellCheckingPage",
                    None,
                    None,
                ],
            }

        elif displayMode == ConfigurationMode.TRAYSTARTERMODE:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "trayStarterPage": [
                    self.tr("Tray Starter"),
                    "erict",
                    "TrayStarterPage",
                    None,
                    None,
                ],
            }

        elif displayMode == ConfigurationMode.HEXEDITORMODE:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "iconsPage": [
                    self.tr("Icons"),
                    "preferences-icons",
                    "IconsPage",
                    None,
                    None,
                ],
                "interfacePage": [
                    self.tr("Interface"),
                    "preferences-interface",
                    "InterfaceLightPage",
                    None,
                    None,
                ],
                "hexEditorPage": [
                    self.tr("Hex Editor"),
                    "hexEditor",
                    "HexEditorPage",
                    None,
                    None,
                ],
            }

        elif displayMode == ConfigurationMode.PDFVIEWERMODE:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "iconsPage": [
                    self.tr("Icons"),
                    "preferences-icons",
                    "IconsPage",
                    None,
                    None,
                ],
                "interfacePage": [
                    self.tr("Interface"),
                    "preferences-interface",
                    "InterfaceLightPage",
                    None,
                    None,
                ],
                "pdfViewerPage": [
                    self.tr("PDF Viewer"),
                    "ericPdf",
                    "PdfViewerPage",
                    None,
                    None,
                ],
            }

        elif displayMode == ConfigurationMode.PIPMANAGERMODE:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "iconsPage": [
                    self.tr("Icons"),
                    "preferences-icons",
                    "IconsPage",
                    None,
                    None,
                ],
                "interfacePage": [
                    self.tr("Interface"),
                    "preferences-interface",
                    "InterfaceLightPage",
                    None,
                    None,
                ],
                "networkProxyPage": [
                    self.tr("Network Proxy"),
                    "preferences-network",
                    "NetworkProxyPage",
                    None,
                    None,
                ],
                "pipPage": [
                    self.tr("Python Package Management"),
                    "pypi",
                    "PipPage",
                    None,
                    None,
                ],
            }

        elif displayMode == ConfigurationMode.SHELLMODE:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "iconsPage": [
                    self.tr("Icons"),
                    "preferences-icons",
                    "IconsPage",
                    None,
                    None,
                ],
                "interfacePage": [
                    self.tr("Interface"),
                    "preferences-interface",
                    "InterfaceLightPage",
                    None,
                    None,
                ],
                "0shellPage": [
                    self.tr("Shell"),
                    "preferences-shell",
                    "ShellPage",
                    None,
                    None,
                ],
                "editorGeneralPage": [
                    self.tr("General"),
                    "preferences-general",
                    "EditorGeneralPage",
                    "0shellPage",
                    None,
                ],
                "editorSearchPage": [
                    self.tr("Searching"),
                    "preferences-search",
                    "EditorSearchPage",
                    "0shellPage",
                    None,
                ],
                "editorStylesPage": [
                    self.tr("Style"),
                    "preferences-styles",
                    "EditorStylesPage",
                    "0shellPage",
                    None,
                ],
                "1editorAutocompletionPage": [
                    self.tr("Autocompletion"),
                    "preferences-autocompletion",
                    "EditorAutocompletionPage",
                    "0shellPage",
                    None,
                ],
                "editorAutocompletionQScintillaPage": [
                    self.tr("QScintilla"),
                    "qscintilla",
                    "EditorAutocompletionQScintillaPage",
                    "1editorAutocompletionPage",
                    None,
                ],
                "1editorCalltipsPage": [
                    self.tr("Calltips"),
                    "preferences-calltips",
                    "EditorCalltipsPage",
                    "0shellPage",
                    None,
                ],
                "editorCalltipsQScintillaPage": [
                    self.tr("QScintilla"),
                    "qscintilla",
                    "EditorCalltipsQScintillaPage",
                    "1editorCalltipsPage",
                    None,
                ],
                "1editorLexerPage": [
                    self.tr("Highlighters"),
                    "preferences-highlighting-styles",
                    None,
                    "0shellPage",
                    None,
                ],
                "editorHighlightingStylesPage": [
                    self.tr("Styles"),
                    "preferences-highlighting-styles",
                    "EditorHighlightingStylesPage",
                    "1editorLexerPage",
                    None,
                ],
                "editorKeywordsPage": [
                    self.tr("Keywords"),
                    "preferences-keywords",
                    "EditorKeywordsPage",
                    "1editorLexerPage",
                    None,
                ],
                "editorPropertiesPage": [
                    self.tr("Properties"),
                    "preferences-properties",
                    "EditorPropertiesPage",
                    "1editorLexerPage",
                    None,
                ],
            }

        elif displayMode == ConfigurationMode.MICROPYTHONMODE:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "iconsPage": [
                    self.tr("Icons"),
                    "preferences-icons",
                    "IconsPage",
                    None,
                    None,
                ],
                "interfacePage": [
                    self.tr("Interface"),
                    "preferences-interface",
                    self.__createInterfaceLightPageWithSidebars,
                    None,
                    None,
                ],
                "microPythonPage": [
                    self.tr("MicroPython"),
                    "micropython",
                    "MicroPythonPage",
                    None,
                    None,
                ],
                "networkProxyPage": [
                    self.tr("Network Proxy"),
                    "preferences-network",
                    "NetworkProxyPage",
                    None,
                    None,
                ],
            }

        else:
            # display mode for generic use
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "iconsPage": [
                    self.tr("Icons"),
                    "preferences-icons",
                    "IconsPage",
                    None,
                    None,
                ],
                "interfacePage": [
                    self.tr("Interface"),
                    "preferences-interface",
                    "InterfaceLightPage",
                    None,
                    None,
                ],
            }

        # generate the list entries
        self.__expandedEntries = []
        for key in sorted(self.configItems):
            pageData = self.configItems[key]
            if pageData[3]:
                if pageData[3] in self.itmDict:
                    pitm = self.itmDict[pageData[3]]  # get the parent item
                else:
                    continue
            else:
                pitm = self.configList
            self.itmDict[key] = ConfigurationPageItem(
                pitm, pageData[0], key, pageData[1]
            )
            self.itmDict[key].setData(0, Qt.ItemDataRole.UserRole, key)
            if (
                not self.fromEric
                or displayMode != ConfigurationMode.DEFAULTMODE
                or key in expandedEntries
            ):
                self.itmDict[key].setExpanded(True)
        self.configList.sortByColumn(0, Qt.SortOrder.AscendingOrder)

        # set the initial size of the splitter
        self.configSplitter.setSizes([200, 600])
        self.configSplitter.splitterMoved.connect(self.__resizeConfigStack)

        self.configList.itemActivated.connect(self.__showConfigurationPage)
        self.configList.itemClicked.connect(self.__showConfigurationPage)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.rejected)

        if displayMode in [
            ConfigurationMode.TRAYSTARTERMODE,
            ConfigurationMode.HEXEDITORMODE,
            ConfigurationMode.WEBBROWSERMODE,
            ConfigurationMode.PDFVIEWERMODE,
            ConfigurationMode.PIPMANAGERMODE,
            ConfigurationMode.SHELLMODE,
        ]:
            self.configListSearch.hide()

        if displayMode not in [
            ConfigurationMode.TRAYSTARTERMODE,
            ConfigurationMode.HEXEDITORMODE,
        ]:
            self.__initLexers()

    def accept(self):
        """
        Public slot to accept the buttonBox accept signal.
        """
        if not OSUtilities.isMacPlatform():
            wdg = self.focusWidget()
            if wdg == self.configList:
                return

        self.accepted.emit()

    def __setupUi(self, withApply=True):
        """
        Private method to perform the general setup of the configuration
        widget.

        @param withApply flag indicating to show the 'Apply' button (defaults to True)
        @type bool (optional)
        """
        self.setObjectName("ConfigurationDialog")
        self.resize(900, 750)
        self.verticalLayout_2 = QVBoxLayout(self)
        self.verticalLayout_2.setSpacing(6)
        self.verticalLayout_2.setContentsMargins(6, 6, 6, 6)
        self.verticalLayout_2.setObjectName("verticalLayout_2")

        self.configSplitter = QSplitter(self)
        self.configSplitter.setOrientation(Qt.Orientation.Horizontal)
        self.configSplitter.setObjectName("configSplitter")

        self.configListWidget = QWidget(self.configSplitter)
        self.leftVBoxLayout = QVBoxLayout(self.configListWidget)
        self.leftVBoxLayout.setContentsMargins(0, 0, 0, 0)
        self.leftVBoxLayout.setSpacing(0)
        self.leftVBoxLayout.setObjectName("leftVBoxLayout")
        self.configListSearch = QLineEdit(self)
        self.configListSearch.setPlaceholderText(self.tr("Enter search text..."))
        self.configListSearch.setClearButtonEnabled(True)
        self.configListSearch.setObjectName("configListSearch")
        self.configListSearch.setClearButtonEnabled(True)
        self.leftVBoxLayout.addWidget(self.configListSearch)
        self.configList = QTreeWidget()
        self.configList.setObjectName("configList")
        self.leftVBoxLayout.addWidget(self.configList)
        self.configListSearch.textChanged.connect(self.__searchTextChanged)

        self.scrollArea = QScrollArea(self.configSplitter)
        self.scrollArea.setFrameShape(QFrame.Shape.NoFrame)
        self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
        self.scrollArea.setHorizontalScrollBarPolicy(
            Qt.ScrollBarPolicy.ScrollBarAlwaysOn
        )
        self.scrollArea.setWidgetResizable(False)
        self.scrollArea.setSizeAdjustPolicy(
            QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents
        )
        self.scrollArea.setObjectName("scrollArea")

        self.configStack = QStackedWidget()
        self.configStack.setFrameShape(QFrame.Shape.Box)
        self.configStack.setFrameShadow(QFrame.Shadow.Sunken)
        self.configStack.setObjectName("configStack")
        self.scrollArea.setWidget(self.configStack)

        self.emptyPage = QWidget()
        self.emptyPage.setGeometry(QRect(0, 0, 372, 591))
        self.emptyPage.setObjectName("emptyPage")
        self.vboxlayout = QVBoxLayout(self.emptyPage)
        self.vboxlayout.setSpacing(6)
        self.vboxlayout.setContentsMargins(6, 6, 6, 6)
        self.vboxlayout.setObjectName("vboxlayout")
        spacerItem = QSpacerItem(
            20, 20, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding
        )
        self.vboxlayout.addItem(spacerItem)
        self.emptyPagePixmap = QLabel(self.emptyPage)
        self.emptyPagePixmap.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.emptyPagePixmap.setObjectName("emptyPagePixmap")
        self.emptyPagePixmap.setPixmap(
            QPixmap(os.path.join(getConfig("ericPixDir"), "eric.png"))
        )
        self.vboxlayout.addWidget(self.emptyPagePixmap)
        self.textLabel1 = QLabel(self.emptyPage)
        self.textLabel1.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.textLabel1.setObjectName("textLabel1")
        self.vboxlayout.addWidget(self.textLabel1)
        spacerItem1 = QSpacerItem(
            20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding
        )
        self.vboxlayout.addItem(spacerItem1)
        self.configStack.addWidget(self.emptyPage)

        self.verticalLayout_2.addWidget(self.configSplitter)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Orientation.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.StandardButton.Apply
            | QDialogButtonBox.StandardButton.Cancel
            | QDialogButtonBox.StandardButton.Ok
            | QDialogButtonBox.StandardButton.Reset
        )
        self.buttonBox.setObjectName("buttonBox")
        if (
            not self.fromEric and self.displayMode == ConfigurationMode.DEFAULTMODE
        ) or not withApply:
            self.buttonBox.button(QDialogButtonBox.StandardButton.Apply).hide()
        self.buttonBox.button(QDialogButtonBox.StandardButton.Apply).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.StandardButton.Reset).setEnabled(False)
        self.verticalLayout_2.addWidget(self.buttonBox)

        self.setWindowTitle(self.tr("Preferences"))

        self.configList.header().hide()
        self.configList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder)
        self.configList.setSortingEnabled(True)
        self.textLabel1.setText(
            self.tr(
                "Please select an entry of the list \n"
                "to display the configuration page."
            )
        )

        QMetaObject.connectSlotsByName(self)
        self.setTabOrder(self.configList, self.configStack)

        self.configStack.setCurrentWidget(self.emptyPage)

        self.configList.setFocus()

    def __searchTextChanged(self, text):
        """
        Private slot to handle a change of the search text.

        @param text text to search for
        @type str
        """
        self.__searchChildItems(self.configList.invisibleRootItem(), text)

    def __searchChildItems(self, parent, text):
        """
        Private method to enable child items based on a search string.

        @param parent reference to the parent item
        @type QTreeWidgetItem
        @param text text to search for
        @type str
        @return flag indicating an enabled child item
        @rtype bool
        """
        childEnabled = False
        text = text.lower()
        for index in range(parent.childCount()):
            itm = parent.child(index)
            enable = (
                (
                    self.__searchChildItems(itm, text)
                    or text == ""
                    or text in itm.text(0).lower()
                )
                if itm.childCount() > 0
                else (text == "" or text in itm.text(0).lower())
            )
            if enable:
                childEnabled = True
            itm.setDisabled(not enable)

        return childEnabled

    def __initLexers(self):
        """
        Private method to initialize the dictionary of preferences lexers.
        """
        from eric7.QScintilla import Lexers

        from .PreferencesLexer import PreferencesLexer, PreferencesLexerLanguageError

        self.lexers = {}
        for language in Lexers.getSupportedLanguages():
            if language not in self.lexers:
                with contextlib.suppress(PreferencesLexerLanguageError):
                    self.lexers[language] = PreferencesLexer(language, self)

    def __importConfigurationPage(self, name):
        """
        Private method to import a configuration page module.

        @param name name of the configuration page module
        @type str
        @return reference to the configuration page module
        @rtype Module
        """
        try:
            mod = importlib.import_module(
                ".ConfigurationPages.{0}".format(name), __package__
            )
            return mod
        except ImportError:
            EricMessageBox.critical(
                self,
                self.tr("Configuration Page Error"),
                self.tr(
                    """<p>The configuration page <b>{0}</b>"""
                    """ could not be loaded.</p>"""
                ).format(name),
            )
            return None

    @pyqtSlot(QTreeWidgetItem)
    def __showConfigurationPage(self, itm):
        """
        Private slot to show a selected configuration page.

        @param itm reference to the selected item
        @type QTreeWidgetItem
        """
        pageName = itm.getPageName()
        self.showConfigurationPageByName(pageName, setCurrent=False)

    def __initPage(self, pageData):
        """
        Private method to initialize a configuration page.

        @param pageData data structure for the page to initialize
        @type list
        @return reference to the initialized page
        @rtype ConfigurationPageBase
        """
        page = None
        if isinstance(
            pageData[2],
            (types.FunctionType, types.LambdaType, types.MethodType),
        ):
            page = pageData[2](self)
        else:
            mod = self.__importConfigurationPage(pageData[2])
            if mod:
                page = mod.create(self)
        if page is not None:
            self.configStack.addWidget(page)
            pageData[-1] = page
            with contextlib.suppress(AttributeError):
                page.setMode(self.displayMode)
        return page

    def showConfigurationPageByName(self, pageName, setCurrent=True):
        """
        Public slot to show a named configuration page.

        @param pageName name of the configuration page to show
        @type str
        @param setCurrent flag indicating to set the current item
        @type bool
        """
        if pageName == "empty" or pageName not in self.configItems:
            page = self.emptyPage
        else:
            pageData = self.configItems[pageName]
            if pageData[-1] is None and pageData[2] is not None:
                # the page was not loaded yet, create it
                page = self.__initPage(pageData)
            else:
                page = pageData[-1]
            if page is None:
                page = self.emptyPage
            elif setCurrent:
                items = self.configList.findItems(
                    pageData[0],
                    Qt.MatchFlag.MatchFixedString | Qt.MatchFlag.MatchRecursive,
                )
                for item in items:
                    if item.data(0, Qt.ItemDataRole.UserRole) == pageName:
                        self.configList.setCurrentItem(item)
        self.configStack.setCurrentWidget(page)
        self.__resizeConfigStack()

        if page != self.emptyPage:
            page.polishPage()
            self.buttonBox.button(QDialogButtonBox.StandardButton.Apply).setEnabled(
                True
            )
            self.buttonBox.button(QDialogButtonBox.StandardButton.Reset).setEnabled(
                True
            )
        else:
            self.buttonBox.button(QDialogButtonBox.StandardButton.Apply).setEnabled(
                False
            )
            self.buttonBox.button(QDialogButtonBox.StandardButton.Reset).setEnabled(
                False
            )

        # reset scrollbars
        for sb in [
            self.scrollArea.horizontalScrollBar(),
            self.scrollArea.verticalScrollBar(),
        ]:
            if sb:
                sb.setValue(0)

        self.__currentConfigurationPageName = pageName

    def __createInterfaceLightPageWithSidebars(self, configDlg):  # noqa: U100
        """
        Private method to create the interface configuration page in light mode.

        @param configDlg reference to the configuration dialog
        @type ConfigurationWidget
        @return reference to the configuration page
        @rtype InterfaceLightPage
        """
        from .ConfigurationPages import InterfaceLightPage

        page = InterfaceLightPage.create(self, withSidebars=True)
        return page

    def resizeEvent(self, evt):
        """
        Protected method to handle the resizing of the widget.

        @param evt reference to the event object
        @type QResizeEvent
        """
        self.__resizeConfigStack()

    def __resizeConfigStack(self):
        """
        Private method to resize the stack of configuration pages.
        """
        ssize = self.scrollArea.size()
        if self.scrollArea.horizontalScrollBar():
            ssize.setHeight(
                ssize.height() - self.scrollArea.horizontalScrollBar().height() - 2
            )
        if self.scrollArea.verticalScrollBar():
            ssize.setWidth(
                ssize.width() - self.scrollArea.verticalScrollBar().width() - 2
            )
        psize = self.configStack.currentWidget().minimumSizeHint()
        self.configStack.resize(
            max(ssize.width(), psize.width()), max(ssize.height(), psize.height())
        )

    def getConfigurationPageName(self):
        """
        Public method to get the page name of the current page.

        @return page name of the current page
        @rtype str
        """
        return self.__currentConfigurationPageName

    def calledFromEric(self):
        """
        Public method to check, if invoked from within eric.

        @return flag indicating invocation from within eric
        @rtype bool
        """
        return self.fromEric

    def getPage(self, pageName):
        """
        Public method to get a reference to the named page.

        @param pageName name of the configuration page
        @type str
        @return reference to the page or None, indicating page was
            not loaded yet
        @rtype ConfigurationPageBase
        """
        return self.configItems[pageName][-1]

    def getLexers(self):
        """
        Public method to get a reference to the lexers dictionary.

        @return reference to the lexers dictionary
        @rtype dict
        """
        return self.lexers

    def setPreferences(self):
        """
        Public method called to store the selected values into the preferences
        storage.
        """
        now = time.monotonic()
        for pageData in self.configItems.values():
            if pageData[-1]:
                pageData[-1].save()
                # page was loaded (and possibly modified)
                if time.monotonic() - now > 0.01:
                    QApplication.processEvents()  # ensure HMI is responsive
                    now = time.monotonic()

    def on_buttonBox_clicked(self, button):
        """
        Private slot called by a button of the button box clicked.

        @param button button that was clicked
        @type QAbstractButton
        """
        if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Apply):
            self.on_applyButton_clicked()
        elif button == self.buttonBox.button(QDialogButtonBox.StandardButton.Reset):
            self.on_resetButton_clicked()

    @pyqtSlot()
    def on_applyButton_clicked(self):
        """
        Private slot called to apply the settings of the current page.
        """
        if self.configStack.currentWidget() != self.emptyPage:
            page = self.configStack.currentWidget()
            savedState = page.saveState()
            page.save()
            self.preferencesChanged.emit()
            if savedState is not None:
                page.setState(savedState)
            page.polishPage()

    @pyqtSlot()
    def on_resetButton_clicked(self):
        """
        Private slot called to reset the settings of the current page.
        """
        if self.configStack.currentWidget() != self.emptyPage:
            currentPage = self.configStack.currentWidget()
            savedState = currentPage.saveState()
            pageName = self.configList.currentItem().getPageName()
            self.configStack.removeWidget(currentPage)
            if pageName == "editorHighlightingStylesPage":
                self.__initLexers()
            self.configItems[pageName][-1] = None

            self.showConfigurationPageByName(pageName)
            if savedState is not None:
                self.configStack.currentWidget().setState(savedState)

    def getExpandedEntries(self):
        """
        Public method to get a list of expanded entries.

        @return list of expanded entries
        @rtype list of str
        """
        return self.__expandedEntries

    @pyqtSlot(QTreeWidgetItem)
    def on_configList_itemCollapsed(self, item):
        """
        Private slot handling a list entry being collapsed.

        @param item reference to the collapsed item
        @type QTreeWidgetItem
        """
        pageName = item.data(0, Qt.ItemDataRole.UserRole)
        if pageName in self.__expandedEntries:
            self.__expandedEntries.remove(pageName)

    @pyqtSlot(QTreeWidgetItem)
    def on_configList_itemExpanded(self, item):
        """
        Private slot handling a list entry being expanded.

        @param item reference to the expanded item
        @type QTreeWidgetItem
        """
        pageName = item.data(0, Qt.ItemDataRole.UserRole)
        if pageName not in self.__expandedEntries:
            self.__expandedEntries.append(pageName)

    def isUsingWebEngine(self):
        """
        Public method to get an indication, if QtWebEngine is being used.

        @return flag indicating the use of QtWebEngine
        @rtype bool
        """
        return self.__webEngine or self.displayMode == ConfigurationMode.WEBBROWSERMODE


class ConfigurationDialog(QDialog):
    """
    Class for the dialog variant.

    @signal preferencesChanged() emitted after settings have been changed
    @signal mainPasswordChanged(str, str) emitted after the main
        password has been changed with the old and the new password
    """

    preferencesChanged = pyqtSignal()
    mainPasswordChanged = pyqtSignal(str, str)

    def __init__(
        self,
        parent=None,
        name=None,
        modal=False,
        fromEric=True,
        displayMode=ConfigurationMode.DEFAULTMODE,
        expandedEntries=None,
    ):
        """
        Constructor

        @param parent reference to the parent widget (defaults to None)
        @type QWidget (optional)
        @param name name of the dialog (defaults to None)
        @type str (optional)
        @param modal flag indicating a modal dialog (defaults to False)
        @type bool (optional)
        @param fromEric flag indicating a dialog generation from within the
            eric IDE (defaults to True)
        @type bool (optional)
        @param displayMode mode of the configuration dialog (defaults to
            ConfigurationMode.DEFAULTMODE)
        @type ConfigurationMode (optional)
        @param expandedEntries list of entries to be shown expanded (defaults to None)
        @type list of str (optional)
        """
        super().__init__(parent)
        if name:
            self.setObjectName(name)
        self.setModal(modal)
        self.setWindowFlags(Qt.WindowType.Window)

        self.layout = QVBoxLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(0)

        self.cw = ConfigurationWidget(
            self,
            fromEric=fromEric,
            displayMode=displayMode,
            expandedEntries=expandedEntries,
            withApply=not modal,
        )
        size = self.cw.size()
        self.layout.addWidget(self.cw)
        self.resize(size)
        self.setWindowTitle(self.cw.windowTitle())

        self.cw.accepted.connect(self.accept)
        self.cw.rejected.connect(self.reject)
        self.cw.preferencesChanged.connect(self.__preferencesChanged)
        self.cw.mainPasswordChanged.connect(self.__mainPasswordChanged)

    def __preferencesChanged(self):
        """
        Private slot to handle a change of the preferences.
        """
        self.preferencesChanged.emit()

    def __mainPasswordChanged(self, oldPassword, newPassword):
        """
        Private slot to handle the change of the main password.

        @param oldPassword current password
        @type str
        @param newPassword new password
        @type str
        """
        self.mainPasswordChanged.emit(oldPassword, newPassword)

    def showConfigurationPageByName(self, pageName):
        """
        Public slot to show a named configuration page.

        @param pageName name of the configuration page to show
        @type str
        """
        self.cw.showConfigurationPageByName(pageName)

    def getConfigurationPageName(self):
        """
        Public method to get the page name of the current page.

        @return page name of the current page
        @rtype str
        """
        return self.cw.getConfigurationPageName()

    def getExpandedEntries(self):
        """
        Public method to get a list of expanded entries.

        @return list of expanded entries
        @rtype list of str
        """
        return self.cw.getExpandedEntries()

    def setPreferences(self):
        """
        Public method called to store the selected values into the preferences
        storage.
        """
        self.cw.setPreferences()

    def accept(self):
        """
        Public method to accept the dialog.
        """
        super().accept()


class ConfigurationWindow(EricMainWindow):
    """
    Main window class for the standalone dialog.
    """

    def __init__(self, parent=None):
        """
        Constructor

        @param parent reference to the parent widget
        @type QWidget
        """
        super().__init__(parent)

        self.cw = ConfigurationWidget(self, fromEric=False, withApply=False)
        size = self.cw.size()
        self.setCentralWidget(self.cw)
        self.resize(size)
        self.setWindowTitle(self.cw.windowTitle())

        self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet"))

        # Setting the style sheet above set the button state of the Apply button
        # to be visible. So we need to hide it again.
        self.cw.buttonBox.button(QDialogButtonBox.StandardButton.Apply).hide()
        self.cw.accepted.connect(self.accept)
        self.cw.rejected.connect(self.close)

    def showConfigurationPageByName(self, pageName):
        """
        Public slot to show a named configuration page.

        @param pageName name of the configuration page to show
        @type str
        """
        self.cw.showConfigurationPageByName(pageName)

    def accept(self):
        """
        Public slot called by the Ok button.
        """
        self.cw.setPreferences()
        Preferences.saveResetLayout()
        Preferences.syncPreferences()
        self.close()
