Plugins/VcsPlugins/vcsMercurial/HgLogDialog.py

changeset 209
94e34c41e823
parent 207
3f889378dede
child 210
b1a204f22291
--- a/Plugins/VcsPlugins/vcsMercurial/HgLogDialog.py	Wed Apr 28 07:25:24 2010 +0000
+++ b/Plugins/VcsPlugins/vcsMercurial/HgLogDialog.py	Wed Apr 28 15:41:48 2010 +0000
@@ -64,7 +64,12 @@
         self.revisions = []  # stack of remembered revisions
         self.revString = self.trUtf8('Revision')
         
-        self.buf = []        # buffer for stdout
+        self.logEntries = []        # list of log entries
+        self.lastLogEntry = {}
+        self.fileCopies = {}
+        self.endInitialText = False
+        self.initialText = ""
+        
         self.diff = None
     
     def closeEvent(self, e):
@@ -96,10 +101,10 @@
         self.dname, self.fname = self.vcs.splitPath(fn)
         
         # find the root of the repo
-        repodir = self.dname
-        while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)):
-            repodir = os.path.dirname(repodir)
-            if repodir == os.sep:
+        self.repodir = self.dname
+        while not os.path.isdir(os.path.join(self.repodir, self.vcs.adminDir)):
+            self.repodir = os.path.dirname(self.repodir)
+            if self.repodir == os.sep:
                 return
         
         self.process.kill()
@@ -126,10 +131,10 @@
                 project.getProjectManagementDir(), "hg-bundle.hg")
             args.append('--bundle')
             args.append(self.vcs.bundleFile)
-        if self.fname != "." or self.dname != repodir:
+        if self.fname != "." or self.dname != self.repodir:
             args.append(self.filename)
         
-        self.process.setWorkingDirectory(repodir)
+        self.process.setWorkingDirectory(self.repodir)
         
         self.process.start('hg', args)
         procStarted = self.process.waitForStarted()
@@ -142,6 +147,52 @@
                     'Ensure, that it is in the search path.'
                 ).format('hg'))
     
+    def __getParents(self, rev):
+        """
+        Private method to get the parents of the currently viewed file/directory.
+        
+        @param rev revision number to get parents for (string)
+        @return list of parent revisions (list of strings)
+        """
+        errMsg = ""
+        parents = []
+        
+        process = QProcess()
+        args = []
+        args.append("parents")
+        if self.commandMode == "incoming" and self.vcs.bundleFile:
+            args.append("--repository")
+            args.append(self.vcs.bundleFile)
+        args.append("--template")
+        args.append("{rev}:{node|short}\n")
+        args.append("-r")
+        args.append(rev)
+        args.append(self.filename)
+        
+        process.setWorkingDirectory(self.repodir)
+        process.start('hg', args)
+        procStarted = process.waitForStarted()
+        if procStarted:
+            finished = process.waitForFinished(30000)
+            if finished and process.exitCode() == 0:
+                output = \
+                    str(process.readAllStandardOutput(), 
+                        Preferences.getSystem("IOEncoding"), 
+                        'replace')
+                parents = [p for p in output.strip().splitlines()]
+            else:
+                if not finished:
+                    errMsg = self.trUtf8("The hg process did not finish within 30s.")
+        else:
+            errMsg = self.trUtf8("Could not start the hg executable.")
+        
+        if errMsg:
+            QMessageBox.critical(self,
+                self.trUtf8("Mercurial Error"),
+                errMsg)
+        
+        return parents
+    
     def __procFinished(self, exitCode, exitStatus):
         """
         Private slot connected to the finished signal.
@@ -154,111 +205,89 @@
         
         self.contents.clear()
         
-        if not self.buf:
+        if not self.logEntries:
             self.errors.append(self.trUtf8("No log available for '{0}'")\
                                .format(self.filename))
             self.errorGroup.show()
             return
-        
-        hasInitialText = 0  # three states flag (-1, 0, 1)
-        lvers = 1
-        fileCopies = {}
-        for s in self.buf:
-            if s == "@@@\n":
-                self.contents.insertHtml('</p>{0}<br/>\n'.format(80 * "="))
-                fileCopies = {}
-            else:
-                try:
-                    key, value = s.split("|", 1)
-                except ValueError:
-                    key = ""
-                    value = s
-                if key == "change":
-                    if hasInitialText == 1:
-                        self.contents.insertHtml('{0}<br/>\n'.format(80 * "="))
-                        hasInitialText = -1
-                    rev, hexRev = value.split(":")
-                    dstr = '<p><b>{0} {1}</b>'.format(self.revString, value)
-                    try:
-                        lv = self.revisions[lvers]
-                        lvers += 1
-                    except IndexError:
-                        lv = str(int(rev) - 1)
-                    if rev != "0":
-                        url = QUrl()
-                        url.setScheme("file")
-                        url.setPath(self.filename)
-                        query = QByteArray()
-                        query.append(lv.split(":")[0]).append('_').append(rev)
-                        url.setEncodedQuery(query)
-                        dstr += ' [<a href="{0}" name="{1}" id="{1}">{2}</a>]'.format(
-                            url.toString(), 
-                            str(query, encoding="ascii"), 
-                            self.trUtf8('diff to {0}').format(lv), 
-                        )
-                    dstr += '<br />\n'
-                    self.contents.insertHtml(dstr)
-                elif key == "branches":
-                    if value.strip():
-                        self.contents.insertHtml(self.trUtf8("Branches: {0}<br />\n")\
-                            .format(value.strip()))
-                elif key == "tags":
-                    if value.strip():
-                        self.contents.insertHtml(self.trUtf8("Tags: {0}<br />\n")\
-                            .format(value.strip()))
-                elif key == "parents":
-                    if value.strip():
-                        self.contents.insertHtml(self.trUtf8("Parents: {0}<br />\n")\
-                            .format(value.strip()))
-                elif key == "user":
-                    dstr = self.contents.insertHtml(
-                        self.trUtf8('<i>Author: {0}</i><br />\n').format(value.strip()))
-                elif key == "date":
-                    date, time = value.strip().split()[:2]
-                    dstr = self.contents.insertHtml(
-                        self.trUtf8('<i>Date: {0}, {1}</i><br />\n')\
-                            .format(date, time))
-                elif key == "description":
-                    self.contents.insertHtml(Utilities.html_encode(value.strip()))
-                    self.contents.insertHtml('<br />\n')
-                elif key == "file_copies":
-                    if value.strip():
-                        for entry in value.strip().split(", "):
-                            newName, oldName = entry[:-1].split(" (")
-                            fileCopies[newName] = oldName
-                elif key == "file_adds":
-                    if value.strip():
-                        self.contents.insertHtml('<br />\n')
-                        for f in value.strip().split(", "):
-                            if f in fileCopies:
-                                self.contents.insertHtml(
-                                    self.trUtf8('Added {0} (copied from {1})<br />\n')\
-                                        .format(Utilities.html_encode(f), 
-                                                Utilities.html_encode(fileCopies[f])))
-                            else:
-                                self.contents.insertHtml(
-                                    self.trUtf8('Added {0}<br />\n')\
-                                        .format(Utilities.html_encode(f)))
-                elif key == "files_mods":
-                    if value.strip():
-                        self.contents.insertHtml('<br />\n')
-                        for f in value.strip().split(", "):
-                            self.contents.insertHtml(
-                                self.trUtf8('Modified {0}<br />\n')\
-                                    .format(Utilities.html_encode(f)))
-                elif key == "file_dels":
-                    if value.strip():
-                        self.contents.insertHtml('<br />\n')
-                        for f in value.strip().split(", "):
-                            self.contents.insertHtml(
-                                self.trUtf8('Deleted {0}<br />\n')\
-                                    .format(Utilities.html_encode(f)))
-                else:
-                    if value.strip():
-                        self.contents.insertHtml(Utilities.html_encode(value.strip()))
-                    self.contents.insertHtml('<br />\n')
-                    if hasInitialText == 0:
-                        hasInitialText = 1
+        
+        if self.initialText:
+            self.contents.insertHtml(Utilities.html_encode(self.initialText.strip()))
+            self.contents.insertHtml('<br />\n')
+            self.contents.insertHtml('{0}<br/>\n'.format(80 * "="))
+            
+        for entry in self.logEntries:
+            fileCopies = {}
+            for fentry in entry["file_copies"].split(", "):
+                newName, oldName = entry[:-1].split(" (")
+                fileCopies[newName] = oldName
+            
+            rev, hexRev = entry["change"].split(":")
+            dstr = '<p><b>{0} {1}</b>'.format(self.revString, entry["change"])
+            parents = self.__getParents(rev)
+            for parent in parents:
+                url = QUrl()
+                url.setScheme("file")
+                url.setPath(self.filename)
+                query = QByteArray()
+                query.append(parent.split(":")[0]).append('_').append(rev)
+                url.setEncodedQuery(query)
+                dstr += ' [<a href="{0}" name="{1}" id="{1}">{2}</a>]'.format(
+                    url.toString(), 
+                    str(query, encoding="ascii"), 
+                    self.trUtf8('diff to {0}').format(parent), 
+                )
+            dstr += '<br />\n'
+            self.contents.insertHtml(dstr)
+            
+            self.contents.insertHtml(self.trUtf8("Branches: {0}<br />\n")\
+                .format(entry["branches"]))
+            
+            self.contents.insertHtml(self.trUtf8("Tags: {0}<br />\n")\
+                .format(entry["tags"]))
+            
+            self.contents.insertHtml(self.trUtf8("Parents: {0}<br />\n")\
+                .format(entry["parents"]))
+            
+            self.contents.insertHtml(self.trUtf8('<i>Author: {0}</i><br />\n')\
+                .format(entry["user"]))
+            
+            date, time = entry["date"].split()[:2]
+            self.contents.insertHtml(self.trUtf8('<i>Date: {0}, {1}</i><br />\n')\
+                .format(date, time))
+            
+            for line in entry["description"]:
+                self.contents.insertHtml(Utilities.html_encode(line.strip()))
+                self.contents.insertHtml('<br />\n')
+            
+            if entry["file_adds"]:
+                self.contents.insertHtml('<br />\n')
+                for f in entry["file_adds"].strip().split(", "):
+                    if f in fileCopies:
+                        self.contents.insertHtml(
+                            self.trUtf8('Added {0} (copied from {1})<br />\n')\
+                                .format(Utilities.html_encode(f), 
+                                        Utilities.html_encode(fileCopies[f])))
+                    else:
+                        self.contents.insertHtml(
+                            self.trUtf8('Added {0}<br />\n')\
+                                .format(Utilities.html_encode(f)))
+            
+            if entry["files_mods"]:
+                self.contents.insertHtml('<br />\n')
+                for f in entry["files_mods"].strip().split(", "):
+                    self.contents.insertHtml(
+                        self.trUtf8('Modified {0}<br />\n')\
+                            .format(Utilities.html_encode(f)))
+            
+            if entry["file_dels"]:
+                self.contents.insertHtml('<br />\n')
+                for f in entry["file_dels"].strip().split(", "):
+                    self.contents.insertHtml(
+                        self.trUtf8('Deleted {0}<br />\n')\
+                            .format(Utilities.html_encode(f)))
+            
+            self.contents.insertHtml('</p>{0}<br/>\n'.format(80 * "="))
         
         tc = self.contents.textCursor()
         tc.movePosition(QTextCursor.Start)
@@ -274,15 +303,39 @@
         self.process.setReadChannel(QProcess.StandardOutput)
         
         while self.process.canReadLine():
-            line = str(self.process.readLine(), 
+            s = str(self.process.readLine(), 
                         Preferences.getSystem("IOEncoding"), 
                         'replace')
-            self.buf.append(line)
+##            self.buf.append(line)
+##            
+##            if line.startswith("change|"):
+##                ver = line[7:]
+##                # save revision number for later use
+##                self.revisions.append(ver)
             
-            if line.startswith("change|"):
-                ver = line[7:]
-                # save revision number for later use
-                self.revisions.append(ver)
+            if s == "@@@\n":
+                self.logEntries.append(self.lastLogEntry)
+                self.lastLogEntry = {}
+                self.fileCopies = {}
+            else:
+                try:
+                    key, value = s.split("|", 1)
+                except ValueError:
+                    key = ""
+                    value = s
+                if key == "change":
+                    self.endInitialText = True
+                if key in ("change", "branches", "tags", "parents", "user",
+                            "date", "file_copies", "file_adds", "files_mods",
+                            "file_dels"):
+                    self.lastLogEntry[key] = value.strip()
+                elif key == "description":
+                    self.lastLogEntry[key] = [value.strip()]
+                else:
+                    if self.endInitialText:
+                        self.lastLogEntry["description"].append(value.strip())
+                    else:
+                        self.initialText.append(value)
     
     def __readStderr(self):
         """

eric ide

mercurial