Continued with Mercurial bookmark support.

Sat, 07 May 2011 17:56:31 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 07 May 2011 17:56:31 +0200
changeset 1017
919147f2b518
parent 1016
72b6b0778e06
child 1018
949812411ab8

Continued with Mercurial bookmark support.

Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/HgBookmarkDialog.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/HgBookmarkDialog.ui file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/ProjectHelper.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/bookmarks.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgBackoutDialog.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgBackoutDialog.ui file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgBundleDialog.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgBundleDialog.ui file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgMergeDialog.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgMergeDialog.ui file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgRevisionSelectionDialog.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgRevisionSelectionDialog.ui file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgRevisionsSelectionDialog.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgRevisionsSelectionDialog.ui file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/hg.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/styles/logBrowserBookmark.style file | annotate | diff | comparison | revisions
eric5.e4p file | annotate | diff | comparison | revisions
--- a/Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/HgBookmarkDialog.py	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/HgBookmarkDialog.py	Sat May 07 17:56:31 2011 +0200
@@ -17,10 +17,14 @@
     """
     Class mplementing the bookmark dialog.
     """
-    def __init__(self, tagsList, branchesList, bookmarksList, parent=None):
+    DEFINE_MODE = 0
+    MOVE_MODE = 1
+    
+    def __init__(self, mode, tagsList, branchesList, bookmarksList, parent=None):
         """
         Constructor
         
+        @param mode of the dialog (integer)
         @param tagsList list of tags (list of strings)
         @param branchesList list of branches (list of strings)
         @param bookmarksList list of bookmarks (list of strings)
@@ -30,11 +34,65 @@
         self.setupUi(self)
         
         self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
-       
+        
+        self.__mode = mode
+        if mode == self.MOVE_MODE:
+            self.nameEdit.hide()
+            self.nameCombo.addItems([""] + sorted(bookmarksList))
+        else:
+            self.nameCombo.hide()
+        
+        self.__bookmarksList = bookmarksList[:]
+        
         self.tagCombo.addItems(sorted(tagsList))
         self.branchCombo.addItems(["default"] + sorted(branchesList))
         self.bookmarkCombo.addItems(sorted(bookmarksList))
     
+    def __updateOK(self):
+        """
+        Private slot to update the OK button.
+        """
+        if self.__mode == self.MOVE_MODE:
+            enabled = self.nameCombo.currentText() != ""
+        else:
+            enabled = self.nameEdit.text() != ""
+        if self.idButton.isChecked():
+            enabled = enabled and self.idEdit.text() != ""
+        elif self.tagButton.isChecked():
+            enabled = enabled and self.tagCombo.currentText() != ""
+        elif self.branchButton.isChecked():
+            enabled = enabled and self.branchCombo.currentText() != ""
+        elif self.bookmarkButton.isChecked():
+            enabled = enabled and self.bookmarkCombo.currentText() != ""
+        
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled)
+    
+    def __updateBookmarksCombo(self):
+        """
+        Private slot to update the bookmarks combo.
+        """
+        if self.__mode == self.MOVE_MODE:
+            bookmark = self.nameCombo.currentText()
+            selectedBookmark = self.bookmarkCombo.currentText()
+            self.bookmarkCombo.clearEditText()
+            self.bookmarkCombo.clear()
+            self.bookmarkCombo.addItems(sorted(self.__bookmarksList))
+            index = self.bookmarkCombo.findText(bookmark)
+            if index > -1:
+                self.bookmarkCombo.removeItem(index)
+            if selectedBookmark:
+                index = self.bookmarkCombo.findText(selectedBookmark)
+                if index > -1:
+                    self.bookmarkCombo.setCurrentIndex(index)
+    
+    @pyqtSlot(str)
+    def on_nameCombo_activated(self, txt):
+        """
+        Private slot to handle changes of the selected bookmark name.
+        """
+        self.__updateOK()
+        self.__updateBookmarksCombo()
+    
     @pyqtSlot(str)
     def on_nameEdit_textChanged(self, txt):
         """
@@ -42,7 +100,79 @@
         
         @param txt text of the edit (string)
         """
-        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(txt != "")
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_idButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the ID select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_tagButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Tag select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_branchButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Branch select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_bookmarkButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Bookmark select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_idEdit_textChanged(self, txt):
+        """
+        Private slot to handle changes of the ID edit.
+        
+        @param txt text of the edit (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_tagCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Tag combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_branchCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Branch combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_bookmarkCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Bookmark combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
     
     def getData(self):
         """
@@ -64,4 +194,9 @@
         else:
             rev = ""
         
-        return rev, self.nameEdit.text()
+        if self.__mode == self.MOVE_MODE:
+            name = self.nameCombo.currentText()
+        else:
+            name = self.nameEdit.text()
+        
+        return rev, name
--- a/Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/HgBookmarkDialog.ui	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/HgBookmarkDialog.ui	Sat May 07 17:56:31 2011 +0200
@@ -33,6 +33,19 @@
        </property>
       </widget>
      </item>
+     <item>
+      <widget class="QComboBox" name="nameCombo">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="toolTip">
+        <string>Select a bookmark</string>
+       </property>
+      </widget>
+     </item>
     </layout>
    </item>
    <item>
@@ -220,6 +233,7 @@
  </widget>
  <tabstops>
   <tabstop>nameEdit</tabstop>
+  <tabstop>nameCombo</tabstop>
   <tabstop>numberButton</tabstop>
   <tabstop>numberSpinBox</tabstop>
   <tabstop>idButton</tabstop>
--- a/Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/ProjectHelper.py	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/ProjectHelper.py	Sat May 07 17:56:31 2011 +0200
@@ -101,6 +101,19 @@
         self.hgBookmarkRenameAct.triggered[()].connect(self.__hgBookmarkRename)
         self.actions.append(self.hgBookmarkRenameAct)
     
+        self.hgBookmarkMoveAct = E5Action(self.trUtf8('Move bookmark'),
+                self.trUtf8('Move bookmark...'),
+                0, 0, self, 'mercurial_move_bookmark')
+        self.hgBookmarkMoveAct.setStatusTip(self.trUtf8(
+            'Move a bookmark of the project'
+        ))
+        self.hgBookmarkMoveAct.setWhatsThis(self.trUtf8(
+            """<b>Move bookmark</b>"""
+            """<p>This moves a bookmark of the project to another changeset.</p>"""
+        ))
+        self.hgBookmarkMoveAct.triggered[()].connect(self.__hgBookmarkMove)
+        self.actions.append(self.hgBookmarkMoveAct)
+    
     def initMenu(self, mainMenu):
         """
         Public method to generate the VCS menu.
@@ -113,6 +126,7 @@
         menu.addAction(self.hgBookmarkDefineAct)
         menu.addAction(self.hgBookmarkDeleteAct)
         menu.addAction(self.hgBookmarkRenameAct)
+        menu.addAction(self.hgBookmarkMoveAct)
         menu.addSeparator()
         menu.addAction(self.hgBookmarksListAct)
         
@@ -141,7 +155,14 @@
     
     def __hgBookmarkRename(self):
         """
-        Private slot used to delete a bookmark.
+        Private slot used to rename a bookmark.
         """
         self.vcs.getExtensionObject("bookmarks")\
             .hgBookmarkRename(self.project.getProjectPath())
+    
+    def __hgBookmarkMove(self):
+        """
+        Private slot used to move a bookmark.
+        """
+        self.vcs.getExtensionObject("bookmarks")\
+            .hgBookmarkMove(self.project.getProjectPath())
--- a/Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/bookmarks.py	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/bookmarks.py	Sat May 07 17:56:31 2011 +0200
@@ -9,7 +9,7 @@
 
 import os
 
-from PyQt4.QtCore import QObject
+from PyQt4.QtCore import QObject, QProcess
 from PyQt4.QtGui import QDialog, QInputDialog
 
 from ..HgDialog import HgDialog
@@ -18,6 +18,8 @@
 from .HgBookmarkDialog import HgBookmarkDialog
 from .HgBookmarkRenameDialog import HgBookmarkRenameDialog
 
+import Preferences
+
 
 class Bookmarks(QObject):
     """
@@ -53,12 +55,36 @@
         self.bookmarksListDlg.show()
         self.bookmarksListDlg.start(path, self.bookmarksList)
     
-    def hgGetLoadedBookmarksList(self):
+    def hgGetBookmarksList(self, repodir):
+        """
+        Public method to get the list of bookmarks.
+        
+        @param repodir directory name of the repository (string)
+        @return list of bookmarks (list of string)
         """
-        Public method to get the list of loaded bookmarks.
+        ioEncoding = Preferences.getSystem("IOEncoding")
+        process = QProcess()
+        args = []
+        args.append('bookmarks')
+        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')
+                self.bookmarksList = []
+                for line in output.splitlines():
+                    l = line.strip().split()
+                    if l[-1][0] in "1234567890":
+                        # last element is a rev:changeset
+                        del l[-1]
+                        if l[0] == "*":
+                            del l[0]
+                        name = " ".join(l)
+                        self.bookmarksList.append(name)
         
-        @return list of loaded bookmarks (list of string)
-        """
         return self.bookmarksList[:]
     
     def hgBookmarkDefine(self, name):
@@ -76,8 +102,10 @@
             if repodir == os.sep:
                 return
         
-        dlg = HgBookmarkDialog(self.vcs.tagsList, self.vcs.branchesList, 
-            self.bookmarksList)
+        dlg = HgBookmarkDialog(HgBookmarkDialog.DEFINE_MODE, 
+                               self.vcs.hgGetTagsList(repodir),
+                               self.vcs.hgGetBranchesList(repodir),
+                               self.hgGetBookmarksList(repodir))
         if dlg.exec_() == QDialog.Accepted:
             rev, bookmark = dlg.getData()
             
@@ -112,7 +140,7 @@
             None,
             self.trUtf8("Delete Bookmark"),
             self.trUtf8("Select the bookmark to be deleted:"),
-            [""] + self.bookmarksList,
+            [""] + sorted(self.hgGetBookmarksList(repodir)),
             0, True)
         if ok and bookmark:
             args = []
@@ -140,7 +168,7 @@
             if repodir == os.sep:
                 return
         
-        dlg = HgBookmarkRenameDialog(self.bookmarksList)
+        dlg = HgBookmarkRenameDialog(self.hgGetBookmarksList(repodir))
         if dlg.exec_() == QDialog.Accepted:
             newName, oldName = dlg.getData()
             
@@ -150,7 +178,42 @@
             args.append(oldName)
             args.append(newName)
             
-            dia = HgDialog(self.trUtf8('Delete Mercurial Bookmark'))
+            dia = HgDialog(self.trUtf8('Rename Mercurial Bookmark'))
             res = dia.startProcess(args, repodir)
             if res:
                 dia.exec_()
+    
+    def hgBookmarkMove(self, name):
+        """
+        Public method to move a bookmark.
+        
+        @param name file/directory name (string)
+        """
+        dname, fname = self.vcs.splitPath(name)
+        
+        # find the root of the repo
+        repodir = str(dname)
+        while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)):
+            repodir = os.path.dirname(repodir)
+            if repodir == os.sep:
+                return
+        
+        dlg = HgBookmarkDialog(HgBookmarkDialog.MOVE_MODE, 
+                               self.vcs.hgGetTagsList(repodir),
+                               self.vcs.hgGetBranchesList(repodir),
+                               self.hgGetBookmarksList(repodir))
+        if dlg.exec_() == QDialog.Accepted:
+            rev, bookmark = dlg.getData()
+            
+            args = []
+            args.append("bookmarks")
+            args.append("--force")
+            if rev:
+                args.append("--rev")
+                args.append(rev)
+            args.append(bookmark)
+            
+            dia = HgDialog(self.trUtf8('Move Mercurial Bookmark'))
+            res = dia.startProcess(args, repodir)
+            if res:
+                dia.exec_()
--- a/Plugins/VcsPlugins/vcsMercurial/HgBackoutDialog.py	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/HgBackoutDialog.py	Sat May 07 17:56:31 2011 +0200
@@ -17,26 +17,85 @@
     """
     Class implementing a dialog to enter the data for a backout operation.
     """
-    def __init__(self, tagsList, branchesList, parent=None):
+    def __init__(self, tagsList, branchesList, bookmarksList=None, parent=None):
         """
         Constructor
         
         @param tagsList list of tags (list of strings)
         @param branchesList list of branches (list of strings)
+        @param bookmarksList list of bookmarks (list of strings)
         @param parent parent widget (QWidget)
         """
         QDialog.__init__(self, parent)
         self.setupUi(self)
         
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
+        
         self.tagCombo.addItems(sorted(tagsList))
         self.branchCombo.addItems(["default"] + sorted(branchesList))
-        
-        self.okButton = self.buttonBox.button(QDialogButtonBox.Ok)
-        self.okButton.setEnabled(False)
+        if bookmarksList is not None:
+            self.bookmarkCombo.addItems(sorted(bookmarksList))
+        else:
+            self.bookmarkButton.setHidden(True)
+            self.bookmarkCombo.setHidden(True)
         
         self.__initDateTime = QDateTime.currentDateTime()
         self.dateEdit.setDateTime(self.__initDateTime)
     
+    def __updateOK(self):
+        """
+        Private slot to update the OK button.
+        """
+        enabled = True
+        if self.noneButton.isChecked():
+            enabled = False
+        elif self.idButton.isChecked():
+            enabled = self.idEdit.text() != ""
+        elif self.tagButton.isChecked():
+            enabled = self.tagCombo.currentText() != ""
+        elif self.branchButton.isChecked():
+            enabled = self.branchCombo.currentText() != ""
+        elif self.bookmarkButton.isChecked():
+            enabled = self.bookmarkCombo.currentText() != ""
+        
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled)
+    
+    @pyqtSlot(bool)
+    def on_idButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the ID select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_tagButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Tag select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_branchButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Branch select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_bookmarkButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Bookmark select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
     @pyqtSlot(bool)
     def on_noneButton_toggled(self, checked):
         """
@@ -44,7 +103,43 @@
         
         @param checked flag indicating the checked state (boolean)
         """
-        self.okButton.setEnabled(not checked)
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_idEdit_textChanged(self, txt):
+        """
+        Private slot to handle changes of the ID edit.
+        
+        @param txt text of the edit (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_tagCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Tag combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_branchCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Branch combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_bookmarkCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Bookmark combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
     
     def getParameters(self):
         """
@@ -62,6 +157,8 @@
             rev = self.tagCombo.currentText()
         elif self.branchButton.isChecked():
             rev = self.branchCombo.currentText()
+        elif self.bookmarkButton.isChecked():
+            rev = self.bookmarkCombo.currentText()
         else:
             rev = ""
         
--- a/Plugins/VcsPlugins/vcsMercurial/HgBackoutDialog.ui	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/HgBackoutDialog.ui	Sat May 07 17:56:31 2011 +0200
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>372</width>
-    <height>492</height>
+    <height>455</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -143,7 +143,36 @@
         </property>
        </widget>
       </item>
-      <item row="4" column="0" colspan="3">
+      <item row="4" column="0">
+       <widget class="QRadioButton" name="bookmarkButton">
+        <property name="toolTip">
+         <string>Select to specify a revision by a bookmark</string>
+        </property>
+        <property name="text">
+         <string>Bookmark:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="1" colspan="2">
+       <widget class="QComboBox" name="bookmarkCombo">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="toolTip">
+         <string>Enter a bookmark name</string>
+        </property>
+        <property name="editable">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="0" colspan="2">
        <widget class="QRadioButton" name="noneButton">
         <property name="toolTip">
          <string>Select to not specify a specific revision</string>
@@ -254,6 +283,8 @@
   <tabstop>tagCombo</tabstop>
   <tabstop>branchButton</tabstop>
   <tabstop>branchCombo</tabstop>
+  <tabstop>bookmarkButton</tabstop>
+  <tabstop>bookmarkCombo</tabstop>
   <tabstop>noneButton</tabstop>
   <tabstop>messageEdit</tabstop>
   <tabstop>dateEdit</tabstop>
@@ -270,8 +301,8 @@
    <slot>accept()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>257</x>
-     <y>215</y>
+     <x>261</x>
+     <y>450</y>
     </hint>
     <hint type="destinationlabel">
      <x>157</x>
@@ -286,8 +317,8 @@
    <slot>reject()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>325</x>
-     <y>215</y>
+     <x>329</x>
+     <y>450</y>
     </hint>
     <hint type="destinationlabel">
      <x>286</x>
@@ -359,5 +390,21 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>bookmarkButton</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>bookmarkCombo</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>57</x>
+     <y>147</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>116</x>
+     <y>147</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
 </ui>
--- a/Plugins/VcsPlugins/vcsMercurial/HgBundleDialog.py	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/HgBundleDialog.py	Sat May 07 17:56:31 2011 +0200
@@ -7,7 +7,8 @@
 Module implementing a dialog to enter the data for a bundle operation.
 """
 
-from PyQt4.QtGui import QDialog
+from PyQt4.QtCore import pyqtSlot
+from PyQt4.QtGui import QDialog, QDialogButtonBox
 
 from .Ui_HgBundleDialog import Ui_HgBundleDialog
 
@@ -16,20 +17,116 @@
     """
     Class implementing a dialog to enter the data for a bundle operation.
     """
-    def __init__(self, tagsList, branchesList, parent=None):
+    def __init__(self, tagsList, branchesList, bookmarksList=None, parent=None):
         """
         Constructor
         
         @param tagsList list of tags (list of strings)
         @param branchesList list of branches (list of strings)
+        @param bookmarksList list of bookmarks (list of strings)
         @param parent parent widget (QWidget)
         """
         QDialog.__init__(self, parent)
         self.setupUi(self)
         
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
+        
         self.compressionCombo.addItems(["", "bzip2", "gzip", "none"])
         self.tagCombo.addItems(sorted(tagsList))
         self.branchCombo.addItems(["default"] + sorted(branchesList))
+        if bookmarksList is not None:
+            self.bookmarkCombo.addItems(sorted(bookmarksList))
+        else:
+            self.bookmarkButton.setHidden(True)
+            self.bookmarkCombo.setHidden(True)
+    
+    def __updateOK(self):
+        """
+        Private slot to update the OK button.
+        """
+        enabled = True
+        if self.idButton.isChecked():
+            enabled = self.idEdit.text() != ""
+        elif self.tagButton.isChecked():
+            enabled = self.tagCombo.currentText() != ""
+        elif self.branchButton.isChecked():
+            enabled = self.branchCombo.currentText() != ""
+        elif self.bookmarkButton.isChecked():
+            enabled = self.bookmarkCombo.currentText() != ""
+        
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled)
+    
+    @pyqtSlot(bool)
+    def on_idButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the ID select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_tagButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Tag select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_branchButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Branch select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_bookmarkButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Bookmark select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_idEdit_textChanged(self, txt):
+        """
+        Private slot to handle changes of the ID edit.
+        
+        @param txt text of the edit (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_tagCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Tag combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_branchCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Branch combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_bookmarkCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Bookmark combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
     
     def getParameters(self):
         """
@@ -46,6 +143,8 @@
             rev = self.tagCombo.currentText()
         elif self.branchButton.isChecked():
             rev = self.branchCombo.currentText()
+        elif self.bookmarkButton.isChecked():
+            rev = self.bookmarkCombo.currentText()
         else:
             rev = ""
         
--- a/Plugins/VcsPlugins/vcsMercurial/HgBundleDialog.ui	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/HgBundleDialog.ui	Sat May 07 17:56:31 2011 +0200
@@ -131,7 +131,36 @@
         </property>
        </widget>
       </item>
-      <item row="4" column="0" colspan="3">
+      <item row="4" column="0">
+       <widget class="QRadioButton" name="bookmarkButton">
+        <property name="toolTip">
+         <string>Select to specify a revision by a bookmark</string>
+        </property>
+        <property name="text">
+         <string>Bookmark:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="1" colspan="2">
+       <widget class="QComboBox" name="bookmarkCombo">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="toolTip">
+         <string>Enter a bookmark name</string>
+        </property>
+        <property name="editable">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="0" colspan="3">
        <widget class="QRadioButton" name="noneButton">
         <property name="toolTip">
          <string>Select to not specify a specific revision</string>
@@ -185,6 +214,8 @@
   <tabstop>tagCombo</tabstop>
   <tabstop>branchButton</tabstop>
   <tabstop>branchCombo</tabstop>
+  <tabstop>bookmarkButton</tabstop>
+  <tabstop>bookmarkCombo</tabstop>
   <tabstop>noneButton</tabstop>
   <tabstop>compressionCombo</tabstop>
   <tabstop>allCheckBox</tabstop>
@@ -199,8 +230,8 @@
    <slot>accept()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>257</x>
-     <y>246</y>
+     <x>261</x>
+     <y>271</y>
     </hint>
     <hint type="destinationlabel">
      <x>157</x>
@@ -215,8 +246,8 @@
    <slot>reject()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>325</x>
-     <y>246</y>
+     <x>329</x>
+     <y>271</y>
     </hint>
     <hint type="destinationlabel">
      <x>286</x>
@@ -288,5 +319,21 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>bookmarkButton</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>bookmarkCombo</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>45</x>
+     <y>150</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>125</x>
+     <y>148</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
 </ui>
--- a/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py	Sat May 07 17:56:31 2011 +0200
@@ -130,6 +130,9 @@
         
         self.logTree.setIconSize(
             QSize(100 * self.__rowHeight, self.__rowHeight))
+        if self.vcs.versionStr >= "1.8":
+            self.logTree.headerItem().setText(self.logTree.columnCount(),
+                self.trUtf8("Bookmarks"))
         
         self.__projectRevision = -1
     
@@ -462,7 +465,7 @@
                 errMsg)
     
     def __generateLogItem(self, author, date, message, revision, changedPaths,
-                          parents, branches, tags):
+                          parents, branches, tags, bookmarks=None):
         """
         Private method to generate a log tree entry.
         
@@ -475,6 +478,7 @@
         @param parents list of parent revisions (list of integers)
         @param branches list of branches (list of strings)
         @param tags list of tags (string)
+        @param bookmarks list of bookmarks (string)
         @return reference to the generated item (QTreeWidgetItem)
         """
         msg = []
@@ -489,7 +493,7 @@
         msgtxt = msg[0]
         if len(msgtxt) > 30:
             msgtxt = "{0}...".format(msgtxt[:30])
-        itm = QTreeWidgetItem(self.logTree, [
+        columnLabels = [
             "",
             branches[0] + closedStr,
             "{0:>7}:{1}".format(rev, node),
@@ -497,7 +501,10 @@
             date,
             msgtxt,
             ", ".join(tags),
-        ])
+        ]
+        if bookmarks is not None:
+            columnLabels.append(", ".join(bookmarks))
+        itm = QTreeWidgetItem(self.logTree, columnLabels)
         
         itm.setForeground(self.BranchColumn,
                           QBrush(QColor(self.__branchColor(branches[0]))))
@@ -595,8 +602,12 @@
         if self.commandMode == "log":
             args.append('--copies')
         args.append('--style')
-        args.append(os.path.join(os.path.dirname(__file__),
-                                 "styles", "logBrowser.style"))
+        if self.vcs.versionStr >= "1.8":
+            args.append(os.path.join(os.path.dirname(__file__),
+                                     "styles", "logBrowserBookmark.style"))
+        else:
+            args.append(os.path.join(os.path.dirname(__file__),
+                                     "styles", "logBrowser.style"))
         if self.commandMode == "incoming":
             if self.bundle:
                 args.append(self.bundle)
@@ -687,7 +698,7 @@
         Private method to process the buffered output of the hg log command.
         """
         noEntries = 0
-        log = {"message": []}
+        log = {"message": [], "bookmarks": None}
         changedPaths = []
         initialText = True
         fileCopies = {}
@@ -754,6 +765,8 @@
                         log["branches"] = ["default"]
                 elif key == "tags":
                     log["tags"] = value.strip().split(", ")
+                elif key == "bookmarks":
+                    log["bookmarks"] = value.strip().split()
                 else:
                     if initialText:
                         continue
@@ -763,7 +776,8 @@
                 if len(log) > 1:
                     self.__generateLogItem(log["author"], log["date"],
                         log["message"], log["revision"], changedPaths,
-                        log["parents"], log["branches"], log["tags"])
+                        log["parents"], log["branches"], log["tags"], 
+                        log["bookmarks"])
                     dt = QDate.fromString(log["date"], Qt.ISODate)
                     if not self.__maxDate.isValid() and \
                        not self.__minDate.isValid():
@@ -775,7 +789,7 @@
                         if self.__minDate > dt:
                             self.__minDate = dt
                     noEntries += 1
-                    log = {"message": []}
+                    log = {"message": [], "bookmarks": None}
                     changedPaths = []
                     fileCopies = {}
         
--- a/Plugins/VcsPlugins/vcsMercurial/HgMergeDialog.py	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/HgMergeDialog.py	Sat May 07 17:56:31 2011 +0200
@@ -7,7 +7,8 @@
 Module implementing a dialog to enter the data for a merge operation.
 """
 
-from PyQt4.QtGui import QDialog
+from PyQt4.QtCore import pyqtSlot
+from PyQt4.QtGui import QDialog, QDialogButtonBox
 
 from .Ui_HgMergeDialog import Ui_HgMergeDialog
 
@@ -16,21 +17,117 @@
     """
     Class implementing a dialog to enter the data for a merge operation.
     """
-    def __init__(self, force, tagsList, branchesList, parent=None):
+    def __init__(self, force, tagsList, branchesList, bookmarksList=None, parent=None):
         """
         Constructor
         
         @param force flag indicating a forced merge (boolean)
         @param tagsList list of tags (list of strings)
         @param branchesList list of branches (list of strings)
+        @param bookmarksList list of bookmarks (list of strings)
         @param parent parent widget (QWidget)
         """
         QDialog.__init__(self, parent)
         self.setupUi(self)
        
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
+        
         self.forceCheckBox.setChecked(force)
         self.tagCombo.addItems(sorted(tagsList))
         self.branchCombo.addItems(["default"] + sorted(branchesList))
+        if bookmarksList is not None:
+            self.bookmarkCombo.addItems(sorted(bookmarksList))
+        else:
+            self.bookmarkButton.setHidden(True)
+            self.bookmarkCombo.setHidden(True)
+    
+    def __updateOK(self):
+        """
+        Private slot to update the OK button.
+        """
+        enabled = True
+        if self.idButton.isChecked():
+            enabled = self.idEdit.text() != ""
+        elif self.tagButton.isChecked():
+            enabled = self.tagCombo.currentText() != ""
+        elif self.branchButton.isChecked():
+            enabled = self.branchCombo.currentText() != ""
+        elif self.bookmarkButton.isChecked():
+            enabled = self.bookmarkCombo.currentText() != ""
+        
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled)
+    
+    @pyqtSlot(bool)
+    def on_idButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the ID select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_tagButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Tag select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_branchButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Branch select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_bookmarkButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Bookmark select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_idEdit_textChanged(self, txt):
+        """
+        Private slot to handle changes of the ID edit.
+        
+        @param txt text of the edit (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_tagCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Tag combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_branchCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Branch combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_bookmarkCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Bookmark combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
     
     def getParameters(self):
         """
@@ -47,6 +144,8 @@
             rev = self.tagCombo.currentText()
         elif self.branchButton.isChecked():
             rev = self.branchCombo.currentText()
+        elif self.bookmarkButton.isChecked():
+            rev = self.bookmarkCombo.currentText()
         else:
             rev = ""
         
--- a/Plugins/VcsPlugins/vcsMercurial/HgMergeDialog.ui	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/HgMergeDialog.ui	Sat May 07 17:56:31 2011 +0200
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>372</width>
-    <height>256</height>
+    <height>249</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -131,7 +131,36 @@
         </property>
        </widget>
       </item>
-      <item row="4" column="0" colspan="3">
+      <item row="4" column="0">
+       <widget class="QRadioButton" name="bookmarkButton">
+        <property name="toolTip">
+         <string>Select to specify a revision by a bookmark</string>
+        </property>
+        <property name="text">
+         <string>Bookmark:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="1" colspan="2">
+       <widget class="QComboBox" name="bookmarkCombo">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="toolTip">
+         <string>Enter a bookmark name</string>
+        </property>
+        <property name="editable">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="0" colspan="3">
        <widget class="QRadioButton" name="noneButton">
         <property name="toolTip">
          <string>Select to not specify a specific revision</string>
@@ -178,6 +207,8 @@
   <tabstop>tagCombo</tabstop>
   <tabstop>branchButton</tabstop>
   <tabstop>branchCombo</tabstop>
+  <tabstop>bookmarkButton</tabstop>
+  <tabstop>bookmarkCombo</tabstop>
   <tabstop>noneButton</tabstop>
   <tabstop>forceCheckBox</tabstop>
   <tabstop>buttonBox</tabstop>
@@ -191,8 +222,8 @@
    <slot>accept()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>257</x>
-     <y>246</y>
+     <x>261</x>
+     <y>244</y>
     </hint>
     <hint type="destinationlabel">
      <x>157</x>
@@ -207,8 +238,8 @@
    <slot>reject()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>325</x>
-     <y>246</y>
+     <x>329</x>
+     <y>244</y>
     </hint>
     <hint type="destinationlabel">
      <x>286</x>
@@ -280,5 +311,21 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>bookmarkButton</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>bookmarkCombo</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>71</x>
+     <y>145</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>121</x>
+     <y>149</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
 </ui>
--- a/Plugins/VcsPlugins/vcsMercurial/HgRevisionSelectionDialog.py	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/HgRevisionSelectionDialog.py	Sat May 07 17:56:31 2011 +0200
@@ -7,7 +7,8 @@
 Module implementing a dialog to select a revision.
 """
 
-from PyQt4.QtGui import QDialog
+from PyQt4.QtCore import pyqtSlot
+from PyQt4.QtGui import QDialog, QDialogButtonBox
 
 from .Ui_HgRevisionSelectionDialog import Ui_HgRevisionSelectionDialog
 
@@ -16,26 +17,123 @@
     """
     Class implementing a dialog to select a revision.
     """
-    def __init__(self, tagsList, branchesList, showNone=False, parent=None):
+    def __init__(self, tagsList, branchesList, bookmarksList=None, showNone=False,
+                 parent=None):
         """
         Constructor
         
         @param tagsList list of tags (list of strings)
         @param branchesList list of branches (list of strings)
+        @param bookmarksList list of bookmarks (list of strings)
         @param showNone flag influencing the label of the 'None' selection (boolean)
         @param parent parent widget (QWidget)
         """
         QDialog.__init__(self, parent)
         self.setupUi(self)
        
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
+        
         self.tagCombo.addItems(sorted(tagsList))
         self.branchCombo.addItems(["default"] + sorted(branchesList))
+        if bookmarksList is not None:
+            self.bookmarkCombo.addItems(sorted(bookmarksList))
+        else:
+            self.bookmarkButton.setHidden(True)
+            self.bookmarkCombo.setHidden(True)
         
         if showNone:
             self.tipButton.setText(self.trUtf8("No revision selected"))
             self.tipButton.setToolTip(self.trUtf8(
                 "Select to not specify a specific revision"))
     
+    def __updateOK(self):
+        """
+        Private slot to update the OK button.
+        """
+        enabled = True
+        if self.idButton.isChecked():
+            enabled = self.idEdit.text() != ""
+        elif self.tagButton.isChecked():
+            enabled = self.tagCombo.currentText() != ""
+        elif self.branchButton.isChecked():
+            enabled = self.branchCombo.currentText() != ""
+        elif self.bookmarkButton.isChecked():
+            enabled = self.bookmarkCombo.currentText() != ""
+        
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled)
+    
+    @pyqtSlot(bool)
+    def on_idButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the ID select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_tagButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Tag select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_branchButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Branch select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_bookmarkButton_toggled(self, checked):
+        """
+        Private slot to handle changes of the Bookmark select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_idEdit_textChanged(self, txt):
+        """
+        Private slot to handle changes of the ID edit.
+        
+        @param txt text of the edit (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_tagCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Tag combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_branchCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Branch combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_bookmarkCombo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Bookmark combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
     def getRevision(self):
         """
         Public method to retrieve the selected revision.
@@ -50,6 +148,8 @@
             rev = self.tagCombo.currentText()
         elif self.branchButton.isChecked():
             rev = self.branchCombo.currentText()
+        elif self.bookmarkButton.isChecked():
+            rev = self.bookmarkCombo.currentText()
         else:
             rev = ""
         
--- a/Plugins/VcsPlugins/vcsMercurial/HgRevisionSelectionDialog.ui	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/HgRevisionSelectionDialog.ui	Sat May 07 17:56:31 2011 +0200
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>372</width>
-    <height>225</height>
+    <height>224</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -143,7 +143,36 @@
         </property>
        </widget>
       </item>
-      <item row="4" column="0" colspan="3">
+      <item row="4" column="0">
+       <widget class="QRadioButton" name="bookmarkButton">
+        <property name="toolTip">
+         <string>Select to specify a revision by a bookmark</string>
+        </property>
+        <property name="text">
+         <string>Bookmark:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="1" colspan="2">
+       <widget class="QComboBox" name="bookmarkCombo">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="toolTip">
+         <string>Enter a bookmark name</string>
+        </property>
+        <property name="editable">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="0" colspan="3">
        <widget class="QRadioButton" name="tipButton">
         <property name="toolTip">
          <string>Select tip revision of repository</string>
@@ -180,6 +209,8 @@
   <tabstop>tagCombo</tabstop>
   <tabstop>branchButton</tabstop>
   <tabstop>branchCombo</tabstop>
+  <tabstop>bookmarkButton</tabstop>
+  <tabstop>bookmarkCombo</tabstop>
   <tabstop>tipButton</tabstop>
   <tabstop>buttonBox</tabstop>
  </tabstops>
@@ -197,7 +228,7 @@
     </hint>
     <hint type="destinationlabel">
      <x>157</x>
-     <y>224</y>
+     <y>223</y>
     </hint>
    </hints>
   </connection>
@@ -213,7 +244,7 @@
     </hint>
     <hint type="destinationlabel">
      <x>286</x>
-     <y>224</y>
+     <y>223</y>
     </hint>
    </hints>
   </connection>
@@ -224,12 +255,12 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>48</x>
-     <y>42</y>
+     <x>55</x>
+     <y>44</y>
     </hint>
     <hint type="destinationlabel">
-     <x>113</x>
-     <y>43</y>
+     <x>125</x>
+     <y>42</y>
     </hint>
    </hints>
   </connection>
@@ -240,12 +271,12 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>38</x>
-     <y>76</y>
+     <x>41</x>
+     <y>69</y>
     </hint>
     <hint type="destinationlabel">
-     <x>125</x>
-     <y>75</y>
+     <x>121</x>
+     <y>68</y>
     </hint>
    </hints>
   </connection>
@@ -256,12 +287,12 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>52</x>
-     <y>104</y>
+     <x>69</x>
+     <y>94</y>
     </hint>
     <hint type="destinationlabel">
-     <x>124</x>
-     <y>99</y>
+     <x>132</x>
+     <y>98</y>
     </hint>
    </hints>
   </connection>
@@ -272,12 +303,28 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>71</x>
-     <y>127</y>
+     <x>60</x>
+     <y>120</y>
     </hint>
     <hint type="destinationlabel">
-     <x>123</x>
-     <y>130</y>
+     <x>117</x>
+     <y>122</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>bookmarkButton</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>bookmarkCombo</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>25</x>
+     <y>146</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>130</x>
+     <y>149</y>
     </hint>
    </hints>
   </connection>
--- a/Plugins/VcsPlugins/vcsMercurial/HgRevisionsSelectionDialog.py	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/HgRevisionsSelectionDialog.py	Sat May 07 17:56:31 2011 +0200
@@ -7,7 +7,8 @@
 Module implementing a dialog to enter the revisions for the hg diff command.
 """
 
-from PyQt4.QtGui import QDialog
+from PyQt4.QtCore import pyqtSlot
+from PyQt4.QtGui import QDialog, QDialogButtonBox
 
 from .Ui_HgRevisionsSelectionDialog import Ui_HgRevisionsSelectionDialog
 
@@ -16,21 +17,202 @@
     """
     Class implementing a dialog to enter the revisions for the hg diff command.
     """
-    def __init__(self, tagsList, branchesList, parent=None):
+    def __init__(self, tagsList, branchesList, bookmarksList=None, parent=None):
         """
         Constructor
         
         @param tagsList list of tags (list of strings)
         @param branchesList list of branches (list of strings)
+        @param bookmarksList list of bookmarks (list of strings)
         @param parent parent widget of the dialog (QWidget)
         """
         QDialog.__init__(self, parent)
         self.setupUi(self)
         
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
+        
         self.tag1Combo.addItems(sorted(tagsList))
         self.tag2Combo.addItems(sorted(tagsList))
         self.branch1Combo.addItems(["default"] + sorted(branchesList))
         self.branch2Combo.addItems(["default"] + sorted(branchesList))
+        if bookmarksList is not None:
+            self.bookmark1Combo.addItems(sorted(bookmarksList))
+            self.bookmark2Combo.addItems(sorted(bookmarksList))
+        else:
+            self.bookmark1Button.setHidden(True)
+            self.bookmark1Combo.setHidden(True)
+            self.bookmark2Button.setHidden(True)
+            self.bookmark2Combo.setHidden(True)
+    
+    def __updateOK(self):
+        """
+        Private slot to update the OK button.
+        """
+        enabled = True
+        if self.id1Button.isChecked():
+            enabled = enabled and self.id1Edit.text() != ""
+        elif self.tag1Button.isChecked():
+            enabled = enabled and self.tag1Combo.currentText() != ""
+        elif self.branch1Button.isChecked():
+            enabled = enabled and self.branch1Combo.currentText() != ""
+        elif self.bookmark1Button.isChecked():
+            enabled = enabled and self.bookmark1Combo.currentText() != ""
+        
+        if self.id2Button.isChecked():
+            enabled = enabled and self.id2Edit.text() != ""
+        elif self.tag2Button.isChecked():
+            enabled = enabled and self.tag2Combo.currentText() != ""
+        elif self.branch2Button.isChecked():
+            enabled = enabled and self.branch2Combo.currentText() != ""
+        elif self.bookmark2Button.isChecked():
+            enabled = enabled and self.bookmark2Combo.currentText() != ""
+        
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled)
+    
+    @pyqtSlot(bool)
+    def on_id1Button_toggled(self, checked):
+        """
+        Private slot to handle changes of the ID1 select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_id2Button_toggled(self, checked):
+        """
+        Private slot to handle changes of the ID2 select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_tag1Button_toggled(self, checked):
+        """
+        Private slot to handle changes of the Tag1 select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_tag2Button_toggled(self, checked):
+        """
+        Private slot to handle changes of the Tag2 select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_branch1Button_toggled(self, checked):
+        """
+        Private slot to handle changes of the Branch1 select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_branch2Button_toggled(self, checked):
+        """
+        Private slot to handle changes of the Branch2 select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_bookmark1Button_toggled(self, checked):
+        """
+        Private slot to handle changes of the Bookmark1 select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_bookmark2Button_toggled(self, checked):
+        """
+        Private slot to handle changes of the Bookmark2 select button.
+        
+        @param checked state of the button (boolean)
+        """
+        self.__updateOK()
+    
+    
+    @pyqtSlot(str)
+    def on_id1Edit_textChanged(self, txt):
+        """
+        Private slot to handle changes of the ID1 edit.
+        
+        @param txt text of the edit (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_id2Edit_textChanged(self, txt):
+        """
+        Private slot to handle changes of the ID2 edit.
+        
+        @param txt text of the edit (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_tag1Combo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Tag1 combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_tag2Combo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Tag2 combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_branch1Combo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Branch1 combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_branch2Combo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Branch2 combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_bookmark1Combo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Bookmark1 combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_bookmark2Combo_editTextChanged(self, txt):
+        """
+        Private slot to handle changes of the Bookmark2 combo.
+        
+        @param txt text of the combo (string)
+        """
+        self.__updateOK()
     
     def __getRevision(self, no):
         """
@@ -48,6 +230,8 @@
             tagCombo = self.tag1Combo
             branchButton = self.branch1Button
             branchCombo = self.branch1Combo
+            bookmarkButton = self.bookmark1Button
+            bookmarkCombo = self.bookmark1Combo
             tipButton = self.tip1Button
             prevButton = self.prev1Button
         else:
@@ -59,6 +243,8 @@
             tagCombo = self.tag2Combo
             branchButton = self.branch2Button
             branchCombo = self.branch2Combo
+            bookmarkButton = self.bookmark2Button
+            bookmarkCombo = self.bookmark2Combo
             tipButton = self.tip2Button
             prevButton = self.prev2Button
         
@@ -70,6 +256,8 @@
             return tagCombo.currentText()
         elif branchButton.isChecked():
             return branchCombo.currentText()
+        elif bookmarkButton.isChecked():
+            return bookmarkCombo.currentText()
         elif tipButton.isChecked():
             return "tip"
         elif prevButton.isChecked():
--- a/Plugins/VcsPlugins/vcsMercurial/HgRevisionsSelectionDialog.ui	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/HgRevisionsSelectionDialog.ui	Sat May 07 17:56:31 2011 +0200
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>371</width>
-    <height>450</height>
+    <height>465</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -134,7 +134,36 @@
         </property>
        </widget>
       </item>
-      <item row="4" column="0" colspan="3">
+      <item row="4" column="0">
+       <widget class="QRadioButton" name="bookmark1Button">
+        <property name="toolTip">
+         <string>Select to specify a revision by a bookmark</string>
+        </property>
+        <property name="text">
+         <string>Bookmark:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="1" colspan="2">
+       <widget class="QComboBox" name="bookmark1Combo">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="toolTip">
+         <string>Enter a bookmark name</string>
+        </property>
+        <property name="editable">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="0" colspan="3">
        <widget class="QRadioButton" name="tip1Button">
         <property name="toolTip">
          <string>Select tip revision of repository</string>
@@ -147,7 +176,7 @@
         </property>
        </widget>
       </item>
-      <item row="5" column="0" colspan="3">
+      <item row="6" column="0" colspan="3">
        <widget class="QRadioButton" name="prev1Button">
         <property name="toolTip">
          <string>Select revision before last commit</string>
@@ -277,7 +306,36 @@
         </property>
        </widget>
       </item>
-      <item row="4" column="0" colspan="3">
+      <item row="4" column="0">
+       <widget class="QRadioButton" name="bookmark2Button">
+        <property name="toolTip">
+         <string>Select to specify a revision by a bookmark</string>
+        </property>
+        <property name="text">
+         <string>Bookmark:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="1" colspan="2">
+       <widget class="QComboBox" name="bookmark2Combo">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="toolTip">
+         <string>Enter a bookmark name</string>
+        </property>
+        <property name="editable">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="0" colspan="3">
        <widget class="QRadioButton" name="tip2Button">
         <property name="toolTip">
          <string>Select tip revision of repository</string>
@@ -290,7 +348,7 @@
         </property>
        </widget>
       </item>
-      <item row="5" column="0" colspan="3">
+      <item row="6" column="0" colspan="3">
        <widget class="QRadioButton" name="prev2Button">
         <property name="toolTip">
          <string>Select revision before last commit</string>
@@ -314,6 +372,10 @@
     </widget>
    </item>
   </layout>
+  <zorder>rev1GroupBox</zorder>
+  <zorder>rev2GroupBox</zorder>
+  <zorder>buttonBox</zorder>
+  <zorder>prev2Button</zorder>
  </widget>
  <layoutdefault spacing="6" margin="6"/>
  <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
@@ -326,6 +388,8 @@
   <tabstop>tag1Combo</tabstop>
   <tabstop>branch1Button</tabstop>
   <tabstop>branch1Combo</tabstop>
+  <tabstop>bookmark1Button</tabstop>
+  <tabstop>bookmark1Combo</tabstop>
   <tabstop>tip1Button</tabstop>
   <tabstop>prev1Button</tabstop>
   <tabstop>number2Button</tabstop>
@@ -336,6 +400,8 @@
   <tabstop>tag2Combo</tabstop>
   <tabstop>branch2Button</tabstop>
   <tabstop>branch2Combo</tabstop>
+  <tabstop>bookmark2Button</tabstop>
+  <tabstop>bookmark2Combo</tabstop>
   <tabstop>tip2Button</tabstop>
   <tabstop>prev2Button</tabstop>
   <tabstop>buttonBox</tabstop>
@@ -445,8 +511,8 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>48</x>
-     <y>106</y>
+     <x>59</x>
+     <y>105</y>
     </hint>
     <hint type="destinationlabel">
      <x>129</x>
@@ -502,5 +568,37 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>bookmark1Button</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>bookmark1Combo</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>24</x>
+     <y>152</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>135</x>
+     <y>148</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>bookmark2Button</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>bookmark2Combo</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>21</x>
+     <y>363</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>145</x>
+     <y>361</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
 </ui>
--- a/Plugins/VcsPlugins/vcsMercurial/hg.py	Sat May 07 13:37:58 2011 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/hg.py	Sat May 07 17:56:31 2011 +0200
@@ -694,18 +694,15 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
                 return
         
-        dlg = HgTagDialog(self.tagsList)
+        dlg = HgTagDialog(self.hgGetTagsList(repodir))
         if dlg.exec_() == QDialog.Accepted:
             tag, tagOp = dlg.getParameters()
-            if tag in self.tagsList:
-                self.tagsList.remove(tag)
-            self.tagsList.insert(0, tag)
         else:
             return
         
@@ -767,17 +764,6 @@
         """
         dname, fname = self.splitPath(name)
         
-        opts = self.options['global'][:]
-        force = '--force' in opts
-        if force:
-            del opts[opts.index('--force')]
-        
-        dlg = HgMergeDialog(force, self.tagsList, self.branchesList)
-        if dlg.exec_() == QDialog.Accepted:
-            rev, force = dlg.getParameters()
-        else:
-            return
-        
         # find the root of the repo
         repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
@@ -785,6 +771,24 @@
             if repodir == os.sep:
                 return
         
+        opts = self.options['global'][:]
+        force = '--force' in opts
+        if force:
+            del opts[opts.index('--force')]
+        
+        if self.isExtensionActive("bookmarks"):
+            bookmarksList = \
+                self.getExtensionObject("bookmarks").hgGetBookmarksList(repodir)
+        else:
+            bookmarksList = None
+        dlg = HgMergeDialog(force, self.hgGetTagsList(repodir),
+                            self.hgGetBranchesList(repodir),
+                            bookmarksList)
+        if dlg.exec_() == QDialog.Accepted:
+            rev, force = dlg.getParameters()
+        else:
+            return
+        
         args = []
         args.append('merge')
         self.addArguments(args, opts)
@@ -806,7 +810,23 @@
         
         @param name directory name to be switched (string)
         """
-        dlg = HgRevisionSelectionDialog(self.tagsList, self.branchesList)
+        dname, fname = self.splitPath(name)
+        
+        # find the root of the repo
+        repodir = dname
+        while not os.path.isdir(os.path.join(repodir, self.adminDir)):
+            repodir = os.path.dirname(repodir)
+            if repodir == os.sep:
+                return
+        
+        if self.isExtensionActive("bookmarks"):
+            bookmarksList = \
+                self.getExtensionObject("bookmarks").hgGetBookmarksList(repodir)
+        else:
+            bookmarksList = None
+        dlg = HgRevisionSelectionDialog(self.hgGetTagsList(repodir),
+                                        self.hgGetBranchesList(repodir), 
+                                        bookmarksList)
         if dlg.exec_() == QDialog.Accepted:
             rev = dlg.getRevision()
             self.vcsUpdate(name, revision=rev)
@@ -1184,6 +1204,74 @@
                         project.appendFile(target)
         return res
     
+    def hgGetTagsList(self, repodir):
+        """
+        Public method to get the list of tags.
+        
+        @param repodir directory name of the repository (string)
+        @return list of tags (list of string)
+        """
+        ioEncoding = Preferences.getSystem("IOEncoding")
+        process = QProcess()
+        args = []
+        args.append('tags')
+        args.append('--verbose')
+        process.setWorkingDirectory(repodir)
+        process.start('hg', args)
+        procStarted = process.waitForStarted()
+        if procStarted:
+            finished = process.waitForFinished(30000)
+            if finished and process.exitCode() == 0:
+                self.tagsList = []
+                output = \
+                    str(process.readAllStandardOutput(), ioEncoding, 'replace')
+                for line in output.splitlines():
+                    l = line.strip().split()
+                    if l[-1][0] in "1234567890":
+                        # last element is a rev:changeset
+                        del l[-1]
+                    else:
+                        del l[-2:]
+                    name = " ".join(l)
+                    if name not in ["tip", "default"]:
+                        self.tagsList.append(name)
+        
+        return self.tagsList[:]
+    
+    def hgGetBranchesList(self, repodir):
+        """
+        Public method to get the list of branches.
+        
+        @param repodir directory name of the repository (string)
+        @return list of branches (list of string)
+        """
+        ioEncoding = Preferences.getSystem("IOEncoding")
+        process = QProcess()
+        args = []
+        args.append('branches')
+        args.append('--closed')
+        process.setWorkingDirectory(repodir)
+        process.start('hg', args)
+        procStarted = process.waitForStarted()
+        if procStarted:
+            finished = process.waitForFinished(30000)
+            if finished and process.exitCode() == 0:
+                self.branchesList = []
+                output = \
+                    str(process.readAllStandardOutput(), ioEncoding, 'replace')
+                for line in output.splitlines():
+                    l = line.strip().split()
+                    if l[-1][0] in "1234567890":
+                        # last element is a rev:changeset
+                        del l[-1]
+                    else:
+                        del l[-2:]
+                    name = " ".join(l)
+                    if name not in ["tip", "default"]:
+                        self.branchesList.append(name)
+        
+        return self.branchesList[:]
+    
     def hgListTagBranch(self, path, tags=True):
         """
         Public method used to list the available tags or branches.
@@ -1237,8 +1325,10 @@
         @param name file/directory name to be diffed (string)
         """
         if isinstance(name, list):
+            dname, fnames = self.splitPathList(name)
             names = name[:]
         else:
+            dname, fname = self.splitPath(name)
             names = [name]
         for nam in names:
             if os.path.isfile(nam):
@@ -1249,7 +1339,22 @@
                 project = e5App().getObject("Project")
                 if nam == project.ppath and not project.saveAllScripts():
                     return
-        dlg = HgRevisionsSelectionDialog(self.tagsList, self.branchesList)
+        
+        # find the root of the repo
+        repodir = dname
+        while not os.path.isdir(os.path.join(repodir, self.adminDir)):
+            repodir = os.path.dirname(repodir)
+            if repodir == os.sep:
+                return
+        
+        if self.isExtensionActive("bookmarks"):
+            bookmarksList = \
+                self.getExtensionObject("bookmarks").hgGetBookmarksList(repodir)
+        else:
+            bookmarksList = None
+        dlg = HgRevisionsSelectionDialog(self.hgGetTagsList(repodir),
+                                         self.hgGetBranchesList(repodir),
+                                         bookmarksList)
         if dlg.exec_() == QDialog.Accepted:
             revisions = dlg.getRevisions()
             self.diff = HgDiffDialog(self)
@@ -1495,7 +1600,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
@@ -1505,7 +1610,7 @@
             None,
             self.trUtf8("Create Branch"),
             self.trUtf8("Enter branch name"),
-            self.branchesList,
+            sorted(self.hgGetBranchesList(repodir)),
             0, True)
         if ok and name:
             args = []
@@ -1526,7 +1631,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
@@ -1549,7 +1654,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
@@ -1574,7 +1679,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
@@ -1597,7 +1702,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
@@ -1621,7 +1726,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
@@ -1644,7 +1749,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
@@ -1667,7 +1772,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
@@ -1735,13 +1840,20 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
                 return
         
-        dlg = HgBundleDialog(self.tagsList, self.branchesList)
+        if self.isExtensionActive("bookmarks"):
+            bookmarksList = \
+                self.getExtensionObject("bookmarks").hgGetBookmarksList(repodir)
+        else:
+            bookmarksList = None
+        dlg = HgBundleDialog(self.hgGetTagsList(repodir),
+                             self.hgGetBranchesList(repodir),
+                             bookmarksList)
         if dlg.exec_() == QDialog.Accepted:
             rev, compression, all = dlg.getParameters()
             
@@ -1799,7 +1911,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
@@ -1830,7 +1942,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
@@ -1860,7 +1972,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
@@ -1903,7 +2015,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
@@ -1911,7 +2023,14 @@
         
         rev = ""
         if subcommand in ("good", "bad"):
-            dlg = HgRevisionSelectionDialog(self.tagsList, self.branchesList,
+            if self.isExtensionActive("bookmarks"):
+                bookmarksList = \
+                    self.getExtensionObject("bookmarks").hgGetBookmarksList(repodir)
+            else:
+                bookmarksList = None
+            dlg = HgRevisionSelectionDialog(self.hgGetTagsList(repodir),
+                                            self.hgGetBranchesList(repodir),
+                                            bookmarksList,
                                             showNone=True)
             if dlg.exec_() == QDialog.Accepted:
                 rev = dlg.getRevision()
@@ -1975,13 +2094,20 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
                 return
         
-        dlg = HgBackoutDialog(self.tagsList, self.branchesList)
+        if self.isExtensionActive("bookmarks"):
+            bookmarksList = \
+                self.getExtensionObject("bookmarks").hgGetBookmarksList(repodir)
+        else:
+            bookmarksList = None
+        dlg = HgBackoutDialog(self.hgGetTagsList(repodir),
+                              self.hgGetBranchesList(repodir),
+                              bookmarksList)
         if dlg.exec_() == QDialog.Accepted:
             rev, merge, date, user, message = dlg.getParameters()
             if not rev:
@@ -2019,7 +2145,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
@@ -2044,7 +2170,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
@@ -2074,7 +2200,7 @@
         dname, fname = self.splitPath(name)
         
         # find the root of the repo
-        repodir = str(dname)
+        repodir = dname
         while not os.path.isdir(os.path.join(repodir, self.adminDir)):
             repodir = os.path.dirname(repodir)
             if repodir == os.sep:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/VcsPlugins/vcsMercurial/styles/logBrowserBookmark.style	Sat May 07 17:56:31 2011 +0200
@@ -0,0 +1,13 @@
+changeset = 'change|{rev}:{node|short}\nuser|{author|email}\nparents|{parents}\ndate|{date|isodate}\ndescription|{desc}\nfile_copies|{file_copies}\nfile_adds|{file_adds}\nfiles_mods|{file_mods}\nfile_dels|{file_dels}\nbranches|{branches}\ntags|{tags}\nbookmarks|{bookmarks}\n@@@\n'
+file_mod = '{file_mod}, '
+last_file_mod = '{file_mod}'
+file_add = '{file_add}, '
+last_file_add = '{file_add}'
+file_del = '{file_del}, '
+last_file_del = '{file_del}'
+file_copy = '{name} ({source}), '
+last_file_copy = '{name} ({source})'
+tag = '{tag}, '
+last_tag = '{tag}'
+branch = '{branch}, '
+last_branch = '{branch}'
--- a/eric5.e4p	Sat May 07 13:37:58 2011 +0200
+++ b/eric5.e4p	Sat May 07 17:56:31 2011 +0200
@@ -1215,6 +1215,7 @@
     <Other>Plugins/VcsPlugins/vcsMercurial/icons/stopServer.png</Other>
     <Other>CSSs/blue.css</Other>
     <Other>CSSs/default.css</Other>
+    <Other>Plugins/VcsPlugins/vcsMercurial/styles/logBrowserBookmark.style</Other>
   </Others>
   <MainScript>eric5.py</MainScript>
   <Vcs>

eric ide

mercurial