Sun, 12 Sep 2010 19:36:57 +0200
Migrated the multi-project handler to multi-project reader.
Documentation/Source/eric5.E5XML.MultiProjectHandler.html | file | annotate | diff | comparison | revisions | |
E5XML/MultiProjectHandler.py | file | annotate | diff | comparison | revisions | |
E5XML/MultiProjectReader.py | file | annotate | diff | comparison | revisions | |
E5XML/MultiProjectWriter.py | file | annotate | diff | comparison | revisions | |
MultiProject/MultiProject.py | file | annotate | diff | comparison | revisions | |
eric5.e4p | file | annotate | diff | comparison | revisions |
--- a/Documentation/Source/eric5.E5XML.MultiProjectHandler.html Sun Sep 12 18:39:21 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,162 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' -'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'> -<html><head> -<title>eric5.E5XML.MultiProjectHandler</title> -<style> -body { - background: #EDECE6; - margin: 0em 1em 10em 1em; - color: black; -} - -h1 { color: white; background: #85774A; } -h2 { color: white; background: #85774A; } -h3 { color: white; background: #9D936E; } -h4 { color: white; background: #9D936E; } - -a { color: #BA6D36; } - -</style> -</head> -<body><a NAME="top" ID="top"></a> -<h1>eric5.E5XML.MultiProjectHandler</h1> -<p> -Module implementing the handler class for reading an XML multi project file. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr> -<td><a href="#MultiProjectHandler">MultiProjectHandler</a></td> -<td>Class implementing a sax handler to read an XML multi project file.</td> -</tr> -</table> -<h3>Functions</h3> -<table> -<tr><td>None</td></tr> -</table> -<hr /><hr /> -<a NAME="MultiProjectHandler" ID="MultiProjectHandler"></a> -<h2>MultiProjectHandler</h2> -<p> - Class implementing a sax handler to read an XML multi project file. -</p> -<h3>Derived from</h3> -XMLHandlerBase -<h3>Class Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Methods</h3> -<table> -<tr> -<td><a href="#MultiProjectHandler.__init__">MultiProjectHandler</a></td> -<td>Constructor</td> -</tr><tr> -<td><a href="#MultiProjectHandler.endDescription">endDescription</a></td> -<td>Handler method for the "Description" end tag.</td> -</tr><tr> -<td><a href="#MultiProjectHandler.endProject">endProject</a></td> -<td>Handler method for the "Project" end tag.</td> -</tr><tr> -<td><a href="#MultiProjectHandler.endProjectDescription">endProjectDescription</a></td> -<td>Handler method for the "ProjectDescription" end tag.</td> -</tr><tr> -<td><a href="#MultiProjectHandler.endProjectFile">endProjectFile</a></td> -<td>Handler method for the "ProjectFile" end tag.</td> -</tr><tr> -<td><a href="#MultiProjectHandler.endProjectName">endProjectName</a></td> -<td>Handler method for the "ProjectName" end tag.</td> -</tr><tr> -<td><a href="#MultiProjectHandler.getVersion">getVersion</a></td> -<td>Public method to retrieve the version of the project.</td> -</tr><tr> -<td><a href="#MultiProjectHandler.startDocumentMultiProject">startDocumentMultiProject</a></td> -<td>Handler called, when the document parsing is started.</td> -</tr><tr> -<td><a href="#MultiProjectHandler.startMultiProject">startMultiProject</a></td> -<td>Handler method for the "MultiProject" start tag.</td> -</tr><tr> -<td><a href="#MultiProjectHandler.startProject">startProject</a></td> -<td>Handler method for the "Project" start tag.</td> -</tr> -</table> -<a NAME="MultiProjectHandler.__init__" ID="MultiProjectHandler.__init__"></a> -<h4>MultiProjectHandler (Constructor)</h4> -<b>MultiProjectHandler</b>(<i>multiProject</i>) -<p> - Constructor -</p><dl> -<dt><i>multiProject</i></dt> -<dd> -Reference to the multi project object to store the - information into. -</dd> -</dl><a NAME="MultiProjectHandler.endDescription" ID="MultiProjectHandler.endDescription"></a> -<h4>MultiProjectHandler.endDescription</h4> -<b>endDescription</b>(<i></i>) -<p> - Handler method for the "Description" end tag. -</p><a NAME="MultiProjectHandler.endProject" ID="MultiProjectHandler.endProject"></a> -<h4>MultiProjectHandler.endProject</h4> -<b>endProject</b>(<i></i>) -<p> - Handler method for the "Project" end tag. -</p><a NAME="MultiProjectHandler.endProjectDescription" ID="MultiProjectHandler.endProjectDescription"></a> -<h4>MultiProjectHandler.endProjectDescription</h4> -<b>endProjectDescription</b>(<i></i>) -<p> - Handler method for the "ProjectDescription" end tag. -</p><a NAME="MultiProjectHandler.endProjectFile" ID="MultiProjectHandler.endProjectFile"></a> -<h4>MultiProjectHandler.endProjectFile</h4> -<b>endProjectFile</b>(<i></i>) -<p> - Handler method for the "ProjectFile" end tag. -</p><a NAME="MultiProjectHandler.endProjectName" ID="MultiProjectHandler.endProjectName"></a> -<h4>MultiProjectHandler.endProjectName</h4> -<b>endProjectName</b>(<i></i>) -<p> - Handler method for the "ProjectName" end tag. -</p><a NAME="MultiProjectHandler.getVersion" ID="MultiProjectHandler.getVersion"></a> -<h4>MultiProjectHandler.getVersion</h4> -<b>getVersion</b>(<i></i>) -<p> - Public method to retrieve the version of the project. -</p><dl> -<dt>Returns:</dt> -<dd> -String containing the version number. -</dd> -</dl><a NAME="MultiProjectHandler.startDocumentMultiProject" ID="MultiProjectHandler.startDocumentMultiProject"></a> -<h4>MultiProjectHandler.startDocumentMultiProject</h4> -<b>startDocumentMultiProject</b>(<i></i>) -<p> - Handler called, when the document parsing is started. -</p><a NAME="MultiProjectHandler.startMultiProject" ID="MultiProjectHandler.startMultiProject"></a> -<h4>MultiProjectHandler.startMultiProject</h4> -<b>startMultiProject</b>(<i>attrs</i>) -<p> - Handler method for the "MultiProject" start tag. -</p><dl> -<dt><i>attrs</i></dt> -<dd> -list of tag attributes -</dd> -</dl><a NAME="MultiProjectHandler.startProject" ID="MultiProjectHandler.startProject"></a> -<h4>MultiProjectHandler.startProject</h4> -<b>startProject</b>(<i>attrs</i>) -<p> - Handler method for the "Project" start tag. -</p><dl> -<dt><i>attrs</i></dt> -<dd> -list of tag attributes -</dd> -</dl> -<div align="right"><a href="#top">Up</a></div> -<hr /> -</body></html> \ No newline at end of file
--- a/E5XML/MultiProjectHandler.py Sun Sep 12 18:39:21 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2008 - 2010 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing the handler class for reading an XML multi project file. -""" - -from .Config import multiProjectFileFormatVersion -from .XMLHandlerBase import XMLHandlerBase - -import Utilities - -class MultiProjectHandler(XMLHandlerBase): - """ - Class implementing a sax handler to read an XML multi project file. - """ - def __init__(self, multiProject): - """ - Constructor - - @param multiProject Reference to the multi project object to store the - information into. - """ - XMLHandlerBase.__init__(self) - - self.startDocumentSpecific = self.startDocumentMultiProject - - self.elements.update({ - 'MultiProject' : (self.startMultiProject, self.defaultEndElement), - 'Description' : (self.defaultStartElement, self.endDescription), - 'Project' : (self.startProject, self.endProject), - 'ProjectName' : (self.defaultStartElement, self.endProjectName), - 'ProjectFile' : (self.defaultStartElement, self.endProjectFile), - 'ProjectDescription' : (self.defaultStartElement, self.endProjectDescription), - }) - - self.multiProject = multiProject - - def startDocumentMultiProject(self): - """ - Handler called, when the document parsing is started. - """ - self.version = '' - - ################################################### - ## below follow the individual handler functions - ################################################### - - def startMultiProject(self, attrs): - """ - Handler method for the "MultiProject" start tag. - - @param attrs list of tag attributes - """ - self.version = attrs.get('version', multiProjectFileFormatVersion) - - def endDescription(self): - """ - Handler method for the "Description" end tag. - """ - self.buffer = self.unescape(self.buffer) - self.multiProject.description = self.decodedNewLines(self.buffer) - - def startProject(self, attrs): - """ - Handler method for the "Project" start tag. - - @param attrs list of tag attributes - """ - self.project = {} - isMaster = attrs.get('isMaster', "False") - self.project["master"] = isMaster == "True" - - def endProject(self): - """ - Handler method for the "Project" end tag. - """ - self.multiProject.projects.append(self.project) - - def endProjectName(self): - """ - Handler method for the "ProjectName" end tag. - """ - self.project["name"] = self.unescape(self.buffer) - - def endProjectFile(self): - """ - Handler method for the "ProjectFile" end tag. - """ - filename = self.buffer - self.project["file"] = Utilities.toNativeSeparators(filename) - - def endProjectDescription(self): - """ - Handler method for the "ProjectDescription" end tag. - """ - self.buffer = self.unescape(self.buffer) - self.project["description"] = self.decodedNewLines(self.buffer) - - def getVersion(self): - """ - Public method to retrieve the version of the project. - - @return String containing the version number. - """ - return self.version -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/E5XML/MultiProjectReader.py Sun Sep 12 19:36:57 2010 +0200 @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2010 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a class for reading an XML multi project file. +""" + +from .Config import multiProjectFileFormatVersion +from .XMLStreamReaderBase import XMLStreamReaderBase + +import Utilities + +class MultiProjectReader(XMLStreamReaderBase): + """ + Class for reading an XML multi project file. + """ + supportedVersions = ["4.2"] + + 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.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.decodedNewLines( + 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() == "Task": + 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")) + + while not self.atEnd(): + self.readNext() + if self.isEndElement() and self.name() == "Project": + self.multiProject.projects.append(project) + break + + if self.isStartElement(): + if self.name() == "ProjectName": + project["name"] = self.readElementText() + elif self.name() == "ProjectFile": + project["file"] = Utilities.toNativeSeparators(self.readElementText()) + elif self.name() == "ProjectDescription": + project["description"] = self.decodedNewLines(self.readElementText()) + else: + self.raiseUnexpectedStartTag(self.name())
--- a/E5XML/MultiProjectWriter.py Sun Sep 12 18:39:21 2010 +0200 +++ b/E5XML/MultiProjectWriter.py Sun Sep 12 19:36:57 2010 +0200 @@ -9,25 +9,25 @@ import time -from .XMLWriterBase import XMLWriterBase +from .XMLStreamWriterBase import XMLStreamWriterBase from .Config import multiProjectFileFormatVersion import Preferences import Utilities -class MultiProjectWriter(XMLWriterBase): +class MultiProjectWriter(XMLStreamWriterBase): """ Class implementing the writer class for writing an XML project file. """ - def __init__(self, multiProject, file, multiProjectName): + 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 file open file (like) object for writing - @param projectName name of the project (string) + @param multiProjectName name of the project (string) """ - XMLWriterBase.__init__(self, file) + XMLStreamWriterBase.__init__(self, device) self.name = multiProjectName self.multiProject = multiProject @@ -36,36 +36,38 @@ """ Public method to write the XML to the file. """ - XMLWriterBase.writeXML(self) + XMLStreamWriterBase.writeXML(self) - self._write('<!DOCTYPE MultiProject SYSTEM "MultiProject-{0}.dtd">'\ + self.writeDTD('<!DOCTYPE MultiProject SYSTEM "MultiProject-{0}.dtd">'\ .format(multiProjectFileFormatVersion)) # add some generation comments - self._write("<!-- eric5 multi project file for multi project {0} -->"\ + self.writeComment(" eric5 multi project file for multi project {0} "\ .format(self.name)) if Preferences.getMultiProject("XMLTimestamp"): - self._write("<!-- Saved: {0} -->".format(time.strftime('%Y-%m-%d, %H:%M:%S'))) - self._write("<!-- Copyright (C) {0} -->".format(time.strftime('%Y'))) + 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._write('<MultiProject version="{0}">'.format(multiProjectFileFormatVersion)) + self.writeStartElement("MultiProject") + self.writeAttribute("version", multiProjectFileFormatVersion) # do description - self._write(" <Description>{0}</Description>".format( - self.escape(self.encodedNewLines(self.multiProject.description)))) + self.writeTextElement("Description", + self.encodedNewLines(self.multiProject.description)) # do the projects - self._write(" <Projects>") + self.writeStartElement("Projects") for project in self.multiProject.getProjects(): - self._write(' <Project isMaster="{0}">'.format(project['master'])) - self._write(" <ProjectName>{0}</ProjectName>".format( - self.escape(project['name']))) - self._write(" <ProjectFile>{0}</ProjectFile>".format( - Utilities.fromNativeSeparators(project['file']))) - self._write(" <ProjectDescription>{0}</ProjectDescription>".format( - self.escape(self.encodedNewLines(project['name'])))) - self._write(" </Project>") - self._write(" </Projects>") + self.writeStartElement("Project") + self.writeAttribute("isMaster", str(project['master'])) + self.writeTextElement("ProjectName", project['name']) + self.writeTextElement("ProjectFile", + Utilities.fromNativeSeparators(project['file'])) + self.writeTextElement("ProjectDescription", + self.encodedNewLines(project['description'])) + self.writeEndElement() + self.writeEndElement() - self._write("</MultiProject>", newline = False) + self.writeEndElement() + self.writeEndDocument()
--- a/MultiProject/MultiProject.py Sun Sep 12 18:39:21 2010 +0200 +++ b/MultiProject/MultiProject.py Sun Sep 12 19:36:57 2010 +0200 @@ -8,7 +8,6 @@ """ import os -import io from PyQt4.QtCore import * from PyQt4.QtGui import * @@ -22,11 +21,7 @@ from E5Gui import E5FileDialog from E5Gui import E5MessageBox -from E5XML.XMLUtilities import make_parser -from E5XML.XMLErrorHandler import XMLErrorHandler, XMLFatalParseError -from E5XML.XMLEntityResolver import XMLEntityResolver - -from E5XML.MultiProjectHandler import MultiProjectHandler +from E5XML.MultiProjectReader import MultiProjectReader from E5XML.MultiProjectWriter import MultiProjectWriter import UI.PixmapCache @@ -197,31 +192,19 @@ def __readMultiProject(self, fn): """ - Private method to read in a multi project (.e4m, .e4mz) file. + Private method to read in a multi project (.e4m) file. @param fn filename of the multi project file to be read (string) @return flag indicating success """ - try: - if fn.lower().endswith("e4mz"): - try: - import gzip - except ImportError: - QApplication.restoreOverrideCursor() - E5MessageBox.critical(self.ui, - self.trUtf8("Read multiproject file"), - self.trUtf8("""Compressed multiproject files not supported.""" - """ The compression library is missing.""")) - return False - g = gzip.open(fn, "rb") - f = io.StringIO(g.read().decode("utf-8")) - g.close() - else: - f = open(fn, "r", encoding = "utf-8") - line = f.readline() - dtdLine = f.readline() + f = QFile(fn) + if f.open(QIODevice.ReadOnly): + reader = MultiProjectReader(f, self) + reader.readXML() f.close() - except EnvironmentError: + if reader.hasError(): + return False + else: QApplication.restoreOverrideCursor() E5MessageBox.critical(self.ui, self.trUtf8("Read multiproject file"), @@ -232,96 +215,16 @@ self.pfile = os.path.abspath(fn) self.ppath = os.path.abspath(os.path.dirname(fn)) - # now read the file - if not line.startswith('<?xml'): - QApplication.restoreOverrideCursor() - E5MessageBox.critical(self.ui, - self.trUtf8("Read multiproject file"), - self.trUtf8("<p>The multiproject file <b>{0}</b> has an unsupported" - " format.</p>").format(fn)) - return False - # insert filename into list of recently opened multi projects self.__syncRecent() - res = self.__readXMLMultiProject(fn, dtdLine.startswith("<!DOCTYPE")) - if res: - self.name = os.path.splitext(os.path.basename(fn))[0] - - # check, if the files of the multi project still exist - self.__checkFilesExist() - - return res - - def __readXMLMultiProject(self, fn, validating): - """ - Private method to read the multi project data from an XML file. - - @param fn filename of the multi project file to be read (string) - @param validating flag indicating a validation of the XML file is - requested (boolean) - @return flag indicating success - """ - if fn.lower().endswith("e4mz"): - # work around for a bug in xmlproc - validating = False - - parser = make_parser(validating) - handler = MultiProjectHandler(self) - er = XMLEntityResolver() - eh = XMLErrorHandler() - - parser.setContentHandler(handler) - parser.setEntityResolver(er) - parser.setErrorHandler(eh) + self.name = os.path.splitext(os.path.basename(fn))[0] - try: - if fn.lower().endswith("e4mz"): - try: - import gzip - except ImportError: - QApplication.restoreOverrideCursor() - E5MessageBox.critical(self.ui, - self.trUtf8("Read multiproject file"), - self.trUtf8("""Compressed multiproject files not supported.""" - """ The compression library is missing.""")) - return False - g = gzip.open(fn, "rb") - f = io.StringIO(g.read().decode("utf-8")) - g.close() - else: - f = open(fn, "r", encoding = "utf-8") - try: - try: - parser.parse(f) - except UnicodeEncodeError: - f.seek(0) - buf = io.StringIO(f.read()) - parser.parse(buf) - finally: - f.close() - except IOError: - QApplication.restoreOverrideCursor() - E5MessageBox.critical(self.ui, - self.trUtf8("Read multiproject file"), - self.trUtf8("<p>The multiproject file <b>{0}</b> could not be read.</p>")\ - .format(fn)) - return False - except XMLFatalParseError: - QApplication.restoreOverrideCursor() - E5MessageBox.critical(self.ui, - self.trUtf8("Read multiproject file"), - self.trUtf8("<p>The multiproject file <b>{0}</b> has invalid " - "contents.</p>").format(fn)) - eh.showParseMessages() - return False + # check, if the files of the multi project still exist + self.__checkFilesExist() - QApplication.restoreOverrideCursor() - eh.showParseMessages() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() return True - + def __writeMultiProject(self, fn = None): """ Private method to save the multi project infos to a multi project file. @@ -336,7 +239,17 @@ if fn is None: fn = self.pfile - res = self.__writeXMLMultiProject(fn) + f = QFile(fn) + if f.open(QIODevice.WriteOnly): + MultiProjectWriter(f, self, os.path.splitext(os.path.basename(fn))[0])\ + .writeXML() + res = True + else: + E5MessageBox.critical(self.ui, + self.trUtf8("Save multiproject file"), + self.trUtf8("<p>The multiproject file <b>{0}</b> could not be " + "written.</p>").format(fn)) + res = False if res: self.pfile = os.path.abspath(fn) @@ -349,43 +262,6 @@ return res - def __writeXMLMultiProject(self, fn = None): - """ - Private method to write the multi project data to an XML file. - - @param fn the filename of the multi project file (string) - """ - try: - if fn.lower().endswith("e4mz"): - try: - import gzip - except ImportError: - E5MessageBox.critical(self.ui, - self.trUtf8("Save multiproject file"), - self.trUtf8("""Compressed multiproject files not supported.""" - """ The compression library is missing.""")) - return False - f = io.StringIO() - else: - f = open(fn, "w", encoding = "utf-8") - - MultiProjectWriter(self, f, os.path.splitext(os.path.basename(fn))[0])\ - .writeXML() - - if fn.lower().endswith("e4mz"): - g = gzip.open(fn, "wb") - g.write(f.getvalue().encode("utf-8")) - g.close() - f.close() - except IOError: - E5MessageBox.critical(self.ui, - self.trUtf8("Save multiproject file"), - self.trUtf8("<p>The multiproject file <b>{0}</b> could not be " - "written.</p>").format(fn)) - return False - - return True - def addProject(self, startdir = None): """ Public slot used to add files to the project. @@ -976,4 +852,4 @@ for project in self.projects: if not project['master']: files.append(project['file']) - return files \ No newline at end of file + return files
--- a/eric5.e4p Sun Sep 12 18:39:21 2010 +0200 +++ b/eric5.e4p Sun Sep 12 19:36:57 2010 +0200 @@ -721,7 +721,6 @@ <Source>E5XML/UserProjectWriter.py</Source> <Source>E5XML/UserProjectHandler.py</Source> <Source>E5XML/MultiProjectWriter.py</Source> - <Source>E5XML/MultiProjectHandler.py</Source> <Source>E5XML/HighlightingStylesWriter.py</Source> <Source>E5XML/XMLUtilities.py</Source> <Source>E5XML/XMLHandlerBase.py</Source> @@ -821,6 +820,7 @@ <Source>E5XML/HighlightingStylesReader.py</Source> <Source>E5XML/ShortcutsReader.py</Source> <Source>E5XML/SessionReader.py</Source> + <Source>E5XML/MultiProjectReader.py</Source> </Sources> <Forms> <Form>PyUnit/UnittestDialog.ui</Form>