Plugins/VcsPlugins/vcsMercurial/QueuesExtension/queues.py

changeset 1035
2cd7817ac659
parent 1034
8a7fa049e9d3
child 1046
5dd14be5d6a1
--- a/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/queues.py	Sat May 14 20:00:13 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/queues.py	Sun May 15 18:07:16 2011 +0200
@@ -18,6 +18,9 @@
 
 from .HgQueuesNewPatchDialog import HgQueuesNewPatchDialog
 from .HgQueuesListDialog import HgQueuesListDialog
+from .HgQueuesRenamePatchDialog import HgQueuesRenamePatchDialog
+from .HgQueuesFoldDialog import HgQueuesFoldDialog
+from .HgQueuesHeaderDialog import HgQueuesHeaderDialog
 
 import Preferences
 
@@ -30,6 +33,10 @@
     UNAPPLIED_LIST = 1
     SERIES_LIST = 2
     
+    POP = 0
+    PUSH = 1
+    GOTO = 2
+    
     def __init__(self, vcs):
         """
         Constructor
@@ -39,6 +46,7 @@
         self.vcs = vcs
         
         self.qdiffDialog = None
+        self.qheaderDialog = None
     
     def shutdown(self):
         """
@@ -46,6 +54,107 @@
         """
         if self.qdiffDialog is not None:
             self.qdiffDialog.close()
+        if self.qheaderDialog is not None:
+            self.qheaderDialog.close()
+    
+    def __getPatchesList(self, repodir, listType, withSummary=False):
+        """
+        Public method to get a list of patches of a given type.
+        
+        @param repodir directory name of the repository (string)
+        @param listType type of patches list to get
+            (Queues.APPLIED_LIST, Queues.UNAPPLIED_LIST, Queues.SERIES_LIST)
+        @param withSummary flag indicating to get a summary as well (boolean)
+        @return list of patches (list of string)
+        """
+        patchesList = []
+        
+        ioEncoding = Preferences.getSystem("IOEncoding")
+        process = QProcess()
+        args = []
+        if listType == Queues.APPLIED_LIST:
+            args.append("qapplied")
+        elif listType == Queues.UNAPPLIED_LIST:
+            args.append("qunapplied")
+        elif listType == Queues.SERIES_LIST:
+            args.append("qseries")
+        else:
+            raise ValueError("illegal value for listType")
+        if withSummary:
+            args.append("--summary")
+        
+        process.setWorkingDirectory(repodir)
+        process.start('hg', args)
+        procStarted = process.waitForStarted()
+        if procStarted:
+            finished = process.waitForFinished(30000)
+            if finished and process.exitCode() == 0:
+                output = \
+                    str(process.readAllStandardOutput(), ioEncoding, 'replace')
+                for line in output.splitlines():
+                    if withSummary:
+                        l = line.strip().split(": ")
+                        if len(l) == 1:
+                            patch, summary = l[0][:-1], ""
+                        else:
+                            patch, summary = l[0], l[1]
+                        patchesList.append("{0}@@{1}".format(patch, summary))
+                    else:
+                        patchesList.append(line.strip())
+        
+        return patchesList
+    
+    def __getCurrentPatch(self, repodir):
+        """
+        Public method to get the name of the current patch.
+        
+        @param repodir directory name of the repository (string)
+        @return name of the current patch (string)
+        """
+        currentPatch = ""
+        
+        ioEncoding = Preferences.getSystem("IOEncoding")
+        process = QProcess()
+        args = []
+        args.append("qtop")
+        
+        process.setWorkingDirectory(repodir)
+        process.start('hg', args)
+        procStarted = process.waitForStarted()
+        if procStarted:
+            finished = process.waitForFinished(30000)
+            if finished and process.exitCode() == 0:
+                currentPatch = str(
+                    process.readAllStandardOutput(),
+                    ioEncoding, 'replace').strip()
+        
+        return currentPatch
+    
+    def __getCommitMessage(self, repodir):
+        """
+        Public method to get the commit message of the current patch.
+        
+        @param repodir directory name of the repository (string)
+        @return name of the current patch (string)
+        """
+        message = ""
+        
+        ioEncoding = Preferences.getSystem("IOEncoding")
+        process = QProcess()
+        args = []
+        args.append("qheader")
+        
+        process.setWorkingDirectory(repodir)
+        process.start('hg', args)
+        procStarted = process.waitForStarted()
+        if procStarted:
+            finished = process.waitForFinished(30000)
+            if finished and process.exitCode() == 0:
+                message = str(
+                    process.readAllStandardOutput(),
+                    ioEncoding, 'replace')
+        
+        return message
     
     def hgQueueNewPatch(self, name):
         """
@@ -60,7 +169,7 @@
             if repodir == os.sep:
                 return
         
-        dlg = HgQueuesNewPatchDialog()
+        dlg = HgQueuesNewPatchDialog(HgQueuesNewPatchDialog.NEW_MODE)
         if dlg.exec_() == QDialog.Accepted:
             name, message, (userData, currentUser, userName), \
             (dateData, currentDate, dateStr) = dlg.getData()
@@ -90,11 +199,13 @@
                 dia.exec_()
                 self.vcs.checkVCSStatus()
     
-    def hgQueueRefreshPatch(self, name):
+    def hgQueueRefreshPatch(self, name, editMessage=False):
         """
-        Public method to create a new named patch.
+        Public method to refresh the current patch.
         
         @param name file/directory name (string)
+        @param editMessage flag indicating to edit the current
+            commit message (boolean)
         """
         # find the root of the repo
         repodir = self.vcs.splitPath(name)[0]
@@ -106,6 +217,31 @@
         args = []
         args.append("qrefresh")
         
+        if editMessage:
+            currentMessage = self.__getCommitMessage(repodir)
+            dlg = HgQueuesNewPatchDialog(HgQueuesNewPatchDialog.REFRESH_MODE,
+                                         currentMessage)
+            if dlg.exec_() == QDialog.Accepted:
+                name, message, (userData, currentUser, userName), \
+                (dateData, currentDate, dateStr) = dlg.getData()
+                if message != "" and message != currentMessage:
+                    args.append("--message")
+                    args.append(message)
+                if userData:
+                    if currentUser:
+                        args.append("--currentuser")
+                    else:
+                        args.append("--user")
+                        args.append(userName)
+                if dateData:
+                    if currentDate:
+                        args.append("--currentdate")
+                    else:
+                        args.append("--date")
+                        args.append(dateStr)
+            else:
+                return
+        
         dia = HgDialog(self.trUtf8('Update Current Patch'))
         res = dia.startProcess(args, repodir)
         if res:
@@ -114,7 +250,7 @@
     
     def hgQueueShowPatch(self, name):
         """
-        Public method to create a new named patch.
+        Public method to show the contents of the current patch.
         
         @param name file/directory name (string)
         """
@@ -123,12 +259,24 @@
         QApplication.processEvents()
         self.qdiffDialog.start(name, qdiff=True)
     
-    def hgQueuePushPopPatches(self, name, pop=False, all=False, named=False, force=False):
+    def hgQueueShowHeader(self, name):
+        """
+        Public method to show the commit message of the current patch.
+        
+        @param name file/directory name (string)
+        """
+        self.qheaderDialog = HgQueuesHeaderDialog(self.vcs)
+        self.qheaderDialog.show()
+        QApplication.processEvents()
+        self.qheaderDialog.start(name)
+    
+    def hgQueuePushPopPatches(self, name, operation, all=False, named=False, force=False):
         """
         Public method to push patches onto the stack or pop patches off the stack.
         
         @param name file/directory name (string)
-        @keyparam pop flag indicating a pop action (boolean)
+        @param operation operation type to be performed (Queues.POP,
+            Queues.PUSH, Queues.GOTO)
         @keyparam all flag indicating to push/pop all (boolean)
         @keyparam named flag indicating to push/pop until a named patch
             is at the top of the stack (boolean)
@@ -142,20 +290,26 @@
                 return
         
         args = []
-        if pop:
+        if operation == Queues.POP:
             args.append("qpop")
             title = self.trUtf8("Pop Patches")
             listType = Queues.APPLIED_LIST
-        else:
+        elif operation == Queues.PUSH:
             args.append("qpush")
             title = self.trUtf8("Push Patches")
             listType = Queues.UNAPPLIED_LIST
+        elif operation == Queues.GOTO:
+            args.append("qgoto")
+            title = self.trUtf8("Go to Patch")
+            listType = Queues.SERIES_LIST
+        else:
+            raise ValueError("illegal value for operation")
         if force:
             args.append("--force")
-        if all:
+        if all and operation in (Queues.POP, Queues.PUSH):
             args.append("--all")
-        elif named:
-            patchnames = self.__getUnAppliedPatches(repodir, listType)
+        elif named or operation == Queues.GOTO:
+            patchnames = self.__getPatchesList(repodir, listType)
             if patchnames:
                 patch, ok = QInputDialog.getItem(
                     None,
@@ -179,45 +333,9 @@
             dia.exec_()
             self.vcs.checkVCSStatus()
     
-    def __getUnAppliedPatches(self, repodir, listType):
-        """
-        Public method to get the list of applied or unapplied patches.
-        
-        @param repodir directory name of the repository (string)
-        @param listType type of patcheslist to get
-            (Queues.APPLIED_LIST, Queues.UNAPPLIED_LIST, Queues.SERIES_LIST)
-        @return list of patches (list of string)
-        """
-        patchesList = []
-        
-        ioEncoding = Preferences.getSystem("IOEncoding")
-        process = QProcess()
-        args = []
-        if listType == Queues.APPLIED_LIST:
-            args.append("qapplied")
-        elif listType == Queues.UNAPPLIED_LIST:
-            args.append("qunapplied")
-        elif listType == Queues.SERIES_LIST:
-            args.append("qseries")
-        else:
-            raise ValueError("Illegal value for listType.")
-        
-        process.setWorkingDirectory(repodir)
-        process.start('hg', args)
-        procStarted = process.waitForStarted()
-        if procStarted:
-            finished = process.waitForFinished(30000)
-            if finished and process.exitCode() == 0:
-                output = \
-                    str(process.readAllStandardOutput(), ioEncoding, 'replace')
-                for line in output.splitlines():
-                    patchesList.append(line.strip())
-        
-        return patchesList
-    
     def hgQueueListPatches(self, name):
         """
-        Public method to create a new named patch.
+        Public method to show a list of all patches.
         
         @param name file/directory name (string)
         """
@@ -227,7 +345,7 @@
     
     def hgQueueFinishAppliedPatches(self, name):
         """
-        Public method to create a new named patch.
+        Public method to finish all applied patches.
         
         @param name file/directory name (string)
         """
@@ -247,3 +365,109 @@
         if res:
             dia.exec_()
             self.vcs.checkVCSStatus()
+    
+    def hgQueueRenamePatch(self, name):
+        """
+        Public method to rename the current or a selected patch.
+        
+        @param name file/directory name (string)
+        """
+        # find the root of the repo
+        repodir = self.vcs.splitPath(name)[0]
+        while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)):
+            repodir = os.path.dirname(repodir)
+            if repodir == os.sep:
+                return
+        
+        args = []
+        args.append("qrename")
+        patchnames = sorted(self.__getPatchesList(repodir, Queues.SERIES_LIST))
+        if patchnames:
+            currentPatch = self.__getCurrentPatch(repodir)
+            if currentPatch:
+                dlg = HgQueuesRenamePatchDialog(currentPatch, patchnames)
+                if dlg.exec_() == QDialog.Accepted:
+                    newName, selectedPatch = dlg.getData()
+                    if selectedPatch:
+                        args.append(selectedPatch)
+                    args.append(newName)
+                    
+                    dia = HgDialog(self.trUtf8("Rename Patch"))
+                    res = dia.startProcess(args, repodir)
+                    if res:
+                        dia.exec_()
+    
+    def hgQueueDeletePatch(self, name):
+        """
+        Public method to delete a selected unapplied patch.
+        
+        @param name file/directory name (string)
+        """
+        # find the root of the repo
+        repodir = self.vcs.splitPath(name)[0]
+        while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)):
+            repodir = os.path.dirname(repodir)
+            if repodir == os.sep:
+                return
+        
+        args = []
+        args.append("qdelete")
+        patchnames = sorted(self.__getPatchesList(repodir, Queues.UNAPPLIED_LIST))
+        if patchnames:
+            patch, ok = QInputDialog.getItem(
+                None,
+                self.trUtf8("Select Patch"),
+                self.trUtf8("Select the patch to be deleted:"),
+                patchnames,
+                0, False)
+            if ok and patch:
+                args.append(patch)
+                
+                dia = HgDialog(self.trUtf8("Delete Patch"))
+                res = dia.startProcess(args, repodir)
+                if res:
+                    dia.exec_()
+        else:
+            E5MessageBox.information(None,
+                self.trUtf8("Select Patch"),
+                self.trUtf8("""No patches to select from."""))
+    
+    def hgQueueFoldUnappliedPatches(self, name):
+        """
+        Public method to fold patches into the current patch.
+        
+        @param name file/directory name (string)
+        """
+        # find the root of the repo
+        repodir = self.vcs.splitPath(name)[0]
+        while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)):
+            repodir = os.path.dirname(repodir)
+            if repodir == os.sep:
+                return
+        
+        args = []
+        args.append("qfold")
+        patchnames = sorted(
+            self.__getPatchesList(repodir, Queues.UNAPPLIED_LIST, withSummary=True))
+        if patchnames:
+            dlg = HgQueuesFoldDialog(patchnames)
+            if dlg.exec_() == QDialog.Accepted:
+                message, patchesList = dlg.getData()
+                if message:
+                    args.append("--message")
+                    args.append(message)
+                if patchesList:
+                    args.extend(patchesList)
+                    
+                    dia = HgDialog(self.trUtf8("Fold Patches"))
+                    res = dia.startProcess(args, repodir)
+                    if res:
+                        dia.exec_()
+                else:
+                    E5MessageBox.information(None,
+                        self.trUtf8("Fold Patches"),
+                        self.trUtf8("""No patches selected."""))
+        else:
+            E5MessageBox.information(None,
+                self.trUtf8("Fold Patches"),
+                self.trUtf8("""No patches available to be folded."""))

eric ide

mercurial