Refactored the Utilities and Globals modules in order to enhance the maintainability. eric7

Sun, 18 Dec 2022 19:33:46 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 18 Dec 2022 19:33:46 +0100
branch
eric7
changeset 9624
b47dfa7a137d
parent 9623
9c1f429cb56b
child 9625
2c760cdc6b64

Refactored the Utilities and Globals modules in order to enhance the maintainability.

eric7.epj file | annotate | diff | comparison | revisions
src/eric7/APIs/Python3/eric7.api file | annotate | diff | comparison | revisions
src/eric7/CodeFormatting/BlackFormattingDialog.py file | annotate | diff | comparison | revisions
src/eric7/CondaInterface/Conda.py file | annotate | diff | comparison | revisions
src/eric7/DataViews/CodeMetricsDialog.py file | annotate | diff | comparison | revisions
src/eric7/DataViews/PyCoverageDialog.py file | annotate | diff | comparison | revisions
src/eric7/DataViews/PyProfileDialog.py file | annotate | diff | comparison | revisions
src/eric7/Debugger/DebugUI.py file | annotate | diff | comparison | revisions
src/eric7/Debugger/DebuggerInterfacePython.py file | annotate | diff | comparison | revisions
src/eric7/Documentation/Help/source.qch file | annotate | diff | comparison | revisions
src/eric7/Documentation/Help/source.qhp file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.Globals.__init__.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.PipInterface.PipPackagesWidget.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.SystemUtilities.DesktopUtilities.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.SystemUtilities.FileSystemUtilities.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.SystemUtilities.OSUtilities.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.SystemUtilities.PySideImporter.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.SystemUtilities.PythonUtilities.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.SystemUtilities.QtUtilities.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.Utilities.__init__.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/index-eric7.SystemUtilities.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/index-eric7.Utilities.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/index-eric7.html file | annotate | diff | comparison | revisions
src/eric7/DocumentationTools/IndexGenerator.py file | annotate | diff | comparison | revisions
src/eric7/DocumentationTools/QtHelpGenerator.py file | annotate | diff | comparison | revisions
src/eric7/EricNetwork/EricGoogleMailHelpers.py file | annotate | diff | comparison | revisions
src/eric7/EricNetwork/EricJsonServer.py file | annotate | diff | comparison | revisions
src/eric7/EricNetwork/EricNetworkProxyFactory.py file | annotate | diff | comparison | revisions
src/eric7/EricNetwork/EricSslErrorHandler.py file | annotate | diff | comparison | revisions
src/eric7/EricWidgets/EricApplication.py file | annotate | diff | comparison | revisions
src/eric7/EricWidgets/EricCompleters.py file | annotate | diff | comparison | revisions
src/eric7/EricWidgets/EricFileDialog.py file | annotate | diff | comparison | revisions
src/eric7/EricWidgets/EricSingleApplication.py file | annotate | diff | comparison | revisions
src/eric7/EricWidgets/EricSqueezeLabels.py file | annotate | diff | comparison | revisions
src/eric7/EricXML/MultiProjectReader.py file | annotate | diff | comparison | revisions
src/eric7/EricXML/ProjectReader.py file | annotate | diff | comparison | revisions
src/eric7/EricXML/TasksReader.py file | annotate | diff | comparison | revisions
src/eric7/Globals/__init__.py file | annotate | diff | comparison | revisions
src/eric7/Graphics/ApplicationDiagramBuilder.py file | annotate | diff | comparison | revisions
src/eric7/Graphics/AssociationItem.py file | annotate | diff | comparison | revisions
src/eric7/Graphics/ClassItem.py file | annotate | diff | comparison | revisions
src/eric7/Graphics/ImportsDiagramBuilder.py file | annotate | diff | comparison | revisions
src/eric7/Graphics/PackageDiagramBuilder.py file | annotate | diff | comparison | revisions
src/eric7/Graphics/PackageItem.py file | annotate | diff | comparison | revisions
src/eric7/Graphics/UMLClassDiagramBuilder.py file | annotate | diff | comparison | revisions
src/eric7/HelpViewer/HelpViewerWidget.py file | annotate | diff | comparison | revisions
src/eric7/HexEdit/HexEditMainWindow.py file | annotate | diff | comparison | revisions
src/eric7/HexEdit/HexEditWidget.py file | annotate | diff | comparison | revisions
src/eric7/JediInterface/JediServer.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/CircuitPythonDevices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/EspDevices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/GenericMicroPythonDevices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/MicroPythonWidget.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/MicrobitDevices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/PyBoardDevices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/UF2FlashDialog.py file | annotate | diff | comparison | revisions
src/eric7/MultiProject/AddProjectDialog.py file | annotate | diff | comparison | revisions
src/eric7/MultiProject/MultiProject.py file | annotate | diff | comparison | revisions
src/eric7/Network/IRC/IrcChannelWidget.py file | annotate | diff | comparison | revisions
src/eric7/Network/IRC/IrcIdentitiesEditDialog.py file | annotate | diff | comparison | revisions
src/eric7/Network/IRC/IrcNetworkManager.py file | annotate | diff | comparison | revisions
src/eric7/Network/IRC/IrcNetworkWidget.py file | annotate | diff | comparison | revisions
src/eric7/Network/IRC/IrcWidget.py file | annotate | diff | comparison | revisions
src/eric7/PipInterface/Pip.py file | annotate | diff | comparison | revisions
src/eric7/PipInterface/PipFileSelectionDialog.py file | annotate | diff | comparison | revisions
src/eric7/PipInterface/PipFreezeDialog.py file | annotate | diff | comparison | revisions
src/eric7/PluginManager/PluginInstallDialog.py file | annotate | diff | comparison | revisions
src/eric7/PluginManager/PluginManager.py file | annotate | diff | comparison | revisions
src/eric7/PluginManager/PluginRepositoryDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckService.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/DocumentationPlugins/Ericapi/EricapiConfigDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/DocumentationPlugins/Ericdoc/EricdocConfigDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/PluginCodeStyleChecker.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/PluginEricapi.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/PluginEricdoc.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/PluginVcsGit.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/PluginVcsMercurial.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/PluginVcsSubversion.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsGit/GitArchiveDataDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsGit/GitCopyDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsGit/GitNewProjectOptionsDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsGit/GitPatchFilesDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsGit/GitSubmoduleAddDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsGit/GitUtilities.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsGit/git.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsMercurial/HgAddSubrepositoryDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsMercurial/HgArchiveDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsMercurial/HgNewProjectOptionsDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsMercurial/HgUserConfigDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsMercurial/HgUtilities.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsMercurial/HisteditExtension/histedit.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfConvertDataDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsMercurial/hg.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnDiffDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnNewProjectOptionsDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnOptionsDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnStatusDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnUrlSelectionDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnUtilities.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnNewProjectOptionsDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnOptionsDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnUrlSelectionDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnUtilities.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/ViewManagerPlugins/Tabview/Tabview.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/WizardPlugins/SetupWizard/SetupWizardDialog.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/ConfigurationDialog.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/ConfigurationPages/ApplicationPage.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/ConfigurationPages/EditorAPIsPage.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/ConfigurationPages/EditorFilePage.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/ConfigurationPages/InterfaceLightPage.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/ConfigurationPages/InterfacePage.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/ConfigurationPages/MicroPythonPage.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/ConfigurationPages/MultiProjectPage.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/ConfigurationPages/WebBrowserSpellCheckingPage.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/PreferencesLexer.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/ProgramsDialog.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/ToolConfigurationDialog.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/__init__.py file | annotate | diff | comparison | revisions
src/eric7/Project/CreateDialogCodeDialog.py file | annotate | diff | comparison | revisions
src/eric7/Project/Project.py file | annotate | diff | comparison | revisions
src/eric7/Project/ProjectBrowserModel.py file | annotate | diff | comparison | revisions
src/eric7/Project/ProjectFile.py file | annotate | diff | comparison | revisions
src/eric7/Project/ProjectFormsBrowser.py file | annotate | diff | comparison | revisions
src/eric7/Project/ProjectResourcesBrowser.py file | annotate | diff | comparison | revisions
src/eric7/Project/ProjectTranslationsBrowser.py file | annotate | diff | comparison | revisions
src/eric7/Project/ProjectVenvConfigurationDialog.py file | annotate | diff | comparison | revisions
src/eric7/Project/ProjectVenvCreationParametersDialog.py file | annotate | diff | comparison | revisions
src/eric7/Project/PropertiesDialog.py file | annotate | diff | comparison | revisions
src/eric7/Project/TranslationPropertiesDialog.py file | annotate | diff | comparison | revisions
src/eric7/QScintilla/Editor.py file | annotate | diff | comparison | revisions
src/eric7/QScintilla/Lexers/LexerPygments.py file | annotate | diff | comparison | revisions
src/eric7/QScintilla/MiniEditor.py file | annotate | diff | comparison | revisions
src/eric7/QScintilla/ShellWindow.py file | annotate | diff | comparison | revisions
src/eric7/QScintilla/SpellChecker.py file | annotate | diff | comparison | revisions
src/eric7/Snapshot/SnapWidget.py file | annotate | diff | comparison | revisions
src/eric7/Snapshot/SnapshotDefaultGrabber.py file | annotate | diff | comparison | revisions
src/eric7/Snapshot/SnapshotFreehandGrabber.py file | annotate | diff | comparison | revisions
src/eric7/Snapshot/SnapshotRegionGrabber.py file | annotate | diff | comparison | revisions
src/eric7/Snapshot/SnapshotWaylandGrabber.py file | annotate | diff | comparison | revisions
src/eric7/SystemUtilities/DesktopUtilities.py file | annotate | diff | comparison | revisions
src/eric7/SystemUtilities/FileSystemUtilities.py file | annotate | diff | comparison | revisions
src/eric7/SystemUtilities/OSUtilities.py file | annotate | diff | comparison | revisions
src/eric7/SystemUtilities/PySideImporter.py file | annotate | diff | comparison | revisions
src/eric7/SystemUtilities/PythonUtilities.py file | annotate | diff | comparison | revisions
src/eric7/SystemUtilities/QtUtilities.py file | annotate | diff | comparison | revisions
src/eric7/SystemUtilities/__init__.py file | annotate | diff | comparison | revisions
src/eric7/Templates/TemplateViewer.py file | annotate | diff | comparison | revisions
src/eric7/Toolbox/Startup.py file | annotate | diff | comparison | revisions
src/eric7/Tools/TrayStarter.py file | annotate | diff | comparison | revisions
src/eric7/UI/Browser.py file | annotate | diff | comparison | revisions
src/eric7/UI/BrowserModel.py file | annotate | diff | comparison | revisions
src/eric7/UI/DiffDialog.py file | annotate | diff | comparison | revisions
src/eric7/UI/FindFileWidget.py file | annotate | diff | comparison | revisions
src/eric7/UI/FindLocationWidget.py file | annotate | diff | comparison | revisions
src/eric7/UI/InstallInfoDialog.py file | annotate | diff | comparison | revisions
src/eric7/UI/NotificationWidget.py file | annotate | diff | comparison | revisions
src/eric7/UI/Previewers/PreviewerHTML.py file | annotate | diff | comparison | revisions
src/eric7/UI/Previewers/PreviewerQSS.py file | annotate | diff | comparison | revisions
src/eric7/UI/UserInterface.py file | annotate | diff | comparison | revisions
src/eric7/Utilities/BackgroundService.py file | annotate | diff | comparison | revisions
src/eric7/Utilities/MouseUtilities.py file | annotate | diff | comparison | revisions
src/eric7/Utilities/PySideImporter.py file | annotate | diff | comparison | revisions
src/eric7/Utilities/__init__.py file | annotate | diff | comparison | revisions
src/eric7/ViewManager/ViewManager.py file | annotate | diff | comparison | revisions
src/eric7/VirtualEnv/VirtualenvAddEditDialog.py file | annotate | diff | comparison | revisions
src/eric7/VirtualEnv/VirtualenvConfigurationDialog.py file | annotate | diff | comparison | revisions
src/eric7/VirtualEnv/VirtualenvExecDialog.py file | annotate | diff | comparison | revisions
src/eric7/VirtualEnv/VirtualenvInterpreterSelectionDialog.py file | annotate | diff | comparison | revisions
src/eric7/VirtualEnv/VirtualenvManager.py file | annotate | diff | comparison | revisions
src/eric7/VirtualEnv/VirtualenvManagerWidgets.py file | annotate | diff | comparison | revisions
src/eric7/VirtualEnv/VirtualenvUpgradeConfigurationDialog.py file | annotate | diff | comparison | revisions
src/eric7/VirtualEnv/VirtualenvUpgradeExecDialog.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/AdBlock/AdBlockManager.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/AdBlock/AdBlockSubscription.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/Bookmarks/BookmarksImportDialog.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/Bookmarks/BookmarksImporters/ChromeImporter.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/Bookmarks/BookmarksImporters/FirefoxImporter.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/Bookmarks/BookmarksImporters/IExplorerImporter.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/Bookmarks/BookmarksImporters/OperaImporter.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/Bookmarks/BookmarksImporters/SafariImporter.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/Bookmarks/BookmarksImporters/__init__.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/Bookmarks/BookmarksManager.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/CookieJar/CookieJar.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/Download/DownloadManager.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyConfiguration/GreaseMonkeyConfigurationListDelegate.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyManager.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/History/HistoryManager.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/Network/ProtocolHandlerManager.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/OpenSearch/OpenSearchManager.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/Passwords/PasswordManager.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/QtHelp/HelpDocsInstaller.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/SafeBrowsing/SafeBrowsingManager.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/Session/SessionManager.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/SpeedDial/SpeedDial.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/Sync/SyncAssistantDialog.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/TabManager/TabManagerWidget.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/UserAgent/UserAgentManager.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/WebBrowserSingleApplication.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/WebBrowserTabWidget.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/WebBrowserView.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/WebBrowserWindow.py file | annotate | diff | comparison | revisions
src/eric7/eric7_api.py file | annotate | diff | comparison | revisions
src/eric7/eric7_doc.py file | annotate | diff | comparison | revisions
src/eric7/eric7_ide.py file | annotate | diff | comparison | revisions
diff -r 9c1f429cb56b -r b47dfa7a137d eric7.epj
--- a/eric7.epj	Sun Dec 18 14:19:10 2022 +0100
+++ b/eric7.epj	Sun Dec 18 19:33:46 2022 +0100
@@ -2029,6 +2029,13 @@
       "src/eric7/SqlBrowser/SqlConnectionDialog.py",
       "src/eric7/SqlBrowser/SqlConnectionWidget.py",
       "src/eric7/SqlBrowser/__init__.py",
+      "src/eric7/SystemUtilities/DesktopUtilities.py",
+      "src/eric7/SystemUtilities/FileSystemUtilities.py",
+      "src/eric7/SystemUtilities/OSUtilities.py",
+      "src/eric7/SystemUtilities/PySideImporter.py",
+      "src/eric7/SystemUtilities/PythonUtilities.py",
+      "src/eric7/SystemUtilities/QtUtilities.py",
+      "src/eric7/SystemUtilities/__init__.py",
       "src/eric7/Tasks/Task.py",
       "src/eric7/Tasks/TaskFilter.py",
       "src/eric7/Tasks/TaskFilterConfigDialog.py",
@@ -2137,7 +2144,6 @@
       "src/eric7/Utilities/ModuleParser.py",
       "src/eric7/Utilities/MouseUtilities.py",
       "src/eric7/Utilities/PasswordChecker.py",
-      "src/eric7/Utilities/PySideImporter.py",
       "src/eric7/Utilities/__init__.py",
       "src/eric7/Utilities/crypto/__init__.py",
       "src/eric7/Utilities/crypto/py3AES.py",
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/APIs/Python3/eric7.api
--- a/src/eric7/APIs/Python3/eric7.api	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/APIs/Python3/eric7.api	Sun Dec 18 19:33:46 2022 +0100
@@ -1974,23 +1974,9 @@
 eric7.Globals.AppInfo.makeAppInfo?4(argv, name, arg, description, options=None)
 eric7.Globals.configDir?7
 eric7.Globals.dataString?4(size)
-eric7.Globals.desktopName?4()
 eric7.Globals.getConfigDir?4()
 eric7.Globals.getInstallInfoFilePath?4()
-eric7.Globals.getPyQt6ModulesDirectory?4()
-eric7.Globals.getPyQtToolsPath?4(version=5)
-eric7.Globals.getPythonExecutable?4()
-eric7.Globals.getPythonLibraryDirectory?4()
-eric7.Globals.getPythonScriptsDirectory?4()
-eric7.Globals.getQtBinariesPath?4(libexec=False)
 eric7.Globals.getWebBrowserSupport?4()
-eric7.Globals.isGnomeDesktop?4()
-eric7.Globals.isKdeDesktop?4()
-eric7.Globals.isLinuxPlatform?4()
-eric7.Globals.isMacPlatform?4()
-eric7.Globals.isWaylandSession?4()
-eric7.Globals.isWindowsPlatform?4()
-eric7.Globals.qVersionTuple?4()
 eric7.Globals.recentNameBreakpointConditions?7
 eric7.Globals.recentNameBreakpointFiles?7
 eric7.Globals.recentNameFiles?7
@@ -2003,7 +1989,6 @@
 eric7.Globals.recentNameTestFileHistory?7
 eric7.Globals.recentNameTestFramework?7
 eric7.Globals.recentNameTestNameHistory?7
-eric7.Globals.sessionType?4()
 eric7.Globals.setConfigDir?4(d)
 eric7.Globals.settingsNameGlobal?7
 eric7.Globals.settingsNameOrganization?7
@@ -3244,9 +3229,9 @@
 eric7.PipInterface.PipPackagesWidget.PipPackagesWidget.on_refreshDependenciesButton_clicked?4()
 eric7.PipInterface.PipPackagesWidget.PipPackagesWidget.on_requiresButton_toggled?4(checked)
 eric7.PipInterface.PipPackagesWidget.PipPackagesWidget.on_searchButton_clicked?4()
-eric7.PipInterface.PipPackagesWidget.PipPackagesWidget.on_searchEditName_returnPressed?4()
-eric7.PipInterface.PipPackagesWidget.PipPackagesWidget.on_searchEditName_textChanged?4(txt)
 eric7.PipInterface.PipPackagesWidget.PipPackagesWidget.on_searchMoreButton_clicked?4()
+eric7.PipInterface.PipPackagesWidget.PipPackagesWidget.on_searchNameEdit_returnPressed?4()
+eric7.PipInterface.PipPackagesWidget.PipPackagesWidget.on_searchNameEdit_textChanged?4(txt)
 eric7.PipInterface.PipPackagesWidget.PipPackagesWidget.on_searchResultList_itemActivated?4(item, column)
 eric7.PipInterface.PipPackagesWidget.PipPackagesWidget.on_searchResultList_itemSelectionChanged?4()
 eric7.PipInterface.PipPackagesWidget.PipPackagesWidget.on_searchToggleButton_1_toggled?4(checked)
@@ -9301,6 +9286,63 @@
 eric7.SqlBrowser.SqlConnectionWidget.SqlConnectionWidget.showSchema?4()
 eric7.SqlBrowser.SqlConnectionWidget.SqlConnectionWidget.tableActivated?7
 eric7.SqlBrowser.SqlConnectionWidget.SqlConnectionWidget?1(parent=None)
+eric7.SystemUtilities.DesktopUtilities.desktopName?4()
+eric7.SystemUtilities.DesktopUtilities.isGnomeDesktop?4()
+eric7.SystemUtilities.DesktopUtilities.isKdeDesktop?4()
+eric7.SystemUtilities.DesktopUtilities.isWaylandSession?4()
+eric7.SystemUtilities.DesktopUtilities.sessionType?4()
+eric7.SystemUtilities.FileSystemUtilities.absolutePath?4(path, start)
+eric7.SystemUtilities.FileSystemUtilities.absoluteUniversalPath?4(path, start)
+eric7.SystemUtilities.FileSystemUtilities.compactPath?4(path, width, measure=len)
+eric7.SystemUtilities.FileSystemUtilities.direntries?4(path, filesonly=False, pattern=None, followsymlinks=True, checkStop=None)
+eric7.SystemUtilities.FileSystemUtilities.findVolume?4(volumeName, findAll=False)
+eric7.SystemUtilities.FileSystemUtilities.fromNativeSeparators?4(path)
+eric7.SystemUtilities.FileSystemUtilities.getDirs?4(path, excludeDirs)
+eric7.SystemUtilities.FileSystemUtilities.getExecutablePath?4(file)
+eric7.SystemUtilities.FileSystemUtilities.getExecutablePaths?4(file)
+eric7.SystemUtilities.FileSystemUtilities.getVolumeName?4(diskName)
+eric7.SystemUtilities.FileSystemUtilities.getWindowsExecutablePath?4(file)
+eric7.SystemUtilities.FileSystemUtilities.isDrive?4(path)
+eric7.SystemUtilities.FileSystemUtilities.isExecutable?4(exe)
+eric7.SystemUtilities.FileSystemUtilities.isinpath?4(file)
+eric7.SystemUtilities.FileSystemUtilities.joinext?4(prefix, ext)
+eric7.SystemUtilities.FileSystemUtilities.normabsjoinpath?4(a, *p)
+eric7.SystemUtilities.FileSystemUtilities.normcaseabspath?4(path)
+eric7.SystemUtilities.FileSystemUtilities.normcasepath?4(path)
+eric7.SystemUtilities.FileSystemUtilities.normjoinpath?4(a, *p)
+eric7.SystemUtilities.FileSystemUtilities.relativeUniversalPath?4(path, start)
+eric7.SystemUtilities.FileSystemUtilities.samefilepath?4(f1, f2)
+eric7.SystemUtilities.FileSystemUtilities.samepath?4(f1, f2)
+eric7.SystemUtilities.FileSystemUtilities.splitPath?4(name)
+eric7.SystemUtilities.FileSystemUtilities.startswithPath?4(path, start)
+eric7.SystemUtilities.FileSystemUtilities.toNativeSeparators?4(path)
+eric7.SystemUtilities.OSUtilities.getEnvironmentEntry?4(key, default=None)
+eric7.SystemUtilities.OSUtilities.getHomeDir?4()
+eric7.SystemUtilities.OSUtilities.getRealName?4()
+eric7.SystemUtilities.OSUtilities.getUserName?4()
+eric7.SystemUtilities.OSUtilities.hasEnvironmentEntry?4(key)
+eric7.SystemUtilities.OSUtilities.isLinuxPlatform?4()
+eric7.SystemUtilities.OSUtilities.isMacPlatform?4()
+eric7.SystemUtilities.OSUtilities.isWindowsPlatform?4()
+eric7.SystemUtilities.OSUtilities.win32_GetUserName?4()
+eric7.SystemUtilities.OSUtilities.win32_Kill?4(pid)
+eric7.SystemUtilities.OSUtilities.win32_getRealName?4()
+eric7.SystemUtilities.PythonUtilities.determinePythonVersion?4(filename, source, editor=None)
+eric7.SystemUtilities.PythonUtilities.getPythonExecutable?4()
+eric7.SystemUtilities.PythonUtilities.getPythonLibPath?4()
+eric7.SystemUtilities.PythonUtilities.getPythonLibraryDirectory?4()
+eric7.SystemUtilities.PythonUtilities.getPythonScriptsDirectory?4()
+eric7.SystemUtilities.PythonUtilities.getPythonVersion?4()
+eric7.SystemUtilities.QtUtilities.checkPyside?4(variant=2)
+eric7.SystemUtilities.QtUtilities.generatePyQtToolPath?4(toolname, alternatives=None)
+eric7.SystemUtilities.QtUtilities.generatePySideToolPath?4(toolname, variant=2)
+eric7.SystemUtilities.QtUtilities.generateQtToolName?4(toolname)
+eric7.SystemUtilities.QtUtilities.getPyQt6ModulesDirectory?4()
+eric7.SystemUtilities.QtUtilities.getPyQtToolsPath?4(version=5)
+eric7.SystemUtilities.QtUtilities.getQtBinariesPath?4(libexec=False)
+eric7.SystemUtilities.QtUtilities.getQtMacBundle?4(toolname)
+eric7.SystemUtilities.QtUtilities.prepareQtMacBundle?4(toolname, args)
+eric7.SystemUtilities.QtUtilities.qVersionTuple?4()
 eric7.Tasks.Task.Task.TaskType2ColorName?7
 eric7.Tasks.Task.Task.TaskType2IconName?7
 eric7.Tasks.Task.Task.TaskType2MarkersName?7
@@ -10367,12 +10409,8 @@
 eric7.Utilities._percentReplacementFunc?5(matchobj)
 eric7.Utilities._uescape?8
 eric7.Utilities._uunescape?8
-eric7.Utilities.absolutePath?4(path, start)
-eric7.Utilities.absoluteUniversalPath?4(path, start)
-eric7.Utilities.checkPyside?4(variant=2)
 eric7.Utilities.codingBytes_regexps?7
 eric7.Utilities.coding_regexps?7
-eric7.Utilities.compactPath?4(path, width, measure=len)
 eric7.Utilities.configDir?7
 eric7.Utilities.convertLineEnds?4(text, eol)
 eric7.Utilities.crypto.CryptoMarker?7
@@ -10413,8 +10451,6 @@
 eric7.Utilities.decode?4(text)
 eric7.Utilities.decodeBytes?4(buffer)
 eric7.Utilities.decodeString?4(text)
-eric7.Utilities.determinePythonVersion?4(filename, source, editor=None)
-eric7.Utilities.direntries?4(path, filesonly=False, pattern=None, followsymlinks=True, checkStop=None)
 eric7.Utilities.encode?4(text, origEncoding, forcedEncoding="")
 eric7.Utilities.escape_entities?4(m, escmap=_escape_map)
 eric7.Utilities.escape_uentities?4(m)
@@ -10422,70 +10458,33 @@
 eric7.Utilities.extractFlagsFromFile?4(filename)
 eric7.Utilities.extractLineFlags?4(line, startComment=")
 eric7.Utilities.filterAnsiSequences?4(txt)
-eric7.Utilities.findVolume?4(volumeName, findAll=False)
-eric7.Utilities.fromNativeSeparators?4(path)
 eric7.Utilities.generateDistroInfo?4(linesep="\n")
 eric7.Utilities.generatePluginsVersionInfo?4(linesep="\n")
-eric7.Utilities.generatePyQtToolPath?4(toolname, alternatives=None)
-eric7.Utilities.generatePySideToolPath?4(toolname, variant=2)
-eric7.Utilities.generateQtToolName?4(toolname)
 eric7.Utilities.generateVersionInfo?4(linesep="\n")
 eric7.Utilities.getCoverageFileName?4(fn, mustExist=True)
 eric7.Utilities.getCoverageFileNames?4(fn)
-eric7.Utilities.getDirs?4(path, excludeDirs)
-eric7.Utilities.getEnvironmentEntry?4(key, default=None)
-eric7.Utilities.getExecutablePath?4(file)
-eric7.Utilities.getExecutablePaths?4(file)
-eric7.Utilities.getHomeDir?4()
 eric7.Utilities.getPercentReplacement?4(code)
 eric7.Utilities.getPercentReplacementHelp?4()
 eric7.Utilities.getProfileFileName?4(fn, mustExist=True)
 eric7.Utilities.getProfileFileNames?4(fn)
-eric7.Utilities.getPythonLibPath?4()
-eric7.Utilities.getPythonVersion?4()
-eric7.Utilities.getQtMacBundle?4(toolname)
-eric7.Utilities.getRealName?4()
 eric7.Utilities.getSysPath?4(interpreter)
 eric7.Utilities.getTestFileNames?4(fn)
-eric7.Utilities.getUserName?4()
-eric7.Utilities.getVolumeName?4(diskName)
-eric7.Utilities.getWindowsExecutablePath?4(file)
 eric7.Utilities.get_coding?4(text)
 eric7.Utilities.get_codingBytes?4(text)
-eric7.Utilities.hasEnvironmentEntry?4(key)
 eric7.Utilities.html_encode?4(text, pattern=_escape)
 eric7.Utilities.html_udecode?4(text, pattern=_uunescape)
 eric7.Utilities.html_uencode?4(text, pattern=_uescape)
-eric7.Utilities.isDrive?4(path)
-eric7.Utilities.isExecutable?4(exe)
-eric7.Utilities.isinpath?4(file)
-eric7.Utilities.joinext?4(prefix, ext)
 eric7.Utilities.linesep?4()
-eric7.Utilities.normabsjoinpath?4(a, *p)
 eric7.Utilities.normalizeCode?4(codestring)
-eric7.Utilities.normcaseabspath?4(path)
-eric7.Utilities.normcasepath?4(path)
-eric7.Utilities.normjoinpath?4(a, *p)
 eric7.Utilities.parseOptionString?4(s)
-eric7.Utilities.prepareQtMacBundle?4(toolname, args)
 eric7.Utilities.readEncodedFile?4(filename)
 eric7.Utilities.readEncodedFileWithEncoding?4(filename, encoding)
 eric7.Utilities.readEncodedFileWithHash?4(filename)
 eric7.Utilities.readStringFromStream?4(stream)
-eric7.Utilities.relativeUniversalPath?4(path, start)
 eric7.Utilities.rxIndex?4(rx, txt)
-eric7.Utilities.samefilepath?4(f1, f2)
-eric7.Utilities.samepath?4(f1, f2)
-eric7.Utilities.splitPath?4(name)
-eric7.Utilities.startswithPath?4(path, start)
 eric7.Utilities.supportedCodecs?7
-eric7.Utilities.toBool?4(dataStr)
-eric7.Utilities.toNativeSeparators?4(path)
 eric7.Utilities.uic.compileUiFiles?4(directory, recurse=False)
 eric7.Utilities.unescape_uentities?4(m)
-eric7.Utilities.win32_GetUserName?4()
-eric7.Utilities.win32_Kill?4(pid)
-eric7.Utilities.win32_getRealName?4()
 eric7.Utilities.writeEncodedFile?4(filename, text, origEncoding, forcedEncoding="")
 eric7.VCS.CommandOptionsDialog.VcsCommandOptionsDialog.getOptions?4()
 eric7.VCS.CommandOptionsDialog.VcsCommandOptionsDialog?1(vcs, parent=None)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/CodeFormatting/BlackFormattingDialog.py
--- a/src/eric7/CodeFormatting/BlackFormattingDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/CodeFormatting/BlackFormattingDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -25,8 +25,9 @@
     QTreeWidgetItem,
 )
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets import EricMessageBox
+from eric7.SystemUtilities import FileSystemUtilities
 
 from . import BlackUtilities
 from .BlackFormattingAction import BlackFormattingAction
@@ -141,7 +142,7 @@
 
         files = []
         for file in filesList:
-            file = Utilities.fromNativeSeparators(file)
+            file = FileSystemUtilities.fromNativeSeparators(file)
             for filterRegExp in filterRegExps:
                 filterMatch = filterRegExp.search(file)
                 if filterMatch and filterMatch.group(0):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/CondaInterface/Conda.py
--- a/src/eric7/CondaInterface/Conda.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/CondaInterface/Conda.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,8 +14,9 @@
 from PyQt6.QtCore import QCoreApplication, QObject, QProcess, pyqtSignal
 from PyQt6.QtWidgets import QDialog
 
-from eric7 import Globals, Preferences
+from eric7 import Preferences
 from eric7.EricWidgets import EricMessageBox
+from eric7.SystemUtilities import OSUtilities
 
 from . import condaVersion, rootPrefix
 from .CondaExecDialog import CondaExecDialog
@@ -83,7 +84,7 @@
             for pathPrefix in pathPrefixes:
                 python = (
                     os.path.join(pathPrefix, "python.exe")
-                    if Globals.isWindowsPlatform()
+                    if OSUtilities.isWindowsPlatform()
                     else os.path.join(pathPrefix, "bin", "python")
                 )
                 if os.path.exists(python):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/DataViews/CodeMetricsDialog.py
--- a/src/eric7/DataViews/CodeMetricsDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/DataViews/CodeMetricsDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -22,8 +22,8 @@
     QTreeWidgetItem,
 )
 
-from eric7 import Utilities
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import FileSystemUtilities
 
 from . import CodeMetrics
 from .Ui_CodeMetricsDialog import Ui_CodeMetricsDialog
@@ -147,7 +147,7 @@
         if isinstance(fn, list):
             files = fn
         elif os.path.isdir(fn):
-            files = Utilities.direntries(fn, True, "*.py", False)
+            files = FileSystemUtilities.direntries(fn, True, "*.py", False)
         else:
             files = [fn]
         files.sort()
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/DataViews/PyCoverageDialog.py
--- a/src/eric7/DataViews/PyCoverageDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/DataViews/PyCoverageDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -21,11 +21,11 @@
     QTreeWidgetItem,
 )
 
-from eric7 import Utilities
 from eric7.DebugClients.Python.coverage import Coverage
 from eric7.DebugClients.Python.coverage.misc import CoverageException
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_PyCoverageDialog import Ui_PyCoverageDialog
 
@@ -196,7 +196,7 @@
             files = fn
             self.path = os.path.dirname(cfn)
         elif os.path.isdir(fn):
-            files = Utilities.direntries(fn, True, "*.py", False)
+            files = FileSystemUtilities.direntries(fn, True, "*.py", False)
             self.path = fn
         else:
             files = [fn]
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/DataViews/PyProfileDialog.py
--- a/src/eric7/DataViews/PyProfileDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/DataViews/PyProfileDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -21,8 +21,8 @@
     QTreeWidgetItem,
 )
 
-from eric7 import Utilities
 from eric7.EricWidgets import EricMessageBox
+from eric7.SystemUtilities import PythonUtilities
 
 from .Ui_PyProfileDialog import Ui_PyProfileDialog
 
@@ -80,7 +80,7 @@
         self.cancelled = False
         self.exclude = True
         self.ericpath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-        self.pyLibPath = Utilities.getPythonLibPath()
+        self.pyLibPath = PythonUtilities.getPythonLibPath()
 
         self.summaryList.headerItem().setText(self.summaryList.columnCount(), "")
         self.resultList.headerItem().setText(self.resultList.columnCount(), "")
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Debugger/DebugUI.py
--- a/src/eric7/Debugger/DebugUI.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Debugger/DebugUI.py	Sun Dec 18 19:33:46 2022 +0100
@@ -20,6 +20,7 @@
 from eric7.EricGui.EricAction import EricAction, createActionGroup
 from eric7.EricWidgets import EricMessageBox
 from eric7.Globals import recentNameBreakpointConditions
+from eric7.SystemUtilities import FileSystemUtilities
 from eric7.UI import Config
 from eric7.UI.Info import Program
 from eric7.UI.NotificationWidget import NotificationTypes
@@ -1877,7 +1878,7 @@
             bpSuffix = " : {0:d}{1}".format(line, formattedCond)
             act = self.breakpointsMenu.addAction(
                 "{0}{1}".format(
-                    Utilities.compactPath(
+                    FileSystemUtilities.compactPath(
                         filename, self.ui.maxMenuFilePathLen - len(bpSuffix)
                     ),
                     bpSuffix,
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Debugger/DebuggerInterfacePython.py
--- a/src/eric7/Debugger/DebuggerInterfacePython.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Debugger/DebuggerInterfacePython.py	Sun Dec 18 19:33:46 2022 +0100
@@ -15,10 +15,11 @@
 
 from PyQt6.QtCore import QObject, QProcess, QProcessEnvironment, QTimer
 
-from eric7 import Globals, Preferences, Utilities
+from eric7 import Preferences, Utilities
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.Globals import getConfig
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities, PythonUtilities
 
 from . import DebugClientCapabilities
 
@@ -190,7 +191,7 @@
             execPath = venvManager.getVirtualenvExecPath(venvName)
         if interpreter == "":
             # use the interpreter used to run eric for identical variants
-            interpreter = Globals.getPythonExecutable()
+            interpreter = PythonUtilities.getPythonExecutable()
         if interpreter == "":
             EricMessageBox.critical(
                 None,
@@ -232,15 +233,15 @@
                 if multiprocessEnabled:
                     args.append(multiprocessEnabled)
                 args.extend([str(port), redirect, ipaddr])
-                if Utilities.isWindowsPlatform():
+                if OSUtilities.isWindowsPlatform():
                     if not os.path.splitext(args[0])[1]:
                         for ext in [".exe", ".com", ".cmd", ".bat"]:
-                            prog = Utilities.getExecutablePath(args[0] + ext)
+                            prog = FileSystemUtilities.getExecutablePath(args[0] + ext)
                             if prog:
                                 args[0] = prog
                                 break
                 else:
-                    args[0] = Utilities.getExecutablePath(args[0])
+                    args[0] = FileSystemUtilities.getExecutablePath(args[0])
                 process = self.__startProcess(args[0], args[1:], workingDir=workingDir)
                 if process is None:
                     EricMessageBox.critical(
@@ -301,7 +302,7 @@
                 if multiprocessEnabled:
                     args.append(multiprocessEnabled)
                 args.extend([str(port), "0", ipaddr])
-                args[0] = Utilities.getExecutablePath(args[0])
+                args[0] = FileSystemUtilities.getExecutablePath(args[0])
                 process = self.__startProcess(
                     args[0], args[1:], clientEnv, workingDir=workingDir
                 )
@@ -445,15 +446,15 @@
                 if multiprocessEnabled:
                     args.append(multiprocessEnabled)
                 args.extend([str(port), redirect, ipaddr])
-                if Utilities.isWindowsPlatform():
+                if OSUtilities.isWindowsPlatform():
                     if not os.path.splitext(args[0])[1]:
                         for ext in [".exe", ".com", ".cmd", ".bat"]:
-                            prog = Utilities.getExecutablePath(args[0] + ext)
+                            prog = FileSystemUtilities.getExecutablePath(args[0] + ext)
                             if prog:
                                 args[0] = prog
                                 break
                 else:
-                    args[0] = Utilities.getExecutablePath(args[0])
+                    args[0] = FileSystemUtilities.getExecutablePath(args[0])
                 process = self.__startProcess(args[0], args[1:], workingDir=workingDir)
                 if process is None:
                     EricMessageBox.critical(
@@ -514,7 +515,7 @@
                 if multiprocessEnabled:
                     args.append(multiprocessEnabled)
                 args.extend([str(port), "0", ipaddr])
-                args[0] = Utilities.getExecutablePath(args[0])
+                args[0] = FileSystemUtilities.getExecutablePath(args[0])
                 process = self.__startProcess(
                     args[0], args[1:], clientEnv, workingDir=workingDir
                 )
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Documentation/Help/source.qch
Binary file src/eric7/Documentation/Help/source.qch has changed
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Documentation/Help/source.qhp
--- a/src/eric7/Documentation/Help/source.qhp	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Documentation/Help/source.qhp	Sun Dec 18 19:33:46 2022 +0100
@@ -1051,6 +1051,14 @@
             <section title="eric7.SqlBrowser.SqlConnectionDialog" ref="eric7.SqlBrowser.SqlConnectionDialog.html" />
             <section title="eric7.SqlBrowser.SqlConnectionWidget" ref="eric7.SqlBrowser.SqlConnectionWidget.html" />
           </section>
+          <section title="eric7.SystemUtilities" ref="index-eric7.SystemUtilities.html">
+            <section title="eric7.SystemUtilities.DesktopUtilities" ref="eric7.SystemUtilities.DesktopUtilities.html" />
+            <section title="eric7.SystemUtilities.FileSystemUtilities" ref="eric7.SystemUtilities.FileSystemUtilities.html" />
+            <section title="eric7.SystemUtilities.OSUtilities" ref="eric7.SystemUtilities.OSUtilities.html" />
+            <section title="eric7.SystemUtilities.PySideImporter" ref="eric7.SystemUtilities.PySideImporter.html" />
+            <section title="eric7.SystemUtilities.PythonUtilities" ref="eric7.SystemUtilities.PythonUtilities.html" />
+            <section title="eric7.SystemUtilities.QtUtilities" ref="eric7.SystemUtilities.QtUtilities.html" />
+          </section>
           <section title="eric7.Tasks" ref="index-eric7.Tasks.html">
             <section title="eric7.Tasks.Task" ref="eric7.Tasks.Task.html" />
             <section title="eric7.Tasks.TaskFilter" ref="eric7.Tasks.TaskFilter.html" />
@@ -1154,7 +1162,6 @@
             <section title="eric7.Utilities.ModuleParser" ref="eric7.Utilities.ModuleParser.html" />
             <section title="eric7.Utilities.MouseUtilities" ref="eric7.Utilities.MouseUtilities.html" />
             <section title="eric7.Utilities.PasswordChecker" ref="eric7.Utilities.PasswordChecker.html" />
-            <section title="eric7.Utilities.PySideImporter" ref="eric7.Utilities.PySideImporter.html" />
             <section title="eric7.Utilities.__init__" ref="eric7.Utilities.__init__.html" />
             <section title="eric7.Utilities.uic" ref="eric7.Utilities.uic.html" />
           </section>
@@ -3902,6 +3909,7 @@
       <keyword name="DeleteFilesConfirmationDialog (Constructor)" id="DeleteFilesConfirmationDialog (Constructor)" ref="eric7.UI.DeleteFilesConfirmationDialog.html#DeleteFilesConfirmationDialog.__init__" />
       <keyword name="DeleteFilesConfirmationDialog (Module)" id="DeleteFilesConfirmationDialog (Module)" ref="eric7.UI.DeleteFilesConfirmationDialog.html" />
       <keyword name="DeleteFilesConfirmationDialog.on_buttonBox_clicked" id="DeleteFilesConfirmationDialog.on_buttonBox_clicked" ref="eric7.UI.DeleteFilesConfirmationDialog.html#DeleteFilesConfirmationDialog.on_buttonBox_clicked" />
+      <keyword name="DesktopUtilities (Module)" id="DesktopUtilities (Module)" ref="eric7.SystemUtilities.DesktopUtilities.html" />
       <keyword name="DictResolver" id="DictResolver" ref="eric7.DebugClients.Python.DebugVariables.html#DictResolver" />
       <keyword name="DictResolver.getVariableList" id="DictResolver.getVariableList" ref="eric7.DebugClients.Python.DebugVariables.html#DictResolver.getVariableList" />
       <keyword name="DictResolver.keyToStr" id="DictResolver.keyToStr" ref="eric7.DebugClients.Python.DebugVariables.html#DictResolver.keyToStr" />
@@ -6175,6 +6183,7 @@
       <keyword name="FileDialogWizardDialog.on_buttonBox_clicked" id="FileDialogWizardDialog.on_buttonBox_clicked" ref="eric7.Plugins.WizardPlugins.FileDialogWizard.FileDialogWizardDialog.html#FileDialogWizardDialog.on_buttonBox_clicked" />
       <keyword name="FileDialogWizardDialog.on_pyqtComboBox_currentIndexChanged" id="FileDialogWizardDialog.on_pyqtComboBox_currentIndexChanged" ref="eric7.Plugins.WizardPlugins.FileDialogWizard.FileDialogWizardDialog.html#FileDialogWizardDialog.on_pyqtComboBox_currentIndexChanged" />
       <keyword name="FileReport" id="FileReport" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#FileReport" />
+      <keyword name="FileSystemUtilities (Module)" id="FileSystemUtilities (Module)" ref="eric7.SystemUtilities.FileSystemUtilities.html" />
       <keyword name="FiletypeAssociationDialog" id="FiletypeAssociationDialog" ref="eric7.Project.FiletypeAssociationDialog.html#FiletypeAssociationDialog" />
       <keyword name="FiletypeAssociationDialog (Constructor)" id="FiletypeAssociationDialog (Constructor)" ref="eric7.Project.FiletypeAssociationDialog.html#FiletypeAssociationDialog.__init__" />
       <keyword name="FiletypeAssociationDialog (Module)" id="FiletypeAssociationDialog (Module)" ref="eric7.Project.FiletypeAssociationDialog.html" />
@@ -11176,6 +11185,7 @@
       <keyword name="NumbersWidget.on_octOutButton_clicked" id="NumbersWidget.on_octOutButton_clicked" ref="eric7.UI.NumbersWidget.html#NumbersWidget.on_octOutButton_clicked" />
       <keyword name="NumbersWidget.on_sizeBox_valueChanged" id="NumbersWidget.on_sizeBox_valueChanged" ref="eric7.UI.NumbersWidget.html#NumbersWidget.on_sizeBox_valueChanged" />
       <keyword name="NumpydocGenerator (Module)" id="NumpydocGenerator (Module)" ref="eric7.QScintilla.DocstringGenerator.NumpydocGenerator.html" />
+      <keyword name="OSUtilities (Module)" id="OSUtilities (Module)" ref="eric7.SystemUtilities.OSUtilities.html" />
       <keyword name="OpenPagesWidget" id="OpenPagesWidget" ref="eric7.HelpViewer.OpenPagesWidget.html#OpenPagesWidget" />
       <keyword name="OpenPagesWidget (Constructor)" id="OpenPagesWidget (Constructor)" ref="eric7.HelpViewer.OpenPagesWidget.html#OpenPagesWidget.__init__" />
       <keyword name="OpenPagesWidget (Module)" id="OpenPagesWidget (Module)" ref="eric7.HelpViewer.OpenPagesWidget.html" />
@@ -11691,9 +11701,9 @@
       <keyword name="PipPackagesWidget.on_refreshDependenciesButton_clicked" id="PipPackagesWidget.on_refreshDependenciesButton_clicked" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.on_refreshDependenciesButton_clicked" />
       <keyword name="PipPackagesWidget.on_requiresButton_toggled" id="PipPackagesWidget.on_requiresButton_toggled" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.on_requiresButton_toggled" />
       <keyword name="PipPackagesWidget.on_searchButton_clicked" id="PipPackagesWidget.on_searchButton_clicked" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.on_searchButton_clicked" />
-      <keyword name="PipPackagesWidget.on_searchEditName_returnPressed" id="PipPackagesWidget.on_searchEditName_returnPressed" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.on_searchEditName_returnPressed" />
-      <keyword name="PipPackagesWidget.on_searchEditName_textChanged" id="PipPackagesWidget.on_searchEditName_textChanged" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.on_searchEditName_textChanged" />
       <keyword name="PipPackagesWidget.on_searchMoreButton_clicked" id="PipPackagesWidget.on_searchMoreButton_clicked" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.on_searchMoreButton_clicked" />
+      <keyword name="PipPackagesWidget.on_searchNameEdit_returnPressed" id="PipPackagesWidget.on_searchNameEdit_returnPressed" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.on_searchNameEdit_returnPressed" />
+      <keyword name="PipPackagesWidget.on_searchNameEdit_textChanged" id="PipPackagesWidget.on_searchNameEdit_textChanged" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.on_searchNameEdit_textChanged" />
       <keyword name="PipPackagesWidget.on_searchResultList_itemActivated" id="PipPackagesWidget.on_searchResultList_itemActivated" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.on_searchResultList_itemActivated" />
       <keyword name="PipPackagesWidget.on_searchResultList_itemSelectionChanged" id="PipPackagesWidget.on_searchResultList_itemSelectionChanged" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.on_searchResultList_itemSelectionChanged" />
       <keyword name="PipPackagesWidget.on_searchToggleButton_1_toggled" id="PipPackagesWidget.on_searchToggleButton_1_toggled" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.on_searchToggleButton_1_toggled" />
@@ -12868,7 +12878,7 @@
       <keyword name="PyRegExpWizardWidget.on_wordboundButton_clicked" id="PyRegExpWizardWidget.on_wordboundButton_clicked" ref="eric7.Plugins.WizardPlugins.PyRegExpWizard.PyRegExpWizardDialog.html#PyRegExpWizardWidget.on_wordboundButton_clicked" />
       <keyword name="PyRegExpWizardWindow" id="PyRegExpWizardWindow" ref="eric7.Plugins.WizardPlugins.PyRegExpWizard.PyRegExpWizardDialog.html#PyRegExpWizardWindow" />
       <keyword name="PyRegExpWizardWindow (Constructor)" id="PyRegExpWizardWindow (Constructor)" ref="eric7.Plugins.WizardPlugins.PyRegExpWizard.PyRegExpWizardDialog.html#PyRegExpWizardWindow.__init__" />
-      <keyword name="PySideImporter (Module)" id="PySideImporter (Module)" ref="eric7.Utilities.PySideImporter.html" />
+      <keyword name="PySideImporter (Module)" id="PySideImporter (Module)" ref="eric7.SystemUtilities.PySideImporter.html" />
       <keyword name="PySvnProjectHelper" id="PySvnProjectHelper" ref="eric7.Plugins.VcsPlugins.vcsPySvn.ProjectHelper.html#PySvnProjectHelper" />
       <keyword name="PySvnProjectHelper (Constructor)" id="PySvnProjectHelper (Constructor)" ref="eric7.Plugins.VcsPlugins.vcsPySvn.ProjectHelper.html#PySvnProjectHelper.__init__" />
       <keyword name="PySvnProjectHelper.__svnBranchList" id="PySvnProjectHelper.__svnBranchList" ref="eric7.Plugins.VcsPlugins.vcsPySvn.ProjectHelper.html#PySvnProjectHelper.__svnBranchList" />
@@ -12987,6 +12997,7 @@
       <keyword name="PythonPage (Module)" id="PythonPage (Module)" ref="eric7.Preferences.ConfigurationPages.PythonPage.html" />
       <keyword name="PythonPage.on_refreshButton_clicked" id="PythonPage.on_refreshButton_clicked" ref="eric7.Preferences.ConfigurationPages.PythonPage.html#PythonPage.on_refreshButton_clicked" />
       <keyword name="PythonPage.save" id="PythonPage.save" ref="eric7.Preferences.ConfigurationPages.PythonPage.html#PythonPage.save" />
+      <keyword name="PythonUtilities (Module)" id="PythonUtilities (Module)" ref="eric7.SystemUtilities.PythonUtilities.html" />
       <keyword name="QProcessExtension (Module)" id="QProcessExtension (Module)" ref="eric7.DebugClients.Python.QProcessExtension.html" />
       <keyword name="QProcessWrapper" id="QProcessWrapper" ref="eric7.DebugClients.Python.QProcessExtension.html#QProcessWrapper" />
       <keyword name="QProcessWrapper (Constructor)" id="QProcessWrapper (Constructor)" ref="eric7.DebugClients.Python.QProcessExtension.html#QProcessWrapper.__init__" />
@@ -13264,6 +13275,7 @@
       <keyword name="QtResolver" id="QtResolver" ref="eric7.DebugClients.Python.DebugVariables.html#QtResolver" />
       <keyword name="QtResolver.getVariableList" id="QtResolver.getVariableList" ref="eric7.DebugClients.Python.DebugVariables.html#QtResolver.getVariableList" />
       <keyword name="QtResolver.resolve" id="QtResolver.resolve" ref="eric7.DebugClients.Python.DebugVariables.html#QtResolver.resolve" />
+      <keyword name="QtUtilities (Module)" id="QtUtilities (Module)" ref="eric7.SystemUtilities.QtUtilities.html" />
       <keyword name="Queues" id="Queues" ref="eric7.Plugins.VcsPlugins.vcsMercurial.QueuesExtension.queues.html#Queues" />
       <keyword name="Queues (Constructor)" id="Queues (Constructor)" ref="eric7.Plugins.VcsPlugins.vcsMercurial.QueuesExtension.queues.html#Queues.__init__" />
       <keyword name="Queues.__getCommitMessage" id="Queues.__getCommitMessage" ref="eric7.Plugins.VcsPlugins.vcsMercurial.QueuesExtension.queues.html#Queues.__getCommitMessage" />
@@ -15697,6 +15709,7 @@
       <keyword name="SysVersionVisitor.visit_ImportFrom" id="SysVersionVisitor.visit_ImportFrom" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#SysVersionVisitor.visit_ImportFrom" />
       <keyword name="SysVersionVisitor.visit_Name" id="SysVersionVisitor.visit_Name" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#SysVersionVisitor.visit_Name" />
       <keyword name="SysVersionVisitor.visit_Subscript" id="SysVersionVisitor.visit_Subscript" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#SysVersionVisitor.visit_Subscript" />
+      <keyword name="SystemUtilities (Package)" id="SystemUtilities (Package)" ref="index-eric7.SystemUtilities.html" />
       <keyword name="TERMINAL" id="TERMINAL" ref="eric7.EricGui.EricGenericDiffHighlighter.html#TERMINAL" />
       <keyword name="TRPreviewer" id="TRPreviewer" ref="eric7.Tools.TRPreviewer.html#TRPreviewer" />
       <keyword name="TRPreviewer (Constructor)" id="TRPreviewer (Constructor)" ref="eric7.Tools.TRPreviewer.html#TRPreviewer.__init__" />
@@ -18473,8 +18486,8 @@
       <keyword name="_weakCryptoKeySizePycrypto" id="_weakCryptoKeySizePycrypto" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.weakCryptographicKey.html#_weakCryptoKeySizePycrypto" />
       <keyword name="aboutBlack" id="aboutBlack" ref="eric7.CodeFormatting.BlackUtilities.html#aboutBlack" />
       <keyword name="aboutIsort" id="aboutIsort" ref="eric7.CodeFormatting.IsortUtilities.html#aboutIsort" />
-      <keyword name="absolutePath" id="absolutePath" ref="eric7.Utilities.__init__.html#absolutePath" />
-      <keyword name="absoluteUniversalPath" id="absoluteUniversalPath" ref="eric7.Utilities.__init__.html#absoluteUniversalPath" />
+      <keyword name="absolutePath" id="absolutePath" ref="eric7.SystemUtilities.FileSystemUtilities.html#absolutePath" />
+      <keyword name="absoluteUniversalPath" id="absoluteUniversalPath" ref="eric7.SystemUtilities.FileSystemUtilities.html#absoluteUniversalPath" />
       <keyword name="addActions" id="addActions" ref="eric7.EricGui.EricAction.html#addActions" />
       <keyword name="addCycloneDXDependencies" id="addCycloneDXDependencies" ref="eric7.CycloneDXInterface.CycloneDXUtilities.html#addCycloneDXDependencies" />
       <keyword name="addCycloneDXVulnerabilities" id="addCycloneDXVulnerabilities" ref="eric7.CycloneDXInterface.CycloneDXUtilities.html#addCycloneDXVulnerabilities" />
@@ -18526,7 +18539,7 @@
       <keyword name="checkOtherFunctionWithShell" id="checkOtherFunctionWithShell" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.injectionShell.html#checkOtherFunctionWithShell" />
       <keyword name="checkParamikoCalls" id="checkParamikoCalls" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.injectionParamiko.html#checkParamikoCalls" />
       <keyword name="checkPotentialRisk" id="checkPotentialRisk" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.djangoXssVulnerability.html#checkPotentialRisk" />
-      <keyword name="checkPyside" id="checkPyside" ref="eric7.Utilities.__init__.html#checkPyside" />
+      <keyword name="checkPyside" id="checkPyside" ref="eric7.SystemUtilities.QtUtilities.html#checkPyside" />
       <keyword name="checkRequestWithouTimeout" id="checkRequestWithouTimeout" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.requestWithoutTimeout.html#checkRequestWithouTimeout" />
       <keyword name="checkSshNoHostKeyVerification" id="checkSshNoHostKeyVerification" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.sshNoHostKeyVerification.html#checkSshNoHostKeyVerification" />
       <keyword name="checkSslWithoutVersion" id="checkSslWithoutVersion" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.insecureSslTls.html#checkSslWithoutVersion" />
@@ -18550,7 +18563,7 @@
       <keyword name="closehead (Module)" id="closehead (Module)" ref="eric7.Plugins.VcsPlugins.vcsMercurial.CloseheadExtension.closehead.html" />
       <keyword name="codeStyleBatchCheck" id="codeStyleBatchCheck" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.CodeStyleChecker.html#codeStyleBatchCheck" />
       <keyword name="codeStyleCheck" id="codeStyleCheck" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.CodeStyleChecker.html#codeStyleCheck" />
-      <keyword name="compactPath" id="compactPath" ref="eric7.Utilities.__init__.html#compactPath" />
+      <keyword name="compactPath" id="compactPath" ref="eric7.SystemUtilities.FileSystemUtilities.html#compactPath" />
       <keyword name="comparison_negative" id="comparison_negative" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#comparison_negative" />
       <keyword name="comparison_to_singleton" id="comparison_to_singleton" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#comparison_to_singleton" />
       <keyword name="comparison_type" id="comparison_type" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#comparison_type" />
@@ -18766,9 +18779,9 @@
       <keyword name="decoratedName" id="decoratedName" ref="eric7.MicroPython.MicroPythonFileSystemUtilities.html#decoratedName" />
       <keyword name="decryptData" id="decryptData" ref="eric7.Utilities.crypto.py3AES.html#decryptData" />
       <keyword name="deepgetattr" id="deepgetattr" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.SecurityUtils.html#deepgetattr" />
-      <keyword name="desktopName" id="desktopName" ref="eric7.Globals.__init__.html#desktopName" />
-      <keyword name="determinePythonVersion" id="determinePythonVersion" ref="eric7.Utilities.__init__.html#determinePythonVersion" />
-      <keyword name="direntries" id="direntries" ref="eric7.Utilities.__init__.html#direntries" />
+      <keyword name="desktopName" id="desktopName" ref="eric7.SystemUtilities.DesktopUtilities.html#desktopName" />
+      <keyword name="determinePythonVersion" id="determinePythonVersion" ref="eric7.SystemUtilities.PythonUtilities.html#determinePythonVersion" />
+      <keyword name="direntries" id="direntries" ref="eric7.SystemUtilities.FileSystemUtilities.html#direntries" />
       <keyword name="displayString" id="displayString" ref="eric7.Plugins.PluginVcsGit.html#displayString" />
       <keyword name="displayString" id="displayString" ref="eric7.Plugins.PluginVcsMercurial.html#displayString" />
       <keyword name="displayString" id="displayString" ref="eric7.Plugins.PluginVcsPySvn.html#displayString" />
@@ -18845,14 +18858,14 @@
       <keyword name="filterMessage" id="filterMessage" ref="eric7.EricWidgets.EricErrorMessage.html#filterMessage" />
       <keyword name="filter_string" id="filter_string" ref="eric7.PipInterface.piplicenses.html#filter_string" />
       <keyword name="findCyccloneDXComponent" id="findCyccloneDXComponent" ref="eric7.CycloneDXInterface.CycloneDXUtilities.html#findCyccloneDXComponent" />
-      <keyword name="findVolume" id="findVolume" ref="eric7.Utilities.__init__.html#findVolume" />
+      <keyword name="findVolume" id="findVolume" ref="eric7.SystemUtilities.FileSystemUtilities.html#findVolume" />
       <keyword name="find_license_from_classifier" id="find_license_from_classifier" ref="eric7.PipInterface.piplicenses.html#find_license_from_classifier" />
       <keyword name="find_module" id="find_module" ref="eric7.Utilities.ClassBrowsers.__init__.html#find_module" />
       <keyword name="find_module" id="find_module" ref="eric7.Utilities.ModuleParser.html#find_module" />
       <keyword name="flaskDebug (Module)" id="flaskDebug (Module)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.flaskDebug.html" />
       <keyword name="formatTime" id="formatTime" ref="eric7.Plugins.VcsPlugins.vcsPySvn.SvnUtilities.html#formatTime" />
       <keyword name="formatargvalues" id="formatargvalues" ref="eric7.DebugClients.Python.DebugUtilities.html#formatargvalues" />
-      <keyword name="fromNativeSeparators" id="fromNativeSeparators" ref="eric7.Utilities.__init__.html#fromNativeSeparators" />
+      <keyword name="fromNativeSeparators" id="fromNativeSeparators" ref="eric7.SystemUtilities.FileSystemUtilities.html#fromNativeSeparators" />
       <keyword name="frozen_req_from_dist" id="frozen_req_from_dist" ref="eric7.PipInterface.pipdeptree.html#frozen_req_from_dist" />
       <keyword name="fstat" id="fstat" ref="eric7.MicroPython.MicroPythonFileSystemUtilities.html#fstat" />
       <keyword name="generalBindAllInterfaces (Module)" id="generalBindAllInterfaces (Module)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.generalBindAllInterfaces.html" />
@@ -18866,9 +18879,9 @@
       <keyword name="generateDoc" id="generateDoc" ref="eric7.QScintilla.DocstringGenerator.NumpydocGenerator.html#generateDoc" />
       <keyword name="generateDoc" id="generateDoc" ref="eric7.QScintilla.DocstringGenerator.SphinxdocGenerator.html#generateDoc" />
       <keyword name="generatePluginsVersionInfo" id="generatePluginsVersionInfo" ref="eric7.Utilities.__init__.html#generatePluginsVersionInfo" />
-      <keyword name="generatePyQtToolPath" id="generatePyQtToolPath" ref="eric7.Utilities.__init__.html#generatePyQtToolPath" />
-      <keyword name="generatePySideToolPath" id="generatePySideToolPath" ref="eric7.Utilities.__init__.html#generatePySideToolPath" />
-      <keyword name="generateQtToolName" id="generateQtToolName" ref="eric7.Utilities.__init__.html#generateQtToolName" />
+      <keyword name="generatePyQtToolPath" id="generatePyQtToolPath" ref="eric7.SystemUtilities.QtUtilities.html#generatePyQtToolPath" />
+      <keyword name="generatePySideToolPath" id="generatePySideToolPath" ref="eric7.SystemUtilities.QtUtilities.html#generatePySideToolPath" />
+      <keyword name="generateQtToolName" id="generateQtToolName" ref="eric7.SystemUtilities.QtUtilities.html#generateQtToolName" />
       <keyword name="generateVersionInfo" id="generateVersionInfo" ref="eric7.Utilities.__init__.html#generateVersionInfo" />
       <keyword name="getAllImages" id="getAllImages" ref="eric7.WebBrowser.Tools.Scripts.html#getAllImages" />
       <keyword name="getAllMetaAttributes" id="getAllMetaAttributes" ref="eric7.WebBrowser.Tools.Scripts.html#getAllMetaAttributes" />
@@ -18931,7 +18944,7 @@
       <keyword name="getDevice" id="getDevice" ref="eric7.MicroPython.MicroPythonDevices.html#getDevice" />
       <keyword name="getDeviceIcon" id="getDeviceIcon" ref="eric7.MicroPython.MicroPythonDevices.html#getDeviceIcon" />
       <keyword name="getDiffColour" id="getDiffColour" ref="eric7.Preferences.__init__.html#getDiffColour" />
-      <keyword name="getDirs" id="getDirs" ref="eric7.Utilities.__init__.html#getDirs" />
+      <keyword name="getDirs" id="getDirs" ref="eric7.SystemUtilities.FileSystemUtilities.html#getDirs" />
       <keyword name="getDocstringGenerator" id="getDocstringGenerator" ref="eric7.QScintilla.DocstringGenerator.__init__.html#getDocstringGenerator" />
       <keyword name="getDocuViewer" id="getDocuViewer" ref="eric7.Preferences.__init__.html#getDocuViewer" />
       <keyword name="getEditor" id="getEditor" ref="eric7.Preferences.__init__.html#getEditor" />
@@ -18944,9 +18957,9 @@
       <keyword name="getEditorOtherFonts" id="getEditorOtherFonts" ref="eric7.Preferences.__init__.html#getEditorOtherFonts" />
       <keyword name="getEditorTyping" id="getEditorTyping" ref="eric7.Preferences.__init__.html#getEditorTyping" />
       <keyword name="getEngineIcon" id="getEngineIcon" ref="eric7.Plugins.UiExtensionPlugins.Translator.TranslatorEngines.__init__.html#getEngineIcon" />
-      <keyword name="getEnvironmentEntry" id="getEnvironmentEntry" ref="eric7.Utilities.__init__.html#getEnvironmentEntry" />
-      <keyword name="getExecutablePath" id="getExecutablePath" ref="eric7.Utilities.__init__.html#getExecutablePath" />
-      <keyword name="getExecutablePaths" id="getExecutablePaths" ref="eric7.Utilities.__init__.html#getExecutablePaths" />
+      <keyword name="getEnvironmentEntry" id="getEnvironmentEntry" ref="eric7.SystemUtilities.OSUtilities.html#getEnvironmentEntry" />
+      <keyword name="getExecutablePath" id="getExecutablePath" ref="eric7.SystemUtilities.FileSystemUtilities.html#getExecutablePath" />
+      <keyword name="getExecutablePaths" id="getExecutablePaths" ref="eric7.SystemUtilities.FileSystemUtilities.html#getExecutablePaths" />
       <keyword name="getExistingDirectory" id="getExistingDirectory" ref="eric7.EricWidgets.EricFileDialog.html#getExistingDirectory" />
       <keyword name="getExistingDirectoryPath" id="getExistingDirectoryPath" ref="eric7.EricWidgets.EricFileDialog.html#getExistingDirectoryPath" />
       <keyword name="getExporter" id="getExporter" ref="eric7.QScintilla.Exporters.__init__.html#getExporter" />
@@ -18961,7 +18974,7 @@
       <keyword name="getHelp" id="getHelp" ref="eric7.Preferences.__init__.html#getHelp" />
       <keyword name="getHexEditor" id="getHexEditor" ref="eric7.Preferences.__init__.html#getHexEditor" />
       <keyword name="getHgExecutable" id="getHgExecutable" ref="eric7.Plugins.VcsPlugins.vcsMercurial.HgUtilities.html#getHgExecutable" />
-      <keyword name="getHomeDir" id="getHomeDir" ref="eric7.Utilities.__init__.html#getHomeDir" />
+      <keyword name="getHomeDir" id="getHomeDir" ref="eric7.SystemUtilities.OSUtilities.html#getHomeDir" />
       <keyword name="getHtmlPage" id="getHtmlPage" ref="eric7.WebBrowser.Tools.WebBrowserTools.html#getHtmlPage" />
       <keyword name="getIcon" id="getIcon" ref="eric7.EricGui.EricPixmapCache.html#getIcon" />
       <keyword name="getIcon" id="getIcon" ref="eric7.Utilities.ClassBrowsers.__init__.html#getIcon" />
@@ -19016,21 +19029,21 @@
       <keyword name="getProject" id="getProject" ref="eric7.Preferences.__init__.html#getProject" />
       <keyword name="getProjectBrowserColour" id="getProjectBrowserColour" ref="eric7.Preferences.__init__.html#getProjectBrowserColour" />
       <keyword name="getProjectBrowsers" id="getProjectBrowsers" ref="eric7.Preferences.__init__.html#getProjectBrowsers" />
-      <keyword name="getPyQt6ModulesDirectory" id="getPyQt6ModulesDirectory" ref="eric7.Globals.__init__.html#getPyQt6ModulesDirectory" />
-      <keyword name="getPyQtToolsPath" id="getPyQtToolsPath" ref="eric7.Globals.__init__.html#getPyQtToolsPath" />
+      <keyword name="getPyQt6ModulesDirectory" id="getPyQt6ModulesDirectory" ref="eric7.SystemUtilities.QtUtilities.html#getPyQt6ModulesDirectory" />
+      <keyword name="getPyQtToolsPath" id="getPyQtToolsPath" ref="eric7.SystemUtilities.QtUtilities.html#getPyQtToolsPath" />
       <keyword name="getPython" id="getPython" ref="eric7.Preferences.__init__.html#getPython" />
-      <keyword name="getPythonExecutable" id="getPythonExecutable" ref="eric7.Globals.__init__.html#getPythonExecutable" />
-      <keyword name="getPythonLibPath" id="getPythonLibPath" ref="eric7.Utilities.__init__.html#getPythonLibPath" />
-      <keyword name="getPythonLibraryDirectory" id="getPythonLibraryDirectory" ref="eric7.Globals.__init__.html#getPythonLibraryDirectory" />
-      <keyword name="getPythonScriptsDirectory" id="getPythonScriptsDirectory" ref="eric7.Globals.__init__.html#getPythonScriptsDirectory" />
-      <keyword name="getPythonVersion" id="getPythonVersion" ref="eric7.Utilities.__init__.html#getPythonVersion" />
+      <keyword name="getPythonExecutable" id="getPythonExecutable" ref="eric7.SystemUtilities.PythonUtilities.html#getPythonExecutable" />
+      <keyword name="getPythonLibPath" id="getPythonLibPath" ref="eric7.SystemUtilities.PythonUtilities.html#getPythonLibPath" />
+      <keyword name="getPythonLibraryDirectory" id="getPythonLibraryDirectory" ref="eric7.SystemUtilities.PythonUtilities.html#getPythonLibraryDirectory" />
+      <keyword name="getPythonScriptsDirectory" id="getPythonScriptsDirectory" ref="eric7.SystemUtilities.PythonUtilities.html#getPythonScriptsDirectory" />
+      <keyword name="getPythonVersion" id="getPythonVersion" ref="eric7.SystemUtilities.PythonUtilities.html#getPythonVersion" />
       <keyword name="getQt" id="getQt" ref="eric7.Preferences.__init__.html#getQt" />
-      <keyword name="getQtBinariesPath" id="getQtBinariesPath" ref="eric7.Globals.__init__.html#getQtBinariesPath" />
+      <keyword name="getQtBinariesPath" id="getQtBinariesPath" ref="eric7.SystemUtilities.QtUtilities.html#getQtBinariesPath" />
       <keyword name="getQtDocDir" id="getQtDocDir" ref="eric7.Preferences.__init__.html#getQtDocDir" />
-      <keyword name="getQtMacBundle" id="getQtMacBundle" ref="eric7.Utilities.__init__.html#getQtMacBundle" />
+      <keyword name="getQtMacBundle" id="getQtMacBundle" ref="eric7.SystemUtilities.QtUtilities.html#getQtMacBundle" />
       <keyword name="getQtTranslationsDir" id="getQtTranslationsDir" ref="eric7.Preferences.__init__.html#getQtTranslationsDir" />
       <keyword name="getQualAttr" id="getQualAttr" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.SecurityUtils.html#getQualAttr" />
-      <keyword name="getRealName" id="getRealName" ref="eric7.Utilities.__init__.html#getRealName" />
+      <keyword name="getRealName" id="getRealName" ref="eric7.SystemUtilities.OSUtilities.html#getRealName" />
       <keyword name="getRegistryData" id="getRegistryData" ref="eric7.Debugger.DebuggerInterfaceNone.html#getRegistryData" />
       <keyword name="getRegistryData" id="getRegistryData" ref="eric7.Debugger.DebuggerInterfacePython.html#getRegistryData" />
       <keyword name="getResolver" id="getResolver" ref="eric7.DebugClients.Python.DebugVariables.html#getResolver" />
@@ -19063,7 +19076,7 @@
       <keyword name="getUI" id="getUI" ref="eric7.Preferences.__init__.html#getUI" />
       <keyword name="getUILanguage" id="getUILanguage" ref="eric7.Preferences.__init__.html#getUILanguage" />
       <keyword name="getUser" id="getUser" ref="eric7.Preferences.__init__.html#getUser" />
-      <keyword name="getUserName" id="getUserName" ref="eric7.Utilities.__init__.html#getUserName" />
+      <keyword name="getUserName" id="getUserName" ref="eric7.SystemUtilities.OSUtilities.html#getUserName" />
       <keyword name="getVCS" id="getVCS" ref="eric7.Preferences.__init__.html#getVCS" />
       <keyword name="getValue" id="getValue" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.AstUtilities.html#getValue" />
       <keyword name="getValue_1" id="getValue_1" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.AstUtilities.html#getValue_1" />
@@ -19074,11 +19087,11 @@
       <keyword name="getVcsSystemIndicator" id="getVcsSystemIndicator" ref="eric7.Plugins.PluginVcsSubversion.html#getVcsSystemIndicator" />
       <keyword name="getVersions" id="getVersions" ref="eric7.Testing.Interfaces.PytestRunner.html#getVersions" />
       <keyword name="getViewManager" id="getViewManager" ref="eric7.Preferences.__init__.html#getViewManager" />
-      <keyword name="getVolumeName" id="getVolumeName" ref="eric7.Utilities.__init__.html#getVolumeName" />
+      <keyword name="getVolumeName" id="getVolumeName" ref="eric7.SystemUtilities.FileSystemUtilities.html#getVolumeName" />
       <keyword name="getWebBrowser" id="getWebBrowser" ref="eric7.Preferences.__init__.html#getWebBrowser" />
       <keyword name="getWebBrowserSupport" id="getWebBrowserSupport" ref="eric7.Globals.__init__.html#getWebBrowserSupport" />
       <keyword name="getWebEngineVersions" id="getWebEngineVersions" ref="eric7.WebBrowser.Tools.WebBrowserTools.html#getWebEngineVersions" />
-      <keyword name="getWindowsExecutablePath" id="getWindowsExecutablePath" ref="eric7.Utilities.__init__.html#getWindowsExecutablePath" />
+      <keyword name="getWindowsExecutablePath" id="getWindowsExecutablePath" ref="eric7.SystemUtilities.FileSystemUtilities.html#getWindowsExecutablePath" />
       <keyword name="getWinregEntry" id="getWinregEntry" ref="eric7.eric7_post_install.html#getWinregEntry" />
       <keyword name="get_class_members" id="get_class_members" ref="eric7.DebugClients.Python.FlexCompleter.html#get_class_members" />
       <keyword name="get_coding" id="get_coding" ref="eric7.Utilities.__init__.html#get_coding" />
@@ -19101,7 +19114,7 @@
       <keyword name="handleArgs" id="handleArgs" ref="eric7.Toolbox.Startup.html#handleArgs" />
       <keyword name="handleSingleApplication" id="handleSingleApplication" ref="eric7.eric7_ide.html#handleSingleApplication" />
       <keyword name="handle_non_host_target" id="handle_non_host_target" ref="eric7.PipInterface.pipdeptree.html#handle_non_host_target" />
-      <keyword name="hasEnvironmentEntry" id="hasEnvironmentEntry" ref="eric7.Utilities.__init__.html#hasEnvironmentEntry" />
+      <keyword name="hasEnvironmentEntry" id="hasEnvironmentEntry" ref="eric7.SystemUtilities.OSUtilities.html#hasEnvironmentEntry" />
       <keyword name="hasEric6Configuration" id="hasEric6Configuration" ref="eric7.Preferences.__init__.html#hasEric6Configuration" />
       <keyword name="hasShell" id="hasShell" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.injectionShell.html#hasShell" />
       <keyword name="hashPassword" id="hashPassword" ref="eric7.Utilities.crypto.py3PBKDF2.html#hashPassword" />
@@ -19156,14 +19169,14 @@
       <keyword name="isCondaAvailable" id="isCondaAvailable" ref="eric7.CondaInterface.__init__.html#isCondaAvailable" />
       <keyword name="isConfigured" id="isConfigured" ref="eric7.Preferences.__init__.html#isConfigured" />
       <keyword name="isCupsAvailable" id="isCupsAvailable" ref="eric7.WebBrowser.WebBrowserTabWidget.html#isCupsAvailable" />
-      <keyword name="isDrive" id="isDrive" ref="eric7.Utilities.__init__.html#isDrive" />
+      <keyword name="isDrive" id="isDrive" ref="eric7.SystemUtilities.FileSystemUtilities.html#isDrive" />
       <keyword name="isExecutable" id="isExecutable" ref="eric7.DebugClients.Python.DebugUtilities.html#isExecutable" />
-      <keyword name="isExecutable" id="isExecutable" ref="eric7.Utilities.__init__.html#isExecutable" />
-      <keyword name="isGnomeDesktop" id="isGnomeDesktop" ref="eric7.Globals.__init__.html#isGnomeDesktop" />
-      <keyword name="isKdeDesktop" id="isKdeDesktop" ref="eric7.Globals.__init__.html#isKdeDesktop" />
+      <keyword name="isExecutable" id="isExecutable" ref="eric7.SystemUtilities.FileSystemUtilities.html#isExecutable" />
+      <keyword name="isGnomeDesktop" id="isGnomeDesktop" ref="eric7.SystemUtilities.DesktopUtilities.html#isGnomeDesktop" />
+      <keyword name="isKdeDesktop" id="isKdeDesktop" ref="eric7.SystemUtilities.DesktopUtilities.html#isKdeDesktop" />
       <keyword name="isLanguageSupported" id="isLanguageSupported" ref="eric7.Testing.__init__.html#isLanguageSupported" />
-      <keyword name="isLinuxPlatform" id="isLinuxPlatform" ref="eric7.Globals.__init__.html#isLinuxPlatform" />
-      <keyword name="isMacPlatform" id="isMacPlatform" ref="eric7.Globals.__init__.html#isMacPlatform" />
+      <keyword name="isLinuxPlatform" id="isLinuxPlatform" ref="eric7.SystemUtilities.OSUtilities.html#isLinuxPlatform" />
+      <keyword name="isMacPlatform" id="isMacPlatform" ref="eric7.SystemUtilities.OSUtilities.html#isMacPlatform" />
       <keyword name="isNameConstant" id="isNameConstant" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.AstUtilities.html#isNameConstant" />
       <keyword name="isNameConstant_1" id="isNameConstant_1" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.AstUtilities.html#isNameConstant_1" />
       <keyword name="isNumber" id="isNumber" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.AstUtilities.html#isNumber" />
@@ -19177,13 +19190,13 @@
       <keyword name="isValidIPv4Address" id="isValidIPv4Address" ref="eric7.EricNetwork.EricNetworkUtilities.html#isValidIPv4Address" />
       <keyword name="isValidIPv6Address" id="isValidIPv6Address" ref="eric7.EricNetwork.EricNetworkUtilities.html#isValidIPv6Address" />
       <keyword name="isVisible" id="isVisible" ref="eric7.MicroPython.MicroPythonFileSystemUtilities.html#isVisible" />
-      <keyword name="isWaylandSession" id="isWaylandSession" ref="eric7.Globals.__init__.html#isWaylandSession" />
+      <keyword name="isWaylandSession" id="isWaylandSession" ref="eric7.SystemUtilities.DesktopUtilities.html#isWaylandSession" />
       <keyword name="isWindowsPlatform" id="isWindowsPlatform" ref="eric7.DebugClients.Python.DebugUtilities.html#isWindowsPlatform" />
-      <keyword name="isWindowsPlatform" id="isWindowsPlatform" ref="eric7.Globals.__init__.html#isWindowsPlatform" />
+      <keyword name="isWindowsPlatform" id="isWindowsPlatform" ref="eric7.SystemUtilities.OSUtilities.html#isWindowsPlatform" />
       <keyword name="is_string_literal" id="is_string_literal" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#is_string_literal" />
-      <keyword name="isinpath" id="isinpath" ref="eric7.Utilities.__init__.html#isinpath" />
+      <keyword name="isinpath" id="isinpath" ref="eric7.SystemUtilities.FileSystemUtilities.html#isinpath" />
       <keyword name="jinja2Templates (Module)" id="jinja2Templates (Module)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.jinja2Templates.html" />
-      <keyword name="joinext" id="joinext" ref="eric7.Utilities.__init__.html#joinext" />
+      <keyword name="joinext" id="joinext" ref="eric7.SystemUtilities.FileSystemUtilities.html#joinext" />
       <keyword name="jsCheckSyntax (Module)" id="jsCheckSyntax (Module)" ref="eric7.Plugins.CheckerPlugins.SyntaxChecker.jsCheckSyntax.html" />
       <keyword name="jsSyntaxBatchCheck" id="jsSyntaxBatchCheck" ref="eric7.Plugins.CheckerPlugins.SyntaxChecker.jsCheckSyntax.html#jsSyntaxBatchCheck" />
       <keyword name="jsSyntaxCheck" id="jsSyntaxCheck" ref="eric7.Plugins.CheckerPlugins.SyntaxChecker.jsCheckSyntax.html#jsSyntaxCheck" />
@@ -19257,12 +19270,12 @@
       <keyword name="newSpawnl" id="newSpawnl" ref="eric7.DebugClients.Python.MultiProcessDebugExtension.html#newSpawnl" />
       <keyword name="newSpawnv" id="newSpawnv" ref="eric7.DebugClients.Python.MultiProcessDebugExtension.html#newSpawnv" />
       <keyword name="newSpawnve" id="newSpawnve" ref="eric7.DebugClients.Python.MultiProcessDebugExtension.html#newSpawnve" />
-      <keyword name="normabsjoinpath" id="normabsjoinpath" ref="eric7.Utilities.__init__.html#normabsjoinpath" />
+      <keyword name="normabsjoinpath" id="normabsjoinpath" ref="eric7.SystemUtilities.FileSystemUtilities.html#normabsjoinpath" />
       <keyword name="normalizeCode" id="normalizeCode" ref="eric7.Utilities.__init__.html#normalizeCode" />
       <keyword name="normalize_paths" id="normalize_paths" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#normalize_paths" />
-      <keyword name="normcaseabspath" id="normcaseabspath" ref="eric7.Utilities.__init__.html#normcaseabspath" />
-      <keyword name="normcasepath" id="normcasepath" ref="eric7.Utilities.__init__.html#normcasepath" />
-      <keyword name="normjoinpath" id="normjoinpath" ref="eric7.Utilities.__init__.html#normjoinpath" />
+      <keyword name="normcaseabspath" id="normcaseabspath" ref="eric7.SystemUtilities.FileSystemUtilities.html#normcaseabspath" />
+      <keyword name="normcasepath" id="normcasepath" ref="eric7.SystemUtilities.FileSystemUtilities.html#normcasepath" />
+      <keyword name="normjoinpath" id="normjoinpath" ref="eric7.SystemUtilities.FileSystemUtilities.html#normjoinpath" />
       <keyword name="nullcontext" id="nullcontext" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Simplify.ast_unparse.html#nullcontext" />
       <keyword name="nullcontext (Constructor)" id="nullcontext (Constructor)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Simplify.ast_unparse.html#nullcontext.__init__" />
       <keyword name="nullcontext.__enter__" id="nullcontext.__enter__" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Simplify.ast_unparse.html#nullcontext.__enter__" />
@@ -19292,7 +19305,7 @@
       <keyword name="prepareJsonCommand" id="prepareJsonCommand" ref="eric7.DebugClients.Python.DebugUtilities.html#prepareJsonCommand" />
       <keyword name="prepareProcess" id="prepareProcess" ref="eric7.Plugins.VcsPlugins.vcsGit.GitUtilities.html#prepareProcess" />
       <keyword name="prepareProcess" id="prepareProcess" ref="eric7.Plugins.VcsPlugins.vcsMercurial.HgUtilities.html#prepareProcess" />
-      <keyword name="prepareQtMacBundle" id="prepareQtMacBundle" ref="eric7.Utilities.__init__.html#prepareQtMacBundle" />
+      <keyword name="prepareQtMacBundle" id="prepareQtMacBundle" ref="eric7.SystemUtilities.QtUtilities.html#prepareQtMacBundle" />
       <keyword name="prepareUninstall" id="prepareUninstall" ref="eric7.Plugins.PluginTranslator.html#prepareUninstall" />
       <keyword name="prepareUninstall" id="prepareUninstall" ref="eric7.Plugins.PluginVcsGit.html#prepareUninstall" />
       <keyword name="prepareUninstall" id="prepareUninstall" ref="eric7.Plugins.PluginVcsMercurial.html#prepareUninstall" />
@@ -19326,7 +19339,7 @@
       <keyword name="python_3000_invalid_escape_sequence" id="python_3000_invalid_escape_sequence" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#python_3000_invalid_escape_sequence" />
       <keyword name="python_3000_not_equal" id="python_3000_not_equal" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#python_3000_not_equal" />
       <keyword name="python_3000_raise_comma" id="python_3000_raise_comma" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#python_3000_raise_comma" />
-      <keyword name="qVersionTuple" id="qVersionTuple" ref="eric7.Globals.__init__.html#qVersionTuple" />
+      <keyword name="qVersionTuple" id="qVersionTuple" ref="eric7.SystemUtilities.QtUtilities.html#qVersionTuple" />
       <keyword name="qtHandler" id="qtHandler" ref="eric7.EricWidgets.EricErrorMessage.html#qtHandler" />
       <keyword name="question" id="question" ref="eric7.EricWidgets.EricMessageBox.html#question" />
       <keyword name="queues (Module)" id="queues (Module)" ref="eric7.Plugins.VcsPlugins.vcsMercurial.QueuesExtension.queues.html" />
@@ -19353,7 +19366,7 @@
       <keyword name="registerView" id="registerView" ref="eric7.WebBrowser.WebInspector.html#registerView" />
       <keyword name="register_check" id="register_check" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#register_check" />
       <keyword name="rehashPassword" id="rehashPassword" ref="eric7.Utilities.crypto.py3PBKDF2.html#rehashPassword" />
-      <keyword name="relativeUniversalPath" id="relativeUniversalPath" ref="eric7.Utilities.__init__.html#relativeUniversalPath" />
+      <keyword name="relativeUniversalPath" id="relativeUniversalPath" ref="eric7.SystemUtilities.FileSystemUtilities.html#relativeUniversalPath" />
       <keyword name="removeMarkers" id="removeMarkers" ref="eric7.UI.CompareDialog.html#removeMarkers" />
       <keyword name="removeProjectBrowsers" id="removeProjectBrowsers" ref="eric7.Preferences.__init__.html#removeProjectBrowsers" />
       <keyword name="removeQuotesFromArgs" id="removeQuotesFromArgs" ref="eric7.DebugClients.Python.DebugUtilities.html#removeQuotesFromArgs" />
@@ -19377,8 +19390,8 @@
       <keyword name="rxIndex" id="rxIndex" ref="eric7.Utilities.__init__.html#rxIndex" />
       <keyword name="rxValidate" id="rxValidate" ref="eric7.Plugins.WizardPlugins.QRegularExpressionWizard.QRegularExpressionWizardServer.html#rxValidate" />
       <keyword name="s2qTranslate" id="s2qTranslate" ref="eric7.QScintilla.KeySequenceTranslator.html#s2qTranslate" />
-      <keyword name="samefilepath" id="samefilepath" ref="eric7.Utilities.__init__.html#samefilepath" />
-      <keyword name="samepath" id="samepath" ref="eric7.Utilities.__init__.html#samepath" />
+      <keyword name="samefilepath" id="samefilepath" ref="eric7.SystemUtilities.FileSystemUtilities.html#samefilepath" />
+      <keyword name="samepath" id="samepath" ref="eric7.SystemUtilities.FileSystemUtilities.html#samepath" />
       <keyword name="saveResetLayout" id="saveResetLayout" ref="eric7.Preferences.__init__.html#saveResetLayout" />
       <keyword name="saveShortcuts" id="saveShortcuts" ref="eric7.Preferences.Shortcuts.html#saveShortcuts" />
       <keyword name="saveToolGroups" id="saveToolGroups" ref="eric7.Preferences.__init__.html#saveToolGroups" />
@@ -19392,7 +19405,7 @@
       <keyword name="securityOk" id="securityOk" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.CodeStyleChecker.html#securityOk" />
       <keyword name="select_license_by_source" id="select_license_by_source" ref="eric7.PipInterface.piplicenses.html#select_license_by_source" />
       <keyword name="sendPostData" id="sendPostData" ref="eric7.WebBrowser.Tools.Scripts.html#sendPostData" />
-      <keyword name="sessionType" id="sessionType" ref="eric7.Globals.__init__.html#sessionType" />
+      <keyword name="sessionType" id="sessionType" ref="eric7.SystemUtilities.DesktopUtilities.html#sessionType" />
       <keyword name="setActions" id="setActions" ref="eric7.Preferences.Shortcuts.html#setActions" />
       <keyword name="setConda" id="setConda" ref="eric7.Preferences.__init__.html#setConda" />
       <keyword name="setConfigDir" id="setConfigDir" ref="eric7.Globals.__init__.html#setConfigDir" />
@@ -19460,12 +19473,12 @@
       <keyword name="sort" id="sort" ref="eric7.Graphics.GraphicsUtilities.html#sort" />
       <keyword name="sorted_tree" id="sorted_tree" ref="eric7.PipInterface.pipdeptree.html#sorted_tree" />
       <keyword name="speedString" id="speedString" ref="eric7.WebBrowser.Download.DownloadUtilities.html#speedString" />
-      <keyword name="splitPath" id="splitPath" ref="eric7.Utilities.__init__.html#splitPath" />
+      <keyword name="splitPath" id="splitPath" ref="eric7.SystemUtilities.FileSystemUtilities.html#splitPath" />
       <keyword name="sshNoHostKeyVerification (Module)" id="sshNoHostKeyVerification (Module)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.sshNoHostKeyVerification.html" />
       <keyword name="startDebugger" id="startDebugger" ref="eric7.DebugClients.Python.eric7dbgstub.html#startDebugger" />
       <keyword name="startEric" id="startEric" ref="eric7.UI.upgrader.html#startEric" />
       <keyword name="startsWithShebang" id="startsWithShebang" ref="eric7.DebugClients.Python.DebugUtilities.html#startsWithShebang" />
-      <keyword name="startswithPath" id="startswithPath" ref="eric7.Utilities.__init__.html#startswithPath" />
+      <keyword name="startswithPath" id="startswithPath" ref="eric7.SystemUtilities.FileSystemUtilities.html#startswithPath" />
       <keyword name="stdin_get_value" id="stdin_get_value" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#stdin_get_value" />
       <keyword name="strGroup" id="strGroup" ref="eric7.Globals.__init__.html#strGroup" />
       <keyword name="strToQByteArray" id="strToQByteArray" ref="eric7.Globals.__init__.html#strToQByteArray" />
@@ -19484,14 +19497,13 @@
       <keyword name="timeString" id="timeString" ref="eric7.WebBrowser.Download.DownloadUtilities.html#timeString" />
       <keyword name="toBool" id="toBool" ref="eric7.Globals.__init__.html#toBool" />
       <keyword name="toBool" id="toBool" ref="eric7.Preferences.__init__.html#toBool" />
-      <keyword name="toBool" id="toBool" ref="eric7.Utilities.__init__.html#toBool" />
       <keyword name="toByteArray" id="toByteArray" ref="eric7.Globals.__init__.html#toByteArray" />
       <keyword name="toByteArray" id="toByteArray" ref="eric7.Preferences.__init__.html#toByteArray" />
       <keyword name="toDict" id="toDict" ref="eric7.Globals.__init__.html#toDict" />
       <keyword name="toDict" id="toDict" ref="eric7.Preferences.__init__.html#toDict" />
       <keyword name="toList" id="toList" ref="eric7.Globals.__init__.html#toList" />
       <keyword name="toList" id="toList" ref="eric7.Preferences.__init__.html#toList" />
-      <keyword name="toNativeSeparators" id="toNativeSeparators" ref="eric7.Utilities.__init__.html#toNativeSeparators" />
+      <keyword name="toNativeSeparators" id="toNativeSeparators" ref="eric7.SystemUtilities.FileSystemUtilities.html#toNativeSeparators" />
       <keyword name="toSecondLevelDomain" id="toSecondLevelDomain" ref="eric7.WebBrowser.AdBlock.AdBlockRule.html#toSecondLevelDomain" />
       <keyword name="toString" id="toString" ref="eric7.Plugins.WizardPlugins.SetupWizard.SetupCfgUtilities.html#toString" />
       <keyword name="tomlCheckSyntax (Module)" id="tomlCheckSyntax (Module)" ref="eric7.Plugins.CheckerPlugins.SyntaxChecker.tomlCheckSyntax.html" />
@@ -19546,9 +19558,9 @@
       <keyword name="whitespace_around_operator" id="whitespace_around_operator" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#whitespace_around_operator" />
       <keyword name="whitespace_before_comment" id="whitespace_before_comment" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#whitespace_before_comment" />
       <keyword name="whitespace_before_parameters" id="whitespace_before_parameters" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#whitespace_before_parameters" />
-      <keyword name="win32_GetUserName" id="win32_GetUserName" ref="eric7.Utilities.__init__.html#win32_GetUserName" />
-      <keyword name="win32_Kill" id="win32_Kill" ref="eric7.Utilities.__init__.html#win32_Kill" />
-      <keyword name="win32_getRealName" id="win32_getRealName" ref="eric7.Utilities.__init__.html#win32_getRealName" />
+      <keyword name="win32_GetUserName" id="win32_GetUserName" ref="eric7.SystemUtilities.OSUtilities.html#win32_GetUserName" />
+      <keyword name="win32_Kill" id="win32_Kill" ref="eric7.SystemUtilities.OSUtilities.html#win32_Kill" />
+      <keyword name="win32_getRealName" id="win32_getRealName" ref="eric7.SystemUtilities.OSUtilities.html#win32_getRealName" />
       <keyword name="windowsDesktopEntries" id="windowsDesktopEntries" ref="eric7.eric7_post_install.html#windowsDesktopEntries" />
       <keyword name="windowsProgramsEntry" id="windowsProgramsEntry" ref="eric7.eric7_post_install.html#windowsProgramsEntry" />
       <keyword name="workerTask" id="workerTask" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.CodeStyleChecker.html#workerTask" />
@@ -20410,6 +20422,12 @@
       <file>eric7.SqlBrowser.SqlBrowserWidget.html</file>
       <file>eric7.SqlBrowser.SqlConnectionDialog.html</file>
       <file>eric7.SqlBrowser.SqlConnectionWidget.html</file>
+      <file>eric7.SystemUtilities.DesktopUtilities.html</file>
+      <file>eric7.SystemUtilities.FileSystemUtilities.html</file>
+      <file>eric7.SystemUtilities.OSUtilities.html</file>
+      <file>eric7.SystemUtilities.PySideImporter.html</file>
+      <file>eric7.SystemUtilities.PythonUtilities.html</file>
+      <file>eric7.SystemUtilities.QtUtilities.html</file>
       <file>eric7.Tasks.Task.html</file>
       <file>eric7.Tasks.TaskFilter.html</file>
       <file>eric7.Tasks.TaskFilterConfigDialog.html</file>
@@ -20825,6 +20843,7 @@
       <file>index-eric7.Sessions.html</file>
       <file>index-eric7.Snapshot.html</file>
       <file>index-eric7.SqlBrowser.html</file>
+      <file>index-eric7.SystemUtilities.html</file>
       <file>index-eric7.Tasks.html</file>
       <file>index-eric7.Templates.html</file>
       <file>index-eric7.Testing.Interfaces.html</file>
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Documentation/Source/eric7.Globals.__init__.html
--- a/src/eric7/Documentation/Source/eric7.Globals.__init__.html	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Documentation/Source/eric7.Globals.__init__.html	Sun Dec 18 19:33:46 2022 +0100
@@ -30,10 +30,6 @@
 <td>Module function to generate a formatted size string.</td>
 </tr>
 <tr>
-<td><a href="#desktopName">desktopName</a></td>
-<td>Function to determine the name of the desktop environment used (Linux only).</td>
-</tr>
-<tr>
 <td><a href="#getConfigDir">getConfigDir</a></td>
 <td>Module function to get the name of the directory storing the config data.</td>
 </tr>
@@ -42,66 +38,10 @@
 <td>Public method to get the path name of the install info file.</td>
 </tr>
 <tr>
-<td><a href="#getPyQt6ModulesDirectory">getPyQt6ModulesDirectory</a></td>
-<td>Function to determine the path to PyQt6 modules directory.</td>
-</tr>
-<tr>
-<td><a href="#getPyQtToolsPath">getPyQtToolsPath</a></td>
-<td>Module function to get the path of the PyQt tools.</td>
-</tr>
-<tr>
-<td><a href="#getPythonExecutable">getPythonExecutable</a></td>
-<td>Function to determine the path of the (non-windowed) Python executable.</td>
-</tr>
-<tr>
-<td><a href="#getPythonLibraryDirectory">getPythonLibraryDirectory</a></td>
-<td>Function to determine the path to Python's library directory.</td>
-</tr>
-<tr>
-<td><a href="#getPythonScriptsDirectory">getPythonScriptsDirectory</a></td>
-<td>Function to determine the path to Python's scripts directory.</td>
-</tr>
-<tr>
-<td><a href="#getQtBinariesPath">getQtBinariesPath</a></td>
-<td>Module function to get the path of the Qt binaries.</td>
-</tr>
-<tr>
 <td><a href="#getWebBrowserSupport">getWebBrowserSupport</a></td>
 <td>Module function to determine the supported web browser variant.</td>
 </tr>
 <tr>
-<td><a href="#isGnomeDesktop">isGnomeDesktop</a></td>
-<td>Function to check, if the current session is a Gnome desktop (Linux only).</td>
-</tr>
-<tr>
-<td><a href="#isKdeDesktop">isKdeDesktop</a></td>
-<td>Function to check, if the current session is a KDE desktop (Linux only).</td>
-</tr>
-<tr>
-<td><a href="#isLinuxPlatform">isLinuxPlatform</a></td>
-<td>Function to check, if this is a Linux platform.</td>
-</tr>
-<tr>
-<td><a href="#isMacPlatform">isMacPlatform</a></td>
-<td>Function to check, if this is a Mac platform.</td>
-</tr>
-<tr>
-<td><a href="#isWaylandSession">isWaylandSession</a></td>
-<td>Function to check, if the current session is a wayland session.</td>
-</tr>
-<tr>
-<td><a href="#isWindowsPlatform">isWindowsPlatform</a></td>
-<td>Function to check, if this is a Windows platform.</td>
-</tr>
-<tr>
-<td><a href="#qVersionTuple">qVersionTuple</a></td>
-<td>Module function to get the Qt version as a tuple.</td>
-</tr>
-<tr>
-<td><a href="#sessionType">sessionType</a></td>
-<td>Function to determine the name of the running session (Linux only).</td>
-</tr>
-<tr>
 <td><a href="#setConfigDir">setConfigDir</a></td>
 <td>Module function to set the name of the directory storing the config data.</td>
 </tr>
@@ -165,29 +105,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="desktopName" ID="desktopName"></a>
-<h2>desktopName</h2>
-<b>desktopName</b>(<i></i>)
-
-<p>
-    Function to determine the name of the desktop environment used
-    (Linux only).
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-name of the desktop environment
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-str
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="getConfigDir" ID="getConfigDir"></a>
 <h2>getConfigDir</h2>
 <b>getConfigDir</b>(<i></i>)
@@ -232,153 +149,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="getPyQt6ModulesDirectory" ID="getPyQt6ModulesDirectory"></a>
-<h2>getPyQt6ModulesDirectory</h2>
-<b>getPyQt6ModulesDirectory</b>(<i></i>)
-
-<p>
-    Function to determine the path to PyQt6 modules directory.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-path to the PyQt6 modules directory
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-str
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="getPyQtToolsPath" ID="getPyQtToolsPath"></a>
-<h2>getPyQtToolsPath</h2>
-<b>getPyQtToolsPath</b>(<i>version=5</i>)
-
-<p>
-    Module function to get the path of the PyQt tools.
-</p>
-<dl>
-
-<dt><i>version</i> (int)</dt>
-<dd>
-PyQt major version
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-path to the PyQt tools
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-str
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="getPythonExecutable" ID="getPythonExecutable"></a>
-<h2>getPythonExecutable</h2>
-<b>getPythonExecutable</b>(<i></i>)
-
-<p>
-    Function to determine the path of the (non-windowed) Python executable.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-path of the Python executable
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-str
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="getPythonLibraryDirectory" ID="getPythonLibraryDirectory"></a>
-<h2>getPythonLibraryDirectory</h2>
-<b>getPythonLibraryDirectory</b>(<i></i>)
-
-<p>
-    Function to determine the path to Python's library directory.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-path to the Python library directory
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-str
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="getPythonScriptsDirectory" ID="getPythonScriptsDirectory"></a>
-<h2>getPythonScriptsDirectory</h2>
-<b>getPythonScriptsDirectory</b>(<i></i>)
-
-<p>
-    Function to determine the path to Python's scripts directory.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-path to the Python scripts directory
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-str
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="getQtBinariesPath" ID="getQtBinariesPath"></a>
-<h2>getQtBinariesPath</h2>
-<b>getQtBinariesPath</b>(<i>libexec=False</i>)
-
-<p>
-    Module function to get the path of the Qt binaries.
-</p>
-<dl>
-
-<dt><i>libexec</i> (bool (optional))</dt>
-<dd>
-flag indicating to get the path of the executable library
-        (defaults to False)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-path of the Qt binaries
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-str
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="getWebBrowserSupport" ID="getWebBrowserSupport"></a>
 <h2>getWebBrowserSupport</h2>
 <b>getWebBrowserSupport</b>(<i></i>)
@@ -402,182 +172,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="isGnomeDesktop" ID="isGnomeDesktop"></a>
-<h2>isGnomeDesktop</h2>
-<b>isGnomeDesktop</b>(<i></i>)
-
-<p>
-    Function to check, if the current session is a Gnome desktop (Linux only).
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-flag indicating a Gnome desktop
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-bool
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="isKdeDesktop" ID="isKdeDesktop"></a>
-<h2>isKdeDesktop</h2>
-<b>isKdeDesktop</b>(<i></i>)
-
-<p>
-    Function to check, if the current session is a KDE desktop (Linux only).
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-flag indicating a KDE desktop
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-bool
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="isLinuxPlatform" ID="isLinuxPlatform"></a>
-<h2>isLinuxPlatform</h2>
-<b>isLinuxPlatform</b>(<i></i>)
-
-<p>
-    Function to check, if this is a Linux platform.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-flag indicating Linux platform
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-bool
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="isMacPlatform" ID="isMacPlatform"></a>
-<h2>isMacPlatform</h2>
-<b>isMacPlatform</b>(<i></i>)
-
-<p>
-    Function to check, if this is a Mac platform.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-flag indicating Mac platform
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-bool
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="isWaylandSession" ID="isWaylandSession"></a>
-<h2>isWaylandSession</h2>
-<b>isWaylandSession</b>(<i></i>)
-
-<p>
-    Function to check, if the current session is a wayland session.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-flag indicating a wayland session
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-bool
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="isWindowsPlatform" ID="isWindowsPlatform"></a>
-<h2>isWindowsPlatform</h2>
-<b>isWindowsPlatform</b>(<i></i>)
-
-<p>
-    Function to check, if this is a Windows platform.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-flag indicating Windows platform
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-bool
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="qVersionTuple" ID="qVersionTuple"></a>
-<h2>qVersionTuple</h2>
-<b>qVersionTuple</b>(<i></i>)
-
-<p>
-    Module function to get the Qt version as a tuple.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-Qt version as a tuple
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-tuple of int
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="sessionType" ID="sessionType"></a>
-<h2>sessionType</h2>
-<b>sessionType</b>(<i></i>)
-
-<p>
-    Function to determine the name of the running session (Linux only).
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-name of the desktop environment
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-str
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="setConfigDir" ID="setConfigDir"></a>
 <h2>setConfigDir</h2>
 <b>setConfigDir</b>(<i>d</i>)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Documentation/Source/eric7.PipInterface.PipPackagesWidget.html
--- a/src/eric7/Documentation/Source/eric7.PipInterface.PipPackagesWidget.html	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Documentation/Source/eric7.PipInterface.PipPackagesWidget.html	Sun Dec 18 19:33:46 2022 +0100
@@ -347,18 +347,18 @@
 <td>Private slot handling a press of the search button.</td>
 </tr>
 <tr>
-<td><a href="#PipPackagesWidget.on_searchEditName_returnPressed">on_searchEditName_returnPressed</a></td>
+<td><a href="#PipPackagesWidget.on_searchMoreButton_clicked">on_searchMoreButton_clicked</a></td>
+<td>Private slot handling a press of the search more button.</td>
+</tr>
+<tr>
+<td><a href="#PipPackagesWidget.on_searchNameEdit_returnPressed">on_searchNameEdit_returnPressed</a></td>
 <td>Private slot initiating a search via a press of the Return key.</td>
 </tr>
 <tr>
-<td><a href="#PipPackagesWidget.on_searchEditName_textChanged">on_searchEditName_textChanged</a></td>
+<td><a href="#PipPackagesWidget.on_searchNameEdit_textChanged">on_searchNameEdit_textChanged</a></td>
 <td>Private slot handling a change of the search term.</td>
 </tr>
 <tr>
-<td><a href="#PipPackagesWidget.on_searchMoreButton_clicked">on_searchMoreButton_clicked</a></td>
-<td>Private slot handling a press of the search more button.</td>
-</tr>
-<tr>
 <td><a href="#PipPackagesWidget.on_searchResultList_itemActivated">on_searchResultList_itemActivated</a></td>
 <td>Private slot reacting on an search result item activation.</td>
 </tr>
@@ -1209,16 +1209,23 @@
 <p>
         Private slot handling a press of the search button.
 </p>
-<a NAME="PipPackagesWidget.on_searchEditName_returnPressed" ID="PipPackagesWidget.on_searchEditName_returnPressed"></a>
-<h4>PipPackagesWidget.on_searchEditName_returnPressed</h4>
-<b>on_searchEditName_returnPressed</b>(<i></i>)
+<a NAME="PipPackagesWidget.on_searchMoreButton_clicked" ID="PipPackagesWidget.on_searchMoreButton_clicked"></a>
+<h4>PipPackagesWidget.on_searchMoreButton_clicked</h4>
+<b>on_searchMoreButton_clicked</b>(<i></i>)
+
+<p>
+        Private slot handling a press of the search more button.
+</p>
+<a NAME="PipPackagesWidget.on_searchNameEdit_returnPressed" ID="PipPackagesWidget.on_searchNameEdit_returnPressed"></a>
+<h4>PipPackagesWidget.on_searchNameEdit_returnPressed</h4>
+<b>on_searchNameEdit_returnPressed</b>(<i></i>)
 
 <p>
         Private slot initiating a search via a press of the Return key.
 </p>
-<a NAME="PipPackagesWidget.on_searchEditName_textChanged" ID="PipPackagesWidget.on_searchEditName_textChanged"></a>
-<h4>PipPackagesWidget.on_searchEditName_textChanged</h4>
-<b>on_searchEditName_textChanged</b>(<i>txt</i>)
+<a NAME="PipPackagesWidget.on_searchNameEdit_textChanged" ID="PipPackagesWidget.on_searchNameEdit_textChanged"></a>
+<h4>PipPackagesWidget.on_searchNameEdit_textChanged</h4>
+<b>on_searchNameEdit_textChanged</b>(<i>txt</i>)
 
 <p>
         Private slot handling a change of the search term.
@@ -1230,13 +1237,6 @@
 search term
 </dd>
 </dl>
-<a NAME="PipPackagesWidget.on_searchMoreButton_clicked" ID="PipPackagesWidget.on_searchMoreButton_clicked"></a>
-<h4>PipPackagesWidget.on_searchMoreButton_clicked</h4>
-<b>on_searchMoreButton_clicked</b>(<i></i>)
-
-<p>
-        Private slot handling a press of the search more button.
-</p>
 <a NAME="PipPackagesWidget.on_searchResultList_itemActivated" ID="PipPackagesWidget.on_searchResultList_itemActivated"></a>
 <h4>PipPackagesWidget.on_searchResultList_itemActivated</h4>
 <b>on_searchResultList_itemActivated</b>(<i>item, column</i>)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Documentation/Source/eric7.SystemUtilities.DesktopUtilities.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.SystemUtilities.DesktopUtilities.html	Sun Dec 18 19:33:46 2022 +0100
@@ -0,0 +1,161 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.SystemUtilities.DesktopUtilities</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.SystemUtilities.DesktopUtilities</h1>
+
+<p>
+Module implementing Linux desktop related utility functions.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+
+<tr>
+<td><a href="#desktopName">desktopName</a></td>
+<td>Function to determine the name of the desktop environment used (Linux only).</td>
+</tr>
+<tr>
+<td><a href="#isGnomeDesktop">isGnomeDesktop</a></td>
+<td>Function to check, if the current session is a Gnome desktop (Linux only).</td>
+</tr>
+<tr>
+<td><a href="#isKdeDesktop">isKdeDesktop</a></td>
+<td>Function to check, if the current session is a KDE desktop (Linux only).</td>
+</tr>
+<tr>
+<td><a href="#isWaylandSession">isWaylandSession</a></td>
+<td>Function to check, if the current session is a wayland session.</td>
+</tr>
+<tr>
+<td><a href="#sessionType">sessionType</a></td>
+<td>Function to determine the name of the running session (Linux only).</td>
+</tr>
+</table>
+<hr />
+<hr />
+<a NAME="desktopName" ID="desktopName"></a>
+<h2>desktopName</h2>
+<b>desktopName</b>(<i></i>)
+
+<p>
+    Function to determine the name of the desktop environment used
+    (Linux only).
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+name of the desktop environment
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="isGnomeDesktop" ID="isGnomeDesktop"></a>
+<h2>isGnomeDesktop</h2>
+<b>isGnomeDesktop</b>(<i></i>)
+
+<p>
+    Function to check, if the current session is a Gnome desktop (Linux only).
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating a Gnome desktop
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="isKdeDesktop" ID="isKdeDesktop"></a>
+<h2>isKdeDesktop</h2>
+<b>isKdeDesktop</b>(<i></i>)
+
+<p>
+    Function to check, if the current session is a KDE desktop (Linux only).
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating a KDE desktop
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="isWaylandSession" ID="isWaylandSession"></a>
+<h2>isWaylandSession</h2>
+<b>isWaylandSession</b>(<i></i>)
+
+<p>
+    Function to check, if the current session is a wayland session.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating a wayland session
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="sessionType" ID="sessionType"></a>
+<h2>sessionType</h2>
+<b>sessionType</b>(<i></i>)
+
+<p>
+    Function to determine the name of the running session (Linux only).
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+name of the desktop environment
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Documentation/Source/eric7.SystemUtilities.FileSystemUtilities.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.SystemUtilities.FileSystemUtilities.html	Sun Dec 18 19:33:46 2022 +0100
@@ -0,0 +1,837 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.SystemUtilities.FileSystemUtilities</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.SystemUtilities.FileSystemUtilities</h1>
+
+<p>
+Module implementing file system related utility functions.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+
+<tr>
+<td><a href="#absolutePath">absolutePath</a></td>
+<td>Public method to convert a path relative to a start path to an absolute path.</td>
+</tr>
+<tr>
+<td><a href="#absoluteUniversalPath">absoluteUniversalPath</a></td>
+<td>Public method to convert a path relative to a start path with universal separators to an absolute path.</td>
+</tr>
+<tr>
+<td><a href="#compactPath">compactPath</a></td>
+<td>Function to return a compacted path fitting inside the given width.</td>
+</tr>
+<tr>
+<td><a href="#direntries">direntries</a></td>
+<td>Function returning a list of all files and directories.</td>
+</tr>
+<tr>
+<td><a href="#findVolume">findVolume</a></td>
+<td>Function to find the directory belonging to a given volume name.</td>
+</tr>
+<tr>
+<td><a href="#fromNativeSeparators">fromNativeSeparators</a></td>
+<td>Function returning a path, that is using "/" separator characters.</td>
+</tr>
+<tr>
+<td><a href="#getDirs">getDirs</a></td>
+<td>Function returning a list of all directories below path.</td>
+</tr>
+<tr>
+<td><a href="#getExecutablePath">getExecutablePath</a></td>
+<td>Function to build the full path of an executable file from the environment.</td>
+</tr>
+<tr>
+<td><a href="#getExecutablePaths">getExecutablePaths</a></td>
+<td>Function to build all full path of an executable file from the environment.</td>
+</tr>
+<tr>
+<td><a href="#getVolumeName">getVolumeName</a></td>
+<td>Local function to determine the volume of a disk or device.</td>
+</tr>
+<tr>
+<td><a href="#getWindowsExecutablePath">getWindowsExecutablePath</a></td>
+<td>Function to build the full path of an executable file from the environment on Windows platforms.</td>
+</tr>
+<tr>
+<td><a href="#isDrive">isDrive</a></td>
+<td>Function to check, if a path is a Windows drive.</td>
+</tr>
+<tr>
+<td><a href="#isExecutable">isExecutable</a></td>
+<td>Function to check, if a file is executable.</td>
+</tr>
+<tr>
+<td><a href="#isinpath">isinpath</a></td>
+<td>Function to check for an executable file.</td>
+</tr>
+<tr>
+<td><a href="#joinext">joinext</a></td>
+<td>Function to join a file extension to a path.</td>
+</tr>
+<tr>
+<td><a href="#normabsjoinpath">normabsjoinpath</a></td>
+<td>Function returning a normalized, absolute path of the joined parts passed into it.</td>
+</tr>
+<tr>
+<td><a href="#normcaseabspath">normcaseabspath</a></td>
+<td>Function returning an absolute path, that is normalized with respect to its case and references.</td>
+</tr>
+<tr>
+<td><a href="#normcasepath">normcasepath</a></td>
+<td>Function returning a path, that is normalized with respect to its case and references.</td>
+</tr>
+<tr>
+<td><a href="#normjoinpath">normjoinpath</a></td>
+<td>Function returning a normalized path of the joined parts passed into it.</td>
+</tr>
+<tr>
+<td><a href="#relativeUniversalPath">relativeUniversalPath</a></td>
+<td>Function to convert a file path to a path relative to a start path with universal separators.</td>
+</tr>
+<tr>
+<td><a href="#samefilepath">samefilepath</a></td>
+<td>Function to compare two paths.</td>
+</tr>
+<tr>
+<td><a href="#samepath">samepath</a></td>
+<td>Function to compare two paths.</td>
+</tr>
+<tr>
+<td><a href="#splitPath">splitPath</a></td>
+<td>Function to split a pathname into a directory part and a file part.</td>
+</tr>
+<tr>
+<td><a href="#startswithPath">startswithPath</a></td>
+<td>Function to check, if a path starts with a given start path.</td>
+</tr>
+<tr>
+<td><a href="#toNativeSeparators">toNativeSeparators</a></td>
+<td>Function returning a path, that is using native separator characters.</td>
+</tr>
+</table>
+<hr />
+<hr />
+<a NAME="absolutePath" ID="absolutePath"></a>
+<h2>absolutePath</h2>
+<b>absolutePath</b>(<i>path, start</i>)
+
+<p>
+    Public method to convert a path relative to a start path to an
+    absolute path.
+</p>
+<dl>
+
+<dt><i>path</i></dt>
+<dd>
+file or directory name to convert (string)
+</dd>
+<dt><i>start</i></dt>
+<dd>
+start path (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+absolute path (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="absoluteUniversalPath" ID="absoluteUniversalPath"></a>
+<h2>absoluteUniversalPath</h2>
+<b>absoluteUniversalPath</b>(<i>path, start</i>)
+
+<p>
+    Public method to convert a path relative to a start path with
+    universal separators to an absolute path.
+</p>
+<dl>
+
+<dt><i>path</i></dt>
+<dd>
+file or directory name to convert (string)
+</dd>
+<dt><i>start</i></dt>
+<dd>
+start path (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+absolute path with native separators (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="compactPath" ID="compactPath"></a>
+<h2>compactPath</h2>
+<b>compactPath</b>(<i>path, width, measure=len</i>)
+
+<p>
+    Function to return a compacted path fitting inside the given width.
+</p>
+<dl>
+
+<dt><i>path</i></dt>
+<dd>
+path to be compacted (string)
+</dd>
+<dt><i>width</i></dt>
+<dd>
+width for the compacted path (integer)
+</dd>
+<dt><i>measure</i></dt>
+<dd>
+reference to a function used to measure the length of the
+        string
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+compacted path (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="direntries" ID="direntries"></a>
+<h2>direntries</h2>
+<b>direntries</b>(<i>path, filesonly=False, pattern=None, followsymlinks=True, checkStop=None</i>)
+
+<p>
+    Function returning a list of all files and directories.
+</p>
+<dl>
+
+<dt><i>path</i> (str)</dt>
+<dd>
+root of the tree to check
+</dd>
+<dt><i>filesonly</i> (bool)</dt>
+<dd>
+flag indicating that only files are wanted
+</dd>
+<dt><i>pattern</i> (str or list of str)</dt>
+<dd>
+a filename pattern or list of filename patterns to check
+        against
+</dd>
+<dt><i>followsymlinks</i> (bool)</dt>
+<dd>
+flag indicating whether symbolic links
+        should be followed
+</dd>
+<dt><i>checkStop</i> (function)</dt>
+<dd>
+function to be called to check for a stop
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+list of all files and directories in the tree rooted
+        at path. The names are expanded to start with path.
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+list of strs
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="findVolume" ID="findVolume"></a>
+<h2>findVolume</h2>
+<b>findVolume</b>(<i>volumeName, findAll=False</i>)
+
+<p>
+    Function to find the directory belonging to a given volume name.
+</p>
+<dl>
+
+<dt><i>volumeName</i> (str)</dt>
+<dd>
+name of the volume to search for
+</dd>
+<dt><i>findAll</i> (bool (optional))</dt>
+<dd>
+flag indicating to get the directories for all volumes
+        starting with the given name (defaults to False)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+directory path or list of directory paths for the given volume
+        name
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str or list of str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="fromNativeSeparators" ID="fromNativeSeparators"></a>
+<h2>fromNativeSeparators</h2>
+<b>fromNativeSeparators</b>(<i>path</i>)
+
+<p>
+    Function returning a path, that is using "/" separator characters.
+</p>
+<dl>
+
+<dt><i>path</i> (str)</dt>
+<dd>
+path to be converted
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+path with converted separator characters
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getDirs" ID="getDirs"></a>
+<h2>getDirs</h2>
+<b>getDirs</b>(<i>path, excludeDirs</i>)
+
+<p>
+    Function returning a list of all directories below path.
+</p>
+<dl>
+
+<dt><i>path</i></dt>
+<dd>
+root of the tree to check
+</dd>
+<dt><i>excludeDirs</i></dt>
+<dd>
+basename of directories to ignore
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+list of all directories found
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getExecutablePath" ID="getExecutablePath"></a>
+<h2>getExecutablePath</h2>
+<b>getExecutablePath</b>(<i>file</i>)
+
+<p>
+    Function to build the full path of an executable file from the environment.
+</p>
+<dl>
+
+<dt><i>file</i></dt>
+<dd>
+filename of the executable to check (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+full executable name, if the executable file is accessible
+        via the searchpath defined by the PATH environment variable, or an
+        empty string otherwise.
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getExecutablePaths" ID="getExecutablePaths"></a>
+<h2>getExecutablePaths</h2>
+<b>getExecutablePaths</b>(<i>file</i>)
+
+<p>
+    Function to build all full path of an executable file from the environment.
+</p>
+<dl>
+
+<dt><i>file</i></dt>
+<dd>
+filename of the executable (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+list of full executable names (list of strings), if the executable
+        file is accessible via the searchpath defined by the PATH environment
+        variable, or an empty list otherwise.
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getVolumeName" ID="getVolumeName"></a>
+<h2>getVolumeName</h2>
+<b>getVolumeName</b>(<i>diskName</i>)
+
+<p>
+            Local function to determine the volume of a disk or device.
+</p>
+<p>
+            Each disk or external device connected to windows has an
+            attribute called "volume name". This function returns the
+            volume name for the given disk/device.
+</p>
+<p>
+            Code from http://stackoverflow.com/a/12056414
+</p>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getWindowsExecutablePath" ID="getWindowsExecutablePath"></a>
+<h2>getWindowsExecutablePath</h2>
+<b>getWindowsExecutablePath</b>(<i>file</i>)
+
+<p>
+    Function to build the full path of an executable file from the environment
+    on Windows platforms.
+</p>
+<p>
+    First an executable with the extension .exe is searched for, thereafter
+    such with the extensions .cmd or .bat and finally the given file name as
+    is. The first match is returned.
+</p>
+<dl>
+
+<dt><i>file</i></dt>
+<dd>
+filename of the executable to check (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+full executable name, if the executable file is accessible
+        via the searchpath defined by the PATH environment variable, or an
+        empty string otherwise.
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="isDrive" ID="isDrive"></a>
+<h2>isDrive</h2>
+<b>isDrive</b>(<i>path</i>)
+
+<p>
+    Function to check, if a path is a Windows drive.
+</p>
+<dl>
+
+<dt><i>path</i> (str)</dt>
+<dd>
+path name to be checked
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating a Windows drive
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="isExecutable" ID="isExecutable"></a>
+<h2>isExecutable</h2>
+<b>isExecutable</b>(<i>exe</i>)
+
+<p>
+    Function to check, if a file is executable.
+</p>
+<dl>
+
+<dt><i>exe</i></dt>
+<dd>
+filename of the executable to check (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating executable status (boolean)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="isinpath" ID="isinpath"></a>
+<h2>isinpath</h2>
+<b>isinpath</b>(<i>file</i>)
+
+<p>
+    Function to check for an executable file.
+</p>
+<dl>
+
+<dt><i>file</i></dt>
+<dd>
+filename of the executable to check (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag to indicate, if the executable file is accessible
+        via the searchpath defined by the PATH environment variable.
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="joinext" ID="joinext"></a>
+<h2>joinext</h2>
+<b>joinext</b>(<i>prefix, ext</i>)
+
+<p>
+    Function to join a file extension to a path.
+</p>
+<p>
+    The leading "." of ext is replaced by a platform specific extension
+    separator if necessary.
+</p>
+<dl>
+
+<dt><i>prefix</i></dt>
+<dd>
+the basepart of the filename (string)
+</dd>
+<dt><i>ext</i></dt>
+<dd>
+the extension part (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+the complete filename (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="normabsjoinpath" ID="normabsjoinpath"></a>
+<h2>normabsjoinpath</h2>
+<b>normabsjoinpath</b>(<i>a, *p</i>)
+
+<p>
+    Function returning a normalized, absolute path of the joined parts passed
+    into it.
+</p>
+<dl>
+
+<dt><i>a</i></dt>
+<dd>
+first path to be joined (string)
+</dd>
+<dt><i>p</i></dt>
+<dd>
+variable number of path parts to be joind (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+absolute, normalized path (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="normcaseabspath" ID="normcaseabspath"></a>
+<h2>normcaseabspath</h2>
+<b>normcaseabspath</b>(<i>path</i>)
+
+<p>
+    Function returning an absolute path, that is normalized with respect to
+    its case and references.
+</p>
+<dl>
+
+<dt><i>path</i></dt>
+<dd>
+file path (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+absolute, normalized path (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="normcasepath" ID="normcasepath"></a>
+<h2>normcasepath</h2>
+<b>normcasepath</b>(<i>path</i>)
+
+<p>
+    Function returning a path, that is normalized with respect to its case
+    and references.
+</p>
+<dl>
+
+<dt><i>path</i></dt>
+<dd>
+file path (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+case normalized path (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="normjoinpath" ID="normjoinpath"></a>
+<h2>normjoinpath</h2>
+<b>normjoinpath</b>(<i>a, *p</i>)
+
+<p>
+    Function returning a normalized path of the joined parts passed into it.
+</p>
+<dl>
+
+<dt><i>a</i></dt>
+<dd>
+first path to be joined (string)
+</dd>
+<dt><i>p</i></dt>
+<dd>
+variable number of path parts to be joined (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+normalized path (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="relativeUniversalPath" ID="relativeUniversalPath"></a>
+<h2>relativeUniversalPath</h2>
+<b>relativeUniversalPath</b>(<i>path, start</i>)
+
+<p>
+    Function to convert a file path to a path relative to a start path
+    with universal separators.
+</p>
+<dl>
+
+<dt><i>path</i></dt>
+<dd>
+file or directory name to convert (string)
+</dd>
+<dt><i>start</i></dt>
+<dd>
+start path (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+relative path or unchanged path, if path does not start with
+        the start path with universal separators (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="samefilepath" ID="samefilepath"></a>
+<h2>samefilepath</h2>
+<b>samefilepath</b>(<i>f1, f2</i>)
+
+<p>
+    Function to compare two paths. Strips the filename.
+</p>
+<dl>
+
+<dt><i>f1</i></dt>
+<dd>
+first filepath for the compare (string)
+</dd>
+<dt><i>f2</i></dt>
+<dd>
+second filepath for the compare (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating whether the two paths represent the
+        same path on disk.
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="samepath" ID="samepath"></a>
+<h2>samepath</h2>
+<b>samepath</b>(<i>f1, f2</i>)
+
+<p>
+    Function to compare two paths.
+</p>
+<dl>
+
+<dt><i>f1</i></dt>
+<dd>
+first path for the compare (string)
+</dd>
+<dt><i>f2</i></dt>
+<dd>
+second path for the compare (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating whether the two paths represent the
+        same path on disk.
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="splitPath" ID="splitPath"></a>
+<h2>splitPath</h2>
+<b>splitPath</b>(<i>name</i>)
+
+<p>
+    Function to split a pathname into a directory part and a file part.
+</p>
+<dl>
+
+<dt><i>name</i></dt>
+<dd>
+path name (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+a tuple of 2 strings (dirname, filename).
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="startswithPath" ID="startswithPath"></a>
+<h2>startswithPath</h2>
+<b>startswithPath</b>(<i>path, start</i>)
+
+<p>
+    Function to check, if a path starts with a given start path.
+</p>
+<dl>
+
+<dt><i>path</i> (str)</dt>
+<dd>
+path to be checked
+</dd>
+<dt><i>start</i> (str)</dt>
+<dd>
+start path
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating that the path starts with the given start
+        path
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="toNativeSeparators" ID="toNativeSeparators"></a>
+<h2>toNativeSeparators</h2>
+<b>toNativeSeparators</b>(<i>path</i>)
+
+<p>
+    Function returning a path, that is using native separator characters.
+</p>
+<dl>
+
+<dt><i>path</i> (str)</dt>
+<dd>
+path to be converted
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+path with converted separator characters
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Documentation/Source/eric7.SystemUtilities.OSUtilities.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.SystemUtilities.OSUtilities.html	Sun Dec 18 19:33:46 2022 +0100
@@ -0,0 +1,301 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.SystemUtilities.OSUtilities</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.SystemUtilities.OSUtilities</h1>
+
+<p>
+Module implementing Operating System related utility functions.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+
+<tr>
+<td><a href="#getEnvironmentEntry">getEnvironmentEntry</a></td>
+<td>Module function to get an environment entry.</td>
+</tr>
+<tr>
+<td><a href="#getHomeDir">getHomeDir</a></td>
+<td>Function to get a users home directory.</td>
+</tr>
+<tr>
+<td><a href="#getRealName">getRealName</a></td>
+<td>Function to get the real name of the user.</td>
+</tr>
+<tr>
+<td><a href="#getUserName">getUserName</a></td>
+<td>Function to get the user name.</td>
+</tr>
+<tr>
+<td><a href="#hasEnvironmentEntry">hasEnvironmentEntry</a></td>
+<td>Module function to check, if the environment contains an entry.</td>
+</tr>
+<tr>
+<td><a href="#isLinuxPlatform">isLinuxPlatform</a></td>
+<td>Function to check, if this is a Linux platform.</td>
+</tr>
+<tr>
+<td><a href="#isMacPlatform">isMacPlatform</a></td>
+<td>Function to check, if this is a Mac platform.</td>
+</tr>
+<tr>
+<td><a href="#isWindowsPlatform">isWindowsPlatform</a></td>
+<td>Function to check, if this is a Windows platform.</td>
+</tr>
+<tr>
+<td><a href="#win32_GetUserName">win32_GetUserName</a></td>
+<td>Function to get the user name under Win32.</td>
+</tr>
+<tr>
+<td><a href="#win32_Kill">win32_Kill</a></td>
+<td>Function to provide an os.kill equivalent for Win32.</td>
+</tr>
+<tr>
+<td><a href="#win32_getRealName">win32_getRealName</a></td>
+<td>Function to get the user's real name (aka.</td>
+</tr>
+</table>
+<hr />
+<hr />
+<a NAME="getEnvironmentEntry" ID="getEnvironmentEntry"></a>
+<h2>getEnvironmentEntry</h2>
+<b>getEnvironmentEntry</b>(<i>key, default=None</i>)
+
+<p>
+    Module function to get an environment entry.
+</p>
+<dl>
+
+<dt><i>key</i></dt>
+<dd>
+key of the requested environment entry (string)
+</dd>
+<dt><i>default</i></dt>
+<dd>
+value to be returned, if the environment doesn't contain
+        the requested entry (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+the requested entry or the default value, if the entry wasn't
+        found (string or None)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getHomeDir" ID="getHomeDir"></a>
+<h2>getHomeDir</h2>
+<b>getHomeDir</b>(<i></i>)
+
+<p>
+    Function to get a users home directory.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+home directory (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getRealName" ID="getRealName"></a>
+<h2>getRealName</h2>
+<b>getRealName</b>(<i></i>)
+
+<p>
+    Function to get the real name of the user.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+real name of the user (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getUserName" ID="getUserName"></a>
+<h2>getUserName</h2>
+<b>getUserName</b>(<i></i>)
+
+<p>
+    Function to get the user name.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+user name (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="hasEnvironmentEntry" ID="hasEnvironmentEntry"></a>
+<h2>hasEnvironmentEntry</h2>
+<b>hasEnvironmentEntry</b>(<i>key</i>)
+
+<p>
+    Module function to check, if the environment contains an entry.
+</p>
+<dl>
+
+<dt><i>key</i> (str)</dt>
+<dd>
+key of the requested environment entry
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating the presence of the requested entry
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="isLinuxPlatform" ID="isLinuxPlatform"></a>
+<h2>isLinuxPlatform</h2>
+<b>isLinuxPlatform</b>(<i></i>)
+
+<p>
+    Function to check, if this is a Linux platform.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating Linux platform
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="isMacPlatform" ID="isMacPlatform"></a>
+<h2>isMacPlatform</h2>
+<b>isMacPlatform</b>(<i></i>)
+
+<p>
+    Function to check, if this is a Mac platform.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating Mac platform
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="isWindowsPlatform" ID="isWindowsPlatform"></a>
+<h2>isWindowsPlatform</h2>
+<b>isWindowsPlatform</b>(<i></i>)
+
+<p>
+    Function to check, if this is a Windows platform.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating Windows platform
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="win32_GetUserName" ID="win32_GetUserName"></a>
+<h2>win32_GetUserName</h2>
+<b>win32_GetUserName</b>(<i></i>)
+
+<p>
+    Function to get the user name under Win32.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+user name (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="win32_Kill" ID="win32_Kill"></a>
+<h2>win32_Kill</h2>
+<b>win32_Kill</b>(<i>pid</i>)
+
+<p>
+    Function to provide an os.kill equivalent for Win32.
+</p>
+<dl>
+
+<dt><i>pid</i></dt>
+<dd>
+process id (integer)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+result of the kill (boolean)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="win32_getRealName" ID="win32_getRealName"></a>
+<h2>win32_getRealName</h2>
+<b>win32_getRealName</b>(<i></i>)
+
+<p>
+    Function to get the user's real name (aka. display name) under Win32.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+real name of the current user (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Documentation/Source/eric7.SystemUtilities.PySideImporter.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.SystemUtilities.PySideImporter.html	Sun Dec 18 19:33:46 2022 +0100
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.SystemUtilities.PySideImporter</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.SystemUtilities.PySideImporter</h1>
+
+<p>
+Module to check for the presence of PySide2/PySide6 by importing it.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<hr />
+</body></html>
\ No newline at end of file
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Documentation/Source/eric7.SystemUtilities.PythonUtilities.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.SystemUtilities.PythonUtilities.html	Sun Dec 18 19:33:46 2022 +0100
@@ -0,0 +1,184 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.SystemUtilities.PythonUtilities</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.SystemUtilities.PythonUtilities</h1>
+
+<p>
+Module implementing Python related utility functions.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+
+<tr>
+<td><a href="#determinePythonVersion">determinePythonVersion</a></td>
+<td>Function to determine the python version of a given file.</td>
+</tr>
+<tr>
+<td><a href="#getPythonExecutable">getPythonExecutable</a></td>
+<td>Function to determine the path of the (non-windowed) Python executable.</td>
+</tr>
+<tr>
+<td><a href="#getPythonLibPath">getPythonLibPath</a></td>
+<td>Function to determine the path to Python's library.</td>
+</tr>
+<tr>
+<td><a href="#getPythonLibraryDirectory">getPythonLibraryDirectory</a></td>
+<td>Function to determine the path to Python's library directory.</td>
+</tr>
+<tr>
+<td><a href="#getPythonScriptsDirectory">getPythonScriptsDirectory</a></td>
+<td>Function to determine the path to Python's scripts directory.</td>
+</tr>
+<tr>
+<td><a href="#getPythonVersion">getPythonVersion</a></td>
+<td>Function to get the Python version (major, minor) as an integer value.</td>
+</tr>
+</table>
+<hr />
+<hr />
+<a NAME="determinePythonVersion" ID="determinePythonVersion"></a>
+<h2>determinePythonVersion</h2>
+<b>determinePythonVersion</b>(<i>filename, source, editor=None</i>)
+
+<p>
+    Function to determine the python version of a given file.
+</p>
+<dl>
+
+<dt><i>filename</i></dt>
+<dd>
+name of the file with extension (str)
+</dd>
+<dt><i>source</i></dt>
+<dd>
+of the file (str)
+</dd>
+<dt><i>editor</i></dt>
+<dd>
+reference to the editor, if the file is opened
+        already (Editor object)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+Python version if file is Python3 (int)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getPythonExecutable" ID="getPythonExecutable"></a>
+<h2>getPythonExecutable</h2>
+<b>getPythonExecutable</b>(<i></i>)
+
+<p>
+    Function to determine the path of the (non-windowed) Python executable.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+path of the Python executable
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getPythonLibPath" ID="getPythonLibPath"></a>
+<h2>getPythonLibPath</h2>
+<b>getPythonLibPath</b>(<i></i>)
+
+<p>
+    Function to determine the path to Python's library.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+path to the Python library (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getPythonLibraryDirectory" ID="getPythonLibraryDirectory"></a>
+<h2>getPythonLibraryDirectory</h2>
+<b>getPythonLibraryDirectory</b>(<i></i>)
+
+<p>
+    Function to determine the path to Python's library directory.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+path to the Python library directory
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getPythonScriptsDirectory" ID="getPythonScriptsDirectory"></a>
+<h2>getPythonScriptsDirectory</h2>
+<b>getPythonScriptsDirectory</b>(<i></i>)
+
+<p>
+    Function to determine the path to Python's scripts directory.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+path to the Python scripts directory
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getPythonVersion" ID="getPythonVersion"></a>
+<h2>getPythonVersion</h2>
+<b>getPythonVersion</b>(<i></i>)
+
+<p>
+    Function to get the Python version (major, minor) as an integer value.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+An integer representing major and minor version number (integer)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Documentation/Source/eric7.SystemUtilities.QtUtilities.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.SystemUtilities.QtUtilities.html	Sun Dec 18 19:33:46 2022 +0100
@@ -0,0 +1,348 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.SystemUtilities.QtUtilities</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.SystemUtilities.QtUtilities</h1>
+
+<p>
+Module implementing Qt/PyQt/PySide related utility functions.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+
+<tr>
+<td><a href="#checkPyside">checkPyside</a></td>
+<td>Module function to check the presence of PySide2/PySide6.</td>
+</tr>
+<tr>
+<td><a href="#generatePyQtToolPath">generatePyQtToolPath</a></td>
+<td>Module function to generate the executable path for a PyQt tool.</td>
+</tr>
+<tr>
+<td><a href="#generatePySideToolPath">generatePySideToolPath</a></td>
+<td>Module function to generate the executable path for a PySide2/PySide6 tool.</td>
+</tr>
+<tr>
+<td><a href="#generateQtToolName">generateQtToolName</a></td>
+<td>Module function to generate the executable name for a Qt tool like designer.</td>
+</tr>
+<tr>
+<td><a href="#getPyQt6ModulesDirectory">getPyQt6ModulesDirectory</a></td>
+<td>Function to determine the path to PyQt6 modules directory.</td>
+</tr>
+<tr>
+<td><a href="#getPyQtToolsPath">getPyQtToolsPath</a></td>
+<td>Module function to get the path of the PyQt tools.</td>
+</tr>
+<tr>
+<td><a href="#getQtBinariesPath">getQtBinariesPath</a></td>
+<td>Module function to get the path of the Qt binaries.</td>
+</tr>
+<tr>
+<td><a href="#getQtMacBundle">getQtMacBundle</a></td>
+<td>Module function to determine the correct Mac OS X bundle name for Qt tools.</td>
+</tr>
+<tr>
+<td><a href="#prepareQtMacBundle">prepareQtMacBundle</a></td>
+<td>Module function for starting Qt tools that are Mac OS X bundles.</td>
+</tr>
+<tr>
+<td><a href="#qVersionTuple">qVersionTuple</a></td>
+<td>Module function to get the Qt version as a tuple.</td>
+</tr>
+</table>
+<hr />
+<hr />
+<a NAME="checkPyside" ID="checkPyside"></a>
+<h2>checkPyside</h2>
+<b>checkPyside</b>(<i>variant=2</i>)
+
+<p>
+    Module function to check the presence of PySide2/PySide6.
+</p>
+<dl>
+
+<dt><i>variant</i> (int or str)</dt>
+<dd>
+indicator for the PySide variant
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+flags indicating the presence of PySide2/PySide6
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="generatePyQtToolPath" ID="generatePyQtToolPath"></a>
+<h2>generatePyQtToolPath</h2>
+<b>generatePyQtToolPath</b>(<i>toolname, alternatives=None</i>)
+
+<p>
+    Module function to generate the executable path for a PyQt tool.
+</p>
+<dl>
+
+<dt><i>toolname</i> (str)</dt>
+<dd>
+base name of the tool
+</dd>
+<dt><i>alternatives</i> (list of str)</dt>
+<dd>
+list of alternative tool names to try
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+executable path name of the tool
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="generatePySideToolPath" ID="generatePySideToolPath"></a>
+<h2>generatePySideToolPath</h2>
+<b>generatePySideToolPath</b>(<i>toolname, variant=2</i>)
+
+<p>
+    Module function to generate the executable path for a PySide2/PySide6 tool.
+</p>
+<dl>
+
+<dt><i>toolname</i> (str)</dt>
+<dd>
+base name of the tool
+</dd>
+<dt><i>variant</i> (int or str)</dt>
+<dd>
+indicator for the PySide variant
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+the PySide2/PySide6 tool path with extension
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="generateQtToolName" ID="generateQtToolName"></a>
+<h2>generateQtToolName</h2>
+<b>generateQtToolName</b>(<i>toolname</i>)
+
+<p>
+    Module function to generate the executable name for a Qt tool like
+    designer.
+</p>
+<dl>
+
+<dt><i>toolname</i></dt>
+<dd>
+base name of the tool (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+the Qt tool name without extension (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getPyQt6ModulesDirectory" ID="getPyQt6ModulesDirectory"></a>
+<h2>getPyQt6ModulesDirectory</h2>
+<b>getPyQt6ModulesDirectory</b>(<i></i>)
+
+<p>
+    Function to determine the path to PyQt6 modules directory.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+path to the PyQt6 modules directory
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getPyQtToolsPath" ID="getPyQtToolsPath"></a>
+<h2>getPyQtToolsPath</h2>
+<b>getPyQtToolsPath</b>(<i>version=5</i>)
+
+<p>
+    Module function to get the path of the PyQt tools.
+</p>
+<dl>
+
+<dt><i>version</i> (int)</dt>
+<dd>
+PyQt major version
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+path to the PyQt tools
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getQtBinariesPath" ID="getQtBinariesPath"></a>
+<h2>getQtBinariesPath</h2>
+<b>getQtBinariesPath</b>(<i>libexec=False</i>)
+
+<p>
+    Module function to get the path of the Qt binaries.
+</p>
+<dl>
+
+<dt><i>libexec</i> (bool (optional))</dt>
+<dd>
+flag indicating to get the path of the executable library
+        (defaults to False)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+path of the Qt binaries
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getQtMacBundle" ID="getQtMacBundle"></a>
+<h2>getQtMacBundle</h2>
+<b>getQtMacBundle</b>(<i>toolname</i>)
+
+<p>
+    Module function to determine the correct Mac OS X bundle name for Qt tools.
+</p>
+<dl>
+
+<dt><i>toolname</i></dt>
+<dd>
+plain name of the tool (e.g. "designer") (string)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+bundle name of the Qt tool (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="prepareQtMacBundle" ID="prepareQtMacBundle"></a>
+<h2>prepareQtMacBundle</h2>
+<b>prepareQtMacBundle</b>(<i>toolname, args</i>)
+
+<p>
+    Module function for starting Qt tools that are Mac OS X bundles.
+</p>
+<dl>
+
+<dt><i>toolname</i> (str)</dt>
+<dd>
+plain name of the tool (e.g. "designer")
+</dd>
+<dt><i>args</i> (list of str)</dt>
+<dd>
+name of input file for tool, if any
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+command-name and args for QProcess
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (str, list of str)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="qVersionTuple" ID="qVersionTuple"></a>
+<h2>qVersionTuple</h2>
+<b>qVersionTuple</b>(<i></i>)
+
+<p>
+    Module function to get the Qt version as a tuple.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+Qt version as a tuple
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of int
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Documentation/Source/eric7.Utilities.__init__.html
--- a/src/eric7/Documentation/Source/eric7.Utilities.__init__.html	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Documentation/Source/eric7.Utilities.__init__.html	Sun Dec 18 19:33:46 2022 +0100
@@ -38,22 +38,6 @@
 <td>Protected function called for replacing % codes.</td>
 </tr>
 <tr>
-<td><a href="#absolutePath">absolutePath</a></td>
-<td>Public method to convert a path relative to a start path to an absolute path.</td>
-</tr>
-<tr>
-<td><a href="#absoluteUniversalPath">absoluteUniversalPath</a></td>
-<td>Public method to convert a path relative to a start path with universal separators to an absolute path.</td>
-</tr>
-<tr>
-<td><a href="#checkPyside">checkPyside</a></td>
-<td>Module function to check the presence of PySide2/PySide6.</td>
-</tr>
-<tr>
-<td><a href="#compactPath">compactPath</a></td>
-<td>Function to return a compacted path fitting inside the given width.</td>
-</tr>
-<tr>
 <td><a href="#convertLineEnds">convertLineEnds</a></td>
 <td>Function to convert the end of line characters.</td>
 </tr>
@@ -70,14 +54,6 @@
 <td>Function to decode a string containing Unicode encoded characters.</td>
 </tr>
 <tr>
-<td><a href="#determinePythonVersion">determinePythonVersion</a></td>
-<td>Function to determine the python version of a given file.</td>
-</tr>
-<tr>
-<td><a href="#direntries">direntries</a></td>
-<td>Function returning a list of all files and directories.</td>
-</tr>
-<tr>
 <td><a href="#encode">encode</a></td>
 <td>Function to encode text into a byte text.</td>
 </tr>
@@ -106,14 +82,6 @@
 <td>Function to filter out ANSI escape sequences (color only).</td>
 </tr>
 <tr>
-<td><a href="#findVolume">findVolume</a></td>
-<td>Function to find the directory belonging to a given volume name.</td>
-</tr>
-<tr>
-<td><a href="#fromNativeSeparators">fromNativeSeparators</a></td>
-<td>Function returning a path, that is using "/" separator characters.</td>
-</tr>
-<tr>
 <td><a href="#generateDistroInfo">generateDistroInfo</a></td>
 <td>Module function to generate a string with distribution infos.</td>
 </tr>
@@ -122,18 +90,6 @@
 <td>Module function to generate a string with plugins version infos.</td>
 </tr>
 <tr>
-<td><a href="#generatePyQtToolPath">generatePyQtToolPath</a></td>
-<td>Module function to generate the executable path for a PyQt tool.</td>
-</tr>
-<tr>
-<td><a href="#generatePySideToolPath">generatePySideToolPath</a></td>
-<td>Module function to generate the executable path for a PySide2/PySide6 tool.</td>
-</tr>
-<tr>
-<td><a href="#generateQtToolName">generateQtToolName</a></td>
-<td>Module function to generate the executable name for a Qt tool like designer.</td>
-</tr>
-<tr>
 <td><a href="#generateVersionInfo">generateVersionInfo</a></td>
 <td>Module function to generate a string with various version infos.</td>
 </tr>
@@ -146,26 +102,6 @@
 <td>Function to build a list of coverage data file names.</td>
 </tr>
 <tr>
-<td><a href="#getDirs">getDirs</a></td>
-<td>Function returning a list of all directories below path.</td>
-</tr>
-<tr>
-<td><a href="#getEnvironmentEntry">getEnvironmentEntry</a></td>
-<td>Module function to get an environment entry.</td>
-</tr>
-<tr>
-<td><a href="#getExecutablePath">getExecutablePath</a></td>
-<td>Function to build the full path of an executable file from the environment.</td>
-</tr>
-<tr>
-<td><a href="#getExecutablePaths">getExecutablePaths</a></td>
-<td>Function to build all full path of an executable file from the environment.</td>
-</tr>
-<tr>
-<td><a href="#getHomeDir">getHomeDir</a></td>
-<td>Function to get a users home directory.</td>
-</tr>
-<tr>
 <td><a href="#getPercentReplacement">getPercentReplacement</a></td>
 <td>Function to get the replacement for code.</td>
 </tr>
@@ -182,22 +118,6 @@
 <td>Function to build a list of profile data file names.</td>
 </tr>
 <tr>
-<td><a href="#getPythonLibPath">getPythonLibPath</a></td>
-<td>Function to determine the path to Python's library.</td>
-</tr>
-<tr>
-<td><a href="#getPythonVersion">getPythonVersion</a></td>
-<td>Function to get the Python version (major, minor) as an integer value.</td>
-</tr>
-<tr>
-<td><a href="#getQtMacBundle">getQtMacBundle</a></td>
-<td>Module function to determine the correct Mac OS X bundle name for Qt tools.</td>
-</tr>
-<tr>
-<td><a href="#getRealName">getRealName</a></td>
-<td>Function to get the real name of the user.</td>
-</tr>
-<tr>
 <td><a href="#getSysPath">getSysPath</a></td>
 <td>Module function to get the Python path (sys.path) of a specific interpreter.</td>
 </tr>
@@ -206,18 +126,6 @@
 <td>Function to build the potential file names of a test file.</td>
 </tr>
 <tr>
-<td><a href="#getUserName">getUserName</a></td>
-<td>Function to get the user name.</td>
-</tr>
-<tr>
-<td><a href="#getVolumeName">getVolumeName</a></td>
-<td>Local function to determine the volume of a disk or device.</td>
-</tr>
-<tr>
-<td><a href="#getWindowsExecutablePath">getWindowsExecutablePath</a></td>
-<td>Function to build the full path of an executable file from the environment on Windows platforms.</td>
-</tr>
-<tr>
 <td><a href="#get_coding">get_coding</a></td>
 <td>Function to get the coding of a text.</td>
 </tr>
@@ -226,10 +134,6 @@
 <td>Function to get the coding of a bytes text.</td>
 </tr>
 <tr>
-<td><a href="#hasEnvironmentEntry">hasEnvironmentEntry</a></td>
-<td>Module function to check, if the environment contains an entry.</td>
-</tr>
-<tr>
 <td><a href="#html_encode">html_encode</a></td>
 <td>Function to correctly encode a text for html.</td>
 </tr>
@@ -242,54 +146,18 @@
 <td>Function to correctly encode a unicode text for html.</td>
 </tr>
 <tr>
-<td><a href="#isDrive">isDrive</a></td>
-<td>Function to check, if a path is a Windows drive.</td>
-</tr>
-<tr>
-<td><a href="#isExecutable">isExecutable</a></td>
-<td>Function to check, if a file is executable.</td>
-</tr>
-<tr>
-<td><a href="#isinpath">isinpath</a></td>
-<td>Function to check for an executable file.</td>
-</tr>
-<tr>
-<td><a href="#joinext">joinext</a></td>
-<td>Function to join a file extension to a path.</td>
-</tr>
-<tr>
 <td><a href="#linesep">linesep</a></td>
 <td>Function to return the line separator used by the editor.</td>
 </tr>
 <tr>
-<td><a href="#normabsjoinpath">normabsjoinpath</a></td>
-<td>Function returning a normalized, absolute path of the joined parts passed into it.</td>
-</tr>
-<tr>
 <td><a href="#normalizeCode">normalizeCode</a></td>
 <td>Function to normalize the given code.</td>
 </tr>
 <tr>
-<td><a href="#normcaseabspath">normcaseabspath</a></td>
-<td>Function returning an absolute path, that is normalized with respect to its case and references.</td>
-</tr>
-<tr>
-<td><a href="#normcasepath">normcasepath</a></td>
-<td>Function returning a path, that is normalized with respect to its case and references.</td>
-</tr>
-<tr>
-<td><a href="#normjoinpath">normjoinpath</a></td>
-<td>Function returning a normalized path of the joined parts passed into it.</td>
-</tr>
-<tr>
 <td><a href="#parseOptionString">parseOptionString</a></td>
 <td>Function used to convert an option string into a list of options.</td>
 </tr>
 <tr>
-<td><a href="#prepareQtMacBundle">prepareQtMacBundle</a></td>
-<td>Module function for starting Qt tools that are Mac OS X bundles.</td>
-</tr>
-<tr>
 <td><a href="#readEncodedFile">readEncodedFile</a></td>
 <td>Function to read a file and decode its contents into proper text.</td>
 </tr>
@@ -306,54 +174,14 @@
 <td>Module function to read a string from the given stream.</td>
 </tr>
 <tr>
-<td><a href="#relativeUniversalPath">relativeUniversalPath</a></td>
-<td>Function to convert a file path to a path relative to a start path with universal separators.</td>
-</tr>
-<tr>
 <td><a href="#rxIndex">rxIndex</a></td>
 <td>Function to get the index (start position) of a regular expression match within some text.</td>
 </tr>
 <tr>
-<td><a href="#samefilepath">samefilepath</a></td>
-<td>Function to compare two paths.</td>
-</tr>
-<tr>
-<td><a href="#samepath">samepath</a></td>
-<td>Function to compare two paths.</td>
-</tr>
-<tr>
-<td><a href="#splitPath">splitPath</a></td>
-<td>Function to split a pathname into a directory part and a file part.</td>
-</tr>
-<tr>
-<td><a href="#startswithPath">startswithPath</a></td>
-<td>Function to check, if a path starts with a given start path.</td>
-</tr>
-<tr>
-<td><a href="#toBool">toBool</a></td>
-<td>Module function to convert a string to a boolean value.</td>
-</tr>
-<tr>
-<td><a href="#toNativeSeparators">toNativeSeparators</a></td>
-<td>Function returning a path, that is using native separator characters.</td>
-</tr>
-<tr>
 <td><a href="#unescape_uentities">unescape_uentities</a></td>
 <td>Function to decode html entities.</td>
 </tr>
 <tr>
-<td><a href="#win32_GetUserName">win32_GetUserName</a></td>
-<td>Function to get the user name under Win32.</td>
-</tr>
-<tr>
-<td><a href="#win32_Kill">win32_Kill</a></td>
-<td>Function to provide an os.kill equivalent for Win32.</td>
-</tr>
-<tr>
-<td><a href="#win32_getRealName">win32_getRealName</a></td>
-<td>Function to get the user's real name (aka.</td>
-</tr>
-<tr>
 <td><a href="#writeEncodedFile">writeEncodedFile</a></td>
 <td>Function to write a file with properly encoded text.</td>
 </tr>
@@ -518,123 +346,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="absolutePath" ID="absolutePath"></a>
-<h2>absolutePath</h2>
-<b>absolutePath</b>(<i>path, start</i>)
-
-<p>
-    Public method to convert a path relative to a start path to an
-    absolute path.
-</p>
-<dl>
-
-<dt><i>path</i></dt>
-<dd>
-file or directory name to convert (string)
-</dd>
-<dt><i>start</i></dt>
-<dd>
-start path (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-absolute path (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="absoluteUniversalPath" ID="absoluteUniversalPath"></a>
-<h2>absoluteUniversalPath</h2>
-<b>absoluteUniversalPath</b>(<i>path, start</i>)
-
-<p>
-    Public method to convert a path relative to a start path with
-    universal separators to an absolute path.
-</p>
-<dl>
-
-<dt><i>path</i></dt>
-<dd>
-file or directory name to convert (string)
-</dd>
-<dt><i>start</i></dt>
-<dd>
-start path (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-absolute path with native separators (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="checkPyside" ID="checkPyside"></a>
-<h2>checkPyside</h2>
-<b>checkPyside</b>(<i>variant=2</i>)
-
-<p>
-    Module function to check the presence of PySide2/PySide6.
-</p>
-<dl>
-
-<dt><i>variant</i> (int or str)</dt>
-<dd>
-indicator for the PySide variant
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-flags indicating the presence of PySide2/PySide6
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-bool
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="compactPath" ID="compactPath"></a>
-<h2>compactPath</h2>
-<b>compactPath</b>(<i>path, width, measure=len</i>)
-
-<p>
-    Function to return a compacted path fitting inside the given width.
-</p>
-<dl>
-
-<dt><i>path</i></dt>
-<dd>
-path to be compacted (string)
-</dd>
-<dt><i>width</i></dt>
-<dd>
-width for the compacted path (integer)
-</dd>
-<dt><i>measure</i></dt>
-<dd>
-reference to a function used to measure the length of the
-        string
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-compacted path (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="convertLineEnds" ID="convertLineEnds"></a>
 <h2>convertLineEnds</h2>
 <b>convertLineEnds</b>(<i>text, eol</i>)
@@ -731,86 +442,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="determinePythonVersion" ID="determinePythonVersion"></a>
-<h2>determinePythonVersion</h2>
-<b>determinePythonVersion</b>(<i>filename, source, editor=None</i>)
-
-<p>
-    Function to determine the python version of a given file.
-</p>
-<dl>
-
-<dt><i>filename</i></dt>
-<dd>
-name of the file with extension (str)
-</dd>
-<dt><i>source</i></dt>
-<dd>
-of the file (str)
-</dd>
-<dt><i>editor</i></dt>
-<dd>
-reference to the editor, if the file is opened
-        already (Editor object)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-Python version if file is Python3 (int)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="direntries" ID="direntries"></a>
-<h2>direntries</h2>
-<b>direntries</b>(<i>path, filesonly=False, pattern=None, followsymlinks=True, checkStop=None</i>)
-
-<p>
-    Function returning a list of all files and directories.
-</p>
-<dl>
-
-<dt><i>path</i> (str)</dt>
-<dd>
-root of the tree to check
-</dd>
-<dt><i>filesonly</i> (bool)</dt>
-<dd>
-flag indicating that only files are wanted
-</dd>
-<dt><i>pattern</i> (str or list of str)</dt>
-<dd>
-a filename pattern or list of filename patterns to check
-        against
-</dd>
-<dt><i>followsymlinks</i> (bool)</dt>
-<dd>
-flag indicating whether symbolic links
-        should be followed
-</dd>
-<dt><i>checkStop</i> (function)</dt>
-<dd>
-function to be called to check for a stop
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-list of all files and directories in the tree rooted
-        at path. The names are expanded to start with path.
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-list of strs
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="encode" ID="encode"></a>
 <h2>encode</h2>
 <b>encode</b>(<i>text, origEncoding, forcedEncoding=""</i>)
@@ -1026,70 +657,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="findVolume" ID="findVolume"></a>
-<h2>findVolume</h2>
-<b>findVolume</b>(<i>volumeName, findAll=False</i>)
-
-<p>
-    Function to find the directory belonging to a given volume name.
-</p>
-<dl>
-
-<dt><i>volumeName</i> (str)</dt>
-<dd>
-name of the volume to search for
-</dd>
-<dt><i>findAll</i> (bool (optional))</dt>
-<dd>
-flag indicating to get the directories for all volumes
-        starting with the given name (defaults to False)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-directory path or list of directory paths for the given volume
-        name
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-str or list of str
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="fromNativeSeparators" ID="fromNativeSeparators"></a>
-<h2>fromNativeSeparators</h2>
-<b>fromNativeSeparators</b>(<i>path</i>)
-
-<p>
-    Function returning a path, that is using "/" separator characters.
-</p>
-<dl>
-
-<dt><i>path</i> (str)</dt>
-<dd>
-path to be converted
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-path with converted separator characters
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-str
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="generateDistroInfo" ID="generateDistroInfo"></a>
 <h2>generateDistroInfo</h2>
 <b>generateDistroInfo</b>(<i>linesep="\n"</i>)
@@ -1148,96 +715,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="generatePyQtToolPath" ID="generatePyQtToolPath"></a>
-<h2>generatePyQtToolPath</h2>
-<b>generatePyQtToolPath</b>(<i>toolname, alternatives=None</i>)
-
-<p>
-    Module function to generate the executable path for a PyQt tool.
-</p>
-<dl>
-
-<dt><i>toolname</i> (str)</dt>
-<dd>
-base name of the tool
-</dd>
-<dt><i>alternatives</i> (list of str)</dt>
-<dd>
-list of alternative tool names to try
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-executable path name of the tool
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-str
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="generatePySideToolPath" ID="generatePySideToolPath"></a>
-<h2>generatePySideToolPath</h2>
-<b>generatePySideToolPath</b>(<i>toolname, variant=2</i>)
-
-<p>
-    Module function to generate the executable path for a PySide2/PySide6 tool.
-</p>
-<dl>
-
-<dt><i>toolname</i> (str)</dt>
-<dd>
-base name of the tool
-</dd>
-<dt><i>variant</i> (int or str)</dt>
-<dd>
-indicator for the PySide variant
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-the PySide2/PySide6 tool path with extension
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-str
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="generateQtToolName" ID="generateQtToolName"></a>
-<h2>generateQtToolName</h2>
-<b>generateQtToolName</b>(<i>toolname</i>)
-
-<p>
-    Module function to generate the executable name for a Qt tool like
-    designer.
-</p>
-<dl>
-
-<dt><i>toolname</i></dt>
-<dd>
-base name of the tool (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-the Qt tool name without extension (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="generateVersionInfo" ID="generateVersionInfo"></a>
 <h2>generateVersionInfo</h2>
 <b>generateVersionInfo</b>(<i>linesep="\n"</i>)
@@ -1330,128 +807,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="getDirs" ID="getDirs"></a>
-<h2>getDirs</h2>
-<b>getDirs</b>(<i>path, excludeDirs</i>)
-
-<p>
-    Function returning a list of all directories below path.
-</p>
-<dl>
-
-<dt><i>path</i></dt>
-<dd>
-root of the tree to check
-</dd>
-<dt><i>excludeDirs</i></dt>
-<dd>
-basename of directories to ignore
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-list of all directories found
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="getEnvironmentEntry" ID="getEnvironmentEntry"></a>
-<h2>getEnvironmentEntry</h2>
-<b>getEnvironmentEntry</b>(<i>key, default=None</i>)
-
-<p>
-    Module function to get an environment entry.
-</p>
-<dl>
-
-<dt><i>key</i></dt>
-<dd>
-key of the requested environment entry (string)
-</dd>
-<dt><i>default</i></dt>
-<dd>
-value to be returned, if the environment doesn't contain
-        the requested entry (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-the requested entry or the default value, if the entry wasn't
-        found (string or None)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="getExecutablePath" ID="getExecutablePath"></a>
-<h2>getExecutablePath</h2>
-<b>getExecutablePath</b>(<i>file</i>)
-
-<p>
-    Function to build the full path of an executable file from the environment.
-</p>
-<dl>
-
-<dt><i>file</i></dt>
-<dd>
-filename of the executable to check (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-full executable name, if the executable file is accessible
-        via the searchpath defined by the PATH environment variable, or an
-        empty string otherwise.
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="getExecutablePaths" ID="getExecutablePaths"></a>
-<h2>getExecutablePaths</h2>
-<b>getExecutablePaths</b>(<i>file</i>)
-
-<p>
-    Function to build all full path of an executable file from the environment.
-</p>
-<dl>
-
-<dt><i>file</i></dt>
-<dd>
-filename of the executable (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-list of full executable names (list of strings), if the executable
-        file is accessible via the searchpath defined by the PATH environment
-        variable, or an empty list otherwise.
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="getHomeDir" ID="getHomeDir"></a>
-<h2>getHomeDir</h2>
-<b>getHomeDir</b>(<i></i>)
-
-<p>
-    Function to get a users home directory.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-home directory (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="getPercentReplacement" ID="getPercentReplacement"></a>
 <h2>getPercentReplacement</h2>
 <b>getPercentReplacement</b>(<i>code</i>)
@@ -1560,77 +915,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="getPythonLibPath" ID="getPythonLibPath"></a>
-<h2>getPythonLibPath</h2>
-<b>getPythonLibPath</b>(<i></i>)
-
-<p>
-    Function to determine the path to Python's library.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-path to the Python library (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="getPythonVersion" ID="getPythonVersion"></a>
-<h2>getPythonVersion</h2>
-<b>getPythonVersion</b>(<i></i>)
-
-<p>
-    Function to get the Python version (major, minor) as an integer value.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-An integer representing major and minor version number (integer)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="getQtMacBundle" ID="getQtMacBundle"></a>
-<h2>getQtMacBundle</h2>
-<b>getQtMacBundle</b>(<i>toolname</i>)
-
-<p>
-    Module function to determine the correct Mac OS X bundle name for Qt tools.
-</p>
-<dl>
-
-<dt><i>toolname</i></dt>
-<dd>
-plain name of the tool (e.g. "designer") (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-bundle name of the Qt tool (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="getRealName" ID="getRealName"></a>
-<h2>getRealName</h2>
-<b>getRealName</b>(<i></i>)
-
-<p>
-    Function to get the real name of the user.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-real name of the user (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="getSysPath" ID="getSysPath"></a>
 <h2>getSysPath</h2>
 <b>getSysPath</b>(<i>interpreter</i>)
@@ -1696,71 +980,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="getUserName" ID="getUserName"></a>
-<h2>getUserName</h2>
-<b>getUserName</b>(<i></i>)
-
-<p>
-    Function to get the user name.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-user name (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="getVolumeName" ID="getVolumeName"></a>
-<h2>getVolumeName</h2>
-<b>getVolumeName</b>(<i>diskName</i>)
-
-<p>
-            Local function to determine the volume of a disk or device.
-</p>
-<p>
-            Each disk or external device connected to windows has an
-            attribute called "volume name". This function returns the
-            volume name for the given disk/device.
-</p>
-<p>
-            Code from http://stackoverflow.com/a/12056414
-</p>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="getWindowsExecutablePath" ID="getWindowsExecutablePath"></a>
-<h2>getWindowsExecutablePath</h2>
-<b>getWindowsExecutablePath</b>(<i>file</i>)
-
-<p>
-    Function to build the full path of an executable file from the environment
-    on Windows platforms.
-</p>
-<p>
-    First an executable with the extension .exe is searched for, thereafter
-    such with the extensions .cmd or .bat and finally the given file name as
-    is. The first match is returned.
-</p>
-<dl>
-
-<dt><i>file</i></dt>
-<dd>
-filename of the executable to check (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-full executable name, if the executable file is accessible
-        via the searchpath defined by the PATH environment variable, or an
-        empty string otherwise.
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="get_coding" ID="get_coding"></a>
 <h2>get_coding</h2>
 <b>get_coding</b>(<i>text</i>)
@@ -1807,35 +1026,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="hasEnvironmentEntry" ID="hasEnvironmentEntry"></a>
-<h2>hasEnvironmentEntry</h2>
-<b>hasEnvironmentEntry</b>(<i>key</i>)
-
-<p>
-    Module function to check, if the environment contains an entry.
-</p>
-<dl>
-
-<dt><i>key</i> (str)</dt>
-<dd>
-key of the requested environment entry
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-flag indicating the presence of the requested entry
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-bool
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="html_encode" ID="html_encode"></a>
 <h2>html_encode</h2>
 <b>html_encode</b>(<i>text, pattern=_escape</i>)
@@ -1917,113 +1107,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="isDrive" ID="isDrive"></a>
-<h2>isDrive</h2>
-<b>isDrive</b>(<i>path</i>)
-
-<p>
-    Function to check, if a path is a Windows drive.
-</p>
-<dl>
-
-<dt><i>path</i> (str)</dt>
-<dd>
-path name to be checked
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-flag indicating a Windows drive
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-bool
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="isExecutable" ID="isExecutable"></a>
-<h2>isExecutable</h2>
-<b>isExecutable</b>(<i>exe</i>)
-
-<p>
-    Function to check, if a file is executable.
-</p>
-<dl>
-
-<dt><i>exe</i></dt>
-<dd>
-filename of the executable to check (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-flag indicating executable status (boolean)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="isinpath" ID="isinpath"></a>
-<h2>isinpath</h2>
-<b>isinpath</b>(<i>file</i>)
-
-<p>
-    Function to check for an executable file.
-</p>
-<dl>
-
-<dt><i>file</i></dt>
-<dd>
-filename of the executable to check (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-flag to indicate, if the executable file is accessible
-        via the searchpath defined by the PATH environment variable.
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="joinext" ID="joinext"></a>
-<h2>joinext</h2>
-<b>joinext</b>(<i>prefix, ext</i>)
-
-<p>
-    Function to join a file extension to a path.
-</p>
-<p>
-    The leading "." of ext is replaced by a platform specific extension
-    separator if necessary.
-</p>
-<dl>
-
-<dt><i>prefix</i></dt>
-<dd>
-the basepart of the filename (string)
-</dd>
-<dt><i>ext</i></dt>
-<dd>
-the extension part (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-the complete filename (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="linesep" ID="linesep"></a>
 <h2>linesep</h2>
 <b>linesep</b>(<i></i>)
@@ -2040,34 +1123,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="normabsjoinpath" ID="normabsjoinpath"></a>
-<h2>normabsjoinpath</h2>
-<b>normabsjoinpath</b>(<i>a, *p</i>)
-
-<p>
-    Function returning a normalized, absolute path of the joined parts passed
-    into it.
-</p>
-<dl>
-
-<dt><i>a</i></dt>
-<dd>
-first path to be joined (string)
-</dd>
-<dt><i>p</i></dt>
-<dd>
-variable number of path parts to be joind (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-absolute, normalized path (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="normalizeCode" ID="normalizeCode"></a>
 <h2>normalizeCode</h2>
 <b>normalizeCode</b>(<i>codestring</i>)
@@ -2091,81 +1146,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="normcaseabspath" ID="normcaseabspath"></a>
-<h2>normcaseabspath</h2>
-<b>normcaseabspath</b>(<i>path</i>)
-
-<p>
-    Function returning an absolute path, that is normalized with respect to
-    its case and references.
-</p>
-<dl>
-
-<dt><i>path</i></dt>
-<dd>
-file path (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-absolute, normalized path (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="normcasepath" ID="normcasepath"></a>
-<h2>normcasepath</h2>
-<b>normcasepath</b>(<i>path</i>)
-
-<p>
-    Function returning a path, that is normalized with respect to its case
-    and references.
-</p>
-<dl>
-
-<dt><i>path</i></dt>
-<dd>
-file path (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-case normalized path (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="normjoinpath" ID="normjoinpath"></a>
-<h2>normjoinpath</h2>
-<b>normjoinpath</b>(<i>a, *p</i>)
-
-<p>
-    Function returning a normalized path of the joined parts passed into it.
-</p>
-<dl>
-
-<dt><i>a</i></dt>
-<dd>
-first path to be joined (string)
-</dd>
-<dt><i>p</i></dt>
-<dd>
-variable number of path parts to be joined (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-normalized path (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="parseOptionString" ID="parseOptionString"></a>
 <h2>parseOptionString</h2>
 <b>parseOptionString</b>(<i>s</i>)
@@ -2195,39 +1175,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="prepareQtMacBundle" ID="prepareQtMacBundle"></a>
-<h2>prepareQtMacBundle</h2>
-<b>prepareQtMacBundle</b>(<i>toolname, args</i>)
-
-<p>
-    Module function for starting Qt tools that are Mac OS X bundles.
-</p>
-<dl>
-
-<dt><i>toolname</i> (str)</dt>
-<dd>
-plain name of the tool (e.g. "designer")
-</dd>
-<dt><i>args</i> (list of str)</dt>
-<dd>
-name of input file for tool, if any
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-command-name and args for QProcess
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-tuple of (str, list of str)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="readEncodedFile" ID="readEncodedFile"></a>
 <h2>readEncodedFile</h2>
 <b>readEncodedFile</b>(<i>filename</i>)
@@ -2326,35 +1273,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="relativeUniversalPath" ID="relativeUniversalPath"></a>
-<h2>relativeUniversalPath</h2>
-<b>relativeUniversalPath</b>(<i>path, start</i>)
-
-<p>
-    Function to convert a file path to a path relative to a start path
-    with universal separators.
-</p>
-<dl>
-
-<dt><i>path</i></dt>
-<dd>
-file or directory name to convert (string)
-</dd>
-<dt><i>start</i></dt>
-<dd>
-start path (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-relative path or unchanged path, if path does not start with
-        the start path with universal separators (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="rxIndex" ID="rxIndex"></a>
 <h2>rxIndex</h2>
 <b>rxIndex</b>(<i>rx, txt</i>)
@@ -2389,171 +1307,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="samefilepath" ID="samefilepath"></a>
-<h2>samefilepath</h2>
-<b>samefilepath</b>(<i>f1, f2</i>)
-
-<p>
-    Function to compare two paths. Strips the filename.
-</p>
-<dl>
-
-<dt><i>f1</i></dt>
-<dd>
-first filepath for the compare (string)
-</dd>
-<dt><i>f2</i></dt>
-<dd>
-second filepath for the compare (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-flag indicating whether the two paths represent the
-        same path on disk.
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="samepath" ID="samepath"></a>
-<h2>samepath</h2>
-<b>samepath</b>(<i>f1, f2</i>)
-
-<p>
-    Function to compare two paths.
-</p>
-<dl>
-
-<dt><i>f1</i></dt>
-<dd>
-first path for the compare (string)
-</dd>
-<dt><i>f2</i></dt>
-<dd>
-second path for the compare (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-flag indicating whether the two paths represent the
-        same path on disk.
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="splitPath" ID="splitPath"></a>
-<h2>splitPath</h2>
-<b>splitPath</b>(<i>name</i>)
-
-<p>
-    Function to split a pathname into a directory part and a file part.
-</p>
-<dl>
-
-<dt><i>name</i></dt>
-<dd>
-path name (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-a tuple of 2 strings (dirname, filename).
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="startswithPath" ID="startswithPath"></a>
-<h2>startswithPath</h2>
-<b>startswithPath</b>(<i>path, start</i>)
-
-<p>
-    Function to check, if a path starts with a given start path.
-</p>
-<dl>
-
-<dt><i>path</i> (str)</dt>
-<dd>
-path to be checked
-</dd>
-<dt><i>start</i> (str)</dt>
-<dd>
-start path
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-flag indicating that the path starts with the given start
-        path
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-bool
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="toBool" ID="toBool"></a>
-<h2>toBool</h2>
-<b>toBool</b>(<i>dataStr</i>)
-
-<p>
-    Module function to convert a string to a boolean value.
-</p>
-<dl>
-
-<dt><i>dataStr</i></dt>
-<dd>
-string to be converted (string)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-converted boolean value (boolean)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="toNativeSeparators" ID="toNativeSeparators"></a>
-<h2>toNativeSeparators</h2>
-<b>toNativeSeparators</b>(<i>path</i>)
-
-<p>
-    Function returning a path, that is using native separator characters.
-</p>
-<dl>
-
-<dt><i>path</i> (str)</dt>
-<dd>
-path to be converted
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-path with converted separator characters
-</dd>
-</dl>
-<dl>
-<dt>Return Type:</dt>
-<dd>
-str
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="unescape_uentities" ID="unescape_uentities"></a>
 <h2>unescape_uentities</h2>
 <b>unescape_uentities</b>(<i>m</i>)
@@ -2577,61 +1330,6 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="win32_GetUserName" ID="win32_GetUserName"></a>
-<h2>win32_GetUserName</h2>
-<b>win32_GetUserName</b>(<i></i>)
-
-<p>
-    Function to get the user name under Win32.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-user name (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="win32_Kill" ID="win32_Kill"></a>
-<h2>win32_Kill</h2>
-<b>win32_Kill</b>(<i>pid</i>)
-
-<p>
-    Function to provide an os.kill equivalent for Win32.
-</p>
-<dl>
-
-<dt><i>pid</i></dt>
-<dd>
-process id (integer)
-</dd>
-</dl>
-<dl>
-<dt>Return:</dt>
-<dd>
-result of the kill (boolean)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
-<a NAME="win32_getRealName" ID="win32_getRealName"></a>
-<h2>win32_getRealName</h2>
-<b>win32_getRealName</b>(<i></i>)
-
-<p>
-    Function to get the user's real name (aka. display name) under Win32.
-</p>
-<dl>
-<dt>Return:</dt>
-<dd>
-real name of the current user (string)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-<hr />
 <a NAME="writeEncodedFile" ID="writeEncodedFile"></a>
 <h2>writeEncodedFile</h2>
 <b>writeEncodedFile</b>(<i>filename, text, origEncoding, forcedEncoding=""</i>)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Documentation/Source/index-eric7.SystemUtilities.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/index-eric7.SystemUtilities.html	Sun Dec 18 19:33:46 2022 +0100
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.SystemUtilities</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<h1>eric7.SystemUtilities</h1>
+
+<p>
+Package implementing system level utility functions and classes.
+</p>
+
+
+<h3>Modules</h3>
+<table>
+
+<tr>
+<td><a href="eric7.SystemUtilities.DesktopUtilities.html">DesktopUtilities</a></td>
+<td>Module implementing Linux desktop related utility functions.</td>
+</tr>
+<tr>
+<td><a href="eric7.SystemUtilities.FileSystemUtilities.html">FileSystemUtilities</a></td>
+<td>Module implementing file system related utility functions.</td>
+</tr>
+<tr>
+<td><a href="eric7.SystemUtilities.OSUtilities.html">OSUtilities</a></td>
+<td>Module implementing Operating System related utility functions.</td>
+</tr>
+<tr>
+<td><a href="eric7.SystemUtilities.PySideImporter.html">PySideImporter</a></td>
+<td>Module to check for the presence of PySide2/PySide6 by importing it.</td>
+</tr>
+<tr>
+<td><a href="eric7.SystemUtilities.PythonUtilities.html">PythonUtilities</a></td>
+<td>Module implementing Python related utility functions.</td>
+</tr>
+<tr>
+<td><a href="eric7.SystemUtilities.QtUtilities.html">QtUtilities</a></td>
+<td>Module implementing Qt/PyQt/PySide related utility functions.</td>
+</tr>
+</table>
+</body></html>
\ No newline at end of file
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Documentation/Source/index-eric7.Utilities.html
--- a/src/eric7/Documentation/Source/index-eric7.Utilities.html	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Documentation/Source/index-eric7.Utilities.html	Sun Dec 18 19:33:46 2022 +0100
@@ -64,10 +64,6 @@
 <td>Module implementing a checker for password strength.</td>
 </tr>
 <tr>
-<td><a href="eric7.Utilities.PySideImporter.html">PySideImporter</a></td>
-<td>Module to check for the presence of PySide2/PySide6 by importing it.</td>
-</tr>
-<tr>
 <td><a href="eric7.Utilities.__init__.html">Utilities</a></td>
 <td>Package implementing various functions/classes needed everywhere within eric.</td>
 </tr>
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Documentation/Source/index-eric7.html
--- a/src/eric7/Documentation/Source/index-eric7.html	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Documentation/Source/index-eric7.html	Sun Dec 18 19:33:46 2022 +0100
@@ -151,6 +151,10 @@
 <td>Package containing module for the SQL browser tool.</td>
 </tr>
 <tr>
+<td><a href="index-eric7.SystemUtilities.html">SystemUtilities</a></td>
+<td>Package implementing system level utility functions and classes.</td>
+</tr>
+<tr>
 <td><a href="index-eric7.Tasks.html">Tasks</a></td>
 <td>Package containing modules for the task management tool.</td>
 </tr>
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/DocumentationTools/IndexGenerator.py
--- a/src/eric7/DocumentationTools/IndexGenerator.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/DocumentationTools/IndexGenerator.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,7 +11,7 @@
 import os
 import sys
 
-from eric7.Utilities import joinext
+from eric7.SystemUtilities import FileSystemUtilities
 
 from . import TemplatesListsStyleCSS
 
@@ -96,7 +96,7 @@
             f = os.path.join(self.outputDir, "index-{0}".format(packagename))
             title = packagename
 
-        filename = joinext(f, ".html")
+        filename = FileSystemUtilities.joinext(f, ".html")
 
         subpackages = ""
         modules = ""
@@ -107,7 +107,7 @@
             names = sorted(subpacks.keys())
             lst = []
             for name in names:
-                link = joinext("index-{0}".format(name), ".html")
+                link = FileSystemUtilities.joinext("index-{0}".format(name), ".html")
                 lst.append(
                     TemplatesListsStyleCSS.indexListEntryTemplate.format(
                         **{
@@ -129,7 +129,7 @@
             names = sorted(mods.keys())
             lst = []
             for name in names:
-                link = joinext(name, ".html")
+                link = FileSystemUtilities.joinext(name, ".html")
                 nam = name.split(".")[-1]
                 if nam == "__init__":
                     nam = name.split(".")[-2]
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/DocumentationTools/QtHelpGenerator.py
--- a/src/eric7/DocumentationTools/QtHelpGenerator.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/DocumentationTools/QtHelpGenerator.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,7 +14,8 @@
 import sys
 
 from eric7 import Preferences
-from eric7.Utilities import generateQtToolName, getQtBinariesPath, html_encode, joinext
+from eric7.SystemUtilities import FileSystemUtilities, QtUtilities
+from eric7.Utilities import html_encode
 
 HelpCollection = r"""<?xml version="1.0" encoding="utf-8" ?>
 <QHelpCollectionProject version="1.0">
@@ -132,7 +133,7 @@
 
             kwEntry = (
                 "{0} (Package)".format(package.split(".")[-1]),
-                joinext("index-{0}".format(package), ".html"),
+                FileSystemUtilities.joinext("index-{0}".format(package), ".html"),
             )
             if kwEntry not in self.keywords:
                 self.keywords.append(kwEntry)
@@ -150,14 +151,16 @@
         if "__init__" not in file:
             kwEntry = (
                 "{0} (Module)".format(moduleDocument.name().split(".")[-1]),
-                joinext(moduleDocument.name(), ".html"),
+                FileSystemUtilities.joinext(moduleDocument.name(), ".html"),
             )
             if kwEntry not in self.keywords:
                 self.keywords.append(kwEntry)
         for kw in moduleDocument.getQtHelpKeywords():
             kwEntry = (
                 kw[0],
-                "{0}{1}".format(joinext(moduleDocument.name(), ".html"), kw[1]),
+                "{0}{1}".format(
+                    FileSystemUtilities.joinext(moduleDocument.name(), ".html"), kw[1]
+                ),
             )
             if kwEntry not in self.keywords:
                 self.keywords.append(kwEntry)
@@ -175,14 +178,14 @@
         s = indent + '<section title="{0}" ref="{1}">\n'.format(
             package == "00index" and self.title or package,
             package == "00index"
-            and joinext("index", ".html")
-            or joinext("index-{0}".format(package), ".html"),
+            and FileSystemUtilities.joinext("index", ".html")
+            or FileSystemUtilities.joinext("index-{0}".format(package), ".html"),
         )
         for subpack in sorted(self.packages[package]["subpackages"]):
             s += self.__generateSections(subpack, level + 1) + "\n"
         for mod in sorted(self.packages[package]["modules"]):
             s += indent1 + '<section title="{0}" ref="{1}" />\n'.format(
-                mod, joinext(mod, ".html")
+                mod, FileSystemUtilities.joinext(mod, ".html")
             )
         s += indent + "</section>"
         return s
@@ -288,12 +291,13 @@
         qhelpgeneratorExe = Preferences.getQt("QHelpGenerator")
         if not qhelpgeneratorExe:
             qhelpgeneratorExe = os.path.join(
-                getQtBinariesPath(libexec=True), generateQtToolName("qhelpgenerator")
+                QtUtilities.getQtBinariesPath(libexec=True),
+                QtUtilities.generateQtToolName("qhelpgenerator"),
             )
             if not os.path.exists(qhelpgeneratorExe):
                 qhelpgeneratorExe = os.path.join(
-                    getQtBinariesPath(libexec=False),
-                    generateQtToolName("qhelpgenerator"),
+                    QtUtilities.getQtBinariesPath(libexec=False),
+                    QtUtilities.generateQtToolName("qhelpgenerator"),
                 )
         shutil.copy(os.path.join(self.outputDir, HelpProjectFile), self.htmlDir)
         os.chdir(self.htmlDir)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/EricNetwork/EricGoogleMailHelpers.py
--- a/src/eric7/EricNetwork/EricGoogleMailHelpers.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/EricNetwork/EricGoogleMailHelpers.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,6 +11,7 @@
 
 from eric7 import Globals
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import PythonUtilities
 
 SCOPES = ["https://www.googleapis.com/auth/gmail.send"]
 CLIENT_SECRET_FILE = "eric_client_secret.json"  # secok
@@ -39,4 +40,6 @@
     Module function to install the required packages to support Google mail.
     """
     pip = ericApp().getObject("Pip")
-    pip.installPackages(RequiredPackages, interpreter=Globals.getPythonExecutable())
+    pip.installPackages(
+        RequiredPackages, interpreter=PythonUtilities.getPythonExecutable()
+    )
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/EricNetwork/EricJsonServer.py
--- a/src/eric7/EricNetwork/EricJsonServer.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/EricNetwork/EricJsonServer.py	Sun Dec 18 19:33:46 2022 +0100
@@ -23,6 +23,7 @@
 
 from eric7 import Preferences, Utilities
 from eric7.EricWidgets import EricMessageBox
+from eric7.SystemUtilities import FileSystemUtilities
 
 
 class EricJsonServer(QTcpServer):
@@ -235,7 +236,7 @@
             in case of an issue
         @rtype bool, int
         """
-        if interpreter == "" or not Utilities.isinpath(interpreter):
+        if interpreter == "" or not FileSystemUtilities.isinpath(interpreter):
             return False
 
         exitCode = None
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/EricNetwork/EricNetworkProxyFactory.py
--- a/src/eric7/EricNetwork/EricNetworkProxyFactory.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/EricNetwork/EricNetworkProxyFactory.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,8 +14,9 @@
 from PyQt6.QtNetwork import QNetworkProxy, QNetworkProxyFactory, QNetworkProxyQuery
 from PyQt6.QtWidgets import QDialog
 
-from eric7 import Globals, Preferences, Utilities
+from eric7 import Preferences, Utilities
 from eric7.EricWidgets import EricMessageBox
+from eric7.SystemUtilities import OSUtilities
 
 
 def schemeFromProxyType(proxyType):
@@ -172,7 +173,7 @@
             if Preferences.getUI("UseSystemProxy"):
                 proxyList = QNetworkProxyFactory.systemProxyForQuery(query)
                 if (
-                    not Globals.isWindowsPlatform()
+                    not OSUtilities.isWindowsPlatform()
                     and len(proxyList) == 1
                     and proxyList[0].type() == QNetworkProxy.ProxyType.NoProxy
                 ):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/EricNetwork/EricSslErrorHandler.py
--- a/src/eric7/EricNetwork/EricSslErrorHandler.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/EricNetwork/EricSslErrorHandler.py	Sun Dec 18 19:33:46 2022 +0100
@@ -16,6 +16,7 @@
 
 from eric7 import Globals, Preferences, Utilities
 from eric7.EricWidgets import EricMessageBox
+from eric7.SystemUtilities import OSUtilities
 
 
 class EricSslErrorState(enum.Enum):
@@ -66,7 +67,7 @@
         sslCfg.setCaCertificates(caList)
         try:
             sslProtocol = QSsl.SslProtocol.TlsV1_1OrLater
-            if Globals.isWindowsPlatform() and platform.win32_ver()[0] == "7":
+            if OSUtilities.isWindowsPlatform() and platform.win32_ver()[0] == "7":
                 sslProtocol = QSsl.SslProtocol.SecureProtocols
         except AttributeError:
             sslProtocol = QSsl.SslProtocol.SecureProtocols
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/EricWidgets/EricApplication.py
--- a/src/eric7/EricWidgets/EricApplication.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/EricWidgets/EricApplication.py	Sun Dec 18 19:33:46 2022 +0100
@@ -16,6 +16,8 @@
 if not QCoreApplication.testAttribute(Qt.ApplicationAttribute.AA_ShareOpenGLContexts):
     QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_ShareOpenGLContexts, True)
 
+from eric7.SystemUtilities import FileSystemUtilities
+
 from . import EricMessageBox
 
 
@@ -188,7 +190,7 @@
         @return directory path containing the style icons
         @rtype str
         """
-        from eric7 import Preferences, Utilities
+        from eric7 import Preferences
         from eric7.Globals import getConfig
 
         styleIconsPath = Preferences.getUI("StyleIconsPath")
@@ -198,7 +200,7 @@
             styleIconsPath = os.path.join(getConfig("ericIconDir"), "StyleIcons")
 
         if universal:
-            return Utilities.fromNativeSeparators(styleIconsPath)
+            return FileSystemUtilities.fromNativeSeparators(styleIconsPath)
         else:
             return styleIconsPath
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/EricWidgets/EricCompleters.py
--- a/src/eric7/EricWidgets/EricCompleters.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/EricWidgets/EricCompleters.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,7 +13,7 @@
 from PyQt6.QtGui import QFileSystemModel
 from PyQt6.QtWidgets import QCompleter
 
-from eric7.Globals import isWindowsPlatform
+from eric7.SystemUtilities import OSUtilities
 
 
 class EricFileCompleter(QCompleter):
@@ -56,7 +56,7 @@
         self.__model.setRootPath("")
         self.setModel(self.__model)
         self.setCompletionMode(completionMode)
-        if isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             self.setCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)
         if parent:
             parent.setCompleter(self)
@@ -113,7 +113,7 @@
         self.__model.setRootPath("")
         self.setModel(self.__model)
         self.setCompletionMode(completionMode)
-        if isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             self.setCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)
         if parent:
             parent.setCompleter(self)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/EricWidgets/EricFileDialog.py
--- a/src/eric7/EricWidgets/EricFileDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/EricWidgets/EricFileDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,7 +11,7 @@
 
 from PyQt6.QtWidgets import QFileDialog
 
-from eric7 import Globals
+from eric7.SystemUtilities import OSUtilities
 
 Option = QFileDialog.Option
 
@@ -36,7 +36,7 @@
     @return the rearranged Qt file filter
     @rtype str
     """
-    if initialFilter and not Globals.isMacPlatform():
+    if initialFilter and not OSUtilities.isMacPlatform():
         fileFilters = filterStr.split(";;")
         if len(fileFilters) < 10 and initialFilter in fileFilters:
             fileFilters.remove(initialFilter)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/EricWidgets/EricSingleApplication.py
--- a/src/eric7/EricWidgets/EricSingleApplication.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/EricWidgets/EricSingleApplication.py	Sun Dec 18 19:33:46 2022 +0100
@@ -9,8 +9,8 @@
 
 import os
 
-from eric7 import Utilities
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import OSUtilities
 from eric7.Toolbox.SingleApplication import (
     SingleApplicationClient,
     SingleApplicationServer,
@@ -124,7 +124,7 @@
         # flag indicating '--' options was found
         ddseen = False
 
-        argChars = ["-", "/"] if Utilities.isWindowsPlatform() else ["-"]
+        argChars = ["-", "/"] if OSUtilities.isWindowsPlatform() else ["-"]
 
         for arg in args:
             if arg == "--" and not ddseen:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/EricWidgets/EricSqueezeLabels.py
--- a/src/eric7/EricWidgets/EricSqueezeLabels.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/EricWidgets/EricSqueezeLabels.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,7 +11,7 @@
 from PyQt6.QtCore import Qt
 from PyQt6.QtWidgets import QLabel
 
-from eric7.Utilities import compactPath
+from eric7.SystemUtilities import FileSystemUtilities
 
 
 class EricSqueezeLabel(QLabel):
@@ -113,7 +113,9 @@
         if self.length(self.__path) > self.contentsRect().width():
             super().setText(
                 self.__surrounding.format(
-                    compactPath(self.__path, self.contentsRect().width(), self.length)
+                    FileSystemUtilities.compactPath(
+                        self.__path, self.contentsRect().width(), self.length
+                    )
                 )
             )
         else:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/EricXML/MultiProjectReader.py
--- a/src/eric7/EricXML/MultiProjectReader.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/EricXML/MultiProjectReader.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,7 +11,7 @@
 
 from PyQt6.QtCore import QUuid
 
-from eric7 import Utilities
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Config import multiProjectFileFormatVersion
 from .XMLStreamReaderBase import XMLStreamReaderBase
@@ -103,7 +103,7 @@
                 if self.name() == "ProjectName":
                     project["name"] = self.readElementText()
                 elif self.name() == "ProjectFile":
-                    project["file"] = Utilities.absoluteUniversalPath(
+                    project["file"] = FileSystemUtilities.absoluteUniversalPath(
                         self.readElementText(), self.path
                     )
                 elif self.name() == "ProjectDescription":
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/EricXML/ProjectReader.py
--- a/src/eric7/EricXML/ProjectReader.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/EricXML/ProjectReader.py	Sun Dec 18 19:33:46 2022 +0100
@@ -7,7 +7,7 @@
 Module implementing a class for reading an XML project file.
 """
 
-from eric7 import Utilities
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Config import projectFileFormatVersion
 from .XMLStreamReaderBase import XMLStreamReaderBase
@@ -53,13 +53,13 @@
                     )
                 elif self.name() == "ProjectWordList":
                     self.project.setProjectData(
-                        Utilities.toNativeSeparators(self.readElementText()),
+                        FileSystemUtilities.toNativeSeparators(self.readElementText()),
                         dataKey="SPELLWORDS",
                         setDirty=False,
                     )
                 elif self.name() == "ProjectExcludeList":
                     self.project.setProjectData(
-                        Utilities.toNativeSeparators(self.readElementText()),
+                        FileSystemUtilities.toNativeSeparators(self.readElementText()),
                         dataKey="SPELLEXCLUDES",
                         setDirty=False,
                     )
@@ -103,13 +103,13 @@
                     )
                 elif self.name() == "TranslationPattern":
                     self.project.setProjectData(
-                        Utilities.toNativeSeparators(self.readElementText()),
+                        FileSystemUtilities.toNativeSeparators(self.readElementText()),
                         dataKey="TRANSLATIONPATTERN",
                         setDirty=False,
                     )
                 elif self.name() == "TranslationsBinPath":
                     self.project.setProjectData(
-                        Utilities.toNativeSeparators(self.readElementText()),
+                        FileSystemUtilities.toNativeSeparators(self.readElementText()),
                         dataKey="TRANSLATIONSBINPATH",
                         setDirty=False,
                     )
@@ -127,7 +127,7 @@
                     )
                 elif self.name() == "MainScript":
                     self.project.setProjectData(
-                        Utilities.toNativeSeparators(self.readElementText()),
+                        FileSystemUtilities.toNativeSeparators(self.readElementText()),
                         dataKey="MAINSCRIPT",
                         setDirty=False,
                     )
@@ -199,7 +199,7 @@
                 if self.name() == listTag:
                     fileList = self.project.getProjectData(dataKey=dataKey)
                     fileList.append(
-                        Utilities.toNativeSeparators(self.readElementText())
+                        FileSystemUtilities.toNativeSeparators(self.readElementText())
                     )
                     self.project.setProjectData(
                         fileList, dataKey=dataKey, setDirty=False
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/EricXML/TasksReader.py
--- a/src/eric7/EricXML/TasksReader.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/EricXML/TasksReader.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,8 +12,8 @@
 
 from PyQt6.QtCore import QUuid
 
-from eric7 import Utilities
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import FileSystemUtilities
 from eric7.Tasks.Task import TaskPriority, TaskType
 
 from .Config import tasksFileFormatVersion
@@ -142,7 +142,7 @@
                 elif self.name() == "Resource":
                     continue  # handle but ignore this tag
                 elif self.name() == "Filename":
-                    task["filename"] = Utilities.toNativeSeparators(
+                    task["filename"] = FileSystemUtilities.toNativeSeparators(
                         self.readElementText()
                     )
                 elif self.name() == "Linenumber":
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Globals/__init__.py
--- a/src/eric7/Globals/__init__.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Globals/__init__.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,17 +14,33 @@
 import contextlib
 import os
 import re
-import sys
-import sysconfig
+
+from PyQt6.QtCore import QByteArray, QCoreApplication, QProcess, qVersion
+
+from eric7.SystemUtilities.DesktopUtilities import (  # __IGNORE_FLAKES_WARNING__
+    desktopName,
+    isGnomeDesktop,
+    isKdeDesktop,
+    isWaylandSession,
+    sessionType,
+)
 
-from PyQt6.QtCore import (
-    QT_VERSION,
-    QByteArray,
-    QCoreApplication,
-    QDir,
-    QLibraryInfo,
-    QProcess,
-    qVersion,
+# imports from eric7.SystemUtilities are for backward compatibility
+from eric7.SystemUtilities.OSUtilities import (  # __IGNORE_FLAKES_WARNING__
+    isLinuxPlatform,
+    isMacPlatform,
+    isWindowsPlatform,
+)
+from eric7.SystemUtilities.PythonUtilities import (  # __IGNORE_FLAKES_WARNING__
+    getPythonExecutable,
+    getPythonLibraryDirectory,
+    getPythonScriptsDirectory,
+)
+from eric7.SystemUtilities.QtUtilities import (  # __IGNORE_FLAKES_WARNING__
+    getPyQt6ModulesDirectory,
+    getPyQtToolsPath,
+    getQtBinariesPath,
+    qVersionTuple,
 )
 
 try:
@@ -54,162 +70,6 @@
 configDir = None
 
 
-def isWindowsPlatform():
-    """
-    Function to check, if this is a Windows platform.
-
-    @return flag indicating Windows platform
-    @rtype bool
-    """
-    return sys.platform.startswith(("win", "cygwin"))
-
-
-def isMacPlatform():
-    """
-    Function to check, if this is a Mac platform.
-
-    @return flag indicating Mac platform
-    @rtype bool
-    """
-    return sys.platform == "darwin"
-
-
-def isLinuxPlatform():
-    """
-    Function to check, if this is a Linux platform.
-
-    @return flag indicating Linux platform
-    @rtype bool
-    """
-    return sys.platform.startswith("linux")
-
-
-def desktopName():
-    """
-    Function to determine the name of the desktop environment used
-    (Linux only).
-
-    @return name of the desktop environment
-    @rtype str
-    """
-    if not isLinuxPlatform():
-        return ""
-
-    currDesktop = os.environ.get("XDG_CURRENT_DESKTOP", "")
-    if currDesktop:
-        return currDesktop
-
-    currDesktop = os.environ.get("XDG_SESSION_DESKTOP", "")
-    if currDesktop:
-        return currDesktop
-
-    currDesktop = os.environ.get("GDMSESSION", "")
-    if currDesktop:
-        return currDesktop
-
-    currDesktop = os.environ.get("GNOME_DESKTOP_SESSION_ID", "")
-    if currDesktop:
-        return currDesktop
-
-    currDesktop = os.environ.get("KDE_FULL_SESSION", "")
-    if currDesktop:
-        if currDesktop == "true":
-            return "KDE"
-
-        return currDesktop
-
-    currDesktop = os.environ.get("DESKTOP_SESSION", "")
-    if currDesktop:
-        return currDesktop
-
-    return ""
-
-
-def isKdeDesktop():
-    """
-    Function to check, if the current session is a KDE desktop (Linux only).
-
-    @return flag indicating a KDE desktop
-    @rtype bool
-    """
-    if not isLinuxPlatform():
-        return False
-
-    isKDE = False
-
-    desktop = (
-        os.environ.get("XDG_CURRENT_DESKTOP", "").lower()
-        or os.environ.get("XDG_SESSION_DESKTOP", "").lower()
-        or os.environ.get("DESKTOP_SESSION", "").lower()
-    )
-    isKDE = (
-        "kde" in desktop or "plasma" in desktop
-        if desktop
-        else bool(os.environ.get("KDE_FULL_SESSION", ""))
-    )
-
-    return isKDE
-
-
-def isGnomeDesktop():
-    """
-    Function to check, if the current session is a Gnome desktop (Linux only).
-
-    @return flag indicating a Gnome desktop
-    @rtype bool
-    """
-    if not isLinuxPlatform():
-        return False
-
-    isGnome = False
-
-    desktop = (
-        os.environ.get("XDG_CURRENT_DESKTOP", "").lower()
-        or os.environ.get("XDG_SESSION_DESKTOP", "").lower()
-        or os.environ.get("GDMSESSION", "").lower()
-    )
-    isGnome = (
-        "gnome" in desktop
-        if desktop
-        else bool(os.environ.get("GNOME_DESKTOP_SESSION_ID", ""))
-    )
-
-    return isGnome
-
-
-def sessionType():
-    """
-    Function to determine the name of the running session (Linux only).
-
-    @return name of the desktop environment
-    @rtype str
-    """
-    if not isLinuxPlatform():
-        return ""
-
-    sessionType = os.environ.get("XDG_SESSION_TYPE", "").lower()
-    if "x11" in sessionType:
-        return "X11"
-    elif "wayland" in sessionType:
-        return "Wayland"
-
-    sessionType = os.environ.get("WAYLAND_DISPLAY", "").lower()
-    if "wayland" in sessionType:
-        return "Wayland"
-
-    return ""
-
-
-def isWaylandSession():
-    """
-    Function to check, if the current session is a wayland session.
-
-    @return flag indicating a wayland session
-    @rtype bool
-    """
-    return sessionType() == "Wayland"
-
-
 def getConfigDir():
     """
     Module function to get the name of the directory storing the config data.
@@ -256,169 +116,6 @@
     configDir = os.path.expanduser(d)
 
 
-def getPythonExecutable():
-    """
-    Function to determine the path of the (non-windowed) Python executable.
-
-    @return path of the Python executable
-    @rtype str
-    """
-    if sys.platform.startswith("linux"):
-        return sys.executable
-    elif sys.platform == "darwin":
-        return sys.executable.replace("pythonw", "python")
-    else:
-        return sys.executable.replace("pythonw.exe", "python.exe")
-
-
-def getPythonLibraryDirectory():
-    """
-    Function to determine the path to Python's library directory.
-
-    @return path to the Python library directory
-    @rtype str
-    """
-    return sysconfig.get_path("platlib")
-
-
-def getPythonScriptsDirectory():
-    """
-    Function to determine the path to Python's scripts directory.
-
-    @return path to the Python scripts directory
-    @rtype str
-    """
-    return sysconfig.get_path("scripts")
-
-
-def getPyQt6ModulesDirectory():
-    """
-    Function to determine the path to PyQt6 modules directory.
-
-    @return path to the PyQt6 modules directory
-    @rtype str
-    """
-    pyqtPath = os.path.join(sysconfig.get_path("platlib"), "PyQt6")
-    if os.path.exists(pyqtPath):
-        return pyqtPath
-
-    return ""
-
-
-def getPyQtToolsPath(version=5):
-    """
-    Module function to get the path of the PyQt tools.
-
-    @param version PyQt major version
-    @type int
-    @return path to the PyQt tools
-    @rtype str
-    """
-    from eric7 import Preferences
-    from eric7.EricWidgets.EricApplication import ericApp
-
-    toolsPath = ""
-
-    # step 1: check, if the user has configured a tools path
-    if version == 5:
-        toolsPath = Preferences.getQt("PyQtToolsDir")
-        venvName = Preferences.getQt("PyQtVenvName")
-    elif version == 6:
-        toolsPath = Preferences.getQt("PyQt6ToolsDir")
-        venvName = Preferences.getQt("PyQt6VenvName")
-
-    # step 2: determine from used Python interpreter (pylupdate is test object)
-    if not toolsPath:
-        program = "pylupdate{0}".format(version)
-        if venvName:
-            venvManager = ericApp().getObject("VirtualEnvManager")
-            dirName = venvManager.getVirtualenvDirectory(venvName)
-        else:
-            dirName = os.path.dirname(sys.executable)
-
-        if isWindowsPlatform():
-            program += ".exe"
-            if os.path.exists(os.path.join(dirName, program)):
-                toolsPath = dirName
-            elif os.path.exists(os.path.join(dirName, "Scripts", program)):
-                toolsPath = os.path.join(dirName, "Scripts")
-        else:
-            if os.path.exists(os.path.join(dirName, program)):
-                toolsPath = dirName
-            elif os.path.exists(os.path.join(dirName, "bin", program)):
-                toolsPath = os.path.join(dirName, "bin")
-
-    return toolsPath
-
-
-def getQtBinariesPath(libexec=False):
-    """
-    Module function to get the path of the Qt binaries.
-
-    @param libexec flag indicating to get the path of the executable library
-        (defaults to False)
-    @type bool (optional)
-    @return path of the Qt binaries
-    @rtype str
-    """
-    from eric7 import Preferences
-
-    binPath = ""
-
-    # step 1: check, if the user has configured a tools path
-    qtToolsDir = Preferences.getQt("QtToolsDir")
-    if qtToolsDir:
-        if libexec:
-            binPath = os.path.join(qtToolsDir, "..", "libexec")
-            if not os.path.exists(binPath):
-                binPath = qtToolsDir
-        else:
-            binPath = Preferences.getQt("QtToolsDir")
-        if not os.path.exists(binPath):
-            binPath = ""
-
-    # step 2: try the qt6_applications package
-    if not binPath:
-        with contextlib.suppress(ImportError):
-            # if qt6-applications is not installed just go to the next step
-            import qt6_applications  # __IGNORE_WARNING_I10__
-
-            if libexec:
-                binPath = os.path.join(
-                    os.path.dirname(qt6_applications.__file__), "Qt", "libexec"
-                )
-                if not os.path.exists(binPath):
-                    binPath = os.path.join(
-                        os.path.dirname(qt6_applications.__file__), "Qt", "bin"
-                    )
-            else:
-                binPath = os.path.join(
-                    os.path.dirname(qt6_applications.__file__), "Qt", "bin"
-                )
-            if not os.path.exists(binPath):
-                binPath = ""
-
-    # step3: determine via QLibraryInfo
-    if not binPath:
-        binPath = (
-            QLibraryInfo.path(QLibraryInfo.LibraryPath.LibraryExecutablesPath)
-            if libexec
-            else QLibraryInfo.path(QLibraryInfo.LibraryPath.BinariesPath)
-        )
-
-    # step 4: determine from used Python interpreter (designer is test object)
-    if not binPath:
-        program = "designer"
-        if isWindowsPlatform():
-            program += ".exe"
-
-        progPath = os.path.join(getPythonScriptsDirectory(), program)
-        if os.path.exists(progPath):
-            binPath = getPythonScriptsDirectory()
-
-    return QDir.toNativeSeparators(binPath)
-
-
 ###############################################################################
 ## functions for version handling
 ###############################################################################
@@ -451,20 +148,6 @@
     return tuple(versionParts[:length])
 
 
-def qVersionTuple():
-    """
-    Module function to get the Qt version as a tuple.
-
-    @return Qt version as a tuple
-    @rtype tuple of int
-    """
-    return (
-        (QT_VERSION & 0xFF0000) >> 16,
-        (QT_VERSION & 0xFF00) >> 8,
-        QT_VERSION & 0xFF,
-    )
-
-
 ###############################################################################
 ## functions for extended string handling
 ###############################################################################
@@ -548,9 +231,9 @@
     @return converted data
     @rtype bool
     """
-    if value in ["true", "1", "True"]:
+    if value in ["True", "true", "1", "Yes", "yes"]:
         return True
-    elif value in ["false", "0", "False"]:
+    elif value in ["False", "false", "0", "No", "no"]:
         return False
     else:
         return bool(value)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Graphics/ApplicationDiagramBuilder.py
--- a/src/eric7/Graphics/ApplicationDiagramBuilder.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Graphics/ApplicationDiagramBuilder.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,9 +13,10 @@
 
 from PyQt6.QtWidgets import QApplication, QInputDialog
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricProgressDialog import EricProgressDialog
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .UMLDiagramBuilder import UMLDiagramBuilder
 
@@ -63,7 +64,9 @@
         mods = self.project.getProjectData(dataKey="SOURCES")
         modules = []
         for module in mods:
-            modules.append(Utilities.normabsjoinpath(self.project.ppath, module))
+            modules.append(
+                FileSystemUtilities.normabsjoinpath(self.project.ppath, module)
+            )
         tot = len(modules)
         progress = EricProgressDialog(
             self.tr("Parsing modules..."),
@@ -438,7 +441,7 @@
             if res:
                 self.project.openProject(projectFile)
 
-        self.noModules = Utilities.toBool(parts[1].split("=", 1)[1].strip())
+        self.noModules = Globals.toBool(parts[1].split("=", 1)[1].strip())
 
         self.initialize()
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Graphics/AssociationItem.py
--- a/src/eric7/Graphics/AssociationItem.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Graphics/AssociationItem.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,7 +12,7 @@
 from PyQt6.QtCore import QLineF, QPointF, QRectF
 from PyQt6.QtWidgets import QGraphicsItem
 
-from eric7 import Utilities
+from eric7 import Globals
 from eric7.EricGraphics.EricArrowItem import EricArrowItem, EricArrowType
 
 
@@ -596,7 +596,7 @@
                 elif key == "type":
                     assocType = AssociationType(int(value))
                 elif key == "topToBottom":
-                    topToBottom = Utilities.toBool(value)
+                    topToBottom = Globals.toBool(value)
 
         return src, dst, assocType, topToBottom
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Graphics/ClassItem.py
--- a/src/eric7/Graphics/ClassItem.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Graphics/ClassItem.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,7 +11,7 @@
 from PyQt6.QtGui import QFont
 from PyQt6.QtWidgets import QGraphicsSimpleTextItem, QStyle
 
-from eric7 import Utilities
+from eric7 import Globals
 
 from .UMLItem import UMLItem, UMLModel
 
@@ -338,9 +338,9 @@
         for part in parts:
             key, value = part.split("=", 1)
             if key == "is_external":
-                self.external = Utilities.toBool(value.strip())
+                self.external = Globals.toBool(value.strip())
             elif key == "no_attributes":
-                self.noAttrs = Utilities.toBool(value.strip())
+                self.noAttrs = Globals.toBool(value.strip())
             elif key == "name":
                 name = value.strip()
             elif key == "attributes":
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Graphics/ImportsDiagramBuilder.py
--- a/src/eric7/Graphics/ImportsDiagramBuilder.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Graphics/ImportsDiagramBuilder.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,8 +13,9 @@
 
 from PyQt6.QtWidgets import QApplication, QGraphicsTextItem
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricWidgets.EricProgressDialog import EricProgressDialog
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .UMLDiagramBuilder import UMLDiagramBuilder
 
@@ -93,7 +94,11 @@
         modules = []
         for ext in Preferences.getPython("Python3Extensions"):
             modules.extend(
-                glob.glob(Utilities.normjoinpath(self.packagePath, "*{0}".format(ext)))
+                glob.glob(
+                    FileSystemUtilities.normjoinpath(
+                        self.packagePath, "*{0}".format(ext)
+                    )
+                )
             )
 
         tot = len(modules)
@@ -359,7 +364,7 @@
             return False
 
         self.packagePath = parts[0].split("=", 1)[1].strip()
-        self.showExternalImports = Utilities.toBool(parts[1].split("=", 1)[1].strip())
+        self.showExternalImports = Globals.toBool(parts[1].split("=", 1)[1].strip())
 
         self.initialize()
 
@@ -376,9 +381,9 @@
             "project_name": self.project.getProjectName(),
             "show_external": self.showExternalImports,
             "package": (
-                Utilities.fromNativeSeparators(self.__relPackagePath)
+                FileSystemUtilities.fromNativeSeparators(self.__relPackagePath)
                 if self.__relPackagePath
-                else Utilities.fromNativeSeparators(self.packagePath)
+                else FileSystemUtilities.fromNativeSeparators(self.packagePath)
             ),
         }
 
@@ -399,7 +404,7 @@
         try:
             self.showExternalImports = data["show_external"]
 
-            packagePath = Utilities.toNativeSeparators(data["package"])
+            packagePath = FileSystemUtilities.toNativeSeparators(data["package"])
             if os.path.isabs(packagePath):
                 self.packagePath = packagePath
                 self.__relPackagePath = ""
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Graphics/PackageDiagramBuilder.py
--- a/src/eric7/Graphics/PackageDiagramBuilder.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Graphics/PackageDiagramBuilder.py	Sun Dec 18 19:33:46 2022 +0100
@@ -15,8 +15,9 @@
 
 from PyQt6.QtWidgets import QApplication, QGraphicsTextItem
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricWidgets.EricProgressDialog import EricProgressDialog
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .UMLDiagramBuilder import UMLDiagramBuilder
 
@@ -96,7 +97,9 @@
         moduleDict = {}
         modules = []
         for ext in supportedExt:
-            modules.extend(glob.glob(Utilities.normjoinpath(self.package, ext)))
+            modules.extend(
+                glob.glob(FileSystemUtilities.normjoinpath(self.package, ext))
+            )
         tot = len(modules)
         progress = EricProgressDialog(
             self.tr("Parsing modules..."),
@@ -163,7 +166,7 @@
         tot = 0
         for ext in supportedExt:
             for subpackage in subpackagesList:
-                tot += len(glob.glob(Utilities.normjoinpath(subpackage, ext)))
+                tot += len(glob.glob(FileSystemUtilities.normjoinpath(subpackage, ext)))
         progress = EricProgressDialog(
             self.tr("Parsing modules..."),
             None,
@@ -183,7 +186,9 @@
                 subpackagesDict[packageName] = []
                 modules = []
                 for ext in supportedExt:
-                    modules.extend(glob.glob(Utilities.normjoinpath(subpackage, ext)))
+                    modules.extend(
+                        glob.glob(FileSystemUtilities.normjoinpath(subpackage, ext))
+                    )
                 for prog, module in enumerate(modules):
                     progress.setValue(prog)
                     if time.monotonic() - now > 0.01:
@@ -527,7 +532,7 @@
             return False
 
         self.package = parts[0].split("=", 1)[1].strip()
-        self.noAttrs = Utilities.toBool(parts[1].split("=", 1)[1].strip())
+        self.noAttrs = Globals.toBool(parts[1].split("=", 1)[1].strip())
 
         self.initialize()
 
@@ -544,9 +549,9 @@
             "project_name": self.project.getProjectName(),
             "no_attributes": self.noAttrs,
             "package": (
-                Utilities.fromNativeSeparators(self.__relPackage)
+                FileSystemUtilities.fromNativeSeparators(self.__relPackage)
                 if self.__relPackage
-                else Utilities.fromNativeSeparators(self.package)
+                else FileSystemUtilities.fromNativeSeparators(self.package)
             ),
         }
 
@@ -567,7 +572,7 @@
         try:
             self.noAttrs = data["no_attributes"]
 
-            package = Utilities.toNativeSeparators(data["package"])
+            package = FileSystemUtilities.toNativeSeparators(data["package"])
             if os.path.isabs(package):
                 self.package = package
                 self.__relPackage = ""
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Graphics/PackageItem.py
--- a/src/eric7/Graphics/PackageItem.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Graphics/PackageItem.py	Sun Dec 18 19:33:46 2022 +0100
@@ -10,7 +10,7 @@
 from PyQt6.QtGui import QFont
 from PyQt6.QtWidgets import QGraphicsSimpleTextItem, QStyle
 
-from eric7 import Utilities
+from eric7 import Globals
 
 from .UMLItem import UMLItem, UMLModel
 
@@ -232,7 +232,7 @@
         for part in parts:
             key, value = part.split("=", 1)
             if key == "no_modules":
-                self.external = Utilities.toBool(value.strip())
+                self.external = Globals.toBool(value.strip())
             elif key == "name":
                 name = value.strip()
             elif key == "modules":
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Graphics/UMLClassDiagramBuilder.py
--- a/src/eric7/Graphics/UMLClassDiagramBuilder.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Graphics/UMLClassDiagramBuilder.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,7 +13,8 @@
 
 from PyQt6.QtWidgets import QGraphicsTextItem
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .UMLDiagramBuilder import UMLDiagramBuilder
 
@@ -356,7 +357,7 @@
             return False
 
         self.file = parts[0].split("=", 1)[1].strip()
-        self.noAttrs = Utilities.toBool(parts[1].split("=", 1)[1].strip())
+        self.noAttrs = Globals.toBool(parts[1].split("=", 1)[1].strip())
 
         self.initialize()
 
@@ -373,9 +374,9 @@
             "project_name": self.project.getProjectName(),
             "no_attributes": self.noAttrs,
             "file": (
-                Utilities.fromNativeSeparators(self.__relFile)
+                FileSystemUtilities.fromNativeSeparators(self.__relFile)
                 if self.__relFile
-                else Utilities.fromNativeSeparators(self.file)
+                else FileSystemUtilities.fromNativeSeparators(self.file)
             ),
         }
 
@@ -396,7 +397,7 @@
         try:
             self.noAttrs = data["no_attributes"]
 
-            file = Utilities.toNativeSeparators(data["file"])
+            file = FileSystemUtilities.toNativeSeparators(data["file"])
             if os.path.isabs(file):
                 self.file = file
                 self.__relFile = ""
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/HelpViewer/HelpViewerWidget.py
--- a/src/eric7/HelpViewer/HelpViewerWidget.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/HelpViewer/HelpViewerWidget.py	Sun Dec 18 19:33:46 2022 +0100
@@ -36,7 +36,7 @@
 except ImportError:
     WEBENGINE_AVAILABLE = False
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
@@ -680,7 +680,7 @@
         @return path of the QtHelp collection file
         @rtype str
         """
-        qthelpDir = os.path.join(Utilities.getConfigDir(), "qthelp")
+        qthelpDir = os.path.join(Globals.getConfigDir(), "qthelp")
         if not os.path.exists(qthelpDir):
             os.makedirs(qthelpDir)
         return os.path.join(qthelpDir, "eric7help.qhc")
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/HexEdit/HexEditMainWindow.py
--- a/src/eric7/HexEdit/HexEditMainWindow.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/HexEdit/HexEditMainWindow.py	Sun Dec 18 19:33:46 2022 +0100
@@ -23,13 +23,14 @@
     QWidget,
 )
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricGui.EricAction import EricAction
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricClickableLabel import EricClickableLabel
 from eric7.EricWidgets.EricMainWindow import EricMainWindow
 from eric7.Globals import recentNameHexFiles, strGroup
+from eric7.SystemUtilities import FileSystemUtilities
 from eric7.UI import Config
 
 from .HexEditGotoWidget import HexEditGotoWidget
@@ -1540,7 +1541,10 @@
             formatStr = "&{0:d}. {1}" if idx < 10 else "{0:d}. {1}"
             act = self.__recentMenu.addAction(
                 formatStr.format(
-                    idx, Utilities.compactPath(rs, HexEditMainWindow.maxMenuFilePathLen)
+                    idx,
+                    FileSystemUtilities.compactPath(
+                        rs, HexEditMainWindow.maxMenuFilePathLen
+                    ),
                 )
             )
             act.setData(rs)
@@ -1596,7 +1600,7 @@
         """
         if fileName:
             for recent in self.__recent[:]:
-                if Utilities.samepath(fileName, recent):
+                if FileSystemUtilities.samepath(fileName, recent):
                     self.__recent.remove(recent)
             self.__recent.insert(0, fileName)
             maxRecent = Preferences.getHexEditor("RecentNumber")
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/HexEdit/HexEditWidget.py
--- a/src/eric7/HexEdit/HexEditWidget.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/HexEdit/HexEditWidget.py	Sun Dec 18 19:33:46 2022 +0100
@@ -24,6 +24,7 @@
 
 from eric7 import Globals
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import OSUtilities
 
 from .HexEditChunks import HexEditChunks
 from .HexEditUndoStack import HexEditUndoStack
@@ -126,7 +127,7 @@
 
         self.__chunks = HexEditChunks()
         self.__undoStack = HexEditUndoStack(self.__chunks, self)
-        if Globals.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             self.setFont(QFont(["Courier"], 10))
         else:
             self.setFont(QFont(["Monospace"], 10))
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/JediInterface/JediServer.py
--- a/src/eric7/JediInterface/JediServer.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/JediInterface/JediServer.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,11 +14,12 @@
 from PyQt6.QtCore import QCoreApplication, QThread, QTimer, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QInputDialog, QLineEdit
 
-from eric7 import Globals, Preferences
+from eric7 import Preferences
 from eric7.EricNetwork.EricJsonServer import EricJsonServer
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.QScintilla.Editor import Editor, ReferenceItem
+from eric7.SystemUtilities import PythonUtilities
 
 from .RefactoringPreviewDialog import RefactoringPreviewDialog
 
@@ -814,7 +815,7 @@
             ok, exitCode = self.startClient(
                 interpreter,
                 client,
-                [Globals.getPythonLibraryDirectory()],
+                [PythonUtilities.getPythonLibraryDirectory()],
                 idString=idString,
                 environment=clientEnv,
             )
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/MicroPython/CircuitPythonDevices.py
--- a/src/eric7/MicroPython/CircuitPythonDevices.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/MicroPython/CircuitPythonDevices.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,8 +12,9 @@
 
 from PyQt6.QtCore import pyqtSlot
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .MicroPythonDevices import MicroPythonDevice
 from .MicroPythonWidget import HAS_QTCHART
@@ -174,7 +175,9 @@
         """
         # Attempts to find the paths on the filesystem that represents the
         # plugged in CIRCUITPY boards.
-        deviceDirectories = Utilities.findVolume(self.DeviceVolumeName, findAll=True)
+        deviceDirectories = FileSystemUtilities.findVolume(
+            self.DeviceVolumeName, findAll=True
+        )
 
         if deviceDirectories:
             if len(deviceDirectories) == 1:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/MicroPython/EspDevices.py
--- a/src/eric7/MicroPython/EspDevices.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/MicroPython/EspDevices.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,10 +11,11 @@
 from PyQt6.QtCore import QProcess, pyqtSlot
 from PyQt6.QtWidgets import QDialog
 
-from eric7 import Globals, Preferences
+from eric7 import Preferences
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricProcessDialog import EricProcessDialog
+from eric7.SystemUtilities import PythonUtilities
 
 from .MicroPythonDevices import MicroPythonDevice
 from .MicroPythonWidget import HAS_QTCHART
@@ -184,7 +185,7 @@
                 self.tr("Erase Flash"),
                 showProgress=True,
             )
-            res = dlg.startProcess(Globals.getPythonExecutable(), flashArgs)
+            res = dlg.startProcess(PythonUtilities.getPythonExecutable(), flashArgs)
             if res:
                 dlg.exec()
 
@@ -221,7 +222,7 @@
                 self.tr("Flash MicroPython Firmware"),
                 showProgress=True,
             )
-            res = dlg.startProcess(Globals.getPythonExecutable(), flashArgs)
+            res = dlg.startProcess(PythonUtilities.getPythonExecutable(), flashArgs)
             if res:
                 dlg.exec()
 
@@ -258,7 +259,7 @@
                 self.tr("Flash Additional Firmware"),
                 showProgress=True,
             )
-            res = dlg.startProcess(Globals.getPythonExecutable(), flashArgs)
+            res = dlg.startProcess(PythonUtilities.getPythonExecutable(), flashArgs)
             if res:
                 dlg.exec()
 
@@ -292,7 +293,7 @@
                 self.tr("Backup Firmware"),
                 showProgress=True,
             )
-            res = dlg.startProcess(Globals.getPythonExecutable(), flashArgs)
+            res = dlg.startProcess(PythonUtilities.getPythonExecutable(), flashArgs)
             if res:
                 dlg.exec()
 
@@ -343,7 +344,7 @@
                 self.tr("Restore Firmware"),
                 showProgress=True,
             )
-            res = dlg.startProcess(Globals.getPythonExecutable(), flashArgs)
+            res = dlg.startProcess(PythonUtilities.getPythonExecutable(), flashArgs)
             if res:
                 dlg.exec()
 
@@ -363,7 +364,7 @@
         dlg = EricProcessDialog(
             self.tr("'esptool chip_id' Output"), self.tr("Show Chip ID")
         )
-        res = dlg.startProcess(Globals.getPythonExecutable(), args)
+        res = dlg.startProcess(PythonUtilities.getPythonExecutable(), args)
         if res:
             dlg.exec()
 
@@ -383,7 +384,7 @@
         dlg = EricProcessDialog(
             self.tr("'esptool flash_id' Output"), self.tr("Show Flash ID")
         )
-        res = dlg.startProcess(Globals.getPythonExecutable(), args)
+        res = dlg.startProcess(PythonUtilities.getPythonExecutable(), args)
         if res:
             dlg.exec()
 
@@ -403,7 +404,7 @@
         dlg = EricProcessDialog(
             self.tr("'esptool read_mac' Output"), self.tr("Show MAC Address")
         )
-        res = dlg.startProcess(Globals.getPythonExecutable(), args)
+        res = dlg.startProcess(PythonUtilities.getPythonExecutable(), args)
         if res:
             dlg.exec()
 
@@ -431,7 +432,7 @@
                 "flash_id",
             ]
             proc = QProcess()
-            proc.start(Globals.getPythonExecutable(), args)
+            proc.start(PythonUtilities.getPythonExecutable(), args)
             procStarted = proc.waitForStarted(10000)
             if procStarted:
                 proc.waitForFinished(10000)
@@ -442,7 +443,9 @@
         Private slot to install the esptool package via pip.
         """
         pip = ericApp().getObject("Pip")
-        pip.installPackages(["esptool"], interpreter=Globals.getPythonExecutable())
+        pip.installPackages(
+            ["esptool"], interpreter=PythonUtilities.getPythonExecutable()
+        )
 
     def getDocumentationUrl(self):
         """
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/MicroPython/GenericMicroPythonDevices.py
--- a/src/eric7/MicroPython/GenericMicroPythonDevices.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/MicroPython/GenericMicroPythonDevices.py	Sun Dec 18 19:33:46 2022 +0100
@@ -10,8 +10,9 @@
 
 import os
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets import EricMessageBox
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .MicroPythonDevices import MicroPythonDevice
 from .MicroPythonWidget import HAS_QTCHART
@@ -177,7 +178,9 @@
         """
         # Attempts to find the path on the filesystem that represents the
         # plugged in board.
-        deviceDirectories = Utilities.findVolume(self.__deviceVolumeName, findAll=True)
+        deviceDirectories = FileSystemUtilities.findVolume(
+            self.__deviceVolumeName, findAll=True
+        )
 
         if deviceDirectories:
             if len(deviceDirectories) == 1:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/MicroPython/MicroPythonWidget.py
--- a/src/eric7/MicroPython/MicroPythonWidget.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/MicroPython/MicroPythonWidget.py	Sun Dec 18 19:33:46 2022 +0100
@@ -26,7 +26,7 @@
     QWidget,
 )
 
-from eric7 import Globals, Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricGui.EricOverrideCursor import EricOverrideCursor, EricOverridenCursor
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
@@ -34,6 +34,7 @@
 from eric7.EricWidgets.EricListSelectionDialog import EricListSelectionDialog
 from eric7.EricWidgets.EricProcessDialog import EricProcessDialog
 from eric7.EricWidgets.EricZoomWidget import EricZoomWidget
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 from eric7.UI.Info import BugAddress
 
 from . import MicroPythonDevices, UF2FlashDialog
@@ -540,7 +541,7 @@
         @param pos position to show the menu at
         @type QPoint
         """
-        if Globals.isMacPlatform():
+        if OSUtilities.isMacPlatform():
             copyKeys = QKeySequence("Ctrl+C")
             pasteKeys = QKeySequence("Ctrl+V")
             selectAllKeys = QKeySequence("Ctrl+A")
@@ -758,10 +759,10 @@
             elif key == Qt.Key.Key_End:
                 msg = b"\x1B[F"
             elif (
-                Globals.isMacPlatform()
+                OSUtilities.isMacPlatform()
                 and evt.modifiers() == Qt.KeyboardModifier.MetaModifier
             ) or (
-                not Globals.isMacPlatform()
+                not OSUtilities.isMacPlatform()
                 and evt.modifiers() == Qt.KeyboardModifier.ControlModifier
             ):
                 if Qt.Key.Key_A <= key <= Qt.Key.Key_Z:
@@ -770,7 +771,7 @@
             elif evt.modifiers() == (
                 Qt.KeyboardModifier.ControlModifier | Qt.KeyboardModifier.ShiftModifier
             ) or (
-                Globals.isMacPlatform()
+                OSUtilities.isMacPlatform()
                 and evt.modifiers() == Qt.KeyboardModifier.ControlModifier
             ):
                 if key == Qt.Key.Key_C:
@@ -1053,7 +1054,7 @@
         """
         portName = self.deviceTypeComboBox.currentData(self.DevicePortRole)
         if portName:
-            if Globals.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 # return it unchanged
                 return portName
             else:
@@ -1425,7 +1426,7 @@
             )
             act.setEnabled(self.__connected)
         self.__superMenu.addSeparator()
-        if not Globals.isWindowsPlatform():
+        if not OSUtilities.isWindowsPlatform():
             available = self.__mpyCrossAvailable()
             act = self.__superMenu.addAction(
                 self.tr("Compile Python File"), self.__compileFile2Mpy
@@ -1698,10 +1699,10 @@
         program = Preferences.getMicroPython("MpyCrossCompiler")
         if not program:
             program = "mpy-cross"
-            if Utilities.isinpath(program):
+            if FileSystemUtilities.isinpath(program):
                 available = True
         else:
-            if Utilities.isExecutable(program):
+            if FileSystemUtilities.isExecutable(program):
                 available = True
 
         return available
@@ -1718,7 +1719,7 @@
         program = Preferences.getMicroPython("MpyCrossCompiler")
         if not program:
             program = "mpy-cross"
-            if not Utilities.isinpath(program):
+            if not FileSystemUtilities.isinpath(program):
                 EricMessageBox.critical(
                     self,
                     title,
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/MicroPython/MicrobitDevices.py
--- a/src/eric7/MicroPython/MicrobitDevices.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/MicroPython/MicrobitDevices.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,9 +14,10 @@
 from PyQt6.QtCore import QStandardPaths, pyqtSlot
 from PyQt6.QtWidgets import QInputDialog, QLineEdit
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .MicroPythonDevices import MicroPythonDevice
 from .MicroPythonWidget import HAS_QTCHART
@@ -188,15 +189,21 @@
         if self.getDeviceType() == "bbc_microbit":
             # BBC micro:bit
             if firmware:
-                deviceDirectories = Utilities.findVolume("MAINTENANCE", findAll=True)
+                deviceDirectories = FileSystemUtilities.findVolume(
+                    "MAINTENANCE", findAll=True
+                )
             else:
-                deviceDirectories = Utilities.findVolume("MICROBIT", findAll=True)
+                deviceDirectories = FileSystemUtilities.findVolume(
+                    "MICROBIT", findAll=True
+                )
         else:
             # Calliope mini
             if firmware:
-                deviceDirectories = Utilities.findVolume("MAINTENANCE", findAll=True)
+                deviceDirectories = FileSystemUtilities.findVolume(
+                    "MAINTENANCE", findAll=True
+                )
             else:
-                deviceDirectories = Utilities.findVolume("MINI", findAll=True)
+                deviceDirectories = FileSystemUtilities.findVolume("MINI", findAll=True)
         if len(deviceDirectories) == 0:
             if self.getDeviceType() == "bbc_microbit":
                 # BBC micro:bit is not ready or not mounted
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/MicroPython/PyBoardDevices.py
--- a/src/eric7/MicroPython/PyBoardDevices.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/MicroPython/PyBoardDevices.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,10 +11,11 @@
 
 from PyQt6.QtCore import QStandardPaths, pyqtSlot
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricProcessDialog import EricProcessDialog
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .MicroPythonDevices import MicroPythonDevice
 from .MicroPythonWidget import HAS_QTCHART
@@ -175,7 +176,9 @@
         """
         # Attempts to find the path on the filesystem that represents the
         # plugged in PyBoard board.
-        deviceDirectories = Utilities.findVolume(self.DeviceVolumeName, findAll=True)
+        deviceDirectories = FileSystemUtilities.findVolume(
+            self.DeviceVolumeName, findAll=True
+        )
 
         if deviceDirectories:
             if len(deviceDirectories) == 1:
@@ -271,10 +274,10 @@
         program = Preferences.getMicroPython("DfuUtilPath")
         if not program:
             program = "dfu-util"
-            if Utilities.isinpath(program):
+            if FileSystemUtilities.isinpath(program):
                 available = True
         else:
-            if Utilities.isExecutable(program):
+            if FileSystemUtilities.isExecutable(program):
                 available = True
 
         if not available:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/MicroPython/UF2FlashDialog.py
--- a/src/eric7/MicroPython/UF2FlashDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/MicroPython/UF2FlashDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -15,10 +15,10 @@
 from PyQt6.QtSerialPort import QSerialPortInfo
 from PyQt6.QtWidgets import QDialog
 
-from eric7 import Utilities
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities
 
 from . import MicroPythonDevices
 from .Ui_UF2FlashDialog import Ui_UF2FlashDialog
@@ -675,7 +675,7 @@
                 volumes = SupportedUF2Boards[board]["volumes"][(0, 0)]
                 foundVolumes = []
                 for volume in volumes:
-                    foundVolumes += Utilities.findVolume(volume, findAll=True)
+                    foundVolumes += FileSystemUtilities.findVolume(volume, findAll=True)
                 if foundVolumes:
                     foundDevices.append(
                         (
@@ -1039,7 +1039,7 @@
             volumes = SupportedUF2Boards[boardType]["volumes"][vidpid]
             foundVolumes = []
             for volume in volumes:
-                foundVolumes += Utilities.findVolume(volume, findAll=True)
+                foundVolumes += FileSystemUtilities.findVolume(volume, findAll=True)
 
             if len(foundVolumes) == 0:
                 self.__showNoVolumeInformation(volumes, boardType)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/MultiProject/AddProjectDialog.py
--- a/src/eric7/MultiProject/AddProjectDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/MultiProject/AddProjectDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,8 +12,9 @@
 from PyQt6.QtCore import QUuid, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_AddProjectDialog import Ui_AddProjectDialog
 
@@ -90,7 +91,7 @@
 
         filename = self.filenamePicker.text()
         if not os.path.isabs(filename):
-            filename = Utilities.toNativeSeparators(
+            filename = FileSystemUtilities.toNativeSeparators(
                 os.path.join(self.startdir, filename)
             )
         return (
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/MultiProject/MultiProject.py
--- a/src/eric7/MultiProject/MultiProject.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/MultiProject/MultiProject.py	Sun Dec 18 19:33:46 2022 +0100
@@ -15,7 +15,7 @@
 from PyQt6.QtCore import QFile, QIODevice, QObject, QUuid, pyqtSignal, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QMenu, QToolBar
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricGui.EricAction import EricAction, createActionGroup
 from eric7.EricGui.EricOverrideCursor import EricOverrideCursor
@@ -23,6 +23,7 @@
 from eric7.EricWidgets.EricPathPickerDialog import EricPathPickerModes
 from eric7.EricXML.MultiProjectReader import MultiProjectReader
 from eric7.Globals import recentNameMultiProject
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 from eric7.UI import Config
 
 from .MultiProjectFile import MultiProjectFile
@@ -535,7 +536,7 @@
             fn = EricFileDialog.getOpenFileName(
                 self.parent(),
                 self.tr("Open Multi Project"),
-                Preferences.getMultiProject("Workspace") or Utilities.getHomeDir(),
+                Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir(),
                 self.tr(
                     "Multi Project Files (*.emj);;"
                     "XML Multi Project Files (*.e5m *.e4m)"
@@ -595,7 +596,7 @@
         defaultPath = (
             self.ppath
             if self.ppath
-            else (Preferences.getMultiProject("Workspace") or Utilities.getHomeDir())
+            else (Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir())
         )
         fn, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
             self.parent(),
@@ -907,7 +908,7 @@
         projects with the central store.
         """
         for recent in self.recent[:]:
-            if Utilities.samepath(self.pfile, recent):
+            if FileSystemUtilities.samepath(self.pfile, recent):
                 self.recent.remove(recent)
         self.recent.insert(0, self.pfile)
         maxRecent = Preferences.getProject("RecentNumber")
@@ -927,7 +928,7 @@
             formatStr = "&{0:d}. {1}" if idx < 10 else "{0:d}. {1}"
             act = self.recentMenu.addAction(
                 formatStr.format(
-                    idx, Utilities.compactPath(rp, self.ui.maxMenuFilePathLen)
+                    idx, FileSystemUtilities.compactPath(rp, self.ui.maxMenuFilePathLen)
                 )
             )
             act.setData(rp)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Network/IRC/IrcChannelWidget.py
--- a/src/eric7/Network/IRC/IrcChannelWidget.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Network/IRC/IrcChannelWidget.py	Sun Dec 18 19:33:46 2022 +0100
@@ -35,6 +35,7 @@
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import OSUtilities
 from eric7.UI.Info import Copyright, Version
 
 from .IrcUtilities import getChannelModesDict, ircFilter, ircTimestamp
@@ -1399,7 +1400,7 @@
         """
         hasText = not self.messages.document().isEmpty()
         if hasText:
-            if Utilities.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 htmlExtension = "htm"
             else:
                 htmlExtension = "html"
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Network/IRC/IrcIdentitiesEditDialog.py
--- a/src/eric7/Network/IRC/IrcIdentitiesEditDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Network/IRC/IrcIdentitiesEditDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -15,6 +15,7 @@
 from eric7 import Utilities
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricMessageBox
+from eric7.SystemUtilities import OSUtilities
 
 from .IrcNetworkManager import IrcIdentity
 from .Ui_IrcIdentitiesEditDialog import Ui_IrcIdentitiesEditDialog
@@ -240,7 +241,7 @@
                     self.on_addButton_clicked()
                 else:
                     identity = IrcIdentity(name)
-                    identity.setIdent(Utilities.getUserName())
+                    identity.setIdent(OSUtilities.getUserName())
                     identity.setRealName(Utilities.getRealName())
                     self.__identities[name] = identity
                     self.identitiesCombo.addItem(name)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Network/IRC/IrcNetworkManager.py
--- a/src/eric7/Network/IRC/IrcNetworkManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Network/IRC/IrcNetworkManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,6 +12,7 @@
 from PyQt6.QtCore import QCoreApplication, QObject, pyqtSignal
 
 from eric7 import Preferences, Utilities
+from eric7.SystemUtilities import OSUtilities
 from eric7.Utilities.AutoSaver import AutoSaver
 from eric7.Utilities.crypto import pwConvert
 
@@ -43,7 +44,7 @@
         self.__nickNames = []
         self.__serviceName = ""
         self.__password = ""
-        self.__ident = Utilities.getUserName()
+        self.__ident = OSUtilities.getUserName()
 
         self.__rememberPosOnAway = True
         self.__awayMessage = IrcIdentity.DefaultAwayMessage
@@ -74,7 +75,7 @@
 
         @param settings reference to the settings object (QSettings)
         """
-        self.__ident = settings.value("Ident", Utilities.getUserName())
+        self.__ident = settings.value("Ident", OSUtilities.getUserName())
         self.__realName = settings.value("RealName", "")
         self.__nickNames = Preferences.toList(settings.value("NickNames", []))
         self.__serviceName = settings.value("ServiceName", "")
@@ -271,7 +272,7 @@
 
         @return default identity (IrcIdentity)
         """
-        userName = Utilities.getUserName()
+        userName = OSUtilities.getUserName()
         realName = Utilities.getRealName()
         if not realName:
             realName = "eric IDE chat"
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Network/IRC/IrcNetworkWidget.py
--- a/src/eric7/Network/IRC/IrcNetworkWidget.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Network/IRC/IrcNetworkWidget.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,10 +13,11 @@
 from PyQt6.QtGui import QDesktopServices
 from PyQt6.QtWidgets import QApplication, QMenu, QWidget
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import OSUtilities
 
 from .IrcUtilities import ircFilter, ircTimestamp
 from .Ui_IrcNetworkWidget import Ui_IrcNetworkWidget
@@ -405,7 +406,7 @@
         """
         hasText = not self.messages.document().isEmpty()
         if hasText:
-            if Utilities.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 htmlExtension = "htm"
             else:
                 htmlExtension = "html"
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Network/IRC/IrcWidget.py
--- a/src/eric7/Network/IRC/IrcWidget.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Network/IRC/IrcWidget.py	Sun Dec 18 19:33:46 2022 +0100
@@ -29,7 +29,7 @@
 from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricMessageBox
-from eric7.Globals import isMacPlatform
+from eric7.SystemUtilities import OSUtilities
 from eric7.UI.Info import Copyright, Version
 
 from .IrcNetworkManager import IrcNetworkManager
@@ -69,7 +69,7 @@
             self.__leaveButton, Qt.Corner.BottomRightCorner
         )
         self.channelsWidget.setTabsClosable(False)
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             self.channelsWidget.setTabPosition(QTabWidget.TabPosition.South)
 
         height = self.height()
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/PipInterface/Pip.py
--- a/src/eric7/PipInterface/Pip.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/PipInterface/Pip.py	Sun Dec 18 19:33:46 2022 +0100
@@ -16,10 +16,11 @@
 from PyQt6.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest
 from PyQt6.QtWidgets import QDialog, QInputDialog, QLineEdit
 
-from eric7 import Globals, Preferences
+from eric7 import Preferences
 from eric7.EricNetwork.EricNetworkProxyFactory import proxyAuthenticationRequired
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import OSUtilities, PythonUtilities
 from eric7.UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
 
 try:
@@ -147,9 +148,9 @@
         with contextlib.suppress(KeyError):
             return os.environ["PIP_CONFIG_FILE"]
 
-        if Globals.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             config = os.path.join(os.environ["APPDATA"], "pip", "pip.ini")
-        elif Globals.isMacPlatform():
+        elif OSUtilities.isMacPlatform():
             config = os.path.expanduser("~/Library/Application Support/pip/pip.conf")
         else:
             config = os.path.expanduser("~/.config/pip/pip.conf")
@@ -168,7 +169,7 @@
         # Unix, OS X:   $VIRTUAL_ENV/pip.conf
         # Windows:      %VIRTUAL_ENV%\pip.ini
 
-        pip = "pip.ini" if Globals.isWindowsPlatform() else "pip.conf"
+        pip = "pip.ini" if OSUtilities.isWindowsPlatform() else "pip.conf"
 
         venvManager = ericApp().getObject("VirtualEnvManager")
         venvDirectory = (
@@ -363,7 +364,7 @@
 
         if self.getVirtualenvInterpreter(venvName) in (
             sys.executable,
-            Globals.getPythonExecutable(),
+            PythonUtilities.getPythonExecutable(),
         ):
             upgradePyQt = self.__checkUpgradePyQt(packages)
             upgradeEric = self.__checkUpgradeEric(packages)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/PipInterface/PipFileSelectionDialog.py
--- a/src/eric7/PipInterface/PipFileSelectionDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/PipInterface/PipFileSelectionDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,8 +13,8 @@
 from PyQt6.QtCore import pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Utilities
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_PipFileSelectionDialog import Ui_PipFileSelectionDialog
 
@@ -91,7 +91,7 @@
         @type str
         """
         self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
-            bool(txt) and os.path.exists(Utilities.toNativeSeparators(txt))
+            bool(txt) and os.path.exists(FileSystemUtilities.toNativeSeparators(txt))
         )
 
     def getData(self):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/PipInterface/PipFreezeDialog.py
--- a/src/eric7/PipInterface/PipFreezeDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/PipInterface/PipFreezeDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,11 +13,11 @@
 from PyQt6.QtCore import Qt, pyqtSlot
 from PyQt6.QtWidgets import QAbstractButton, QApplication, QDialog, QDialogButtonBox
 
-from eric7 import Utilities
 from eric7.EricGui.EricOverrideCursor import EricOverrideCursor
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_PipFreezeDialog import Ui_PipFreezeDialog
 
@@ -169,7 +169,9 @@
                 else "requirements.txt"
             )
 
-        fileName = Utilities.toNativeSeparators(self.requirementsFilePicker.text())
+        fileName = FileSystemUtilities.toNativeSeparators(
+            self.requirementsFilePicker.text()
+        )
         if fileName and not os.path.isabs(fileName):
             fileName = ""
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/PluginManager/PluginInstallDialog.py
--- a/src/eric7/PluginManager/PluginInstallDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/PluginManager/PluginInstallDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -31,6 +31,7 @@
 from eric7 import Preferences, Utilities
 from eric7.EricWidgets import EricFileDialog
 from eric7.EricWidgets.EricMainWindow import EricMainWindow
+from eric7.SystemUtilities import OSUtilities
 from eric7.Utilities.uic import compileUiFiles
 
 from .PluginManager import PluginManager
@@ -172,7 +173,7 @@
 
         if archives:
             matchflags = Qt.MatchFlag.MatchFixedString
-            if not Utilities.isWindowsPlatform():
+            if not OSUtilities.isWindowsPlatform():
                 matchflags |= Qt.MatchFlag.MatchCaseSensitive
             for archive in archives:
                 if len(self.archivesList.findItems(archive, matchflags)) == 0:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/PluginManager/PluginManager.py
--- a/src/eric7/PluginManager/PluginManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/PluginManager/PluginManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -20,13 +20,14 @@
 from PyQt6.QtGui import QPixmap
 from PyQt6.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest
 
-from eric7 import Globals, Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricNetwork.EricNetworkProxyFactory import proxyAuthenticationRequired
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricXML.PluginRepositoryReader import PluginRepositoryReader
 from eric7.Globals import getConfig
+from eric7.SystemUtilities import FileSystemUtilities, PythonUtilities
 
 try:
     from eric7.EricNetwork.EricSslErrorHandler import (
@@ -118,13 +119,13 @@
         self.pluginDirs = {
             "eric7": os.path.join(getConfig("ericDir"), "Plugins"),
             "global": os.path.join(
-                Utilities.getPythonLibraryDirectory(), "eric7plugins"
+                PythonUtilities.getPythonLibraryDirectory(), "eric7plugins"
             ),
-            "user": os.path.join(Utilities.getConfigDir(), "eric7plugins"),
+            "user": os.path.join(Globals.getConfigDir(), "eric7plugins"),
         }
         self.__priorityOrder = ["eric7", "global", "user"]
 
-        self.__defaultDownloadDir = os.path.join(Utilities.getConfigDir(), "Downloads")
+        self.__defaultDownloadDir = os.path.join(Globals.getConfigDir(), "Downloads")
 
         self.__activePlugins = {}
         self.__inactivePlugins = {}
@@ -157,7 +158,7 @@
         self.__checkPluginsDownloadDirectory()
 
         self.pluginRepositoryFile = os.path.join(
-            Utilities.getConfigDir(), "PluginRepository"
+            Globals.getConfigDir(), "PluginRepository"
         )
 
         # attributes for the network objects
@@ -205,7 +206,7 @@
             directories (boolean) and a message (string)
         """
         if self.__develPluginFile:
-            path = Utilities.splitPath(self.__develPluginFile)[0]
+            path = FileSystemUtilities.splitPath(self.__develPluginFile)[0]
             fname = os.path.join(path, "__init__.py")
             if not os.path.exists(fname):
                 try:
@@ -314,7 +315,7 @@
                 EricPixmapCache.addSearchPath(self.pluginDirs[key])
 
         if self.__develPluginFile:
-            path = Utilities.splitPath(self.__develPluginFile)[0]
+            path = FileSystemUtilities.splitPath(self.__develPluginFile)[0]
             if path not in sys.path:
                 sys.path.insert(2, path)
             EricPixmapCache.addSearchPath(path)
@@ -325,7 +326,7 @@
         """
         develPluginName = ""
         if self.__develPluginFile:
-            develPluginPath, develPluginName = Utilities.splitPath(
+            develPluginPath, develPluginName = FileSystemUtilities.splitPath(
                 self.__develPluginFile
             )
             if self.isValidPluginName(develPluginName):
@@ -1455,7 +1456,7 @@
             from eric7.PipInterface.Pip import Pip  # __IGNORE_WARNING_I101__
 
             pip = Pip(self)
-        pip.installPackages(packages, interpreter=Globals.getPythonExecutable())
+        pip.installPackages(packages, interpreter=PythonUtilities.getPythonExecutable())
 
 
 #
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/PluginManager/PluginRepositoryDialog.py
--- a/src/eric7/PluginManager/PluginRepositoryDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/PluginManager/PluginRepositoryDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -42,7 +42,7 @@
     QWidget,
 )
 
-from eric7 import Globals, Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricNetwork.EricNetworkProxyFactory import proxyAuthenticationRequired
 from eric7.EricWidgets import EricMessageBox
@@ -50,6 +50,7 @@
 from eric7.EricWidgets.EricMainWindow import EricMainWindow
 from eric7.EricXML.PluginRepositoryReader import PluginRepositoryReader
 from eric7.Globals import getConfig
+from eric7.SystemUtilities import PythonUtilities
 
 try:
     from eric7.EricNetwork.EricSslErrorHandler import (
@@ -209,7 +210,7 @@
         )
 
         self.pluginRepositoryFile = os.path.join(
-            Utilities.getConfigDir(), "PluginRepository"
+            Globals.getConfigDir(), "PluginRepository"
         )
 
         self.__pluginManager.pluginRepositoryFileDownloaded.connect(self.__populateList)
@@ -1037,7 +1038,7 @@
         args += self.cw.getDownloadedPlugins()
 
         if not os.path.isfile(applPath) or not proc.startDetached(
-            Globals.getPythonExecutable(), args
+            PythonUtilities.getPythonExecutable(), args
         ):
             EricMessageBox.critical(
                 self,
@@ -1144,7 +1145,7 @@
                     )
 
     # step 3: delete entries of obsolete plug-ins
-    pluginRepositoryFile = os.path.join(Utilities.getConfigDir(), "PluginRepository")
+    pluginRepositoryFile = os.path.join(Globals.getConfigDir(), "PluginRepository")
     if os.path.exists(pluginRepositoryFile):
         f = QFile(pluginRepositoryFile)
         if f.open(QIODevice.OpenModeFlag.ReadOnly):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py
--- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -30,6 +30,7 @@
 from eric7 import Preferences, Utilities
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import FileSystemUtilities
 
 from . import CodeStyleCheckerUtilities, pycodestyle
 from .Annotations.AnnotationsCheckerDefaults import AnnotationsCheckerDefaultArgs
@@ -787,7 +788,9 @@
             self.files = []
             extensions = set(Preferences.getPython("Python3Extensions"))
             for ext in extensions:
-                self.files.extend(Utilities.direntries(fn, True, "*{0}".format(ext), 0))
+                self.files.extend(
+                    FileSystemUtilities.direntries(fn, True, "*{0}".format(ext), 0)
+                )
         else:
             self.files = [fn]
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckService.py
--- a/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckService.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckService.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,7 +12,7 @@
 from PyQt6.QtCore import QObject, pyqtSignal
 
 from eric7.EricWidgets.EricApplication import ericApp
-from eric7.Utilities import determinePythonVersion
+from eric7.SystemUtilities import PythonUtilities
 
 
 class SyntaxCheckService(QObject):
@@ -52,7 +52,7 @@
         @param source code of the file (str)
         @return language of the file or None if not found (str or None)
         """
-        pyVer = determinePythonVersion(filename, source)
+        pyVer = PythonUtilities.determinePythonVersion(filename, source)
         if pyVer:
             return "Python{0}".format(pyVer)
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py
--- a/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -23,6 +23,7 @@
 from eric7 import Utilities
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_SyntaxCheckerDialog import Ui_SyntaxCheckerDialog
 
@@ -192,7 +193,9 @@
         elif os.path.isdir(fn):
             files = []
             for ext in self.syntaxCheckService.getExtensions():
-                files.extend(Utilities.direntries(fn, True, "*{0}".format(ext), 0))
+                files.extend(
+                    FileSystemUtilities.direntries(fn, True, "*{0}".format(ext), 0)
+                )
         else:
             files = [fn]
 
@@ -247,7 +250,7 @@
                 self.files = []
                 for ext in self.syntaxCheckService.getExtensions():
                     self.files.extend(
-                        Utilities.direntries(fn, True, "*{0}".format(ext), 0)
+                        FileSystemUtilities.direntries(fn, True, "*{0}".format(ext), 0)
                     )
             else:
                 self.files = [fn]
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/DocumentationPlugins/Ericapi/EricapiConfigDialog.py
--- a/src/eric7/Plugins/DocumentationPlugins/Ericapi/EricapiConfigDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/DocumentationPlugins/Ericapi/EricapiConfigDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,9 +13,10 @@
 from PyQt6.QtCore import Qt, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import DocumentationTools, Globals, Utilities
+from eric7 import DocumentationTools
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
 from eric7.Globals import getConfig
+from eric7.SystemUtilities import FileSystemUtilities, PythonUtilities
 
 from .Ui_EricapiConfigDialog import Ui_EricapiConfigDialog
 
@@ -63,10 +64,10 @@
         # combine it with the values of parms
         if parms is not None:
             self.parameters.update(parms)
-        self.parameters["startDirectory"] = Utilities.toNativeSeparators(
+        self.parameters["startDirectory"] = FileSystemUtilities.toNativeSeparators(
             self.parameters["startDirectory"]
         )
-        self.parameters["outputFile"] = Utilities.toNativeSeparators(
+        self.parameters["outputFile"] = FileSystemUtilities.toNativeSeparators(
             self.parameters["outputFile"]
         )
 
@@ -129,8 +130,10 @@
         args = []
 
         # 1. the program name
-        args.append(Globals.getPythonExecutable())
-        args.append(Utilities.normabsjoinpath(getConfig("ericDir"), "eric7_api.py"))
+        args.append(PythonUtilities.getPythonExecutable())
+        args.append(
+            FileSystemUtilities.normabsjoinpath(getConfig("ericDir"), "eric7_api.py")
+        )
 
         # 2. the commandline options
         if self.parameters["startDirectory"] != self.defaults["startDirectory"]:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/DocumentationPlugins/Ericdoc/EricdocConfigDialog.py
--- a/src/eric7/Plugins/DocumentationPlugins/Ericdoc/EricdocConfigDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/DocumentationPlugins/Ericdoc/EricdocConfigDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,13 +14,13 @@
 from PyQt6.QtGui import QColor
 from PyQt6.QtWidgets import QColorDialog, QDialog, QDialogButtonBox
 
-from eric7 import Globals, Utilities
 from eric7.DocumentationTools.Config import (
     eric7docColorParameterNames,
     eric7docDefaultColors,
 )
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
 from eric7.Globals import getConfig
+from eric7.SystemUtilities import FileSystemUtilities, PythonUtilities
 
 from .Ui_EricdocConfigDialog import Ui_EricdocConfigDialog
 
@@ -94,21 +94,23 @@
                     self.colors[key] = parms[key]
                 else:
                     self.parameters[key] = parms[key]
-        self.parameters["startDirectory"] = Utilities.toNativeSeparators(
+        self.parameters["startDirectory"] = FileSystemUtilities.toNativeSeparators(
             self.parameters["startDirectory"]
         )
-        self.parameters["outputDirectory"] = Utilities.toNativeSeparators(
+        self.parameters["outputDirectory"] = FileSystemUtilities.toNativeSeparators(
             self.parameters["outputDirectory"]
         )
-        self.parameters["qtHelpOutputDirectory"] = Utilities.toNativeSeparators(
+        self.parameters[
+            "qtHelpOutputDirectory"
+        ] = FileSystemUtilities.toNativeSeparators(
             self.parameters["qtHelpOutputDirectory"]
         )
-        self.parameters["cssFile"] = Utilities.toNativeSeparators(
+        self.parameters["cssFile"] = FileSystemUtilities.toNativeSeparators(
             self.parameters["cssFile"]
         )
         if self.parameters["cssFile"].startswith("%PYTHON%"):
             self.parameters["cssFile"] = self.parameters["cssFile"].replace(
-                "%PYTHON%", Utilities.getPythonLibraryDirectory()
+                "%PYTHON%", PythonUtilities.getPythonLibraryDirectory()
             )
 
         self.ppath = project.getProjectPath()
@@ -185,8 +187,10 @@
         args = []
 
         # 1. the program name
-        args.append(Globals.getPythonExecutable())
-        args.append(Utilities.normabsjoinpath(getConfig("ericDir"), "eric7_doc.py"))
+        args.append(PythonUtilities.getPythonExecutable())
+        args.append(
+            FileSystemUtilities.normabsjoinpath(getConfig("ericDir"), "eric7_doc.py")
+        )
 
         # 2. the commandline options
         # 2a. general commandline options
@@ -236,11 +240,11 @@
         # 2b. style commandline options
         if self.parameters["cssFile"] != self.defaults["cssFile"]:
             cssFile = self.project.getRelativePath(self.parameters["cssFile"])
-            if cssFile.startswith(Utilities.getPythonLibraryDirectory()):
+            if cssFile.startswith(PythonUtilities.getPythonLibraryDirectory()):
                 cssFile = cssFile.replace(
-                    Utilities.getPythonLibraryDirectory(), "%PYTHON%"
+                    PythonUtilities.getPythonLibraryDirectory(), "%PYTHON%"
                 )
-            parms["cssFile"] = Utilities.fromNativeSeparators(cssFile)
+            parms["cssFile"] = FileSystemUtilities.fromNativeSeparators(cssFile)
             args.append("-c")
             if os.path.isabs(self.parameters["cssFile"]):
                 args.append(self.parameters["cssFile"])
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/PluginCodeStyleChecker.py
--- a/src/eric7/Plugins/PluginCodeStyleChecker.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/PluginCodeStyleChecker.py	Sun Dec 18 19:33:46 2022 +0100
@@ -17,8 +17,8 @@
 from eric7.EricGui.EricAction import EricAction
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.Project.ProjectBrowserModel import ProjectBrowserFileItem
+from eric7.SystemUtilities import PythonUtilities
 from eric7.UI import Info
-from eric7.Utilities import determinePythonVersion
 
 # Start-Of-Header
 name = "Code Style Checker Plugin"
@@ -163,7 +163,9 @@
             bool, str, dict, dict, list of str, str, str, bool)
         """
         if lang is None:
-            lang = "Python{0}".format(determinePythonVersion(filename, source))
+            lang = "Python{0}".format(
+                PythonUtilities.determinePythonVersion(filename, source)
+            )
         if lang != "Python3":
             return
 
@@ -183,7 +185,9 @@
             "Python3": [],
         }
         for filename, source, args in argumentsList:
-            lang = "Python{0}".format(determinePythonVersion(filename, source))
+            lang = "Python{0}".format(
+                PythonUtilities.determinePythonVersion(filename, source)
+            )
             if lang != "Python3":
                 continue
             else:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/PluginEricapi.py
--- a/src/eric7/Plugins/PluginEricapi.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/PluginEricapi.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,10 +12,10 @@
 from PyQt6.QtCore import QCoreApplication, QObject
 from PyQt6.QtWidgets import QDialog
 
-from eric7 import Utilities
 from eric7.EricGui.EricAction import EricAction
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.Globals import getConfig
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities, PythonUtilities
 from eric7.UI import Info
 
 # Start-Of-Header
@@ -46,10 +46,10 @@
         the executable
     """
     exe = "eric7_api"
-    if Utilities.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         for exepath in (
             getConfig("bindir"),
-            Utilities.getPythonScriptsDirectory(),
+            PythonUtilities.getPythonScriptsDirectory(),
         ):
             found = False
             for ext in (".exe", ".cmd", ".bat"):
@@ -63,7 +63,7 @@
     else:
         for exepath in (
             getConfig("bindir"),
-            Utilities.getPythonScriptsDirectory(),
+            PythonUtilities.getPythonScriptsDirectory(),
         ):
             exe_ = os.path.join(exepath, exe)
             if os.path.exists(exe_):
@@ -202,7 +202,7 @@
             if res:
                 dia.exec()
 
-            outputFileName = Utilities.toNativeSeparators(parms["outputFile"])
+            outputFileName = FileSystemUtilities.toNativeSeparators(parms["outputFile"])
 
             # add output files to the project data, if they aren't in already
             for progLanguage in parms["languages"]:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/PluginEricdoc.py
--- a/src/eric7/Plugins/PluginEricdoc.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/PluginEricdoc.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,10 +12,16 @@
 from PyQt6.QtCore import QCoreApplication, QObject
 from PyQt6.QtWidgets import QDialog
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui.EricAction import EricAction
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.Globals import getConfig
+from eric7.SystemUtilities import (
+    FileSystemUtilities,
+    OSUtilities,
+    PythonUtilities,
+    QtUtilities,
+)
 from eric7.UI import Info
 
 # Start-Of-Header
@@ -49,10 +55,10 @@
 
     # 1. eric7_doc
     exe = "eric7_doc"
-    if Utilities.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         for exepath in (
             getConfig("bindir"),
-            Utilities.getPythonScriptsDirectory(),
+            PythonUtilities.getPythonScriptsDirectory(),
         ):
             found = False
             for ext in (".exe", ".cmd", ".bat"):
@@ -66,7 +72,7 @@
     else:
         for exepath in (
             getConfig("bindir"),
-            Utilities.getPythonScriptsDirectory(),
+            PythonUtilities.getPythonScriptsDirectory(),
         ):
             exe_ = os.path.join(exepath, exe)
             if os.path.exists(exe_):
@@ -95,16 +101,16 @@
     if not exe:
         # 2.2 location before 6.3 (Linux and macOS) and Windows
         exe = os.path.join(
-            Utilities.getQtBinariesPath(),
-            Utilities.generateQtToolName("qhelpgenerator"),
+            QtUtilities.getQtBinariesPath(),
+            QtUtilities.generateQtToolName("qhelpgenerator"),
         )
-        if Utilities.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             exe += ".exe"
         if not os.path.exists(exe):
             # 2.3 location starting with 6.3.0 (Linux and macOS)
             exe = os.path.join(
-                Utilities.getQtBinariesPath(libexec=True),
-                Utilities.generateQtToolName("qhelpgenerator"),
+                QtUtilities.getQtBinariesPath(libexec=True),
+                QtUtilities.generateQtToolName("qhelpgenerator"),
             )
 
     if exe:
@@ -240,7 +246,7 @@
             if res:
                 dia.exec()
 
-            outdir = Utilities.toNativeSeparators(parms["outputDirectory"])
+            outdir = FileSystemUtilities.toNativeSeparators(parms["outputDirectory"])
             if outdir == "":
                 outdir = "doc"  # that is eric7_docs default output dir
 
@@ -255,7 +261,9 @@
                 project.othersAdded(outdir)
 
             if parms["qtHelpEnabled"]:
-                outdir = Utilities.toNativeSeparators(parms["qtHelpOutputDirectory"])
+                outdir = FileSystemUtilities.toNativeSeparators(
+                    parms["qtHelpOutputDirectory"]
+                )
                 if outdir == "":
                     outdir = "help"
                     # that is eric7_docs default QtHelp output dir
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/PluginVcsGit.py
--- a/src/eric7/Plugins/PluginVcsGit.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/PluginVcsGit.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,10 +12,11 @@
 
 from PyQt6.QtCore import QByteArray, QCoreApplication, QObject
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.Plugins.VcsPlugins.vcsGit.GitUtilities import getConfigPath
 from eric7.Preferences.Shortcuts import readShortcuts
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 from eric7.UI import Info
 
 # Start-Of-Header
@@ -44,7 +45,7 @@
         the executable
     """
     exe = "git"
-    if Utilities.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         exe += ".exe"
 
     data = {
@@ -71,9 +72,9 @@
     global pluginTypename
     data = {}
     exe = "git"
-    if Utilities.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         exe += ".exe"
-    if Utilities.isinpath(exe):
+    if FileSystemUtilities.isinpath(exe):
         data[".git"] = (pluginTypename, displayString())
         data["_git"] = (pluginTypename, displayString())
     return data
@@ -86,9 +87,9 @@
     @return display string (string)
     """
     exe = "git"
-    if Utilities.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         exe += ".exe"
-    if Utilities.isinpath(exe):
+    if FileSystemUtilities.isinpath(exe):
         return QCoreApplication.translate("VcsGitPlugin", "Git")
     else:
         return ""
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/PluginVcsMercurial.py
--- a/src/eric7/Plugins/PluginVcsMercurial.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/PluginVcsMercurial.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,13 +12,14 @@
 
 from PyQt6.QtCore import QByteArray, QCoreApplication, QObject
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.Plugins.VcsPlugins.vcsMercurial.HgUtilities import (
     getConfigPath,
     getHgExecutable,
 )
 from eric7.Preferences.Shortcuts import readShortcuts
+from eric7.SystemUtilities import FileSystemUtilities
 from eric7.UI import Info
 
 # Start-Of-Header
@@ -72,7 +73,7 @@
     global pluginTypename
     data = {}
     exe = getHgExecutable()
-    if Utilities.isinpath(exe):
+    if FileSystemUtilities.isinpath(exe):
         data[".hg"] = (pluginTypename, displayString())
         data["_hg"] = (pluginTypename, displayString())
     return data
@@ -85,7 +86,7 @@
     @return display string (string)
     """
     exe = getHgExecutable()
-    if Utilities.isinpath(exe):
+    if FileSystemUtilities.isinpath(exe):
         return QCoreApplication.translate("VcsMercurialPlugin", "Mercurial")
     else:
         return ""
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/PluginVcsSubversion.py
--- a/src/eric7/Plugins/PluginVcsSubversion.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/PluginVcsSubversion.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,13 +12,14 @@
 
 from PyQt6.QtCore import QCoreApplication, QObject
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.Plugins.VcsPlugins.vcsSubversion.SvnUtilities import (
     getConfigPath,
     getServersPath,
 )
 from eric7.Preferences.Shortcuts import readShortcuts
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 from eric7.UI import Info
 
 # Start-Of-Header
@@ -47,7 +48,7 @@
         the executable
     """
     exe = "svn"
-    if Utilities.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         exe += ".exe"
 
     data = {
@@ -76,9 +77,9 @@
     global pluginTypename
     data = {}
     exe = "svn"
-    if Utilities.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         exe += ".exe"
-    if Utilities.isinpath(exe):
+    if FileSystemUtilities.isinpath(exe):
         data[".svn"] = (pluginTypename, displayString())
         data["_svn"] = (pluginTypename, displayString())
     return data
@@ -91,9 +92,9 @@
     @return display string (string)
     """
     exe = "svn"
-    if Utilities.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         exe += ".exe"
-    if Utilities.isinpath(exe):
+    if FileSystemUtilities.isinpath(exe):
         return QCoreApplication.translate("VcsSubversionPlugin", "Subversion (svn)")
     else:
         return ""
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsGit/GitArchiveDataDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsGit/GitArchiveDataDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsGit/GitArchiveDataDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,9 +12,9 @@
 from PyQt6.QtCore import pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Utilities
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_GitArchiveDataDialog import Ui_GitArchiveDataDialog
 
@@ -82,7 +82,7 @@
         fileName = EricFileDialog.getSaveFileName(
             self,
             self.tr("Select Archive File"),
-            Utilities.fromNativeSeparators(self.fileEdit.text()),
+            FileSystemUtilities.fromNativeSeparators(self.fileEdit.text()),
             "",
         )
 
@@ -91,7 +91,7 @@
             if not ext:
                 ext = "." + self.formatComboBox.currentText()
             fileName = root + ext
-            self.fileEdit.setText(Utilities.toNativeSeparators(fileName))
+            self.fileEdit.setText(FileSystemUtilities.toNativeSeparators(fileName))
 
     @pyqtSlot(bool)
     def on_revButton_toggled(self, checked):
@@ -166,6 +166,6 @@
         return (
             rev,
             self.formatComboBox.currentText(),
-            Utilities.toNativeSeparators(self.fileEdit.text()),
+            FileSystemUtilities.toNativeSeparators(self.fileEdit.text()),
             self.prefixEdit.text(),
         )
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsGit/GitCopyDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsGit/GitCopyDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsGit/GitCopyDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,10 +12,10 @@
 from PyQt6.QtCore import pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Utilities
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog
 from eric7.EricWidgets.EricCompleters import EricDirCompleter, EricFileCompleter
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_GitCopyDialog import Ui_GitCopyDialog
 
@@ -68,7 +68,10 @@
         if not os.path.isabs(target):
             sourceDir = os.path.dirname(self.sourceEdit.text())
             target = os.path.join(sourceDir, target)
-        return (Utilities.toNativeSeparators(target), self.forceCheckBox.isChecked())
+        return (
+            FileSystemUtilities.toNativeSeparators(target),
+            self.forceCheckBox.isChecked(),
+        )
 
     @pyqtSlot()
     def on_dirButton_clicked(self):
@@ -94,7 +97,7 @@
         )
 
         if target:
-            self.targetEdit.setText(Utilities.toNativeSeparators(target))
+            self.targetEdit.setText(FileSystemUtilities.toNativeSeparators(target))
 
     @pyqtSlot(str)
     def on_targetEdit_textChanged(self, txt):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsGit/GitNewProjectOptionsDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsGit/GitNewProjectOptionsDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsGit/GitNewProjectOptionsDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,10 +11,11 @@
 from PyQt6.QtCore import QUrl, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog
 from eric7.EricWidgets.EricCompleters import EricDirCompleter
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 
 from .Config import ConfigGitSchemes
 from .Ui_GitNewProjectOptionsDialog import Ui_GitNewProjectOptionsDialog
@@ -49,13 +50,13 @@
         self.vcsDirectoryCompleter = EricDirCompleter(self.vcsUrlCombo)
         self.vcsProjectDirCompleter = EricDirCompleter(self.vcsProjectDirEdit)
 
-        ipath = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir()
+        ipath = Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir()
         self.__initPaths = [
-            Utilities.fromNativeSeparators(ipath),
-            Utilities.fromNativeSeparators(ipath) + "/",
+            FileSystemUtilities.fromNativeSeparators(ipath),
+            FileSystemUtilities.fromNativeSeparators(ipath) + "/",
         ]
         self.vcsProjectDirEdit.setText(
-            Utilities.toNativeSeparators(self.__initPaths[0])
+            FileSystemUtilities.toNativeSeparators(self.__initPaths[0])
         )
 
         self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False)
@@ -71,7 +72,8 @@
         @param txt name of the project directory (string)
         """
         self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
-            bool(txt) and Utilities.fromNativeSeparators(txt) not in self.__initPaths
+            bool(txt)
+            and FileSystemUtilities.fromNativeSeparators(txt) not in self.__initPaths
         )
 
     @pyqtSlot()
@@ -87,7 +89,9 @@
         )
 
         if directory:
-            self.vcsUrlCombo.setEditText(Utilities.toNativeSeparators(directory))
+            self.vcsUrlCombo.setEditText(
+                FileSystemUtilities.toNativeSeparators(directory)
+            )
 
     @pyqtSlot()
     def on_projectDirButton_clicked(self):
@@ -102,7 +106,9 @@
         )
 
         if directory:
-            self.vcsProjectDirEdit.setText(Utilities.toNativeSeparators(directory))
+            self.vcsProjectDirEdit.setText(
+                FileSystemUtilities.toNativeSeparators(directory)
+            )
 
     @pyqtSlot(str)
     def on_vcsUrlCombo_editTextChanged(self, txt):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsGit/GitPatchFilesDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsGit/GitPatchFilesDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsGit/GitPatchFilesDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -10,9 +10,9 @@
 from PyQt6.QtCore import pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Utilities
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_GitPatchFilesDialog import Ui_GitPatchFilesDialog
 
@@ -84,7 +84,7 @@
         if patchFiles:
             currentPatchFiles = self.__getPatchFilesList()
             for patchFile in patchFiles:
-                patchFile = Utilities.toNativeSeparators(patchFile)
+                patchFile = FileSystemUtilities.toNativeSeparators(patchFile)
                 if patchFile not in currentPatchFiles:
                     self.patchFilesList.addItem(patchFile)
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsGit/GitSubmoduleAddDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsGit/GitSubmoduleAddDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsGit/GitSubmoduleAddDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -10,10 +10,11 @@
 from PyQt6.QtCore import QUrl, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog
 from eric7.EricWidgets.EricCompleters import EricDirCompleter
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 
 from .Config import ConfigGitSchemes
 from .Ui_GitSubmoduleAddDialog import Ui_GitSubmoduleAddDialog
@@ -56,10 +57,10 @@
         self.submoduleUrlDirCompleter = EricDirCompleter(self.submoduleUrlCombo)
         self.submoduleDirCompleter = EricDirCompleter(self.submoduleDirEdit)
 
-        ipath = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir()
+        ipath = Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir()
         self.__initPaths = [
-            Utilities.fromNativeSeparators(ipath),
-            Utilities.fromNativeSeparators(ipath) + "/",
+            FileSystemUtilities.fromNativeSeparators(ipath),
+            FileSystemUtilities.fromNativeSeparators(ipath) + "/",
         ]
 
         self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False)
@@ -106,7 +107,9 @@
         )
 
         if directory:
-            self.submoduleUrlCombo.setEditText(Utilities.toNativeSeparators(directory))
+            self.submoduleUrlCombo.setEditText(
+                FileSystemUtilities.toNativeSeparators(directory)
+            )
 
     @pyqtSlot()
     def on_submoduleUrlClearHistoryButton_clicked(self):
@@ -132,7 +135,9 @@
         )
 
         if directory:
-            self.submoduleDirEdit.setText(Utilities.toNativeSeparators(directory))
+            self.submoduleDirEdit.setText(
+                FileSystemUtilities.toNativeSeparators(directory)
+            )
 
     def getData(self):
         """
@@ -189,8 +194,12 @@
         """
         if path == self.__repodir:
             return ""
-        elif Utilities.normcasepath(Utilities.toNativeSeparators(path)).startswith(
-            Utilities.normcasepath(Utilities.toNativeSeparators(self.__repodir + "/"))
+        elif FileSystemUtilities.normcasepath(
+            FileSystemUtilities.toNativeSeparators(path)
+        ).startswith(
+            FileSystemUtilities.normcasepath(
+                FileSystemUtilities.toNativeSeparators(self.__repodir + "/")
+            )
         ):
             relpath = path[len(self.__repodir) :]
             if relpath.startswith(("/", "\\")):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsGit/GitUtilities.py
--- a/src/eric7/Plugins/VcsPlugins/vcsGit/GitUtilities.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsGit/GitUtilities.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,7 +11,7 @@
 
 from PyQt6.QtCore import QProcessEnvironment
 
-from eric7 import Utilities
+from eric7.SystemUtilities import OSUtilities
 
 
 def getConfigPath():
@@ -20,11 +20,11 @@
 
     @return filename of the config file (string)
     """
-    if Utilities.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         userprofile = os.environ["USERPROFILE"]
         return os.path.join(userprofile, ".gitconfig")
     else:
-        homedir = Utilities.getHomeDir()
+        homedir = OSUtilities.getHomeDir()
         return os.path.join(homedir, ".gitconfig")
 
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsGit/git.py
--- a/src/eric7/Plugins/VcsPlugins/vcsGit/git.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsGit/git.py	Sun Dec 18 19:33:46 2022 +0100
@@ -17,10 +17,11 @@
 from PyQt6.QtCore import QProcess, pyqtSignal
 from PyQt6.QtWidgets import QApplication, QDialog, QInputDialog, QLineEdit
 
-from eric7 import Globals, Preferences, Utilities
+from eric7 import Preferences, Utilities
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.QScintilla.MiniEditor import MiniEditor
+from eric7.SystemUtilities import FileSystemUtilities, PythonUtilities
 from eric7.VCS.RepositoryInfoDialog import VcsRepositoryInfoDialog
 from eric7.VCS.VersionControl import VersionControl
 
@@ -1191,7 +1192,7 @@
 
         entries = []
         for pat in patterns:
-            entries.extend(Utilities.direntries(name, True, pat))
+            entries.extend(FileSystemUtilities.direntries(name, True, pat))
 
         for entry in entries:
             with contextlib.suppress(OSError):
@@ -1850,7 +1851,11 @@
             return
 
         editor = sys.argv[0].replace(".py", "_editor.py")
-        env = {"GIT_EDITOR": "{0} {1}".format(Globals.getPythonExecutable(), editor)}
+        env = {
+            "GIT_EDITOR": "{0} {1}".format(
+                PythonUtilities.getPythonExecutable(), editor
+            )
+        }
 
         args = self.initCommand("commit")
 
@@ -3248,7 +3253,11 @@
             return False
 
         editor = sys.argv[0].replace(".py", "_editor.py")
-        env = {"GIT_EDITOR": "{0} {1}".format(Globals.getPythonExecutable(), editor)}
+        env = {
+            "GIT_EDITOR": "{0} {1}".format(
+                PythonUtilities.getPythonExecutable(), editor
+            )
+        }
 
         args = self.initCommand("cherry-pick")
         args.append("--continue")
@@ -3881,7 +3890,7 @@
             args.append("--format={0}".format(archiveFormat))
             args.append("--output={0}".format(fileName))
             if prefix:
-                prefix = Utilities.fromNativeSeparators(prefix)
+                prefix = FileSystemUtilities.fromNativeSeparators(prefix)
                 if not prefix.endswith("/"):
                     prefix += "/"
                 args.append("--prefix={0}".format(prefix))
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.py
--- a/src/eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,12 +11,12 @@
 
 from PyQt6.QtCore import pyqtSlot
 
-from eric7 import Globals
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
 from eric7.Preferences.ConfigurationPages.ConfigurationPageBase import (
     ConfigurationPageBase,
 )
+from eric7.SystemUtilities import OSUtilities, PythonUtilities
 from eric7.Utilities import supportedCodecs
 
 from .. import HgUtilities
@@ -41,7 +41,7 @@
         self.__plugin = plugin
 
         self.hgPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
-        if Globals.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             self.hgPicker.setFilters(self.tr("Executable Files (*.exe);;All Files (*)"))
         else:
             self.hgPicker.setFilters(self.tr("All Files (*)"))
@@ -148,7 +148,9 @@
         Private slot to install Mercurial alongside eric7.
         """
         pip = ericApp().getObject("Pip")
-        pip.installPackages(["mercurial"], interpreter=Globals.getPythonExecutable())
+        pip.installPackages(
+            ["mercurial"], interpreter=PythonUtilities.getPythonExecutable()
+        )
         self.installButton.setEnabled(not self.__mercurialInstalled())
 
     def __mercurialInstalled(self):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsMercurial/HgAddSubrepositoryDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsMercurial/HgAddSubrepositoryDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsMercurial/HgAddSubrepositoryDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,9 +12,9 @@
 from PyQt6.QtCore import pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Utilities
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_HgAddSubrepositoryDialog import Ui_HgAddSubrepositoryDialog
 
@@ -40,7 +40,7 @@
         self.__ok = self.buttonBox.button(QDialogButtonBox.StandardButton.Ok)
         self.__ok.setEnabled(False)
 
-        self.__projectPath = Utilities.toNativeSeparators(projectPath)
+        self.__projectPath = FileSystemUtilities.toNativeSeparators(projectPath)
 
         self.typeCombo.addItem("Mercurial", "hg")
         self.typeCombo.addItem("GIT", "git")
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsMercurial/HgArchiveDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsMercurial/HgArchiveDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsMercurial/HgArchiveDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -10,8 +10,8 @@
 from PyQt6.QtCore import pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Utilities
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import OSUtilities
 
 from .Ui_HgArchiveDialog import Ui_HgArchiveDialog
 
@@ -52,7 +52,7 @@
         ]
         fileFilters = (
             ";;".join(self.__windowsFileFilters + self.__unixFileFilters)
-            if Utilities.isWindowsPlatform()
+            if OSUtilities.isWindowsPlatform()
             else ";;".join(self.__unixFileFilters + self.__windowsFileFilters)
         )
         fileFilters += ";;" + self.tr("All Files (*)")
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsMercurial/HgNewProjectOptionsDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsMercurial/HgNewProjectOptionsDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsMercurial/HgNewProjectOptionsDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,9 +11,10 @@
 from PyQt6.QtCore import QUrl, pyqtSlot
 from PyQt6.QtWidgets import QComboBox, QDialog, QDialogButtonBox
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 
 from .Config import ConfigHgSchemes
 from .Ui_HgNewProjectOptionsDialog import Ui_HgNewProjectOptionsDialog
@@ -49,10 +50,10 @@
         self.vcsUrlClearHistoryButton.setIcon(EricPixmapCache.getIcon("editDelete"))
         self.vcsUrlPicker.setText("")
 
-        ipath = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir()
+        ipath = Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir()
         self.__initPaths = [
-            Utilities.fromNativeSeparators(ipath),
-            Utilities.fromNativeSeparators(ipath) + "/",
+            FileSystemUtilities.fromNativeSeparators(ipath),
+            FileSystemUtilities.fromNativeSeparators(ipath) + "/",
         ]
         self.vcsProjectDirPicker.setText(self.__initPaths[0])
 
@@ -72,7 +73,8 @@
         @param txt name of the project directory (string)
         """
         self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
-            bool(txt) and Utilities.fromNativeSeparators(txt) not in self.__initPaths
+            bool(txt)
+            and FileSystemUtilities.fromNativeSeparators(txt) not in self.__initPaths
         )
 
     @pyqtSlot(str)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsMercurial/HgUserConfigDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsMercurial/HgUserConfigDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsMercurial/HgUserConfigDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -15,10 +15,10 @@
 from PyQt6.QtCore import QEvent, Qt, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QTreeWidgetItem
 
-from eric7 import Globals
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import OSUtilities
 
 from .HgUserConfigHostFingerprintDialog import HgUserConfigHostFingerprintDialog
 from .HgUserConfigHostMinimumProtocolDialog import HgUserConfigHostMinimumProtocolDialog
@@ -52,11 +52,11 @@
         }
 
         self.lfUserCachePicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
-        if Globals.isLinuxPlatform():
+        if OSUtilities.isLinuxPlatform():
             self.lfUserCachePicker.setDefaultDirectory(
                 os.path.expanduser("~/.cache/largefiles")
             )
-        elif Globals.isMacPlatform():
+        elif OSUtilities.isMacPlatform():
             self.lfUserCachePicker.setDefaultDirectory(
                 os.path.expanduser("~/Library/Caches/largefiles")
             )
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsMercurial/HgUtilities.py
--- a/src/eric7/Plugins/VcsPlugins/vcsMercurial/HgUtilities.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsMercurial/HgUtilities.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,8 +12,7 @@
 
 from PyQt6.QtCore import QCoreApplication, QProcess, QProcessEnvironment
 
-from eric7 import Utilities
-from eric7.Globals import isWindowsPlatform
+from eric7.SystemUtilities import OSUtilities, PythonUtilities
 
 
 def getHgExecutable():
@@ -28,10 +27,10 @@
     exe = VcsMercurialPlugin.getPreferences("MercurialExecutablePath")
     if not exe:
         program = "hg"
-        if isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             program += ".exe"
 
-        progPath = os.path.join(Utilities.getPythonScriptsDirectory(), program)
+        progPath = os.path.join(PythonUtilities.getPythonScriptsDirectory(), program)
         if os.path.exists(progPath):
             exe = progPath
 
@@ -48,11 +47,11 @@
     @return filename of the config file
     @rtype str
     """
-    if Utilities.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         userprofile = os.environ["USERPROFILE"]
         return os.path.join(userprofile, "Mercurial.ini")
     else:
-        homedir = Utilities.getHomeDir()
+        homedir = OSUtilities.getHomeDir()
         return os.path.join(homedir, ".hgrc")
 
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsMercurial/HisteditExtension/histedit.py
--- a/src/eric7/Plugins/VcsPlugins/vcsMercurial/HisteditExtension/histedit.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsMercurial/HisteditExtension/histedit.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,7 +11,7 @@
 
 from PyQt6.QtWidgets import QDialog
 
-from eric7 import Globals
+from eric7.SystemUtilities import PythonUtilities
 
 from ..HgDialog import HgDialog
 from ..HgExtension import HgExtension
@@ -57,7 +57,10 @@
             args = self.vcs.initCommand("histedit")
             args.append("-v")
             args.extend(
-                ["--config", f"ui.editor={Globals.getPythonExecutable()} {editor}"]
+                [
+                    "--config",
+                    f"ui.editor={PythonUtilities.getPythonExecutable()} {editor}",
+                ]
             )
             if keep:
                 args.append("--keep")
@@ -70,8 +73,12 @@
                 args.append(rev)
 
             env = {
-                "HGEDITOR": "{0} {1}".format(Globals.getPythonExecutable(), editor),
-                "EDITOR": "{0} {1}".format(Globals.getPythonExecutable(), editor),
+                "HGEDITOR": "{0} {1}".format(
+                    PythonUtilities.getPythonExecutable(), editor
+                ),
+                "EDITOR": "{0} {1}".format(
+                    PythonUtilities.getPythonExecutable(), editor
+                ),
             }
 
             dia = HgDialog(
@@ -96,7 +103,9 @@
         args.append("-v")
 
         editor = os.path.join(os.path.dirname(__file__), "HgHisteditEditor.py")
-        env = {"HGEDITOR": "{0} {1}".format(Globals.getPythonExecutable(), editor)}
+        env = {
+            "HGEDITOR": "{0} {1}".format(PythonUtilities.getPythonExecutable(), editor)
+        }
 
         dia = HgDialog(self.tr("Continue histedit session"), self.vcs, useClient=False)
         res = dia.startProcess(args, environment=env)
@@ -120,7 +129,9 @@
         args.append("-v")
 
         editor = os.path.join(os.path.dirname(__file__), "HgHisteditEditor.py")
-        env = {"HGEDITOR": "{0} {1}".format(Globals.getPythonExecutable(), editor)}
+        env = {
+            "HGEDITOR": "{0} {1}".format(PythonUtilities.getPythonExecutable(), editor)
+        }
 
         dia = HgDialog(self.tr("Abort histedit session"), self.vcs, useClient=False)
         res = dia.startProcess(args, environment=env)
@@ -143,7 +154,9 @@
         args.append("-v")
 
         editor = os.path.join(os.path.dirname(__file__), "HgHisteditEditor.py")
-        env = {"HGEDITOR": "{0} {1}".format(Globals.getPythonExecutable(), editor)}
+        env = {
+            "HGEDITOR": "{0} {1}".format(PythonUtilities.getPythonExecutable(), editor)
+        }
 
         dia = HgDialog(self.tr("Edit Plan"), self.vcs, useClient=False)
         res = dia.startProcess(args, environment=env)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfConvertDataDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfConvertDataDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfConvertDataDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,8 +12,8 @@
 from PyQt6.QtCore import pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Utilities
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities
 
 from . import getDefaults
 from .Ui_LfConvertDataDialog import Ui_LfConvertDataDialog
@@ -38,7 +38,7 @@
         self.newProjectPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
 
         self.__defaults = getDefaults()
-        self.__currentPath = Utilities.toNativeSeparators(currentPath)
+        self.__currentPath = FileSystemUtilities.toNativeSeparators(currentPath)
 
         self.currentProjectLabel.setPath(currentPath)
         self.newProjectPicker.setText(os.path.dirname(currentPath))
@@ -62,7 +62,8 @@
         """
         self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
             txt
-            and Utilities.toNativeSeparators(txt) != os.path.dirname(self.__currentPath)
+            and FileSystemUtilities.toNativeSeparators(txt)
+            != os.path.dirname(self.__currentPath)
         )
 
     def getData(self):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsMercurial/hg.py
--- a/src/eric7/Plugins/VcsPlugins/vcsMercurial/hg.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsMercurial/hg.py	Sun Dec 18 19:33:46 2022 +0100
@@ -19,6 +19,7 @@
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.QScintilla.MiniEditor import MiniEditor
+from eric7.SystemUtilities import FileSystemUtilities
 from eric7.VCS.RepositoryInfoDialog import VcsRepositoryInfoDialog
 from eric7.VCS.VersionControl import VersionControl
 
@@ -1075,7 +1076,9 @@
             for line in output.splitlines():
                 if len(line) > 2 and line[0] in "MARC!?I" and line[1] == " ":
                     flag, path = line.split(" ", 1)
-                    absname = Utilities.normcasepath(os.path.join(repodir, path))
+                    absname = FileSystemUtilities.normcasepath(
+                        os.path.join(repodir, path)
+                    )
                     if flag not in "?I" and absname == name:
                         return self.canBeCommitted
 
@@ -1180,7 +1183,7 @@
 
         entries = []
         for pat in patterns:
-            entries.extend(Utilities.direntries(name, True, pat))
+            entries.extend(FileSystemUtilities.direntries(name, True, pat))
 
         for entry in entries:
             with contextlib.suppress(OSError):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnDiffDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnDiffDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnDiffDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -17,11 +17,12 @@
 from PyQt6.QtGui import QTextCursor
 from PyQt6.QtWidgets import QDialogButtonBox, QWidget
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui.EricOverrideCursor import EricOverrideCursor
 from eric7.EricUtilities.EricMutexLocker import EricMutexLocker
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import OSUtilities
 
 from .SvnDialogMixin import SvnDialogMixin
 from .SvnDiffHighlighter import SvnDiffHighlighter
@@ -153,12 +154,12 @@
         self.__oldFileLine = -1
         self.__fileSeparators = []
 
-        if Utilities.hasEnvironmentEntry("TEMP"):
-            tmpdir = Utilities.getEnvironmentEntry("TEMP")
-        elif Utilities.hasEnvironmentEntry("TMPDIR"):
-            tmpdir = Utilities.getEnvironmentEntry("TMPDIR")
-        elif Utilities.hasEnvironmentEntry("TMP"):
-            tmpdir = Utilities.getEnvironmentEntry("TMP")
+        if OSUtilities.hasEnvironmentEntry("TEMP"):
+            tmpdir = OSUtilities.getEnvironmentEntry("TEMP")
+        elif OSUtilities.hasEnvironmentEntry("TMPDIR"):
+            tmpdir = OSUtilities.getEnvironmentEntry("TMPDIR")
+        elif OSUtilities.hasEnvironmentEntry("TMP"):
+            tmpdir = OSUtilities.getEnvironmentEntry("TMP")
         elif os.path.exists("/var/tmp"):  # secok
             tmpdir = "/var/tmp"  # secok
         elif os.path.exists("/usr/tmp"):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnNewProjectOptionsDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnNewProjectOptionsDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnNewProjectOptionsDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,8 +13,9 @@
 from PyQt6.QtCore import QDir, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 
 from .Config import ConfigSvnProtocols
 from .Ui_SvnNewProjectOptionsDialog import Ui_SvnNewProjectOptionsDialog
@@ -41,7 +42,7 @@
 
         self.protocolCombo.addItems(ConfigSvnProtocols)
 
-        hd = Utilities.toNativeSeparators(QDir.homePath())
+        hd = FileSystemUtilities.toNativeSeparators(QDir.homePath())
         hd = os.path.join(hd, "subversionroot")
         self.vcsUrlPicker.setText(hd)
 
@@ -51,10 +52,10 @@
         self.networkPath = "localhost/"
         self.localProtocol = True
 
-        ipath = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir()
+        ipath = Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir()
         self.__initPaths = [
-            Utilities.fromNativeSeparators(ipath),
-            Utilities.fromNativeSeparators(ipath) + "/",
+            FileSystemUtilities.fromNativeSeparators(ipath),
+            FileSystemUtilities.fromNativeSeparators(ipath) + "/",
         ]
         self.vcsProjectDirPicker.setText(self.__initPaths[0])
 
@@ -73,7 +74,8 @@
         @param txt name of the project directory (string)
         """
         self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
-            bool(txt) and Utilities.fromNativeSeparators(txt) not in self.__initPaths
+            bool(txt)
+            and FileSystemUtilities.fromNativeSeparators(txt) not in self.__initPaths
         )
 
     @pyqtSlot()
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnOptionsDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnOptionsDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnOptionsDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,8 +13,8 @@
 from PyQt6.QtCore import QDir, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Utilities
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Config import ConfigSvnProtocols
 from .Ui_SvnOptionsDialog import Ui_SvnOptionsDialog
@@ -43,7 +43,7 @@
 
         self.protocolCombo.addItems(ConfigSvnProtocols)
 
-        hd = Utilities.toNativeSeparators(QDir.homePath())
+        hd = FileSystemUtilities.toNativeSeparators(QDir.homePath())
         hd = os.path.join(hd, "subversionroot")
         self.vcsUrlPicker.setText(hd)
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnStatusDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnStatusDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnStatusDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -22,11 +22,12 @@
     QWidget,
 )
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui.EricOverrideCursor import EricOverrideCursor
 from eric7.EricUtilities.EricMutexLocker import EricMutexLocker
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .SvnConst import svnStatusMap
 from .SvnDialogMixin import SvnDialogMixin
@@ -360,7 +361,7 @@
                                 depth = pysvn.depth.immediate
                             changelists = self.client.get_changelist(name, depth=depth)
                             for fpath, changelist in changelists:
-                                fpath = Utilities.normcasepath(fpath)
+                                fpath = FileSystemUtilities.normcasepath(fpath)
                                 changelistsDict[fpath] = changelist
                         hideChangelistColumn = (
                             hideChangelistColumn and len(changelistsDict) == 0
@@ -409,7 +410,7 @@
                                 ):
                                     lockState = "S"
 
-                            fpath = Utilities.normcasepath(
+                            fpath = FileSystemUtilities.normcasepath(
                                 os.path.join(self.dname, file.path)
                             )
                             changelist = (
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnUrlSelectionDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnUrlSelectionDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnUrlSelectionDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,9 +14,9 @@
 from PyQt6.QtCore import pyqtSlot
 from PyQt6.QtWidgets import QDialog
 
-from eric7 import Utilities
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_SvnUrlSelectionDialog import Ui_SvnUrlSelectionDialog
 
@@ -86,9 +86,9 @@
             self.repoRootLabel2.setText(reposRoot)
         else:
             project = ericApp().getObject("Project")
-            if Utilities.normcasepath(path) != Utilities.normcasepath(
-                project.getProjectPath()
-            ):
+            if FileSystemUtilities.normcasepath(
+                path
+            ) != FileSystemUtilities.normcasepath(project.getProjectPath()):
                 path = project.getRelativePath(path)
                 reposURL = reposURL.replace(path, "")
             self.repoRootLabel1.hide()
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnUtilities.py
--- a/src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnUtilities.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsPySvn/SvnUtilities.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,7 +12,7 @@
 
 from PyQt6.QtCore import QDateTime, Qt
 
-from eric7 import Utilities
+from eric7.SystemUtilities import OSUtilities
 
 from .Config import DefaultConfig, DefaultIgnores
 
@@ -51,11 +51,11 @@
 
     @return filename of the servers file (string)
     """
-    if Utilities.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         appdata = os.environ["APPDATA"]
         return os.path.join(appdata, "Subversion", "servers")
     else:
-        homedir = Utilities.getHomeDir()
+        homedir = OSUtilities.getHomeDir()
         return os.path.join(homedir, ".subversion", "servers")
 
 
@@ -65,11 +65,11 @@
 
     @return filename of the config file (string)
     """
-    if Utilities.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         appdata = os.environ["APPDATA"]
         return os.path.join(appdata, "Subversion", "config")
     else:
-        homedir = Utilities.getHomeDir()
+        homedir = OSUtilities.getHomeDir()
         return os.path.join(homedir, ".subversion", "config")
 
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnNewProjectOptionsDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnNewProjectOptionsDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnNewProjectOptionsDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,8 +13,9 @@
 from PyQt6.QtCore import QDir, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 
 from .Config import ConfigSvnProtocols
 from .Ui_SvnNewProjectOptionsDialog import Ui_SvnNewProjectOptionsDialog
@@ -43,7 +44,7 @@
 
         self.vcs = vcs
 
-        hd = Utilities.toNativeSeparators(QDir.homePath())
+        hd = FileSystemUtilities.toNativeSeparators(QDir.homePath())
         hd = os.path.join(hd, "subversionroot")
         self.vcsUrlPicker.setText(hd)
 
@@ -51,10 +52,10 @@
         self.networkPath = "localhost/"
         self.localProtocol = True
 
-        ipath = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir()
+        ipath = Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir()
         self.__initPaths = [
-            Utilities.fromNativeSeparators(ipath),
-            Utilities.fromNativeSeparators(ipath) + "/",
+            FileSystemUtilities.fromNativeSeparators(ipath),
+            FileSystemUtilities.fromNativeSeparators(ipath) + "/",
         ]
         self.vcsProjectDirPicker.setText(self.__initPaths[0])
 
@@ -73,7 +74,8 @@
         @param txt name of the project directory (string)
         """
         self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
-            bool(txt) and Utilities.fromNativeSeparators(txt) not in self.__initPaths
+            bool(txt)
+            and FileSystemUtilities.fromNativeSeparators(txt) not in self.__initPaths
         )
 
     def on_vcsUrlPicker_pickerButtonClicked(self):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnOptionsDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnOptionsDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnOptionsDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,8 +13,8 @@
 from PyQt6.QtCore import QDir, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Utilities
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Config import ConfigSvnProtocols
 from .Ui_SvnOptionsDialog import Ui_SvnOptionsDialog
@@ -43,7 +43,7 @@
 
         self.protocolCombo.addItems(ConfigSvnProtocols)
 
-        hd = Utilities.toNativeSeparators(QDir.homePath())
+        hd = FileSystemUtilities.toNativeSeparators(QDir.homePath())
         hd = os.path.join(hd, "subversionroot")
         self.vcsUrlPicker.setText(hd)
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnUrlSelectionDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnUrlSelectionDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnUrlSelectionDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,9 +12,9 @@
 from PyQt6.QtCore import pyqtSlot
 from PyQt6.QtWidgets import QDialog
 
-from eric7 import Utilities
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_SvnUrlSelectionDialog import Ui_SvnUrlSelectionDialog
 
@@ -84,9 +84,9 @@
             self.repoRootLabel2.setText(reposRoot)
         else:
             project = ericApp().getObject("Project")
-            if Utilities.normcasepath(path) != Utilities.normcasepath(
-                project.getProjectPath()
-            ):
+            if FileSystemUtilities.normcasepath(
+                path
+            ) != FileSystemUtilities.normcasepath(project.getProjectPath()):
                 path = project.getRelativePath(path)
                 reposURL = reposURL.replace(path, "")
             self.repoRootLabel1.hide()
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnUtilities.py
--- a/src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnUtilities.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnUtilities.py	Sun Dec 18 19:33:46 2022 +0100
@@ -10,7 +10,7 @@
 import contextlib
 import os
 
-from eric7 import Utilities
+from eric7.SystemUtilities import OSUtilities
 
 from .Config import DefaultConfig, DefaultIgnores
 
@@ -21,11 +21,11 @@
 
     @return filename of the servers file (string)
     """
-    if Utilities.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         appdata = os.environ["APPDATA"]
         return os.path.join(appdata, "Subversion", "servers")
     else:
-        homedir = Utilities.getHomeDir()
+        homedir = OSUtilities.getHomeDir()
         return os.path.join(homedir, ".subversion", "servers")
 
 
@@ -35,11 +35,11 @@
 
     @return filename of the config file (string)
     """
-    if Utilities.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         appdata = os.environ["APPDATA"]
         return os.path.join(appdata, "Subversion", "config")
     else:
-        homedir = Utilities.getHomeDir()
+        homedir = OSUtilities.getHomeDir()
         return os.path.join(homedir, ".subversion", "config")
 
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/ViewManagerPlugins/Tabview/Tabview.py
--- a/src/eric7/Plugins/ViewManagerPlugins/Tabview/Tabview.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/ViewManagerPlugins/Tabview/Tabview.py	Sun Dec 18 19:33:46 2022 +0100
@@ -36,9 +36,10 @@
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricLed import EricLed
 from eric7.EricWidgets.EricTabWidget import EricTabWidget, EricWheelTabBar
-from eric7.Globals import getConfig, isMacPlatform
+from eric7.Globals import getConfig
 from eric7.QScintilla.Editor import Editor
 from eric7.QScintilla.EditorAssembly import EditorAssembly
+from eric7.SystemUtilities import OSUtilities
 from eric7.ViewManager.ViewManager import ViewManager
 
 
@@ -188,7 +189,7 @@
 
         self.setUsesScrollButtons(True)
         self.setElideMode(Qt.TextElideMode.ElideNone)
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             self.setDocumentMode(True)
 
         self.__tabBar.tabMoveRequested.connect(self.moveTab)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardDialog.py
--- a/src/eric7/Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -23,10 +23,11 @@
     QWidget,
 )
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricMainWindow import EricMainWindow
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_PyRegExpWizardDialog import Ui_PyRegExpWizardDialog
 
@@ -374,7 +375,7 @@
             self.tr("RegExp Files (*.rx);;All Files (*)"),
         )
         if fname:
-            fname = Utilities.toNativeSeparators(fname)
+            fname = FileSystemUtilities.toNativeSeparators(fname)
             try:
                 with open(fname, "r", encoding="utf-8") as f:
                     regexp = f.read()
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardDialog.py
--- a/src/eric7/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -24,10 +24,11 @@
     QWidget,
 )
 
-from eric7 import Globals, Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricMainWindow import EricMainWindow
+from eric7.SystemUtilities import FileSystemUtilities, PythonUtilities
 
 from .Ui_QRegularExpressionWizardDialog import Ui_QRegularExpressionWizardDialog
 
@@ -75,7 +76,7 @@
         self.__pyqt6Available = False
         self.__pyqt6Server = QProcess(self)
         self.__pyqt6Server.start(
-            Globals.getPythonExecutable(),
+            PythonUtilities.getPythonExecutable(),
             [
                 os.path.join(
                     os.path.dirname(__file__), "QRegularExpressionWizardServer.py"
@@ -458,7 +459,7 @@
             self.tr("RegExp Files (*.rx);;All Files (*)"),
         )
         if fname:
-            fname = Utilities.toNativeSeparators(fname)
+            fname = FileSystemUtilities.toNativeSeparators(fname)
             try:
                 with open(fname, "r", encoding="utf-8") as f:
                     regexp = f.read()
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Plugins/WizardPlugins/SetupWizard/SetupWizardDialog.py
--- a/src/eric7/Plugins/WizardPlugins/SetupWizard/SetupWizardDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Plugins/WizardPlugins/SetupWizard/SetupWizardDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -19,10 +19,11 @@
 from PyQt6.QtCore import Qt, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QListWidgetItem, QTreeWidgetItem
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets import EricFileDialog
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 
 from .AddEntryPointDialog import AddEntryPointDialog
 from .AddProjectUrlDialog import AddProjectUrlDialog
@@ -400,7 +401,9 @@
             )
 
         sourceCode += "{0}packages=find_packages(".format(istring)
-        src = Utilities.fromNativeSeparators(self.sourceDirectoryPicker.text())
+        src = FileSystemUtilities.fromNativeSeparators(
+            self.sourceDirectoryPicker.text()
+        )
         excludePatterns = []
         for row in range(self.excludePatternList.count()):
             excludePatterns.append(self.excludePatternList.item(row).text())
@@ -554,7 +557,9 @@
             options["python_requires"] = self.pyVersionEdit.text()
 
         findOptions = {}
-        src = Utilities.fromNativeSeparators(self.sourceDirectoryPicker.text())
+        src = FileSystemUtilities.fromNativeSeparators(
+            self.sourceDirectoryPicker.text()
+        )
         excludePatterns = []
         for row in range(self.excludePatternList.count()):
             excludePatterns.append(self.excludePatternList.item(row).text())
@@ -771,7 +776,9 @@
             setuptools["py-modules"] = modulesArray
 
         findspec = tomlkit.table()
-        src = Utilities.fromNativeSeparators(self.sourceDirectoryPicker.text())
+        src = FileSystemUtilities.fromNativeSeparators(
+            self.sourceDirectoryPicker.text()
+        )
         excludePatterns = []
         for row in range(self.excludePatternList.count()):
             excludePatterns.append(self.excludePatternList.item(row).text())
@@ -862,7 +869,7 @@
         @return start directory
         @rtype str
         """
-        return Preferences.getMultiProject("Workspace") or Utilities.getHomeDir()
+        return Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir()
 
     @pyqtSlot()
     def on_entryPointsList_itemSelectionChanged(self):
@@ -951,7 +958,9 @@
             self.tr("Python Files (*.py)"),
         )
         for module in modulesList:
-            module = module.replace(Utilities.toNativeSeparators(startDir), "")
+            module = module.replace(
+                FileSystemUtilities.toNativeSeparators(startDir), ""
+            )
             if module.startswith(("\\", "/")):
                 module = module[1:]
             if module:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Preferences/ConfigurationDialog.py
--- a/src/eric7/Preferences/ConfigurationDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Preferences/ConfigurationDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -40,7 +40,8 @@
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricMainWindow import EricMainWindow
-from eric7.Globals import getConfig, getWebBrowserSupport, isMacPlatform
+from eric7.Globals import getConfig, getWebBrowserSupport
+from eric7.SystemUtilities import OSUtilities
 
 
 class ConfigurationPageItem(QTreeWidgetItem):
@@ -927,7 +928,7 @@
         """
         Public slot to accept the buttonBox accept signal.
         """
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             wdg = self.focusWidget()
             if wdg == self.configList:
                 return
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Preferences/ConfigurationPages/ApplicationPage.py
--- a/src/eric7/Preferences/ConfigurationPages/ApplicationPage.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Preferences/ConfigurationPages/ApplicationPage.py	Sun Dec 18 19:33:46 2022 +0100
@@ -9,7 +9,8 @@
 
 import multiprocessing
 
-from eric7 import Globals, Preferences
+from eric7 import Preferences
+from eric7.SystemUtilities import OSUtilities
 
 from .ConfigurationPageBase import ConfigurationPageBase
 from .Ui_ApplicationPage import Ui_ApplicationPage
@@ -53,7 +54,7 @@
             Preferences.getUI("CrashSessionEnabled")
         )
         self.globalMenuCheckBox.setChecked(Preferences.getUI("UseNativeMenuBar"))
-        if not Globals.isLinuxPlatform():
+        if not OSUtilities.isLinuxPlatform():
             self.globalMenuCheckBox.hide()
 
         openOnStartup = Preferences.getUI("OpenOnStartup")
@@ -112,7 +113,7 @@
         Preferences.setUI(
             "CrashSessionEnabled", self.crashSessionEnabledCheckBox.isChecked()
         )
-        if Globals.isLinuxPlatform():
+        if OSUtilities.isLinuxPlatform():
             Preferences.setUI("UseNativeMenuBar", self.globalMenuCheckBox.isChecked())
 
         if self.noOpenRadioButton.isChecked():
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Preferences/ConfigurationPages/EditorAPIsPage.py
--- a/src/eric7/Preferences/ConfigurationPages/EditorAPIsPage.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Preferences/ConfigurationPages/EditorAPIsPage.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,13 +13,14 @@
 from PyQt6.QtCore import pyqtSlot
 from PyQt6.QtWidgets import QDialog
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricListSelectionDialog import EricListSelectionDialog
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
 from eric7.QScintilla import Lexers
 from eric7.QScintilla.APIsManager import APIsManager
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .ConfigurationPageBase import ConfigurationPageBase
 from .Ui_EditorAPIsPage import Ui_EditorAPIsPage
@@ -222,7 +223,7 @@
         """
         file = self.apiFilePicker.text()
         if file:
-            self.apiList.addItem(Utilities.toNativeSeparators(file))
+            self.apiList.addItem(FileSystemUtilities.toNativeSeparators(file))
             self.apiFilePicker.clear()
         self.prepareApiButton.setEnabled(self.apiList.count() > 0)
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Preferences/ConfigurationPages/EditorFilePage.py
--- a/src/eric7/Preferences/ConfigurationPages/EditorFilePage.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Preferences/ConfigurationPages/EditorFilePage.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,10 +13,11 @@
 from PyQt6.QtCore import pyqtSlot
 from PyQt6.QtWidgets import QInputDialog, QLineEdit, QListWidgetItem
 
-from eric7 import Globals, Preferences
+from eric7 import Preferences
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.QScintilla import Lexers
+from eric7.SystemUtilities import PythonUtilities
 from eric7.Utilities import supportedCodecs
 
 from .ConfigurationPageBase import ConfigurationPageBase
@@ -387,7 +388,7 @@
         """
         pip = ericApp().getObject("Pip")
         pip.installPackages(
-            ["pymdown-extensions"], interpreter=Globals.getPythonExecutable()
+            ["pymdown-extensions"], interpreter=PythonUtilities.getPythonExecutable()
         )
         self.polishPage()
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Preferences/ConfigurationPages/InterfaceLightPage.py
--- a/src/eric7/Preferences/ConfigurationPages/InterfaceLightPage.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Preferences/ConfigurationPages/InterfaceLightPage.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,7 +13,7 @@
 from PyQt6.QtCore import QTranslator
 from PyQt6.QtWidgets import QStyleFactory
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
 from eric7.Globals import getConfig
@@ -97,7 +97,7 @@
         fnlist = (
             glob.glob("eric7_*.qm")
             + glob.glob(os.path.join(getConfig("ericTranslationsDir"), "eric7_*.qm"))
-            + glob.glob(os.path.join(Utilities.getConfigDir(), "eric7_*.qm"))
+            + glob.glob(os.path.join(Globals.getConfigDir(), "eric7_*.qm"))
         )
         locales = {}
         for fn in fnlist:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Preferences/ConfigurationPages/InterfacePage.py
--- a/src/eric7/Preferences/ConfigurationPages/InterfacePage.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Preferences/ConfigurationPages/InterfacePage.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,7 +13,7 @@
 from PyQt6.QtCore import QTranslator, pyqtSlot
 from PyQt6.QtWidgets import QColorDialog, QDialog, QStyleFactory
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricIconBar import EricIconBar
@@ -226,7 +226,7 @@
         fnlist = (
             glob.glob("eric7_*.qm")
             + glob.glob(os.path.join(getConfig("ericTranslationsDir"), "eric7_*.qm"))
-            + glob.glob(os.path.join(Utilities.getConfigDir(), "eric7_*.qm"))
+            + glob.glob(os.path.join(Globals.getConfigDir(), "eric7_*.qm"))
         )
         locales = {}
         for fn in fnlist:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Preferences/ConfigurationPages/MicroPythonPage.py
--- a/src/eric7/Preferences/ConfigurationPages/MicroPythonPage.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Preferences/ConfigurationPages/MicroPythonPage.py	Sun Dec 18 19:33:46 2022 +0100
@@ -8,9 +8,10 @@
 """
 
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
 from eric7.MicroPython.MicroPythonWidget import AnsiColorSchemes
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 
 from .ConfigurationPageBase import ConfigurationPageBase
 from .Ui_MicroPythonPage import Ui_MicroPythonPage
@@ -80,8 +81,8 @@
         # set initial values
         # workspace
         self.workspacePicker.setText(
-            Utilities.toNativeSeparators(
-                Preferences.getMicroPython("MpyWorkspace") or Utilities.getHomeDir()
+            FileSystemUtilities.toNativeSeparators(
+                Preferences.getMicroPython("MpyWorkspace") or OSUtilities.getHomeDir()
             )
         )
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Preferences/ConfigurationPages/MultiProjectPage.py
--- a/src/eric7/Preferences/ConfigurationPages/MultiProjectPage.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Preferences/ConfigurationPages/MultiProjectPage.py	Sun Dec 18 19:33:46 2022 +0100
@@ -7,8 +7,9 @@
 Module implementing the Multi Project configuration page.
 """
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 
 from .ConfigurationPageBase import ConfigurationPageBase
 from .Ui_MultiProjectPage import Ui_MultiProjectPage
@@ -40,8 +41,8 @@
             Preferences.getMultiProject("RecentNumber")
         )
         self.workspacePicker.setText(
-            Utilities.toNativeSeparators(
-                Preferences.getMultiProject("Workspace") or Utilities.getHomeDir()
+            FileSystemUtilities.toNativeSeparators(
+                Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir()
             )
         )
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Preferences/ConfigurationPages/WebBrowserSpellCheckingPage.py
--- a/src/eric7/Preferences/ConfigurationPages/WebBrowserSpellCheckingPage.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Preferences/ConfigurationPages/WebBrowserSpellCheckingPage.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,7 +13,8 @@
 from PyQt6.QtCore import QCoreApplication, QDir, QLibraryInfo, QLocale, Qt, pyqtSlot
 from PyQt6.QtWidgets import QListWidgetItem
 
-from eric7 import Globals, Preferences
+from eric7 import Preferences
+from eric7.SystemUtilities import OSUtilities
 
 from .ConfigurationPageBase import ConfigurationPageBase
 from .Ui_WebBrowserSpellCheckingPage import Ui_WebBrowserSpellCheckingPage
@@ -40,7 +41,7 @@
         )
         self.on_spellCheckEnabledCheckBox_clicked()
 
-        if Globals.isMacPlatform():
+        if OSUtilities.isMacPlatform():
             self.__dictionaryDirectories = {
                 QDir.cleanPath(
                     QCoreApplication.applicationDirPath()
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Preferences/PreferencesLexer.py
--- a/src/eric7/Preferences/PreferencesLexer.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Preferences/PreferencesLexer.py	Sun Dec 18 19:33:46 2022 +0100
@@ -10,8 +10,9 @@
 from PyQt6.Qsci import QsciScintillaBase
 from PyQt6.QtCore import QCoreApplication, QObject
 
-from eric7 import Globals, Preferences
+from eric7 import Preferences
 from eric7.QScintilla import Lexers
+from eric7.SystemUtilities import OSUtilities
 
 
 class PreferencesLexerError(Exception):
@@ -83,9 +84,9 @@
         super().__init__(parent)
 
         # These default font families are taken from eric7.QScintilla
-        if Globals.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             self.__defaultFontFamily = "Courier New"
-        elif Globals.isMacPlatform():
+        elif OSUtilities.isMacPlatform():
             self.__defaultFontFamily = "Courier"
         else:
             self.__defaultFontFamily = "Bitstream Vera Sans Mono"
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Preferences/ProgramsDialog.py
--- a/src/eric7/Preferences/ProgramsDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Preferences/ProgramsDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -19,9 +19,15 @@
     QTreeWidgetItem,
 )
 
-from eric7 import Globals, Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui.EricOverrideCursor import EricOverrideCursor
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import (
+    FileSystemUtilities,
+    OSUtilities,
+    PythonUtilities,
+    QtUtilities,
+)
 
 from .Ui_ProgramsDialog import Ui_ProgramsDialog
 
@@ -92,54 +98,54 @@
             # 1. do the Qt programs
             # 1a. Translation Converter
             exe = (
-                Utilities.isWindowsPlatform()
-                and "{0}.exe".format(Utilities.generateQtToolName("lrelease"))
-                or Utilities.generateQtToolName("lrelease")
+                OSUtilities.isWindowsPlatform()
+                and "{0}.exe".format(QtUtilities.generateQtToolName("lrelease"))
+                or QtUtilities.generateQtToolName("lrelease")
             )
-            exe = os.path.join(Utilities.getQtBinariesPath(), exe)
+            exe = os.path.join(QtUtilities.getQtBinariesPath(), exe)
             version = self.__createProgramEntry(
                 self.tr("Translation Converter (Qt)"), exe, "-version", "lrelease", -1
             )
             # 1b. Qt Designer
-            if Utilities.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 exe = os.path.join(
-                    Utilities.getQtBinariesPath(),
-                    "{0}.exe".format(Utilities.generateQtToolName("designer")),
+                    QtUtilities.getQtBinariesPath(),
+                    "{0}.exe".format(QtUtilities.generateQtToolName("designer")),
                 )
-            elif Utilities.isMacPlatform():
-                exe = Utilities.getQtMacBundle("designer")
+            elif OSUtilities.isMacPlatform():
+                exe = QtUtilities.getQtMacBundle("designer")
             else:
                 exe = os.path.join(
-                    Utilities.getQtBinariesPath(),
-                    Utilities.generateQtToolName("designer"),
+                    QtUtilities.getQtBinariesPath(),
+                    QtUtilities.generateQtToolName("designer"),
                 )
             self.__createProgramEntry(self.tr("Qt Designer"), exe, version=version)
             # 1c. Qt Linguist
-            if Utilities.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 exe = os.path.join(
-                    Utilities.getQtBinariesPath(),
-                    "{0}.exe".format(Utilities.generateQtToolName("linguist")),
+                    QtUtilities.getQtBinariesPath(),
+                    "{0}.exe".format(QtUtilities.generateQtToolName("linguist")),
                 )
-            elif Utilities.isMacPlatform():
-                exe = Utilities.getQtMacBundle("linguist")
+            elif OSUtilities.isMacPlatform():
+                exe = QtUtilities.getQtMacBundle("linguist")
             else:
                 exe = os.path.join(
-                    Utilities.getQtBinariesPath(),
-                    Utilities.generateQtToolName("linguist"),
+                    QtUtilities.getQtBinariesPath(),
+                    QtUtilities.generateQtToolName("linguist"),
                 )
             self.__createProgramEntry(self.tr("Qt Linguist"), exe, version=version)
             # 1d. Qt Assistant
-            if Utilities.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 exe = os.path.join(
-                    Utilities.getQtBinariesPath(),
-                    "{0}.exe".format(Utilities.generateQtToolName("assistant")),
+                    QtUtilities.getQtBinariesPath(),
+                    "{0}.exe".format(QtUtilities.generateQtToolName("assistant")),
                 )
-            elif Utilities.isMacPlatform():
-                exe = Utilities.getQtMacBundle("assistant")
+            elif OSUtilities.isMacPlatform():
+                exe = QtUtilities.getQtMacBundle("assistant")
             else:
                 exe = os.path.join(
-                    Utilities.getQtBinariesPath(),
-                    Utilities.generateQtToolName("assistant"),
+                    QtUtilities.getQtBinariesPath(),
+                    QtUtilities.generateQtToolName("assistant"),
                 )
             self.__createProgramEntry(self.tr("Qt Assistant"), exe, version=version)
 
@@ -148,7 +154,7 @@
             # 2.1a. Translation Extractor PyQt5
             self.__createProgramEntry(
                 self.tr("Translation Extractor (Python, PyQt5)"),
-                Utilities.generatePyQtToolPath("pylupdate5"),
+                QtUtilities.generatePyQtToolPath("pylupdate5"),
                 "-version",
                 "pylupdate",
                 -1,
@@ -156,7 +162,7 @@
             # 2.1b. Forms Compiler PyQt5
             self.__createProgramEntry(
                 self.tr("Forms Compiler (Python, PyQt5)"),
-                Utilities.generatePyQtToolPath("pyuic5", ["py3uic5"]),
+                QtUtilities.generatePyQtToolPath("pyuic5", ["py3uic5"]),
                 "--version",
                 "Python User",
                 4,
@@ -164,7 +170,7 @@
             # 2.1c. Resource Compiler PyQt5
             self.__createProgramEntry(
                 self.tr("Resource Compiler (Python, PyQt5)"),
-                Utilities.generatePyQtToolPath("pyrcc5"),
+                QtUtilities.generatePyQtToolPath("pyrcc5"),
                 "-version",
                 "",
                 -1,
@@ -175,14 +181,14 @@
             # 2.2a. Translation Extractor PyQt6
             self.__createProgramEntry(
                 self.tr("Translation Extractor (Python, PyQt6)"),
-                Utilities.generatePyQtToolPath("pylupdate6"),
+                QtUtilities.generatePyQtToolPath("pylupdate6"),
                 "--version",
                 versionPosition=0,
             )
             # 2.2b. Forms Compiler PyQt6
             self.__createProgramEntry(
                 self.tr("Forms Compiler (Python, PyQt6)"),
-                Utilities.generatePyQtToolPath("pyuic6"),
+                QtUtilities.generatePyQtToolPath("pyuic6"),
                 "--version",
                 versionPosition=0,
             )
@@ -192,7 +198,7 @@
             # 3.1a. Translation Extractor PySide2
             self.__createProgramEntry(
                 self.tr("Translation Extractor (Python, PySide2)"),
-                Utilities.generatePySideToolPath("pyside2-lupdate", variant=2),
+                QtUtilities.generatePySideToolPath("pyside2-lupdate", variant=2),
                 "-version",
                 "",
                 -1,
@@ -201,7 +207,7 @@
             # 3.1b. Forms Compiler PySide2
             self.__createProgramEntry(
                 self.tr("Forms Compiler (Python, PySide2)"),
-                Utilities.generatePySideToolPath("pyside2-uic", variant=2),
+                QtUtilities.generatePySideToolPath("pyside2-uic", variant=2),
                 "--version",
                 "",
                 -1,
@@ -210,7 +216,7 @@
             # 3.1c Resource Compiler PySide2
             self.__createProgramEntry(
                 self.tr("Resource Compiler (Python, PySide2)"),
-                Utilities.generatePySideToolPath("pyside2-rcc", variant=2),
+                QtUtilities.generatePySideToolPath("pyside2-rcc", variant=2),
                 "-version",
                 "",
                 -1,
@@ -220,7 +226,7 @@
             # 3.2a. Translation Extractor PySide6
             self.__createProgramEntry(
                 self.tr("Translation Extractor (Python, PySide6)"),
-                Utilities.generatePySideToolPath("pyside6-lupdate", variant=6),
+                QtUtilities.generatePySideToolPath("pyside6-lupdate", variant=6),
                 "-version",
                 "",
                 -1,
@@ -229,7 +235,7 @@
             # 3.2b. Forms Compiler PySide6
             self.__createProgramEntry(
                 self.tr("Forms Compiler (Python, PySide6)"),
-                Utilities.generatePySideToolPath("pyside6-uic", variant=6),
+                QtUtilities.generatePySideToolPath("pyside6-uic", variant=6),
                 "--version",
                 "",
                 -1,
@@ -238,7 +244,7 @@
             # 3.2c Resource Compiler PySide6
             self.__createProgramEntry(
                 self.tr("Resource Compiler (Python, PySide6)"),
-                Utilities.generatePySideToolPath("pyside6-rcc", variant=6),
+                QtUtilities.generatePySideToolPath("pyside6-rcc", variant=6),
                 "--version",
                 "",
                 -1,
@@ -249,7 +255,7 @@
             exe = Preferences.getConda("CondaExecutable")
             if not exe:
                 exe = "conda"
-                if Utilities.isWindowsPlatform():
+                if OSUtilities.isWindowsPlatform():
                     exe += ".exe"
             self.__createProgramEntry(
                 self.tr("conda Manager"), exe, "--version", "conda", -1
@@ -315,7 +321,7 @@
             )
             self.__createProgramEntry(
                 self.tr("MicroPython - ESP Tool"),
-                Globals.getPythonExecutable(),
+                PythonUtilities.getPythonExecutable(),
                 "version",
                 "esptool",
                 -1,
@@ -423,10 +429,10 @@
             itm.setText(1, self.tr("(not configured)"))
         else:
             if os.path.isabs(exe):
-                if not Utilities.isExecutable(exe):
+                if not FileSystemUtilities.isExecutable(exe):
                     exe = ""
             else:
-                exe = Utilities.getExecutablePath(exe)
+                exe = FileSystemUtilities.getExecutablePath(exe)
             if exe:
                 available = True
                 if versionCommand and versionPosition is not None:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Preferences/ToolConfigurationDialog.py
--- a/src/eric7/Preferences/ToolConfigurationDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Preferences/ToolConfigurationDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -15,6 +15,7 @@
 from eric7 import Utilities
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_ToolConfigurationDialog import Ui_ToolConfigurationDialog
 
@@ -116,7 +117,7 @@
             )
             return
 
-        if not Utilities.isinpath(executable):
+        if not FileSystemUtilities.isinpath(executable):
             EricMessageBox.critical(
                 self,
                 self.tr("Add tool entry"),
@@ -184,7 +185,7 @@
             )
             return
 
-        if not Utilities.isinpath(executable):
+        if not FileSystemUtilities.isinpath(executable):
             EricMessageBox.critical(
                 self,
                 self.tr("Change tool entry"),
@@ -276,7 +277,7 @@
         @param path path of the executable
         @type str
         """
-        if path and not Utilities.isinpath(path):
+        if path and not FileSystemUtilities.isinpath(path):
             EricMessageBox.critical(
                 self,
                 self.tr("Select executable"),
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Preferences/__init__.py
--- a/src/eric7/Preferences/__init__.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Preferences/__init__.py	Sun Dec 18 19:33:46 2022 +0100
@@ -52,6 +52,7 @@
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricIconBar import EricIconBar
 from eric7.QScintilla.Shell import ShellHistoryStyle
+from eric7.SystemUtilities import OSUtilities, PythonUtilities, QtUtilities
 from eric7.Utilities.crypto import pwConvert
 from eric7.Utilities.crypto.py3PBKDF2 import hashPassword
 
@@ -723,7 +724,7 @@
         "YAMLFoldComment": False,
     }
 
-    if Globals.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         editorDefaults["EOLMode"] = QsciScintilla.EolMode.EolWindows
     else:
         editorDefaults["EOLMode"] = QsciScintilla.EolMode.EolUnix
@@ -1520,7 +1521,7 @@
         "HighlightChanges": True,
         "RecentNumber": 9,
     }
-    if Globals.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         hexEditorDefaults["Font"] = "Courier,10,-1,5,50,0,0,0,0,0"
     else:
         hexEditorDefaults["Font"] = "Monospace,10,-1,5,50,0,0,0,0,0"
@@ -1601,9 +1602,9 @@
             "https://github.com/calliope-mini/calliope-mini-micropython/"
         ),
     }
-    if Globals.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         microPythonDefaults["ColorScheme"] = "Windows 10"
-    elif Globals.isMacPlatform():
+    elif OSUtilities.isMacPlatform():
         microPythonDefaults["ColorScheme"] = "xterm"
     else:
         microPythonDefaults["ColorScheme"] = "Ubuntu"
@@ -1738,7 +1739,7 @@
         Globals.settingsNameGlobal,
         ericApp(),
     )
-    if not Globals.isWindowsPlatform():
+    if not OSUtilities.isWindowsPlatform():
         hp = QDir.homePath()
         dn = QDir(hp)
         dn.mkdir(".eric7")
@@ -1933,7 +1934,7 @@
         else:
             interpreter = ""
         if not interpreter:
-            return Globals.getPythonExecutable()
+            return PythonUtilities.getPythonExecutable()
         return interpreter
     elif key == "DebugClientType3":
         debugClientType = Prefs.settings.value(
@@ -3233,8 +3234,8 @@
     )
     if s == "":
         s = QLibraryInfo.path(QLibraryInfo.LibraryPath.TranslationsPath)
-    if s == "" and Globals.isWindowsPlatform():
-        transPath = os.path.join(Globals.getPyQt6ModulesDirectory(), "translations")
+    if s == "" and OSUtilities.isWindowsPlatform():
+        transPath = os.path.join(QtUtilities.getPyQt6ModulesDirectory(), "translations")
         if os.path.exists(transPath):
             s = transPath
     return s
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Project/CreateDialogCodeDialog.py
--- a/src/eric7/Project/CreateDialogCodeDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Project/CreateDialogCodeDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -23,10 +23,11 @@
 from PyQt6.QtGui import QBrush, QColor, QStandardItem, QStandardItemModel
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Globals, Preferences
+from eric7 import Preferences
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.Globals import getConfig
+from eric7.SystemUtilities import PythonUtilities
 from eric7.Utilities import ModuleParser
 
 from .NewDialogClassDialog import NewDialogClassDialog
@@ -185,7 +186,7 @@
         execPath = venvManager.getVirtualenvExecPath(venvName)
 
         if not interpreter:
-            interpreter = Globals.getPythonExecutable()
+            interpreter = PythonUtilities.getPythonExecutable()
 
         env = QProcessEnvironment.systemEnvironment()
         if execPath:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Project/Project.py
--- a/src/eric7/Project/Project.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Project/Project.py	Sun Dec 18 19:33:46 2022 +0100
@@ -33,7 +33,7 @@
 from PyQt6.QtGui import QAction, QKeySequence
 from PyQt6.QtWidgets import QDialog, QInputDialog, QLineEdit, QMenu, QToolBar
 
-from eric7 import Globals, Preferences, Utilities
+from eric7 import Preferences, Utilities
 from eric7.CodeFormatting.BlackFormattingAction import BlackFormattingAction
 from eric7.CodeFormatting.BlackUtilities import aboutBlack
 from eric7.CodeFormatting.IsortFormattingAction import IsortFormattingAction
@@ -52,6 +52,12 @@
 from eric7.EricXML.UserProjectReader import UserProjectReader
 from eric7.Globals import recentNameProject
 from eric7.Sessions.SessionFile import SessionFile
+from eric7.SystemUtilities import (
+    FileSystemUtilities,
+    OSUtilities,
+    PythonUtilities,
+    QtUtilities,
+)
 from eric7.Tasks.TasksFile import TasksFile
 from eric7.UI import Config
 from eric7.UI.NotificationWidget import NotificationTypes
@@ -347,12 +353,12 @@
             "JavaScript": ["Other"],
         }
 
-        if Utilities.checkPyside(variant=2):
+        if QtUtilities.checkPyside(variant=2):
             self.__projectTypes["PySide2"] = self.tr("PySide2 GUI")
             self.__projectTypes["PySide2C"] = self.tr("PySide2 Console")
             self.__projectProgLanguages["Python3"].extend(["PySide2", "PySide2C"])
 
-        if Utilities.checkPyside(variant=6):
+        if QtUtilities.checkPyside(variant=6):
             self.__projectTypes["PySide6"] = self.tr("PySide6 GUI")
             self.__projectTypes["PySide6C"] = self.tr("PySide6 Console")
             self.__projectProgLanguages["Python3"].extend(["PySide6", "PySide6C"])
@@ -1896,7 +1902,7 @@
             if target != "":
                 for fn in fnames:
                     targetfile = os.path.join(target, os.path.basename(fn))
-                    if not Utilities.samepath(os.path.dirname(fn), target):
+                    if not FileSystemUtilities.samepath(os.path.dirname(fn), target):
                         try:
                             if not os.path.isdir(target):
                                 os.makedirs(target)
@@ -1971,7 +1977,9 @@
                 )
             return
 
-        if not Utilities.samepath(target, source) and not os.path.isdir(target):
+        if not FileSystemUtilities.samepath(target, source) and not os.path.isdir(
+            target
+        ):
             try:
                 os.makedirs(target)
             except OSError as why:
@@ -1991,7 +1999,7 @@
                     continue
 
             targetfile = os.path.join(target, os.path.basename(file))
-            if not Utilities.samepath(target, source):
+            if not FileSystemUtilities.samepath(target, source):
                 try:
                     if os.path.exists(targetfile):
                         res = EricMessageBox.yesNo(
@@ -2149,7 +2157,7 @@
             )
             if not newfn:
                 return False
-            newfn = Utilities.toNativeSeparators(newfn)
+            newfn = FileSystemUtilities.toNativeSeparators(newfn)
 
         if os.path.exists(newfn):
             res = EricMessageBox.yesNo(
@@ -2830,7 +2838,7 @@
             # search the project directory for files with known extensions
             filespecs = list(self.__pdata["FILETYPES"].keys())
             for filespec in filespecs:
-                files = Utilities.direntries(self.ppath, True, filespec)
+                files = FileSystemUtilities.direntries(self.ppath, True, filespec)
                 for file in files:
                     self.appendFile(file)
 
@@ -2850,10 +2858,10 @@
                     tpd = self.__pdata["TRANSLATIONPATTERN"].split("%language%")[0]
             else:
                 pattern = "*.ts"
-            tslist.extend(Utilities.direntries(tpd, True, pattern))
+            tslist.extend(FileSystemUtilities.direntries(tpd, True, pattern))
             pattern = self.__binaryTranslationFile(pattern)
             if pattern:
-                tslist.extend(Utilities.direntries(tpd, True, pattern))
+                tslist.extend(FileSystemUtilities.direntries(tpd, True, pattern))
             if tslist:
                 if "_" in os.path.basename(tslist[0]):
                     # the first entry determines the mainscript name
@@ -2902,7 +2910,7 @@
                             self.__pdata["TRANSLATIONPATTERN"]
                         ).replace("%language%", "*")
                         pattern = self.__binaryTranslationFile(pattern)
-                        qmlist = Utilities.direntries(tpd, True, pattern)
+                        qmlist = FileSystemUtilities.direntries(tpd, True, pattern)
                         for qm in qmlist:
                             self.__pdata["TRANSLATIONS"].append(qm)
                             self.projectFileAdded.emit(qm, "TRANSLATIONS")
@@ -3116,7 +3124,7 @@
             fn = EricFileDialog.getOpenFileName(
                 self.parent(),
                 self.tr("Open project"),
-                Preferences.getMultiProject("Workspace") or Utilities.getHomeDir(),
+                Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir(),
                 self.tr("Project Files (*.epj);;XML Project Files (*.e4p)"),
             )
 
@@ -3312,7 +3320,7 @@
         defaultPath = (
             self.ppath
             if self.ppath
-            else (Preferences.getMultiProject("Workspace") or Utilities.getHomeDir())
+            else (Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir())
         )
         fn, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
             self.parent(),
@@ -3750,8 +3758,12 @@
         """
         return bool(self.ppath) and (
             path == self.ppath
-            or Utilities.normcasepath(Utilities.toNativeSeparators(path)).startswith(
-                Utilities.normcasepath(Utilities.toNativeSeparators(self.ppath + "/"))
+            or FileSystemUtilities.normcasepath(
+                FileSystemUtilities.toNativeSeparators(path)
+            ).startswith(
+                FileSystemUtilities.normcasepath(
+                    FileSystemUtilities.toNativeSeparators(self.ppath + "/")
+                )
             )
         )
 
@@ -3827,7 +3839,7 @@
         @return project relative path or unchanged path, if path doesn't
             belong to the project (string)
         """
-        return Utilities.fromNativeSeparators(self.getRelativePath(path))
+        return FileSystemUtilities.fromNativeSeparators(self.getRelativePath(path))
 
     def getAbsolutePath(self, fn):
         """
@@ -3850,7 +3862,7 @@
         @return absolute path (string)
         """
         if not os.path.isabs(fn):
-            fn = os.path.join(self.ppath, Utilities.toNativeSeparators(fn))
+            fn = os.path.join(self.ppath, FileSystemUtilities.toNativeSeparators(fn))
         return fn
 
     def getEolString(self):
@@ -3967,7 +3979,7 @@
                     .getVirtualenvInterpreter(venvName)
                 )
         if not interpreter and resolveGlobal:
-            interpreter = Globals.getPythonExecutable()
+            interpreter = PythonUtilities.getPythonExecutable()
 
         return interpreter
 
@@ -4062,7 +4074,7 @@
         ):
             return True
 
-        if Utilities.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             # try the above case-insensitive
             newfn = newfn.lower()
             if any(entry.lower() == newfn for entry in self.__pdata[group]):
@@ -5390,7 +5402,7 @@
         with the central store.
         """
         for recent in self.recent[:]:
-            if Utilities.samepath(self.pfile, recent):
+            if FileSystemUtilities.samepath(self.pfile, recent):
                 self.recent.remove(recent)
         self.recent.insert(0, self.pfile)
         maxRecent = Preferences.getProject("RecentNumber")
@@ -5410,7 +5422,7 @@
             formatStr = "&{0:d}. {1}" if idx < 10 else "{0:d}. {1}"
             act = self.recentMenu.addAction(
                 formatStr.format(
-                    idx, Utilities.compactPath(rp, self.ui.maxMenuFilePathLen)
+                    idx, FileSystemUtilities.compactPath(rp, self.ui.maxMenuFilePathLen)
                 )
             )
             act.setData(rp)
@@ -5520,7 +5532,7 @@
                 if ns.startswith("."):
                     continue
                 if (
-                    Utilities.isWindowsPlatform()
+                    OSUtilities.isWindowsPlatform()
                     and os.path.isdir(os.path.join(curpath, ns))
                     and ns.startswith("_")
                 ):
@@ -6139,7 +6151,9 @@
                 lst.extend(
                     [
                         self.getRelativePath(p)
-                        for p in Utilities.direntries(self.getAbsolutePath(entry), True)
+                        for p in FileSystemUtilities.direntries(
+                            self.getAbsolutePath(entry), True
+                        )
                     ]
                 )
                 continue
@@ -6163,7 +6177,9 @@
             with open(pkglist, "w", encoding="utf-8", newline=newline) as pkglistFile:
                 pkglistFile.write("\n".join(header) + "\n")
                 pkglistFile.write(
-                    "\n".join([Utilities.fromNativeSeparators(f) for f in lst])
+                    "\n".join(
+                        [FileSystemUtilities.fromNativeSeparators(f) for f in lst]
+                    )
                 )
                 pkglistFile.write("\n")
                 # ensure the file ends with an empty line
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Project/ProjectBrowserModel.py
--- a/src/eric7/Project/ProjectBrowserModel.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Project/ProjectBrowserModel.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,8 +14,9 @@
 from PyQt6.QtCore import QDir, QFileSystemWatcher, QModelIndex, Qt, pyqtSignal
 from PyQt6.QtGui import QColor
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
+from eric7.SystemUtilities import FileSystemUtilities
 from eric7.UI.BrowserModel import (
     BrowserDirectoryItem,
     BrowserFileItem,
@@ -365,14 +366,14 @@
                 node = (
                     ProjectBrowserDirectoryItem(
                         parentItem,
-                        Utilities.toNativeSeparators(f.absoluteFilePath()),
+                        FileSystemUtilities.toNativeSeparators(f.absoluteFilePath()),
                         parentItem.getProjectTypes()[0],
                         False,
                     )
                     if f.isDir()
                     else ProjectBrowserFileItem(
                         parentItem,
-                        Utilities.toNativeSeparators(f.absoluteFilePath()),
+                        FileSystemUtilities.toNativeSeparators(f.absoluteFilePath()),
                         parentItem.getProjectTypes()[0],
                     )
                 )
@@ -711,7 +712,7 @@
             # step 1: check for new entries
             children = itm.children()
             for f in entryInfoList:
-                fpath = Utilities.toNativeSeparators(f.absoluteFilePath())
+                fpath = FileSystemUtilities.toNativeSeparators(f.absoluteFilePath())
                 childFound = False
                 for child in children:
                     if child.name() == fpath:
@@ -726,14 +727,14 @@
                 node = (
                     ProjectBrowserDirectoryItem(
                         itm,
-                        Utilities.toNativeSeparators(f.absoluteFilePath()),
+                        FileSystemUtilities.toNativeSeparators(f.absoluteFilePath()),
                         itm.getProjectTypes()[0],
                         False,
                     )
                     if f.isDir()
                     else ProjectBrowserFileItem(
                         itm,
-                        Utilities.toNativeSeparators(f.absoluteFilePath()),
+                        FileSystemUtilities.toNativeSeparators(f.absoluteFilePath()),
                         itm.getProjectTypes()[0],
                     )
                 )
@@ -751,7 +752,7 @@
             if len(entryInfoList) != itm.childCount():
                 for row in range(oldCnt - 1, -1, -1):
                     child = itm.child(row)
-                    childname = Utilities.fromNativeSeparators(child.name())
+                    childname = FileSystemUtilities.fromNativeSeparators(child.name())
                     entryFound = False
                     for f in entryInfoList:
                         if f.absoluteFilePath() == childname:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Project/ProjectFile.py
--- a/src/eric7/Project/ProjectFile.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Project/ProjectFile.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,9 +14,10 @@
 
 from PyQt6.QtCore import QObject
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui.EricOverrideCursor import EricOverridenCursor
 from eric7.EricWidgets import EricMessageBox
+from eric7.SystemUtilities import FileSystemUtilities
 
 Project = typing.TypeVar("Project")
 
@@ -80,7 +81,7 @@
             with contextlib.suppress(KeyError):
                 projectDict["project"][key] = sorted(
                     [
-                        Utilities.fromNativeSeparators(f)
+                        FileSystemUtilities.fromNativeSeparators(f)
                         for f in projectDict["project"][key]
                     ]
                 )
@@ -93,7 +94,7 @@
             "MAINSCRIPT",
         ):
             with contextlib.suppress(KeyError):
-                projectDict["project"][key] = Utilities.fromNativeSeparators(
+                projectDict["project"][key] = FileSystemUtilities.fromNativeSeparators(
                     projectDict["project"][key]
                 )
 
@@ -143,7 +144,8 @@
         for key in self.__project.getFileCategories() + ["TRANSLATIONEXCEPTIONS"]:
             with contextlib.suppress(KeyError):
                 projectDict["project"][key] = [
-                    Utilities.toNativeSeparators(f) for f in projectDict["project"][key]
+                    FileSystemUtilities.toNativeSeparators(f)
+                    for f in projectDict["project"][key]
                 ]
         for key in (
             "SPELLWORDS",
@@ -154,7 +156,7 @@
             "MAINSCRIPT",
         ):
             with contextlib.suppress(KeyError):
-                projectDict["project"][key] = Utilities.toNativeSeparators(
+                projectDict["project"][key] = FileSystemUtilities.toNativeSeparators(
                     projectDict["project"][key]
                 )
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Project/ProjectFormsBrowser.py
--- a/src/eric7/Project/ProjectFormsBrowser.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Project/ProjectFormsBrowser.py	Sun Dec 18 19:33:46 2022 +0100
@@ -16,12 +16,13 @@
 from PyQt6.QtCore import QProcess, QThread, pyqtSignal
 from PyQt6.QtWidgets import QApplication, QDialog, QInputDialog, QMenu
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricProgressDialog import EricProgressDialog
 from eric7.Globals import getConfig
+from eric7.SystemUtilities import QtUtilities
 from eric7.UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
 from eric7.UI.NotificationWidget import NotificationTypes
 
@@ -756,17 +757,17 @@
 
         if self.project.getProjectLanguage() == "Python3":
             if self.project.getProjectType() in ["PyQt5"]:
-                self.__uicompiler = Utilities.generatePyQtToolPath(
+                self.__uicompiler = QtUtilities.generatePyQtToolPath(
                     "pyuic5", ["py3uic5"]
                 )
             elif self.project.getProjectType() in ["PyQt6", "E7Plugin"]:
-                self.__uicompiler = Utilities.generatePyQtToolPath("pyuic6")
+                self.__uicompiler = QtUtilities.generatePyQtToolPath("pyuic6")
             elif self.project.getProjectType() == "PySide2":
-                self.__uicompiler = Utilities.generatePySideToolPath(
+                self.__uicompiler = QtUtilities.generatePySideToolPath(
                     "pyside2-uic", variant=2
                 )
             elif self.project.getProjectType() == "PySide6":
-                self.__uicompiler = Utilities.generatePySideToolPath(
+                self.__uicompiler = QtUtilities.generatePySideToolPath(
                     "pyside6-uic", variant=6
                 )
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Project/ProjectResourcesBrowser.py
--- a/src/eric7/Project/ProjectResourcesBrowser.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Project/ProjectResourcesBrowser.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,11 +14,12 @@
 from PyQt6.QtCore import QProcess, QThread, pyqtSignal
 from PyQt6.QtWidgets import QApplication, QDialog, QMenu
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricProgressDialog import EricProgressDialog
+from eric7.SystemUtilities import QtUtilities
 from eric7.UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
 from eric7.UI.NotificationWidget import NotificationTypes
 
@@ -726,13 +727,13 @@
 
         if self.project.getProjectLanguage() == "Python3":
             if self.project.getProjectType() in ["PyQt5", "PyQt5C"]:
-                self.rccCompiler = Utilities.generatePyQtToolPath("pyrcc5")
+                self.rccCompiler = QtUtilities.generatePyQtToolPath("pyrcc5")
             elif self.project.getProjectType() in ["PySide2", "PySide2C"]:
-                self.rccCompiler = Utilities.generatePySideToolPath(
+                self.rccCompiler = QtUtilities.generatePySideToolPath(
                     "pyside2-rcc", variant=2
                 )
             elif self.project.getProjectType() in ["PySide6", "PySide6C"]:
-                self.rccCompiler = Utilities.generatePySideToolPath(
+                self.rccCompiler = QtUtilities.generatePySideToolPath(
                     "pyside6-rcc", variant=6
                 )
             else:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Project/ProjectTranslationsBrowser.py
--- a/src/eric7/Project/ProjectTranslationsBrowser.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Project/ProjectTranslationsBrowser.py	Sun Dec 18 19:33:46 2022 +0100
@@ -18,11 +18,12 @@
 from PyQt6.QtGui import QCursor, QGuiApplication
 from PyQt6.QtWidgets import QDialog, QMenu
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricGui.EricOverrideCursor import EricOverridenCursor
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import OSUtilities, QtUtilities
 from eric7.UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
 from eric7.UI.NotificationWidget import NotificationTypes
 
@@ -1198,15 +1199,15 @@
             return
 
         if self.project.getProjectType() in ["PyQt5", "PyQt5C"]:
-            self.pylupdate = Utilities.generatePyQtToolPath("pylupdate5")
+            self.pylupdate = QtUtilities.generatePyQtToolPath("pylupdate5")
         elif self.project.getProjectType() in ["PyQt6", "PyQt6C", "E7Plugin"]:
-            self.pylupdate = Utilities.generatePyQtToolPath("pylupdate6")
+            self.pylupdate = QtUtilities.generatePyQtToolPath("pylupdate6")
         elif self.project.getProjectType() in ["PySide2", "PySide2C"]:
-            self.pylupdate = Utilities.generatePySideToolPath(
+            self.pylupdate = QtUtilities.generatePySideToolPath(
                 "pyside2-lupdate", variant=2
             )
         elif self.project.getProjectType() in ["PySide6", "PySide6C"]:
-            self.pylupdate = Utilities.generatePySideToolPath(
+            self.pylupdate = QtUtilities.generatePySideToolPath(
                 "pyside6-lupdate", variant=6
             )
         else:
@@ -1469,11 +1470,12 @@
             "PySide6C",
         ]:
             lrelease = os.path.join(
-                Utilities.getQtBinariesPath(), Utilities.generateQtToolName("lrelease")
+                QtUtilities.getQtBinariesPath(),
+                QtUtilities.generateQtToolName("lrelease"),
             )
         else:
             return
-        if Utilities.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             lrelease += ".exe"
 
         if langs:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Project/ProjectVenvConfigurationDialog.py
--- a/src/eric7/Project/ProjectVenvConfigurationDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Project/ProjectVenvConfigurationDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,8 +14,8 @@
 from PyQt6.QtCore import pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Globals
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import OSUtilities
 
 from .Ui_ProjectVenvConfigurationDialog import Ui_ProjectVenvConfigurationDialog
 
@@ -70,7 +70,7 @@
 
         if venvDirectory:
             # try to determine a Python interpreter name
-            if Globals.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 candidates = glob.glob(
                     os.path.join(venvDirectory, "Scripts", "python*.exe")
                 ) + glob.glob(os.path.join(venvDirectory, "python*.exe"))
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Project/ProjectVenvCreationParametersDialog.py
--- a/src/eric7/Project/ProjectVenvCreationParametersDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Project/ProjectVenvCreationParametersDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -10,8 +10,8 @@
 
 from PyQt6.QtWidgets import QDialog
 
-from eric7 import Globals
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import PythonUtilities
 
 from .Ui_ProjectVenvCreationParametersDialog import (
     Ui_ProjectVenvCreationParametersDialog,
@@ -41,7 +41,7 @@
 
         self.pythonExecPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
         self.pythonExecPicker.setWindowTitle(self.tr("Python Interpreter"))
-        self.pythonExecPicker.setDefaultDirectory(Globals.getPythonExecutable())
+        self.pythonExecPicker.setDefaultDirectory(PythonUtilities.getPythonExecutable())
 
         self.systemCheckBox.setChecked(withSystemSitePackages)
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Project/PropertiesDialog.py
--- a/src/eric7/Project/PropertiesDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Project/PropertiesDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -15,11 +15,12 @@
 from PyQt6.QtCore import QDir, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
 from eric7.QScintilla.DocstringGenerator import getSupportedDocstringTypes
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 from eric7.Testing.Interfaces import FrameworkNames
 
 from .Ui_PropertiesDialog import Ui_PropertiesDialog
@@ -85,10 +86,10 @@
         for projectType in sorted(projectTypes):
             self.projectTypeComboBox.addItem(projectType[0], projectType[1])
 
-        ipath = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir()
+        ipath = Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir()
         self.__initPaths = [
-            Utilities.fromNativeSeparators(ipath),
-            Utilities.fromNativeSeparators(ipath) + "/",
+            FileSystemUtilities.fromNativeSeparators(ipath),
+            FileSystemUtilities.fromNativeSeparators(ipath) + "/",
         ]
 
         self.licenseComboBox.lineEdit().setClearButtonEnabled(True)
@@ -240,7 +241,8 @@
         @param txt name of the project directory (string)
         """
         self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
-            bool(txt) and Utilities.fromNativeSeparators(txt) not in self.__initPaths
+            bool(txt)
+            and FileSystemUtilities.fromNativeSeparators(txt) not in self.__initPaths
         )
 
     @pyqtSlot()
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Project/TranslationPropertiesDialog.py
--- a/src/eric7/Project/TranslationPropertiesDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Project/TranslationPropertiesDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,10 +12,10 @@
 from PyQt6.QtCore import pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QListWidgetItem
 
-from eric7 import Utilities
 from eric7.EricWidgets import EricFileDialog
 from eric7.EricWidgets.EricCompleters import EricFileCompleter
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_TranslationPropertiesDialog import Ui_TranslationPropertiesDialog
 
@@ -171,7 +171,7 @@
             self.filters,
         )
         if texcept:
-            self.exceptionEdit.setText(Utilities.toNativeSeparators(texcept))
+            self.exceptionEdit.setText(FileSystemUtilities.toNativeSeparators(texcept))
 
     @pyqtSlot()
     def on_exceptDirButton_clicked(self):
@@ -185,7 +185,7 @@
             EricFileDialog.ShowDirsOnly,
         )
         if texcept:
-            self.exceptionEdit.setText(Utilities.toNativeSeparators(texcept))
+            self.exceptionEdit.setText(FileSystemUtilities.toNativeSeparators(texcept))
 
     def on_exceptionsList_currentRowChanged(self, row):
         """
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/QScintilla/Editor.py
--- a/src/eric7/QScintilla/Editor.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/QScintilla/Editor.py	Sun Dec 18 19:33:46 2022 +0100
@@ -40,7 +40,7 @@
 )
 from PyQt6.QtWidgets import QApplication, QDialog, QInputDialog, QLineEdit, QMenu
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences, Utilities
 from eric7.CodeFormatting.BlackFormattingAction import BlackFormattingAction
 from eric7.CodeFormatting.BlackUtilities import aboutBlack
 from eric7.CodeFormatting.IsortFormattingAction import IsortFormattingAction
@@ -51,6 +51,7 @@
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.Globals import recentNameBreakpointConditions
+from eric7.SystemUtilities import OSUtilities, PythonUtilities
 from eric7.UI import PythonDisViewer
 from eric7.Utilities import MouseUtilities
 
@@ -1858,7 +1859,9 @@
                     language = Preferences.getEditorLexerAssoc(bindName)
             if language == "Python":
                 # correction for Python
-                pyVer = Utilities.determinePythonVersion(filename, self.text(0), self)
+                pyVer = PythonUtilities.determinePythonVersion(
+                    filename, self.text(0), self
+                )
                 language = "Python{0}".format(pyVer)
             if language in [
                 "Python3",
@@ -2164,7 +2167,7 @@
 
         @return Python version or 0 if it's not a Python file (int)
         """
-        return Utilities.determinePythonVersion(self.fileName, self.text(0), self)
+        return PythonUtilities.determinePythonVersion(self.fileName, self.text(0), self)
 
     def isPyFile(self):
         """
@@ -3416,7 +3419,7 @@
         if not path and self.fileName:
             path = os.path.dirname(self.fileName)
         if not path:
-            path = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir()
+            path = Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir()
 
         if self.fileName:
             filterPattern = "(*{0})".format(os.path.splitext(self.fileName)[1])
@@ -6911,7 +6914,7 @@
         """
         Public method to load a macro from a file.
         """
-        configDir = Utilities.getConfigDir()
+        configDir = Globals.getConfigDir()
         fname = EricFileDialog.getOpenFileName(
             self,
             self.tr("Load macro file"),
@@ -6950,7 +6953,7 @@
         """
         Public method to save a macro to a file.
         """
-        configDir = Utilities.getConfigDir()
+        configDir = Globals.getConfigDir()
 
         name, ok = self.__getMacroName()
         if not ok or not name:
@@ -8843,9 +8846,9 @@
             elif option == "DefaultEncoding":
                 value = config["charset"]
             elif option == "InsertFinalNewline":
-                value = Utilities.toBool(config["insert_final_newline"])
+                value = Globals.toBool(config["insert_final_newline"])
             elif option == "StripTrailingWhitespace":
-                value = Utilities.toBool(config["trim_trailing_whitespace"])
+                value = Globals.toBool(config["trim_trailing_whitespace"])
             elif option == "TabWidth":
                 value = int(config["tab_width"])
             elif option == "IndentWidth":
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/QScintilla/Lexers/LexerPygments.py
--- a/src/eric7/QScintilla/Lexers/LexerPygments.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/QScintilla/Lexers/LexerPygments.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,8 +14,8 @@
 from pygments.util import ClassNotFound
 from PyQt6.QtGui import QColor, QFont
 
-from eric7 import Utilities
 from eric7.QScintilla.Lexers.LexerContainer import LexerContainer
+from eric7.SystemUtilities import OSUtilities
 
 PYGMENTS_DEFAULT = 0
 PYGMENTS_COMMENT = 1
@@ -439,9 +439,9 @@
             PYGMENTS_PREPROCESSOR,
             PYGMENTS_MULTILINECOMMENT,
         ]:
-            if Utilities.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 f = QFont(["Comic Sans MS"], 9)
-            elif Utilities.isMacPlatform():
+            elif OSUtilities.isMacPlatform():
                 f = QFont(["Courier"], 11)
             else:
                 f = QFont(["Bitstream Vera Serif"], 9)
@@ -450,9 +450,9 @@
             return f
 
         if style in [PYGMENTS_STRING, PYGMENTS_CHAR]:
-            if Utilities.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 return QFont(["Comic Sans MS"], 10)
-            elif Utilities.isMacPlatform():
+            elif OSUtilities.isMacPlatform():
                 f = QFont(["Courier"], 11)
             else:
                 return QFont(["Bitstream Vera Serif"], 10)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/QScintilla/MiniEditor.py
--- a/src/eric7/QScintilla/MiniEditor.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/QScintilla/MiniEditor.py	Sun Dec 18 19:33:46 2022 +0100
@@ -44,7 +44,7 @@
     QWidget,
 )
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences, Utilities
 from eric7.EricGui import EricPixmapCache
 from eric7.EricGui.EricAction import EricAction, createActionGroup
 from eric7.EricGui.EricOverrideCursor import EricOverrideCursor
@@ -52,7 +52,7 @@
 from eric7.EricWidgets.EricClickableLabel import EricClickableLabel
 from eric7.EricWidgets.EricMainWindow import EricMainWindow
 from eric7.EricWidgets.EricZoomWidget import EricZoomWidget
-from eric7.Globals import isMacPlatform
+from eric7.SystemUtilities import OSUtilities
 from eric7.UI import Config
 
 from . import Lexers
@@ -901,7 +901,7 @@
             "vm_edit_move_left_char",
         )
         self.esm.setMapping(act, QsciScintilla.SCI_CHARLEFT)
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+B"))
             )
@@ -916,7 +916,7 @@
             self.editorActGrp,
             "vm_edit_move_right_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+F"))
             )
@@ -932,7 +932,7 @@
             self.editorActGrp,
             "vm_edit_move_up_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+P"))
             )
@@ -948,7 +948,7 @@
             self.editorActGrp,
             "vm_edit_move_down_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+N"))
             )
@@ -964,7 +964,7 @@
             self.editorActGrp,
             "vm_edit_move_left_word_part",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Alt+Left"))
             )
@@ -980,7 +980,7 @@
             self.editorActGrp,
             "vm_edit_move_right_word_part",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Alt+Right"))
             )
@@ -996,7 +996,7 @@
             self.editorActGrp,
             "vm_edit_move_left_word",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Alt+Left"))
             )
@@ -1016,7 +1016,7 @@
             self.editorActGrp,
             "vm_edit_move_right_word",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Alt+Right"))
             )
@@ -1040,7 +1040,7 @@
             self.editorActGrp,
             "vm_edit_move_first_visible_char",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Home"))
             )
@@ -1056,7 +1056,7 @@
             self.editorActGrp,
             "vm_edit_move_start_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Ctrl+Left"))
             )
@@ -1076,7 +1076,7 @@
             self.editorActGrp,
             "vm_edit_move_end_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+E"))
             )
@@ -1156,7 +1156,7 @@
             self.editorActGrp,
             "vm_edit_move_down_page",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+V"))
             )
@@ -1172,7 +1172,7 @@
             self.editorActGrp,
             "vm_edit_move_start_text",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Ctrl+Up"))
             )
@@ -1192,7 +1192,7 @@
             self.editorActGrp,
             "vm_edit_move_end_text",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Ctrl+Down"))
             )
@@ -1240,7 +1240,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_left_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+B"))
             )
@@ -1260,7 +1260,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_right_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+F"))
             )
@@ -1276,7 +1276,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_up_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+P"))
             )
@@ -1292,7 +1292,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_down_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+N"))
             )
@@ -1312,7 +1312,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_left_word_part",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Alt+Shift+Left")
@@ -1334,7 +1334,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_right_word_part",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Alt+Shift+Right")
@@ -1352,7 +1352,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_left_word",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Alt+Shift+Left")
@@ -1380,7 +1380,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_right_word",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Alt+Shift+Right")
@@ -1410,7 +1410,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_first_visible_char",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Shift+Home"))
             )
@@ -1430,7 +1430,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_end_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+E"))
             )
@@ -1494,7 +1494,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_down_page",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+V"))
             )
@@ -1514,7 +1514,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_start_text",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Ctrl+Shift+Up"))
             )
@@ -1540,7 +1540,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_end_text",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Ctrl+Shift+Down")
@@ -1564,7 +1564,7 @@
             self.editorActGrp,
             "vm_edit_delete_previous_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+H"))
             )
@@ -1602,7 +1602,7 @@
             self.editorActGrp,
             "vm_edit_delete_current_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+D"))
             )
@@ -1656,7 +1656,7 @@
             self.editorActGrp,
             "vm_edit_delete_line_right",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+K"))
             )
@@ -1810,7 +1810,7 @@
             self.editorActGrp,
             "vm_edit_move_end_displayed_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Ctrl+Right"))
             )
@@ -1834,7 +1834,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_end_displayed_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Ctrl+Shift+Right")
@@ -1880,7 +1880,7 @@
             self.editorActGrp,
             "vm_edit_extend_rect_selection_down_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Meta+Alt+Shift+N")
@@ -1902,7 +1902,7 @@
             self.editorActGrp,
             "vm_edit_extend_rect_selection_up_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Meta+Alt+Shift+P")
@@ -1924,7 +1924,7 @@
             self.editorActGrp,
             "vm_edit_extend_rect_selection_left_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Meta+Alt+Shift+B")
@@ -1946,7 +1946,7 @@
             self.editorActGrp,
             "vm_edit_extend_rect_selection_right_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Meta+Alt+Shift+F")
@@ -1972,7 +1972,7 @@
             self.editorActGrp,
             "vm_edit_extend_rect_selection_first_visible_char",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Alt+Shift+Home")
@@ -1994,7 +1994,7 @@
             self.editorActGrp,
             "vm_edit_extend_rect_selection_end_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Meta+Alt+Shift+E")
@@ -2036,7 +2036,7 @@
             self.editorActGrp,
             "vm_edit_extend_rect_selection_down_page",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Meta+Alt+Shift+V")
@@ -2071,7 +2071,7 @@
                 self.editorActGrp,
                 "vm_edit_scroll_start_text",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(QCoreApplication.translate("ViewManager", "Home"))
                 )
@@ -2088,7 +2088,7 @@
                 self.editorActGrp,
                 "vm_edit_scroll_end_text",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(QCoreApplication.translate("ViewManager", "End"))
                 )
@@ -2109,7 +2109,7 @@
                 self.editorActGrp,
                 "vm_edit_scroll_vertically_center",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(QCoreApplication.translate("ViewManager", "Meta+L"))
                 )
@@ -2126,7 +2126,7 @@
                 self.editorActGrp,
                 "vm_edit_move_end_next_word",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(QCoreApplication.translate("ViewManager", "Alt+Right"))
                 )
@@ -2147,7 +2147,7 @@
                 self.editorActGrp,
                 "vm_edit_select_end_next_word",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(
                         QCoreApplication.translate("ViewManager", "Alt+Shift+Right")
@@ -2204,7 +2204,7 @@
                 self.editorActGrp,
                 "vm_edit_move_start_document_line",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(QCoreApplication.translate("ViewManager", "Meta+A"))
                 )
@@ -2225,7 +2225,7 @@
                 self.editorActGrp,
                 "vm_edit_extend_selection_start_document_line",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(
                         QCoreApplication.translate("ViewManager", "Meta+Shift+A")
@@ -2250,7 +2250,7 @@
                 self.editorActGrp,
                 "vm_edit_select_rect_start_line",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(
                         QCoreApplication.translate("ViewManager", "Meta+Alt+Shift+A")
@@ -2273,7 +2273,7 @@
                 self.editorActGrp,
                 "vm_edit_extend_selection_start_display_line",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(
                         QCoreApplication.translate("ViewManager", "Ctrl+Shift+Left")
@@ -2470,7 +2470,7 @@
                 self.editorActGrp,
                 "vm_edit_delete_right_end_next_word",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(QCoreApplication.translate("ViewManager", "Alt+Del"))
                 )
@@ -4365,9 +4365,9 @@
             elif option == "DefaultEncoding":
                 value = config["charset"]
             elif option == "InsertFinalNewline":
-                value = Utilities.toBool(config["insert_final_newline"])
+                value = Globals.toBool(config["insert_final_newline"])
             elif option == "StripTrailingWhitespace":
-                value = Utilities.toBool(config["trim_trailing_whitespace"])
+                value = Globals.toBool(config["trim_trailing_whitespace"])
             elif option == "TabWidth":
                 value = int(config["tab_width"])
             elif option == "IndentWidth":
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/QScintilla/ShellWindow.py
--- a/src/eric7/QScintilla/ShellWindow.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/QScintilla/ShellWindow.py	Sun Dec 18 19:33:46 2022 +0100
@@ -22,7 +22,8 @@
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricMainWindow import EricMainWindow
 from eric7.EricWidgets.EricZoomWidget import EricZoomWidget
-from eric7.Globals import getConfig, getPythonExecutable, isMacPlatform
+from eric7.Globals import getConfig
+from eric7.SystemUtilities import OSUtilities, PythonUtilities
 from eric7.UI import Config
 from eric7.UI.SearchWidget import SearchWidget
 from eric7.VirtualEnv.VirtualenvManager import VirtualenvManager
@@ -474,7 +475,7 @@
             self.editorActGrp,
             "vm_edit_delete_previous_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+H"))
             )
@@ -496,7 +497,7 @@
             self.editorActGrp,
             "vm_edit_delete_current_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+D"))
             )
@@ -550,7 +551,7 @@
             self.editorActGrp,
             "vm_edit_delete_line_right",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+K"))
             )
@@ -573,7 +574,7 @@
             "vm_edit_move_left_char",
         )
         self.esm.setMapping(act, QsciScintilla.SCI_CHARLEFT)
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+B"))
             )
@@ -588,7 +589,7 @@
             self.editorActGrp,
             "vm_edit_move_right_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+F"))
             )
@@ -604,7 +605,7 @@
             self.editorActGrp,
             "vm_edit_move_left_word",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Alt+Left"))
             )
@@ -624,7 +625,7 @@
             self.editorActGrp,
             "vm_edit_move_right_word",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform()():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Ctrl+Right"))
             )
@@ -644,7 +645,7 @@
             self.editorActGrp,
             "vm_edit_move_first_visible_char",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform()():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Home"))
             )
@@ -660,7 +661,7 @@
             self.editorActGrp,
             "vm_edit_move_end_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+E"))
             )
@@ -680,7 +681,7 @@
             self.editorActGrp,
             "vm_edit_move_up_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+P"))
             )
@@ -696,7 +697,7 @@
             self.editorActGrp,
             "vm_edit_move_down_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+N"))
             )
@@ -748,7 +749,7 @@
             self.editorActGrp,
             "vm_edit_move_down_page",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+V"))
             )
@@ -780,7 +781,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_left_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+B"))
             )
@@ -800,7 +801,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_right_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+F"))
             )
@@ -816,7 +817,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_left_word",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Alt+Shift+Left")
@@ -844,7 +845,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_right_word",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Alt+Shift+Right")
@@ -874,7 +875,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_first_visible_char",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform()():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Shift+Home"))
             )
@@ -894,7 +895,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_end_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform()():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+E"))
             )
@@ -1257,7 +1258,7 @@
         """
         Private slot to start a new instance of eric.
         """
-        program = getPythonExecutable()
+        program = PythonUtilities.getPythonExecutable()
         eric7 = os.path.join(getConfig("ericDir"), "eric7_shell.py")
         args = [eric7]
         QProcess.startDetached(program, args)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/QScintilla/SpellChecker.py
--- a/src/eric7/QScintilla/SpellChecker.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/QScintilla/SpellChecker.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,7 +14,7 @@
 
 from PyQt6.QtCore import QObject, QTimer
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 
 with contextlib.suppress(ImportError, AttributeError, OSError):
     import enchant
@@ -91,9 +91,9 @@
             exception dictionary (string)
         """
         if isException:
-            return os.path.join(Utilities.getConfigDir(), "spelling", "pel.dic")
+            return os.path.join(Globals.getConfigDir(), "spelling", "pel.dic")
         else:
-            return os.path.join(Utilities.getConfigDir(), "spelling", "pwl.dic")
+            return os.path.join(Globals.getConfigDir(), "spelling", "pwl.dic")
 
     @classmethod
     def getUserDictionaryPath(cls, isException=False):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Snapshot/SnapWidget.py
--- a/src/eric7/Snapshot/SnapWidget.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Snapshot/SnapWidget.py	Sun Dec 18 19:33:46 2022 +0100
@@ -28,9 +28,10 @@
 from PyQt6.QtGui import QDrag, QImageWriter, QKeySequence, QPixmap, QShortcut
 from PyQt6.QtWidgets import QApplication, QWidget
 
-from eric7 import Globals, Preferences
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
+from eric7.SystemUtilities import DesktopUtilities
 
 from .SnapshotModes import SnapshotModes
 from .Ui_SnapWidget import Ui_SnapWidget
@@ -56,7 +57,7 @@
         self.copyPreviewButton.setIcon(EricPixmapCache.getIcon("editCopy"))
         self.setWindowIcon(EricPixmapCache.getIcon("ericSnap"))
 
-        if Globals.isWaylandSession():
+        if DesktopUtilities.isWaylandSession():
             from .SnapshotWaylandGrabber import (  # __IGNORE_WARNING_I101__
                 SnapshotWaylandGrabber,
             )
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Snapshot/SnapshotDefaultGrabber.py
--- a/src/eric7/Snapshot/SnapshotDefaultGrabber.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Snapshot/SnapshotDefaultGrabber.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,7 +11,7 @@
 from PyQt6.QtGui import QCursor, QGuiApplication, QPixmap
 from PyQt6.QtWidgets import QWidget
 
-from eric7 import Globals
+from eric7.SystemUtilities import OSUtilities
 
 from .SnapshotModes import SnapshotModes
 from .SnapshotTimer import SnapshotTimer
@@ -103,7 +103,7 @@
         elif self.__mode == SnapshotModes.FREEHAND:
             self.__grabFreehand()
         else:
-            if Globals.isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 self.__performGrab(self.__mode)
             else:
                 self.__grabberWidget.show()
@@ -156,7 +156,7 @@
         elif mode == SnapshotModes.SELECTEDSCREEN:
             screen = QGuiApplication.screenAt(QCursor.pos())
             sgeom = screen.geometry()
-            if Globals.isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 # macOS variant
                 snapshot = screen.grabWindow(
                     0, sgeom.x(), sgeom.y(), sgeom.width(), sgeom.height()
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Snapshot/SnapshotFreehandGrabber.py
--- a/src/eric7/Snapshot/SnapshotFreehandGrabber.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Snapshot/SnapshotFreehandGrabber.py	Sun Dec 18 19:33:46 2022 +0100
@@ -23,7 +23,7 @@
 )
 from PyQt6.QtWidgets import QToolTip, QWidget
 
-from eric7 import Globals
+from eric7.SystemUtilities import OSUtilities
 
 
 def drawPolygon(painter, polygon, outline, fill=None):
@@ -104,7 +104,7 @@
         """
         Private slot to initialize the rest of the widget.
         """
-        if Globals.isMacPlatform():
+        if OSUtilities.isMacPlatform():
             # macOS variant
             screen = QGuiApplication.screenAt(QCursor.pos())
             geom = screen.geometry()
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Snapshot/SnapshotRegionGrabber.py
--- a/src/eric7/Snapshot/SnapshotRegionGrabber.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Snapshot/SnapshotRegionGrabber.py	Sun Dec 18 19:33:46 2022 +0100
@@ -22,7 +22,7 @@
 )
 from PyQt6.QtWidgets import QToolTip, QWidget
 
-from eric7 import Globals
+from eric7.SystemUtilities import OSUtilities
 
 
 def drawRect(painter, rect, outline, fill=None):
@@ -134,7 +134,7 @@
         """
         Private slot to initialize the rest of the widget.
         """
-        if Globals.isMacPlatform():
+        if OSUtilities.isMacPlatform():
             # macOS variant
             screen = QGuiApplication.screenAt(QCursor.pos())
             geom = screen.geometry()
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Snapshot/SnapshotWaylandGrabber.py
--- a/src/eric7/Snapshot/SnapshotWaylandGrabber.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Snapshot/SnapshotWaylandGrabber.py	Sun Dec 18 19:33:46 2022 +0100
@@ -22,8 +22,8 @@
 except ImportError:
     DBusAvailable = False
 
-from eric7 import Globals
 from eric7.EricWidgets import EricMessageBox
+from eric7.SystemUtilities import DesktopUtilities
 
 from .SnapshotModes import SnapshotModes
 from .SnapshotTimer import SnapshotTimer
@@ -57,14 +57,14 @@
         @return tuple of supported screenshot modes
         @rtype tuple of SnapshotModes
         """
-        if DBusAvailable and Globals.isKdeDesktop():
+        if DBusAvailable and DesktopUtilities.isKdeDesktop():
             # __IGNORE_WARNING_Y114__
             return (
                 SnapshotModes.FULLSCREEN,
                 SnapshotModes.SELECTEDSCREEN,
                 SnapshotModes.SELECTEDWINDOW,
             )
-        elif DBusAvailable and Globals.isGnomeDesktop():
+        elif DBusAvailable and DesktopUtilities.isGnomeDesktop():
             return (
                 SnapshotModes.FULLSCREEN,
                 SnapshotModes.SELECTEDSCREEN,
@@ -130,7 +130,7 @@
         """
         snapshot = QPixmap()
 
-        if Globals.isKdeDesktop():
+        if DesktopUtilities.isKdeDesktop():
             interface = QDBusInterface(
                 "org.kde.KWin", "/Screenshot", "org.kde.kwin.Screenshot"
             )
@@ -141,7 +141,7 @@
                     snapshot = QPixmap(filename)
                     with contextlib.suppress(OSError):
                         os.remove(filename)
-        elif Globals.isGnomeDesktop():
+        elif DesktopUtilities.isGnomeDesktop():
             path = self.__temporaryFilename()
             interface = QDBusInterface(
                 "org.gnome.Shell",
@@ -164,7 +164,7 @@
         """
         snapshot = QPixmap()
 
-        if Globals.isKdeDesktop():
+        if DesktopUtilities.isKdeDesktop():
             screen = QApplication.screenAt(QCursor.pos())
             try:
                 screenId = QApplication.screens().index(screen)
@@ -183,7 +183,7 @@
                     snapshot = QPixmap(filename)
                     with contextlib.suppress(OSError):
                         os.remove(filename)
-        elif Globals.isGnomeDesktop():
+        elif DesktopUtilities.isGnomeDesktop():
             # Step 1: grab entire desktop
             path = self.__temporaryFilename()
             interface = QDBusInterface(
@@ -220,7 +220,7 @@
         """
         snapshot = QPixmap()
 
-        if Globals.isKdeDesktop():
+        if DesktopUtilities.isKdeDesktop():
             mask = 0
             if self.__captureDecorations:
                 mask |= 1
@@ -236,7 +236,7 @@
                     snapshot = QPixmap(filename)
                     with contextlib.suppress(OSError):
                         os.remove(filename)
-        elif Globals.isGnomeDesktop():
+        elif DesktopUtilities.isGnomeDesktop():
             path = self.__temporaryFilename()
             interface = QDBusInterface(
                 "org.gnome.Shell",
@@ -265,7 +265,7 @@
         """
         snapshot = QPixmap()
 
-        if Globals.isGnomeDesktop():
+        if DesktopUtilities.isGnomeDesktop():
             # Step 1: let the user select the area
             interface = QDBusInterface(
                 "org.gnome.Shell",
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/SystemUtilities/DesktopUtilities.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/SystemUtilities/DesktopUtilities.py	Sun Dec 18 19:33:46 2022 +0100
@@ -0,0 +1,126 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing Linux desktop related utility functions.
+"""
+
+import os
+
+from eric7.SystemUtilities import OSUtilities
+
+
+def desktopName():
+    """
+    Function to determine the name of the desktop environment used
+    (Linux only).
+
+    @return name of the desktop environment
+    @rtype str
+    """
+    if OSUtilities.isLinuxPlatform():
+        currDesktop = os.environ.get("XDG_CURRENT_DESKTOP", "")
+        if currDesktop:
+            return currDesktop
+
+        currDesktop = os.environ.get("XDG_SESSION_DESKTOP", "")
+        if currDesktop:
+            return currDesktop
+
+        currDesktop = os.environ.get("GDMSESSION", "")
+        if currDesktop:
+            return currDesktop
+
+        currDesktop = os.environ.get("GNOME_DESKTOP_SESSION_ID", "")
+        if currDesktop:
+            return currDesktop
+
+        currDesktop = os.environ.get("KDE_FULL_SESSION", "")
+        if currDesktop:
+            if currDesktop == "true":
+                return "KDE"
+
+            return currDesktop
+
+        currDesktop = os.environ.get("DESKTOP_SESSION", "")
+        if currDesktop:
+            return currDesktop
+
+    return ""
+
+
+def isKdeDesktop():
+    """
+    Function to check, if the current session is a KDE desktop (Linux only).
+
+    @return flag indicating a KDE desktop
+    @rtype bool
+    """
+    if OSUtilities.isLinuxPlatform():
+        desktop = (
+            os.environ.get("XDG_CURRENT_DESKTOP", "").lower()
+            or os.environ.get("XDG_SESSION_DESKTOP", "").lower()
+            or os.environ.get("DESKTOP_SESSION", "").lower()
+        )
+        return (
+            "kde" in desktop or "plasma" in desktop
+            if desktop
+            else bool(os.environ.get("KDE_FULL_SESSION", ""))
+        )
+
+    return False
+
+
+def isGnomeDesktop():
+    """
+    Function to check, if the current session is a Gnome desktop (Linux only).
+
+    @return flag indicating a Gnome desktop
+    @rtype bool
+    """
+    if OSUtilities.isLinuxPlatform():
+        desktop = (
+            os.environ.get("XDG_CURRENT_DESKTOP", "").lower()
+            or os.environ.get("XDG_SESSION_DESKTOP", "").lower()
+            or os.environ.get("GDMSESSION", "").lower()
+        )
+        return (
+            "gnome" in desktop
+            if desktop
+            else bool(os.environ.get("GNOME_DESKTOP_SESSION_ID", ""))
+        )
+
+    return False
+
+
+def sessionType():
+    """
+    Function to determine the name of the running session (Linux only).
+
+    @return name of the desktop environment
+    @rtype str
+    """
+    if OSUtilities.isLinuxPlatform():
+        sessionType = os.environ.get("XDG_SESSION_TYPE", "").lower()
+        if "x11" in sessionType:
+            return "X11"
+        elif "wayland" in sessionType:
+            return "Wayland"
+
+        sessionType = os.environ.get("WAYLAND_DISPLAY", "").lower()
+        if "wayland" in sessionType:
+            return "Wayland"
+
+    return ""
+
+
+def isWaylandSession():
+    """
+    Function to check, if the current session is a wayland session.
+
+    @return flag indicating a wayland session
+    @rtype bool
+    """
+    return sessionType() == "Wayland"
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/SystemUtilities/FileSystemUtilities.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/SystemUtilities/FileSystemUtilities.py	Sun Dec 18 19:33:46 2022 +0100
@@ -0,0 +1,612 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing file system related utility functions.
+"""
+
+import contextlib
+import ctypes
+import fnmatch
+import os
+import pathlib
+import subprocess
+
+from eric7.SystemUtilities import OSUtilities
+
+
+def toNativeSeparators(path):
+    """
+    Function returning a path, that is using native separator characters.
+
+    @param path path to be converted
+    @type str
+    @return path with converted separator characters
+    @rtype str
+    """
+    return str(pathlib.PurePath(path)) if bool(path) else ""
+
+
+def fromNativeSeparators(path):
+    """
+    Function returning a path, that is using "/" separator characters.
+
+    @param path path to be converted
+    @type str
+    @return path with converted separator characters
+    @rtype str
+    """
+    return pathlib.PurePath(path).as_posix() if bool(path) else ""
+
+
+def normcasepath(path):
+    """
+    Function returning a path, that is normalized with respect to its case
+    and references.
+
+    @param path file path (string)
+    @return case normalized path (string)
+    """
+    return os.path.normcase(os.path.normpath(path))
+
+
+def normcaseabspath(path):
+    """
+    Function returning an absolute path, that is normalized with respect to
+    its case and references.
+
+    @param path file path (string)
+    @return absolute, normalized path (string)
+    """
+    return os.path.normcase(os.path.abspath(path))
+
+
+def normjoinpath(a, *p):
+    """
+    Function returning a normalized path of the joined parts passed into it.
+
+    @param a first path to be joined (string)
+    @param p variable number of path parts to be joined (string)
+    @return normalized path (string)
+    """
+    return os.path.normpath(os.path.join(a, *p))
+
+
+def normabsjoinpath(a, *p):
+    """
+    Function returning a normalized, absolute path of the joined parts passed
+    into it.
+
+    @param a first path to be joined (string)
+    @param p variable number of path parts to be joind (string)
+    @return absolute, normalized path (string)
+    """
+    return os.path.abspath(os.path.join(a, *p))
+
+
+def isinpath(file):
+    """
+    Function to check for an executable file.
+
+    @param file filename of the executable to check (string)
+    @return flag to indicate, if the executable file is accessible
+        via the searchpath defined by the PATH environment variable.
+    """
+    if os.path.isabs(file):
+        return os.access(file, os.X_OK)
+
+    if os.path.exists(os.path.join(os.curdir, file)):
+        return os.access(os.path.join(os.curdir, file), os.X_OK)
+
+    path = OSUtilities.getEnvironmentEntry("PATH")
+
+    # environment variable not defined
+    if path is None:
+        return False
+
+    dirs = path.split(os.pathsep)
+    return any(os.access(os.path.join(directory, file), os.X_OK) for directory in dirs)
+
+
+def startswithPath(path, start):
+    """
+    Function to check, if a path starts with a given start path.
+
+    @param path path to be checked
+    @type str
+    @param start start path
+    @type str
+    @return flag indicating that the path starts with the given start
+        path
+    @rtype bool
+    """
+    return bool(start) and (
+        path == start or normcasepath(path).startswith(normcasepath(start + "/"))
+    )
+
+
+def relativeUniversalPath(path, start):
+    """
+    Function to convert a file path to a path relative to a start path
+    with universal separators.
+
+    @param path file or directory name to convert (string)
+    @param start start path (string)
+    @return relative path or unchanged path, if path does not start with
+        the start path with universal separators (string)
+    """
+    return fromNativeSeparators(os.path.relpath(path, start))
+
+
+def absolutePath(path, start):
+    """
+    Public method to convert a path relative to a start path to an
+    absolute path.
+
+    @param path file or directory name to convert (string)
+    @param start start path (string)
+    @return absolute path (string)
+    """
+    if not os.path.isabs(path):
+        path = os.path.normpath(os.path.join(start, path))
+    return path
+
+
+def absoluteUniversalPath(path, start):
+    """
+    Public method to convert a path relative to a start path with
+    universal separators to an absolute path.
+
+    @param path file or directory name to convert (string)
+    @param start start path (string)
+    @return absolute path with native separators (string)
+    """
+    if not os.path.isabs(path):
+        path = toNativeSeparators(os.path.normpath(os.path.join(start, path)))
+    return path
+
+
+def getExecutablePath(file):
+    """
+    Function to build the full path of an executable file from the environment.
+
+    @param file filename of the executable to check (string)
+    @return full executable name, if the executable file is accessible
+        via the searchpath defined by the PATH environment variable, or an
+        empty string otherwise.
+    """
+    if os.path.isabs(file):
+        if os.access(file, os.X_OK):
+            return file
+        else:
+            return ""
+
+    cur_path = os.path.join(os.curdir, file)
+    if os.path.exists(cur_path) and os.access(cur_path, os.X_OK):
+        return cur_path
+
+    path = os.getenv("PATH")
+
+    # environment variable not defined
+    if path is None:
+        return ""
+
+    dirs = path.split(os.pathsep)
+    for directory in dirs:
+        exe = os.path.join(directory, file)
+        if os.access(exe, os.X_OK):
+            return exe
+
+    return ""
+
+
+def getExecutablePaths(file):
+    """
+    Function to build all full path of an executable file from the environment.
+
+    @param file filename of the executable (string)
+    @return list of full executable names (list of strings), if the executable
+        file is accessible via the searchpath defined by the PATH environment
+        variable, or an empty list otherwise.
+    """
+    paths = []
+
+    if os.path.isabs(file):
+        if os.access(file, os.X_OK):
+            return [file]
+        else:
+            return []
+
+    cur_path = os.path.join(os.curdir, file)
+    if os.path.exists(cur_path) and os.access(cur_path, os.X_OK):
+        paths.append(cur_path)
+
+    path = os.getenv("PATH")
+
+    # environment variable not defined
+    if path is not None:
+        dirs = path.split(os.pathsep)
+        for directory in dirs:
+            exe = os.path.join(directory, file)
+            if os.access(exe, os.X_OK) and exe not in paths:
+                paths.append(exe)
+
+    return paths
+
+
+def getWindowsExecutablePath(file):
+    """
+    Function to build the full path of an executable file from the environment
+    on Windows platforms.
+
+    First an executable with the extension .exe is searched for, thereafter
+    such with the extensions .cmd or .bat and finally the given file name as
+    is. The first match is returned.
+
+    @param file filename of the executable to check (string)
+    @return full executable name, if the executable file is accessible
+        via the searchpath defined by the PATH environment variable, or an
+        empty string otherwise.
+    """
+    if os.path.isabs(file):
+        if os.access(file, os.X_OK):
+            return file
+        else:
+            return ""
+
+    filenames = [file + ".exe", file + ".cmd", file + ".bat", file]
+
+    for filename in filenames:
+        cur_path = os.path.join(os.curdir, filename)
+        if os.path.exists(cur_path) and os.access(cur_path, os.X_OK):
+            return os.path.abspath(cur_path)
+
+    path = os.getenv("PATH")
+
+    # environment variable not defined
+    if path is None:
+        return ""
+
+    dirs = path.split(os.pathsep)
+    for directory in dirs:
+        for filename in filenames:
+            exe = os.path.join(directory, filename)
+            if os.access(exe, os.X_OK):
+                return exe
+
+    return ""
+
+
+def isExecutable(exe):
+    """
+    Function to check, if a file is executable.
+
+    @param exe filename of the executable to check (string)
+    @return flag indicating executable status (boolean)
+    """
+    return os.access(exe, os.X_OK)
+
+
+def isDrive(path):
+    """
+    Function to check, if a path is a Windows drive.
+
+    @param path path name to be checked
+    @type str
+    @return flag indicating a Windows drive
+    @rtype bool
+    """
+    isWindowsDrive = False
+    drive, directory = os.path.splitdrive(path)
+    if (
+        drive
+        and len(drive) == 2
+        and drive.endswith(":")
+        and directory in ["", "\\", "/"]
+    ):
+        isWindowsDrive = True
+
+    return isWindowsDrive
+
+
+def samepath(f1, f2):
+    """
+    Function to compare two paths.
+
+    @param f1 first path for the compare (string)
+    @param f2 second path for the compare (string)
+    @return flag indicating whether the two paths represent the
+        same path on disk.
+    """
+    if f1 is None or f2 is None:
+        return False
+
+    if normcaseabspath(os.path.realpath(f1)) == normcaseabspath(os.path.realpath(f2)):
+        return True
+
+    return False
+
+
+def samefilepath(f1, f2):
+    """
+    Function to compare two paths. Strips the filename.
+
+    @param f1 first filepath for the compare (string)
+    @param f2 second filepath for the compare (string)
+    @return flag indicating whether the two paths represent the
+        same path on disk.
+    """
+    if f1 is None or f2 is None:
+        return False
+
+    if normcaseabspath(os.path.dirname(os.path.realpath(f1))) == normcaseabspath(
+        os.path.dirname(os.path.realpath(f2))
+    ):
+        return True
+
+    return False
+
+
+try:
+    EXTSEP = os.extsep
+except AttributeError:
+    EXTSEP = "."
+
+
+def splitPath(name):
+    """
+    Function to split a pathname into a directory part and a file part.
+
+    @param name path name (string)
+    @return a tuple of 2 strings (dirname, filename).
+    """
+    if os.path.isdir(name):
+        dn = os.path.abspath(name)
+        fn = "."
+    else:
+        dn, fn = os.path.split(name)
+    return (dn, fn)
+
+
+def joinext(prefix, ext):
+    """
+    Function to join a file extension to a path.
+
+    The leading "." of ext is replaced by a platform specific extension
+    separator if necessary.
+
+    @param prefix the basepart of the filename (string)
+    @param ext the extension part (string)
+    @return the complete filename (string)
+    """
+    if ext[0] != ".":
+        ext = ".{0}".format(ext)
+        # require leading separator to match os.path.splitext
+    return prefix + EXTSEP + ext[1:]
+
+
+def compactPath(path, width, measure=len):
+    """
+    Function to return a compacted path fitting inside the given width.
+
+    @param path path to be compacted (string)
+    @param width width for the compacted path (integer)
+    @param measure reference to a function used to measure the length of the
+        string
+    @return compacted path (string)
+    """
+    if measure(path) <= width:
+        return path
+
+    ellipsis = "..."
+
+    head, tail = os.path.split(path)
+    mid = len(head) // 2
+    head1 = head[:mid]
+    head2 = head[mid:]
+    while head1:
+        # head1 is same size as head2 or one shorter
+        path = os.path.join("{0}{1}{2}".format(head1, ellipsis, head2), tail)
+        if measure(path) <= width:
+            return path
+        head1 = head1[:-1]
+        head2 = head2[1:]
+    path = os.path.join(ellipsis, tail)
+    if measure(path) <= width:
+        return path
+    while tail:
+        path = "{0}{1}".format(ellipsis, tail)
+        if measure(path) <= width:
+            return path
+        tail = tail[1:]
+    return ""
+
+
+def direntries(
+    path, filesonly=False, pattern=None, followsymlinks=True, checkStop=None
+):
+    """
+    Function returning a list of all files and directories.
+
+    @param path root of the tree to check
+    @type str
+    @param filesonly flag indicating that only files are wanted
+    @type bool
+    @param pattern a filename pattern or list of filename patterns to check
+        against
+    @type str or list of str
+    @param followsymlinks flag indicating whether symbolic links
+        should be followed
+    @type bool
+    @param checkStop function to be called to check for a stop
+    @type function
+    @return list of all files and directories in the tree rooted
+        at path. The names are expanded to start with path.
+    @rtype list of strs
+    """
+    patterns = pattern if isinstance(pattern, list) else [pattern]
+    files = [] if filesonly else [path]
+    try:
+        entries = os.listdir(path)
+        for entry in entries:
+            if checkStop and checkStop():
+                break
+
+            if entry in [
+                ".svn",
+                ".hg",
+                ".git",
+                ".ropeproject",
+                ".eric7project",
+                ".jedi",
+            ]:
+                continue
+
+            fentry = os.path.join(path, entry)
+            if (
+                pattern
+                and not os.path.isdir(fentry)
+                and not any(fnmatch.fnmatch(entry, p) for p in patterns)
+            ):
+                # entry doesn't fit the given pattern
+                continue
+
+            if os.path.isdir(fentry):
+                if os.path.islink(fentry) and not followsymlinks:
+                    continue
+                files += direntries(
+                    fentry, filesonly, pattern, followsymlinks, checkStop
+                )
+            else:
+                files.append(fentry)
+    except OSError:
+        pass
+    except UnicodeDecodeError:
+        pass
+    return files
+
+
+def getDirs(path, excludeDirs):
+    """
+    Function returning a list of all directories below path.
+
+    @param path root of the tree to check
+    @param excludeDirs basename of directories to ignore
+    @return list of all directories found
+    """
+    try:
+        names = os.listdir(path)
+    except OSError:
+        return []
+
+    dirs = []
+    for name in names:
+        if os.path.isdir(os.path.join(path, name)) and not os.path.islink(
+            os.path.join(path, name)
+        ):
+            exclude = 0
+            for e in excludeDirs:
+                if name.split(os.sep, 1)[0] == e:
+                    exclude = 1
+                    break
+            if not exclude:
+                dirs.append(os.path.join(path, name))
+
+    for name in dirs[:]:
+        if not os.path.islink(name):
+            dirs += getDirs(name, excludeDirs)
+
+    return dirs
+
+
+def findVolume(volumeName, findAll=False):
+    """
+    Function to find the directory belonging to a given volume name.
+
+    @param volumeName name of the volume to search for
+    @type str
+    @param findAll flag indicating to get the directories for all volumes
+        starting with the given name (defaults to False)
+    @type bool (optional)
+    @return directory path or list of directory paths for the given volume
+        name
+    @rtype str or list of str
+    """
+    volumeDirectories = []
+    volumeDirectory = None
+
+    if OSUtilities.isWindowsPlatform():
+        # we are on a Windows platform
+        def getVolumeName(diskName):
+            """
+            Local function to determine the volume of a disk or device.
+
+            Each disk or external device connected to windows has an
+            attribute called "volume name". This function returns the
+            volume name for the given disk/device.
+
+            Code from http://stackoverflow.com/a/12056414
+            """
+            volumeNameBuffer = ctypes.create_unicode_buffer(1024)
+            ctypes.windll.kernel32.GetVolumeInformationW(
+                ctypes.c_wchar_p(diskName),
+                volumeNameBuffer,
+                ctypes.sizeof(volumeNameBuffer),
+                None,
+                None,
+                None,
+                None,
+                0,
+            )
+            return volumeNameBuffer.value
+
+        #
+        # In certain circumstances, volumes are allocated to USB
+        # storage devices which cause a Windows popup to raise if their
+        # volume contains no media. Wrapping the check in SetErrorMode
+        # with SEM_FAILCRITICALERRORS (1) prevents this popup.
+        #
+        oldMode = ctypes.windll.kernel32.SetErrorMode(1)
+        try:
+            for disk in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
+                dirpath = "{0}:\\".format(disk)
+                if os.path.exists(dirpath):
+                    if findAll:
+                        if getVolumeName(dirpath).startswith(volumeName):
+                            volumeDirectories.append(dirpath)
+                    else:
+                        if getVolumeName(dirpath) == volumeName:
+                            volumeDirectory = dirpath
+                            break
+        finally:
+            ctypes.windll.kernel32.SetErrorMode(oldMode)
+    else:
+        # we are on a Linux or macOS platform
+        for mountCommand in ["mount", "/sbin/mount", "/usr/sbin/mount"]:
+            with contextlib.suppress(FileNotFoundError):
+                mountOutput = subprocess.run(  # secok
+                    mountCommand, check=True, capture_output=True, text=True
+                ).stdout.splitlines()
+                mountedVolumes = [
+                    x.split(" type")[0].split(maxsplit=2)[2] for x in mountOutput
+                ]
+                if findAll:
+                    for volume in mountedVolumes:
+                        if volumeName in volume:
+                            volumeDirectories.append(volume)
+                    if volumeDirectories:
+                        break
+                else:
+                    for volume in mountedVolumes:
+                        if volume.endswith(volumeName):
+                            volumeDirectory = volume
+                            break
+                    if volumeDirectory:
+                        break
+
+    if findAll:
+        return volumeDirectories
+    else:
+        return volumeDirectory
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/SystemUtilities/OSUtilities.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/SystemUtilities/OSUtilities.py	Sun Dec 18 19:33:46 2022 +0100
@@ -0,0 +1,189 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing Operating System related utility functions.
+"""
+
+import contextlib
+import ctypes
+import getpass
+import os
+import sys
+
+with contextlib.suppress(ImportError):
+    import pwd  # only available on Unix systems
+
+
+###############################################################################
+## functions for platform handling
+###############################################################################
+
+
+def isWindowsPlatform():
+    """
+    Function to check, if this is a Windows platform.
+
+    @return flag indicating Windows platform
+    @rtype bool
+    """
+    return sys.platform.startswith(("win", "cygwin"))
+
+
+def isMacPlatform():
+    """
+    Function to check, if this is a Mac platform.
+
+    @return flag indicating Mac platform
+    @rtype bool
+    """
+    return sys.platform == "darwin"
+
+
+def isLinuxPlatform():
+    """
+    Function to check, if this is a Linux platform.
+
+    @return flag indicating Linux platform
+    @rtype bool
+    """
+    return sys.platform.startswith("linux")
+
+
+###############################################################################
+## functions for user handling
+###############################################################################
+
+
+def getUserName():
+    """
+    Function to get the user name.
+
+    @return user name (string)
+    """
+    user = getpass.getuser()
+
+    if isWindowsPlatform() and not user:
+        return win32_GetUserName()
+
+    return user
+
+
+def getRealName():
+    """
+    Function to get the real name of the user.
+
+    @return real name of the user (string)
+    """
+    if isWindowsPlatform():
+        return win32_getRealName()
+    else:
+        user = getpass.getuser()
+        return pwd.getpwnam(user).pw_gecos
+
+
+def getHomeDir():
+    """
+    Function to get a users home directory.
+
+    @return home directory (string)
+    """
+    return os.path.expanduser("~")
+
+
+###############################################################################
+## functions for environment handling
+###############################################################################
+
+
+def getEnvironmentEntry(key, default=None):
+    """
+    Module function to get an environment entry.
+
+    @param key key of the requested environment entry (string)
+    @param default value to be returned, if the environment doesn't contain
+        the requested entry (string)
+    @return the requested entry or the default value, if the entry wasn't
+        found (string or None)
+    """
+    if key in os.environ:
+        entryKey = key
+    elif isWindowsPlatform() and key.lower() in os.environ:
+        entryKey = key.lower()
+    else:
+        return default
+
+    return os.environ[entryKey].strip()
+
+
+def hasEnvironmentEntry(key):
+    """
+    Module function to check, if the environment contains an entry.
+
+    @param key key of the requested environment entry
+    @type str
+    @return flag indicating the presence of the requested entry
+    @rtype bool
+    """
+    return key in os.environ or (isWindowsPlatform() and key.lower() in os.environ)
+
+
+###############################################################################
+## posix compatibility functions below
+###############################################################################
+
+# None right now
+
+###############################################################################
+## win32 compatibility functions below
+###############################################################################
+
+
+def win32_Kill(pid):
+    """
+    Function to provide an os.kill equivalent for Win32.
+
+    @param pid process id (integer)
+    @return result of the kill (boolean)
+    """
+    import win32api  # __IGNORE_WARNING_I102__
+
+    handle = win32api.OpenProcess(1, 0, pid)
+    return 0 != win32api.TerminateProcess(handle, 0)
+
+
+def win32_GetUserName():
+    """
+    Function to get the user name under Win32.
+
+    @return user name (string)
+    """
+    try:
+        import win32api  # __IGNORE_WARNING_I10__
+
+        return win32api.GetUserName()
+    except ImportError:
+        try:
+            u = getEnvironmentEntry("USERNAME")
+        except KeyError:
+            u = getEnvironmentEntry("username", None)
+        return u
+
+
+def win32_getRealName():
+    """
+    Function to get the user's real name (aka. display name) under Win32.
+
+    @return real name of the current user (string)
+    """
+    GetUserNameEx = ctypes.windll.secur32.GetUserNameExW
+    NameDisplay = 3
+
+    size = ctypes.pointer(ctypes.c_ulong(0))
+    GetUserNameEx(NameDisplay, None, size)
+
+    nameBuffer = ctypes.create_unicode_buffer(size.contents.value)
+    GetUserNameEx(NameDisplay, nameBuffer, size)
+    return nameBuffer.value
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/SystemUtilities/PySideImporter.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/SystemUtilities/PySideImporter.py	Sun Dec 18 19:33:46 2022 +0100
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2011 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module to check for the presence of PySide2/PySide6 by importing it.
+"""
+
+import sys
+
+if __name__ == "__main__":
+    pySideVariant = "2"
+    if len(sys.argv) == 2:
+        pySideVariant = sys.argv[1].replace("--variant=", "")
+
+    if pySideVariant == "1":
+        # no PySide support anymore
+        ret = 1
+
+    elif pySideVariant == "2":
+        try:
+            import PySide2  # __IGNORE_EXCEPTION__ __IGNORE_WARNING__
+
+            ret = 0
+        except ImportError:
+            ret = 1
+
+    elif pySideVariant == "6":
+        try:
+            import PySide6  # __IGNORE_EXCEPTION__ __IGNORE_WARNING__
+
+            ret = 0
+        except ImportError:
+            ret = 1
+
+    else:
+        ret = 1
+
+    sys.exit(ret)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/SystemUtilities/PythonUtilities.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/SystemUtilities/PythonUtilities.py	Sun Dec 18 19:33:46 2022 +0100
@@ -0,0 +1,137 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing Python related utility functions.
+"""
+
+import os
+import sys
+import sysconfig
+
+
+def getPythonExecutable():
+    """
+    Function to determine the path of the (non-windowed) Python executable.
+
+    @return path of the Python executable
+    @rtype str
+    """
+    if sys.platform.startswith("linux"):
+        return sys.executable
+    elif sys.platform == "darwin":
+        return sys.executable.replace("pythonw", "python")
+    else:
+        return sys.executable.replace("pythonw.exe", "python.exe")
+
+
+def getPythonLibraryDirectory():
+    """
+    Function to determine the path to Python's library directory.
+
+    @return path to the Python library directory
+    @rtype str
+    """
+    return sysconfig.get_path("platlib")
+
+
+def getPythonScriptsDirectory():
+    """
+    Function to determine the path to Python's scripts directory.
+
+    @return path to the Python scripts directory
+    @rtype str
+    """
+    return sysconfig.get_path("scripts")
+
+
+def getPythonLibPath():
+    """
+    Function to determine the path to Python's library.
+
+    @return path to the Python library (string)
+    """
+    return sysconfig.get_path("platstdlib")
+
+
+def getPythonVersion():
+    """
+    Function to get the Python version (major, minor) as an integer value.
+
+    @return An integer representing major and minor version number (integer)
+    """
+    return sys.hexversion >> 16
+
+
+def determinePythonVersion(filename, source, editor=None):
+    """
+    Function to determine the python version of a given file.
+
+    @param filename name of the file with extension (str)
+    @param source of the file (str)
+    @param editor reference to the editor, if the file is opened
+        already (Editor object)
+    @return Python version if file is Python3 (int)
+    """
+    from eric7 import Preferences, Utilities
+    from eric7.EricWidgets.EricApplication import ericApp
+
+    pyAssignment = {
+        "Python3": 3,
+        "MicroPython": 3,
+        "Cython": 3,
+    }
+
+    if not editor:
+        viewManager = ericApp().getObject("ViewManager")
+        editor = viewManager.getOpenEditor(filename)
+
+    # Maybe the user has changed the language
+    if editor and editor.getFileType() in pyAssignment:
+        return pyAssignment[editor.getFileType()]
+
+    pyVer = 0
+    if filename:
+        if not source:
+            source = Utilities.readEncodedFile(filename)[0]
+        flags = Utilities.extractFlags(source)
+        ext = os.path.splitext(filename)[1]
+        py3Ext = Preferences.getPython("Python3Extensions")
+        project = ericApp().getObject("Project")
+        basename = os.path.basename(filename)
+
+        if "FileType" in flags:
+            pyVer = pyAssignment.get(flags["FileType"], 0)
+        elif project.isOpen() and project.isProjectFile(filename):
+            language = project.getEditorLexerAssoc(basename)
+            if not language:
+                language = Preferences.getEditorLexerAssoc(basename)
+            if language == "Python3":
+                pyVer = pyAssignment[language]
+
+        if pyVer:
+            # Skip the next tests
+            pass
+        elif (
+            Preferences.getProject("DeterminePyFromProject")
+            and project.isOpen()
+            and project.isProjectFile(filename)
+            and ext in py3Ext
+        ):
+            pyVer = pyAssignment.get(project.getProjectLanguage(), 0)
+        elif ext in py3Ext:
+            pyVer = 3
+        elif source:
+            if isinstance(source, str):
+                line0 = source.splitlines()[0]
+            else:
+                line0 = source[0]
+            if line0.startswith("#!") and (("python3" in line0) or ("python" in line0)):
+                pyVer = 3
+
+        if pyVer == 0 and ext in py3Ext:
+            pyVer = 3
+
+    return pyVer
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/SystemUtilities/QtUtilities.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/SystemUtilities/QtUtilities.py	Sun Dec 18 19:33:46 2022 +0100
@@ -0,0 +1,357 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing Qt/PyQt/PySide related utility functions.
+"""
+
+import contextlib
+import functools
+import os
+import sys
+import sysconfig
+
+from PyQt6.QtCore import QT_VERSION, QDir, QLibraryInfo, QProcess
+
+from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities, PythonUtilities
+
+try:
+    from eric7.eric7config import getConfig
+except ImportError:
+    from eric7config import getConfig
+
+###############################################################################
+## Qt utility functions below
+###############################################################################
+
+
+def qVersionTuple():
+    """
+    Module function to get the Qt version as a tuple.
+
+    @return Qt version as a tuple
+    @rtype tuple of int
+    """
+    return (
+        (QT_VERSION & 0xFF0000) >> 16,
+        (QT_VERSION & 0xFF00) >> 8,
+        QT_VERSION & 0xFF,
+    )
+
+
+def generateQtToolName(toolname):
+    """
+    Module function to generate the executable name for a Qt tool like
+    designer.
+
+    @param toolname base name of the tool (string)
+    @return the Qt tool name without extension (string)
+    """
+    from eric7 import Preferences
+
+    return "{0}{1}{2}".format(
+        Preferences.getQt("QtToolsPrefix"),
+        toolname,
+        Preferences.getQt("QtToolsPostfix"),
+    )
+
+
+def getQtBinariesPath(libexec=False):
+    """
+    Module function to get the path of the Qt binaries.
+
+    @param libexec flag indicating to get the path of the executable library
+        (defaults to False)
+    @type bool (optional)
+    @return path of the Qt binaries
+    @rtype str
+    """
+    from eric7 import Preferences
+
+    binPath = ""
+
+    # step 1: check, if the user has configured a tools path
+    qtToolsDir = Preferences.getQt("QtToolsDir")
+    if qtToolsDir:
+        if libexec:
+            binPath = os.path.join(qtToolsDir, "..", "libexec")
+            if not os.path.exists(binPath):
+                binPath = qtToolsDir
+        else:
+            binPath = Preferences.getQt("QtToolsDir")
+        if not os.path.exists(binPath):
+            binPath = ""
+
+    # step 2: try the qt6_applications package
+    if not binPath:
+        with contextlib.suppress(ImportError):
+            # if qt6-applications is not installed just go to the next step
+            import qt6_applications  # __IGNORE_WARNING_I10__
+
+            if libexec:
+                binPath = os.path.join(
+                    os.path.dirname(qt6_applications.__file__), "Qt", "libexec"
+                )
+                if not os.path.exists(binPath):
+                    binPath = os.path.join(
+                        os.path.dirname(qt6_applications.__file__), "Qt", "bin"
+                    )
+            else:
+                binPath = os.path.join(
+                    os.path.dirname(qt6_applications.__file__), "Qt", "bin"
+                )
+            if not os.path.exists(binPath):
+                binPath = ""
+
+    # step3: determine via QLibraryInfo
+    if not binPath:
+        binPath = (
+            QLibraryInfo.path(QLibraryInfo.LibraryPath.LibraryExecutablesPath)
+            if libexec
+            else QLibraryInfo.path(QLibraryInfo.LibraryPath.BinariesPath)
+        )
+
+    # step 4: determine from used Python interpreter (designer is test object)
+    if not binPath:
+        program = "designer"
+        if OSUtilities.isWindowsPlatform():
+            program += ".exe"
+
+        progPath = os.path.join(PythonUtilities.getPythonScriptsDirectory(), program)
+        if os.path.exists(progPath):
+            binPath = PythonUtilities.getPythonScriptsDirectory()
+
+    return QDir.toNativeSeparators(binPath)
+
+
+def getQtMacBundle(toolname):
+    """
+    Module function to determine the correct Mac OS X bundle name for Qt tools.
+
+    @param toolname  plain name of the tool (e.g. "designer") (string)
+    @return bundle name of the Qt tool (string)
+    """
+    qtDir = getQtBinariesPath()
+    bundles = [
+        os.path.join(qtDir, "bin", generateQtToolName(toolname.capitalize())) + ".app",
+        os.path.join(qtDir, "bin", generateQtToolName(toolname)) + ".app",
+        os.path.join(qtDir, generateQtToolName(toolname.capitalize())) + ".app",
+        os.path.join(qtDir, generateQtToolName(toolname)) + ".app",
+    ]
+    if toolname == "designer":
+        # support the standalone Qt Designer installer from
+        # https://build-system.fman.io/qt-designer-download
+        designer = "Qt Designer.app"
+        bundles.extend(
+            [
+                os.path.join(qtDir, "bin", designer),
+                os.path.join(qtDir, designer),
+            ]
+        )
+    for bundle in bundles:
+        if os.path.exists(bundle):
+            return bundle
+    return ""
+
+
+def prepareQtMacBundle(toolname, args):
+    """
+    Module function for starting Qt tools that are Mac OS X bundles.
+
+    @param toolname  plain name of the tool (e.g. "designer")
+    @type str
+    @param args    name of input file for tool, if any
+    @type list of str
+    @return command-name and args for QProcess
+    @rtype tuple of (str, list of str)
+    """
+    fullBundle = getQtMacBundle(toolname)
+    if fullBundle == "":
+        return ("", [])
+
+    newArgs = []
+    newArgs.append("-a")
+    newArgs.append(fullBundle)
+    if args:
+        newArgs.append("--args")
+        newArgs += args
+
+    return ("open", newArgs)
+
+
+###############################################################################
+## PyQt utility functions below
+###############################################################################
+
+
+def getPyQt6ModulesDirectory():
+    """
+    Function to determine the path to PyQt6 modules directory.
+
+    @return path to the PyQt6 modules directory
+    @rtype str
+    """
+    pyqtPath = os.path.join(sysconfig.get_path("platlib"), "PyQt6")
+    if os.path.exists(pyqtPath):
+        return pyqtPath
+
+    return ""
+
+
+def getPyQtToolsPath(version=5):
+    """
+    Module function to get the path of the PyQt tools.
+
+    @param version PyQt major version
+    @type int
+    @return path to the PyQt tools
+    @rtype str
+    """
+    from eric7 import Preferences
+    from eric7.EricWidgets.EricApplication import ericApp
+
+    toolsPath = ""
+
+    # step 1: check, if the user has configured a tools path
+    if version == 5:
+        toolsPath = Preferences.getQt("PyQtToolsDir")
+        venvName = Preferences.getQt("PyQtVenvName")
+    elif version == 6:
+        toolsPath = Preferences.getQt("PyQt6ToolsDir")
+        venvName = Preferences.getQt("PyQt6VenvName")
+
+    # step 2: determine from used Python interpreter (pylupdate is test object)
+    if not toolsPath:
+        program = "pylupdate{0}".format(version)
+        if venvName:
+            venvManager = ericApp().getObject("VirtualEnvManager")
+            dirName = venvManager.getVirtualenvDirectory(venvName)
+        else:
+            dirName = os.path.dirname(sys.executable)
+
+        if OSUtilities.isWindowsPlatform():
+            program += ".exe"
+            if os.path.exists(os.path.join(dirName, program)):
+                toolsPath = dirName
+            elif os.path.exists(os.path.join(dirName, "Scripts", program)):
+                toolsPath = os.path.join(dirName, "Scripts")
+        else:
+            if os.path.exists(os.path.join(dirName, program)):
+                toolsPath = dirName
+            elif os.path.exists(os.path.join(dirName, "bin", program)):
+                toolsPath = os.path.join(dirName, "bin")
+
+    return toolsPath
+
+
+def generatePyQtToolPath(toolname, alternatives=None):
+    """
+    Module function to generate the executable path for a PyQt tool.
+
+    @param toolname base name of the tool
+    @type str
+    @param alternatives list of alternative tool names to try
+    @type list of str
+    @return executable path name of the tool
+    @rtype str
+    """
+    pyqtVariant = int(toolname[-1])
+    pyqtToolsPath = getPyQtToolsPath(pyqtVariant)
+    if pyqtToolsPath:
+        exe = os.path.join(pyqtToolsPath, toolname)
+        if OSUtilities.isWindowsPlatform():
+            exe += ".exe"
+    else:
+        if OSUtilities.isWindowsPlatform():
+            exe = OSUtilities.getWindowsExecutablePath(toolname)
+        else:
+            exe = toolname
+
+    if not FileSystemUtilities.isinpath(exe) and alternatives:
+        ex_ = generatePyQtToolPath(alternatives[0], alternatives[1:])
+        if FileSystemUtilities.isinpath(ex_):
+            exe = ex_
+
+    return exe
+
+
+###############################################################################
+## PySide2/PySide6 utility functions below
+###############################################################################
+
+
+def generatePySideToolPath(toolname, variant=2):
+    """
+    Module function to generate the executable path for a PySide2/PySide6 tool.
+
+    @param toolname base name of the tool
+    @type str
+    @param variant indicator for the PySide variant
+    @type int or str
+    @return the PySide2/PySide6 tool path with extension
+    @rtype str
+    """
+    from eric7 import Preferences
+
+    if OSUtilities.isWindowsPlatform():
+        hasPyside = checkPyside(variant)
+        if not hasPyside:
+            return ""
+
+        venvName = Preferences.getQt("PySide{0}VenvName".format(variant))
+        if not venvName:
+            venvName = Preferences.getDebugger("Python3VirtualEnv")
+        interpreter = (
+            ericApp().getObject("VirtualEnvManager").getVirtualenvInterpreter(venvName)
+        )
+        if interpreter == "" or not FileSystemUtilities.isinpath(interpreter):
+            interpreter = PythonUtilities.getPythonExecutable()
+        prefix = os.path.dirname(interpreter)
+        if not prefix.endswith("Scripts"):
+            prefix = os.path.join(prefix, "Scripts")
+        return os.path.join(prefix, toolname + ".exe")
+    else:
+        # step 1: check, if the user has configured a tools path
+        path = Preferences.getQt("PySide{0}ToolsDir".format(variant))
+        if path:
+            return os.path.join(path, toolname)
+
+        # step 2: determine from used Python interpreter
+        dirName = os.path.dirname(sys.executable)
+        if os.path.exists(os.path.join(dirName, toolname)):
+            return os.path.join(dirName, toolname)
+
+        return toolname
+
+
+@functools.lru_cache()
+def checkPyside(variant=2):
+    """
+    Module function to check the presence of PySide2/PySide6.
+
+    @param variant indicator for the PySide variant
+    @type int or str
+    @return flags indicating the presence of PySide2/PySide6
+    @rtype bool
+    """
+    from eric7 import Preferences
+
+    venvName = Preferences.getQt("PySide{0}VenvName".format(variant))
+    if not venvName:
+        venvName = Preferences.getDebugger("Python3VirtualEnv")
+    interpreter = (
+        ericApp().getObject("VirtualEnvManager").getVirtualenvInterpreter(venvName)
+    )
+    if interpreter == "" or not FileSystemUtilities.isinpath(interpreter):
+        interpreter = PythonUtilities.getPythonExecutable()
+
+    checker = os.path.join(getConfig("ericDir"), "SystemUtilities", "PySideImporter.py")
+    args = [checker, "--variant={0}".format(variant)]
+    proc = QProcess()
+    proc.setProcessChannelMode(QProcess.ProcessChannelMode.MergedChannels)
+    proc.start(interpreter, args)
+    finished = proc.waitForFinished(30000)
+    return finished and proc.exitCode() == 0
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/SystemUtilities/__init__.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/SystemUtilities/__init__.py	Sun Dec 18 19:33:46 2022 +0100
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Package implementing system level utility functions and classes.
+"""
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Templates/TemplateViewer.py
--- a/src/eric7/Templates/TemplateViewer.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Templates/TemplateViewer.py	Sun Dec 18 19:33:46 2022 +0100
@@ -15,7 +15,7 @@
 from PyQt6.QtCore import QCoreApplication, QFile, QIODevice, Qt
 from PyQt6.QtWidgets import QApplication, QDialog, QMenu, QTreeWidget, QTreeWidgetItem
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
@@ -972,7 +972,7 @@
         @rtype bool
         """
         if filename is None:
-            filename = os.path.join(Utilities.getConfigDir(), "eric7templates.ecj")
+            filename = os.path.join(Globals.getConfigDir(), "eric7templates.ecj")
 
         return self.__templatesFile.writeFile(filename)
 
@@ -985,10 +985,10 @@
         """
         if filename is None:
             # new JSON based file first
-            filename = os.path.join(Utilities.getConfigDir(), "eric7templates.ecj")
+            filename = os.path.join(Globals.getConfigDir(), "eric7templates.ecj")
             if not os.path.exists(filename):
                 # old XML based file second
-                filename = os.path.join(Utilities.getConfigDir(), "eric7templates.e4c")
+                filename = os.path.join(Globals.getConfigDir(), "eric7templates.e4c")
                 if not os.path.exists(filename):
                     return
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Toolbox/Startup.py
--- a/src/eric7/Toolbox/Startup.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Toolbox/Startup.py	Sun Dec 18 19:33:46 2022 +0100
@@ -17,6 +17,7 @@
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets.EricApplication import EricApplication
 from eric7.Globals import getConfig
+from eric7.SystemUtilities import QtUtilities
 
 application = None
 
@@ -160,8 +161,8 @@
     Module function to set the Qt library paths correctly.
     """
     libPaths = (
-        os.path.join(Globals.getPyQt6ModulesDirectory(), "plugins"),
-        os.path.join(Globals.getPyQt6ModulesDirectory(), "Qt6", "plugins"),
+        os.path.join(QtUtilities.getPyQt6ModulesDirectory(), "plugins"),
+        os.path.join(QtUtilities.getPyQt6ModulesDirectory(), "Qt6", "plugins"),
     )
 
     libraryPaths = QApplication.libraryPaths()
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Tools/TrayStarter.py
--- a/src/eric7/Tools/TrayStarter.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Tools/TrayStarter.py	Sun Dec 18 19:33:46 2022 +0100
@@ -18,10 +18,11 @@
 from PyQt6.QtGui import QCursor
 from PyQt6.QtWidgets import QApplication, QDialog, QMenu, QSystemTrayIcon
 
-from eric7 import Globals, Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import DesktopUtilities, FileSystemUtilities, PythonUtilities
 from eric7.UI.Info import Program, Version
 
 
@@ -303,14 +304,14 @@
 
         args = []
         args.append(applPath)
-        args.append("--config={0}".format(Utilities.getConfigDir()))
+        args.append("--config={0}".format(Globals.getConfigDir()))
         if self.settingsDir:
             args.append("--settings={0}".format(self.settingsDir))
         for arg in applArgs:
             args.append(arg)
 
         if not os.path.isfile(applPath) or not proc.startDetached(
-            Globals.getPythonExecutable(), args
+            PythonUtilities.getPythonExecutable(), args
         ):
             EricMessageBox.critical(
                 self,
@@ -474,7 +475,7 @@
             formatStr = "&{0:d}. {1}" if idx < 10 else "{0:d}. {1}"
             act = self.recentProjectsMenu.addAction(
                 formatStr.format(
-                    idx, Utilities.compactPath(rp, self.maxMenuFilePathLen)
+                    idx, FileSystemUtilities.compactPath(rp, self.maxMenuFilePathLen)
                 )
             )
             act.setData(rp)
@@ -493,7 +494,7 @@
             formatStr = "&{0:d}. {1}" if idx < 10 else "{0:d}. {1}"
             act = self.recentMultiProjectsMenu.addAction(
                 formatStr.format(
-                    idx, Utilities.compactPath(rmp, self.maxMenuFilePathLen)
+                    idx, FileSystemUtilities.compactPath(rmp, self.maxMenuFilePathLen)
                 )
             )
             act.setData(rmp)
@@ -512,7 +513,7 @@
             formatStr = "&{0:d}. {1}" if idx < 10 else "{0:d}. {1}"
             act = self.recentFilesMenu.addAction(
                 formatStr.format(
-                    idx, Utilities.compactPath(rf, self.maxMenuFilePathLen)
+                    idx, FileSystemUtilities.compactPath(rf, self.maxMenuFilePathLen)
                 )
             )
             act.setData(rf)
@@ -626,8 +627,8 @@
         )
 
         # desktop and session type
-        desktop = Globals.desktopName()
-        session = Globals.sessionType()
+        desktop = DesktopUtilities.desktopName()
+        session = DesktopUtilities.sessionType()
         if desktop or session:
             versionText += "<tr><td></td><td></td></tr>"
             if desktop:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/UI/Browser.py
--- a/src/eric7/UI/Browser.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/UI/Browser.py	Sun Dec 18 19:33:46 2022 +0100
@@ -31,11 +31,12 @@
     QTreeView,
 )
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.Project.ProjectBrowserModel import ProjectBrowserSimpleDirectoryItem
+from eric7.SystemUtilities import FileSystemUtilities
 from eric7.UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
 from eric7.Utilities import MimeTypes
 
@@ -714,7 +715,7 @@
             EricFileDialog.ShowDirsOnly,
         )
         if dname:
-            dname = os.path.abspath(Utilities.toNativeSeparators(dname))
+            dname = os.path.abspath(FileSystemUtilities.toNativeSeparators(dname))
             self.__model.addTopLevelDir(dname)
 
     def __removeToplevel(self):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/UI/BrowserModel.py
--- a/src/eric7/UI/BrowserModel.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/UI/BrowserModel.py	Sun Dec 18 19:33:46 2022 +0100
@@ -24,8 +24,9 @@
 from PyQt6.QtGui import QFont, QImageReader
 from PyQt6.QtWidgets import QApplication
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
+from eric7.SystemUtilities import FileSystemUtilities
 from eric7.Utilities import ClassBrowsers
 from eric7.Utilities.ClassBrowsers import ClbrBaseClasses
 
@@ -336,7 +337,7 @@
             # step 1: check for new entries
             children = itm.children()
             for f in entryInfoList:
-                fpath = Utilities.toNativeSeparators(f.absoluteFilePath())
+                fpath = FileSystemUtilities.toNativeSeparators(f.absoluteFilePath())
                 childFound = False
                 for child in children:
                     if child.name() == fpath:
@@ -350,11 +351,14 @@
                 self.beginInsertRows(self.createIndex(itm.row(), 0, itm), cnt, cnt)
                 node = (
                     BrowserDirectoryItem(
-                        itm, Utilities.toNativeSeparators(f.absoluteFilePath()), False
+                        itm,
+                        FileSystemUtilities.toNativeSeparators(f.absoluteFilePath()),
+                        False,
                     )
                     if f.isDir()
                     else BrowserFileItem(
-                        itm, Utilities.toNativeSeparators(f.absoluteFilePath())
+                        itm,
+                        FileSystemUtilities.toNativeSeparators(f.absoluteFilePath()),
                     )
                 )
                 self._addItem(node, itm)
@@ -364,7 +368,7 @@
             if len(entryInfoList) != itm.childCount():
                 for row in range(oldCnt - 1, -1, -1):
                     child = itm.child(row)
-                    childname = Utilities.fromNativeSeparators(child.name())
+                    childname = FileSystemUtilities.fromNativeSeparators(child.name())
                     entryFound = False
                     for f in entryInfoList:
                         if f.absoluteFilePath() == childname:
@@ -388,10 +392,12 @@
         if tdp:
             self.toplevelDirs = tdp
         else:
-            self.toplevelDirs.append(Utilities.toNativeSeparators(QDir.homePath()))
+            self.toplevelDirs.append(
+                FileSystemUtilities.toNativeSeparators(QDir.homePath())
+            )
             for d in QDir.drives():
                 self.toplevelDirs.append(
-                    Utilities.toNativeSeparators(d.absoluteFilePath())
+                    FileSystemUtilities.toNativeSeparators(d.absoluteFilePath())
                 )
 
         for d in self.toplevelDirs:
@@ -566,7 +572,7 @@
                 if f.isDir():
                     node = BrowserDirectoryItem(
                         parentItem,
-                        Utilities.toNativeSeparators(f.absoluteFilePath()),
+                        FileSystemUtilities.toNativeSeparators(f.absoluteFilePath()),
                         False,
                     )
                 else:
@@ -576,7 +582,8 @@
                         if any(fnmatch.fnmatch(fn, ff.strip()) for ff in fileFilters):
                             continue
                     node = BrowserFileItem(
-                        parentItem, Utilities.toNativeSeparators(f.absoluteFilePath())
+                        parentItem,
+                        FileSystemUtilities.toNativeSeparators(f.absoluteFilePath()),
                     )
                 self._addItem(node, parentItem)
             if repopulate:
@@ -1061,7 +1068,7 @@
 
         self.type_ = BrowserItemDirectory
         if (
-            not Utilities.isDrive(self._dirName)
+            not FileSystemUtilities.isDrive(self._dirName)
             and os.path.lexists(self._dirName)
             and os.path.islink(self._dirName)
         ):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/UI/DiffDialog.py
--- a/src/eric7/UI/DiffDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/UI/DiffDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -18,10 +18,11 @@
 from PyQt6.QtGui import QTextCursor
 from PyQt6.QtWidgets import QApplication, QDialogButtonBox, QWidget
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricMainWindow import EricMainWindow
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .DiffHighlighter import DiffHighlighter
 from .Ui_DiffDialog import Ui_DiffDialog
@@ -103,7 +104,7 @@
         It saves the diff shown in the dialog to a file in the local
         filesystem.
         """
-        dname, fname = Utilities.splitPath(self.filename2)
+        dname, fname = FileSystemUtilities.splitPath(self.filename2)
         fname = "{0}.diff".format(self.filename2) if fname != "." else dname
 
         fname, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
@@ -156,7 +157,7 @@
         """
         Private slot to handle the Compare button press.
         """
-        self.filename1 = Utilities.toNativeSeparators(self.file1Picker.text())
+        self.filename1 = FileSystemUtilities.toNativeSeparators(self.file1Picker.text())
         try:
             filemtime1 = time.ctime(os.stat(self.filename1).st_mtime)
         except OSError:
@@ -174,7 +175,7 @@
             )
             return
 
-        self.filename2 = Utilities.toNativeSeparators(self.file2Picker.text())
+        self.filename2 = FileSystemUtilities.toNativeSeparators(self.file2Picker.text())
         try:
             filemtime2 = time.ctime(os.stat(self.filename2).st_mtime)
         except OSError:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/UI/FindFileWidget.py
--- a/src/eric7/UI/FindFileWidget.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/UI/FindFileWidget.py	Sun Dec 18 19:33:46 2022 +0100
@@ -30,6 +30,7 @@
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_FindFileWidget import Ui_FindFileWidget
 
@@ -809,7 +810,7 @@
         @type str
         """
         self.dirButton.setChecked(True)
-        self.dirPicker.setEditText(Utilities.toNativeSeparators(searchDir))
+        self.dirPicker.setEditText(FileSystemUtilities.toNativeSeparators(searchDir))
 
     @pyqtSlot()
     def __setOpenFiles(self):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/UI/FindLocationWidget.py
--- a/src/eric7/UI/FindLocationWidget.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/UI/FindLocationWidget.py	Sun Dec 18 19:33:46 2022 +0100
@@ -25,7 +25,7 @@
 from eric7 import Utilities
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
-from eric7.Utilities import direntries
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_FindLocationWidget import Ui_FindLocationWidget
 
@@ -192,7 +192,9 @@
 
         for path in searchPaths:
             if os.path.isdir(path):
-                files = direntries(path, True, fileNamePatterns, False, self.checkStop)
+                files = FileSystemUtilities.direntries(
+                    path, True, fileNamePatterns, False, self.checkStop
+                )
                 if files:
                     for file in files:
                         fp, fn = os.path.split(file)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/UI/InstallInfoDialog.py
--- a/src/eric7/UI/InstallInfoDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/UI/InstallInfoDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -17,6 +17,7 @@
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricPlainTextDialog import EricPlainTextDialog
+from eric7.SystemUtilities import OSUtilities
 
 from .Ui_InstallInfoDialog import Ui_InstallInfoDialog
 
@@ -59,7 +60,7 @@
             with open(infoFileName, "r") as infoFile:
                 self.__info = json.load(infoFile)
 
-            if Globals.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 self.sudoLabel1.setText(self.tr("Installed as Administrator:"))
             else:
                 self.sudoLabel1.setText(self.tr("Installed with sudo:"))
@@ -243,7 +244,7 @@
         cmdPrefix = ""
 
         if self.__info["sudo"]:
-            if Globals.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 updateTextList.append(
                     self.tr(
                         "Perform the following step(s) with Administrator"
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/UI/NotificationWidget.py
--- a/src/eric7/UI/NotificationWidget.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/UI/NotificationWidget.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,8 +13,9 @@
 from PyQt6.QtCore import QPoint, Qt, QTimer
 from PyQt6.QtWidgets import QFrame, QVBoxLayout, QWidget
 
-from eric7 import Globals, Preferences
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
+from eric7.SystemUtilities import OSUtilities
 
 from .Ui_NotificationFrame import Ui_NotificationFrame
 
@@ -151,7 +152,7 @@
             | Qt.WindowType.WindowStaysOnTopHint
             | Qt.WindowType.X11BypassWindowManagerHint
         )
-        if Globals.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             flags |= Qt.WindowType.ToolTip
         self.setWindowFlags(flags)
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/UI/Previewers/PreviewerHTML.py
--- a/src/eric7/UI/Previewers/PreviewerHTML.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/UI/Previewers/PreviewerHTML.py	Sun Dec 18 19:33:46 2022 +0100
@@ -29,8 +29,9 @@
     QWidget,
 )
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import FileSystemUtilities
 
 
 class PreviewerHTML(QWidget):
@@ -254,8 +255,8 @@
         @param rootPath path of the web site root
         @type str
         """
-        self.__previewedPath = Utilities.normcasepath(
-            Utilities.fromNativeSeparators(filePath)
+        self.__previewedPath = FileSystemUtilities.normcasepath(
+            FileSystemUtilities.fromNativeSeparators(filePath)
         )
         self.__saveScrollBarPositions()
         self.previewView.page().loadFinished.connect(self.__restoreScrollBarPositions)
@@ -552,9 +553,9 @@
                 break
 
             if incMatch.group(1) == "virtual":
-                incFile = Utilities.normjoinpath(docRoot, incMatch.group(2))
+                incFile = FileSystemUtilities.normjoinpath(docRoot, incMatch.group(2))
             elif incMatch.group(1) == "file":
-                incFile = Utilities.normjoinpath(baseDir, incMatch.group(2))
+                incFile = FileSystemUtilities.normjoinpath(baseDir, incMatch.group(2))
             else:
                 incFile = ""
             if os.path.exists(incFile):
@@ -585,7 +586,7 @@
         if not root:
             return txt
 
-        root = Utilities.fromNativeSeparators(root)
+        root = FileSystemUtilities.fromNativeSeparators(root)
         if not root.endswith("/"):
             root += "/"
         rootLen = len(root)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/UI/Previewers/PreviewerQSS.py
--- a/src/eric7/UI/Previewers/PreviewerQSS.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/UI/Previewers/PreviewerQSS.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,11 +12,12 @@
 from PyQt6.QtCore import Qt, pyqtSlot
 from PyQt6.QtWidgets import QHeaderView, QLabel, QListWidgetItem, QMenu, QWidget
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
 from eric7.Globals import getConfig
+from eric7.SystemUtilities import FileSystemUtilities
 
 from .Ui_PreviewerQSS import Ui_PreviewerQSS
 
@@ -119,7 +120,9 @@
                                 getConfig("ericIconDir"), "StyleIcons"
                             )
 
-                    styleIconsPath = Utilities.fromNativeSeparators(styleIconsPath)
+                    styleIconsPath = FileSystemUtilities.fromNativeSeparators(
+                        styleIconsPath
+                    )
                     styleSheet = styleSheet.replace("${path}", styleIconsPath)
                     self.scrollAreaWidgetContents.setStyleSheet(styleSheet)
                 else:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/UI/UserInterface.py
--- a/src/eric7/UI/UserInterface.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/UI/UserInterface.py	Sun Dec 18 19:33:46 2022 +0100
@@ -83,6 +83,13 @@
 from eric7.Project.Project import Project
 from eric7.QScintilla.SpellChecker import SpellChecker
 from eric7.Sessions.SessionFile import SessionFile
+from eric7.SystemUtilities import (
+    DesktopUtilities,
+    FileSystemUtilities,
+    OSUtilities,
+    PythonUtilities,
+    QtUtilities,
+)
 from eric7.Tasks.TasksFile import TasksFile
 from eric7.Testing.TestingWidget import clearSavedHistories
 from eric7.Utilities.BackgroundService import BackgroundService
@@ -1625,7 +1632,7 @@
         # flag indicating '--' options was found
         ddseen = False
 
-        argChars = ["-", "/"] if Utilities.isWindowsPlatform() else ["-"]
+        argChars = ["-", "/"] if OSUtilities.isWindowsPlatform() else ["-"]
 
         for arg in args:
             # handle a request to start with last session
@@ -1810,7 +1817,9 @@
         @param project project name to be displayed (string)
         """
         if editor is not None and self.captionShowsFilename:
-            self.capEditor = Utilities.compactPath(editor, self.maxFilePathLen)
+            self.capEditor = FileSystemUtilities.compactPath(
+                editor, self.maxFilePathLen
+            )
         if project is not None:
             self.capProject = project
 
@@ -2884,16 +2893,17 @@
         self.actions.append(self.testProjectAct)
 
         # check for Qt5 designer and linguist
-        if Utilities.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             designerExe = os.path.join(
-                Utilities.getQtBinariesPath(),
-                "{0}.exe".format(Utilities.generateQtToolName("designer")),
-            )
-        elif Utilities.isMacPlatform():
-            designerExe = Utilities.getQtMacBundle("designer")
+                QtUtilities.getQtBinariesPath(),
+                "{0}.exe".format(QtUtilities.generateQtToolName("designer")),
+            )
+        elif OSUtilities.isMacPlatform():
+            designerExe = QtUtilities.getQtMacBundle("designer")
         else:
             designerExe = os.path.join(
-                Utilities.getQtBinariesPath(), Utilities.generateQtToolName("designer")
+                QtUtilities.getQtBinariesPath(),
+                QtUtilities.generateQtToolName("designer"),
             )
         if os.path.exists(designerExe):
             self.designer4Act = EricAction(
@@ -2914,16 +2924,17 @@
         else:
             self.designer4Act = None
 
-        if Utilities.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             linguistExe = os.path.join(
-                Utilities.getQtBinariesPath(),
-                "{0}.exe".format(Utilities.generateQtToolName("linguist")),
-            )
-        elif Utilities.isMacPlatform():
-            linguistExe = Utilities.getQtMacBundle("linguist")
+                QtUtilities.getQtBinariesPath(),
+                "{0}.exe".format(QtUtilities.generateQtToolName("linguist")),
+            )
+        elif OSUtilities.isMacPlatform():
+            linguistExe = QtUtilities.getQtMacBundle("linguist")
         else:
             linguistExe = os.path.join(
-                Utilities.getQtBinariesPath(), Utilities.generateQtToolName("linguist")
+                QtUtilities.getQtBinariesPath(),
+                QtUtilities.generateQtToolName("linguist"),
             )
         if os.path.exists(linguistExe):
             self.linguist4Act = EricAction(
@@ -3709,7 +3720,7 @@
         Private slot to initialize the actions to show the PySide
         documentation.
         """
-        if Utilities.checkPyside(variant=2):
+        if QtUtilities.checkPyside(variant=2):
             self.pyside2DocAct = EricAction(
                 self.tr("PySide2 Documentation"),
                 self.tr("PySide2 Documentation"),
@@ -3735,7 +3746,7 @@
         else:
             self.pyside2DocAct = None
 
-        if Utilities.checkPyside(variant=6):
+        if QtUtilities.checkPyside(variant=6):
             self.pyside6DocAct = EricAction(
                 self.tr("PySide6 Documentation"),
                 self.tr("PySide6 Documentation"),
@@ -3767,7 +3778,7 @@
         """
         self.__menus = {}
         mb = self.menuBar()
-        if Utilities.isLinuxPlatform() and not Preferences.getUI("UseNativeMenuBar"):
+        if OSUtilities.isLinuxPlatform() and not Preferences.getUI("UseNativeMenuBar"):
             mb.setNativeMenuBar(False)
 
         ##############################################################
@@ -4576,8 +4587,8 @@
         )
 
         # desktop and session type
-        desktop = Globals.desktopName()
-        session = Globals.sessionType()
+        desktop = DesktopUtilities.desktopName()
+        session = DesktopUtilities.sessionType()
         if desktop or session:
             versionText += "<tr><td></td><td></td></tr>"
             if desktop:
@@ -4679,7 +4690,7 @@
         from .ErrorLogDialog import ErrorLogDialog
 
         if Preferences.getUI("CheckErrorLog"):
-            logFile = os.path.join(Utilities.getConfigDir(), self.ErrorLogFileName)
+            logFile = os.path.join(Globals.getConfigDir(), self.ErrorLogFileName)
             if os.path.exists(logFile):
                 dlg = ErrorLogDialog(logFile, False, self)
                 dlg.exec()
@@ -4690,7 +4701,7 @@
 
         @return flag indicating the existence of an error log file (boolean)
         """
-        logFile = os.path.join(Utilities.getConfigDir(), self.ErrorLogFileName)
+        logFile = os.path.join(Globals.getConfigDir(), self.ErrorLogFileName)
         return os.path.exists(logFile)
 
     def __showErrorLog(self):
@@ -4699,7 +4710,7 @@
         """
         from .ErrorLogDialog import ErrorLogDialog
 
-        logFile = os.path.join(Utilities.getConfigDir(), self.ErrorLogFileName)
+        logFile = os.path.join(Globals.getConfigDir(), self.ErrorLogFileName)
         if os.path.exists(logFile):
             dlg = ErrorLogDialog(logFile, True, self)
             dlg.show()
@@ -4951,7 +4962,7 @@
 
         if res and self.__shutdown():
             ericApp().closeAllWindows()
-            program = Globals.getPythonExecutable()
+            program = PythonUtilities.getPythonExecutable()
             args = ["-m", "eric7", "--start-session"]
             args.extend(self.__restartArgs)
             QProcess.startDetached(program, args)
@@ -5045,7 +5056,7 @@
         @type str
         """
         ericApp().closeAllWindows()
-        program = Globals.getPythonExecutable()
+        program = PythonUtilities.getPythonExecutable()
         ericStartArgs = ["-m", "eric7", "--start-session"]
         ericStartArgs.extend(self.__restartArgs)
 
@@ -5064,7 +5075,7 @@
         """
         if not Preferences.getUI("SingleApplicationMode"):
             # start eric without loading anything and without crash session
-            program = Globals.getPythonExecutable()
+            program = PythonUtilities.getPythonExecutable()
             eric7 = os.path.join(os.path.dirname(__file__), "..", "eric7_ide.py")
             args = [eric7, "--no-open", "--disable-crash"]
             QProcess.startDetached(program, args)
@@ -5984,13 +5995,14 @@
                 )
                 return
 
-        if Utilities.isMacPlatform():
-            designer, args = Utilities.prepareQtMacBundle("designer", args)
+        if OSUtilities.isMacPlatform():
+            designer, args = QtUtilities.prepareQtMacBundle("designer", args)
         else:
             designer = os.path.join(
-                Utilities.getQtBinariesPath(), Utilities.generateQtToolName("designer")
-            )
-            if Utilities.isWindowsPlatform():
+                QtUtilities.getQtBinariesPath(),
+                QtUtilities.generateQtToolName("designer"),
+            )
+            if OSUtilities.isWindowsPlatform():
                 designer += ".exe"
 
         if designer:
@@ -6051,13 +6063,14 @@
                 )
                 return
 
-        if Utilities.isMacPlatform():
-            linguist, args = Utilities.prepareQtMacBundle("linguist", args)
+        if OSUtilities.isMacPlatform():
+            linguist, args = QtUtilities.prepareQtMacBundle("linguist", args)
         else:
             linguist = os.path.join(
-                Utilities.getQtBinariesPath(), Utilities.generateQtToolName("linguist")
-            )
-            if Utilities.isWindowsPlatform():
+                QtUtilities.getQtBinariesPath(),
+                QtUtilities.generateQtToolName("linguist"),
+            )
+            if OSUtilities.isWindowsPlatform():
                 linguist += ".exe"
 
         if linguist:
@@ -6094,13 +6107,14 @@
             args.append("-showUrl")
             args.append(home)
 
-        if Utilities.isMacPlatform():
-            assistant, args = Utilities.prepareQtMacBundle("assistant", args)
+        if OSUtilities.isMacPlatform():
+            assistant, args = QtUtilities.prepareQtMacBundle("assistant", args)
         else:
             assistant = os.path.join(
-                Utilities.getQtBinariesPath(), Utilities.generateQtToolName("assistant")
-            )
-            if Utilities.isWindowsPlatform():
+                QtUtilities.getQtBinariesPath(),
+                QtUtilities.generateQtToolName("assistant"),
+            )
+            if OSUtilities.isWindowsPlatform():
                 assistant += ".exe"
 
         if assistant:
@@ -6226,7 +6240,7 @@
                 return
 
         if not os.path.isfile(viewer) or not proc.startDetached(
-            Globals.getPythonExecutable(), args
+            PythonUtilities.getPythonExecutable(), args
         ):
             EricMessageBox.critical(
                 self,
@@ -6285,7 +6299,7 @@
                         return
 
         if not os.path.isfile(viewer) or not proc.startDetached(
-            Globals.getPythonExecutable(), args
+            PythonUtilities.getPythonExecutable(), args
         ):
             EricMessageBox.critical(
                 self,
@@ -6308,7 +6322,7 @@
         args.append(browser)
 
         if not os.path.isfile(browser) or not proc.startDetached(
-            Globals.getPythonExecutable(), args
+            PythonUtilities.getPythonExecutable(), args
         ):
             EricMessageBox.critical(
                 self,
@@ -6398,7 +6412,7 @@
         args.append(snap)
 
         if not os.path.isfile(snap) or not proc.startDetached(
-            Globals.getPythonExecutable(), args
+            PythonUtilities.getPythonExecutable(), args
         ):
             EricMessageBox.critical(
                 self,
@@ -6575,7 +6589,7 @@
         """
         pythonDocDir = Preferences.getHelp("PythonDocDir")
         if not pythonDocDir:
-            if Utilities.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 venvName = Preferences.getDebugger("Python3VirtualEnv")
                 interpreter = (
                     ericApp()
@@ -6586,18 +6600,18 @@
                     default = os.path.join(os.path.dirname(interpreter), "doc")
                 else:
                     default = ""
-                pythonDocDir = Utilities.getEnvironmentEntry("PYTHON3DOCDIR", default)
+                pythonDocDir = OSUtilities.getEnvironmentEntry("PYTHON3DOCDIR", default)
             else:
-                pythonDocDir = Utilities.getEnvironmentEntry(
+                pythonDocDir = OSUtilities.getEnvironmentEntry(
                     "PYTHON3DOCDIR", "/usr/share/doc/packages/python3/html"
                 )
         if not pythonDocDir.startswith(("http://", "https://", "qthelp://")):
             if pythonDocDir.startswith("file://"):
                 pythonDocDir = pythonDocDir[7:]
             if not os.path.splitext(pythonDocDir)[1]:
-                home = Utilities.normjoinpath(pythonDocDir, "index.html")
-
-                if Utilities.isWindowsPlatform() and not os.path.exists(home):
+                home = FileSystemUtilities.normjoinpath(pythonDocDir, "index.html")
+
+                if OSUtilities.isWindowsPlatform() and not os.path.exists(home):
                     pyversion = sys.hexversion >> 16
                     vers = "{0:d}{1:d}".format(
                         (pyversion >> 8) & 0xFF, pyversion & 0xFF
@@ -6618,8 +6632,8 @@
                 return
 
             if not home.endswith(".chm"):
-                if Utilities.isWindowsPlatform():
-                    home = "file:///" + Utilities.fromNativeSeparators(home)
+                if OSUtilities.isWindowsPlatform():
+                    home = "file:///" + FileSystemUtilities.fromNativeSeparators(home)
                 else:
                     home = "file://" + home
         else:
@@ -6666,7 +6680,7 @@
             if qtDocDir.startswith("file://"):
                 qtDocDir = qtDocDir[7:]
             if not os.path.splitext(qtDocDir)[1]:
-                home = Utilities.normjoinpath(qtDocDir, "index.html")
+                home = FileSystemUtilities.normjoinpath(qtDocDir, "index.html")
             else:
                 home = qtDocDir
 
@@ -6681,8 +6695,8 @@
                 )
                 return
 
-            if Utilities.isWindowsPlatform():
-                home = "file:///" + Utilities.fromNativeSeparators(home)
+            if OSUtilities.isWindowsPlatform():
+                home = "file:///" + FileSystemUtilities.fromNativeSeparators(home)
             else:
                 home = "file://" + home
 
@@ -6710,7 +6724,7 @@
         """
         pyqtDocDir = Preferences.getHelp("PyQt{0}DocDir".format(variant))
         if not pyqtDocDir:
-            pyqtDocDir = Utilities.getEnvironmentEntry(
+            pyqtDocDir = OSUtilities.getEnvironmentEntry(
                 "PYQT{0}DOCDIR".format(variant), None
             )
 
@@ -6732,8 +6746,10 @@
                     pyqtDocDir = pyqtDocDir[7:]
                 if not os.path.splitext(pyqtDocDir)[1]:
                     possibleHomes = [
-                        Utilities.normjoinpath(pyqtDocDir, "index.html"),
-                        Utilities.normjoinpath(pyqtDocDir, "class_reference.html"),
+                        FileSystemUtilities.normjoinpath(pyqtDocDir, "index.html"),
+                        FileSystemUtilities.normjoinpath(
+                            pyqtDocDir, "class_reference.html"
+                        ),
                     ]
                     for possibleHome in possibleHomes:
                         if os.path.exists(possibleHome):
@@ -6753,8 +6769,8 @@
                 )
                 return
 
-            if Utilities.isWindowsPlatform():
-                home = "file:///" + Utilities.fromNativeSeparators(home)
+            if OSUtilities.isWindowsPlatform():
+                home = "file:///" + FileSystemUtilities.fromNativeSeparators(home)
             else:
                 home = "file://" + home
         else:
@@ -6781,7 +6797,7 @@
         """
         home = Preferences.getHelp("EricDocDir")
         if not home:
-            home = Utilities.normjoinpath(
+            home = FileSystemUtilities.normjoinpath(
                 getConfig("ericDocDir"), "Source", "index.html"
             )
 
@@ -6797,8 +6813,8 @@
                 )
                 return
 
-            if Utilities.isWindowsPlatform():
-                home = "file:///" + Utilities.fromNativeSeparators(home)
+            if OSUtilities.isWindowsPlatform():
+                home = "file:///" + FileSystemUtilities.fromNativeSeparators(home)
             else:
                 home = "file://" + home
 
@@ -6826,7 +6842,7 @@
         """
         pysideDocDir = Preferences.getHelp("PySide{0}DocDir".format(variant))
         if not pysideDocDir:
-            pysideDocDir = Utilities.getEnvironmentEntry(
+            pysideDocDir = OSUtilities.getEnvironmentEntry(
                 "PYSIDE{0}DOCDIR".format(variant), None
             )
 
@@ -6845,7 +6861,7 @@
             if pysideDocDir.startswith("file://"):
                 pysideDocDir = pysideDocDir[7:]
             if not os.path.splitext(pysideDocDir)[1]:
-                home = Utilities.normjoinpath(pysideDocDir, "index.html")
+                home = FileSystemUtilities.normjoinpath(pysideDocDir, "index.html")
             else:
                 home = pysideDocDir
             if not os.path.exists(home):
@@ -6859,8 +6875,8 @@
                 )
                 return
 
-            if Utilities.isWindowsPlatform():
-                home = "file:///" + Utilities.fromNativeSeparators(home)
+            if OSUtilities.isWindowsPlatform():
+                home = "file:///" + FileSystemUtilities.fromNativeSeparators(home)
             else:
                 home = "file://" + home
         else:
@@ -6945,7 +6961,7 @@
                     "--name={0}".format(self.__webBrowserSAName),
                     home,
                 ]
-                process.start(Globals.getPythonExecutable(), args)
+                process.start(PythonUtilities.getPythonExecutable(), args)
                 if not process.waitForStarted():
                     EricMessageBox.warning(
                         self,
@@ -7507,20 +7523,20 @@
         """
         Private slot to write the tasks data to a JSON file (.etj).
         """
-        fn = os.path.join(Utilities.getConfigDir(), "eric7tasks.etj")
+        fn = os.path.join(Globals.getConfigDir(), "eric7tasks.etj")
         self.__tasksFile.writeFile(fn)
 
     def __readTasks(self):
         """
         Private slot to read in the tasks file (.etj or .e6t).
         """
-        fn = os.path.join(Utilities.getConfigDir(), "eric7tasks.etj")
+        fn = os.path.join(Globals.getConfigDir(), "eric7tasks.etj")
         if os.path.exists(fn):
             # try new style JSON file first
             self.__tasksFile.readFile(fn)
         else:
             # try old style XML file second
-            fn = os.path.join(Utilities.getConfigDir(), "eric7tasks.e6t")
+            fn = os.path.join(Globals.getConfigDir(), "eric7tasks.e6t")
             if os.path.exists(fn):
                 f = QFile(fn)
                 if f.open(QIODevice.OpenModeFlag.ReadOnly):
@@ -7550,9 +7566,9 @@
         if filename:
             fn = filename
         elif crashSession:
-            fn = os.path.join(Utilities.getConfigDir(), "eric7_crash_session.esj")
+            fn = os.path.join(Globals.getConfigDir(), "eric7_crash_session.esj")
         else:
-            fn = os.path.join(Utilities.getConfigDir(), "eric7session.esj")
+            fn = os.path.join(Globals.getConfigDir(), "eric7session.esj")
 
         return self.__sessionFile.writeFile(fn)
 
@@ -7568,9 +7584,9 @@
         if filename:
             fn = filename
         else:
-            fn = os.path.join(Utilities.getConfigDir(), "eric7session.esj")
+            fn = os.path.join(Globals.getConfigDir(), "eric7session.esj")
             if not os.path.exists(fn):
-                fn = os.path.join(Utilities.getConfigDir(), "eric7session.e5s")
+                fn = os.path.join(Globals.getConfigDir(), "eric7session.e5s")
                 if not os.path.exists(fn):
                     EricMessageBox.critical(
                         self,
@@ -7619,7 +7635,7 @@
         sessionFile, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
             self,
             self.tr("Save Session"),
-            Utilities.getHomeDir(),
+            OSUtilities.getHomeDir(),
             self.tr("eric Session Files (*.esj)"),
             "",
         )
@@ -7642,7 +7658,7 @@
         sessionFile = EricFileDialog.getOpenFileName(
             self,
             self.tr("Load session"),
-            Utilities.getHomeDir(),
+            OSUtilities.getHomeDir(),
             self.tr("eric Session Files (*.esj);;eric XML Session Files (*.e5s)"),
         )
 
@@ -7656,7 +7672,7 @@
         Private slot to delete the crash session file.
         """
         for ext in (".esj", ".e5s"):
-            fn = os.path.join(Utilities.getConfigDir(), f"eric7_crash_session{ext}")
+            fn = os.path.join(Globals.getConfigDir(), f"eric7_crash_session{ext}")
             if os.path.exists(fn):
                 with contextlib.suppress(OSError):
                     os.remove(fn)
@@ -7685,7 +7701,7 @@
             and not self.__noCrashOpenAtStartup
             and Preferences.getUI("OpenCrashSessionOnStartup")
         ):
-            fn = os.path.join(Utilities.getConfigDir(), "eric7_crash_session.esj")
+            fn = os.path.join(Globals.getConfigDir(), "eric7_crash_session.esj")
             if os.path.exists(fn):
                 yes = EricMessageBox.yesNo(
                     self,
@@ -8312,7 +8328,7 @@
 
         workspace = Preferences.getMultiProject("Workspace")
         if workspace == "":
-            default = Utilities.getHomeDir()
+            default = OSUtilities.getHomeDir()
             workspace = EricFileDialog.getExistingDirectory(
                 None,
                 self.tr("Select Workspace Directory"),
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Utilities/BackgroundService.py
--- a/src/eric7/Utilities/BackgroundService.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Utilities/BackgroundService.py	Sun Dec 18 19:33:46 2022 +0100
@@ -20,9 +20,10 @@
 from PyQt6.QtNetwork import QHostAddress, QTcpServer
 from PyQt6.QtWidgets import QApplication
 
-from eric7 import Globals, Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import FileSystemUtilities, PythonUtilities
 
 
 class BackgroundService(QTcpServer):
@@ -97,7 +98,7 @@
             ericApp().getObject("VirtualEnvManager").getVirtualenvInterpreter(venvName)
         )
         if not interpreter:
-            interpreter = Globals.getPythonExecutable()
+            interpreter = PythonUtilities.getPythonExecutable()
         return interpreter
 
     def __startExternalClient(self, interpreter, port):
@@ -111,7 +112,7 @@
         @return the process object
         @rtype QProcess or None
         """
-        if interpreter == "" or not Utilities.isinpath(interpreter):
+        if interpreter == "" or not FileSystemUtilities.isinpath(interpreter):
             return None
 
         backgroundClient = os.path.join(
@@ -124,7 +125,7 @@
             self.__hostAddress,
             str(port),
             str(Preferences.getUI("BackgroundServiceProcesses")),
-            Globals.getPythonLibraryDirectory(),
+            PythonUtilities.getPythonLibraryDirectory(),
         ]
         proc.start(interpreter, args)
         if not proc.waitForStarted(10000):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Utilities/MouseUtilities.py
--- a/src/eric7/Utilities/MouseUtilities.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Utilities/MouseUtilities.py	Sun Dec 18 19:33:46 2022 +0100
@@ -9,9 +9,9 @@
 
 from PyQt6.QtCore import QCoreApplication, Qt
 
-from eric7 import Globals
+from eric7.SystemUtilities import OSUtilities
 
-if Globals.isMacPlatform():
+if OSUtilities.isMacPlatform():
     __modifier2String = {
         Qt.KeyboardModifier.ShiftModifier: QCoreApplication.translate(
             "MouseUtilities", "Shift"
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Utilities/PySideImporter.py
--- a/src/eric7/Utilities/PySideImporter.py	Sun Dec 18 14:19:10 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2011 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module to check for the presence of PySide2/PySide6 by importing it.
-"""
-
-import sys
-
-if __name__ == "__main__":
-    pySideVariant = "2"
-    if len(sys.argv) == 2:
-        pySideVariant = sys.argv[1].replace("--variant=", "")
-
-    if pySideVariant == "1":
-        # no PySide support anymore
-        ret = 1
-
-    elif pySideVariant == "2":
-        try:
-            import PySide2  # __IGNORE_EXCEPTION__ __IGNORE_WARNING__
-
-            ret = 0
-        except ImportError:
-            ret = 1
-
-    elif pySideVariant == "6":
-        try:
-            import PySide6  # __IGNORE_EXCEPTION__ __IGNORE_WARNING__
-
-            ret = 0
-        except ImportError:
-            ret = 1
-
-    else:
-        ret = 1
-
-    sys.exit(ret)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/Utilities/__init__.py
--- a/src/eric7/Utilities/__init__.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/Utilities/__init__.py	Sun Dec 18 19:33:46 2022 +0100
@@ -9,22 +9,12 @@
 
 import codecs
 import contextlib
-import ctypes
-import fnmatch
-import functools
-import getpass
 import glob
 import json
 import os
-import pathlib
 import re
 import shlex
-import subprocess  # secok
 import sys
-
-with contextlib.suppress(ImportError):
-    import pwd  # only available on Unix systems
-
 import warnings
 
 from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF32
@@ -38,7 +28,6 @@
     QByteArray,
     QCoreApplication,
     QCryptographicHash,
-    QDir,
     QProcess,
     qVersion,
 )
@@ -46,23 +35,73 @@
 from eric7 import Preferences
 from eric7.EricWidgets.EricApplication import ericApp
 
-# import these methods into the Utilities namespace
-from eric7.Globals import (  # __IGNORE_WARNING__
+# imports from eric7.SystemUtilities are for backward compatibility
+from eric7.Globals import (  # __IGNORE_FLAKES_WARNING__
     desktopName,
     getConfig,
     getConfigDir,
-    getPyQt6ModulesDirectory,
-    getPyQtToolsPath,
     getPythonExecutable,
     getPythonLibraryDirectory,
     getPythonScriptsDirectory,
-    getQtBinariesPath,
+    sessionType,
+    setConfigDir,
+    toBool,
+)
+from eric7.SystemUtilities import DesktopUtilities
+from eric7.SystemUtilities.FileSystemUtilities import (  # __IGNORE_FLAKES_WARNING__
+    absolutePath,
+    absoluteUniversalPath,
+    compactPath,
+    direntries,
+    findVolume,
+    fromNativeSeparators,
+    getDirs,
+    getExecutablePath,
+    getExecutablePaths,
+    getWindowsExecutablePath,
+    isDrive,
+    isExecutable,
+    isinpath,
+    joinext,
+    normabsjoinpath,
+    normcaseabspath,
+    normcasepath,
+    normjoinpath,
+    relativeUniversalPath,
+    samefilepath,
+    samepath,
+    splitPath,
+    startswithPath,
+    toNativeSeparators,
+)
+from eric7.SystemUtilities.OSUtilities import (  # __IGNORE_FLAKES_WARNING__
+    getEnvironmentEntry,
+    getHomeDir,
+    getUserName,
+    hasEnvironmentEntry,
     isLinuxPlatform,
     isMacPlatform,
     isWindowsPlatform,
+    win32_getRealName,
+    win32_GetUserName,
+    win32_Kill,
+)
+from eric7.SystemUtilities.PythonUtilities import (  # __IGNORE_FLAKES_WARNING__
+    determinePythonVersion,
+    getPythonLibPath,
+    getPythonVersion,
+)
+from eric7.SystemUtilities.QtUtilities import (  # __IGNORE_FLAKES_WARNING__
+    checkPyside,
+    generatePyQtToolPath,
+    generatePySideToolPath,
+    generateQtToolName,
+    getPyQt6ModulesDirectory,
+    getPyQtToolsPath,
+    getQtBinariesPath,
+    getQtMacBundle,
+    prepareQtMacBundle,
     qVersionTuple,
-    sessionType,
-    setConfigDir,
 )
 from eric7.UI.Info import Program, Version
 
@@ -803,601 +842,6 @@
     return ntxt
 
 
-def toNativeSeparators(path):
-    """
-    Function returning a path, that is using native separator characters.
-
-    @param path path to be converted
-    @type str
-    @return path with converted separator characters
-    @rtype str
-    """
-    return str(pathlib.PurePath(path)) if bool(path) else ""
-
-
-def fromNativeSeparators(path):
-    """
-    Function returning a path, that is using "/" separator characters.
-
-    @param path path to be converted
-    @type str
-    @return path with converted separator characters
-    @rtype str
-    """
-    return pathlib.PurePath(path).as_posix() if bool(path) else ""
-
-
-def normcasepath(path):
-    """
-    Function returning a path, that is normalized with respect to its case
-    and references.
-
-    @param path file path (string)
-    @return case normalized path (string)
-    """
-    return os.path.normcase(os.path.normpath(path))
-
-
-def normcaseabspath(path):
-    """
-    Function returning an absolute path, that is normalized with respect to
-    its case and references.
-
-    @param path file path (string)
-    @return absolute, normalized path (string)
-    """
-    return os.path.normcase(os.path.abspath(path))
-
-
-def normjoinpath(a, *p):
-    """
-    Function returning a normalized path of the joined parts passed into it.
-
-    @param a first path to be joined (string)
-    @param p variable number of path parts to be joined (string)
-    @return normalized path (string)
-    """
-    return os.path.normpath(os.path.join(a, *p))
-
-
-def normabsjoinpath(a, *p):
-    """
-    Function returning a normalized, absolute path of the joined parts passed
-    into it.
-
-    @param a first path to be joined (string)
-    @param p variable number of path parts to be joind (string)
-    @return absolute, normalized path (string)
-    """
-    return os.path.abspath(os.path.join(a, *p))
-
-
-def isinpath(file):
-    """
-    Function to check for an executable file.
-
-    @param file filename of the executable to check (string)
-    @return flag to indicate, if the executable file is accessible
-        via the searchpath defined by the PATH environment variable.
-    """
-    if os.path.isabs(file):
-        return os.access(file, os.X_OK)
-
-    if os.path.exists(os.path.join(os.curdir, file)):
-        return os.access(os.path.join(os.curdir, file), os.X_OK)
-
-    path = getEnvironmentEntry("PATH")
-
-    # environment variable not defined
-    if path is None:
-        return False
-
-    dirs = path.split(os.pathsep)
-    return any(os.access(os.path.join(directory, file), os.X_OK) for directory in dirs)
-
-
-def startswithPath(path, start):
-    """
-    Function to check, if a path starts with a given start path.
-
-    @param path path to be checked
-    @type str
-    @param start start path
-    @type str
-    @return flag indicating that the path starts with the given start
-        path
-    @rtype bool
-    """
-    return bool(start) and (
-        path == start or normcasepath(path).startswith(normcasepath(start + "/"))
-    )
-
-
-def relativeUniversalPath(path, start):
-    """
-    Function to convert a file path to a path relative to a start path
-    with universal separators.
-
-    @param path file or directory name to convert (string)
-    @param start start path (string)
-    @return relative path or unchanged path, if path does not start with
-        the start path with universal separators (string)
-    """
-    return fromNativeSeparators(os.path.relpath(path, start))
-
-
-def absolutePath(path, start):
-    """
-    Public method to convert a path relative to a start path to an
-    absolute path.
-
-    @param path file or directory name to convert (string)
-    @param start start path (string)
-    @return absolute path (string)
-    """
-    if not os.path.isabs(path):
-        path = os.path.normpath(os.path.join(start, path))
-    return path
-
-
-def absoluteUniversalPath(path, start):
-    """
-    Public method to convert a path relative to a start path with
-    universal separators to an absolute path.
-
-    @param path file or directory name to convert (string)
-    @param start start path (string)
-    @return absolute path with native separators (string)
-    """
-    if not os.path.isabs(path):
-        path = toNativeSeparators(os.path.normpath(os.path.join(start, path)))
-    return path
-
-
-def getExecutablePath(file):
-    """
-    Function to build the full path of an executable file from the environment.
-
-    @param file filename of the executable to check (string)
-    @return full executable name, if the executable file is accessible
-        via the searchpath defined by the PATH environment variable, or an
-        empty string otherwise.
-    """
-    if os.path.isabs(file):
-        if os.access(file, os.X_OK):
-            return file
-        else:
-            return ""
-
-    cur_path = os.path.join(os.curdir, file)
-    if os.path.exists(cur_path) and os.access(cur_path, os.X_OK):
-        return cur_path
-
-    path = os.getenv("PATH")
-
-    # environment variable not defined
-    if path is None:
-        return ""
-
-    dirs = path.split(os.pathsep)
-    for directory in dirs:
-        exe = os.path.join(directory, file)
-        if os.access(exe, os.X_OK):
-            return exe
-
-    return ""
-
-
-def getExecutablePaths(file):
-    """
-    Function to build all full path of an executable file from the environment.
-
-    @param file filename of the executable (string)
-    @return list of full executable names (list of strings), if the executable
-        file is accessible via the searchpath defined by the PATH environment
-        variable, or an empty list otherwise.
-    """
-    paths = []
-
-    if os.path.isabs(file):
-        if os.access(file, os.X_OK):
-            return [file]
-        else:
-            return []
-
-    cur_path = os.path.join(os.curdir, file)
-    if os.path.exists(cur_path) and os.access(cur_path, os.X_OK):
-        paths.append(cur_path)
-
-    path = os.getenv("PATH")
-
-    # environment variable not defined
-    if path is not None:
-        dirs = path.split(os.pathsep)
-        for directory in dirs:
-            exe = os.path.join(directory, file)
-            if os.access(exe, os.X_OK) and exe not in paths:
-                paths.append(exe)
-
-    return paths
-
-
-def getWindowsExecutablePath(file):
-    """
-    Function to build the full path of an executable file from the environment
-    on Windows platforms.
-
-    First an executable with the extension .exe is searched for, thereafter
-    such with the extensions .cmd or .bat and finally the given file name as
-    is. The first match is returned.
-
-    @param file filename of the executable to check (string)
-    @return full executable name, if the executable file is accessible
-        via the searchpath defined by the PATH environment variable, or an
-        empty string otherwise.
-    """
-    if os.path.isabs(file):
-        if os.access(file, os.X_OK):
-            return file
-        else:
-            return ""
-
-    filenames = [file + ".exe", file + ".cmd", file + ".bat", file]
-
-    for filename in filenames:
-        cur_path = os.path.join(os.curdir, filename)
-        if os.path.exists(cur_path) and os.access(cur_path, os.X_OK):
-            return os.path.abspath(cur_path)
-
-    path = os.getenv("PATH")
-
-    # environment variable not defined
-    if path is None:
-        return ""
-
-    dirs = path.split(os.pathsep)
-    for directory in dirs:
-        for filename in filenames:
-            exe = os.path.join(directory, filename)
-            if os.access(exe, os.X_OK):
-                return exe
-
-    return ""
-
-
-def isExecutable(exe):
-    """
-    Function to check, if a file is executable.
-
-    @param exe filename of the executable to check (string)
-    @return flag indicating executable status (boolean)
-    """
-    return os.access(exe, os.X_OK)
-
-
-def isDrive(path):
-    """
-    Function to check, if a path is a Windows drive.
-
-    @param path path name to be checked
-    @type str
-    @return flag indicating a Windows drive
-    @rtype bool
-    """
-    isDrive = False
-    drive, directory = os.path.splitdrive(path)
-    if (
-        drive
-        and len(drive) == 2
-        and drive.endswith(":")
-        and directory in ["", "\\", "/"]
-    ):
-        isDrive = True
-
-    return isDrive
-
-
-def samepath(f1, f2):
-    """
-    Function to compare two paths.
-
-    @param f1 first path for the compare (string)
-    @param f2 second path for the compare (string)
-    @return flag indicating whether the two paths represent the
-        same path on disk.
-    """
-    if f1 is None or f2 is None:
-        return False
-
-    if normcaseabspath(os.path.realpath(f1)) == normcaseabspath(os.path.realpath(f2)):
-        return True
-
-    return False
-
-
-def samefilepath(f1, f2):
-    """
-    Function to compare two paths. Strips the filename.
-
-    @param f1 first filepath for the compare (string)
-    @param f2 second filepath for the compare (string)
-    @return flag indicating whether the two paths represent the
-        same path on disk.
-    """
-    if f1 is None or f2 is None:
-        return False
-
-    if normcaseabspath(os.path.dirname(os.path.realpath(f1))) == normcaseabspath(
-        os.path.dirname(os.path.realpath(f2))
-    ):
-        return True
-
-    return False
-
-
-try:
-    EXTSEP = os.extsep
-except AttributeError:
-    EXTSEP = "."
-
-
-def splitPath(name):
-    """
-    Function to split a pathname into a directory part and a file part.
-
-    @param name path name (string)
-    @return a tuple of 2 strings (dirname, filename).
-    """
-    if os.path.isdir(name):
-        dn = os.path.abspath(name)
-        fn = "."
-    else:
-        dn, fn = os.path.split(name)
-    return (dn, fn)
-
-
-def joinext(prefix, ext):
-    """
-    Function to join a file extension to a path.
-
-    The leading "." of ext is replaced by a platform specific extension
-    separator if necessary.
-
-    @param prefix the basepart of the filename (string)
-    @param ext the extension part (string)
-    @return the complete filename (string)
-    """
-    if ext[0] != ".":
-        ext = ".{0}".format(ext)
-        # require leading separator to match os.path.splitext
-    return prefix + EXTSEP + ext[1:]
-
-
-def compactPath(path, width, measure=len):
-    """
-    Function to return a compacted path fitting inside the given width.
-
-    @param path path to be compacted (string)
-    @param width width for the compacted path (integer)
-    @param measure reference to a function used to measure the length of the
-        string
-    @return compacted path (string)
-    """
-    if measure(path) <= width:
-        return path
-
-    ellipsis = "..."
-
-    head, tail = os.path.split(path)
-    mid = len(head) // 2
-    head1 = head[:mid]
-    head2 = head[mid:]
-    while head1:
-        # head1 is same size as head2 or one shorter
-        path = os.path.join("{0}{1}{2}".format(head1, ellipsis, head2), tail)
-        if measure(path) <= width:
-            return path
-        head1 = head1[:-1]
-        head2 = head2[1:]
-    path = os.path.join(ellipsis, tail)
-    if measure(path) <= width:
-        return path
-    while tail:
-        path = "{0}{1}".format(ellipsis, tail)
-        if measure(path) <= width:
-            return path
-        tail = tail[1:]
-    return ""
-
-
-def direntries(
-    path, filesonly=False, pattern=None, followsymlinks=True, checkStop=None
-):
-    """
-    Function returning a list of all files and directories.
-
-    @param path root of the tree to check
-    @type str
-    @param filesonly flag indicating that only files are wanted
-    @type bool
-    @param pattern a filename pattern or list of filename patterns to check
-        against
-    @type str or list of str
-    @param followsymlinks flag indicating whether symbolic links
-        should be followed
-    @type bool
-    @param checkStop function to be called to check for a stop
-    @type function
-    @return list of all files and directories in the tree rooted
-        at path. The names are expanded to start with path.
-    @rtype list of strs
-    """
-    patterns = pattern if isinstance(pattern, list) else [pattern]
-    files = [] if filesonly else [path]
-    try:
-        entries = os.listdir(path)
-        for entry in entries:
-            if checkStop and checkStop():
-                break
-
-            if entry in [
-                ".svn",
-                ".hg",
-                ".git",
-                ".ropeproject",
-                ".eric7project",
-                ".jedi",
-            ]:
-                continue
-
-            fentry = os.path.join(path, entry)
-            if (
-                pattern
-                and not os.path.isdir(fentry)
-                and not any(fnmatch.fnmatch(entry, p) for p in patterns)
-            ):
-                # entry doesn't fit the given pattern
-                continue
-
-            if os.path.isdir(fentry):
-                if os.path.islink(fentry) and not followsymlinks:
-                    continue
-                files += direntries(
-                    fentry, filesonly, pattern, followsymlinks, checkStop
-                )
-            else:
-                files.append(fentry)
-    except OSError:
-        pass
-    except UnicodeDecodeError:
-        pass
-    return files
-
-
-def getDirs(path, excludeDirs):
-    """
-    Function returning a list of all directories below path.
-
-    @param path root of the tree to check
-    @param excludeDirs basename of directories to ignore
-    @return list of all directories found
-    """
-    try:
-        names = os.listdir(path)
-    except OSError:
-        return []
-
-    dirs = []
-    for name in names:
-        if os.path.isdir(os.path.join(path, name)) and not os.path.islink(
-            os.path.join(path, name)
-        ):
-            exclude = 0
-            for e in excludeDirs:
-                if name.split(os.sep, 1)[0] == e:
-                    exclude = 1
-                    break
-            if not exclude:
-                dirs.append(os.path.join(path, name))
-
-    for name in dirs[:]:
-        if not os.path.islink(name):
-            dirs += getDirs(name, excludeDirs)
-
-    return dirs
-
-
-def findVolume(volumeName, findAll=False):
-    """
-    Function to find the directory belonging to a given volume name.
-
-    @param volumeName name of the volume to search for
-    @type str
-    @param findAll flag indicating to get the directories for all volumes
-        starting with the given name (defaults to False)
-    @type bool (optional)
-    @return directory path or list of directory paths for the given volume
-        name
-    @rtype str or list of str
-    """
-    volumeDirectories = []
-    volumeDirectory = None
-
-    if isWindowsPlatform():
-        # we are on a Windows platform
-        def getVolumeName(diskName):
-            """
-            Local function to determine the volume of a disk or device.
-
-            Each disk or external device connected to windows has an
-            attribute called "volume name". This function returns the
-            volume name for the given disk/device.
-
-            Code from http://stackoverflow.com/a/12056414
-            """
-            volumeNameBuffer = ctypes.create_unicode_buffer(1024)
-            ctypes.windll.kernel32.GetVolumeInformationW(
-                ctypes.c_wchar_p(diskName),
-                volumeNameBuffer,
-                ctypes.sizeof(volumeNameBuffer),
-                None,
-                None,
-                None,
-                None,
-                0,
-            )
-            return volumeNameBuffer.value
-
-        #
-        # In certain circumstances, volumes are allocated to USB
-        # storage devices which cause a Windows popup to raise if their
-        # volume contains no media. Wrapping the check in SetErrorMode
-        # with SEM_FAILCRITICALERRORS (1) prevents this popup.
-        #
-        oldMode = ctypes.windll.kernel32.SetErrorMode(1)
-        try:
-            for disk in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
-                dirpath = "{0}:\\".format(disk)
-                if os.path.exists(dirpath):
-                    if findAll:
-                        if getVolumeName(dirpath).startswith(volumeName):
-                            volumeDirectories.append(dirpath)
-                    else:
-                        if getVolumeName(dirpath) == volumeName:
-                            volumeDirectory = dirpath
-                            break
-        finally:
-            ctypes.windll.kernel32.SetErrorMode(oldMode)
-    else:
-        # we are on a Linux or macOS platform
-        for mountCommand in ["mount", "/sbin/mount", "/usr/sbin/mount"]:
-            with contextlib.suppress(FileNotFoundError):
-                mountOutput = subprocess.run(  # secok
-                    mountCommand, check=True, capture_output=True, text=True
-                ).stdout.splitlines()
-                mountedVolumes = [
-                    x.split(" type")[0].split(maxsplit=2)[2] for x in mountOutput
-                ]
-                if findAll:
-                    for volume in mountedVolumes:
-                        if volumeName in volume:
-                            volumeDirectories.append(volume)
-                    if volumeDirectories:
-                        break
-                else:
-                    for volume in mountedVolumes:
-                        if volume.endswith(volumeName):
-                            volumeDirectory = volume
-                            break
-                    if volumeDirectory:
-                        break
-
-    if findAll:
-        return volumeDirectories
-    else:
-        return volumeDirectory
-
-
 def getTestFileNames(fn):
     """
     Function to build the potential file names of a test file.
@@ -1633,146 +1077,6 @@
     )
 
 
-def getUserName():
-    """
-    Function to get the user name.
-
-    @return user name (string)
-    """
-    user = getpass.getuser()
-
-    if isWindowsPlatform() and not user:
-        return win32_GetUserName()
-
-    return user
-
-
-def getRealName():
-    """
-    Function to get the real name of the user.
-
-    @return real name of the user (string)
-    """
-    if isWindowsPlatform():
-        return win32_getRealName()
-    else:
-        user = getpass.getuser()
-        return pwd.getpwnam(user).pw_gecos
-
-
-def getHomeDir():
-    """
-    Function to get a users home directory.
-
-    @return home directory (string)
-    """
-    return QDir.homePath()
-
-
-def getPythonLibPath():
-    """
-    Function to determine the path to Python's library.
-
-    @return path to the Python library (string)
-    """
-    pyFullVers = sys.version.split()[0]
-
-    vl = re.findall("[0-9.]*", pyFullVers)[0].split(".")
-    major = vl[0]
-    minor = vl[1]
-
-    pyVers = major + "." + minor
-
-    if isWindowsPlatform():
-        libDir = sys.prefix + "\\Lib"
-    else:
-        try:
-            syslib = sys.lib
-        except AttributeError:
-            syslib = "lib"
-        libDir = sys.prefix + "/" + syslib + "/python" + pyVers
-
-    return libDir
-
-
-def getPythonVersion():
-    """
-    Function to get the Python version (major, minor) as an integer value.
-
-    @return An integer representing major and minor version number (integer)
-    """
-    return sys.hexversion >> 16
-
-
-def determinePythonVersion(filename, source, editor=None):
-    """
-    Function to determine the python version of a given file.
-
-    @param filename name of the file with extension (str)
-    @param source of the file (str)
-    @param editor reference to the editor, if the file is opened
-        already (Editor object)
-    @return Python version if file is Python3 (int)
-    """
-    pyAssignment = {
-        "Python3": 3,
-        "MicroPython": 3,
-        "Cython": 3,
-    }
-
-    if not editor:
-        viewManager = ericApp().getObject("ViewManager")
-        editor = viewManager.getOpenEditor(filename)
-
-    # Maybe the user has changed the language
-    if editor and editor.getFileType() in pyAssignment:
-        return pyAssignment[editor.getFileType()]
-
-    pyVer = 0
-    if filename:
-        if not source:
-            source = readEncodedFile(filename)[0]
-        flags = extractFlags(source)
-        ext = os.path.splitext(filename)[1]
-        py3Ext = Preferences.getPython("Python3Extensions")
-        project = ericApp().getObject("Project")
-        basename = os.path.basename(filename)
-
-        if "FileType" in flags:
-            pyVer = pyAssignment.get(flags["FileType"], 0)
-        elif project.isOpen() and project.isProjectFile(filename):
-            language = project.getEditorLexerAssoc(basename)
-            if not language:
-                language = Preferences.getEditorLexerAssoc(basename)
-            if language == "Python3":
-                pyVer = pyAssignment[language]
-
-        if pyVer:
-            # Skip the next tests
-            pass
-        elif (
-            Preferences.getProject("DeterminePyFromProject")
-            and project.isOpen()
-            and project.isProjectFile(filename)
-            and ext in py3Ext
-        ):
-            pyVer = pyAssignment.get(project.getProjectLanguage(), 0)
-        elif ext in py3Ext:
-            pyVer = 3
-        elif source:
-            if isinstance(source, str):
-                line0 = source.splitlines()[0]
-            else:
-                line0 = source[0]
-            if line0.startswith("#!") and (("python3" in line0) or ("python" in line0)):
-                pyVer = 3
-
-        if pyVer == 0 and ext in py3Ext:
-            pyVer = 3
-
-    return pyVer
-
-
 def rxIndex(rx, txt):
     """
     Function to get the index (start position) of a regular expression match
@@ -1793,247 +1097,6 @@
 
 
 ###############################################################################
-## functions for environment handling
-###############################################################################
-
-
-def getEnvironmentEntry(key, default=None):
-    """
-    Module function to get an environment entry.
-
-    @param key key of the requested environment entry (string)
-    @param default value to be returned, if the environment doesn't contain
-        the requested entry (string)
-    @return the requested entry or the default value, if the entry wasn't
-        found (string or None)
-    """
-    pattern = "^{0}[ \t]*=".format(key)
-    filterRe = (
-        re.compile(pattern, re.IGNORECASE)
-        if isWindowsPlatform()
-        else re.compile(pattern)
-    )
-
-    entries = [
-        e for e in QProcess.systemEnvironment() if filterRe.search(e) is not None
-    ]
-    if not entries:
-        return default
-
-    # if there are multiple entries, just consider the first one
-    ename, value = entries[0].split("=", 1)
-    return value.strip()
-
-
-def hasEnvironmentEntry(key):
-    """
-    Module function to check, if the environment contains an entry.
-
-    @param key key of the requested environment entry
-    @type str
-    @return flag indicating the presence of the requested entry
-    @rtype bool
-    """
-    pattern = "^{0}[ \t]*=".format(key)
-    filterRe = (
-        re.compile(pattern, re.IGNORECASE)
-        if isWindowsPlatform()
-        else re.compile(pattern)
-    )
-
-    entries = [
-        e for e in QProcess.systemEnvironment() if filterRe.search(e) is not None
-    ]
-    return len(entries) > 0
-
-
-###############################################################################
-## Qt utility functions below
-###############################################################################
-
-
-def generateQtToolName(toolname):
-    """
-    Module function to generate the executable name for a Qt tool like
-    designer.
-
-    @param toolname base name of the tool (string)
-    @return the Qt tool name without extension (string)
-    """
-    return "{0}{1}{2}".format(
-        Preferences.getQt("QtToolsPrefix"),
-        toolname,
-        Preferences.getQt("QtToolsPostfix"),
-    )
-
-
-def getQtMacBundle(toolname):
-    """
-    Module function to determine the correct Mac OS X bundle name for Qt tools.
-
-    @param toolname  plain name of the tool (e.g. "designer") (string)
-    @return bundle name of the Qt tool (string)
-    """
-    qtDir = getQtBinariesPath()
-    bundles = [
-        os.path.join(qtDir, "bin", generateQtToolName(toolname.capitalize())) + ".app",
-        os.path.join(qtDir, "bin", generateQtToolName(toolname)) + ".app",
-        os.path.join(qtDir, generateQtToolName(toolname.capitalize())) + ".app",
-        os.path.join(qtDir, generateQtToolName(toolname)) + ".app",
-    ]
-    if toolname == "designer":
-        # support the standalone Qt Designer installer from
-        # https://build-system.fman.io/qt-designer-download
-        designer = "Qt Designer.app"
-        bundles.extend(
-            [
-                os.path.join(qtDir, "bin", designer),
-                os.path.join(qtDir, designer),
-            ]
-        )
-    for bundle in bundles:
-        if os.path.exists(bundle):
-            return bundle
-    return ""
-
-
-def prepareQtMacBundle(toolname, args):
-    """
-    Module function for starting Qt tools that are Mac OS X bundles.
-
-    @param toolname  plain name of the tool (e.g. "designer")
-    @type str
-    @param args    name of input file for tool, if any
-    @type list of str
-    @return command-name and args for QProcess
-    @rtype tuple of (str, list of str)
-    """
-    fullBundle = getQtMacBundle(toolname)
-    if fullBundle == "":
-        return ("", [])
-
-    newArgs = []
-    newArgs.append("-a")
-    newArgs.append(fullBundle)
-    if args:
-        newArgs.append("--args")
-        newArgs += args
-
-    return ("open", newArgs)
-
-
-###############################################################################
-## PyQt utility functions below
-###############################################################################
-
-
-def generatePyQtToolPath(toolname, alternatives=None):
-    """
-    Module function to generate the executable path for a PyQt tool.
-
-    @param toolname base name of the tool
-    @type str
-    @param alternatives list of alternative tool names to try
-    @type list of str
-    @return executable path name of the tool
-    @rtype str
-    """
-    pyqtVariant = int(toolname[-1])
-    pyqtToolsPath = getPyQtToolsPath(pyqtVariant)
-    if pyqtToolsPath:
-        exe = os.path.join(pyqtToolsPath, toolname)
-        if isWindowsPlatform():
-            exe += ".exe"
-    else:
-        if isWindowsPlatform():
-            exe = getWindowsExecutablePath(toolname)
-        else:
-            exe = toolname
-
-    if not isinpath(exe) and alternatives:
-        ex_ = generatePyQtToolPath(alternatives[0], alternatives[1:])
-        if isinpath(ex_):
-            exe = ex_
-
-    return exe
-
-
-###############################################################################
-## PySide2/PySide6 utility functions below
-###############################################################################
-
-
-def generatePySideToolPath(toolname, variant=2):
-    """
-    Module function to generate the executable path for a PySide2/PySide6 tool.
-
-    @param toolname base name of the tool
-    @type str
-    @param variant indicator for the PySide variant
-    @type int or str
-    @return the PySide2/PySide6 tool path with extension
-    @rtype str
-    """
-    if isWindowsPlatform():
-        hasPyside = checkPyside(variant)
-        if not hasPyside:
-            return ""
-
-        venvName = Preferences.getQt("PySide{0}VenvName".format(variant))
-        if not venvName:
-            venvName = Preferences.getDebugger("Python3VirtualEnv")
-        interpreter = (
-            ericApp().getObject("VirtualEnvManager").getVirtualenvInterpreter(venvName)
-        )
-        if interpreter == "" or not isinpath(interpreter):
-            interpreter = getPythonExecutable()
-        prefix = os.path.dirname(interpreter)
-        if not prefix.endswith("Scripts"):
-            prefix = os.path.join(prefix, "Scripts")
-        return os.path.join(prefix, toolname + ".exe")
-    else:
-        # step 1: check, if the user has configured a tools path
-        path = Preferences.getQt("PySide{0}ToolsDir".format(variant))
-        if path:
-            return os.path.join(path, toolname)
-
-        # step 2: determine from used Python interpreter
-        dirName = os.path.dirname(sys.executable)
-        if os.path.exists(os.path.join(dirName, toolname)):
-            return os.path.join(dirName, toolname)
-
-        return toolname
-
-
-@functools.lru_cache()
-def checkPyside(variant=2):
-    """
-    Module function to check the presence of PySide2/PySide6.
-
-    @param variant indicator for the PySide variant
-    @type int or str
-    @return flags indicating the presence of PySide2/PySide6
-    @rtype bool
-    """
-    venvName = Preferences.getQt("PySide{0}VenvName".format(variant))
-    if not venvName:
-        venvName = Preferences.getDebugger("Python3VirtualEnv")
-    interpreter = (
-        ericApp().getObject("VirtualEnvManager").getVirtualenvInterpreter(venvName)
-    )
-    if interpreter == "" or not isinpath(interpreter):
-        interpreter = getPythonExecutable()
-
-    checker = os.path.join(getConfig("ericDir"), "Utilities", "PySideImporter.py")
-    args = [checker, "--variant={0}".format(variant)]
-    proc = QProcess()
-    proc.setProcessChannelMode(QProcess.ProcessChannelMode.MergedChannels)
-    proc.start(interpreter, args)
-    finished = proc.waitForFinished(30000)
-    return finished and proc.exitCode() == 0
-
-
-###############################################################################
 ## Other utility functions below
 ###############################################################################
 
@@ -2093,11 +1156,11 @@
     if os.environ.get("SOMMELIER_VERSION", ""):
         info[-1] += ", ChromeOS"
     info.append(sys.version)
-    desktop = desktopName()
+    desktop = DesktopUtilities.desktopName()
     if desktop:
         info.append("")
         info.append("Desktop: {0}".format(desktop))
-    session = sessionType()
+    session = DesktopUtilities.sessionType()
     if session:
         info.append("")
         info.append("Session Type: {0}".format(session))
@@ -2160,21 +1223,6 @@
     return linesep.join(info)
 
 
-def toBool(dataStr):
-    """
-    Module function to convert a string to a boolean value.
-
-    @param dataStr string to be converted (string)
-    @return converted boolean value (boolean)
-    """
-    if dataStr in ["True", "true", "1", "Yes", "yes"]:
-        return True
-    elif dataStr in ["False", "false", "0", "No", "no"]:
-        return False
-    else:
-        return bool(dataStr)
-
-
 def getSysPath(interpreter):
     """
     Module function to get the Python path (sys.path) of a specific
@@ -2203,62 +1251,3 @@
                 sysPath.remove("")
 
     return sysPath
-
-
-###############################################################################
-## posix compatibility functions below
-###############################################################################
-
-# None right now
-
-###############################################################################
-## win32 compatibility functions below
-###############################################################################
-
-
-def win32_Kill(pid):
-    """
-    Function to provide an os.kill equivalent for Win32.
-
-    @param pid process id (integer)
-    @return result of the kill (boolean)
-    """
-    import win32api  # __IGNORE_WARNING_I102__
-
-    handle = win32api.OpenProcess(1, 0, pid)
-    return 0 != win32api.TerminateProcess(handle, 0)
-
-
-def win32_GetUserName():
-    """
-    Function to get the user name under Win32.
-
-    @return user name (string)
-    """
-    try:
-        import win32api  # __IGNORE_WARNING_I10__
-
-        return win32api.GetUserName()
-    except ImportError:
-        try:
-            u = getEnvironmentEntry("USERNAME")
-        except KeyError:
-            u = getEnvironmentEntry("username", None)
-        return u
-
-
-def win32_getRealName():
-    """
-    Function to get the user's real name (aka. display name) under Win32.
-
-    @return real name of the current user (string)
-    """
-    GetUserNameEx = ctypes.windll.secur32.GetUserNameExW
-    NameDisplay = 3
-
-    size = ctypes.pointer(ctypes.c_ulong(0))
-    GetUserNameEx(NameDisplay, None, size)
-
-    nameBuffer = ctypes.create_unicode_buffer(size.contents.value)
-    GetUserNameEx(NameDisplay, nameBuffer, size)
-    return nameBuffer.value
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/ViewManager/ViewManager.py
--- a/src/eric7/ViewManager/ViewManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/ViewManager/ViewManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -25,12 +25,12 @@
 from PyQt6.QtGui import QKeySequence, QPixmap
 from PyQt6.QtWidgets import QApplication, QDialog, QMenu, QToolBar, QWidget
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricGui.EricAction import EricAction, createActionGroup
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
-from eric7.Globals import isMacPlatform, recentNameFiles
+from eric7.Globals import recentNameFiles
 from eric7.QScintilla import Exporters, Lexers
 from eric7.QScintilla.APIsManager import APIsManager
 from eric7.QScintilla.Editor import Editor
@@ -39,6 +39,7 @@
 from eric7.QScintilla.SpellChecker import SpellChecker
 from eric7.QScintilla.SpellingDictionaryEditDialog import SpellingDictionaryEditDialog
 from eric7.QScintilla.ZoomDialog import ZoomDialog
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 from eric7.UI import Config
 
 
@@ -1732,7 +1733,7 @@
             "vm_edit_move_left_char",
         )
         self.esm.setMapping(act, QsciScintilla.SCI_CHARLEFT)
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+B"))
             )
@@ -1747,7 +1748,7 @@
             self.editorActGrp,
             "vm_edit_move_right_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+F"))
             )
@@ -1763,7 +1764,7 @@
             self.editorActGrp,
             "vm_edit_move_up_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+P"))
             )
@@ -1779,7 +1780,7 @@
             self.editorActGrp,
             "vm_edit_move_down_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+N"))
             )
@@ -1795,7 +1796,7 @@
             self.editorActGrp,
             "vm_edit_move_left_word_part",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Alt+Left"))
             )
@@ -1811,7 +1812,7 @@
             self.editorActGrp,
             "vm_edit_move_right_word_part",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Alt+Right"))
             )
@@ -1827,7 +1828,7 @@
             self.editorActGrp,
             "vm_edit_move_left_word",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Alt+Left"))
             )
@@ -1847,7 +1848,7 @@
             self.editorActGrp,
             "vm_edit_move_right_word",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Ctrl+Right"))
             )
@@ -1867,7 +1868,7 @@
             self.editorActGrp,
             "vm_edit_move_first_visible_char",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Home"))
             )
@@ -1883,7 +1884,7 @@
             self.editorActGrp,
             "vm_edit_move_start_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Ctrl+Left"))
             )
@@ -1903,7 +1904,7 @@
             self.editorActGrp,
             "vm_edit_move_end_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+E"))
             )
@@ -1983,7 +1984,7 @@
             self.editorActGrp,
             "vm_edit_move_down_page",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+V"))
             )
@@ -1999,7 +2000,7 @@
             self.editorActGrp,
             "vm_edit_move_start_text",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Ctrl+Up"))
             )
@@ -2019,7 +2020,7 @@
             self.editorActGrp,
             "vm_edit_move_end_text",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Ctrl+Down"))
             )
@@ -2067,7 +2068,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_left_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+B"))
             )
@@ -2087,7 +2088,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_right_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+F"))
             )
@@ -2103,7 +2104,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_up_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+P"))
             )
@@ -2119,7 +2120,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_down_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+N"))
             )
@@ -2139,7 +2140,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_left_word_part",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Alt+Shift+Left")
@@ -2161,7 +2162,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_right_word_part",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Alt+Shift+Right")
@@ -2179,7 +2180,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_left_word",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Alt+Shift+Left")
@@ -2207,7 +2208,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_right_word",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Alt+Shift+Right")
@@ -2237,7 +2238,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_first_visible_char",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Shift+Home"))
             )
@@ -2257,7 +2258,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_end_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+E"))
             )
@@ -2321,7 +2322,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_down_page",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+Shift+V"))
             )
@@ -2341,7 +2342,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_start_text",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Ctrl+Shift+Up"))
             )
@@ -2367,7 +2368,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_end_text",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Ctrl+Shift+Down")
@@ -2391,7 +2392,7 @@
             self.editorActGrp,
             "vm_edit_delete_previous_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+H"))
             )
@@ -2429,7 +2430,7 @@
             self.editorActGrp,
             "vm_edit_delete_current_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+D"))
             )
@@ -2483,7 +2484,7 @@
             self.editorActGrp,
             "vm_edit_delete_line_right",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Meta+K"))
             )
@@ -2620,7 +2621,7 @@
             self.editorActGrp,
             "vm_edit_move_end_displayed_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(QCoreApplication.translate("ViewManager", "Ctrl+Right"))
             )
@@ -2644,7 +2645,7 @@
             self.editorActGrp,
             "vm_edit_extend_selection_end_displayed_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Ctrl+Shift+Right")
@@ -2690,7 +2691,7 @@
             self.editorActGrp,
             "vm_edit_extend_rect_selection_down_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Meta+Alt+Shift+N")
@@ -2712,7 +2713,7 @@
             self.editorActGrp,
             "vm_edit_extend_rect_selection_up_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Meta+Alt+Shift+P")
@@ -2734,7 +2735,7 @@
             self.editorActGrp,
             "vm_edit_extend_rect_selection_left_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Meta+Alt+Shift+B")
@@ -2756,7 +2757,7 @@
             self.editorActGrp,
             "vm_edit_extend_rect_selection_right_char",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Meta+Alt+Shift+F")
@@ -2782,7 +2783,7 @@
             self.editorActGrp,
             "vm_edit_extend_rect_selection_first_visible_char",
         )
-        if not isMacPlatform():
+        if not OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Alt+Shift+Home")
@@ -2804,7 +2805,7 @@
             self.editorActGrp,
             "vm_edit_extend_rect_selection_end_line",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Meta+Alt+Shift+E")
@@ -2846,7 +2847,7 @@
             self.editorActGrp,
             "vm_edit_extend_rect_selection_down_page",
         )
-        if isMacPlatform():
+        if OSUtilities.isMacPlatform():
             act.setAlternateShortcut(
                 QKeySequence(
                     QCoreApplication.translate("ViewManager", "Meta+Alt+Shift+V")
@@ -2881,7 +2882,7 @@
                 self.editorActGrp,
                 "vm_edit_scroll_start_text",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(QCoreApplication.translate("ViewManager", "Home"))
                 )
@@ -2898,7 +2899,7 @@
                 self.editorActGrp,
                 "vm_edit_scroll_end_text",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(QCoreApplication.translate("ViewManager", "End"))
                 )
@@ -2919,7 +2920,7 @@
                 self.editorActGrp,
                 "vm_edit_scroll_vertically_center",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(QCoreApplication.translate("ViewManager", "Meta+L"))
                 )
@@ -2936,7 +2937,7 @@
                 self.editorActGrp,
                 "vm_edit_move_end_next_word",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(QCoreApplication.translate("ViewManager", "Alt+Right"))
                 )
@@ -2957,7 +2958,7 @@
                 self.editorActGrp,
                 "vm_edit_select_end_next_word",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(
                         QCoreApplication.translate("ViewManager", "Alt+Shift+Right")
@@ -3014,7 +3015,7 @@
                 self.editorActGrp,
                 "vm_edit_move_start_document_line",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(QCoreApplication.translate("ViewManager", "Meta+A"))
                 )
@@ -3035,7 +3036,7 @@
                 self.editorActGrp,
                 "vm_edit_extend_selection_start_document_line",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(
                         QCoreApplication.translate("ViewManager", "Meta+Shift+A")
@@ -3060,7 +3061,7 @@
                 self.editorActGrp,
                 "vm_edit_select_rect_start_line",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(
                         QCoreApplication.translate("ViewManager", "Meta+Alt+Shift+A")
@@ -3083,7 +3084,7 @@
                 self.editorActGrp,
                 "vm_edit_extend_selection_start_display_line",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(
                         QCoreApplication.translate("ViewManager", "Ctrl+Shift+Left")
@@ -3280,7 +3281,7 @@
                 self.editorActGrp,
                 "vm_edit_delete_right_end_next_word",
             )
-            if isMacPlatform():
+            if OSUtilities.isMacPlatform():
                 act.setShortcut(
                     QKeySequence(QCoreApplication.translate("ViewManager", "Alt+Del"))
                 )
@@ -5436,7 +5437,7 @@
         @rtype bool
         """
         for editor in self.editors:
-            if Utilities.samepath(fn, editor.getFileName()):
+            if FileSystemUtilities.samepath(fn, editor.getFileName()):
                 break
         else:
             return True
@@ -5530,7 +5531,7 @@
         @rtype bool
         """
         for editor in self.editors:
-            if Utilities.samepath(fn, editor.getFileName()):
+            if FileSystemUtilities.samepath(fn, editor.getFileName()):
                 break
         else:
             return True
@@ -5748,7 +5749,7 @@
         @param fn name of the file to be added
         """
         for recent in self.recent[:]:
-            if Utilities.samepath(fn, recent):
+            if FileSystemUtilities.samepath(fn, recent):
                 self.recent.remove(recent)
         self.recent.insert(0, fn)
         maxRecent = Preferences.getUI("RecentNumber")
@@ -5953,9 +5954,9 @@
         """
         newWin = False
         editor = self.activeWindow()
-        if editor is None or not Utilities.samepath(fn, editor.getFileName()):
+        if editor is None or not FileSystemUtilities.samepath(fn, editor.getFileName()):
             for editor in self.editors:
-                if Utilities.samepath(fn, editor.getFileName()):
+                if FileSystemUtilities.samepath(fn, editor.getFileName()):
                     break
             else:
                 assembly = EditorAssembly(
@@ -6006,7 +6007,7 @@
             no editor was found
         """
         for editor in self.editors:
-            if Utilities.samepath(fn, editor.getFileName()):
+            if FileSystemUtilities.samepath(fn, editor.getFileName()):
                 return editor
 
         return None
@@ -6020,7 +6021,7 @@
         """
         count = 0
         for editor in self.editors:
-            if Utilities.samepath(fn, editor.getFileName()):
+            if FileSystemUtilities.samepath(fn, editor.getFileName()):
                 count += 1
         return count
 
@@ -6058,7 +6059,7 @@
         @return flag indicating success (boolean)
         """
         for editor in self.editors:
-            if Utilities.samepath(fn, editor.getFileName()):
+            if FileSystemUtilities.samepath(fn, editor.getFileName()):
                 break
         else:
             return True
@@ -6236,7 +6237,7 @@
             formatStr = "&{0:d}. {1}" if idx < 10 else "{0:d}. {1}"
             act = self.recentMenu.addAction(
                 formatStr.format(
-                    idx, Utilities.compactPath(rs, self.ui.maxMenuFilePathLen)
+                    idx, FileSystemUtilities.compactPath(rs, self.ui.maxMenuFilePathLen)
                 )
             )
             act.setData(rs)
@@ -6272,7 +6273,7 @@
 
         for rp in self.bookmarked:
             act = self.bookmarkedMenu.addAction(
-                Utilities.compactPath(rp, self.ui.maxMenuFilePathLen)
+                FileSystemUtilities.compactPath(rp, self.ui.maxMenuFilePathLen)
             )
             act.setData(rp)
             act.setEnabled(pathlib.Path(rp).exists())
@@ -7033,7 +7034,7 @@
                 bmSuffix = " : {0:d}".format(bookmark)
                 act = self.bookmarksMenu.addAction(
                     "{0}{1}".format(
-                        Utilities.compactPath(
+                        FileSystemUtilities.compactPath(
                             filename, self.ui.maxMenuFilePathLen - len(bmSuffix)
                         ),
                         bmSuffix,
@@ -7853,7 +7854,7 @@
             return ericApp().getObject("Project").ppath
 
         else:
-            return Preferences.getMultiProject("Workspace") or Utilities.getHomeDir()
+            return Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir()
 
     def _getOpenFileFilter(self):
         """
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/VirtualEnv/VirtualenvAddEditDialog.py
--- a/src/eric7/VirtualEnv/VirtualenvAddEditDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/VirtualEnv/VirtualenvAddEditDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,8 +12,8 @@
 from PyQt6.QtCore import Qt, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Globals, Utilities
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import OSUtilities, PythonUtilities
 
 from .Ui_VirtualenvAddEditDialog import Ui_VirtualenvAddEditDialog
 
@@ -78,7 +78,7 @@
 
         self.__envBaseDir = baseDir
         if not self.__envBaseDir:
-            self.__envBaseDir = Utilities.getHomeDir()
+            self.__envBaseDir = OSUtilities.getHomeDir()
 
         self.targetDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
         self.targetDirectoryPicker.setWindowTitle(
@@ -88,7 +88,7 @@
 
         self.pythonExecPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
         self.pythonExecPicker.setWindowTitle(self.tr("Python Interpreter"))
-        self.pythonExecPicker.setDefaultDirectory(Globals.getPythonExecutable())
+        self.pythonExecPicker.setDefaultDirectory(PythonUtilities.getPythonExecutable())
 
         self.execPathEdit.setToolTip(
             self.tr(
@@ -167,7 +167,7 @@
         """
         if venvDirectory:
             # try to determine a Python interpreter name
-            if Utilities.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 candidates = (
                     os.path.join(venvDirectory, "Scripts", "python.exe"),
                     os.path.join(venvDirectory, "python.exe"),
@@ -203,7 +203,9 @@
         if txt:
             self.pythonExecPicker.setDefaultDirectory(txt)
         else:
-            self.pythonExecPicker.setDefaultDirectory(Globals.getPythonExecutable())
+            self.pythonExecPicker.setDefaultDirectory(
+                PythonUtilities.getPythonExecutable()
+            )
         py = self.__detectPythonInterpreter(txt)
         if py:
             self.pythonExecPicker.setText(py)
@@ -248,7 +250,7 @@
         """
         if checked and not bool(self.execPathEdit.text()):
             # prepopulate the execPathEdit widget
-            if Utilities.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 self.execPathEdit.setText(
                     os.pathsep.join(
                         [
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/VirtualEnv/VirtualenvConfigurationDialog.py
--- a/src/eric7/VirtualEnv/VirtualenvConfigurationDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/VirtualEnv/VirtualenvConfigurationDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,9 +14,10 @@
 from PyQt6.QtCore import QProcess, QTimer, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import CondaInterface, Globals, Preferences, Utilities
+from eric7 import CondaInterface, Preferences
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities, PythonUtilities
 
 from .Ui_VirtualenvConfigurationDialog import Ui_VirtualenvConfigurationDialog
 
@@ -40,7 +41,7 @@
         self.setupUi(self)
 
         if not baseDir:
-            baseDir = Utilities.getHomeDir()
+            baseDir = OSUtilities.getHomeDir()
         self.__envBaseDir = baseDir
 
         self.targetDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
@@ -54,29 +55,29 @@
         self.extraSearchPathPicker.setWindowTitle(
             self.tr("Extra Search Path for setuptools/pip")
         )
-        self.extraSearchPathPicker.setDefaultDirectory(Utilities.getHomeDir())
+        self.extraSearchPathPicker.setDefaultDirectory(OSUtilities.getHomeDir())
 
         self.pythonExecPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
         self.pythonExecPicker.setWindowTitle(self.tr("Python Interpreter"))
-        self.pythonExecPicker.setDefaultDirectory(Globals.getPythonExecutable())
+        self.pythonExecPicker.setDefaultDirectory(PythonUtilities.getPythonExecutable())
 
         self.condaTargetDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
         self.condaTargetDirectoryPicker.setWindowTitle(
             self.tr("Conda Environment Location")
         )
-        self.condaTargetDirectoryPicker.setDefaultDirectory(Utilities.getHomeDir())
+        self.condaTargetDirectoryPicker.setDefaultDirectory(OSUtilities.getHomeDir())
 
         self.condaCloneDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
         self.condaCloneDirectoryPicker.setWindowTitle(
             self.tr("Conda Environment Location")
         )
-        self.condaCloneDirectoryPicker.setDefaultDirectory(Utilities.getHomeDir())
+        self.condaCloneDirectoryPicker.setDefaultDirectory(OSUtilities.getHomeDir())
 
         self.condaRequirementsFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
         self.condaRequirementsFilePicker.setWindowTitle(
             self.tr("Conda Requirements File")
         )
-        self.condaRequirementsFilePicker.setDefaultDirectory(Utilities.getHomeDir())
+        self.condaRequirementsFilePicker.setDefaultDirectory(OSUtilities.getHomeDir())
         self.condaRequirementsFilePicker.setFilters(
             self.tr("Text Files (*.txt);;All Files (*)")
         )
@@ -323,7 +324,10 @@
             )
         calls.extend(
             [
-                (Globals.getPythonExecutable(), ["-m", "virtualenv", "--version"]),
+                (
+                    PythonUtilities.getPythonExecutable(),
+                    ["-m", "virtualenv", "--version"],
+                ),
                 ("virtualenv", ["--version"]),
             ]
         )
@@ -379,7 +383,7 @@
             calls.append((self.pythonExecPicker.text(), ["-m", "venv"]))
         calls.extend(
             [
-                (Globals.getPythonExecutable(), ["-m", "venv"]),
+                (PythonUtilities.getPythonExecutable(), ["-m", "venv"]),
                 ("python3", ["-m", "venv"]),
                 ("python", ["-m", "venv"]),
             ]
@@ -446,7 +450,7 @@
         @return target directory path
         @rtype str
         """
-        targetDirectory = Utilities.toNativeSeparators(
+        targetDirectory = FileSystemUtilities.toNativeSeparators(
             self.targetDirectoryPicker.text()
         )
         if not os.path.isabs(targetDirectory):
@@ -488,7 +492,7 @@
                 if self.extraSearchPathPicker.text():
                     args.append(
                         "--extra-search-dir={0}".format(
-                            Utilities.toNativeSeparators(
+                            FileSystemUtilities.toNativeSeparators(
                                 self.extraSearchPathPicker.text()
                             )
                         )
@@ -502,7 +506,9 @@
                 if self.pythonExecPicker.text():
                     args.append(
                         "--python={0}".format(
-                            Utilities.toNativeSeparators(self.pythonExecPicker.text())
+                            FileSystemUtilities.toNativeSeparators(
+                                self.pythonExecPicker.text()
+                            )
                         )
                     )
                 elif self.versionComboBox.currentText():
@@ -583,7 +589,7 @@
                     "createLog": self.logCheckBox.isChecked(),
                     "createScript": self.scriptCheckBox.isChecked(),
                     "targetDirectory": self.__generateTargetDir(),
-                    "pythonExe": Utilities.toNativeSeparators(
+                    "pythonExe": FileSystemUtilities.toNativeSeparators(
                         self.pythonExecPicker.text()
                     ),
                 }
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/VirtualEnv/VirtualenvExecDialog.py
--- a/src/eric7/VirtualEnv/VirtualenvExecDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/VirtualEnv/VirtualenvExecDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,7 +14,7 @@
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
 from eric7 import Preferences
-from eric7.Globals import getPythonExecutable, isWindowsPlatform
+from eric7.SystemUtilities import OSUtilities, PythonUtilities
 
 from .Ui_VirtualenvExecDialog import Ui_VirtualenvExecDialog
 
@@ -62,14 +62,14 @@
                 self.__calls.append((configuration["pythonExe"], ["-m", "venv"]))
             self.__calls.extend(
                 [
-                    (getPythonExecutable(), ["-m", "venv"]),
+                    (PythonUtilities.getPythonExecutable(), ["-m", "venv"]),
                     ("python3", ["-m", "venv"]),
                     ("python", ["-m", "venv"]),
                 ]
             )
         else:
             self.__calls = [
-                (getPythonExecutable(), ["-m", "virtualenv"]),
+                (PythonUtilities.getPythonExecutable(), ["-m", "virtualenv"]),
                 ("virtualenv", []),
             ]
         self.__callIndex = 0
@@ -281,7 +281,7 @@
         Private method to write a script file to the virtualenv directory.
         """
         basename = "create_pyvenv" if self.__pyvenv else "create_virtualenv"
-        if isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             script = os.path.join(self.__targetDir, basename + ".cmd")
             txt = self.__cmd
         else:
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/VirtualEnv/VirtualenvInterpreterSelectionDialog.py
--- a/src/eric7/VirtualEnv/VirtualenvInterpreterSelectionDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/VirtualEnv/VirtualenvInterpreterSelectionDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,8 +14,8 @@
 from PyQt6.QtCore import pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Globals
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import OSUtilities
 
 from .Ui_VirtualenvInterpreterSelectionDialog import (
     Ui_VirtualenvInterpreterSelectionDialog,
@@ -52,7 +52,7 @@
 
         if venvDirectory:
             # try to determine a Python interpreter name
-            if Globals.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 candidates = glob.glob(
                     os.path.join(venvDirectory, "Scripts", "python*.exe")
                 ) + glob.glob(os.path.join(venvDirectory, "python*.exe"))
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/VirtualEnv/VirtualenvManager.py
--- a/src/eric7/VirtualEnv/VirtualenvManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/VirtualEnv/VirtualenvManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -16,9 +16,10 @@
 from PyQt6.QtCore import QObject, pyqtSignal, pyqtSlot
 from PyQt6.QtWidgets import QDialog
 
-from eric7 import Globals, Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import FileSystemUtilities, PythonUtilities
 from eric7.UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
 
 
@@ -107,7 +108,7 @@
             del environments[venvName]
 
         # check, if the interpreter used to run eric is in the environments
-        defaultPy = Globals.getPythonExecutable()
+        defaultPy = PythonUtilities.getPythonExecutable()
         if "{0}.venv{0}".format(os.sep) not in defaultPy:
             # only check for a non-embedded environment
             found = False
@@ -184,9 +185,9 @@
             containing a copy of the default virtual environment
         @rtype tuple of (str, dict)
         """
-        py = Utilities.normcaseabspath(interpreter.replace("w.exe", ".exe"))
+        py = FileSystemUtilities.normcaseabspath(interpreter.replace("w.exe", ".exe"))
         for venvName in self.__virtualEnvironments:
-            if py == Utilities.normcaseabspath(
+            if py == FileSystemUtilities.normcaseabspath(
                 self.__virtualEnvironments[venvName]["interpreter"]
             ):
                 return (venvName, copy.copy(self.__virtualEnvironments[venvName]))
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/VirtualEnv/VirtualenvManagerWidgets.py
--- a/src/eric7/VirtualEnv/VirtualenvManagerWidgets.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/VirtualEnv/VirtualenvManagerWidgets.py	Sun Dec 18 19:33:46 2022 +0100
@@ -20,10 +20,10 @@
     QWidget,
 )
 
-from eric7 import Utilities
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets.EricMainWindow import EricMainWindow
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import OSUtilities
 
 from .Ui_VirtualenvManagerWidget import Ui_VirtualenvManagerWidget
 
@@ -69,7 +69,7 @@
 
         baseDir = self.__manager.getVirtualEnvironmentsBaseDir()
         if not baseDir:
-            baseDir = Utilities.getHomeDir()
+            baseDir = OSUtilities.getHomeDir()
 
         self.envBaseDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
         self.envBaseDirectoryPicker.setWindowTitle(self.tr("Virtualenv Base Directory"))
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/VirtualEnv/VirtualenvUpgradeConfigurationDialog.py
--- a/src/eric7/VirtualEnv/VirtualenvUpgradeConfigurationDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/VirtualEnv/VirtualenvUpgradeConfigurationDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,8 +13,9 @@
 from PyQt6.QtCore import QProcess, QTimer, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
-from eric7 import Globals, Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import FileSystemUtilities, PythonUtilities
 
 from .Ui_VirtualenvUpgradeConfigurationDialog import (
     Ui_VirtualenvUpgradeConfigurationDialog,
@@ -45,7 +46,7 @@
 
         self.pythonExecPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
         self.pythonExecPicker.setWindowTitle(self.tr("Python Interpreter"))
-        self.pythonExecPicker.setDefaultDirectory(Globals.getPythonExecutable())
+        self.pythonExecPicker.setDefaultDirectory(PythonUtilities.getPythonExecutable())
 
         self.envNameLabel.setText(envName)
         self.envDirectoryLabel.setText(envPath)
@@ -73,7 +74,7 @@
             calls.append((self.pythonExecPicker.text(), ["-m", "venv"]))
         calls.extend(
             [
-                (Globals.getPythonExecutable(), ["-m", "venv"]),
+                (PythonUtilities.getPythonExecutable(), ["-m", "venv"]),
                 ("python3", ["-m", "venv"]),
                 ("python", ["-m", "venv"]),
             ]
@@ -149,7 +150,7 @@
         args.append(self.envDirectoryLabel.text())
 
         return (
-            Utilities.toNativeSeparators(self.pythonExecPicker.text()),
+            FileSystemUtilities.toNativeSeparators(self.pythonExecPicker.text()),
             args,
             self.logCheckBox.isChecked(),
         )
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/VirtualEnv/VirtualenvUpgradeExecDialog.py
--- a/src/eric7/VirtualEnv/VirtualenvUpgradeExecDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/VirtualEnv/VirtualenvUpgradeExecDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,7 +13,7 @@
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
 
 from eric7 import Preferences
-from eric7.Globals import getPythonExecutable
+from eric7.SystemUtilities import PythonUtilities
 
 from .Ui_VirtualenvExecDialog import Ui_VirtualenvExecDialog
 
@@ -52,7 +52,7 @@
             self.__progs.append(interpreter)
         self.__progs.extend(
             [
-                getPythonExecutable(),
+                PythonUtilities.getPythonExecutable(),
                 "python3",
                 "python",
             ]
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/AdBlock/AdBlockManager.py
--- a/src/eric7/WebBrowser/AdBlock/AdBlockManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/AdBlock/AdBlockManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -13,7 +13,7 @@
 from PyQt6.QtCore import QByteArray, QMutex, QObject, QUrl, QUrlQuery, pyqtSignal
 from PyQt6.QtWebEngineCore import QWebEngineUrlRequestInfo
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricUtilities.EricMutexLocker import EricMutexLocker
 from eric7.EricWidgets import EricMessageBox
 from eric7.Utilities.AutoSaver import AutoSaver
@@ -206,7 +206,7 @@
         @return URL for custom subscriptions
         @rtype QUrl
         """
-        dataDir = os.path.join(Utilities.getConfigDir(), "web_browser", "subscriptions")
+        dataDir = os.path.join(Globals.getConfigDir(), "web_browser", "subscriptions")
         if not os.path.exists(dataDir):
             os.makedirs(dataDir)
         fileName = os.path.join(dataDir, "adblock_subscription_custom")
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/AdBlock/AdBlockSubscription.py
--- a/src/eric7/WebBrowser/AdBlock/AdBlockSubscription.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/AdBlock/AdBlockSubscription.py	Sun Dec 18 19:33:46 2022 +0100
@@ -26,7 +26,7 @@
 )
 from PyQt6.QtNetwork import QNetworkReply, QNetworkRequest
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricWidgets import EricMessageBox
 from eric7.WebBrowser.WebBrowserWindow import WebBrowserWindow
 
@@ -281,7 +281,7 @@
                 self.__location, QCryptographicHash.Algorithm.Sha1
             ).toHex()
         ).decode()
-        dataDir = os.path.join(Utilities.getConfigDir(), "web_browser", "subscriptions")
+        dataDir = os.path.join(Globals.getConfigDir(), "web_browser", "subscriptions")
         if not os.path.exists(dataDir):
             os.makedirs(dataDir)
         fileName = os.path.join(dataDir, "adblock_subscription_{0}".format(sha1))
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/Bookmarks/BookmarksImportDialog.py
--- a/src/eric7/WebBrowser/Bookmarks/BookmarksImportDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/Bookmarks/BookmarksImportDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,9 +12,9 @@
 from PyQt6.QtCore import QSize, Qt, pyqtSlot
 from PyQt6.QtWidgets import QDialog, QListWidgetItem
 
-from eric7 import Globals
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
+from eric7.SystemUtilities import OSUtilities
 
 from . import BookmarksImporters
 from .Ui_BookmarksImportDialog import Ui_BookmarksImportDialog
@@ -118,7 +118,7 @@
                 self.filePicker.setText(self.__sourceDir)
             else:
                 self.filePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
-                if Globals.isMacPlatform():
+                if OSUtilities.isMacPlatform():
                     fileFilter = "*{0}".format(os.path.splitext(self.__sourceFile)[1])
                 else:
                     fileFilter = self.__sourceFile
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/Bookmarks/BookmarksImporters/ChromeImporter.py
--- a/src/eric7/WebBrowser/Bookmarks/BookmarksImporters/ChromeImporter.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/Bookmarks/BookmarksImporters/ChromeImporter.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,8 +12,8 @@
 
 from PyQt6.QtCore import QCoreApplication, QDate, Qt
 
-from eric7 import Globals
 from eric7.EricGui import EricPixmapCache
+from eric7.SystemUtilities import OSUtilities
 
 from .BookmarksImporter import BookmarksImporter
 
@@ -33,11 +33,11 @@
         raise ValueError("Unsupported browser ID given ({0}).".format(sourceId))
 
     if sourceId == "chrome":
-        if Globals.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             standardDir = os.path.expandvars(
                 "%USERPROFILE%\\AppData\\Local\\Google\\Chrome\\User Data\\Default"
             )
-        elif Globals.isMacPlatform():
+        elif OSUtilities.isMacPlatform():
             standardDir = os.path.expanduser(
                 "~/Library/Application Support/Google/Chrome/Default"
             )
@@ -61,7 +61,7 @@
         )
 
     elif sourceId == "chromium":
-        if Globals.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             standardDir = os.path.expandvars(
                 "%USERPROFILE%\\AppData\\Local\\Google\\Chrome\\User Data\\Default"
             )
@@ -84,7 +84,7 @@
         )
 
     elif sourceId == "edge":
-        if Globals.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             standardDir = os.path.expandvars(
                 "%USERPROFILE%\\AppData\\Local\\Microsoft\\Edge\\User Data\\Default"
             )
@@ -108,7 +108,7 @@
         )
 
     elif sourceId == "falkon":
-        if Globals.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             standardDir = os.path.expandvars(
                 "%USERPROFILE%\\AppData\\Local\\falkon\\profiles\\default"
             )
@@ -132,7 +132,7 @@
         )
 
     elif sourceId == "opera":
-        if Globals.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             standardDir = os.path.expandvars(
                 "%USERPROFILE%\\AppData\\Roaming\\Opera Software\\Opera Stable"
             )
@@ -156,7 +156,7 @@
         )
 
     elif sourceId == "vivaldi":
-        if Globals.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             standardDir = os.path.expandvars(
                 "%USERPROFILE%\\AppData\\Local\\Vivaldi\\User Data\\Default"
             )
@@ -182,7 +182,7 @@
     # entry if an unknown source is given
     standardDir = (
         os.path.expandvars("%USERPROFILE%\\AppData")
-        if Globals.isWindowsPlatform()
+        if OSUtilities.isWindowsPlatform()
         else os.path.expanduser("~/.config")
     )
     return (
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/Bookmarks/BookmarksImporters/FirefoxImporter.py
--- a/src/eric7/WebBrowser/Bookmarks/BookmarksImporters/FirefoxImporter.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/Bookmarks/BookmarksImporters/FirefoxImporter.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,8 +12,8 @@
 
 from PyQt6.QtCore import QCoreApplication, QDate, Qt, QUrl
 
-from eric7 import Globals
 from eric7.EricGui import EricPixmapCache
+from eric7.SystemUtilities import OSUtilities
 
 from .BookmarksImporter import BookmarksImporter
 
@@ -32,9 +32,9 @@
     if sourceId != "firefox":
         raise ValueError("Unsupported browser ID given ({0}).".format(sourceId))
 
-    if Globals.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         standardDir = os.path.expandvars("%APPDATA%\\Mozilla\\Firefox\\Profiles")
-    elif Globals.isMacPlatform():
+    elif OSUtilities.isMacPlatform():
         standardDir = os.path.expanduser(
             "~/Library/Application Support/Firefox/Profiles"
         )
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/Bookmarks/BookmarksImporters/IExplorerImporter.py
--- a/src/eric7/WebBrowser/Bookmarks/BookmarksImporters/IExplorerImporter.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/Bookmarks/BookmarksImporters/IExplorerImporter.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,8 +11,8 @@
 
 from PyQt6.QtCore import QCoreApplication, QDate, Qt
 
-from eric7 import Globals
 from eric7.EricGui import EricPixmapCache
+from eric7.SystemUtilities import OSUtilities
 
 from .BookmarksImporter import BookmarksImporter
 
@@ -33,7 +33,7 @@
 
     standardDir = (
         os.path.expandvars("%USERPROFILE%\\Favorites")
-        if Globals.isWindowsPlatform()
+        if OSUtilities.isWindowsPlatform()
         else ""
     )
     return (
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/Bookmarks/BookmarksImporters/OperaImporter.py
--- a/src/eric7/WebBrowser/Bookmarks/BookmarksImporters/OperaImporter.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/Bookmarks/BookmarksImporters/OperaImporter.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,8 +11,8 @@
 
 from PyQt6.QtCore import QCoreApplication, QDate, Qt
 
-from eric7 import Globals
 from eric7.EricGui import EricPixmapCache
+from eric7.SystemUtilities import OSUtilities
 
 from .BookmarksImporter import BookmarksImporter
 
@@ -31,9 +31,9 @@
     if sourceId != "opera_legacy":
         raise ValueError("Unsupported browser ID given ({0}).".format(sourceId))
 
-    if Globals.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         standardDir = os.path.expandvars("%APPDATA%\\Opera\\Opera")
-    elif Globals.isMacPlatform():
+    elif OSUtilities.isMacPlatform():
         standardDir = os.path.expanduser("~/Library/Opera")
     else:
         standardDir = os.path.expanduser("~/.opera")
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/Bookmarks/BookmarksImporters/SafariImporter.py
--- a/src/eric7/WebBrowser/Bookmarks/BookmarksImporters/SafariImporter.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/Bookmarks/BookmarksImporters/SafariImporter.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,8 +12,8 @@
 
 from PyQt6.QtCore import QCoreApplication, QDate, Qt
 
-from eric7 import Globals
 from eric7.EricGui import EricPixmapCache
+from eric7.SystemUtilities import OSUtilities
 
 from .BookmarksImporter import BookmarksImporter
 
@@ -32,9 +32,9 @@
     if sourceId != "safari":
         raise ValueError("Unsupported browser ID given ({0}).".format(sourceId))
 
-    if Globals.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         standardDir = os.path.expandvars("%APPDATA%\\Apple Computer\\Safari")
-    elif Globals.isMacPlatform():
+    elif OSUtilities.isMacPlatform():
         standardDir = os.path.expanduser("~/Library/Safari")
     else:
         standardDir = ""
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/Bookmarks/BookmarksImporters/__init__.py
--- a/src/eric7/WebBrowser/Bookmarks/BookmarksImporters/__init__.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/Bookmarks/BookmarksImporters/__init__.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,8 +11,8 @@
 
 from PyQt6.QtCore import QCoreApplication
 
-from eric7 import Globals
 from eric7.EricGui import EricPixmapCache
+from eric7.SystemUtilities import OSUtilities
 
 
 def getImporters():
@@ -44,13 +44,13 @@
         (EricPixmapCache.getIcon("falkon"), "Falkon", "falkon"),
     ]
 
-    if Globals.isLinuxPlatform():
+    if OSUtilities.isLinuxPlatform():
         importers.append((EricPixmapCache.getIcon("chromium"), "Chromium", "chromium"))
         importers.append(
             (EricPixmapCache.getIcon("konqueror"), "Konqueror", "konqueror")
         )
 
-    if Globals.isWindowsPlatform():
+    if OSUtilities.isWindowsPlatform():
         importers.append(
             (EricPixmapCache.getIcon("internet_explorer"), "Internet Explorer", "ie")
         )
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/Bookmarks/BookmarksManager.py
--- a/src/eric7/WebBrowser/Bookmarks/BookmarksManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/Bookmarks/BookmarksManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -25,7 +25,7 @@
 from PyQt6.QtGui import QUndoCommand, QUndoStack
 from PyQt6.QtWidgets import QDialog
 
-from eric7 import Utilities
+from eric7 import Globals
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.Utilities.AutoSaver import AutoSaver
 
@@ -92,7 +92,7 @@
 
         @return name of the bookmark file (string)
         """
-        return os.path.join(Utilities.getConfigDir(), "web_browser", "bookmarks.xbel")
+        return os.path.join(Globals.getConfigDir(), "web_browser", "bookmarks.xbel")
 
     def close(self):
         """
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/CookieJar/CookieJar.py
--- a/src/eric7/WebBrowser/CookieJar/CookieJar.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/CookieJar/CookieJar.py	Sun Dec 18 19:33:46 2022 +0100
@@ -12,7 +12,7 @@
 from PyQt6.QtCore import QSettings, pyqtSignal, pyqtSlot
 from PyQt6.QtNetwork import QNetworkCookie, QNetworkCookieJar
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.Utilities.AutoSaver import AutoSaver
 from eric7.WebBrowser.WebBrowserWindow import WebBrowserWindow
 
@@ -53,7 +53,7 @@
         self.__saveTimer = AutoSaver(self, self.__save)
 
         self.__cookiesFile = os.path.join(
-            Utilities.getConfigDir(), "web_browser", "cookies.ini"
+            Globals.getConfigDir(), "web_browser", "cookies.ini"
         )
 
         self.__store = WebBrowserWindow.webProfile().cookieStore()
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/Download/DownloadManager.py
--- a/src/eric7/WebBrowser/Download/DownloadManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/Download/DownloadManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -19,10 +19,11 @@
 from PyQt6.QtGui import QCursor, QKeySequence, QShortcut
 from PyQt6.QtWidgets import QApplication, QDialog, QFileIconProvider, QMenu, QStyle
 
-from eric7 import Globals, Preferences
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
+from eric7.SystemUtilities import OSUtilities
 from eric7.Utilities.AutoSaver import AutoSaver
 from eric7.WebBrowser.WebBrowserWindow import WebBrowserWindow
 
@@ -507,7 +508,7 @@
             self.__stopUpdateTimer()
             self.infoLabel.clear()
             self.setWindowTitle(self.tr("Download Manager"))
-            if Globals.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 self.__taskbarButton().progress().hide()
 
             if Preferences.getWebBrowser("DownloadManagerAutoClose"):
@@ -562,7 +563,7 @@
         @return reference to the task bar button
         @rtype QWinTaskbarButton or None
         """
-        if Globals.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             from PyQt6.QtWinExtras import QWinTaskbarButton  # __IGNORE_WARNING_I10__
 
             if self.__winTaskbarButton is None:
@@ -584,7 +585,7 @@
                 self.__stopUpdateTimer()
                 self.infoLabel.clear()
                 self.setWindowTitle(self.tr("Download Manager"))
-                if Globals.isWindowsPlatform():
+                if OSUtilities.isWindowsPlatform():
                     self.__taskbarButton().progress().hide()
             else:
                 progresses = []
@@ -626,7 +627,7 @@
                     )
                     self.setWindowTitle(self.tr("{0}% - Download Manager"))
 
-                if Globals.isWindowsPlatform():
+                if OSUtilities.isWindowsPlatform():
                     self.__taskbarButton().progress().show()
                     self.__taskbarButton().progress().setValue(progress)
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyConfiguration/GreaseMonkeyConfigurationListDelegate.py
--- a/src/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyConfiguration/GreaseMonkeyConfigurationListDelegate.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyConfiguration/GreaseMonkeyConfigurationListDelegate.py	Sun Dec 18 19:33:46 2022 +0100
@@ -17,8 +17,8 @@
     QStyleOptionViewItem,
 )
 
-from eric7 import Globals
 from eric7.EricGui import EricPixmapCache
+from eric7.SystemUtilities import OSUtilities
 
 
 class GreaseMonkeyConfigurationListDelegate(QStyledItemDelegate):
@@ -79,7 +79,7 @@
         titleMetrics = QFontMetrics(titleFont)
         colorRole = (
             QPalette.ColorRole.Text
-            if Globals.isWindowsPlatform()
+            if OSUtilities.isWindowsPlatform()
             else (
                 QPalette.ColorRole.HighlightedText
                 if opt.state & QStyle.StateFlag.State_Selected
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyManager.py
--- a/src/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -26,7 +26,7 @@
 )
 from PyQt6.QtWidgets import QDialog
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricWidgets import EricMessageBox
 from eric7.WebBrowser.JavaScript.ExternalJsObject import ExternalJsObject
 from eric7.WebBrowser.WebBrowserWindow import WebBrowserWindow
@@ -151,7 +151,7 @@
 
         @return path of the scripts directory (string)
         """
-        return os.path.join(Utilities.getConfigDir(), "web_browser", "greasemonkey")
+        return os.path.join(Globals.getConfigDir(), "web_browser", "greasemonkey")
 
     def requireScriptsDirectory(self):
         """
@@ -341,7 +341,7 @@
 
         self.__jsObject.setSettingsFile(
             os.path.join(
-                Utilities.getConfigDir(), "web_browser", "greasemonkey_values.ini"
+                Globals.getConfigDir(), "web_browser", "greasemonkey_values.ini"
             )
         )
         ExternalJsObject.registerExtraObject("GreaseMonkey", self.__jsObject)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/History/HistoryManager.py
--- a/src/eric7/WebBrowser/History/HistoryManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/History/HistoryManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -26,7 +26,7 @@
     pyqtSlot,
 )
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences, Utilities
 from eric7.EricWidgets import EricMessageBox
 from eric7.Utilities.AutoSaver import AutoSaver
 
@@ -439,7 +439,7 @@
 
         @return name of the history file (string)
         """
-        return os.path.join(Utilities.getConfigDir(), "web_browser", "history")
+        return os.path.join(Globals.getConfigDir(), "web_browser", "history")
 
     def reload(self):
         """
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/Network/ProtocolHandlerManager.py
--- a/src/eric7/WebBrowser/Network/ProtocolHandlerManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/Network/ProtocolHandlerManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,7 +14,7 @@
 from PyQt6.QtCore import QObject, QUrl
 from PyQt6.QtWebEngineCore import QWebEnginePage
 
-from eric7 import Utilities
+from eric7 import Globals
 
 
 class ProtocolHandlerManager(QObject):
@@ -93,7 +93,7 @@
         @rtype str
         """
         return os.path.join(
-            Utilities.getConfigDir(), "web_browser", "protocol_handlers.json"
+            Globals.getConfigDir(), "web_browser", "protocol_handlers.json"
         )
 
     def __load(self):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/OpenSearch/OpenSearchManager.py
--- a/src/eric7/WebBrowser/OpenSearch/OpenSearchManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/OpenSearch/OpenSearchManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,7 +14,7 @@
 from PyQt6.QtNetwork import QNetworkReply, QNetworkRequest
 from PyQt6.QtWidgets import QInputDialog, QLineEdit
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.Utilities.AutoSaver import AutoSaver
@@ -442,7 +442,7 @@
 
         @return directory name (string)
         """
-        return os.path.join(Utilities.getConfigDir(), "web_browser", "searchengines")
+        return os.path.join(Globals.getConfigDir(), "web_browser", "searchengines")
 
     def __confirmAddition(self, engine):
         """
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/Passwords/PasswordManager.py
--- a/src/eric7/WebBrowser/Passwords/PasswordManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/Passwords/PasswordManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -20,7 +20,7 @@
 from PyQt6.QtWebEngineCore import QWebEngineScript
 from PyQt6.QtWidgets import QApplication
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricProgressDialog import EricProgressDialog
 from eric7.Utilities import crypto
@@ -144,7 +144,7 @@
 
         @return name of the passwords file (string)
         """
-        return os.path.join(Utilities.getConfigDir(), "web_browser", "logins.xml")
+        return os.path.join(Globals.getConfigDir(), "web_browser", "logins.xml")
 
     def save(self):
         """
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/QtHelp/HelpDocsInstaller.py
--- a/src/eric7/WebBrowser/QtHelp/HelpDocsInstaller.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/QtHelp/HelpDocsInstaller.py	Sun Dec 18 19:33:46 2022 +0100
@@ -14,7 +14,8 @@
 from PyQt6.QtCore import QLibraryInfo, QMutex, QThread, pyqtSignal
 from PyQt6.QtHelp import QHelpEngineCore
 
-from eric7.Globals import getConfig, qVersionTuple
+from eric7.Globals import getConfig
+from eric7.SystemUtilities import QtUtilities
 
 
 class HelpDocsInstaller(QThread):
@@ -207,7 +208,9 @@
             )
             if not docsPath.is_dir() or len(list(docsPath.glob("*.qch"))) == 0:
                 docsPath = (
-                    docsPath.parents[2] / "Docs" / "Qt-{0}.{1}".format(*qVersionTuple())
+                    docsPath.parents[2]
+                    / "Docs"
+                    / "Qt-{0}.{1}".format(*QtUtilities.qVersionTuple())
                 )
         else:
             # unsupported Qt version
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/SafeBrowsing/SafeBrowsingManager.py
--- a/src/eric7/WebBrowser/SafeBrowsing/SafeBrowsingManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/SafeBrowsing/SafeBrowsingManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -27,8 +27,9 @@
     pyqtSlot,
 )
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricGui import EricPixmapCache
+from eric7.SystemUtilities import OSUtilities
 from eric7.UI.NotificationWidget import NotificationTypes
 from eric7.WebBrowser.WebBrowserWindow import WebBrowserWindow
 
@@ -67,7 +68,7 @@
             self.__apiClient = None
 
         gsbCachePath = os.path.join(
-            Utilities.getConfigDir(), "web_browser", "safe_browsing"
+            Globals.getConfigDir(), "web_browser", "safe_browsing"
         )
         self.__cache = SafeBrowsingCache(gsbCachePath, self)
 
@@ -110,9 +111,9 @@
         """
         self.__platforms = None
         if Preferences.getWebBrowser("SafeBrowsingFilterPlatform"):
-            if Utilities.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 platform = "windows"
-            elif Utilities.isMacPlatform():
+            elif OSUtilities.isMacPlatform():
                 platform = "macos"
             else:
                 # treat all other platforms like linux
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/Session/SessionManager.py
--- a/src/eric7/WebBrowser/Session/SessionManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/Session/SessionManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -39,7 +39,7 @@
     QVBoxLayout,
 )
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricGui.EricOverrideCursor import EricOverrideCursor
 from eric7.EricWidgets import EricMessageBox
 from eric7.WebBrowser.WebBrowserWindow import WebBrowserWindow
@@ -133,7 +133,7 @@
         @return name of the sessions directory
         @rtype str
         """
-        return os.path.join(Utilities.getConfigDir(), "web_browser", "sessions")
+        return os.path.join(Globals.getConfigDir(), "web_browser", "sessions")
 
     def defaultSessionFile(self):
         """
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/SpeedDial/SpeedDial.py
--- a/src/eric7/WebBrowser/SpeedDial/SpeedDial.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/SpeedDial/SpeedDial.py	Sun Dec 18 19:33:46 2022 +0100
@@ -19,7 +19,7 @@
     qWarning,
 )
 
-from eric7 import Utilities
+from eric7 import Globals, Utilities
 from eric7.EricWidgets import EricMessageBox
 from eric7.Utilities.AutoSaver import AutoSaver
 
@@ -150,14 +150,14 @@
 
         @return name of the user agents file (string)
         """
-        return os.path.join(Utilities.getConfigDir(), "web_browser", "speedDial.xml")
+        return os.path.join(Globals.getConfigDir(), "web_browser", "speedDial.xml")
 
     def __initialize(self):
         """
         Private method to initialize the speed dial.
         """
         self.__thumbnailsDirectory = os.path.join(
-            Utilities.getConfigDir(), "web_browser", "thumbnails"
+            Globals.getConfigDir(), "web_browser", "thumbnails"
         )
         # Create directory if it does not exist yet
         if not os.path.exists(self.__thumbnailsDirectory):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/Sync/SyncAssistantDialog.py
--- a/src/eric7/WebBrowser/Sync/SyncAssistantDialog.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/Sync/SyncAssistantDialog.py	Sun Dec 18 19:33:46 2022 +0100
@@ -9,8 +9,8 @@
 
 from PyQt6.QtWidgets import QWizard
 
-from eric7 import Globals
 from eric7.EricGui import EricPixmapCache
+from eric7.SystemUtilities import OSUtilities
 
 from . import SyncGlobals
 from .SyncCheckPage import SyncCheckPage
@@ -52,7 +52,7 @@
         )
 
         self.setMinimumSize(650, 450)
-        if Globals.isWindowsPlatform():
+        if OSUtilities.isWindowsPlatform():
             self.setWizardStyle(QWizard.WizardStyle.ModernStyle)
 
         self.setOption(QWizard.WizardOption.NoCancelButtonOnLastPage, True)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/TabManager/TabManagerWidget.py
--- a/src/eric7/WebBrowser/TabManager/TabManagerWidget.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/TabManager/TabManagerWidget.py	Sun Dec 18 19:33:46 2022 +0100
@@ -26,7 +26,7 @@
     QWidget,
 )
 
-from eric7 import Preferences, Utilities
+from eric7 import Globals, Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricNetwork import EricNetworkUtilities, EricTldExtractor
 from eric7.EricWidgets.EricApplication import ericApp
@@ -87,7 +87,7 @@
         if TabManagerWidget._tldExtractor is None:
             TabManagerWidget._tldExtractor = EricTldExtractor.instance()
             TabManagerWidget._tldExtractor.setDataSearchPaths(
-                [os.path.join(Utilities.getConfigDir(), "web_browser")]
+                [os.path.join(Globals.getConfigDir(), "web_browser")]
             )
 
         self.__tree.itemDoubleClicked.connect(self.__itemDoubleClicked)
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/UserAgent/UserAgentManager.py
--- a/src/eric7/WebBrowser/UserAgent/UserAgentManager.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/UserAgent/UserAgentManager.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,7 +11,7 @@
 
 from PyQt6.QtCore import QObject, QXmlStreamReader, pyqtSignal
 
-from eric7 import Utilities
+from eric7 import Globals
 from eric7.EricWidgets import EricMessageBox
 from eric7.Utilities.AutoSaver import AutoSaver
 
@@ -50,7 +50,7 @@
         @return name of the user agents file (string)
         """
         return os.path.join(
-            Utilities.getConfigDir(), "web_browser", "userAgentSettings.xml"
+            Globals.getConfigDir(), "web_browser", "userAgentSettings.xml"
         )
 
     def save(self):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/WebBrowserSingleApplication.py
--- a/src/eric7/WebBrowser/WebBrowserSingleApplication.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/WebBrowserSingleApplication.py	Sun Dec 18 19:33:46 2022 +0100
@@ -11,7 +11,7 @@
 
 from PyQt6.QtCore import pyqtSignal
 
-from eric7 import Globals
+from eric7.SystemUtilities import OSUtilities
 from eric7.Toolbox.SingleApplication import (
     SingleApplicationClient,
     SingleApplicationServer,
@@ -143,7 +143,7 @@
         if args is None:
             return
 
-        argChars = ("-", "/") if Globals.isWindowsPlatform() else ("-",)
+        argChars = ("-", "/") if OSUtilities.isWindowsPlatform() else ("-",)
 
         for arg in args:
             if arg.startswith("--search="):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/WebBrowserTabWidget.py
--- a/src/eric7/WebBrowser/WebBrowserTabWidget.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/WebBrowserTabWidget.py	Sun Dec 18 19:33:46 2022 +0100
@@ -19,12 +19,13 @@
 )
 from PyQt6.QtWidgets import QDialog, QHBoxLayout, QMenu, QToolButton, QWidget
 
-from eric7 import Globals, Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricGui.EricOverrideCursor import EricOverrideCursor
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricTabWidget import EricTabWidget
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 from eric7.WebBrowser.WebBrowserWindow import WebBrowserWindow
 
 from . import WebInspector
@@ -43,10 +44,10 @@
     @return flag indicating the availability of CUPS
     @rtype bool
     """
-    if Globals.isMacPlatform():
+    if OSUtilities.isMacPlatform():
         # OS X/MacOS always have CUPS
         return True
-    elif Globals.isLinuxPlatform():
+    elif OSUtilities.isLinuxPlatform():
         testPrinter = QPrinter()
         return testPrinter.supportsMultipleCopies()
     else:
@@ -679,7 +680,7 @@
             QAbstractPrintDialog.PrintDialogOption.PrintToFile
             | QAbstractPrintDialog.PrintDialogOption.PrintShowPageSize
         )
-        if not Globals.isWindowsPlatform():
+        if not OSUtilities.isWindowsPlatform():
             if isCupsAvailable():
                 printDialog.setOption(
                     QAbstractPrintDialog.PrintDialogOption.PrintCollateCopies
@@ -729,7 +730,7 @@
                         lambda pdf: self.__pdfGeneratedForSave(filePath, pdf),
                         pageLayout,
                     )
-        elif Globals.isLinuxPlatform():
+        elif OSUtilities.isLinuxPlatform():
             printer = QPrinter(mode=QPrinter.PrinterMode.HighResolution)
             if Preferences.getPrinter("ColorMode"):
                 printer.setColorMode(QPrinter.ColorMode.Color)
@@ -1057,7 +1058,7 @@
         @return guessed URL (QUrl)
         """
         manager = self.__mainWindow.openSearchManager()
-        path = Utilities.fromNativeSeparators(path)
+        path = FileSystemUtilities.fromNativeSeparators(path)
         url = manager.convertKeywordSearchToUrl(path)
         if url.isValid():
             return url
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/WebBrowserView.py
--- a/src/eric7/WebBrowser/WebBrowserView.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/WebBrowserView.py	Sun Dec 18 19:33:46 2022 +0100
@@ -40,11 +40,11 @@
 from PyQt6.QtWebEngineWidgets import QWebEngineView
 from PyQt6.QtWidgets import QApplication, QDialog, QMenu, QStyle
 
-from eric7 import Preferences, Utilities
+from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
-from eric7.Globals import qVersionTuple
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities, QtUtilities
 from eric7.WebBrowser.WebBrowserWindow import WebBrowserWindow
 from eric7.WebBrowser.ZoomManager import ZoomManager
 
@@ -268,9 +268,10 @@
             if not os.path.exists(name.toString()):
                 name.setScheme(Preferences.getWebBrowser("DefaultScheme"))
             else:
-                if Utilities.isWindowsPlatform():
+                if OSUtilities.isWindowsPlatform():
                     name.setUrl(
-                        "file:///" + Utilities.fromNativeSeparators(name.toString())
+                        "file:///"
+                        + FileSystemUtilities.fromNativeSeparators(name.toString())
                     )
                 else:
                     name.setUrl("file://" + name.toString())
@@ -1967,7 +1968,7 @@
             defaultFileName = os.path.join(documentLocation, self.url().fileName())
         else:
             defaultFileName = os.path.join(documentLocation, self.page().title())
-            if Utilities.isWindowsPlatform():
+            if OSUtilities.isWindowsPlatform():
                 defaultFileName += ".mht"
             else:
                 defaultFileName += ".mhtml"
@@ -1994,7 +1995,7 @@
             extension = os.path.splitext(fileName)[1]
             if not extension:
                 # add the platform specific default extension
-                if Utilities.isWindowsPlatform():
+                if OSUtilities.isWindowsPlatform():
                     extensionsIndex = 1
                 else:
                     extensionsIndex = 0
@@ -2375,7 +2376,7 @@
     ## Methods below implement slots for Qt 6.4+
     ###########################################################################
 
-    if qVersionTuple() >= (6, 4, 0):
+    if QtUtilities.qVersionTuple() >= (6, 4, 0):
 
         @pyqtSlot("QWebEngineFileSystemAccessRequest")
         def __fileSystemAccessRequested(self, accessRequest):
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/WebBrowser/WebBrowserWindow.py
--- a/src/eric7/WebBrowser/WebBrowserWindow.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/WebBrowser/WebBrowserWindow.py	Sun Dec 18 19:33:46 2022 +0100
@@ -68,6 +68,7 @@
 from eric7.Globals import getConfig
 from eric7.Preferences import Shortcuts
 from eric7.Preferences.ShortcutsDialog import ShortcutsDialog
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities, PythonUtilities
 from eric7.UI import Config
 from eric7.UI.Info import Version
 from eric7.UI.NotificationWidget import NotificationTypes
@@ -521,7 +522,7 @@
         """
         if enable:
             iconDatabasePath = os.path.join(
-                Utilities.getConfigDir(), "web_browser", "favicons"
+                Globals.getConfigDir(), "web_browser", "favicons"
             )
             if not os.path.exists(iconDatabasePath):
                 os.makedirs(iconDatabasePath)
@@ -1500,7 +1501,7 @@
             self,
             "webbrowser_view_full_screen",
         )
-        if Globals.isMacPlatform():
+        if OSUtilities.isMacPlatform():
             self.fullScreenAct.setShortcut(QKeySequence(self.tr("Meta+Ctrl+F")))
         else:
             self.fullScreenAct.setShortcut(QKeySequence(self.tr("F11")))
@@ -2855,7 +2856,7 @@
         applPath = os.path.join(getConfig("ericDir"), "eric7_browser.py")
         args = []
         args.append(applPath)
-        args.append("--config={0}".format(Utilities.getConfigDir()))
+        args.append("--config={0}".format(Globals.getConfigDir()))
         if self.__settingsDir:
             args.append("--settings={0}".format(self.__settingsDir))
         args.append("--private")
@@ -2863,7 +2864,7 @@
             args.append(linkName)
 
         if not os.path.isfile(applPath) or not QProcess.startDetached(
-            Globals.getPythonExecutable(), args
+            PythonUtilities.getPythonExecutable(), args
         ):
             EricMessageBox.critical(
                 self,
@@ -2892,8 +2893,8 @@
             ),
         )
         if fn:
-            if Utilities.isWindowsPlatform():
-                url = "file:///" + Utilities.fromNativeSeparators(fn)
+            if OSUtilities.isWindowsPlatform():
+                url = "file:///" + FileSystemUtilities.fromNativeSeparators(fn)
             else:
                 url = "file://" + fn
             self.currentBrowser().setSource(QUrl(url))
@@ -2915,8 +2916,8 @@
             ),
         )
         if fn:
-            if Utilities.isWindowsPlatform():
-                url = "file:///" + Utilities.fromNativeSeparators(fn)
+            if OSUtilities.isWindowsPlatform():
+                url = "file:///" + FileSystemUtilities.fromNativeSeparators(fn)
             else:
                 url = "file://" + fn
             self.newTab(url)
@@ -3786,7 +3787,7 @@
         @return path of the QtHelp collection file
         @rtype str
         """
-        qthelpDir = os.path.join(Utilities.getConfigDir(), "qthelp")
+        qthelpDir = os.path.join(Globals.getConfigDir(), "qthelp")
         if not os.path.exists(qthelpDir):
             os.makedirs(qthelpDir)
         return os.path.join(qthelpDir, "eric7help.qhc")
@@ -5292,7 +5293,7 @@
                         Preferences.getWebBrowser("DiskCacheSize") * 1024 * 1024
                     )
                     cls._webProfile.setCachePath(
-                        os.path.join(Utilities.getConfigDir(), "web_browser")
+                        os.path.join(Globals.getConfigDir(), "web_browser")
                     )
                 else:
                     cls._webProfile.setHttpCacheType(
@@ -5301,7 +5302,7 @@
                     cls._webProfile.setHttpCacheMaximumSize(0)
                 cls._webProfile.setPersistentStoragePath(
                     os.path.join(
-                        Utilities.getConfigDir(), "web_browser", "persistentstorage"
+                        Globals.getConfigDir(), "web_browser", "persistentstorage"
                     )
                 )
                 cls._webProfile.setPersistentCookiesPolicy(
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/eric7_api.py
--- a/src/eric7/eric7_api.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/eric7_api.py	Sun Dec 18 19:33:46 2022 +0100
@@ -18,8 +18,9 @@
 import os
 import sys
 
-from eric7 import DocumentationTools, Utilities
+from eric7 import DocumentationTools
 from eric7.DocumentationTools.APIGenerator import APIGenerator
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 from eric7.UI.Info import Version
 from eric7.Utilities import ModuleParser
 
@@ -229,7 +230,7 @@
         for arg in args:
             if os.path.isdir(arg):
                 if os.path.exists(
-                    os.path.join(arg, Utilities.joinext("__init__", ".py"))
+                    os.path.join(arg, FileSystemUtilities.joinext("__init__", ".py"))
                 ):
                     basename = os.path.dirname(arg)
                     if arg == ".":
@@ -245,7 +246,7 @@
                     basename = "{0}{1}".format(basename, os.sep)
 
                 if recursive and not os.path.islink(arg):
-                    names = [arg] + Utilities.getDirs(arg, excludeDirs)
+                    names = [arg] + FileSystemUtilities.getDirs(arg, excludeDirs)
                 else:
                     names = [arg]
             else:
@@ -259,11 +260,13 @@
                     for ext in supportedExtensions:
                         files.extend(
                             glob.glob(
-                                os.path.join(filename, Utilities.joinext("*", ext))
+                                os.path.join(
+                                    filename, FileSystemUtilities.joinext("*", ext)
+                                )
                             )
                         )
                         initFile = os.path.join(
-                            filename, Utilities.joinext("__init__", ext)
+                            filename, FileSystemUtilities.joinext("__init__", ext)
                         )
                         if initFile in files:
                             inpackage = True
@@ -273,7 +276,7 @@
                             # assume package
                             inpackage = True
                 else:
-                    if Utilities.isWindowsPlatform() and glob.has_magic(filename):
+                    if OSUtilities.isWindowsPlatform() and glob.has_magic(filename):
                         files = glob.glob(filename)
                     else:
                         files = [filename]
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/eric7_doc.py
--- a/src/eric7/eric7_doc.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/eric7_doc.py	Sun Dec 18 19:33:46 2022 +0100
@@ -19,12 +19,12 @@
 import shutil
 import sys
 
-from eric7 import Utilities
 from eric7.DocumentationTools import TemplatesListsStyleCSS
 from eric7.DocumentationTools.Config import eric7docDefaultColors
 from eric7.DocumentationTools.IndexGenerator import IndexGenerator
 from eric7.DocumentationTools.ModuleDocumentor import ModuleDocument
 from eric7.DocumentationTools.QtHelpGenerator import QtHelpGenerator
+from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
 from eric7.UI.Info import Version
 from eric7.Utilities import ModuleParser
 
@@ -363,7 +363,9 @@
 
     for arg in args:
         if os.path.isdir(arg):
-            if os.path.exists(os.path.join(arg, Utilities.joinext("__init__", ".py"))):
+            if os.path.exists(
+                os.path.join(arg, FileSystemUtilities.joinext("__init__", ".py"))
+            ):
                 basename = os.path.dirname(arg)
                 if arg == ".":
                     sys.stderr.write("The directory '.' is a package.\n")
@@ -376,7 +378,7 @@
                 basename = "{0}{1}".format(basename, os.sep)
 
             if recursive and not os.path.islink(arg):
-                names = [arg] + Utilities.getDirs(arg, excludeDirs)
+                names = [arg] + FileSystemUtilities.getDirs(arg, excludeDirs)
             else:
                 names = [arg]
         else:
@@ -389,17 +391,21 @@
                 files = []
                 for ext in supportedExtensions:
                     files.extend(
-                        glob.glob(os.path.join(filename, Utilities.joinext("*", ext)))
+                        glob.glob(
+                            os.path.join(
+                                filename, FileSystemUtilities.joinext("*", ext)
+                            )
+                        )
                     )
                     initFile = os.path.join(
-                        filename, Utilities.joinext("__init__", ext)
+                        filename, FileSystemUtilities.joinext("__init__", ext)
                     )
                     if initFile in files:
                         inpackage = True
                         files.remove(initFile)
                         files.insert(0, initFile)
             else:
-                if Utilities.isWindowsPlatform() and glob.has_magic(filename):
+                if OSUtilities.isWindowsPlatform() and glob.has_magic(filename):
                     files = glob.glob(filename)
                 else:
                     files = [filename]
@@ -429,7 +435,7 @@
                     sys.stderr.write("{0} error: {1}\n".format(file, v))
                     continue
 
-                f = Utilities.joinext(
+                f = FileSystemUtilities.joinext(
                     os.path.join(outputDir, moduleDocument.name()), ".html"
                 )
 
diff -r 9c1f429cb56b -r b47dfa7a137d src/eric7/eric7_ide.py
--- a/src/eric7/eric7_ide.py	Sun Dec 18 14:19:10 2022 +0100
+++ b/src/eric7/eric7_ide.py	Sun Dec 18 19:33:46 2022 +0100
@@ -227,8 +227,8 @@
     """
     Main entry point into the application.
     """
-    from eric7 import Globals
     from eric7.Globals import AppInfo
+    from eric7.SystemUtilities import OSUtilities, QtUtilities
     from eric7.Toolbox import Startup
 
     global app, args, mainWindow, splash, restartArgs, inMainLoop
@@ -326,8 +326,8 @@
     QCoreApplication.processEvents()
 
     # modify the executable search path for the PyQt5 installer
-    if Globals.isWindowsPlatform():
-        pyqtDataDir = Globals.getPyQt6ModulesDirectory()
+    if OSUtilities.isWindowsPlatform():
+        pyqtDataDir = QtUtilities.getPyQt6ModulesDirectory()
         if os.path.exists(os.path.join(pyqtDataDir, "bin")):
             path = os.path.join(pyqtDataDir, "bin")
         else:

eric ide

mercurial