Sat, 11 Feb 2017 15:35:07 +0100
Added a GPG actions to the Mercurial log browser action menu.
--- a/Plugins/VcsPlugins/vcsMercurial/GpgExtension/gpg.py Sat Feb 11 10:57:25 2017 +0100 +++ b/Plugins/VcsPlugins/vcsMercurial/GpgExtension/gpg.py Sat Feb 11 15:35:07 2017 +0100 @@ -83,11 +83,14 @@ if res: dia.exec_() - def hgGpgSign(self, path): + def hgGpgSign(self, path, revisions=None): """ Public method used to list the available bookmarks. - @param path directory name of the project (string) + @param path directory name of the project + @type str + @param revisions list containing the revisions to be signed + @type list of str """ # find the root of the repo repodir = self.vcs.splitPath(path)[0] @@ -96,30 +99,44 @@ if os.path.splitdrive(repodir)[1] == os.sep: return - from .HgGpgSignDialog import HgGpgSignDialog - dlg = HgGpgSignDialog(self.vcs.hgGetTagsList(repodir), - self.vcs.hgGetBranchesList(repodir), - self.vcs.hgGetBookmarksList(repodir)) - if dlg.exec_() == QDialog.Accepted: - revision, noCommit, message, keyId, local, force = dlg.getData() - - args = self.vcs.initCommand("sign") - if noCommit: - args.append("--no-commit") - if message: - args.append("--message") - args.append(message) - if keyId: - args.append("--key") - args.append(keyId) - if local: - args.append("--local") - if force: - args.append("--force") - if revision: - args.append(revision) - - dia = HgDialog(self.tr('Sign Revision'), self.vcs) - res = dia.startProcess(args, repodir) - if res: - dia.exec_() + if revisions is None: + from .HgGpgSignDialog import HgGpgSignDialog + dlg = HgGpgSignDialog(self.vcs.hgGetTagsList(repodir), + self.vcs.hgGetBranchesList(repodir), + self.vcs.hgGetBookmarksList(repodir)) + if dlg.exec_() == QDialog.Accepted: + revision, noCommit, message, keyId, local, force = \ + dlg.getData() + if revision: + revisions = [revision] + else: + revisions = [] + else: + return + else: + noCommit = False + message = "" + keyId = "" + local = False + force = False + + args = self.vcs.initCommand("sign") + if noCommit: + args.append("--no-commit") + if message: + args.append("--message") + args.append(message) + if keyId: + args.append("--key") + args.append(keyId) + if local: + args.append("--local") + if force: + args.append("--force") + for rev in revisions: + args.append(rev) + + dia = HgDialog(self.tr('Sign Revision'), self.vcs) + res = dia.startProcess(args, repodir) + if res: + dia.exec_()
--- a/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py Sat Feb 11 10:57:25 2017 +0100 +++ b/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py Sat Feb 11 15:35:07 2017 +0100 @@ -17,12 +17,12 @@ import re import collections -from PyQt5.QtCore import pyqtSlot, Qt, QDate, QProcess, QTimer, QRegExp, \ - QSize, QPoint, QFileInfo +from PyQt5.QtCore import pyqtSlot, qVersion, Qt, QDate, QProcess, QTimer, \ + QRegExp, QSize, QPoint, QFileInfo from PyQt5.QtGui import QCursor, QColor, QPixmap, QPainter, QPen, QBrush, \ QIcon, QTextCursor from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QHeaderView, \ - QTreeWidgetItem, QApplication, QLineEdit, QMenu, QInputDialog + QTreeWidgetItem, QApplication, QLineEdit, QMenu, QInputDialog, QToolTip from E5Gui.E5Application import e5App from E5Gui import E5MessageBox, E5FileDialog @@ -73,6 +73,10 @@ super(HgLogBrowserDialog, self).__init__(parent) self.setupUi(self) + windowFlags = self.windowFlags() + windowFlags |= Qt.WindowContextHelpButtonHint + self.setWindowFlags(windowFlags) + self.mainSplitter.setSizes([300, 400]) self.mainSplitter.setStretchFactor(0, 1) self.mainSplitter.setStretchFactor(1, 2) @@ -238,6 +242,11 @@ Private method to initialize the actions menu. """ self.__actionsMenu = QMenu() + self.__actionsMenu.setTearOffEnabled(True) + if qVersion() >= "5.1.0": + self.__actionsMenu.setToolTipsVisible(True) + else: + self.__actionsMenu.hovered.connect(self.__actionsMenuHovered) self.__graftAct = self.__actionsMenu.addAction( UI.PixmapCache.getIcon("vcsGraft.png"), @@ -333,6 +342,19 @@ self.__actionsMenu.addSeparator() + self.__gpgSignAct = self.__actionsMenu.addAction( + UI.PixmapCache.getIcon("changesetSign.png"), + self.tr("Sign Revisions"), self.__gpgSignActTriggered) + self.__gpgSignAct.setToolTip(self.tr( + "Add a signature for the selected revisions")) + self.__gpgVerifyAct = self.__actionsMenu.addAction( + UI.PixmapCache.getIcon("changesetSignVerify.png"), + self.tr("Verify Signatures"), self.__gpgVerifyActTriggered) + self.__gpgVerifyAct.setToolTip(self.tr( + "Verify all signatures there may be for the selected revision")) + + self.__actionsMenu.addSeparator() + self.__stripAct = self.__actionsMenu.addAction( UI.PixmapCache.getIcon("fileDelete.png"), self.tr("Strip Changesets"), self.__stripActTriggered) @@ -351,8 +373,16 @@ UI.PixmapCache.getIcon("actionsToolButton.png")) self.actionsButton.setMenu(self.__actionsMenu) - # TODO: add action "Sign Revision" (>= 1 revs) (GPG extension) - # TODO: add action "Verify Signature" (1 rev) (GPG extension) + def __actionsMenuHovered(self, action): + """ + Private slot to show the tooltip for an action menu entry. + + @param action action to show tooltip for + @type QAction + """ + QToolTip.showText( + QCursor.pos(), action.toolTip(), + self.__actionsMenu, self.__actionsMenu.actionGeometry(action)) def __initData(self): """ @@ -1447,19 +1477,18 @@ # step 2: set the status of the graft action self.__graftAct.setEnabled(otherBranches > 0) - self.__mergeAct.setEnabled(len(self.logTree.selectedItems()) == 1) - self.__tagAct.setEnabled(len(self.logTree.selectedItems()) == 1) - self.__switchAct.setEnabled(len(self.logTree.selectedItems()) == 1) - self.__bookmarkAct.setEnabled( - len(self.logTree.selectedItems()) == 1) - self.__bookmarkMoveAct.setEnabled( - len(self.logTree.selectedItems()) == 1) + selectedItemsCount = len(self.logTree.selectedItems()) + self.__mergeAct.setEnabled(selectedItemsCount == 1) + self.__tagAct.setEnabled(selectedItemsCount == 1) + self.__switchAct.setEnabled(selectedItemsCount == 1) + self.__bookmarkAct.setEnabled(selectedItemsCount == 1) + self.__bookmarkMoveAct.setEnabled(selectedItemsCount == 1) if self.vcs.canPull(): self.__pullAct.setEnabled(True) self.__lfPullAct.setEnabled( self.vcs.isExtensionActive("largefiles") and - bool(self.logTree.selectedItems())) + selectedItemsCount > 0) self.__fetchAct.setEnabled( self.vcs.isExtensionActive("fetch")) else: @@ -1469,7 +1498,7 @@ if self.vcs.canPush(): self.__pushAct.setEnabled( - len(self.logTree.selectedItems()) == 1 and + selectedItemsCount == 1 and self.logTree.selectedItems()[0].text(self.PhaseColumn) == self.phases["draft"]) self.__pushAllAct.setEnabled(True) @@ -1479,10 +1508,17 @@ self.__stripAct.setEnabled( self.vcs.isExtensionActive("strip") and - len(self.logTree.selectedItems()) == 1) + selectedItemsCount == 1) self.__bundleAct.setEnabled(self.logTree.topLevelItemCount() > 0) + self.__gpgSignAct.setEnabled( + self.vcs.isExtensionActive("gpg") and + selectedItemsCount > 0) + self.__gpgVerifyAct.setEnabled( + self.vcs.isExtensionActive("gpg") and + selectedItemsCount == 1) + self.actionsButton.setEnabled(True) else: self.actionsButton.setEnabled(False) @@ -2209,6 +2245,32 @@ self.vcs.hgBundle(self.repodir, bundleData=bundleData) + @pyqtSlot() + def __gpgSignActTriggered(self): + """ + Private slot to sign the selected revisions. + """ + revs = [] + for itm in self.logTree.selectedItems(): + rev = itm.text(self.RevisionColumn).split(":", 1)[0].strip() + if rev: + revs.append(rev) + + if revs: + self.vcs.getExtensionObject("gpg").hgGpgSign( + self.repodir, revisions=revs) + + @pyqtSlot() + def __gpgVerifyActTriggered(self): + """ + Private slot to verify the signatures of a selected revisions. + """ + rev = self.logTree.selectedItems()[0].text(self.RevisionColumn)\ + .split(":", 1)[0].strip() + if rev: + self.vcs.getExtensionObject("gpg").hgGpgVerifySignatures( + self.repodir, rev=rev) + def __selectAllActTriggered(self, select=True): """ Private method to select or unselect all log entries.