Removed for writing old style XML files and renamed E5XML to EricXML. eric7

Sat, 22 May 2021 11:14:43 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 22 May 2021 11:14:43 +0200
branch
eric7
changeset 8351
7d13e08ddb3f
parent 8350
74a3b2a6a944
child 8352
879dc528461f

Removed for writing old style XML files and renamed E5XML to EricXML.

eric7.epj file | annotate | diff | comparison | revisions
eric7/E5Gui/E5PathPicker.py file | annotate | diff | comparison | revisions
eric7/E5XML/Config.py file | annotate | diff | comparison | revisions
eric7/E5XML/DebuggerPropertiesReader.py file | annotate | diff | comparison | revisions
eric7/E5XML/DebuggerPropertiesWriter.py file | annotate | diff | comparison | revisions
eric7/E5XML/HighlightingStylesReader.py file | annotate | diff | comparison | revisions
eric7/E5XML/HighlightingStylesWriter.py file | annotate | diff | comparison | revisions
eric7/E5XML/MultiProjectReader.py file | annotate | diff | comparison | revisions
eric7/E5XML/MultiProjectWriter.py file | annotate | diff | comparison | revisions
eric7/E5XML/PluginRepositoryReader.py file | annotate | diff | comparison | revisions
eric7/E5XML/ProjectReader.py file | annotate | diff | comparison | revisions
eric7/E5XML/ProjectWriter.py file | annotate | diff | comparison | revisions
eric7/E5XML/SessionReader.py file | annotate | diff | comparison | revisions
eric7/E5XML/SessionWriter.py file | annotate | diff | comparison | revisions
eric7/E5XML/ShortcutsReader.py file | annotate | diff | comparison | revisions
eric7/E5XML/ShortcutsWriter.py file | annotate | diff | comparison | revisions
eric7/E5XML/SpellCheckDictionariesReader.py file | annotate | diff | comparison | revisions
eric7/E5XML/TasksReader.py file | annotate | diff | comparison | revisions
eric7/E5XML/TasksWriter.py file | annotate | diff | comparison | revisions
eric7/E5XML/TemplatesReader.py file | annotate | diff | comparison | revisions
eric7/E5XML/TemplatesWriter.py file | annotate | diff | comparison | revisions
eric7/E5XML/UserProjectReader.py file | annotate | diff | comparison | revisions
eric7/E5XML/UserProjectWriter.py file | annotate | diff | comparison | revisions
eric7/E5XML/XMLStreamReaderBase.py file | annotate | diff | comparison | revisions
eric7/E5XML/XMLStreamWriterBase.py file | annotate | diff | comparison | revisions
eric7/E5XML/__init__.py file | annotate | diff | comparison | revisions
eric7/EricXML/Config.py file | annotate | diff | comparison | revisions
eric7/EricXML/DebuggerPropertiesReader.py file | annotate | diff | comparison | revisions
eric7/EricXML/HighlightingStylesReader.py file | annotate | diff | comparison | revisions
eric7/EricXML/MultiProjectReader.py file | annotate | diff | comparison | revisions
eric7/EricXML/PluginRepositoryReader.py file | annotate | diff | comparison | revisions
eric7/EricXML/ProjectReader.py file | annotate | diff | comparison | revisions
eric7/EricXML/SessionReader.py file | annotate | diff | comparison | revisions
eric7/EricXML/ShortcutsReader.py file | annotate | diff | comparison | revisions
eric7/EricXML/SpellCheckDictionariesReader.py file | annotate | diff | comparison | revisions
eric7/EricXML/TasksReader.py file | annotate | diff | comparison | revisions
eric7/EricXML/TemplatesReader.py file | annotate | diff | comparison | revisions
eric7/EricXML/UserProjectReader.py file | annotate | diff | comparison | revisions
eric7/EricXML/XMLStreamReaderBase.py file | annotate | diff | comparison | revisions
eric7/EricXML/__init__.py file | annotate | diff | comparison | revisions
eric7/MultiProject/MultiProject.py file | annotate | diff | comparison | revisions
eric7/PluginManager/PluginManager.py file | annotate | diff | comparison | revisions
eric7/PluginManager/PluginRepositoryDialog.py file | annotate | diff | comparison | revisions
eric7/Preferences/ConfigurationDialog.py file | annotate | diff | comparison | revisions
eric7/Preferences/ConfigurationPages/EditorHighlightingStylesPage.py file | annotate | diff | comparison | revisions
eric7/Preferences/Shortcuts.py file | annotate | diff | comparison | revisions
eric7/Project/Project.py file | annotate | diff | comparison | revisions
eric7/Templates/TemplateViewer.py file | annotate | diff | comparison | revisions
eric7/UI/UserInterface.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/SpellCheck/ManageDictionariesDialog.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/WebBrowserWindow.py file | annotate | diff | comparison | revisions
eric7/eric7.py file | annotate | diff | comparison | revisions
--- a/eric7.epj	Fri May 21 20:14:48 2021 +0200
+++ b/eric7.epj	Sat May 22 11:14:43 2021 +0200
@@ -1,7 +1,8 @@
 {
   "header": {
     "comment": "eric project file for project eric7",
-    "copyright": "Copyright (C) 2021 Detlev Offenbach, detlev@die-offenbachs.de"
+    "copyright": "Copyright (C) 2021 Detlev Offenbach, detlev@die-offenbachs.de",
+    "saved": "2021-05-22, 11:10:19"
   },
   "project": {
     "AUTHOR": "Detlev Offenbach",
@@ -1142,30 +1143,6 @@
       "eric7/E5Utilities/E5Cache.py",
       "eric7/E5Utilities/E5MutexLocker.py",
       "eric7/E5Utilities/__init__.py",
-      "eric7/E5XML/Config.py",
-      "eric7/E5XML/DebuggerPropertiesReader.py",
-      "eric7/E5XML/DebuggerPropertiesWriter.py",
-      "eric7/E5XML/HighlightingStylesReader.py",
-      "eric7/E5XML/HighlightingStylesWriter.py",
-      "eric7/E5XML/MultiProjectReader.py",
-      "eric7/E5XML/MultiProjectWriter.py",
-      "eric7/E5XML/PluginRepositoryReader.py",
-      "eric7/E5XML/ProjectReader.py",
-      "eric7/E5XML/ProjectWriter.py",
-      "eric7/E5XML/SessionReader.py",
-      "eric7/E5XML/SessionWriter.py",
-      "eric7/E5XML/ShortcutsReader.py",
-      "eric7/E5XML/ShortcutsWriter.py",
-      "eric7/E5XML/SpellCheckDictionariesReader.py",
-      "eric7/E5XML/TasksReader.py",
-      "eric7/E5XML/TasksWriter.py",
-      "eric7/E5XML/TemplatesReader.py",
-      "eric7/E5XML/TemplatesWriter.py",
-      "eric7/E5XML/UserProjectReader.py",
-      "eric7/E5XML/UserProjectWriter.py",
-      "eric7/E5XML/XMLStreamReaderBase.py",
-      "eric7/E5XML/XMLStreamWriterBase.py",
-      "eric7/E5XML/__init__.py",
       "eric7/Globals/AppInfo.py",
       "eric7/Globals/__init__.py",
       "eric7/Graphics/ApplicationDiagramBuilder.py",
@@ -2277,7 +2254,21 @@
       "eric7/DebugClients/Python/eric7dbgstub.py",
       "eric7/EricGraphics/__init__.py",
       "eric7/EricGraphics/EricArrowItem.py",
-      "eric7/EricGraphics/EricGraphicsView.py"
+      "eric7/EricGraphics/EricGraphicsView.py",
+      "eric7/EricXML/Config.py",
+      "eric7/EricXML/DebuggerPropertiesReader.py",
+      "eric7/EricXML/HighlightingStylesReader.py",
+      "eric7/EricXML/MultiProjectReader.py",
+      "eric7/EricXML/PluginRepositoryReader.py",
+      "eric7/EricXML/ProjectReader.py",
+      "eric7/EricXML/SessionReader.py",
+      "eric7/EricXML/ShortcutsReader.py",
+      "eric7/EricXML/SpellCheckDictionariesReader.py",
+      "eric7/EricXML/TasksReader.py",
+      "eric7/EricXML/TemplatesReader.py",
+      "eric7/EricXML/UserProjectReader.py",
+      "eric7/EricXML/XMLStreamReaderBase.py",
+      "eric7/EricXML/__init__.py"
     ],
     "SPELLEXCLUDES": "Dictionaries/excludes.dic",
     "SPELLLANGUAGE": "en_US",
--- a/eric7/E5Gui/E5PathPicker.py	Fri May 21 20:14:48 2021 +0200
+++ b/eric7/E5Gui/E5PathPicker.py	Sat May 22 11:14:43 2021 +0200
@@ -86,8 +86,8 @@
         self.setLayout(self.__layout)
         
         if useLineEdit:
-            self._editor = QLineEdit(
-                self, QCoreApplication.translate(
+            self._editor = QLineEdit(self)
+            self._editor.setPlaceholderText(QCoreApplication.translate(
                     "E5PathPickerBase", "Enter Path Name"))
             self._editor.setClearButtonEnabled(True)
         else:
--- a/eric7/E5XML/Config.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2004 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing some common configuration stuf for the XML package.
-"""
-
-# version number of the multi project file
-multiProjectFileFormatVersion = "5.1"
-
-# version numbers of the project file
-projectFileFormatVersion = "6.5"
-projectFileFormatVersionRcc = "6.4"
-projectFileFormatVersionUic = "6.3"
-projectFileFormatVersionIdl = "6.2"
-projectFileFormatVersionMake = "6.1"
-projectFileFormatVersionProto = "6.0"
-projectFileFormatVersionAlt = "5.1"
-
-# version number of the user project file
-userProjectFileFormatVersion = "4.0"
-
-# version number of the project session file
-sessionFileFormatVersion = "6.4"
-
-# version number of the shortcuts file
-shortcutsFileFormatVersion = "3.6"
-
-# version number of the tasks file
-tasksFileFormatVersion = "6.0"
-
-# version number of the debugger properties file
-debuggerPropertiesFileFormatVersion = "6.0"
-
-# version number of the templates file
-templatesFileFormatVersion = "4.0"
-
-# version number of the plugin repository file
-pluginRepositoryFileFormatVersion = "4.2"
-
-# version number of the highlighting styles file
-highlightingStylesFileFormatVersion = "6.0"
-
-# version number of the web browser spell check dictionaries list file
-dictionariesListFileFormatVersion = "1.0"
--- a/eric7/E5XML/DebuggerPropertiesReader.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing a class for reading an XML project debugger properties
-file.
-"""
-
-from .Config import debuggerPropertiesFileFormatVersion
-from .XMLStreamReaderBase import XMLStreamReaderBase
-
-
-class DebuggerPropertiesReader(XMLStreamReaderBase):
-    """
-    Class for reading an XML project debugger properties file.
-    """
-    supportedVersions = ["3.9", "6.0"]
-    
-    def __init__(self, device, project):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to read from (QIODevice)
-        @param project Reference to the project object to store the
-                information into.
-        """
-        XMLStreamReaderBase.__init__(self, device)
-    
-        self.project = project
-        
-        self.version = ""
-    
-    def readXML(self, quiet=False):
-        """
-        Public method to read and parse the XML document.
-        
-        @param quiet flag indicating quiet operations.
-                If this flag is true, no errors are reported.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isStartElement():
-                if self.name() == "DebuggerProperties":
-                    self.version = self.attribute(
-                        "version", debuggerPropertiesFileFormatVersion)
-                    if self.version not in self.supportedVersions:
-                        self.raiseUnsupportedFormatVersion(self.version)
-                elif self.name() == "VirtualEnv":
-                    self.project.debugProperties["VIRTUALENV"] = (
-                        self.readElementText()
-                    )
-                elif self.name() == "Interpreter":
-                    # just read this obsolete entry and ignore it
-                    self.readElementText()
-                elif self.name() == "DebugClient":
-                    self.project.debugProperties["DEBUGCLIENT"] = (
-                        self.readElementText()
-                    )
-                elif self.name() == "Environment":
-                    self.project.debugProperties["ENVIRONMENTOVERRIDE"] = (
-                        int(self.attribute("override", "0"))
-                    )
-                    self.project.debugProperties["ENVIRONMENTSTRING"] = (
-                        self.readElementText()
-                    )
-                elif self.name() == "RemoteDebugger":
-                    self.__readRemoteDebugger()
-                elif self.name() == "PathTranslation":
-                    self.__readPathTranslation()
-                elif self.name() == "ConsoleDebugger":
-                    self.project.debugProperties["CONSOLEDEBUGGER"] = (
-                        int(self.attribute("on", "0"))
-                    )
-                    self.project.debugProperties["CONSOLECOMMAND"] = (
-                        self.readElementText()
-                    )
-                elif self.name() == "Redirect":
-                    self.project.debugProperties["REDIRECT"] = (
-                        int(self.attribute("on", "1"))
-                    )
-                elif self.name() == "Noencoding":
-                    self.project.debugProperties["NOENCODING"] = (
-                        int(self.attribute("on", "0"))
-                    )
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-        
-        if not quiet:
-            self.showErrorMessage()
-    
-    def __readRemoteDebugger(self):
-        """
-        Private method to read the remote debugger info.
-        """
-        self.project.debugProperties["REMOTEDEBUGGER"] = int(self.attribute(
-            "on", "0"))
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "RemoteDebugger":
-                break
-            
-            if self.isStartElement():
-                if self.name() == "RemoteHost":
-                    self.project.debugProperties["REMOTEHOST"] = (
-                        self.readElementText()
-                    )
-                elif self.name() == "RemoteCommand":
-                    self.project.debugProperties["REMOTECOMMAND"] = (
-                        self.readElementText()
-                    )
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readPathTranslation(self):
-        """
-        Private method to read the path translation info.
-        """
-        self.project.debugProperties["PATHTRANSLATION"] = int(self.attribute(
-            "on", "0"))
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "PathTranslation":
-                break
-            
-            if self.isStartElement():
-                if self.name() == "RemotePath":
-                    self.project.debugProperties["REMOTEPATH"] = (
-                        self.readElementText()
-                    )
-                elif self.name() == "LocalPath":
-                    self.project.debugProperties["LOCALPATH"] = (
-                        self.readElementText()
-                    )
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
--- a/eric7/E5XML/DebuggerPropertiesWriter.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2005 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the writer class for writing an XML project debugger
-properties file.
-"""
-
-import time
-
-from E5Gui.E5Application import e5App
-
-from .XMLStreamWriterBase import XMLStreamWriterBase
-from .Config import debuggerPropertiesFileFormatVersion
-
-import Preferences
-
-
-class DebuggerPropertiesWriter(XMLStreamWriterBase):
-    """
-    Class implementing the writer class for writing an XML project debugger
-    properties file.
-    """
-    def __init__(self, device, projectName):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to write to (QIODevice)
-        @param projectName name of the project (string)
-        """
-        XMLStreamWriterBase.__init__(self, device)
-        
-        self.name = projectName
-        self.project = e5App().getObject("Project")
-        
-    def writeXML(self):
-        """
-        Public method to write the XML to the file.
-        """
-        XMLStreamWriterBase.writeXML(self)
-        
-        self.writeDTD(
-            '<!DOCTYPE DebuggerProperties SYSTEM'
-            ' "DebuggerProperties-{0}.dtd">'.format(
-                debuggerPropertiesFileFormatVersion))
-        
-        # add some generation comments
-        self.writeComment(
-            " eric debugger properties file for project {0} ".format(
-                self.name))
-        self.writeComment(
-            " This file was generated automatically, do not edit. ")
-        if Preferences.getProject("TimestampFile"):
-            self.writeComment(
-                " Saved: {0} ".format(time.strftime('%Y-%m-%d, %H:%M:%S')))
-        
-        # add the main tag
-        self.writeStartElement("DebuggerProperties")
-        self.writeAttribute("version", debuggerPropertiesFileFormatVersion)
-        
-        self.writeTextElement(
-            "VirtualEnv", self.project.debugProperties["VIRTUALENV"])
-        
-        self.writeTextElement(
-            "DebugClient", self.project.debugProperties["DEBUGCLIENT"])
-        
-        self.writeStartElement("Environment")
-        self.writeAttribute(
-            "override",
-            str(int(self.project.debugProperties["ENVIRONMENTOVERRIDE"])))
-        self.writeCharacters(self.project.debugProperties["ENVIRONMENTSTRING"])
-        self.writeEndElement()
-        
-        self.writeStartElement("RemoteDebugger")
-        self.writeAttribute(
-            "on", str(int(self.project.debugProperties["REMOTEDEBUGGER"])))
-        self.writeTextElement(
-            "RemoteHost", self.project.debugProperties["REMOTEHOST"])
-        self.writeTextElement(
-            "RemoteCommand", self.project.debugProperties["REMOTECOMMAND"])
-        self.writeEndElement()
-        
-        self.writeStartElement("PathTranslation")
-        self.writeAttribute(
-            "on", str(int(self.project.debugProperties["PATHTRANSLATION"])))
-        self.writeTextElement(
-            "RemotePath", self.project.debugProperties["REMOTEPATH"])
-        self.writeTextElement(
-            "LocalPath", self.project.debugProperties["LOCALPATH"])
-        self.writeEndElement()
-        
-        self.writeStartElement("ConsoleDebugger")
-        self.writeAttribute(
-            "on", str(int(self.project.debugProperties["CONSOLEDEBUGGER"])))
-        self.writeCharacters(self.project.debugProperties["CONSOLECOMMAND"])
-        self.writeEndElement()
-        
-        self.writeEmptyElement("Redirect")
-        self.writeAttribute(
-            "on", str(int(self.project.debugProperties["REDIRECT"])))
-        
-        self.writeEmptyElement("Noencoding")
-        self.writeAttribute(
-            "on", str(int(self.project.debugProperties["NOENCODING"])))
-        
-        self.writeEndElement()
-        self.writeEndDocument()
--- a/eric7/E5XML/HighlightingStylesReader.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-
-"""
-Module implementing a class for reading a highlighting styles XML file.
-"""
-
-from .Config import highlightingStylesFileFormatVersion
-from .XMLStreamReaderBase import XMLStreamReaderBase
-
-
-class HighlightingStylesReader(XMLStreamReaderBase):
-    """
-    Class for reading a highlighting styles XML file.
-    """
-    supportedVersions = ["4.3", "6.0"]
-    
-    def __init__(self, device, lexers):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to read from (QIODevice)
-        @param lexers dictionary of lexer objects for which to import the
-            styles
-        """
-        XMLStreamReaderBase.__init__(self, device)
-        
-        self.lexers = lexers
-        
-        self.version = ""
-    
-    def readXML(self):
-        """
-        Public method to read and parse the XML document.
-        
-        @return list of read lexer style definitions
-        @rtype list of dict
-        """
-        self.__lexersList = []
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isStartElement():
-                if self.name() == "HighlightingStyles":
-                    self.version = self.attribute(
-                        "version",
-                        highlightingStylesFileFormatVersion)
-                    if self.version not in self.supportedVersions:
-                        self.raiseUnsupportedFormatVersion(self.version)
-                elif self.name() == "Lexer":
-                    self.__readLexer()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-        
-        self.showErrorMessage()
-        
-        return self.__lexersList
-    
-    def __readLexer(self):
-        """
-        Private method to read the lexer info.
-        """
-        language = self.attribute("name")
-        self.__lexersList.append({
-            "name": language,
-            "styles": [],
-        })
-        lexer = (
-            self.lexers[language]
-            if language and language in self.lexers else
-            None
-        )
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Lexer":
-                break
-            
-            if self.isStartElement():
-                if self.name() == "Style":
-                    self.__readStyle(lexer)
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readStyle(self, lexer):
-        """
-        Private method to read the style info.
-        
-        @param lexer reference to the lexer object
-        """
-        if lexer is not None:
-            style = self.attribute("style")
-            if style:
-                style = int(style)
-                substyle = int(self.attribute("substyle", "-1"))
-                # -1 is default for base styles
-                
-                styleDict = {
-                    "style": style,
-                    "substyle": substyle,
-                }
-                
-                color = self.attribute("color")
-                if color:
-                    styleDict["color"] = color
-                else:
-                    styleDict["color"] = (
-                        lexer.defaultColor(style, substyle).name()
-                    )
-                
-                paper = self.attribute("paper")
-                if paper:
-                    styleDict["paper"] = paper
-                else:
-                    styleDict["paper"] = (
-                        lexer.defaultPaper(style, substyle).name()
-                    )
-                
-                fontStr = self.attribute("font")
-                if fontStr:
-                    styleDict["font"] = fontStr
-                else:
-                    styleDict["font"] = (
-                        lexer.defaultFont(style, substyle).toString()
-                    )
-                
-                eolfill = self.attribute("eolfill")
-                if eolfill:
-                    eolfill = self.toBool(eolfill)
-                    if eolfill is None:
-                        eolfill = lexer.defaulEolFill(style, substyle)
-                else:
-                    eolfill = lexer.defaulEolFill(style, substyle)
-                styleDict["eolfill"] = eolfill
-        
-                while not self.atEnd():
-                    self.readNext()
-                    if self.isStartElement():
-                        if self.name() == "Description":
-                            description = self.readElementText().strip()
-                            if not description:
-                                description = lexer.defaultDescription(
-                                    style, substyle)
-                            styleDict["description"] = description
-                        elif self.name() == "Words":
-                            words = self.readElementText().strip()
-                            if not words:
-                                words = lexer.defaultWords(style, substyle)
-                            styleDict["words"] = words
-                    
-                    if self.isEndElement() and self.name() == "Style":
-                        if "description" not in styleDict:
-                            styleDict["description"] = ""
-                        if "words" not in styleDict:
-                            styleDict["words"] = ""
-                        self.__lexersList[-1]["styles"].append(styleDict)
-                        return
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Style":
-                break
--- a/eric7/E5XML/HighlightingStylesWriter.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2008 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the writer class for writing a highlighting styles XML
-file.
-"""
-
-import time
-
-from .XMLStreamWriterBase import XMLStreamWriterBase
-from .Config import highlightingStylesFileFormatVersion
-
-import Preferences
-
-
-class HighlightingStylesWriter(XMLStreamWriterBase):
-    """
-    Class implementing the writer class for writing a highlighting styles XML
-    file.
-    """
-    def __init__(self, device, lexers):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to write to (QIODevice)
-        @param lexers list of lexer objects for which to export the styles
-        """
-        XMLStreamWriterBase.__init__(self, device)
-        
-        self.lexers = lexers
-        self.email = Preferences.getUser("Email")
-    
-    def writeXML(self):
-        """
-        Public method to write the XML to the file.
-        """
-        XMLStreamWriterBase.writeXML(self)
-        
-        self.writeDTD(
-            '<!DOCTYPE HighlightingStyles SYSTEM'
-            ' "HighlightingStyles-{0}.dtd">'.format(
-                highlightingStylesFileFormatVersion))
-        
-        # add some generation comments
-        self.writeComment(" Eric highlighting styles ")
-        self.writeComment(
-            " Saved: {0}".format(time.strftime('%Y-%m-%d, %H:%M:%S')))
-        self.writeComment(" Author: {0} ".format(self.email))
-        
-        # add the main tag
-        self.writeStartElement("HighlightingStyles")
-        self.writeAttribute("version", highlightingStylesFileFormatVersion)
-        
-        for lexer in self.lexers:
-            self.writeStartElement("Lexer")
-            self.writeAttribute("name", lexer.language())
-            for description, style, substyle in lexer.getStyles():
-                self.writeStartElement("Style")
-                self.writeAttribute("style", str(style))
-                self.writeAttribute("substyle", str(substyle))
-                self.writeAttribute("color",
-                                    lexer.color(style, substyle).name())
-                self.writeAttribute("paper",
-                                    lexer.paper(style, substyle).name())
-                self.writeAttribute("font",
-                                    lexer.font(style, substyle).toString())
-                self.writeAttribute("eolfill",
-                                    str(lexer.eolFill(style, substyle)))
-                self.writeStartElement("Description")
-                self.writeCharacters(description)
-                self.writeEndElement()      # Description
-                if substyle >= 0:
-                    self.writeStartElement("Words")
-                    self.writeCharacters(lexer.words(style, substyle).strip())
-                    self.writeEndElement()      # Words
-                self.writeEndElement()      # Style
-            self.writeEndElement()          # Lexer
-        
-        self.writeEndElement()              # HighlightingStyles
-        self.writeEndDocument()
--- a/eric7/E5XML/MultiProjectReader.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing a class for reading an XML multi project file.
-"""
-
-import os
-
-from .Config import multiProjectFileFormatVersion
-from .XMLStreamReaderBase import XMLStreamReaderBase
-
-import Utilities
-
-
-class MultiProjectReader(XMLStreamReaderBase):
-    """
-    Class for reading an XML multi project file.
-    """
-    supportedVersions = ["4.2", "5.0", "5.1"]
-    
-    def __init__(self, device, multiProject):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to read from (QIODevice)
-        @param multiProject Reference to the multi project object to store the
-                information into.
-        """
-        XMLStreamReaderBase.__init__(self, device)
-        
-        self.multiProject = multiProject
-        self.path = os.path.dirname(device.fileName())
-        
-        self.version = ""
-    
-    def readXML(self):
-        """
-        Public method to read and parse the XML document.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isStartElement():
-                if self.name() == "MultiProject":
-                    self.version = self.attribute(
-                        "version",
-                        multiProjectFileFormatVersion)
-                    if self.version not in self.supportedVersions:
-                        self.raiseUnsupportedFormatVersion(self.version)
-                elif self.name() == "Description":
-                    self.multiProject.description = self.readElementText()
-                elif self.name() == "Projects":
-                    self.__readProjects()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-        
-        self.showErrorMessage()
-    
-    def __readProjects(self):
-        """
-        Private method to read the project infos.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Projects":
-                break
-            
-            if self.isStartElement():
-                if self.name() == "Project":
-                    self.__readProject()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readProject(self):
-        """
-        Private method to read the project info.
-        """
-        project = {}
-        
-        project["master"] = self.toBool(self.attribute("isMaster", "False"))
-        uid = self.attribute("uid", "")
-        if uid:
-            project["uid"] = uid
-        else:
-            # upgrade from pre 5.1 format
-            from PyQt6.QtCore import QUuid
-            project["uid"] = QUuid.createUuid().toString()
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Project":
-                if 'category' not in project:
-                    # upgrade from 4.2 format
-                    project["category"] = ""
-                self.multiProject.addProject(project)
-                break
-            
-            if self.isStartElement():
-                if self.name() == "ProjectName":
-                    project["name"] = self.readElementText()
-                elif self.name() == "ProjectFile":
-                    project["file"] = Utilities.absoluteUniversalPath(
-                        self.readElementText(), self.path)
-                elif self.name() == "ProjectDescription":
-                    project["description"] = self.readElementText()
-                elif self.name() == "ProjectCategory":
-                    project["category"] = self.readElementText()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
--- a/eric7/E5XML/MultiProjectWriter.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2008 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the writer class for writing an XML multi project file.
-"""
-
-import os
-import time
-
-from .XMLStreamWriterBase import XMLStreamWriterBase
-from .Config import multiProjectFileFormatVersion
-
-import Preferences
-import Utilities
-
-
-class MultiProjectWriter(XMLStreamWriterBase):
-    """
-    Class implementing the writer class for writing an XML project file.
-    """
-    def __init__(self, device, multiProject, multiProjectName):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to write to (QIODevice)
-        @param multiProject Reference to the multi project object
-        @param multiProjectName name of the project (string)
-        """
-        XMLStreamWriterBase.__init__(self, device)
-        
-        self.name = multiProjectName
-        self.multiProject = multiProject
-        self.path = os.path.dirname(device.fileName())
-    
-    def writeXML(self):
-        """
-        Public method to write the XML to the file.
-        """
-        XMLStreamWriterBase.writeXML(self)
-        
-        self.writeDTD('<!DOCTYPE MultiProject SYSTEM "MultiProject-{0}.dtd">'
-                      .format(multiProjectFileFormatVersion))
-        
-        # add some generation comments
-        self.writeComment(" eric multi project file for multi project {0} "
-                          .format(self.name))
-        if Preferences.getMultiProject("TimestampFile"):
-            self.writeComment(
-                " Saved: {0} ".format(time.strftime('%Y-%m-%d, %H:%M:%S')))
-            self.writeComment(
-                " Copyright (C) {0} ".format(time.strftime('%Y')))
-        
-        # add the main tag
-        self.writeStartElement("MultiProject")
-        self.writeAttribute("version", multiProjectFileFormatVersion)
-        
-        # do description
-        self.writeTextElement("Description", self.multiProject.description)
-        
-        # do the projects
-        self.writeStartElement("Projects")
-        for project in self.multiProject.getProjects():
-            self.writeStartElement("Project")
-            self.writeAttribute("isMaster", str(project['master']))
-            self.writeAttribute("uid", project["uid"])
-            self.writeTextElement("ProjectName", project['name'])
-            self.writeTextElement(
-                "ProjectFile",
-                Utilities.relativeUniversalPath(project['file'], self.path))
-            self.writeTextElement("ProjectDescription", project['description'])
-            self.writeTextElement("ProjectCategory", project['category'])
-            self.writeEndElement()
-        self.writeEndElement()
-        
-        self.writeEndElement()
-        self.writeEndDocument()
--- a/eric7/E5XML/PluginRepositoryReader.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module to read the plug-in repository contents file.
-"""
-
-from .Config import pluginRepositoryFileFormatVersion
-from .XMLStreamReaderBase import XMLStreamReaderBase
-
-import Preferences
-
-
-class PluginRepositoryReader(XMLStreamReaderBase):
-    """
-    Class to read the plug-in repository contents file.
-    """
-    supportedVersions = ["4.1", "4.2"]
-    
-    def __init__(self, device, entryCallback):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to read from (QIODevice)
-        @param entryCallback reference to a function to be called once the
-            data for a plug-in has been read (function)
-        """
-        XMLStreamReaderBase.__init__(self, device)
-        
-        self.__entryCallback = entryCallback
-        
-        self.version = ""
-    
-    def readXML(self):
-        """
-        Public method to read and parse the XML document.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isStartElement():
-                if self.name() == "Plugins":
-                    self.version = self.attribute(
-                        "version",
-                        pluginRepositoryFileFormatVersion)
-                    if self.version not in self.supportedVersions:
-                        self.raiseUnsupportedFormatVersion(self.version)
-                elif self.name() == "RepositoryUrl":
-                    url = self.readElementText()
-                    Preferences.setUI("PluginRepositoryUrl7", url)
-                elif self.name() == "Plugin":
-                    self.__readPlugin()
-                else:
-                    self._skipUnknownElement()
-        
-        self.showErrorMessage()
-    
-    def __readPlugin(self):
-        """
-        Private method to read the plug-in info.
-        """
-        pluginInfo = {"name": "",
-                      "short": "",
-                      "description": "",
-                      "url": "",
-                      "author": "",
-                      "version": "",
-                      "filename": "",
-                      }
-        pluginInfo["status"] = self.attribute("status", "unknown")
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Plugin":
-                self.__entryCallback(
-                    pluginInfo["name"], pluginInfo["short"],
-                    pluginInfo["description"], pluginInfo["url"],
-                    pluginInfo["author"], pluginInfo["version"],
-                    pluginInfo["filename"], pluginInfo["status"])
-                break
-            
-            if self.isStartElement():
-                if self.name() == "Name":
-                    pluginInfo["name"] = self.readElementText()
-                elif self.name() == "Short":
-                    pluginInfo["short"] = self.readElementText()
-                elif self.name() == "Description":
-                    txt = self.readElementText()
-                    pluginInfo["description"] = [
-                        line.strip() for line in txt.splitlines()
-                    ]
-                elif self.name() == "Url":
-                    pluginInfo["url"] = self.readElementText()
-                elif self.name() == "Author":
-                    pluginInfo["author"] = self.readElementText()
-                elif self.name() == "Version":
-                    pluginInfo["version"] = self.readElementText()
-                elif self.name() == "Filename":
-                    pluginInfo["filename"] = self.readElementText()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
--- a/eric7/E5XML/ProjectReader.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,251 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing a class for reading an XML project file.
-"""
-
-from .Config import projectFileFormatVersion
-from .XMLStreamReaderBase import XMLStreamReaderBase
-
-import Utilities
-
-
-class ProjectReader(XMLStreamReaderBase):
-    """
-    Class for reading an XML project file.
-    """
-    supportedVersions = ["4.6",
-                         "5.0", "5.1",
-                         "6.0", "6.1", "6.2", "6.3", "6.4", "6.5"]
-    
-    def __init__(self, device, project):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to read from (QIODevice)
-        @param project Reference to the project object to store the
-                information into.
-        """
-        XMLStreamReaderBase.__init__(self, device)
-    
-        self.project = project
-        
-        self.version = ""
-    
-    def readXML(self):
-        """
-        Public method to read and parse the XML document.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isStartElement():
-                if self.name() == "Project":
-                    self.version = self.attribute(
-                        "version", projectFileFormatVersion)
-                    if self.version not in self.supportedVersions:
-                        self.raiseUnsupportedFormatVersion(self.version)
-                elif self.name() == "Language":
-                    self.project.pdata["SPELLLANGUAGE"] = (
-                        self.readElementText()
-                    )
-                elif self.name() == "ProjectWordList":
-                    self.project.pdata["SPELLWORDS"] = (
-                        Utilities.toNativeSeparators(self.readElementText())
-                    )
-                elif self.name() == "ProjectExcludeList":
-                    self.project.pdata["SPELLEXCLUDES"] = (
-                        Utilities.toNativeSeparators(self.readElementText())
-                    )
-                elif self.name() == "Hash":
-                    self.project.pdata["HASH"] = self.readElementText()
-                elif self.name() == "ProgLanguage":
-                    self.project.pdata["MIXEDLANGUAGE"] = int(
-                        self.attribute("mixed", "0")
-                    )
-                    self.project.pdata["PROGLANGUAGE"] = self.readElementText()
-                    if self.project.pdata["PROGLANGUAGE"] == "Python":
-                        # convert Python to the more specific Python3
-                        self.project.pdata["PROGLANGUAGE"] = "Python3"
-                elif self.name() == "ProjectType":
-                    self.project.pdata["PROJECTTYPE"] = self.readElementText()
-                elif self.name() == "Description":
-                    self.project.pdata["DESCRIPTION"] = self.readElementText()
-                elif self.name() == "Version":
-                    self.project.pdata["VERSION"] = self.readElementText()
-                elif self.name() == "Author":
-                    self.project.pdata["AUTHOR"] = self.readElementText()
-                elif self.name() == "Email":
-                    self.project.pdata["EMAIL"] = self.readElementText()
-                elif self.name() == "TranslationPattern":
-                    self.project.pdata["TRANSLATIONPATTERN"] = (
-                        Utilities.toNativeSeparators(self.readElementText())
-                    )
-                elif self.name() == "TranslationsBinPath":
-                    self.project.pdata["TRANSLATIONSBINPATH"] = (
-                        Utilities.toNativeSeparators(self.readElementText())
-                    )
-                elif self.name() == "Eol":
-                    self.project.pdata["EOL"] = int(
-                        self.attribute("index", "0")
-                    )
-                elif self.name() == "Sources":
-                    self.__readFiles("Sources", "Source", "SOURCES")
-                elif self.name() == "Forms":
-                    self.__readFiles("Forms", "Form", "FORMS")
-                elif self.name() == "Translations":
-                    self.__readFiles(
-                        "Translations", "Translation", "TRANSLATIONS")
-                elif self.name() == "TranslationExceptions":
-                    self.__readFiles(
-                        "TranslationExceptions", "TranslationException",
-                        "TRANSLATIONEXCEPTIONS")
-                elif self.name() == "Resources":
-                    self.__readFiles("Resources", "Resource", "RESOURCES")
-                elif self.name() == "Interfaces":
-                    self.__readFiles("Interfaces", "Interface", "INTERFACES")
-                elif self.name() == "Protocols":
-                    self.__readFiles("Protocols", "Protocol", "PROTOCOLS")
-                elif self.name() == "Others":
-                    self.__readFiles("Others", "Other", "OTHERS")
-                elif self.name() == "MainScript":
-                    self.project.pdata["MAINSCRIPT"] = (
-                        Utilities.toNativeSeparators(self.readElementText())
-                    )
-                elif self.name() == "Vcs":
-                    self.__readVcs()
-                elif self.name() == "FiletypeAssociations":
-                    self.__readFiletypeAssociations()
-                elif self.name() == "LexerAssociations":
-                    self.__readLexerAssociations()
-                elif self.name() == "Make":
-                    self.__readBasicDataField(
-                        "Make", "MakeParameters", "MAKEPARAMS")
-                elif self.name() == "IdlCompiler":
-                    self.__readBasicDataField(
-                        "IdlCompiler", "IdlCompilerParameters", "IDLPARAMS")
-                elif self.name() == "UicCompiler":
-                    self.__readBasicDataField(
-                        "UicCompiler", "UicCompilerParameters", "UICPARAMS")
-                elif self.name() == "RccCompiler":
-                    self.__readBasicDataField(
-                        "RccCompiler", "RccCompilerParameters", "RCCPARAMS")
-                elif self.name() == "DocstringStyle":
-                    self.project.pdata["DOCSTRING"] = self.readElementText()
-                elif self.name() == "ProjectTypeSpecific":
-                    self.__readBasicDataField(
-                        "ProjectTypeSpecific", "ProjectTypeSpecificData",
-                        "PROJECTTYPESPECIFICDATA")
-                elif self.name() == "Documentation":
-                    self.__readBasicDataField(
-                        "Documentation", "DocumentationParams",
-                        "DOCUMENTATIONPARMS")
-                elif self.name() == "Packagers":
-                    self.__readBasicDataField(
-                        "Packagers", "PackagersParams", "PACKAGERSPARMS")
-                elif self.name() == "Checkers":
-                    self.__readBasicDataField(
-                        "Checkers", "CheckersParams", "CHECKERSPARMS")
-                elif self.name() == "OtherTools":
-                    self.__readBasicDataField(
-                        "OtherTools", "OtherToolsParams", "OTHERTOOLSPARMS")
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-        
-        self.showErrorMessage()
-    
-    def __readFiles(self, tag, listTag, dataKey):
-        """
-        Private method to read a list of files.
-        
-        @param tag name of the list tag (string)
-        @param listTag name of the list element tag (string)
-        @param dataKey key of the project data element (string)
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == tag:
-                break
-            
-            if self.isStartElement():
-                if self.name() == listTag:
-                    self.project.pdata[dataKey].append(
-                        Utilities.toNativeSeparators(self.readElementText()))
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readBasicDataField(self, tag, dataTag, dataKey):
-        """
-        Private method to read a list of files.
-        
-        @param tag name of the list tag (string)
-        @param dataTag name of the data tag (string)
-        @param dataKey key of the project data element (string)
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == tag:
-                break
-            
-            if self.isStartElement():
-                if self.name() == dataTag:
-                    self.project.pdata[dataKey] = self._readBasics()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readVcs(self):
-        """
-        Private method to read the VCS info.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Vcs":
-                break
-            
-            if self.isStartElement():
-                if self.name() == "VcsType":
-                    self.project.pdata["VCS"] = self.readElementText()
-                elif self.name() == "VcsOptions":
-                    self.project.pdata["VCSOPTIONS"] = self._readBasics()
-                elif self.name() == "VcsOtherData":
-                    self.project.pdata["VCSOTHERDATA"] = self._readBasics()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readFiletypeAssociations(self):
-        """
-        Private method to read the file type associations.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "FiletypeAssociations":
-                break
-            
-            if self.isStartElement():
-                if self.name() == "FiletypeAssociation":
-                    pattern = self.attribute("pattern", "")
-                    filetype = self.attribute("type", "OTHERS")
-                    if pattern:
-                        self.project.pdata["FILETYPES"][pattern] = filetype
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readLexerAssociations(self):
-        """
-        Private method to read the lexer associations.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "LexerAssociations":
-                break
-            
-            if self.isStartElement():
-                if self.name() == "LexerAssociation":
-                    pattern = self.attribute("pattern", "")
-                    lexer = self.attribute("lexer")
-                    if pattern:
-                        self.project.pdata["LEXERASSOCS"][pattern] = lexer
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
--- a/eric7/E5XML/ProjectWriter.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,301 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2004 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the writer class for writing an XML project file.
-"""
-
-import time
-
-from E5Gui.E5Application import e5App
-
-from .XMLStreamWriterBase import XMLStreamWriterBase
-from .Config import (
-    projectFileFormatVersion, projectFileFormatVersionRcc,
-    projectFileFormatVersionUic, projectFileFormatVersionIdl,
-    projectFileFormatVersionMake, projectFileFormatVersionProto,
-    projectFileFormatVersionAlt
-)
-
-import Preferences
-import Utilities
-
-
-class ProjectWriter(XMLStreamWriterBase):
-    """
-    Class implementing the writer class for writing an XML project file.
-    """
-    def __init__(self, device, projectName):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to write to (QIODevice)
-        @param projectName name of the project (string)
-        """
-        XMLStreamWriterBase.__init__(self, device)
-        
-        self.pdata = e5App().getObject("Project").pdata
-        self.name = projectName
-        
-    def writeXML(self):
-        """
-        Public method to write the XML to the file.
-        """
-        XMLStreamWriterBase.writeXML(self)
-        
-        project = e5App().getObject("Project")
-        if not project.hasDefaultDocstringParameter():
-            fileFormatVersion = projectFileFormatVersion
-        elif not project.hasDefaultRccCompilerParameters():
-            fileFormatVersion = projectFileFormatVersionRcc
-        elif not project.hasDefaultUicCompilerParameters():
-            fileFormatVersion = projectFileFormatVersionUic
-        elif not project.hasDefaultIdlCompilerParameters():
-            fileFormatVersion = projectFileFormatVersionIdl
-        elif not project.hasDefaultMakeParameters():
-            fileFormatVersion = projectFileFormatVersionMake
-        elif self.pdata["PROTOCOLS"]:
-            fileFormatVersion = projectFileFormatVersionProto
-        else:
-            fileFormatVersion = projectFileFormatVersionAlt
-        
-        self.writeDTD('<!DOCTYPE Project SYSTEM "Project-{0}.dtd">'.format(
-            fileFormatVersion))
-        
-        # add some generation comments
-        self.writeComment(
-            " eric project file for project {0} ".format(self.name))
-        if Preferences.getProject("TimestampFile"):
-            self.writeComment(
-                " Saved: {0} ".format(time.strftime('%Y-%m-%d, %H:%M:%S')))
-        self.writeComment(" Copyright (C) {0} {1}, {2} ".format(
-            time.strftime('%Y'),
-            self.pdata["AUTHOR"],
-            self.pdata["EMAIL"]))
-        
-        # add the main tag
-        self.writeStartElement("Project")
-        self.writeAttribute("version", fileFormatVersion)
-        
-        # do the language (used for spell checking)
-        self.writeTextElement("Language", self.pdata["SPELLLANGUAGE"])
-        if self.pdata["SPELLWORDS"]:
-            self.writeTextElement(
-                "ProjectWordList",
-                Utilities.fromNativeSeparators(self.pdata["SPELLWORDS"]))
-        if self.pdata["SPELLEXCLUDES"]:
-            self.writeTextElement(
-                "ProjectExcludeList",
-                Utilities.fromNativeSeparators(self.pdata["SPELLEXCLUDES"]))
-        
-        # do the hash
-        self.writeTextElement("Hash", self.pdata["HASH"])
-        
-        # do the programming language
-        self.writeStartElement("ProgLanguage")
-        self.writeAttribute("mixed", str(int(self.pdata["MIXEDLANGUAGE"])))
-        self.writeCharacters(self.pdata["PROGLANGUAGE"])
-        self.writeEndElement()
-        
-        # do the UI type
-        self.writeTextElement("ProjectType", self.pdata["PROJECTTYPE"])
-        
-        # do description
-        if self.pdata["DESCRIPTION"]:
-            self.writeTextElement("Description", self.pdata["DESCRIPTION"])
-        
-        # do version, author and email
-        self.writeTextElement("Version", self.pdata["VERSION"])
-        self.writeTextElement("Author", self.pdata["AUTHOR"])
-        self.writeTextElement("Email", self.pdata["EMAIL"])
-            
-        # do the translation pattern
-        if self.pdata["TRANSLATIONPATTERN"]:
-            self.writeTextElement(
-                "TranslationPattern",
-                Utilities.fromNativeSeparators(
-                    self.pdata["TRANSLATIONPATTERN"]))
-        
-        # do the binary translations path
-        if self.pdata["TRANSLATIONSBINPATH"]:
-            self.writeTextElement(
-                "TranslationsBinPath",
-                Utilities.fromNativeSeparators(
-                    self.pdata["TRANSLATIONSBINPATH"]))
-        
-        # do the eol setting
-        if self.pdata["EOL"] >= 0:
-            self.writeEmptyElement("Eol")
-            self.writeAttribute("index", str(int(self.pdata["EOL"])))
-        
-        # do the sources
-        if self.pdata["SOURCES"]:
-            self.writeStartElement("Sources")
-            for name in sorted(self.pdata["SOURCES"]):
-                self.writeTextElement(
-                    "Source", Utilities.fromNativeSeparators(name))
-            self.writeEndElement()
-        
-        # do the forms
-        if self.pdata["FORMS"]:
-            self.writeStartElement("Forms")
-            for name in sorted(self.pdata["FORMS"]):
-                self.writeTextElement(
-                    "Form", Utilities.fromNativeSeparators(name))
-            self.writeEndElement()
-        
-        # do the translations
-        if self.pdata["TRANSLATIONS"]:
-            self.writeStartElement("Translations")
-            for name in sorted(self.pdata["TRANSLATIONS"]):
-                self.writeTextElement(
-                    "Translation", Utilities.fromNativeSeparators(name))
-            self.writeEndElement()
-        
-        # do the translation exceptions
-        if self.pdata["TRANSLATIONEXCEPTIONS"]:
-            self.writeStartElement("TranslationExceptions")
-            for name in sorted(self.pdata["TRANSLATIONEXCEPTIONS"]):
-                self.writeTextElement(
-                    "TranslationException",
-                    Utilities.fromNativeSeparators(name))
-            self.writeEndElement()
-        
-        # do the resources
-        if self.pdata["RESOURCES"]:
-            self.writeStartElement("Resources")
-            for name in sorted(self.pdata["RESOURCES"]):
-                self.writeTextElement(
-                    "Resource", Utilities.fromNativeSeparators(name))
-            self.writeEndElement()
-        
-        # do the interfaces (IDL)
-        if self.pdata["INTERFACES"]:
-            self.writeStartElement("Interfaces")
-            for name in sorted(self.pdata["INTERFACES"]):
-                self.writeTextElement(
-                    "Interface", Utilities.fromNativeSeparators(name))
-            self.writeEndElement()
-        
-        # do the protocols (protobuf)
-        if self.pdata["PROTOCOLS"]:
-            self.writeStartElement("Protocols")
-            for name in sorted(self.pdata["PROTOCOLS"]):
-                self.writeTextElement(
-                    "Protocol", Utilities.fromNativeSeparators(name))
-            self.writeEndElement()
-        
-        # do the others
-        if self.pdata["OTHERS"]:
-            self.writeStartElement("Others")
-            for name in sorted(self.pdata["OTHERS"]):
-                self.writeTextElement(
-                    "Other", Utilities.fromNativeSeparators(name))
-            self.writeEndElement()
-        
-        # do the main script
-        if self.pdata["MAINSCRIPT"]:
-            self.writeTextElement(
-                "MainScript",
-                Utilities.fromNativeSeparators(self.pdata["MAINSCRIPT"]))
-        
-        # do the vcs stuff
-        self.writeStartElement("Vcs")
-        if self.pdata["VCS"]:
-            self.writeTextElement("VcsType", self.pdata["VCS"])
-        if self.pdata["VCSOPTIONS"]:
-            self.writeBasics("VcsOptions", self.pdata["VCSOPTIONS"])
-        if self.pdata["VCSOTHERDATA"]:
-            self.writeBasics("VcsOtherData", self.pdata["VCSOTHERDATA"])
-        self.writeEndElement()
-        
-        # do the filetype associations
-        self.writeStartElement("FiletypeAssociations")
-        for pattern, filetype in sorted(self.pdata["FILETYPES"].items()):
-            self.writeEmptyElement("FiletypeAssociation")
-            self.writeAttribute("pattern", pattern)
-            self.writeAttribute("type", filetype)
-        self.writeEndElement()
-        
-        # do the lexer associations
-        if self.pdata["LEXERASSOCS"]:
-            self.writeStartElement("LexerAssociations")
-            for pattern, lexer in sorted(self.pdata["LEXERASSOCS"].items()):
-                self.writeEmptyElement("LexerAssociation")
-                self.writeAttribute("pattern", pattern)
-                self.writeAttribute("lexer", lexer)
-            self.writeEndElement()
-        
-        # do the 'make' parameters
-        if not e5App().getObject("Project").hasDefaultMakeParameters():
-            self.writeStartElement("Make")
-            self.writeBasics("MakeParameters", self.pdata["MAKEPARAMS"])
-            self.writeEndElement()
-        
-        # do the 'IDL' parameters
-        if not e5App().getObject("Project").hasDefaultIdlCompilerParameters():
-            self.writeStartElement("IdlCompiler")
-            self.writeBasics("IdlCompilerParameters", self.pdata["IDLPARAMS"])
-            self.writeEndElement()
-        
-        # do the 'uic' parameters
-        if not e5App().getObject("Project").hasDefaultUicCompilerParameters():
-            self.writeStartElement("UicCompiler")
-            self.writeBasics("UicCompilerParameters", self.pdata["UICPARAMS"])
-            self.writeEndElement()
-        
-        # do the 'rcc' parameters
-        if not e5App().getObject("Project").hasDefaultRccCompilerParameters():
-            self.writeStartElement("RccCompiler")
-            self.writeBasics("RccCompilerParameters", self.pdata["RCCPARAMS"])
-            self.writeEndElement()
-        
-        # do the 'docstring' parameter
-        if not e5App().getObject("Project").hasDefaultDocstringParameter():
-            self.writeTextElement("DocstringStyle", self.pdata["DOCSTRING"])
-        
-        # do the extra project data stuff
-        if len(self.pdata["PROJECTTYPESPECIFICDATA"]):
-            self.writeStartElement("ProjectTypeSpecific")
-            if self.pdata["PROJECTTYPESPECIFICDATA"]:
-                self.writeBasics(
-                    "ProjectTypeSpecificData",
-                    self.pdata["PROJECTTYPESPECIFICDATA"])
-            self.writeEndElement()
-        
-        # do the documentation generators stuff
-        if len(self.pdata["DOCUMENTATIONPARMS"]):
-            self.writeStartElement("Documentation")
-            if self.pdata["DOCUMENTATIONPARMS"]:
-                self.writeBasics(
-                    "DocumentationParams", self.pdata["DOCUMENTATIONPARMS"])
-            self.writeEndElement()
-        
-        # do the packagers stuff
-        if len(self.pdata["PACKAGERSPARMS"]):
-            self.writeStartElement("Packagers")
-            if self.pdata["PACKAGERSPARMS"]:
-                self.writeBasics(
-                    "PackagersParams", self.pdata["PACKAGERSPARMS"])
-            self.writeEndElement()
-        
-        # do the checkers stuff
-        if len(self.pdata["CHECKERSPARMS"]):
-            self.writeStartElement("Checkers")
-            if self.pdata["CHECKERSPARMS"]:
-                self.writeBasics(
-                    "CheckersParams", self.pdata["CHECKERSPARMS"])
-            self.writeEndElement()
-        
-        # do the other tools stuff
-        if len(self.pdata["OTHERTOOLSPARMS"]):
-            self.writeStartElement("OtherTools")
-            if self.pdata["OTHERTOOLSPARMS"]:
-                self.writeBasics(
-                    "OtherToolsParams", self.pdata["OTHERTOOLSPARMS"])
-            self.writeEndElement()
-        
-        self.writeEndElement()
-        self.writeEndDocument()
--- a/eric7/E5XML/SessionReader.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,425 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing a class for reading an XML session file.
-"""
-
-from E5Gui.E5Application import e5App
-
-from .Config import sessionFileFormatVersion
-from .XMLStreamReaderBase import XMLStreamReaderBase
-
-
-class SessionReader(XMLStreamReaderBase):
-    """
-    Class for reading an XML session file.
-    """
-    supportedVersions = ["4.3", "4.4", "5.0", "6.0", "6.1", "6.2", "6.3",
-                         "6.4"]
-    
-    def __init__(self, device, isGlobal):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to read from
-        @type QIODevice
-        @param isGlobal flag indicating to read the global session
-        @type bool
-        """
-        XMLStreamReaderBase.__init__(self, device)
-        
-        self.version = ""
-        self.isGlobal = isGlobal
-        
-        self.project = e5App().getObject("Project")
-        self.projectBrowser = e5App().getObject("ProjectBrowser")
-        self.multiProject = e5App().getObject("MultiProject")
-        self.vm = e5App().getObject("ViewManager")
-        self.dbg = e5App().getObject("DebugUI")
-        self.dbs = e5App().getObject("DebugServer")
-        
-        if not self.isGlobal:
-            # clear all breakpoints and bookmarks first
-            # (in case we are rereading a session file)
-            files = self.project.getSources(True)
-            for file in files:
-                editor = self.vm.getOpenEditor(file)
-                if editor is not None:
-                    editor.clearBookmarks()
-            self.dbs.getBreakPointModel().deleteAll()
-            self.dbs.getWatchPointModel().deleteAll()
-    
-    def readXML(self, quiet=False):
-        """
-        Public method to read and parse the XML document.
-        
-        @param quiet flag indicating quiet operations.
-            If this flag is true, no errors are reported.
-        @type bool
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isStartElement():
-                if self.name() == "Session":
-                    self.version = self.attribute(
-                        "version", sessionFileFormatVersion)
-                    if self.version not in self.supportedVersions:
-                        self.raiseUnsupportedFormatVersion(self.version)
-                elif self.name() == "MultiProject":
-                    self.multiProject.openMultiProject(
-                        self.readElementText(), False)
-                elif self.name() == "Project":
-                    self.project.openProject(self.readElementText(), False)
-                elif self.name() == "Filenames":
-                    self.__readFilenames()
-                elif self.name() == "ActiveWindow":
-                    cline = int(self.attribute("cline", "0"))
-                    cindex = int(self.attribute("cindex", "0"))
-                    filename = self.readElementText()
-                    self.vm.openFiles(filename)
-                    ed = self.vm.getOpenEditor(filename)
-                    if ed is not None:
-                        ed.setCursorPosition(cline, cindex)
-                        ed.ensureCursorVisible()
-                elif self.name() == "Breakpoints":
-                    self.__readBreakpoints()
-                elif self.name() == "Watchexpressions":
-                    self.__readWatchexpressions()
-                elif self.name() == "DebugInfo":
-                    self.__readDebugInfo()
-                elif self.name() == "Bookmarks":
-                    self.__readBookmarks()
-                elif self.name() == "ProjectBrowserStates":
-                    self.__readProjectBrowserStates()
-                elif self.name() == "ViewManagerSplits":
-                    splitCount = int(self.attribute("count", "0"))
-                    orientation = int(self.attribute("orientation", "1"))
-                    self.vm.setSplitOrientation(orientation)
-                    self.vm.setSplitCount(splitCount)
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-        
-        if not quiet:
-            self.showErrorMessage()
-    
-    def __readFilenames(self):
-        """
-        Private method to read the file name infos.
-        """
-        editorDict = {}
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Filenames":
-                break
-            
-            if self.isStartElement():
-                if self.name() == "Filename":
-                    cline = int(self.attribute("cline", "0"))
-                    cindex = int(self.attribute("cindex", "0"))
-                    folds = self.attribute("folds")
-                    if folds:
-                        folds = [int(f) - 1 for f in folds.split(',')]
-                    else:
-                        folds = []
-                    zoom = int(self.attribute("zoom", "-9999"))
-                    cloned = bool(int(self.attribute("cloned", "0")))
-                    splitIndex = int(self.attribute("splitindex", "0"))
-                    editorIndex = int(self.attribute("editorindex", "-1"))
-                    filename = self.readElementText()
-                    
-                    if cloned and filename in editorDict:
-                        editor = editorDict[filename]
-                        ed = self.vm.newEditorView(
-                            filename, editor, editor.getFileType(),
-                            indexes=(splitIndex, editorIndex))
-                    else:
-                        ed = self.vm.openSourceFile(
-                            filename, indexes=(splitIndex, editorIndex))
-                        editorDict[filename] = ed
-                    if ed is not None:
-                        if zoom > -9999:
-                            ed.zoomTo(zoom)
-                        if folds:
-                            ed.recolor()
-                            ed.setContractedFolds(folds)
-                        ed.setCursorPosition(cline, cindex)
-                        ed.ensureCursorVisible()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readBreakpoints(self):
-        """
-        Private method to read the break point infos.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Breakpoints":
-                break
-            
-            if self.isStartElement():
-                if self.name() == "Breakpoint":
-                    self.__readBreakpoint()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readBreakpoint(self):
-        """
-        Private method to read the break point info.
-        """
-        filename = ""
-        lineno = 0
-        bpCond = ""
-        bpTemp = False
-        bpEnabled = True
-        bpCount = 0
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Breakpoint":
-                self.dbs.getBreakPointModel().addBreakPoint(
-                    filename, lineno, (bpCond, bpTemp, bpEnabled, bpCount))
-                break
-            
-            if self.isStartElement():
-                if self.name() == "BpFilename":
-                    filename = self.readElementText()
-                elif self.name() == "Linenumber":
-                    lineno = int(self.attribute("value", "0"))
-                elif self.name() == "Condition":
-                    bpCond = self.readElementText()
-                    if bpCond == 'None':
-                        bpCond = ''
-                elif self.name() == "Temporary":
-                    bpTemp = self.toBool(self.attribute("value", "False"))
-                elif self.name() == "Enabled":
-                    bpEnabled = self.toBool(self.attribute("value", "True"))
-                elif self.name() == "Count":
-                    bpCount = int(self.attribute("value", "0"))
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readWatchexpressions(self):
-        """
-        Private method to read watch expression infos.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Watchexpressions":
-                break
-            
-            if self.isStartElement():
-                if self.name() == "Watchexpression":
-                    self.__readWatchexpression()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readWatchexpression(self):
-        """
-        Private method to read the watch expression info.
-        """
-        weCond = ""
-        weTemp = False
-        weEnabled = True
-        weCount = 0
-        weSpecialCond = ""
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Watchexpression":
-                self.dbs.getWatchPointModel().addWatchPoint(
-                    weCond, weSpecialCond, (weTemp, weEnabled, weCount))
-                break
-            
-            if self.isStartElement():
-                if self.name() == "Condition":
-                    weCond = self.readElementText()
-                    if weCond == 'None':
-                        weCond = ''
-                elif self.name() == "Temporary":
-                    weTemp = self.toBool(self.attribute("value", "False"))
-                elif self.name() == "Enabled":
-                    weEnabled = self.toBool(self.attribute("value", "True"))
-                elif self.name() == "Count":
-                    weCount = int(self.attribute("value", "0"))
-                elif self.name() == "Special":
-                    weSpecialCond = self.readElementText()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readDebugInfo(self):
-        """
-        Private method to read the debug infos.
-        """
-        dbgExcList = []
-        dbgExcIgnoreList = []
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement():
-                if self.name() == "DebugInfo":
-                    break
-                elif self.name() == "Exceptions":
-                    self.dbg.setExcList(dbgExcList)
-                    if not self.isGlobal:
-                        self.project.dbgExcList = dbgExcList[:]
-                elif self.name() == "IgnoredExceptions":
-                    self.dbg.setExcIgnoreList(dbgExcIgnoreList)
-                    if not self.isGlobal:
-                        self.project.dbgExcIgnoreList = dbgExcIgnoreList[:]
-            
-            if self.isStartElement():
-                if self.name() in ("Exceptions", "IgnoredExceptions",
-                                   "CovexcPattern"):
-                    pass    # ignore these start tags
-                elif self.name() == "VirtualEnv":
-                    txt = self.readElementText()
-                    self.dbg.lastUsedVenvName = txt
-                    if not self.isGlobal:
-                        self.project.dbgVirtualEnv = txt
-                elif self.name() == "Interpreter":
-                    # just read this obsolete entry and ignore it
-                    self.readElementText()
-                elif self.name() == "CommandLine":
-                    txt = self.readElementText()
-                    self.dbg.setArgvHistory(txt)
-                    if not self.isGlobal:
-                        self.project.dbgCmdline = txt
-                elif self.name() == "WorkingDirectory":
-                    txt = self.readElementText()
-                    self.dbg.setWdHistory(txt)
-                    if not self.isGlobal:
-                        self.project.dbgWd = txt
-                elif self.name() == "Environment":
-                    txt = self.readElementText()
-                    self.dbg.setEnvHistory(txt)
-                    if not self.isGlobal:
-                        self.project.dbgEnv = txt
-                elif self.name() == "ReportExceptions":
-                    exc = self.toBool(self.attribute("value", "True"))
-                    self.dbg.setExceptionReporting(exc)
-                    if not self.isGlobal:
-                        self.project.dbgReportExceptions = exc
-                elif self.name() == "Exception":
-                    dbgExcList.append(self.readElementText())
-                elif self.name() == "IgnoredException":
-                    dbgExcIgnoreList.append(self.readElementText())
-                elif self.name() == "AutoClearShell":
-                    val = self.toBool(self.attribute("value"))
-                    self.dbg.setAutoClearShell(val)
-                    if not self.isGlobal:
-                        self.project.dbgAutoClearShell = val
-                elif self.name() == "TracePython":
-                    val = self.toBool(self.attribute("value"))
-                    self.dbg.setTracePython(val)
-                    if not self.isGlobal:
-                        self.project.dbgTracePython = val
-                elif self.name() == "AutoContinue":
-                    val = self.toBool(self.attribute("value"))
-                    self.dbg.setAutoContinue(val)
-                    if not self.isGlobal:
-                        self.project.dbgAutoContinue = val
-                elif self.name() == "EnableMultiprocess":
-                    val = self.toBool(self.attribute("value"))
-                    self.dbg.setEnableMultiprocess(val)
-                    if not self.isGlobal:
-                        self.project.dbgEnableMultiprocess = val
-                elif self.name() == "MultiprocessNoDebug":
-                    txt = self.readElementText()
-                    self.dbg.setMultiprocessNoDebugHistory(txt)
-                    if not self.isGlobal:
-                        self.project.dbgMultiprocessNoDebug = txt
-                elif self.name() == "GlobalConfigOverride":
-                    configOverride = {
-                        "enable": self.toBool(self.attribute("enable")),
-                        "redirect": self.toBool(self.attribute("redirect")),
-                    }
-                    self.dbg.setEnableGlobalConfigOverride(configOverride)
-                    if not self.isGlobal:
-                        self.project.dbgGlobalConfigOverride = configOverride
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readBookmarks(self):
-        """
-        Private method to read the bookmark infos.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Bookmarks":
-                break
-            
-            if self.isStartElement():
-                if self.name() == "Bookmark":
-                    self.__readBookmark()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readBookmark(self):
-        """
-        Private method to read the bookmark info.
-        """
-        filename = ""
-        lineno = 0
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Bookmark":
-                editor = self.vm.getOpenEditor(filename)
-                if editor is not None:
-                    editor.toggleBookmark(lineno)
-                break
-            
-            if self.isStartElement():
-                if self.name() == "BmFilename":
-                    filename = self.readElementText()
-                elif self.name() == "Linenumber":
-                    lineno = int(self.attribute("value", "0"))
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readProjectBrowserStates(self):
-        """
-        Private method to read the project browser state infos.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "ProjectBrowserStates":
-                break
-            
-            if self.isStartElement():
-                if self.name() == "ProjectBrowserState":
-                    browserName = self.attribute("name", "")
-                    if not browserName:
-                        self.raiseBadValue("ProjectBrowserState.name")
-                    self.__readProjectBrowserState(browserName)
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-        
-    def __readProjectBrowserState(self, browserName):
-        """
-        Private method to read the project browser state info.
-        
-        @param browserName name of the project browser
-        @type str
-        """
-        expandedNames = []
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "ProjectBrowserState":
-                projectBrowser = self.projectBrowser.getProjectBrowser(
-                    browserName)
-                if projectBrowser is not None:
-                    projectBrowser.expandItemsByName(expandedNames)
-                break
-            
-            if self.isStartElement():
-                if self.name() == "ExpandedItemName":
-                    itemName = self.readElementText()
-                    if itemName:
-                        expandedNames.append(itemName)
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
--- a/eric7/E5XML/SessionWriter.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,281 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2004 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the writer class for writing an XML session file.
-"""
-
-import time
-
-from E5Gui.E5Application import e5App
-
-from .XMLStreamWriterBase import XMLStreamWriterBase
-from .Config import sessionFileFormatVersion
-
-import Preferences
-
-
-class SessionWriter(XMLStreamWriterBase):
-    """
-    Class implementing the writer class for writing an XML session file.
-    """
-    def __init__(self, device, projectName):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to write to
-        @type QIODevice
-        @param projectName name of the project or None for the
-            global session
-        @type str or None
-        """
-        XMLStreamWriterBase.__init__(self, device)
-        
-        self.name = projectName
-        self.project = e5App().getObject("Project")
-        self.projectBrowser = e5App().getObject("ProjectBrowser")
-        self.multiProject = e5App().getObject("MultiProject")
-        self.vm = e5App().getObject("ViewManager")
-        self.dbg = e5App().getObject("DebugUI")
-        self.dbs = e5App().getObject("DebugServer")
-        
-    def writeXML(self):
-        """
-        Public method to write the XML to the file.
-        """
-        isGlobal = self.name is None
-        
-        XMLStreamWriterBase.writeXML(self)
-        
-        self.writeDTD('<!DOCTYPE Session SYSTEM "Session-{0}.dtd">'.format(
-            sessionFileFormatVersion))
-        
-        # add some generation comments
-        if not isGlobal:
-            self.writeComment(
-                " eric session file for project {0} ".format(self.name))
-        self.writeComment(
-            " This file was generated automatically, do not edit. ")
-        if Preferences.getProject("TimestampFile") or isGlobal:
-            self.writeComment(
-                " Saved: {0} ".format(time.strftime('%Y-%m-%d, %H:%M:%S')))
-        
-        # add the main tag
-        self.writeStartElement("Session")
-        self.writeAttribute("version", sessionFileFormatVersion)
-        
-        # step 0: save open multi project and project for the global session
-        if isGlobal:
-            if self.multiProject.isOpen():
-                self.writeTextElement(
-                    "MultiProject", self.multiProject.getMultiProjectFile())
-            if self.project.isOpen():
-                self.writeTextElement("Project", self.project.getProjectFile())
-        
-        # step 1: save all open (project) filenames and the active window
-        if self.vm.canSplit():
-            self.writeEmptyElement("ViewManagerSplits")
-            self.writeAttribute("count", str(self.vm.splitCount()))
-            self.writeAttribute("orientation",
-                                str(self.vm.getSplitOrientation()))
-        
-        allOpenEditorLists = self.vm.getOpenEditorsForSession()
-        editorDict = {}     # remember editors by file name to detect clones
-        self.writeStartElement("Filenames")
-        for splitIndex, openEditorList in enumerate(allOpenEditorLists):
-            for editorIndex, editor in enumerate(openEditorList):
-                fileName = editor.getFileName()
-                if isGlobal or self.project.isProjectFile(fileName):
-                    line, index = editor.getCursorPosition()
-                    folds = ','.join(
-                        [str(i + 1) for i in editor.contractedFolds()])
-                    zoom = editor.getZoom()
-                    if fileName in editorDict:
-                        isClone = int(editorDict[fileName].isClone(editor))
-                    else:
-                        isClone = 0
-                        editorDict[fileName] = editor
-                    self.writeStartElement("Filename")
-                    self.writeAttribute("cline", str(line))
-                    self.writeAttribute("cindex", str(index))
-                    self.writeAttribute("folds", folds)
-                    self.writeAttribute("zoom", str(zoom))
-                    self.writeAttribute("cloned", str(isClone))
-                    self.writeAttribute("splitindex", str(splitIndex))
-                    self.writeAttribute("editorindex", str(editorIndex))
-                    self.writeCharacters(fileName)
-                    self.writeEndElement()
-        self.writeEndElement()
-        
-        aw = self.vm.getActiveName()
-        if aw and (isGlobal or self.project.isProjectFile(aw)):
-            ed = self.vm.getOpenEditor(aw)
-            line, index = ed.getCursorPosition()
-            self.writeStartElement("ActiveWindow")
-            self.writeAttribute("cline", str(line))
-            self.writeAttribute("cindex", str(index))
-            self.writeCharacters(aw)
-            self.writeEndElement()
-        
-        # step 2a: save all breakpoints
-        allBreaks = Preferences.getProject("SessionAllBreakpoints")
-        projectFiles = self.project.getSources(True)
-        bpModel = self.dbs.getBreakPointModel()
-        self.writeStartElement("Breakpoints")
-        for row in range(bpModel.rowCount()):
-            index = bpModel.index(row, 0)
-            fname, lineno, cond, temp, enabled, count = (
-                bpModel.getBreakPointByIndex(index)[:6]
-            )
-            if isGlobal or allBreaks or fname in projectFiles:
-                self.writeStartElement("Breakpoint")
-                self.writeTextElement("BpFilename", fname)
-                self.writeEmptyElement("Linenumber")
-                self.writeAttribute("value", str(lineno))
-                self.writeTextElement("Condition", str(cond))
-                self.writeEmptyElement("Temporary")
-                self.writeAttribute("value", str(temp))
-                self.writeEmptyElement("Enabled")
-                self.writeAttribute("value", str(enabled))
-                self.writeEmptyElement("Count")
-                self.writeAttribute("value", str(count))
-                self.writeEndElement()
-        self.writeEndElement()
-        
-        # step 2b: save all watch expressions
-        self.writeStartElement("Watchexpressions")
-        wpModel = self.dbs.getWatchPointModel()
-        for row in range(wpModel.rowCount()):
-            index = wpModel.index(row, 0)
-            cond, special, temp, enabled, count = (
-                wpModel.getWatchPointByIndex(index)[:5]
-            )
-            self.writeStartElement("Watchexpression")
-            self.writeTextElement("Condition", str(cond))
-            self.writeEmptyElement("Temporary")
-            self.writeAttribute("value", str(temp))
-            self.writeEmptyElement("Enabled")
-            self.writeAttribute("value", str(enabled))
-            self.writeEmptyElement("Count")
-            self.writeAttribute("value", str(count))
-            self.writeTextElement("Special", special)
-            self.writeEndElement()
-        self.writeEndElement()
-        
-        # step 3: save the debug info
-        self.writeStartElement("DebugInfo")
-        if isGlobal:
-            if len(self.dbg.argvHistory):
-                dbgCmdline = str(self.dbg.argvHistory[0])
-            else:
-                dbgCmdline = ""
-            if len(self.dbg.wdHistory):
-                dbgWd = self.dbg.wdHistory[0]
-            else:
-                dbgWd = ""
-            if len(self.dbg.envHistory):
-                dbgEnv = self.dbg.envHistory[0]
-            else:
-                dbgEnv = ""
-            if len(self.dbg.multiprocessNoDebugHistory):
-                dbgMultiprocessNoDebug = self.dbg.multiprocessNoDebugHistory[0]
-            else:
-                dbgMultiprocessNoDebug = ""
-            
-            self.writeTextElement("VirtualEnv", self.dbg.lastUsedVenvName)
-            self.writeTextElement("CommandLine", dbgCmdline)
-            self.writeTextElement("WorkingDirectory", dbgWd)
-            self.writeTextElement("Environment", dbgEnv)
-            self.writeEmptyElement("ReportExceptions")
-            self.writeAttribute("value", str(self.dbg.exceptions))
-            self.writeStartElement("Exceptions")
-            for exc in self.dbg.excList:
-                self.writeTextElement("Exception", exc)
-            self.writeEndElement()
-            self.writeStartElement("IgnoredExceptions")
-            for iexc in self.dbg.excIgnoreList:
-                self.writeTextElement("IgnoredException", iexc)
-            self.writeEndElement()
-            self.writeEmptyElement("AutoClearShell")
-            self.writeAttribute("value", str(self.dbg.autoClearShell))
-            self.writeEmptyElement("TracePython")
-            self.writeAttribute("value", str(self.dbg.tracePython))
-            self.writeEmptyElement("AutoContinue")
-            self.writeAttribute("value", str(self.dbg.autoContinue))
-            self.writeEmptyElement("EnableMultiprocess")
-            self.writeAttribute("value", str(self.dbg.enableMultiprocess))
-            self.writeTextElement("MultiprocessNoDebug",
-                                  dbgMultiprocessNoDebug)
-            self.writeEmptyElement("CovexcPattern")    # kept for compatibility
-            self.writeEmptyElement("GlobalConfigOverride")
-            self.writeAttribute(
-                "enable", str(self.dbg.overrideGlobalConfig["enable"]))
-            self.writeAttribute(
-                "redirect", str(self.dbg.overrideGlobalConfig["redirect"]))
-        else:
-            self.writeTextElement("VirtualEnv", self.project.dbgVirtualEnv)
-            self.writeTextElement("CommandLine", self.project.dbgCmdline)
-            self.writeTextElement("WorkingDirectory", self.project.dbgWd)
-            self.writeTextElement("Environment", self.project.dbgEnv)
-            self.writeEmptyElement("ReportExceptions")
-            self.writeAttribute("value", str(self.project.dbgReportExceptions))
-            self.writeStartElement("Exceptions")
-            for exc in self.project.dbgExcList:
-                self.writeTextElement("Exception", exc)
-            self.writeEndElement()
-            self.writeStartElement("IgnoredExceptions")
-            for iexc in self.project.dbgExcIgnoreList:
-                self.writeTextElement("IgnoredException", iexc)
-            self.writeEndElement()
-            self.writeEmptyElement("AutoClearShell")
-            self.writeAttribute("value", str(self.project.dbgAutoClearShell))
-            self.writeEmptyElement("TracePython")
-            self.writeAttribute("value", str(self.project.dbgTracePython))
-            self.writeEmptyElement("AutoContinue")
-            self.writeAttribute("value", str(self.project.dbgAutoContinue))
-            self.writeEmptyElement("EnableMultiprocess")
-            self.writeAttribute("value",
-                                str(self.project.dbgEnableMultiprocess))
-            self.writeTextElement("MultiprocessNoDebug",
-                                  self.project.dbgMultiprocessNoDebug)
-            self.writeEmptyElement("CovexcPattern")    # kept for compatibility
-            self.writeEmptyElement("GlobalConfigOverride")
-            self.writeAttribute(
-                "enable", str(self.project.dbgGlobalConfigOverride["enable"]))
-            self.writeAttribute(
-                "redirect",
-                str(self.project.dbgGlobalConfigOverride["redirect"]))
-        self.writeEndElement()
-        
-        # step 4: save bookmarks of all open (project) files
-        self.writeStartElement("Bookmarks")
-        for fileName in editorDict:
-            if isGlobal or self.project.isProjectFile(fileName):
-                editor = editorDict[fileName]
-                for bookmark in editor.getBookmarks():
-                    self.writeStartElement("Bookmark")
-                    self.writeTextElement("BmFilename", fileName)
-                    self.writeEmptyElement("Linenumber")
-                    self.writeAttribute("value", str(bookmark))
-                    self.writeEndElement()
-        self.writeEndElement()
-        
-        # step 5: save state of the various project browsers
-        if not isGlobal:
-            self.writeStartElement("ProjectBrowserStates")
-            for browserName in self.projectBrowser.getProjectBrowserNames():
-                self.writeStartElement("ProjectBrowserState")
-                self.writeAttribute("name", browserName)
-                # get the names of expanded files and directories
-                names = self.projectBrowser.getProjectBrowser(
-                    browserName).getExpandedItemNames()
-                for name in names:
-                    self.writeTextElement("ExpandedItemName", name)
-                self.writeEndElement()
-            self.writeEndElement()
-        
-        # add the main end tag
-        self.writeEndElement()
-        self.writeEndDocument()
--- a/eric7/E5XML/ShortcutsReader.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing a class for reading an XML shortcuts file.
-"""
-
-from .Config import shortcutsFileFormatVersion
-from .XMLStreamReaderBase import XMLStreamReaderBase
-
-
-class ShortcutsReader(XMLStreamReaderBase):
-    """
-    Class for reading an XML shortcuts file.
-    """
-    supportedVersions = ["3.6"]
-    
-    def __init__(self, device):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to read from (QIODevice)
-        """
-        XMLStreamReaderBase.__init__(self, device)
-        
-        self.version = ""
-        self.shortcuts = {}
-    
-    def readXML(self):
-        """
-        Public method to read and parse the XML document.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isStartElement():
-                if self.name() == "Shortcuts":
-                    self.version = self.attribute(
-                        "version", shortcutsFileFormatVersion)
-                    if self.version not in self.supportedVersions:
-                        self.raiseUnsupportedFormatVersion(self.version)
-                elif self.name() == "Shortcut":
-                    self.__readShortCut()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-        
-        self.showErrorMessage()
-    
-    def __readShortCut(self):
-        """
-        Private method to read the shortcut data.
-        """
-        category = self.attribute("category")
-        name = ""
-        accel = ""
-        altAccel = ""
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Shortcut":
-                if category:
-                    if category not in self.shortcuts:
-                        self.shortcuts[category] = {}
-                    self.shortcuts[category][name] = (accel, altAccel)
-                break
-            
-            if self.isStartElement():
-                if self.name() == "Name":
-                    name = self.readElementText()
-                elif self.name() == "Accel":
-                    accel = self.readElementText()
-                elif self.name() == "AltAccel":
-                    altAccel = self.readElementText()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def getShortcuts(self):
-        """
-        Public method to retrieve the shortcuts.
-        
-        @return Dictionary of dictionaries of shortcuts. The keys of the
-            dictionary are the categories, the values are dictionaries.
-            These dictionaries have the shortcut name as their key and
-            a tuple of accelerators as their value.
-        """
-        return self.shortcuts
--- a/eric7/E5XML/ShortcutsWriter.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2004 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the writer class for writing an XML shortcuts file.
-"""
-
-import time
-
-from E5Gui.E5Application import e5App
-
-from .XMLStreamWriterBase import XMLStreamWriterBase
-from .Config import shortcutsFileFormatVersion
-
-import Preferences
-
-
-class ShortcutsWriter(XMLStreamWriterBase):
-    """
-    Class implementing the writer class for writing an XML shortcuts file.
-    """
-    def __init__(self, device):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to write to (QIODevice)
-        """
-        XMLStreamWriterBase.__init__(self, device)
-        
-        self.email = Preferences.getUser("Email")
-        
-    def writeXML(self, helpViewer=None):
-        """
-        Public method to write the XML to the file.
-        
-        @param helpViewer reference to the help window object
-        """
-        XMLStreamWriterBase.writeXML(self)
-        
-        self.writeDTD('<!DOCTYPE Shortcuts SYSTEM "Shortcuts-{0}.dtd">'.format(
-            shortcutsFileFormatVersion))
-        
-        # add some generation comments
-        self.writeComment(" eric keyboard shortcuts ")
-        self.writeComment(
-            " Saved: {0}".format(time.strftime('%Y-%m-%d, %H:%M:%S')))
-        self.writeComment(" Author: {0} ".format(self.email))
-        
-        # add the main tag
-        self.writeStartElement("Shortcuts")
-        self.writeAttribute("version", shortcutsFileFormatVersion)
-        
-        if helpViewer is None:
-            self.__writeActions(
-                "Project",
-                e5App().getObject("Project").getActions())
-            self.__writeActions(
-                "General",
-                e5App().getObject("UserInterface").getActions('ui'))
-            self.__writeActions(
-                "Wizards",
-                e5App().getObject("UserInterface").getActions('wizards'))
-            self.__writeActions(
-                "Debug",
-                e5App().getObject("DebugUI").getActions())
-            self.__writeActions(
-                "Edit",
-                e5App().getObject("ViewManager").getActions('edit'))
-            self.__writeActions(
-                "File",
-                e5App().getObject("ViewManager").getActions('file'))
-            self.__writeActions(
-                "Search",
-                e5App().getObject("ViewManager").getActions('search'))
-            self.__writeActions(
-                "View",
-                e5App().getObject("ViewManager").getActions('view'))
-            self.__writeActions(
-                "Macro",
-                e5App().getObject("ViewManager").getActions('macro'))
-            self.__writeActions(
-                "Bookmarks",
-                e5App().getObject("ViewManager").getActions('bookmark'))
-            self.__writeActions(
-                "Spelling",
-                e5App().getObject("ViewManager").getActions('spelling'))
-            self.__writeActions(
-                "Window",
-                e5App().getObject("ViewManager").getActions('window'))
-            
-            for category, ref in e5App().getPluginObjects():
-                if hasattr(ref, "getActions"):
-                    self.__writeActions(category, ref.getActions())
-        
-        else:
-            self.__writeActions(
-                helpViewer.getActionsCategory(),
-                helpViewer.getActions())
-    
-        # add the main end tag
-        self.writeEndElement()
-        self.writeEndDocument()
-    
-    def __writeActions(self, category, actions):
-        """
-        Private method to write the shortcuts for the given actions.
-        
-        @param category category the actions belong to (string)
-        @param actions list of actions to write (E5Action)
-        """
-        for act in actions:
-            if act.objectName():
-                # shortcuts are only exported, if their objectName is set
-                self.writeStartElement("Shortcut")
-                self.writeAttribute("category", category)
-                self.writeTextElement("Name", act.objectName())
-                self.writeTextElement("Accel", act.shortcut().toString())
-                self.writeTextElement(
-                    "AltAccel", act.alternateShortcut().toString())
-                self.writeEndElement()
--- a/eric7/E5XML/SpellCheckDictionariesReader.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2017 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module to read the web browser spell check dictionaries list file.
-"""
-
-from .Config import dictionariesListFileFormatVersion
-from .XMLStreamReaderBase import XMLStreamReaderBase
-
-import Preferences
-
-
-class SpellCheckDictionariesReader(XMLStreamReaderBase):
-    """
-    Class to read the web browser spell check dictionaries list file.
-    """
-    supportedVersions = ["1.0", ]
-    
-    def __init__(self, data, entryCallback):
-        """
-        Constructor
-        
-        @param data reference to the data array to read XML from (QByteArray)
-        @param entryCallback reference to a function to be called once the
-            data for a dictionary has been read (function)
-        """
-        XMLStreamReaderBase.__init__(self, data)
-        
-        self.__entryCallback = entryCallback
-        
-        self.version = ""
-        self.baseUrl = ""
-    
-    def readXML(self):
-        """
-        Public method to read and parse the XML document.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isStartElement():
-                if self.name() == "Dictionaries":
-                    self.version = self.attribute(
-                        "version",
-                        dictionariesListFileFormatVersion)
-                    self.baseUrl = self.attribute("baseurl", "")
-                    if self.version not in self.supportedVersions:
-                        self.raiseUnsupportedFormatVersion(self.version)
-                elif self.name() == "DictionariesUrl":
-                    url = self.readElementText()
-                    Preferences.setWebBrowser("SpellCheckDictionariesUrl", url)
-                elif self.name() == "Dictionary":
-                    self.__readDictionary()
-                else:
-                    self._skipUnknownElement()
-        
-        self.showErrorMessage()
-    
-    def __readDictionary(self):
-        """
-        Private method to read the plug-in info.
-        """
-        dictionaryInfo = {"short": "",
-                          "filename": "",
-                          "documentation": "",
-                          "locales": [],
-                          }
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Dictionary":
-                self.__entryCallback(
-                    dictionaryInfo["short"], dictionaryInfo["filename"],
-                    self.baseUrl + dictionaryInfo["filename"],
-                    dictionaryInfo["documentation"], dictionaryInfo["locales"])
-                break
-            
-            if self.isStartElement():
-                if self.name() == "Short":
-                    dictionaryInfo["short"] = self.readElementText()
-                elif self.name() == "Filename":
-                    dictionaryInfo["filename"] = self.readElementText()
-                elif self.name() == "Documentation":
-                    dictionaryInfo["documentation"] = self.readElementText()
-                elif self.name() == "Locales":
-                    dictionaryInfo["locales"] = self.readElementText().split()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
--- a/eric7/E5XML/TasksReader.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing a class for reading an XML tasks file.
-"""
-
-import time
-import contextlib
-
-from E5Gui.E5Application import e5App
-
-from .Config import tasksFileFormatVersion
-from .XMLStreamReaderBase import XMLStreamReaderBase
-
-from Tasks.Task import TaskType, TaskPriority
-
-import Utilities
-
-
-class TasksReader(XMLStreamReaderBase):
-    """
-    Class for reading an XML tasks file.
-    """
-    supportedVersions = ["4.2", "5.0", "5.1", "6.0"]
-    
-    def __init__(self, device, forProject=False, viewer=None):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to read from (QIODevice)
-        @param forProject flag indicating project related mode (boolean)
-        @param viewer reference to the task viewer (TaskViewer)
-        """
-        XMLStreamReaderBase.__init__(self, device)
-        
-        self.viewer = viewer
-        
-        self.forProject = forProject
-        if viewer:
-            self.viewer = viewer
-        else:
-            self.viewer = e5App().getObject("TaskViewer")
-        
-        self.version = ""
-        self.tasks = []
-    
-    def readXML(self):
-        """
-        Public method to read and parse the XML document.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Tasks":
-                for task, expanded in self.tasks:
-                    task.setExpanded(expanded)
-                break
-            
-            if self.isStartElement():
-                if self.name() == "Tasks":
-                    self.version = self.attribute(
-                        "version", tasksFileFormatVersion)
-                    if self.version not in self.supportedVersions:
-                        self.raiseUnsupportedFormatVersion(self.version)
-                elif self.name() == "Task":
-                    self.__readTask()
-                elif self.name() == "ProjectScanFilter":
-                    scanFilter = self.readElementText()
-                    if self.forProject:
-                        self.viewer.setTasksScanFilter(scanFilter)
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-        
-        self.showErrorMessage()
-    
-    def __readTask(self):
-        """
-        Private method to read the task info.
-        """
-        task = {"summary": "",
-                "priority": TaskPriority.NORMAL,
-                "completed": False,
-                "created": 0,
-                "filename": "",
-                "linenumber": 0,
-                "type": TaskType.TODO,
-                "description": "",
-                "uid": "",
-                }
-        task["priority"] = TaskPriority(
-            int(self.attribute("priority", str(TaskPriority.NORMAL.value)))
-        )
-        task["completed"] = self.toBool(self.attribute("completed", "False"))
-        if self.version in ["4.2", "5.0"]:
-            isBugfix = self.toBool(self.attribute("bugfix", "False"))
-            if isBugfix:
-                task["type"] = TaskType.FIXME
-        else:
-            task["type"] = TaskType(
-                int(self.attribute("type", str(TaskType.TODO.value)))
-            )
-        uid = self.attribute("uid", "")
-        if uid:
-            task["uid"] = uid
-        else:
-            # upgrade from pre 6.0 format
-            from PyQt6.QtCore import QUuid
-            task["uid"] = QUuid.createUuid().toString()
-        parentUid = self.attribute("parent_uid", "")
-        expanded = self.toBool(self.attribute("expanded", "True"))
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "Task":
-                parentTask = self.viewer.findParentTask(parentUid)
-                addedTask = self.viewer.addTask(
-                    task["summary"], priority=task["priority"],
-                    filename=task["filename"], lineno=task["linenumber"],
-                    completed=task["completed"], _time=task["created"],
-                    isProjectTask=self.forProject, taskType=task["type"],
-                    description=task["description"], uid=task["uid"],
-                    parentTask=parentTask)
-                self.tasks.append((addedTask, expanded))
-                break
-            
-            if self.isStartElement():
-                if self.name() == "Summary":
-                    task["summary"] = self.readElementText()
-                elif self.name() == "Description":
-                    task["description"] = self.readElementText()
-                elif self.name() == "Created":
-                    task["created"] = time.mktime(time.strptime(
-                        self.readElementText(), "%Y-%m-%d, %H:%M:%S"))
-                elif self.name() == "Resource":
-                    continue    # handle but ignore this tag
-                elif self.name() == "Filename":
-                    task["filename"] = Utilities.toNativeSeparators(
-                        self.readElementText()
-                    )
-                elif self.name() == "Linenumber":
-                    with contextlib.suppress(ValueError):
-                        task["linenumber"] = int(self.readElementText())
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
--- a/eric7/E5XML/TasksWriter.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2005 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the writer class for writing an XML tasks file.
-"""
-
-import time
-
-from E5Gui.E5Application import e5App
-
-from .XMLStreamWriterBase import XMLStreamWriterBase
-from .Config import tasksFileFormatVersion
-
-import Preferences
-import Utilities
-
-
-class TasksWriter(XMLStreamWriterBase):
-    """
-    Class implementing the writer class for writing an XML tasks file.
-    """
-    def __init__(self, device, forProject=False, projectName=""):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to write to (QIODevice)
-        @param forProject flag indicating project related mode (boolean)
-        @param projectName name of the project (string)
-        """
-        XMLStreamWriterBase.__init__(self, device)
-        
-        self.name = projectName
-        self.forProject = forProject
-        
-    def writeXML(self):
-        """
-        Public method to write the XML to the file.
-        """
-        XMLStreamWriterBase.writeXML(self)
-        
-        self.writeDTD('<!DOCTYPE Tasks SYSTEM "Tasks-{0}.dtd">'.format(
-            tasksFileFormatVersion))
-        
-        # add some generation comments
-        if self.forProject:
-            self.writeComment(
-                " eric tasks file for project {0} ".format(self.name))
-            if Preferences.getProject("TimestampFile"):
-                self.writeComment(" Saved: {0} ".format(
-                    time.strftime('%Y-%m-%d, %H:%M:%S')))
-        else:
-            self.writeComment(" eric tasks file ")
-            self.writeComment(
-                " Saved: {0} ".format(time.strftime('%Y-%m-%d, %H:%M:%S')))
-        
-        # add the main tag
-        self.writeStartElement("Tasks")
-        self.writeAttribute("version", tasksFileFormatVersion)
-        
-        # write the project scan filter
-        if self.forProject:
-            self.writeTextElement(
-                "ProjectScanFilter",
-                e5App().getObject("TaskViewer").getTasksScanFilter())
-        
-        # do the tasks
-        tasks = (
-            e5App().getObject("TaskViewer").getProjectTasks()
-            if self.forProject else
-            e5App().getObject("TaskViewer").getGlobalTasks()
-        )
-        for task in tasks:
-            self.writeStartElement("Task")
-            self.writeAttribute("priority", str(task.priority.value))
-            self.writeAttribute("completed", str(task.completed))
-            self.writeAttribute("type", str(task.taskType.value))
-            self.writeAttribute("uid", task.uid)
-            if task.parentUid:
-                self.writeAttribute("parent_uid", task.parentUid)
-            if task.childCount() > 0:
-                self.writeAttribute("expanded", str(task.isExpanded()))
-            
-            self.writeTextElement("Summary", task.summary.strip())
-            self.writeTextElement("Description", task.description.strip())
-            self.writeTextElement("Created", time.strftime(
-                "%Y-%m-%d, %H:%M:%S", time.localtime(task.created)))
-            if task.filename:
-                self.writeStartElement("Resource")
-                self.writeTextElement(
-                    "Filename",
-                    Utilities.fromNativeSeparators(task.filename))
-                self.writeTextElement("Linenumber", str(task.lineno))
-                self.writeEndElement()
-            self.writeEndElement()
-        
-        self.writeEndElement()
-        self.writeEndDocument()
--- a/eric7/E5XML/TemplatesReader.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing a class for reading an XML templates file.
-"""
-
-from .Config import templatesFileFormatVersion
-from .XMLStreamReaderBase import XMLStreamReaderBase
-
-
-class TemplatesReader(XMLStreamReaderBase):
-    """
-    Class for reading an XML tasks file.
-    """
-    supportedVersions = ["4.0"]
-    
-    def __init__(self, device, viewer):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to read from (QIODevice)
-        @param viewer reference to the template viewer object (TemplateViewer)
-        """
-        XMLStreamReaderBase.__init__(self, device)
-        
-        self.__viewer = viewer
-        
-        self.version = ""
-        self.groupName = "DEFAULT"
-    
-    def readXML(self):
-        """
-        Public method to read and parse the XML document.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isStartElement():
-                if self.name() == "Templates":
-                    self.version = self.attribute(
-                        "version", templatesFileFormatVersion)
-                    if self.version not in self.supportedVersions:
-                        self.raiseUnsupportedFormatVersion(self.version)
-                elif self.name() == "TemplateGroup":
-                    self.__readTemplateGroup()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-        
-        self.showErrorMessage()
-    
-    def __readTemplateGroup(self):
-        """
-        Private method to read a template group.
-        """
-        self.groupName = self.attribute('name', "DEFAULT")
-        language = self.attribute('language', "All")
-        self.__viewer.addGroup(self.groupName, language)
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement() and self.name() == "TemplateGroup":
-                break
-            
-            if self.isStartElement():
-                if self.name() == "Template":
-                    self.__readTemplate()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-    
-    def __readTemplate(self):
-        """
-        Private method to read the template definition.
-        """
-        templateName = self.attribute('name', '')
-        templateDescription = ""
-        templateText = ""
-        
-        while not self.atEnd():
-            self.readNext()
-            if (
-                self.isEndElement() and
-                self.name() == "Template" and
-                templateName
-            ):
-                self.__viewer.addEntry(self.groupName, templateName,
-                                       templateDescription, templateText,
-                                       quiet=True)
-                break
-            
-            if self.isStartElement():
-                if self.name() == "TemplateDescription":
-                    templateDescription = self.readElementText()
-                elif self.name() == "TemplateText":
-                    templateText = self.readElementText()
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
--- a/eric7/E5XML/TemplatesWriter.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2005 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the writer class for writing an XML templates file.
-"""
-
-import time
-
-from .XMLStreamWriterBase import XMLStreamWriterBase
-from .Config import templatesFileFormatVersion
-
-
-class TemplatesWriter(XMLStreamWriterBase):
-    """
-    Class implementing the writer class for writing an XML templates file.
-    """
-    def __init__(self, device, templatesViewer):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to write to (QIODevice)
-        @param templatesViewer reference to the templates viewer object
-            (TemplateViewer)
-        """
-        XMLStreamWriterBase.__init__(self, device)
-        
-        self.templatesViewer = templatesViewer
-        
-    def writeXML(self):
-        """
-        Public method to write the XML to the file.
-        """
-        XMLStreamWriterBase.writeXML(self)
-        
-        self.writeDTD('<!DOCTYPE Templates SYSTEM "Templates-{0}.dtd">'.format(
-            templatesFileFormatVersion))
-        
-        # add some generation comments
-        self.writeComment(" eric templates file ")
-        self.writeComment(
-            " Saved: {0} ".format(time.strftime('%Y-%m-%d, %H:%M:%S')))
-        
-        # add the main tag
-        self.writeStartElement("Templates")
-        self.writeAttribute("version", templatesFileFormatVersion)
-        
-        # do the template groups
-        groups = self.templatesViewer.getAllGroups()
-        for group in groups:
-            self.writeStartElement("TemplateGroup")
-            self.writeAttribute("name", group.getName())
-            self.writeAttribute("language", group.getLanguage())
-            # do the templates
-            templates = group.getAllEntries()
-            for template in templates:
-                self.writeStartElement("Template")
-                self.writeAttribute("name", template.getName())
-                self.writeTextElement(
-                    "TemplateDescription", template.getDescription())
-                self.writeTextElement(
-                    "TemplateText", template.getTemplateText())
-                self.writeEndElement()
-            self.writeEndElement()
-        
-        self.writeEndElement()
-        self.writeEndDocument()
--- a/eric7/E5XML/UserProjectReader.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing a class for reading an XML user project properties file.
-"""
-
-from .Config import userProjectFileFormatVersion
-from .XMLStreamReaderBase import XMLStreamReaderBase
-
-import Preferences
-
-
-class UserProjectReader(XMLStreamReaderBase):
-    """
-    Class for reading an XML user project properties file.
-    """
-    supportedVersions = ["4.0"]
-    
-    def __init__(self, device, project):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to read from (QIODevice)
-        @param project Reference to the project object to store the
-                information into.
-        """
-        XMLStreamReaderBase.__init__(self, device)
-    
-        self.project = project
-        
-        self.version = ""
-    
-    def readXML(self):
-        """
-        Public method to read and parse the XML document.
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isStartElement():
-                if self.name() == "UserProject":
-                    self.version = self.attribute(
-                        "version", userProjectFileFormatVersion)
-                    if self.version not in self.supportedVersions:
-                        self.raiseUnsupportedFormatVersion(self.version)
-                elif self.name() == "VcsType":
-                    self.project.pudata["VCSOVERRIDE"] = self.readElementText()
-                elif self.name() == "VcsStatusMonitorInterval":
-                    interval = int(self.attribute(
-                        "value",
-                        Preferences.getVCS("StatusMonitorInterval")))
-                    self.project.pudata["VCSSTATUSMONITORINTERVAL"] = interval
-                else:
-                    self.raiseUnexpectedStartTag(self.name())
-        
-        self.showErrorMessage()
--- a/eric7/E5XML/UserProjectWriter.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2006 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the writer class for writing an XML user project
-properties file.
-"""
-
-import time
-
-from E5Gui.E5Application import e5App
-
-from .XMLStreamWriterBase import XMLStreamWriterBase
-from .Config import userProjectFileFormatVersion
-
-import Preferences
-
-
-class UserProjectWriter(XMLStreamWriterBase):
-    """
-    Class implementing the writer class for writing an XML user project
-    properties  file.
-    """
-    def __init__(self, device, projectName):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to write to (QIODevice)
-        @param projectName name of the project (string)
-        """
-        XMLStreamWriterBase.__init__(self, device)
-        
-        self.pudata = e5App().getObject("Project").pudata
-        self.pdata = e5App().getObject("Project").pdata
-        self.name = projectName
-        
-    def writeXML(self):
-        """
-        Public method to write the XML to the file.
-        """
-        XMLStreamWriterBase.writeXML(self)
-        
-        self.writeDTD(
-            '<!DOCTYPE UserProject SYSTEM "UserProject-{0}.dtd">'.format(
-                userProjectFileFormatVersion))
-        
-        # add some generation comments
-        self.writeComment(
-            " eric user project file for project {0} ".format(self.name))
-        if Preferences.getProject("TimestampFile"):
-            self.writeComment(
-                " Saved: {0} ".format(time.strftime('%Y-%m-%d, %H:%M:%S')))
-            self.writeComment(" Copyright (C) {0} {1}, {2} ".format(
-                time.strftime('%Y'), self.pdata["AUTHOR"],
-                self.pdata["EMAIL"]))
-        
-        # add the main tag
-        self.writeStartElement("UserProject")
-        self.writeAttribute("version", userProjectFileFormatVersion)
-        
-        # do the vcs override stuff
-        if self.pudata["VCSOVERRIDE"]:
-            self.writeTextElement("VcsType", self.pudata["VCSOVERRIDE"])
-        if self.pudata["VCSSTATUSMONITORINTERVAL"]:
-            self.writeEmptyElement("VcsStatusMonitorInterval")
-            self.writeAttribute(
-                "value", str(self.pudata["VCSSTATUSMONITORINTERVAL"]))
-        
-        self.writeEndElement()
-        self.writeEndDocument()
--- a/eric7/E5XML/XMLStreamReaderBase.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,299 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing a base class for all of eric7s XML stream writers.
-"""
-
-import pickle           # secok
-import base64
-
-from PyQt6.QtCore import QXmlStreamReader, QCoreApplication
-
-from E5Gui import E5MessageBox
-
-
-class XMLStreamReaderBase(QXmlStreamReader):
-    """
-    Class implementing a base class for all of eric7s XML stream readers.
-    """
-    def __init__(self, device):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to read from (QIODevice)
-        """
-        super().__init__(device)
-    
-    def toBool(self, value):
-        """
-        Public method to convert the given value to bool.
-        
-        @param value value to be converted ("True", "False", "1", "0")
-        @return converted value (boolean) or None in case of an error
-        """
-        if value.lower() in ["true", "false"]:
-            return value.lower() == "true"
-        
-        if value in ["1", "0"]:
-            return bool(int(value))
-        
-        self.raiseBadValue(value)
-        return None
-    
-    def showErrorMessage(self):
-        """
-        Public method to show an error message.
-        """
-        if self.hasError():
-            if self.device() is not None:
-                msg = QCoreApplication.translate(
-                    "XMLStreamReaderBase",
-                    "<p>XML parse error in file <b>{0}</b>, line {1},"
-                    " column {2}</p><p>Error: {3}</p>").format(
-                    self.device().fileName(),
-                    self.lineNumber(), self.columnNumber(),
-                    self.errorString())
-            else:
-                msg = QCoreApplication.translate(
-                    "XMLStreamReaderBase",
-                    "<p>XML parse error (line {0},"
-                    " column {1})</p><p>Error: {2}</p>").format(
-                    self.lineNumber(), self.columnNumber(),
-                    self.errorString())
-            E5MessageBox.warning(
-                None,
-                QCoreApplication.translate(
-                    "XMLStreamReaderBase", "XML parse error"),
-                msg)
-    
-    def raiseUnexpectedStartTag(self, tag):
-        """
-        Public method to raise an error for an unexpected start tag.
-        
-        @param tag name of the unexpected tag (string)
-        """
-        self.raiseError(QCoreApplication.translate(
-            "XMLStreamReaderBase", "Unexpected start tag '{0}'.".format(tag)))
-    
-    def raiseUnsupportedFormatVersion(self, version):
-        """
-        Public method to raise an error for an unsupported file format version.
-        
-        @param version unsupported version (string)
-        """
-        self.raiseError(QCoreApplication.translate(
-            "XMLStreamReaderBase",
-            "File format version '{0}' is not supported.").format(version))
-    
-    def raiseBadValue(self, value):
-        """
-        Public method to raise an error for a bad value.
-        
-        @param value bad value (string)
-        """
-        self.raiseError(QCoreApplication.translate(
-            "XMLStreamReaderBase", "Bad value: {0}").format(value))
-    
-    def readXML(self):
-        """
-        Public method to read and parse the XML document.
-        """
-        pass
-    
-    def attribute(self, name, default=""):
-        """
-        Public method to read the given attribute of the current tag.
-        
-        @param name name of the attribute (string)
-        @param default default value (string)
-        @return value of the requested tag attribute (string)
-        """
-        try:
-            att = self.attributes().value(name)
-            if att == "":
-                att = default
-            return att
-        except AttributeError:
-            # Work around for PyQt6 < 6.1.1
-            attributes = self.attributes()
-            for attribute in attributes:
-                if attribute.name() == name:
-                    value = attribute.value()
-                    if not value:
-                        value = default
-                    break
-            else:
-                value = default
-            return value
-    
-    def _skipUnknownElement(self):
-        """
-        Protected method to skip over all unknown elements.
-        """
-        if not self.isStartElement():
-            return
-        
-        while not self.atEnd():
-            self.readNext()
-            if self.isEndElement():
-                break
-            
-            if self.isStartElement():
-                self._skipUnknownElement()
-    
-    def _readBasics(self):
-        """
-        Protected method to read an object of a basic Python type.
-        
-        @return Python object read
-        """
-        while not self.atEnd():
-            self.readNext()
-            if self.isStartElement():
-                try:
-                    if self.name() == "none":
-                        val = None
-                    elif self.name() in ("int", "long"):
-                        val = int(self.readElementText())
-                    elif self.name() == "bool":
-                        b = self.readElementText()
-                        if b == "True":
-                            val = True
-                        else:
-                            val = False
-                    elif self.name() == "float":
-                        val = float(self.readElementText())
-                    elif self.name() == "complex":
-                        real, imag = self.readElementText().split()
-                        val = float(real) + float(imag) * 1j
-                    elif self.name() == "string":
-                        val = self.readElementText()
-                    elif self.name() == "bytes":
-                        by = bytes([int(b) for b in
-                                    self.readElementText().split(",")])
-                        val = by
-                    elif self.name() == "bytearray":
-                        by = bytearray([int(b) for b in
-                                        self.readElementText().split(",")])
-                        val = by
-                    elif self.name() == "tuple":
-                        val = self.__readTuple()
-                        return val
-                    elif self.name() == "list":
-                        val = self.__readList()
-                        return val
-                    elif self.name() == "dict":
-                        val = self.__readDict()
-                        return val
-                    elif self.name() == "set":
-                        val = self.__readSet()
-                        return val
-                    elif self.name() == "frozenset":
-                        val = self.__readFrozenset()
-                        return val
-                    elif self.name() == "pickle":
-                        encoding = self.attribute("encoding")
-                        if encoding != "base64":
-                            self.raiseError(QCoreApplication.translate(
-                                "XMLStreamReaderBase",
-                                "Pickle data encoding '{0}' is not"
-                                " supported.").format(encoding))
-                            continue
-                        b64 = self.readElementText()
-                        pic = base64.b64decode(b64.encode("ASCII"))
-                        val = pickle.loads(pic)         # secok
-                    else:
-                        self._skipUnknownElement()
-                except ValueError as err:
-                    self.raiseError(str(err))
-                    continue
-            
-            if self.isEndElement():
-                if self.name() in [
-                        "tuple", "list", "dict", "set", "frozenset"]:
-                    return None
-                else:
-                    return val
-    
-    def __readTuple(self):
-        """
-        Private method to read a Python tuple.
-        
-        @return Python tuple
-        """
-        li = []
-        while not self.atEnd():
-            val = self._readBasics()
-            if self.isEndElement() and self.name() == "tuple" and val is None:
-                return tuple(li)
-            else:
-                li.append(val)
-    
-    def __readList(self):
-        """
-        Private method to read a Python list.
-        
-        @return Python list
-        """
-        li = []
-        while not self.atEnd():
-            val = self._readBasics()
-            if self.isEndElement() and self.name() == "list" and val is None:
-                return li
-            else:
-                li.append(val)
-    
-    def __readDict(self):
-        """
-        Private method to read a Python dictionary.
-        
-        @return Python dictionary
-        """
-        d = {}
-        while not self.atEnd():
-            self.readNext()
-            if self.isStartElement():
-                if self.name() == "key":
-                    key = self._readBasics()
-                elif self.name() == "value":
-                    d[key] = self._readBasics()
-                    if self.isEndElement() and self.name() == "dict":
-                        self.readNext()
-            
-            if self.isEndElement() and self.name() == "dict":
-                return d
-    
-    def __readSet(self):
-        """
-        Private method to read a Python set.
-        
-        @return Python set
-        """
-        li = []
-        while not self.atEnd():
-            val = self._readBasics()
-            if self.isEndElement() and self.name() == "set" and val is None:
-                return set(li)
-            else:
-                li.append(val)
-    
-    def __readFrozenset(self):
-        """
-        Private method to read a Python set.
-        
-        @return Python set
-        """
-        li = []
-        while not self.atEnd():
-            val = self._readBasics()
-            if (
-                self.isEndElement() and
-                self.name() == "frozenset" and
-                val is None
-            ):
-                return frozenset(li)
-            else:
-                li.append(val)
--- a/eric7/E5XML/XMLStreamWriterBase.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,224 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing a base class for all of eric7s XML stream writers.
-"""
-
-import pickle           # secok
-import base64
-
-from PyQt6.QtCore import QXmlStreamWriter
-
-
-class XMLStreamWriterBase(QXmlStreamWriter):
-    """
-    Class implementing a base class for all of eric7s XML stream writers.
-    """
-    def __init__(self, device):
-        """
-        Constructor
-        
-        @param device reference to the I/O device to write to (QIODevice)
-        """
-        super().__init__(device)
-        
-        self.basics = {
-            type(None): self._write_none,
-            int: self._write_int,
-            float: self._write_float,
-            complex: self._write_complex,
-            bool: self._write_bool,
-            str: self._write_string,
-            bytearray: self._write_bytearray,
-            tuple: self._write_tuple,
-            list: self._write_list,
-            dict: self._write_dictionary,
-            set: self._write_set,
-            frozenset: self._write_frozenset,
-            bytes: self._write_bytes,
-        }
-
-        self.setAutoFormatting(True)
-        self.setAutoFormattingIndent(2)
-    
-    def writeXML(self):
-        """
-        Public method to write the XML to the file.
-        """
-        # write the XML header
-        self.writeStartDocument()
-    
-    def writeBasics(self, tag, pyobject):
-        """
-        Public method to write a tag with a basic Python object dump.
-        
-        @param tag tag name (string)
-        @param pyobject object to be dumped
-        """
-        self.writeStartElement(tag)
-        self._writeBasics(pyobject)
-        self.writeEndElement()
-    
-    def _writeBasics(self, pyobject):
-        """
-        Protected method to dump an object of a basic Python type.
-        
-        @param pyobject object to be dumped
-        """
-        writeMethod = (
-            self.basics.get(type(pyobject)) or
-            self._write_unimplemented
-        )
-        writeMethod(pyobject)
-
-    ###########################################################################
-    ## The various writer methods for basic types
-    ###########################################################################
-
-    def _write_none(self, value):
-        """
-        Protected method to dump a NoneType object.
-        
-        @param value value to be dumped (None) (ignored)
-        """
-        self.writeEmptyElement("none")
-        
-    def _write_int(self, value):
-        """
-        Protected method to dump an int object.
-        
-        @param value value to be dumped (integer)
-        """
-        self.writeTextElement("int", str(value))
-        
-    def _write_bool(self, value):
-        """
-        Protected method to dump a bool object.
-        
-        @param value value to be dumped (boolean)
-        """
-        self.writeTextElement("bool", str(value))
-        
-    def _write_float(self, value):
-        """
-        Protected method to dump a float object.
-        
-        @param value value to be dumped (float)
-        """
-        self.writeTextElement("float", str(value))
-        
-    def _write_complex(self, value):
-        """
-        Protected method to dump a complex object.
-        
-        @param value value to be dumped (complex)
-        """
-        self.writeTextElement("complex", '{0} {1}'.format(
-            value.real, value.imag))
-        
-    def _write_string(self, value):
-        """
-        Protected method to dump a str object.
-        
-        @param value value to be dumped (string)
-        """
-        self.writeTextElement("string", str(value))
-        
-    def _write_bytes(self, value):
-        """
-        Protected method to dump a bytes object.
-        
-        @param value value to be dumped (bytes)
-        """
-        self.writeTextElement(
-            "bytes", ",".join(["{0:d}".format(b) for b in value]))
-        
-    def _write_bytearray(self, value):
-        """
-        Protected method to dump a bytearray object.
-        
-        @param value value to be dumped (bytearray)
-        """
-        self.writeTextElement(
-            "bytearray", ",".join(["{0:d}".format(b) for b in value]))
-    
-    def _write_tuple(self, value):
-        """
-        Protected method to dump a tuple object.
-        
-        @param value value to be dumped (tuple)
-        """
-        self.writeStartElement("tuple")
-        for elem in value:
-            self._writeBasics(elem)
-        self.writeEndElement()
-    
-    def _write_list(self, value):
-        """
-        Protected method to dump a list object.
-        
-        @param value value to be dumped (list)
-        """
-        self.writeStartElement("list")
-        for elem in value:
-            self._writeBasics(elem)
-        self.writeEndElement()
-    
-    def _write_dictionary(self, value):
-        """
-        Protected method to dump a dict object.
-        
-        @param value value to be dumped (dictionary)
-        """
-        self.writeStartElement("dict")
-        try:
-            keys = sorted(list(value.keys()))
-        except TypeError:
-            keys = list(value.keys())
-        for key in keys:
-            self.writeStartElement("key")
-            self._writeBasics(key)
-            self.writeEndElement()
-            
-            self.writeStartElement("value")
-            self._writeBasics(value[key])
-            self.writeEndElement()
-        self.writeEndElement()
-    
-    def _write_set(self, value):
-        """
-        Protected method to dump a set object.
-        
-        @param value value to be dumped (set)
-        """
-        self.writeStartElement("set")
-        for elem in value:
-            self._writeBasics(elem)
-        self.writeEndElement()
-    
-    def _write_frozenset(self, value):
-        """
-        Protected method to dump a frozenset object.
-        
-        @param value value to be dumped (frozenset)
-        """
-        self.writeStartElement("frozenset")
-        for elem in value:
-            self._writeBasics(elem)
-        self.writeEndElement()
-    
-    def _write_unimplemented(self, value):
-        """
-        Protected method to dump a type, that has no special method.
-        
-        @param value value to be dumped (any pickleable object)
-        """
-        self.writeStartElement("pickle")
-        self.writeAttribute("method", "pickle")
-        self.writeAttribute("encoding", "base64")
-        self.writeCharacters(
-            str(base64.b64encode(pickle.dumps(value)), "ASCII"))
-        self.writeEndElement()
--- a/eric7/E5XML/__init__.py	Fri May 21 20:14:48 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2004 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Package implementing the XML handling module of eric.
-
-This module includes XML handlers and writers for
-<ul>
-    <li>Project files</li>
-    <li>User project data files</li>
-    <li>Multi-project files</li>
-    <li>Session files</li>
-    <li>Shortcuts files</li>
-    <li>Debugger Properties files</li>
-    <li>Tasks files</li>
-    <li>Templates files</li>
-    <li>Highlighting styles</li>
-    <li>Plugiin repository (handler only)</li>
-</ul>
-"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricXML/Config.py	Sat May 22 11:14:43 2021 +0200
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2004 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing some common configuration stuf for the XML package.
+"""
+
+# version number of the multi project file
+multiProjectFileFormatVersion = "5.1"
+
+# version numbers of the project file
+projectFileFormatVersion = "6.5"
+projectFileFormatVersionRcc = "6.4"
+projectFileFormatVersionUic = "6.3"
+projectFileFormatVersionIdl = "6.2"
+projectFileFormatVersionMake = "6.1"
+projectFileFormatVersionProto = "6.0"
+projectFileFormatVersionAlt = "5.1"
+
+# version number of the user project file
+userProjectFileFormatVersion = "4.0"
+
+# version number of the project session file
+sessionFileFormatVersion = "6.4"
+
+# version number of the shortcuts file
+shortcutsFileFormatVersion = "3.6"
+
+# version number of the tasks file
+tasksFileFormatVersion = "6.0"
+
+# version number of the debugger properties file
+debuggerPropertiesFileFormatVersion = "6.0"
+
+# version number of the templates file
+templatesFileFormatVersion = "4.0"
+
+# version number of the plugin repository file
+pluginRepositoryFileFormatVersion = "4.2"
+
+# version number of the highlighting styles file
+highlightingStylesFileFormatVersion = "6.0"
+
+# version number of the web browser spell check dictionaries list file
+dictionariesListFileFormatVersion = "1.0"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricXML/DebuggerPropertiesReader.py	Sat May 22 11:14:43 2021 +0200
@@ -0,0 +1,139 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a class for reading an XML project debugger properties
+file.
+"""
+
+from .Config import debuggerPropertiesFileFormatVersion
+from .XMLStreamReaderBase import XMLStreamReaderBase
+
+
+class DebuggerPropertiesReader(XMLStreamReaderBase):
+    """
+    Class for reading an XML project debugger properties file.
+    """
+    supportedVersions = ["3.9", "6.0"]
+    
+    def __init__(self, device, project):
+        """
+        Constructor
+        
+        @param device reference to the I/O device to read from (QIODevice)
+        @param project Reference to the project object to store the
+                information into.
+        """
+        XMLStreamReaderBase.__init__(self, device)
+    
+        self.project = project
+        
+        self.version = ""
+    
+    def readXML(self, quiet=False):
+        """
+        Public method to read and parse the XML document.
+        
+        @param quiet flag indicating quiet operations.
+                If this flag is true, no errors are reported.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isStartElement():
+                if self.name() == "DebuggerProperties":
+                    self.version = self.attribute(
+                        "version", debuggerPropertiesFileFormatVersion)
+                    if self.version not in self.supportedVersions:
+                        self.raiseUnsupportedFormatVersion(self.version)
+                elif self.name() == "VirtualEnv":
+                    self.project.debugProperties["VIRTUALENV"] = (
+                        self.readElementText()
+                    )
+                elif self.name() == "Interpreter":
+                    # just read this obsolete entry and ignore it
+                    self.readElementText()
+                elif self.name() == "DebugClient":
+                    self.project.debugProperties["DEBUGCLIENT"] = (
+                        self.readElementText()
+                    )
+                elif self.name() == "Environment":
+                    self.project.debugProperties["ENVIRONMENTOVERRIDE"] = (
+                        int(self.attribute("override", "0"))
+                    )
+                    self.project.debugProperties["ENVIRONMENTSTRING"] = (
+                        self.readElementText()
+                    )
+                elif self.name() == "RemoteDebugger":
+                    self.__readRemoteDebugger()
+                elif self.name() == "PathTranslation":
+                    self.__readPathTranslation()
+                elif self.name() == "ConsoleDebugger":
+                    self.project.debugProperties["CONSOLEDEBUGGER"] = (
+                        int(self.attribute("on", "0"))
+                    )
+                    self.project.debugProperties["CONSOLECOMMAND"] = (
+                        self.readElementText()
+                    )
+                elif self.name() == "Redirect":
+                    self.project.debugProperties["REDIRECT"] = (
+                        int(self.attribute("on", "1"))
+                    )
+                elif self.name() == "Noencoding":
+                    self.project.debugProperties["NOENCODING"] = (
+                        int(self.attribute("on", "0"))
+                    )
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+        
+        if not quiet:
+            self.showErrorMessage()
+    
+    def __readRemoteDebugger(self):
+        """
+        Private method to read the remote debugger info.
+        """
+        self.project.debugProperties["REMOTEDEBUGGER"] = int(self.attribute(
+            "on", "0"))
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "RemoteDebugger":
+                break
+            
+            if self.isStartElement():
+                if self.name() == "RemoteHost":
+                    self.project.debugProperties["REMOTEHOST"] = (
+                        self.readElementText()
+                    )
+                elif self.name() == "RemoteCommand":
+                    self.project.debugProperties["REMOTECOMMAND"] = (
+                        self.readElementText()
+                    )
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readPathTranslation(self):
+        """
+        Private method to read the path translation info.
+        """
+        self.project.debugProperties["PATHTRANSLATION"] = int(self.attribute(
+            "on", "0"))
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "PathTranslation":
+                break
+            
+            if self.isStartElement():
+                if self.name() == "RemotePath":
+                    self.project.debugProperties["REMOTEPATH"] = (
+                        self.readElementText()
+                    )
+                elif self.name() == "LocalPath":
+                    self.project.debugProperties["LOCALPATH"] = (
+                        self.readElementText()
+                    )
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricXML/HighlightingStylesReader.py	Sat May 22 11:14:43 2021 +0200
@@ -0,0 +1,165 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+
+"""
+Module implementing a class for reading a highlighting styles XML file.
+"""
+
+from .Config import highlightingStylesFileFormatVersion
+from .XMLStreamReaderBase import XMLStreamReaderBase
+
+
+class HighlightingStylesReader(XMLStreamReaderBase):
+    """
+    Class for reading a highlighting styles XML file.
+    """
+    supportedVersions = ["4.3", "6.0"]
+    
+    def __init__(self, device, lexers):
+        """
+        Constructor
+        
+        @param device reference to the I/O device to read from (QIODevice)
+        @param lexers dictionary of lexer objects for which to import the
+            styles
+        """
+        XMLStreamReaderBase.__init__(self, device)
+        
+        self.lexers = lexers
+        
+        self.version = ""
+    
+    def readXML(self):
+        """
+        Public method to read and parse the XML document.
+        
+        @return list of read lexer style definitions
+        @rtype list of dict
+        """
+        self.__lexersList = []
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isStartElement():
+                if self.name() == "HighlightingStyles":
+                    self.version = self.attribute(
+                        "version",
+                        highlightingStylesFileFormatVersion)
+                    if self.version not in self.supportedVersions:
+                        self.raiseUnsupportedFormatVersion(self.version)
+                elif self.name() == "Lexer":
+                    self.__readLexer()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+        
+        self.showErrorMessage()
+        
+        return self.__lexersList
+    
+    def __readLexer(self):
+        """
+        Private method to read the lexer info.
+        """
+        language = self.attribute("name")
+        self.__lexersList.append({
+            "name": language,
+            "styles": [],
+        })
+        lexer = (
+            self.lexers[language]
+            if language and language in self.lexers else
+            None
+        )
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Lexer":
+                break
+            
+            if self.isStartElement():
+                if self.name() == "Style":
+                    self.__readStyle(lexer)
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readStyle(self, lexer):
+        """
+        Private method to read the style info.
+        
+        @param lexer reference to the lexer object
+        """
+        if lexer is not None:
+            style = self.attribute("style")
+            if style:
+                style = int(style)
+                substyle = int(self.attribute("substyle", "-1"))
+                # -1 is default for base styles
+                
+                styleDict = {
+                    "style": style,
+                    "substyle": substyle,
+                }
+                
+                color = self.attribute("color")
+                if color:
+                    styleDict["color"] = color
+                else:
+                    styleDict["color"] = (
+                        lexer.defaultColor(style, substyle).name()
+                    )
+                
+                paper = self.attribute("paper")
+                if paper:
+                    styleDict["paper"] = paper
+                else:
+                    styleDict["paper"] = (
+                        lexer.defaultPaper(style, substyle).name()
+                    )
+                
+                fontStr = self.attribute("font")
+                if fontStr:
+                    styleDict["font"] = fontStr
+                else:
+                    styleDict["font"] = (
+                        lexer.defaultFont(style, substyle).toString()
+                    )
+                
+                eolfill = self.attribute("eolfill")
+                if eolfill:
+                    eolfill = self.toBool(eolfill)
+                    if eolfill is None:
+                        eolfill = lexer.defaulEolFill(style, substyle)
+                else:
+                    eolfill = lexer.defaulEolFill(style, substyle)
+                styleDict["eolfill"] = eolfill
+        
+                while not self.atEnd():
+                    self.readNext()
+                    if self.isStartElement():
+                        if self.name() == "Description":
+                            description = self.readElementText().strip()
+                            if not description:
+                                description = lexer.defaultDescription(
+                                    style, substyle)
+                            styleDict["description"] = description
+                        elif self.name() == "Words":
+                            words = self.readElementText().strip()
+                            if not words:
+                                words = lexer.defaultWords(style, substyle)
+                            styleDict["words"] = words
+                    
+                    if self.isEndElement() and self.name() == "Style":
+                        if "description" not in styleDict:
+                            styleDict["description"] = ""
+                        if "words" not in styleDict:
+                            styleDict["words"] = ""
+                        self.__lexersList[-1]["styles"].append(styleDict)
+                        return
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Style":
+                break
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricXML/MultiProjectReader.py	Sat May 22 11:14:43 2021 +0200
@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a class for reading an XML multi project file.
+"""
+
+import os
+
+from .Config import multiProjectFileFormatVersion
+from .XMLStreamReaderBase import XMLStreamReaderBase
+
+import Utilities
+
+
+class MultiProjectReader(XMLStreamReaderBase):
+    """
+    Class for reading an XML multi project file.
+    """
+    supportedVersions = ["4.2", "5.0", "5.1"]
+    
+    def __init__(self, device, multiProject):
+        """
+        Constructor
+        
+        @param device reference to the I/O device to read from (QIODevice)
+        @param multiProject Reference to the multi project object to store the
+                information into.
+        """
+        XMLStreamReaderBase.__init__(self, device)
+        
+        self.multiProject = multiProject
+        self.path = os.path.dirname(device.fileName())
+        
+        self.version = ""
+    
+    def readXML(self):
+        """
+        Public method to read and parse the XML document.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isStartElement():
+                if self.name() == "MultiProject":
+                    self.version = self.attribute(
+                        "version",
+                        multiProjectFileFormatVersion)
+                    if self.version not in self.supportedVersions:
+                        self.raiseUnsupportedFormatVersion(self.version)
+                elif self.name() == "Description":
+                    self.multiProject.description = self.readElementText()
+                elif self.name() == "Projects":
+                    self.__readProjects()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+        
+        self.showErrorMessage()
+    
+    def __readProjects(self):
+        """
+        Private method to read the project infos.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Projects":
+                break
+            
+            if self.isStartElement():
+                if self.name() == "Project":
+                    self.__readProject()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readProject(self):
+        """
+        Private method to read the project info.
+        """
+        project = {}
+        
+        project["master"] = self.toBool(self.attribute("isMaster", "False"))
+        uid = self.attribute("uid", "")
+        if uid:
+            project["uid"] = uid
+        else:
+            # upgrade from pre 5.1 format
+            from PyQt6.QtCore import QUuid
+            project["uid"] = QUuid.createUuid().toString()
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Project":
+                if 'category' not in project:
+                    # upgrade from 4.2 format
+                    project["category"] = ""
+                self.multiProject.addProject(project)
+                break
+            
+            if self.isStartElement():
+                if self.name() == "ProjectName":
+                    project["name"] = self.readElementText()
+                elif self.name() == "ProjectFile":
+                    project["file"] = Utilities.absoluteUniversalPath(
+                        self.readElementText(), self.path)
+                elif self.name() == "ProjectDescription":
+                    project["description"] = self.readElementText()
+                elif self.name() == "ProjectCategory":
+                    project["category"] = self.readElementText()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricXML/PluginRepositoryReader.py	Sat May 22 11:14:43 2021 +0200
@@ -0,0 +1,102 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module to read the plug-in repository contents file.
+"""
+
+from .Config import pluginRepositoryFileFormatVersion
+from .XMLStreamReaderBase import XMLStreamReaderBase
+
+import Preferences
+
+
+class PluginRepositoryReader(XMLStreamReaderBase):
+    """
+    Class to read the plug-in repository contents file.
+    """
+    supportedVersions = ["4.1", "4.2"]
+    
+    def __init__(self, device, entryCallback):
+        """
+        Constructor
+        
+        @param device reference to the I/O device to read from (QIODevice)
+        @param entryCallback reference to a function to be called once the
+            data for a plug-in has been read (function)
+        """
+        XMLStreamReaderBase.__init__(self, device)
+        
+        self.__entryCallback = entryCallback
+        
+        self.version = ""
+    
+    def readXML(self):
+        """
+        Public method to read and parse the XML document.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isStartElement():
+                if self.name() == "Plugins":
+                    self.version = self.attribute(
+                        "version",
+                        pluginRepositoryFileFormatVersion)
+                    if self.version not in self.supportedVersions:
+                        self.raiseUnsupportedFormatVersion(self.version)
+                elif self.name() == "RepositoryUrl":
+                    url = self.readElementText()
+                    Preferences.setUI("PluginRepositoryUrl7", url)
+                elif self.name() == "Plugin":
+                    self.__readPlugin()
+                else:
+                    self._skipUnknownElement()
+        
+        self.showErrorMessage()
+    
+    def __readPlugin(self):
+        """
+        Private method to read the plug-in info.
+        """
+        pluginInfo = {"name": "",
+                      "short": "",
+                      "description": "",
+                      "url": "",
+                      "author": "",
+                      "version": "",
+                      "filename": "",
+                      }
+        pluginInfo["status"] = self.attribute("status", "unknown")
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Plugin":
+                self.__entryCallback(
+                    pluginInfo["name"], pluginInfo["short"],
+                    pluginInfo["description"], pluginInfo["url"],
+                    pluginInfo["author"], pluginInfo["version"],
+                    pluginInfo["filename"], pluginInfo["status"])
+                break
+            
+            if self.isStartElement():
+                if self.name() == "Name":
+                    pluginInfo["name"] = self.readElementText()
+                elif self.name() == "Short":
+                    pluginInfo["short"] = self.readElementText()
+                elif self.name() == "Description":
+                    txt = self.readElementText()
+                    pluginInfo["description"] = [
+                        line.strip() for line in txt.splitlines()
+                    ]
+                elif self.name() == "Url":
+                    pluginInfo["url"] = self.readElementText()
+                elif self.name() == "Author":
+                    pluginInfo["author"] = self.readElementText()
+                elif self.name() == "Version":
+                    pluginInfo["version"] = self.readElementText()
+                elif self.name() == "Filename":
+                    pluginInfo["filename"] = self.readElementText()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricXML/ProjectReader.py	Sat May 22 11:14:43 2021 +0200
@@ -0,0 +1,251 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a class for reading an XML project file.
+"""
+
+from .Config import projectFileFormatVersion
+from .XMLStreamReaderBase import XMLStreamReaderBase
+
+import Utilities
+
+
+class ProjectReader(XMLStreamReaderBase):
+    """
+    Class for reading an XML project file.
+    """
+    supportedVersions = ["4.6",
+                         "5.0", "5.1",
+                         "6.0", "6.1", "6.2", "6.3", "6.4", "6.5"]
+    
+    def __init__(self, device, project):
+        """
+        Constructor
+        
+        @param device reference to the I/O device to read from (QIODevice)
+        @param project Reference to the project object to store the
+                information into.
+        """
+        XMLStreamReaderBase.__init__(self, device)
+    
+        self.project = project
+        
+        self.version = ""
+    
+    def readXML(self):
+        """
+        Public method to read and parse the XML document.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isStartElement():
+                if self.name() == "Project":
+                    self.version = self.attribute(
+                        "version", projectFileFormatVersion)
+                    if self.version not in self.supportedVersions:
+                        self.raiseUnsupportedFormatVersion(self.version)
+                elif self.name() == "Language":
+                    self.project.pdata["SPELLLANGUAGE"] = (
+                        self.readElementText()
+                    )
+                elif self.name() == "ProjectWordList":
+                    self.project.pdata["SPELLWORDS"] = (
+                        Utilities.toNativeSeparators(self.readElementText())
+                    )
+                elif self.name() == "ProjectExcludeList":
+                    self.project.pdata["SPELLEXCLUDES"] = (
+                        Utilities.toNativeSeparators(self.readElementText())
+                    )
+                elif self.name() == "Hash":
+                    self.project.pdata["HASH"] = self.readElementText()
+                elif self.name() == "ProgLanguage":
+                    self.project.pdata["MIXEDLANGUAGE"] = int(
+                        self.attribute("mixed", "0")
+                    )
+                    self.project.pdata["PROGLANGUAGE"] = self.readElementText()
+                    if self.project.pdata["PROGLANGUAGE"] == "Python":
+                        # convert Python to the more specific Python3
+                        self.project.pdata["PROGLANGUAGE"] = "Python3"
+                elif self.name() == "ProjectType":
+                    self.project.pdata["PROJECTTYPE"] = self.readElementText()
+                elif self.name() == "Description":
+                    self.project.pdata["DESCRIPTION"] = self.readElementText()
+                elif self.name() == "Version":
+                    self.project.pdata["VERSION"] = self.readElementText()
+                elif self.name() == "Author":
+                    self.project.pdata["AUTHOR"] = self.readElementText()
+                elif self.name() == "Email":
+                    self.project.pdata["EMAIL"] = self.readElementText()
+                elif self.name() == "TranslationPattern":
+                    self.project.pdata["TRANSLATIONPATTERN"] = (
+                        Utilities.toNativeSeparators(self.readElementText())
+                    )
+                elif self.name() == "TranslationsBinPath":
+                    self.project.pdata["TRANSLATIONSBINPATH"] = (
+                        Utilities.toNativeSeparators(self.readElementText())
+                    )
+                elif self.name() == "Eol":
+                    self.project.pdata["EOL"] = int(
+                        self.attribute("index", "0")
+                    )
+                elif self.name() == "Sources":
+                    self.__readFiles("Sources", "Source", "SOURCES")
+                elif self.name() == "Forms":
+                    self.__readFiles("Forms", "Form", "FORMS")
+                elif self.name() == "Translations":
+                    self.__readFiles(
+                        "Translations", "Translation", "TRANSLATIONS")
+                elif self.name() == "TranslationExceptions":
+                    self.__readFiles(
+                        "TranslationExceptions", "TranslationException",
+                        "TRANSLATIONEXCEPTIONS")
+                elif self.name() == "Resources":
+                    self.__readFiles("Resources", "Resource", "RESOURCES")
+                elif self.name() == "Interfaces":
+                    self.__readFiles("Interfaces", "Interface", "INTERFACES")
+                elif self.name() == "Protocols":
+                    self.__readFiles("Protocols", "Protocol", "PROTOCOLS")
+                elif self.name() == "Others":
+                    self.__readFiles("Others", "Other", "OTHERS")
+                elif self.name() == "MainScript":
+                    self.project.pdata["MAINSCRIPT"] = (
+                        Utilities.toNativeSeparators(self.readElementText())
+                    )
+                elif self.name() == "Vcs":
+                    self.__readVcs()
+                elif self.name() == "FiletypeAssociations":
+                    self.__readFiletypeAssociations()
+                elif self.name() == "LexerAssociations":
+                    self.__readLexerAssociations()
+                elif self.name() == "Make":
+                    self.__readBasicDataField(
+                        "Make", "MakeParameters", "MAKEPARAMS")
+                elif self.name() == "IdlCompiler":
+                    self.__readBasicDataField(
+                        "IdlCompiler", "IdlCompilerParameters", "IDLPARAMS")
+                elif self.name() == "UicCompiler":
+                    self.__readBasicDataField(
+                        "UicCompiler", "UicCompilerParameters", "UICPARAMS")
+                elif self.name() == "RccCompiler":
+                    self.__readBasicDataField(
+                        "RccCompiler", "RccCompilerParameters", "RCCPARAMS")
+                elif self.name() == "DocstringStyle":
+                    self.project.pdata["DOCSTRING"] = self.readElementText()
+                elif self.name() == "ProjectTypeSpecific":
+                    self.__readBasicDataField(
+                        "ProjectTypeSpecific", "ProjectTypeSpecificData",
+                        "PROJECTTYPESPECIFICDATA")
+                elif self.name() == "Documentation":
+                    self.__readBasicDataField(
+                        "Documentation", "DocumentationParams",
+                        "DOCUMENTATIONPARMS")
+                elif self.name() == "Packagers":
+                    self.__readBasicDataField(
+                        "Packagers", "PackagersParams", "PACKAGERSPARMS")
+                elif self.name() == "Checkers":
+                    self.__readBasicDataField(
+                        "Checkers", "CheckersParams", "CHECKERSPARMS")
+                elif self.name() == "OtherTools":
+                    self.__readBasicDataField(
+                        "OtherTools", "OtherToolsParams", "OTHERTOOLSPARMS")
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+        
+        self.showErrorMessage()
+    
+    def __readFiles(self, tag, listTag, dataKey):
+        """
+        Private method to read a list of files.
+        
+        @param tag name of the list tag (string)
+        @param listTag name of the list element tag (string)
+        @param dataKey key of the project data element (string)
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == tag:
+                break
+            
+            if self.isStartElement():
+                if self.name() == listTag:
+                    self.project.pdata[dataKey].append(
+                        Utilities.toNativeSeparators(self.readElementText()))
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readBasicDataField(self, tag, dataTag, dataKey):
+        """
+        Private method to read a list of files.
+        
+        @param tag name of the list tag (string)
+        @param dataTag name of the data tag (string)
+        @param dataKey key of the project data element (string)
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == tag:
+                break
+            
+            if self.isStartElement():
+                if self.name() == dataTag:
+                    self.project.pdata[dataKey] = self._readBasics()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readVcs(self):
+        """
+        Private method to read the VCS info.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Vcs":
+                break
+            
+            if self.isStartElement():
+                if self.name() == "VcsType":
+                    self.project.pdata["VCS"] = self.readElementText()
+                elif self.name() == "VcsOptions":
+                    self.project.pdata["VCSOPTIONS"] = self._readBasics()
+                elif self.name() == "VcsOtherData":
+                    self.project.pdata["VCSOTHERDATA"] = self._readBasics()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readFiletypeAssociations(self):
+        """
+        Private method to read the file type associations.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "FiletypeAssociations":
+                break
+            
+            if self.isStartElement():
+                if self.name() == "FiletypeAssociation":
+                    pattern = self.attribute("pattern", "")
+                    filetype = self.attribute("type", "OTHERS")
+                    if pattern:
+                        self.project.pdata["FILETYPES"][pattern] = filetype
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readLexerAssociations(self):
+        """
+        Private method to read the lexer associations.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "LexerAssociations":
+                break
+            
+            if self.isStartElement():
+                if self.name() == "LexerAssociation":
+                    pattern = self.attribute("pattern", "")
+                    lexer = self.attribute("lexer")
+                    if pattern:
+                        self.project.pdata["LEXERASSOCS"][pattern] = lexer
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricXML/SessionReader.py	Sat May 22 11:14:43 2021 +0200
@@ -0,0 +1,425 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a class for reading an XML session file.
+"""
+
+from E5Gui.E5Application import e5App
+
+from .Config import sessionFileFormatVersion
+from .XMLStreamReaderBase import XMLStreamReaderBase
+
+
+class SessionReader(XMLStreamReaderBase):
+    """
+    Class for reading an XML session file.
+    """
+    supportedVersions = ["4.3", "4.4", "5.0", "6.0", "6.1", "6.2", "6.3",
+                         "6.4"]
+    
+    def __init__(self, device, isGlobal):
+        """
+        Constructor
+        
+        @param device reference to the I/O device to read from
+        @type QIODevice
+        @param isGlobal flag indicating to read the global session
+        @type bool
+        """
+        XMLStreamReaderBase.__init__(self, device)
+        
+        self.version = ""
+        self.isGlobal = isGlobal
+        
+        self.project = e5App().getObject("Project")
+        self.projectBrowser = e5App().getObject("ProjectBrowser")
+        self.multiProject = e5App().getObject("MultiProject")
+        self.vm = e5App().getObject("ViewManager")
+        self.dbg = e5App().getObject("DebugUI")
+        self.dbs = e5App().getObject("DebugServer")
+        
+        if not self.isGlobal:
+            # clear all breakpoints and bookmarks first
+            # (in case we are rereading a session file)
+            files = self.project.getSources(True)
+            for file in files:
+                editor = self.vm.getOpenEditor(file)
+                if editor is not None:
+                    editor.clearBookmarks()
+            self.dbs.getBreakPointModel().deleteAll()
+            self.dbs.getWatchPointModel().deleteAll()
+    
+    def readXML(self, quiet=False):
+        """
+        Public method to read and parse the XML document.
+        
+        @param quiet flag indicating quiet operations.
+            If this flag is true, no errors are reported.
+        @type bool
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isStartElement():
+                if self.name() == "Session":
+                    self.version = self.attribute(
+                        "version", sessionFileFormatVersion)
+                    if self.version not in self.supportedVersions:
+                        self.raiseUnsupportedFormatVersion(self.version)
+                elif self.name() == "MultiProject":
+                    self.multiProject.openMultiProject(
+                        self.readElementText(), False)
+                elif self.name() == "Project":
+                    self.project.openProject(self.readElementText(), False)
+                elif self.name() == "Filenames":
+                    self.__readFilenames()
+                elif self.name() == "ActiveWindow":
+                    cline = int(self.attribute("cline", "0"))
+                    cindex = int(self.attribute("cindex", "0"))
+                    filename = self.readElementText()
+                    self.vm.openFiles(filename)
+                    ed = self.vm.getOpenEditor(filename)
+                    if ed is not None:
+                        ed.setCursorPosition(cline, cindex)
+                        ed.ensureCursorVisible()
+                elif self.name() == "Breakpoints":
+                    self.__readBreakpoints()
+                elif self.name() == "Watchexpressions":
+                    self.__readWatchexpressions()
+                elif self.name() == "DebugInfo":
+                    self.__readDebugInfo()
+                elif self.name() == "Bookmarks":
+                    self.__readBookmarks()
+                elif self.name() == "ProjectBrowserStates":
+                    self.__readProjectBrowserStates()
+                elif self.name() == "ViewManagerSplits":
+                    splitCount = int(self.attribute("count", "0"))
+                    orientation = int(self.attribute("orientation", "1"))
+                    self.vm.setSplitOrientation(orientation)
+                    self.vm.setSplitCount(splitCount)
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+        
+        if not quiet:
+            self.showErrorMessage()
+    
+    def __readFilenames(self):
+        """
+        Private method to read the file name infos.
+        """
+        editorDict = {}
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Filenames":
+                break
+            
+            if self.isStartElement():
+                if self.name() == "Filename":
+                    cline = int(self.attribute("cline", "0"))
+                    cindex = int(self.attribute("cindex", "0"))
+                    folds = self.attribute("folds")
+                    if folds:
+                        folds = [int(f) - 1 for f in folds.split(',')]
+                    else:
+                        folds = []
+                    zoom = int(self.attribute("zoom", "-9999"))
+                    cloned = bool(int(self.attribute("cloned", "0")))
+                    splitIndex = int(self.attribute("splitindex", "0"))
+                    editorIndex = int(self.attribute("editorindex", "-1"))
+                    filename = self.readElementText()
+                    
+                    if cloned and filename in editorDict:
+                        editor = editorDict[filename]
+                        ed = self.vm.newEditorView(
+                            filename, editor, editor.getFileType(),
+                            indexes=(splitIndex, editorIndex))
+                    else:
+                        ed = self.vm.openSourceFile(
+                            filename, indexes=(splitIndex, editorIndex))
+                        editorDict[filename] = ed
+                    if ed is not None:
+                        if zoom > -9999:
+                            ed.zoomTo(zoom)
+                        if folds:
+                            ed.recolor()
+                            ed.setContractedFolds(folds)
+                        ed.setCursorPosition(cline, cindex)
+                        ed.ensureCursorVisible()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readBreakpoints(self):
+        """
+        Private method to read the break point infos.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Breakpoints":
+                break
+            
+            if self.isStartElement():
+                if self.name() == "Breakpoint":
+                    self.__readBreakpoint()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readBreakpoint(self):
+        """
+        Private method to read the break point info.
+        """
+        filename = ""
+        lineno = 0
+        bpCond = ""
+        bpTemp = False
+        bpEnabled = True
+        bpCount = 0
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Breakpoint":
+                self.dbs.getBreakPointModel().addBreakPoint(
+                    filename, lineno, (bpCond, bpTemp, bpEnabled, bpCount))
+                break
+            
+            if self.isStartElement():
+                if self.name() == "BpFilename":
+                    filename = self.readElementText()
+                elif self.name() == "Linenumber":
+                    lineno = int(self.attribute("value", "0"))
+                elif self.name() == "Condition":
+                    bpCond = self.readElementText()
+                    if bpCond == 'None':
+                        bpCond = ''
+                elif self.name() == "Temporary":
+                    bpTemp = self.toBool(self.attribute("value", "False"))
+                elif self.name() == "Enabled":
+                    bpEnabled = self.toBool(self.attribute("value", "True"))
+                elif self.name() == "Count":
+                    bpCount = int(self.attribute("value", "0"))
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readWatchexpressions(self):
+        """
+        Private method to read watch expression infos.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Watchexpressions":
+                break
+            
+            if self.isStartElement():
+                if self.name() == "Watchexpression":
+                    self.__readWatchexpression()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readWatchexpression(self):
+        """
+        Private method to read the watch expression info.
+        """
+        weCond = ""
+        weTemp = False
+        weEnabled = True
+        weCount = 0
+        weSpecialCond = ""
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Watchexpression":
+                self.dbs.getWatchPointModel().addWatchPoint(
+                    weCond, weSpecialCond, (weTemp, weEnabled, weCount))
+                break
+            
+            if self.isStartElement():
+                if self.name() == "Condition":
+                    weCond = self.readElementText()
+                    if weCond == 'None':
+                        weCond = ''
+                elif self.name() == "Temporary":
+                    weTemp = self.toBool(self.attribute("value", "False"))
+                elif self.name() == "Enabled":
+                    weEnabled = self.toBool(self.attribute("value", "True"))
+                elif self.name() == "Count":
+                    weCount = int(self.attribute("value", "0"))
+                elif self.name() == "Special":
+                    weSpecialCond = self.readElementText()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readDebugInfo(self):
+        """
+        Private method to read the debug infos.
+        """
+        dbgExcList = []
+        dbgExcIgnoreList = []
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement():
+                if self.name() == "DebugInfo":
+                    break
+                elif self.name() == "Exceptions":
+                    self.dbg.setExcList(dbgExcList)
+                    if not self.isGlobal:
+                        self.project.dbgExcList = dbgExcList[:]
+                elif self.name() == "IgnoredExceptions":
+                    self.dbg.setExcIgnoreList(dbgExcIgnoreList)
+                    if not self.isGlobal:
+                        self.project.dbgExcIgnoreList = dbgExcIgnoreList[:]
+            
+            if self.isStartElement():
+                if self.name() in ("Exceptions", "IgnoredExceptions",
+                                   "CovexcPattern"):
+                    pass    # ignore these start tags
+                elif self.name() == "VirtualEnv":
+                    txt = self.readElementText()
+                    self.dbg.lastUsedVenvName = txt
+                    if not self.isGlobal:
+                        self.project.dbgVirtualEnv = txt
+                elif self.name() == "Interpreter":
+                    # just read this obsolete entry and ignore it
+                    self.readElementText()
+                elif self.name() == "CommandLine":
+                    txt = self.readElementText()
+                    self.dbg.setArgvHistory(txt)
+                    if not self.isGlobal:
+                        self.project.dbgCmdline = txt
+                elif self.name() == "WorkingDirectory":
+                    txt = self.readElementText()
+                    self.dbg.setWdHistory(txt)
+                    if not self.isGlobal:
+                        self.project.dbgWd = txt
+                elif self.name() == "Environment":
+                    txt = self.readElementText()
+                    self.dbg.setEnvHistory(txt)
+                    if not self.isGlobal:
+                        self.project.dbgEnv = txt
+                elif self.name() == "ReportExceptions":
+                    exc = self.toBool(self.attribute("value", "True"))
+                    self.dbg.setExceptionReporting(exc)
+                    if not self.isGlobal:
+                        self.project.dbgReportExceptions = exc
+                elif self.name() == "Exception":
+                    dbgExcList.append(self.readElementText())
+                elif self.name() == "IgnoredException":
+                    dbgExcIgnoreList.append(self.readElementText())
+                elif self.name() == "AutoClearShell":
+                    val = self.toBool(self.attribute("value"))
+                    self.dbg.setAutoClearShell(val)
+                    if not self.isGlobal:
+                        self.project.dbgAutoClearShell = val
+                elif self.name() == "TracePython":
+                    val = self.toBool(self.attribute("value"))
+                    self.dbg.setTracePython(val)
+                    if not self.isGlobal:
+                        self.project.dbgTracePython = val
+                elif self.name() == "AutoContinue":
+                    val = self.toBool(self.attribute("value"))
+                    self.dbg.setAutoContinue(val)
+                    if not self.isGlobal:
+                        self.project.dbgAutoContinue = val
+                elif self.name() == "EnableMultiprocess":
+                    val = self.toBool(self.attribute("value"))
+                    self.dbg.setEnableMultiprocess(val)
+                    if not self.isGlobal:
+                        self.project.dbgEnableMultiprocess = val
+                elif self.name() == "MultiprocessNoDebug":
+                    txt = self.readElementText()
+                    self.dbg.setMultiprocessNoDebugHistory(txt)
+                    if not self.isGlobal:
+                        self.project.dbgMultiprocessNoDebug = txt
+                elif self.name() == "GlobalConfigOverride":
+                    configOverride = {
+                        "enable": self.toBool(self.attribute("enable")),
+                        "redirect": self.toBool(self.attribute("redirect")),
+                    }
+                    self.dbg.setEnableGlobalConfigOverride(configOverride)
+                    if not self.isGlobal:
+                        self.project.dbgGlobalConfigOverride = configOverride
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readBookmarks(self):
+        """
+        Private method to read the bookmark infos.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Bookmarks":
+                break
+            
+            if self.isStartElement():
+                if self.name() == "Bookmark":
+                    self.__readBookmark()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readBookmark(self):
+        """
+        Private method to read the bookmark info.
+        """
+        filename = ""
+        lineno = 0
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Bookmark":
+                editor = self.vm.getOpenEditor(filename)
+                if editor is not None:
+                    editor.toggleBookmark(lineno)
+                break
+            
+            if self.isStartElement():
+                if self.name() == "BmFilename":
+                    filename = self.readElementText()
+                elif self.name() == "Linenumber":
+                    lineno = int(self.attribute("value", "0"))
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readProjectBrowserStates(self):
+        """
+        Private method to read the project browser state infos.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "ProjectBrowserStates":
+                break
+            
+            if self.isStartElement():
+                if self.name() == "ProjectBrowserState":
+                    browserName = self.attribute("name", "")
+                    if not browserName:
+                        self.raiseBadValue("ProjectBrowserState.name")
+                    self.__readProjectBrowserState(browserName)
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+        
+    def __readProjectBrowserState(self, browserName):
+        """
+        Private method to read the project browser state info.
+        
+        @param browserName name of the project browser
+        @type str
+        """
+        expandedNames = []
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "ProjectBrowserState":
+                projectBrowser = self.projectBrowser.getProjectBrowser(
+                    browserName)
+                if projectBrowser is not None:
+                    projectBrowser.expandItemsByName(expandedNames)
+                break
+            
+            if self.isStartElement():
+                if self.name() == "ExpandedItemName":
+                    itemName = self.readElementText()
+                    if itemName:
+                        expandedNames.append(itemName)
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricXML/ShortcutsReader.py	Sat May 22 11:14:43 2021 +0200
@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a class for reading an XML shortcuts file.
+"""
+
+from .Config import shortcutsFileFormatVersion
+from .XMLStreamReaderBase import XMLStreamReaderBase
+
+
+class ShortcutsReader(XMLStreamReaderBase):
+    """
+    Class for reading an XML shortcuts file.
+    """
+    supportedVersions = ["3.6"]
+    
+    def __init__(self, device):
+        """
+        Constructor
+        
+        @param device reference to the I/O device to read from (QIODevice)
+        """
+        XMLStreamReaderBase.__init__(self, device)
+        
+        self.version = ""
+        self.shortcuts = {}
+    
+    def readXML(self):
+        """
+        Public method to read and parse the XML document.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isStartElement():
+                if self.name() == "Shortcuts":
+                    self.version = self.attribute(
+                        "version", shortcutsFileFormatVersion)
+                    if self.version not in self.supportedVersions:
+                        self.raiseUnsupportedFormatVersion(self.version)
+                elif self.name() == "Shortcut":
+                    self.__readShortCut()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+        
+        self.showErrorMessage()
+    
+    def __readShortCut(self):
+        """
+        Private method to read the shortcut data.
+        """
+        category = self.attribute("category")
+        name = ""
+        accel = ""
+        altAccel = ""
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Shortcut":
+                if category:
+                    if category not in self.shortcuts:
+                        self.shortcuts[category] = {}
+                    self.shortcuts[category][name] = (accel, altAccel)
+                break
+            
+            if self.isStartElement():
+                if self.name() == "Name":
+                    name = self.readElementText()
+                elif self.name() == "Accel":
+                    accel = self.readElementText()
+                elif self.name() == "AltAccel":
+                    altAccel = self.readElementText()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def getShortcuts(self):
+        """
+        Public method to retrieve the shortcuts.
+        
+        @return Dictionary of dictionaries of shortcuts. The keys of the
+            dictionary are the categories, the values are dictionaries.
+            These dictionaries have the shortcut name as their key and
+            a tuple of accelerators as their value.
+        """
+        return self.shortcuts
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricXML/SpellCheckDictionariesReader.py	Sat May 22 11:14:43 2021 +0200
@@ -0,0 +1,90 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2017 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module to read the web browser spell check dictionaries list file.
+"""
+
+from .Config import dictionariesListFileFormatVersion
+from .XMLStreamReaderBase import XMLStreamReaderBase
+
+import Preferences
+
+
+class SpellCheckDictionariesReader(XMLStreamReaderBase):
+    """
+    Class to read the web browser spell check dictionaries list file.
+    """
+    supportedVersions = ["1.0", ]
+    
+    def __init__(self, data, entryCallback):
+        """
+        Constructor
+        
+        @param data reference to the data array to read XML from (QByteArray)
+        @param entryCallback reference to a function to be called once the
+            data for a dictionary has been read (function)
+        """
+        XMLStreamReaderBase.__init__(self, data)
+        
+        self.__entryCallback = entryCallback
+        
+        self.version = ""
+        self.baseUrl = ""
+    
+    def readXML(self):
+        """
+        Public method to read and parse the XML document.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isStartElement():
+                if self.name() == "Dictionaries":
+                    self.version = self.attribute(
+                        "version",
+                        dictionariesListFileFormatVersion)
+                    self.baseUrl = self.attribute("baseurl", "")
+                    if self.version not in self.supportedVersions:
+                        self.raiseUnsupportedFormatVersion(self.version)
+                elif self.name() == "DictionariesUrl":
+                    url = self.readElementText()
+                    Preferences.setWebBrowser("SpellCheckDictionariesUrl", url)
+                elif self.name() == "Dictionary":
+                    self.__readDictionary()
+                else:
+                    self._skipUnknownElement()
+        
+        self.showErrorMessage()
+    
+    def __readDictionary(self):
+        """
+        Private method to read the plug-in info.
+        """
+        dictionaryInfo = {"short": "",
+                          "filename": "",
+                          "documentation": "",
+                          "locales": [],
+                          }
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Dictionary":
+                self.__entryCallback(
+                    dictionaryInfo["short"], dictionaryInfo["filename"],
+                    self.baseUrl + dictionaryInfo["filename"],
+                    dictionaryInfo["documentation"], dictionaryInfo["locales"])
+                break
+            
+            if self.isStartElement():
+                if self.name() == "Short":
+                    dictionaryInfo["short"] = self.readElementText()
+                elif self.name() == "Filename":
+                    dictionaryInfo["filename"] = self.readElementText()
+                elif self.name() == "Documentation":
+                    dictionaryInfo["documentation"] = self.readElementText()
+                elif self.name() == "Locales":
+                    dictionaryInfo["locales"] = self.readElementText().split()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricXML/TasksReader.py	Sat May 22 11:14:43 2021 +0200
@@ -0,0 +1,146 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a class for reading an XML tasks file.
+"""
+
+import time
+import contextlib
+
+from E5Gui.E5Application import e5App
+
+from .Config import tasksFileFormatVersion
+from .XMLStreamReaderBase import XMLStreamReaderBase
+
+from Tasks.Task import TaskType, TaskPriority
+
+import Utilities
+
+
+class TasksReader(XMLStreamReaderBase):
+    """
+    Class for reading an XML tasks file.
+    """
+    supportedVersions = ["4.2", "5.0", "5.1", "6.0"]
+    
+    def __init__(self, device, forProject=False, viewer=None):
+        """
+        Constructor
+        
+        @param device reference to the I/O device to read from (QIODevice)
+        @param forProject flag indicating project related mode (boolean)
+        @param viewer reference to the task viewer (TaskViewer)
+        """
+        XMLStreamReaderBase.__init__(self, device)
+        
+        self.viewer = viewer
+        
+        self.forProject = forProject
+        if viewer:
+            self.viewer = viewer
+        else:
+            self.viewer = e5App().getObject("TaskViewer")
+        
+        self.version = ""
+        self.tasks = []
+    
+    def readXML(self):
+        """
+        Public method to read and parse the XML document.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Tasks":
+                for task, expanded in self.tasks:
+                    task.setExpanded(expanded)
+                break
+            
+            if self.isStartElement():
+                if self.name() == "Tasks":
+                    self.version = self.attribute(
+                        "version", tasksFileFormatVersion)
+                    if self.version not in self.supportedVersions:
+                        self.raiseUnsupportedFormatVersion(self.version)
+                elif self.name() == "Task":
+                    self.__readTask()
+                elif self.name() == "ProjectScanFilter":
+                    scanFilter = self.readElementText()
+                    if self.forProject:
+                        self.viewer.setTasksScanFilter(scanFilter)
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+        
+        self.showErrorMessage()
+    
+    def __readTask(self):
+        """
+        Private method to read the task info.
+        """
+        task = {"summary": "",
+                "priority": TaskPriority.NORMAL,
+                "completed": False,
+                "created": 0,
+                "filename": "",
+                "linenumber": 0,
+                "type": TaskType.TODO,
+                "description": "",
+                "uid": "",
+                }
+        task["priority"] = TaskPriority(
+            int(self.attribute("priority", str(TaskPriority.NORMAL.value)))
+        )
+        task["completed"] = self.toBool(self.attribute("completed", "False"))
+        if self.version in ["4.2", "5.0"]:
+            isBugfix = self.toBool(self.attribute("bugfix", "False"))
+            if isBugfix:
+                task["type"] = TaskType.FIXME
+        else:
+            task["type"] = TaskType(
+                int(self.attribute("type", str(TaskType.TODO.value)))
+            )
+        uid = self.attribute("uid", "")
+        if uid:
+            task["uid"] = uid
+        else:
+            # upgrade from pre 6.0 format
+            from PyQt6.QtCore import QUuid
+            task["uid"] = QUuid.createUuid().toString()
+        parentUid = self.attribute("parent_uid", "")
+        expanded = self.toBool(self.attribute("expanded", "True"))
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "Task":
+                parentTask = self.viewer.findParentTask(parentUid)
+                addedTask = self.viewer.addTask(
+                    task["summary"], priority=task["priority"],
+                    filename=task["filename"], lineno=task["linenumber"],
+                    completed=task["completed"], _time=task["created"],
+                    isProjectTask=self.forProject, taskType=task["type"],
+                    description=task["description"], uid=task["uid"],
+                    parentTask=parentTask)
+                self.tasks.append((addedTask, expanded))
+                break
+            
+            if self.isStartElement():
+                if self.name() == "Summary":
+                    task["summary"] = self.readElementText()
+                elif self.name() == "Description":
+                    task["description"] = self.readElementText()
+                elif self.name() == "Created":
+                    task["created"] = time.mktime(time.strptime(
+                        self.readElementText(), "%Y-%m-%d, %H:%M:%S"))
+                elif self.name() == "Resource":
+                    continue    # handle but ignore this tag
+                elif self.name() == "Filename":
+                    task["filename"] = Utilities.toNativeSeparators(
+                        self.readElementText()
+                    )
+                elif self.name() == "Linenumber":
+                    with contextlib.suppress(ValueError):
+                        task["linenumber"] = int(self.readElementText())
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricXML/TemplatesReader.py	Sat May 22 11:14:43 2021 +0200
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a class for reading an XML templates file.
+"""
+
+from .Config import templatesFileFormatVersion
+from .XMLStreamReaderBase import XMLStreamReaderBase
+
+
+class TemplatesReader(XMLStreamReaderBase):
+    """
+    Class for reading an XML tasks file.
+    """
+    supportedVersions = ["4.0"]
+    
+    def __init__(self, device, viewer):
+        """
+        Constructor
+        
+        @param device reference to the I/O device to read from (QIODevice)
+        @param viewer reference to the template viewer object (TemplateViewer)
+        """
+        XMLStreamReaderBase.__init__(self, device)
+        
+        self.__viewer = viewer
+        
+        self.version = ""
+        self.groupName = "DEFAULT"
+    
+    def readXML(self):
+        """
+        Public method to read and parse the XML document.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isStartElement():
+                if self.name() == "Templates":
+                    self.version = self.attribute(
+                        "version", templatesFileFormatVersion)
+                    if self.version not in self.supportedVersions:
+                        self.raiseUnsupportedFormatVersion(self.version)
+                elif self.name() == "TemplateGroup":
+                    self.__readTemplateGroup()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+        
+        self.showErrorMessage()
+    
+    def __readTemplateGroup(self):
+        """
+        Private method to read a template group.
+        """
+        self.groupName = self.attribute('name', "DEFAULT")
+        language = self.attribute('language', "All")
+        self.__viewer.addGroup(self.groupName, language)
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement() and self.name() == "TemplateGroup":
+                break
+            
+            if self.isStartElement():
+                if self.name() == "Template":
+                    self.__readTemplate()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+    
+    def __readTemplate(self):
+        """
+        Private method to read the template definition.
+        """
+        templateName = self.attribute('name', '')
+        templateDescription = ""
+        templateText = ""
+        
+        while not self.atEnd():
+            self.readNext()
+            if (
+                self.isEndElement() and
+                self.name() == "Template" and
+                templateName
+            ):
+                self.__viewer.addEntry(self.groupName, templateName,
+                                       templateDescription, templateText,
+                                       quiet=True)
+                break
+            
+            if self.isStartElement():
+                if self.name() == "TemplateDescription":
+                    templateDescription = self.readElementText()
+                elif self.name() == "TemplateText":
+                    templateText = self.readElementText()
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricXML/UserProjectReader.py	Sat May 22 11:14:43 2021 +0200
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a class for reading an XML user project properties file.
+"""
+
+from .Config import userProjectFileFormatVersion
+from .XMLStreamReaderBase import XMLStreamReaderBase
+
+import Preferences
+
+
+class UserProjectReader(XMLStreamReaderBase):
+    """
+    Class for reading an XML user project properties file.
+    """
+    supportedVersions = ["4.0"]
+    
+    def __init__(self, device, project):
+        """
+        Constructor
+        
+        @param device reference to the I/O device to read from (QIODevice)
+        @param project Reference to the project object to store the
+                information into.
+        """
+        XMLStreamReaderBase.__init__(self, device)
+    
+        self.project = project
+        
+        self.version = ""
+    
+    def readXML(self):
+        """
+        Public method to read and parse the XML document.
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isStartElement():
+                if self.name() == "UserProject":
+                    self.version = self.attribute(
+                        "version", userProjectFileFormatVersion)
+                    if self.version not in self.supportedVersions:
+                        self.raiseUnsupportedFormatVersion(self.version)
+                elif self.name() == "VcsType":
+                    self.project.pudata["VCSOVERRIDE"] = self.readElementText()
+                elif self.name() == "VcsStatusMonitorInterval":
+                    interval = int(self.attribute(
+                        "value",
+                        Preferences.getVCS("StatusMonitorInterval")))
+                    self.project.pudata["VCSSTATUSMONITORINTERVAL"] = interval
+                else:
+                    self.raiseUnexpectedStartTag(self.name())
+        
+        self.showErrorMessage()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricXML/XMLStreamReaderBase.py	Sat May 22 11:14:43 2021 +0200
@@ -0,0 +1,299 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a base class for all of eric7s XML stream writers.
+"""
+
+import pickle           # secok
+import base64
+
+from PyQt6.QtCore import QXmlStreamReader, QCoreApplication
+
+from E5Gui import E5MessageBox
+
+
+class XMLStreamReaderBase(QXmlStreamReader):
+    """
+    Class implementing a base class for all of eric7s XML stream readers.
+    """
+    def __init__(self, device):
+        """
+        Constructor
+        
+        @param device reference to the I/O device to read from (QIODevice)
+        """
+        super().__init__(device)
+    
+    def toBool(self, value):
+        """
+        Public method to convert the given value to bool.
+        
+        @param value value to be converted ("True", "False", "1", "0")
+        @return converted value (boolean) or None in case of an error
+        """
+        if value.lower() in ["true", "false"]:
+            return value.lower() == "true"
+        
+        if value in ["1", "0"]:
+            return bool(int(value))
+        
+        self.raiseBadValue(value)
+        return None
+    
+    def showErrorMessage(self):
+        """
+        Public method to show an error message.
+        """
+        if self.hasError():
+            if self.device() is not None:
+                msg = QCoreApplication.translate(
+                    "XMLStreamReaderBase",
+                    "<p>XML parse error in file <b>{0}</b>, line {1},"
+                    " column {2}</p><p>Error: {3}</p>").format(
+                    self.device().fileName(),
+                    self.lineNumber(), self.columnNumber(),
+                    self.errorString())
+            else:
+                msg = QCoreApplication.translate(
+                    "XMLStreamReaderBase",
+                    "<p>XML parse error (line {0},"
+                    " column {1})</p><p>Error: {2}</p>").format(
+                    self.lineNumber(), self.columnNumber(),
+                    self.errorString())
+            E5MessageBox.warning(
+                None,
+                QCoreApplication.translate(
+                    "XMLStreamReaderBase", "XML parse error"),
+                msg)
+    
+    def raiseUnexpectedStartTag(self, tag):
+        """
+        Public method to raise an error for an unexpected start tag.
+        
+        @param tag name of the unexpected tag (string)
+        """
+        self.raiseError(QCoreApplication.translate(
+            "XMLStreamReaderBase", "Unexpected start tag '{0}'.".format(tag)))
+    
+    def raiseUnsupportedFormatVersion(self, version):
+        """
+        Public method to raise an error for an unsupported file format version.
+        
+        @param version unsupported version (string)
+        """
+        self.raiseError(QCoreApplication.translate(
+            "XMLStreamReaderBase",
+            "File format version '{0}' is not supported.").format(version))
+    
+    def raiseBadValue(self, value):
+        """
+        Public method to raise an error for a bad value.
+        
+        @param value bad value (string)
+        """
+        self.raiseError(QCoreApplication.translate(
+            "XMLStreamReaderBase", "Bad value: {0}").format(value))
+    
+    def readXML(self):
+        """
+        Public method to read and parse the XML document.
+        """
+        pass
+    
+    def attribute(self, name, default=""):
+        """
+        Public method to read the given attribute of the current tag.
+        
+        @param name name of the attribute (string)
+        @param default default value (string)
+        @return value of the requested tag attribute (string)
+        """
+        try:
+            att = self.attributes().value(name)
+            if att == "":
+                att = default
+            return att
+        except AttributeError:
+            # Work around for PyQt6 < 6.1.1
+            attributes = self.attributes()
+            for attribute in attributes:
+                if attribute.name() == name:
+                    value = attribute.value()
+                    if not value:
+                        value = default
+                    break
+            else:
+                value = default
+            return value
+    
+    def _skipUnknownElement(self):
+        """
+        Protected method to skip over all unknown elements.
+        """
+        if not self.isStartElement():
+            return
+        
+        while not self.atEnd():
+            self.readNext()
+            if self.isEndElement():
+                break
+            
+            if self.isStartElement():
+                self._skipUnknownElement()
+    
+    def _readBasics(self):
+        """
+        Protected method to read an object of a basic Python type.
+        
+        @return Python object read
+        """
+        while not self.atEnd():
+            self.readNext()
+            if self.isStartElement():
+                try:
+                    if self.name() == "none":
+                        val = None
+                    elif self.name() in ("int", "long"):
+                        val = int(self.readElementText())
+                    elif self.name() == "bool":
+                        b = self.readElementText()
+                        if b == "True":
+                            val = True
+                        else:
+                            val = False
+                    elif self.name() == "float":
+                        val = float(self.readElementText())
+                    elif self.name() == "complex":
+                        real, imag = self.readElementText().split()
+                        val = float(real) + float(imag) * 1j
+                    elif self.name() == "string":
+                        val = self.readElementText()
+                    elif self.name() == "bytes":
+                        by = bytes([int(b) for b in
+                                    self.readElementText().split(",")])
+                        val = by
+                    elif self.name() == "bytearray":
+                        by = bytearray([int(b) for b in
+                                        self.readElementText().split(",")])
+                        val = by
+                    elif self.name() == "tuple":
+                        val = self.__readTuple()
+                        return val
+                    elif self.name() == "list":
+                        val = self.__readList()
+                        return val
+                    elif self.name() == "dict":
+                        val = self.__readDict()
+                        return val
+                    elif self.name() == "set":
+                        val = self.__readSet()
+                        return val
+                    elif self.name() == "frozenset":
+                        val = self.__readFrozenset()
+                        return val
+                    elif self.name() == "pickle":
+                        encoding = self.attribute("encoding")
+                        if encoding != "base64":
+                            self.raiseError(QCoreApplication.translate(
+                                "XMLStreamReaderBase",
+                                "Pickle data encoding '{0}' is not"
+                                " supported.").format(encoding))
+                            continue
+                        b64 = self.readElementText()
+                        pic = base64.b64decode(b64.encode("ASCII"))
+                        val = pickle.loads(pic)         # secok
+                    else:
+                        self._skipUnknownElement()
+                except ValueError as err:
+                    self.raiseError(str(err))
+                    continue
+            
+            if self.isEndElement():
+                if self.name() in [
+                        "tuple", "list", "dict", "set", "frozenset"]:
+                    return None
+                else:
+                    return val
+    
+    def __readTuple(self):
+        """
+        Private method to read a Python tuple.
+        
+        @return Python tuple
+        """
+        li = []
+        while not self.atEnd():
+            val = self._readBasics()
+            if self.isEndElement() and self.name() == "tuple" and val is None:
+                return tuple(li)
+            else:
+                li.append(val)
+    
+    def __readList(self):
+        """
+        Private method to read a Python list.
+        
+        @return Python list
+        """
+        li = []
+        while not self.atEnd():
+            val = self._readBasics()
+            if self.isEndElement() and self.name() == "list" and val is None:
+                return li
+            else:
+                li.append(val)
+    
+    def __readDict(self):
+        """
+        Private method to read a Python dictionary.
+        
+        @return Python dictionary
+        """
+        d = {}
+        while not self.atEnd():
+            self.readNext()
+            if self.isStartElement():
+                if self.name() == "key":
+                    key = self._readBasics()
+                elif self.name() == "value":
+                    d[key] = self._readBasics()
+                    if self.isEndElement() and self.name() == "dict":
+                        self.readNext()
+            
+            if self.isEndElement() and self.name() == "dict":
+                return d
+    
+    def __readSet(self):
+        """
+        Private method to read a Python set.
+        
+        @return Python set
+        """
+        li = []
+        while not self.atEnd():
+            val = self._readBasics()
+            if self.isEndElement() and self.name() == "set" and val is None:
+                return set(li)
+            else:
+                li.append(val)
+    
+    def __readFrozenset(self):
+        """
+        Private method to read a Python set.
+        
+        @return Python set
+        """
+        li = []
+        while not self.atEnd():
+            val = self._readBasics()
+            if (
+                self.isEndElement() and
+                self.name() == "frozenset" and
+                val is None
+            ):
+                return frozenset(li)
+            else:
+                li.append(val)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricXML/__init__.py	Sat May 22 11:14:43 2021 +0200
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2004 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Package implementing the XML handling module of eric.
+
+This module includes XML handlers and writers for
+<ul>
+    <li>Project files</li>
+    <li>User project data files</li>
+    <li>Multi-project files</li>
+    <li>Session files</li>
+    <li>Shortcuts files</li>
+    <li>Debugger Properties files</li>
+    <li>Tasks files</li>
+    <li>Templates files</li>
+    <li>Highlighting styles</li>
+    <li>Plugiin repository (handler only)</li>
+</ul>
+"""
--- a/eric7/MultiProject/MultiProject.py	Fri May 21 20:14:48 2021 +0200
+++ b/eric7/MultiProject/MultiProject.py	Sat May 22 11:14:43 2021 +0200
@@ -236,7 +236,7 @@
             f = QFile(fn)
             if f.open(QIODevice.OpenModeFlag.ReadOnly):
                 with E5OverrideCursor():
-                    from E5XML.MultiProjectReader import MultiProjectReader
+                    from EricXML.MultiProjectReader import MultiProjectReader
                     reader = MultiProjectReader(f, self)
                     reader.readXML()
                     f.close()
@@ -280,28 +280,7 @@
         if fn is None:
             fn = self.pfile
         
-        if os.path.splitext(fn)[1] == ".emj":
-            # new JSON based format
-            res = self.__multiProjectFile.writeFile(fn)
-        else:
-            # old XML based format
-            f = QFile(fn)
-            if f.open(QIODevice.OpenModeFlag.WriteOnly):
-                from E5XML.MultiProjectWriter import MultiProjectWriter
-                MultiProjectWriter(
-                    f,
-                    self, os.path.splitext(os.path.basename(fn))[0]
-                ).writeXML()
-                res = True
-            else:
-                E5MessageBox.critical(
-                    self.ui,
-                    self.tr("Save Multi Project File"),
-                    self.tr(
-                        "<p>The multi project file <b>{0}</b> could not be "
-                        "written.</p>").format(fn))
-                res = False
-        
+        res = self.__multiProjectFile.writeFile(fn)
         if res:
             self.pfile = os.path.abspath(fn)
             self.ppath = os.path.abspath(os.path.dirname(fn))
@@ -624,10 +603,9 @@
         )
         fn, selectedFilter = E5FileDialog.getSaveFileNameAndFilter(
             self.parent(),
-            self.tr("Save multiproject as"),
+            self.tr("Save Multiproject"),
             defaultPath,
-            self.tr("Multi Project Files (*.emj);;"
-                    "XML Multi Project Files (*.e5m)"),
+            self.tr("Multi Project Files (*.emj)"),
             defaultFilter,
             E5FileDialog.DontConfirmOverwrite)
         
--- a/eric7/PluginManager/PluginManager.py	Fri May 21 20:14:48 2021 +0200
+++ b/eric7/PluginManager/PluginManager.py	Sat May 22 11:14:43 2021 +0200
@@ -1305,7 +1305,7 @@
                 url = Preferences.getUI("PluginRepositoryUrl7")
                 
                 # read the repository file
-                from E5XML.PluginRepositoryReader import PluginRepositoryReader
+                from EricXML.PluginRepositoryReader import PluginRepositoryReader
                 reader = PluginRepositoryReader(f, self.checkPluginEntry)
                 reader.readXML()
                 if url != Preferences.getUI("PluginRepositoryUrl7"):
--- a/eric7/PluginManager/PluginRepositoryDialog.py	Fri May 21 20:14:48 2021 +0200
+++ b/eric7/PluginManager/PluginRepositoryDialog.py	Sat May 22 11:14:43 2021 +0200
@@ -392,7 +392,7 @@
             self.__repositoryMissing = False
             f = QFile(self.pluginRepositoryFile)
             if f.open(QIODevice.OpenModeFlag.ReadOnly):
-                from E5XML.PluginRepositoryReader import PluginRepositoryReader
+                from EricXML.PluginRepositoryReader import PluginRepositoryReader
                 reader = PluginRepositoryReader(f, self.addEntry)
                 reader.readXML()
                 self.repositoryList.resizeColumnToContents(0)
@@ -964,7 +964,7 @@
     if os.path.exists(pluginRepositoryFile):
         f = QFile(pluginRepositoryFile)
         if f.open(QIODevice.OpenModeFlag.ReadOnly):
-            from E5XML.PluginRepositoryReader import PluginRepositoryReader
+            from EricXML.PluginRepositoryReader import PluginRepositoryReader
             reader = PluginRepositoryReader(f, registerPlugin)
             reader.readXML()
             
--- a/eric7/Preferences/ConfigurationDialog.py	Fri May 21 20:14:48 2021 +0200
+++ b/eric7/Preferences/ConfigurationDialog.py	Sat May 22 11:14:43 2021 +0200
@@ -507,8 +507,9 @@
         self.leftVBoxLayout.setContentsMargins(0, 0, 0, 0)
         self.leftVBoxLayout.setSpacing(0)
         self.leftVBoxLayout.setObjectName("leftVBoxLayout")
-        self.configListSearch = QLineEdit(
-            self, self.tr("Enter search text..."))
+        self.configListSearch = QLineEdit(self)
+        self.configListSearch.setPlaceholderText(self.tr("Enter search text..."))
+        self.configListSearch.setClearButtonEnabled(True)
         self.configListSearch.setObjectName("configListSearch")
         self.configListSearch.setClearButtonEnabled(True)
         self.leftVBoxLayout.addWidget(self.configListSearch)
--- a/eric7/Preferences/ConfigurationPages/EditorHighlightingStylesPage.py	Fri May 21 20:14:48 2021 +0200
+++ b/eric7/Preferences/ConfigurationPages/EditorHighlightingStylesPage.py	Sat May 22 11:14:43 2021 +0200
@@ -546,8 +546,7 @@
             self,
             self.tr("Export Highlighting Styles"),
             stylesDir,
-            self.tr("Highlighting Styles File (*.ehj);;"
-                    "XML Highlighting Styles File (*.e6h)"),
+            self.tr("Highlighting Styles File (*.ehj)"),
             "",
             E5FileDialog.DontConfirmOverwrite)
         
@@ -571,28 +570,10 @@
         )
         
         if ok:
-            if fn.endswith(".ehj"):
-                from Preferences.HighlightingStylesFile import (
-                    HighlightingStylesFile
-                )
-                highlightingStylesFile = HighlightingStylesFile()
-                highlightingStylesFile.writeFile(fn, lexers)
-            else:
-                f = QFile(fn)
-                if f.open(QIODevice.OpenModeFlag.WriteOnly):
-                    from E5XML.HighlightingStylesWriter import (
-                        HighlightingStylesWriter
-                    )
-                    HighlightingStylesWriter(f, lexers).writeXML()
-                    f.close()
-                else:
-                    E5MessageBox.critical(
-                        self,
-                        self.tr("Export Highlighting Styles"),
-                        self.tr("<p>The highlighting styles file <b>{0}</b>"
-                                " could not be written.</p><p>Reason: {1}</p>")
-                        .format(fn, f.errorString())
-                    )
+            from Preferences.HighlightingStylesFile import (HighlightingStylesFile
+            )
+            highlightingStylesFile = HighlightingStylesFile()
+            highlightingStylesFile.writeFile(fn, lexers)
     
     def __importStyles(self, importAll=False):
         """
@@ -628,7 +609,7 @@
             # old XML based file
             f = QFile(fn)
             if f.open(QIODevice.OpenModeFlag.ReadOnly):
-                from E5XML.HighlightingStylesReader import (
+                from EricXML.HighlightingStylesReader import (
                     HighlightingStylesReader
                 )
                 reader = HighlightingStylesReader(f, self.lexers)
--- a/eric7/Preferences/Shortcuts.py	Fri May 21 20:14:48 2021 +0200
+++ b/eric7/Preferences/Shortcuts.py	Sat May 22 11:14:43 2021 +0200
@@ -208,28 +208,9 @@
     pm = e5App().getObject("PluginManager")
     pm.initOnDemandPlugins()
     
-    if fn.endswith(".ekj"):
-        # new JSON based file
-        from .ShortcutsFile import ShortcutsFile
-        shortcutsFile = ShortcutsFile()
-        shortcutsFile.writeFile(fn, helpViewer)
-    else:
-        # old XML based file
-        f = QFile(fn)
-        if f.open(QIODevice.OpenModeFlag.WriteOnly):
-            from E5XML.ShortcutsWriter import ShortcutsWriter
-            ShortcutsWriter(f).writeXML(helpViewer=helpViewer)
-            f.close()
-        else:
-            E5MessageBox.critical(
-                None,
-                QCoreApplication.translate(
-                    "Shortcuts", "Export Keyboard Shortcuts"),
-                QCoreApplication.translate(
-                    "Shortcuts",
-                    "<p>The keyboard shortcuts file <b>{0}</b> could not"
-                    " be written.</p>")
-                .format(fn))
+    from .ShortcutsFile import ShortcutsFile
+    shortcutsFile = ShortcutsFile()
+    shortcutsFile.writeFile(fn, helpViewer)
 
 
 def importShortcuts(fn, helpViewer=None):
@@ -258,7 +239,7 @@
         # old XML based file
         f = QFile(fn)
         if f.open(QIODevice.OpenModeFlag.ReadOnly):
-            from E5XML.ShortcutsReader import ShortcutsReader
+            from EricXML.ShortcutsReader import ShortcutsReader
             reader = ShortcutsReader(f)
             reader.readXML()
             f.close()
--- a/eric7/Project/Project.py	Fri May 21 20:14:48 2021 +0200
+++ b/eric7/Project/Project.py	Sat May 22 11:14:43 2021 +0200
@@ -811,7 +811,7 @@
             # old XML based format
             f = QFile(fn)
             if f.open(QIODevice.OpenModeFlag.ReadOnly):
-                from E5XML.ProjectReader import ProjectReader
+                from EricXML.ProjectReader import ProjectReader
                 reader = ProjectReader(f, self)
                 reader.readXML()
                 res = not reader.hasError()
@@ -914,26 +914,8 @@
         if fn is None:
             fn = self.pfile
         
-        if os.path.splitext(fn)[1] == ".epj":
-            # new JSON based format
-            with E5OverrideCursor():
-                res = self.__projectFile.writeFile(fn)
-        else:
-            # old XML based format
-            f = QFile(fn)
-            if f.open(QIODevice.OpenModeFlag.WriteOnly):
-                from E5XML.ProjectWriter import ProjectWriter
-                ProjectWriter(f, os.path.splitext(
-                    os.path.basename(fn))[0]).writeXML()
-                res = True
-            else:
-                E5MessageBox.critical(
-                    self.ui,
-                    self.tr("Save Project File"),
-                    self.tr(
-                        "<p>The project file <b>{0}</b> could not be"
-                        " written.</p>").format(fn))
-                res = False
+        with E5OverrideCursor():
+            res = self.__projectFile.writeFile(fn)
         
         if res:
             self.pfile = os.path.abspath(fn)
@@ -967,7 +949,7 @@
             if os.path.exists(fn):
                 f = QFile(fn)
                 if f.open(QIODevice.OpenModeFlag.ReadOnly):
-                    from E5XML.UserProjectReader import UserProjectReader
+                    from EricXML.UserProjectReader import UserProjectReader
                     reader = UserProjectReader(f, self)
                     reader.readXML()
                     f.close()
@@ -1041,7 +1023,7 @@
             if os.path.exists(fn):
                 f = QFile(fn)
                 if f.open(QIODevice.OpenModeFlag.ReadOnly):
-                    from E5XML.SessionReader import SessionReader
+                    from EricXML.SessionReader import SessionReader
                     reader = SessionReader(f, False)
                     reader.readXML(quiet=quiet)
                     f.close()
@@ -1128,7 +1110,7 @@
             if os.path.exists(fn):
                 f = QFile(fn)
                 if f.open(QIODevice.OpenModeFlag.ReadOnly):
-                    from E5XML.TasksReader import TasksReader
+                    from EricXML.TasksReader import TasksReader
                     reader = TasksReader(f, True)
                     reader.readXML()
                     f.close()
@@ -1206,7 +1188,7 @@
             
             f = QFile(fn)
             if f.open(QIODevice.OpenModeFlag.ReadOnly):
-                from E5XML.DebuggerPropertiesReader import (
+                from EricXML.DebuggerPropertiesReader import (
                     DebuggerPropertiesReader
                 )
                 reader = DebuggerPropertiesReader(f, self)
@@ -3134,10 +3116,9 @@
         )
         fn, selectedFilter = E5FileDialog.getSaveFileNameAndFilter(
             self.parent(),
-            self.tr("Save project as"),
+            self.tr("Save Project"),
             defaultPath,
-            self.tr("Project Files (*.epj);;"
-                    "XML Project Files (*.e4p)"),
+            self.tr("Project Files (*.epj)"),
             defaultFilter,
             E5FileDialog.DontConfirmOverwrite)
         
--- a/eric7/Templates/TemplateViewer.py	Fri May 21 20:14:48 2021 +0200
+++ b/eric7/Templates/TemplateViewer.py	Sat May 22 11:14:43 2021 +0200
@@ -582,8 +582,7 @@
             self,
             self.tr("Export Templates"),
             "",
-            self.tr("Templates Files (*.ecj);;"
-                    "XML Templates Files (*.e4c);;"
+            self.tr("Templates Files (*.ecj)"
                     "All Files (*)"),
             "",
             E5FileDialog.DontConfirmOverwrite)
@@ -978,29 +977,8 @@
         if filename is None:
             filename = os.path.join(
                 Utilities.getConfigDir(), "eric7templates.ecj")
-        if filename.endswith(".ecj"):
-            # new JSON based file
-            res = self.__templatesFile.writeFile(filename)
-        else:
-            # old XML based file
-            f = QFile(filename)
-            ok = f.open(QIODevice.OpenModeFlag.WriteOnly)
-            if not ok:
-                E5MessageBox.critical(
-                    self,
-                    self.tr("Save Templates"),
-                    self.tr(
-                        "<p>The templates file <b>{0}</b> could not be"
-                        " written.</p>")
-                    .format(filename))
-                res = False
-            else:
-                from E5XML.TemplatesWriter import TemplatesWriter
-                TemplatesWriter(f, self).writeXML()
-                f.close()
-                res = True
         
-        return res
+        return self.__templatesFile.writeFile(filename)
     
     def readTemplates(self, filename=None):
         """
@@ -1025,7 +1003,7 @@
         else:
             f = QFile(filename)
             if f.open(QIODevice.OpenModeFlag.ReadOnly):
-                from E5XML.TemplatesReader import TemplatesReader
+                from EricXML.TemplatesReader import TemplatesReader
                 reader = TemplatesReader(f, viewer=self)
                 reader.readXML()
                 f.close()
--- a/eric7/UI/UserInterface.py	Fri May 21 20:14:48 2021 +0200
+++ b/eric7/UI/UserInterface.py	Sat May 22 11:14:43 2021 +0200
@@ -6307,8 +6307,7 @@
             None,
             self.tr("Export Keyboard Shortcuts"),
             "",
-            self.tr("Keyboard Shortcuts File (*.ekj);;"
-                    "XML Keyboard Shortcuts File (*.e4k)"),
+            self.tr("Keyboard Shortcuts File (*.ekj)"),
             "",
             E5FileDialog.DontConfirmOverwrite)
         
@@ -6520,7 +6519,7 @@
             if os.path.exists(fn):
                 f = QFile(fn)
                 if f.open(QIODevice.OpenModeFlag.ReadOnly):
-                    from E5XML.TasksReader import TasksReader
+                    from EricXML.TasksReader import TasksReader
                     reader = TasksReader(f, viewer=self.taskViewer)
                     reader.readXML()
                     f.close()
@@ -6553,25 +6552,7 @@
             fn = os.path.join(Utilities.getConfigDir(),
                               "eric7session.esj")
         
-        if fn.endswith(".esj"):
-            res = self.__sessionFile.writeFile(fn)
-        else:
-            f = QFile(fn)
-            if f.open(QIODevice.OpenModeFlag.WriteOnly):
-                from E5XML.SessionWriter import SessionWriter
-                SessionWriter(f, None).writeXML()
-                f.close()
-                res = True
-            else:
-                E5MessageBox.critical(
-                    self,
-                    self.tr("Save Session"),
-                    self.tr("<p>The session file <b>{0}</b> could not be"
-                            " written.</p>")
-                    .format(fn))
-                res = False
-        
-        return res
+        return self.__sessionFile.writeFile(fn)
     
     def __readSession(self, filename=""):
         """
@@ -6610,7 +6591,7 @@
                 # old XML based format
                 f = QFile(fn)
                 if f.open(QIODevice.OpenModeFlag.ReadOnly):
-                    from E5XML.SessionReader import SessionReader
+                    from EricXML.SessionReader import SessionReader
                     self.__readingSession = True
                     reader = SessionReader(f, True)
                     reader.readXML()
@@ -6638,8 +6619,7 @@
             self,
             self.tr("Save Session"),
             Utilities.getHomeDir(),
-            self.tr("eric Session Files (*.esj);;"
-                    "eric XML Session Files (*.e5s)"),
+            self.tr("eric Session Files (*.esj)"),
             "")
         
         if not sessionFile:
--- a/eric7/WebBrowser/SpellCheck/ManageDictionariesDialog.py	Fri May 21 20:14:48 2021 +0200
+++ b/eric7/WebBrowser/SpellCheck/ManageDictionariesDialog.py	Sat May 22 11:14:43 2021 +0200
@@ -193,7 +193,7 @@
         listFileData = reply.readAll()
         
         # extract the dictionaries
-        from E5XML.SpellCheckDictionariesReader import (
+        from EricXML.SpellCheckDictionariesReader import (
             SpellCheckDictionariesReader
         )
         reader = SpellCheckDictionariesReader(listFileData, self.addEntry)
--- a/eric7/WebBrowser/WebBrowserWindow.py	Fri May 21 20:14:48 2021 +0200
+++ b/eric7/WebBrowser/WebBrowserWindow.py	Sat May 22 11:14:43 2021 +0200
@@ -4983,8 +4983,7 @@
             None,
             self.tr("Export Keyboard Shortcuts"),
             "",
-            self.tr("Keyboard Shortcuts File (*.ekj);;"
-                    "XML Keyboard Shortcuts File (*.e4k)"),
+            self.tr("Keyboard Shortcuts File (*.ekj)"),
             "",
             E5FileDialog.DontConfirmOverwrite)
         
--- a/eric7/eric7.py	Fri May 21 20:14:48 2021 +0200
+++ b/eric7/eric7.py	Sat May 22 11:14:43 2021 +0200
@@ -44,7 +44,7 @@
     sys.exit(100)
 
 with contextlib.suppress(ImportError):
-    from PyQt6 import QtWebEngineWidgets    # __IGNORE_WARNING__
+    from PyQt6 import QtWebEngineWidgets    # __IGNORE_WARNING__ __IGNORE_EXCEPTION__
 
 # some global variables needed to start the application
 args = None

eric ide

mercurial