Sat, 21 May 2011 16:17:31 +0200
Continued with support for Mercurial queues extension.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesDefineGuardsDialog.py Sat May 21 16:17:31 2011 +0200 @@ -0,0 +1,317 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2011 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to define guards for patches. +""" + +import os + +from PyQt4.QtCore import pyqtSlot, Qt, QProcess, QTimer +from PyQt4.QtGui import QDialog, QDialogButtonBox, QAbstractButton, QListWidgetItem + +from E5Gui import E5MessageBox + +from .Ui_HgQueuesDefineGuardsDialog import Ui_HgQueuesDefineGuardsDialog + +import Preferences +import UI.PixmapCache + + +class HgQueuesDefineGuardsDialog(QDialog, Ui_HgQueuesDefineGuardsDialog): + """ + Class implementing a dialog to define guards for patches. + """ + def __init__(self, vcs, patchesList, parent=None): + """ + Constructor + + @param vcs reference to the vcs object + @param patchesList list of patches (list of strings) + @param parent reference to the parent widget (QWidget) + """ + QDialog.__init__(self, parent) + self.setupUi(self) + + self.process = QProcess() + self.vcs = vcs + + self.__patches = patchesList[:] + self.patchSelector.addItems([""] + self.__patches) + + self.plusButton.setIcon(UI.PixmapCache.getIcon("plus.png")) + self.minusButton.setIcon(UI.PixmapCache.getIcon("minus.png")) + + self.__dirtyList = False + self.__currentPatch = "" + + def closeEvent(self, e): + """ + Private slot implementing a close event handler. + + @param e close event (QCloseEvent) + """ + if self.process is not None and \ + self.process.state() != QProcess.NotRunning: + self.process.terminate() + QTimer.singleShot(2000, self.process.kill) + self.process.waitForFinished(3000) + + if self.__dirtyList: + res = E5MessageBox.question(self, + self.trUtf8("Unsaved Changes"), + self.trUtf8("""The guards list has been changed.""" + """ Shall the changes be applied?"""), + E5MessageBox.StandardButtons( + E5MessageBox.Apply | \ + E5MessageBox.Discard), + E5MessageBox.Apply) + if res == E5MessageBox.Apply: + self.__applyGuards() + else: + self.__dirtyList = False + + e.accept() + + def start(self, path): + """ + Public slot to start the list command. + + @param path name of directory to be listed (string) + """ + dname, fname = self.vcs.splitPath(path) + + # find the root of the repo + repodir = dname + while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): + repodir = os.path.dirname(repodir) + if repodir == os.sep: + return + + self.__repodir = repodir + self.on_patchSelector_activated("") + + def __getGuards(self): + """ + Private method to get a list of all guards defined. + + @return list of guards (list of strings) + """ + guardsList = [] + + ioEncoding = Preferences.getSystem("IOEncoding") + process = QProcess() + args = [] + args.append("qselect") + args.append("--series") + + process.setWorkingDirectory(self.__repodir) + process.start('hg', args) + procStarted = process.waitForStarted() + if procStarted: + finished = process.waitForFinished(30000) + if finished and process.exitCode() == 0: + output = \ + str(process.readAllStandardOutput(), ioEncoding, 'replace') + for guard in output.splitlines(): + guard = guard.strip()[1:] + if guard not in guardsList: + guardsList.append(guard) + + return sorted(guardsList) + + @pyqtSlot(str) + def on_patchSelector_activated(self, patch): + """ + Private slot to get the list of guards defined for the given patch name. + + @param patch selected patch name (empty for current patch) + """ + if self.__dirtyList: + res = E5MessageBox.question(self, + self.trUtf8("Unsaved Changes"), + self.trUtf8("""The guards list has been changed.""" + """ Shall the changes be applied?"""), + E5MessageBox.StandardButtons( + E5MessageBox.Apply | \ + E5MessageBox.Discard), + E5MessageBox.Apply) + if res == E5MessageBox.Apply: + self.__applyGuards() + else: + self.__dirtyList = False + + self.guardsList.clear() + self.patchNameLabel.setText("") + + self.guardCombo.clear() + guardsList = self.__getGuards() + self.guardCombo.addItems(guardsList) + self.guardCombo.setEditText("") + + ioEncoding = Preferences.getSystem("IOEncoding") + process = QProcess() + args = [] + args.append("qguard") + if patch: + args.append(patch) + + process.setWorkingDirectory(self.__repodir) + process.start('hg', args) + procStarted = process.waitForStarted() + if procStarted: + finished = process.waitForFinished(30000) + if finished and process.exitCode() == 0: + output = \ + str(process.readAllStandardOutput(), ioEncoding, 'replace').strip() + if output: + patchName, guards = output.split(":", 1) + self.patchNameLabel.setText(patchName) + guardsList = guards.strip().split() + for guard in guardsList: + if guard.startswith("+"): + icon = UI.PixmapCache.getIcon("plus.png") + guard = guard[1:] + sign = "+" + elif guard.startswith("-"): + icon = UI.PixmapCache.getIcon("minus.png") + guard = guard[1:] + sign = "-" + else: + continue + itm = QListWidgetItem(icon, guard, self.guardsList) + itm.setData(Qt.UserRole, sign) + + self.on_guardsList_itemSelectionChanged() + + @pyqtSlot() + def on_guardsList_itemSelectionChanged(self): + """ + Private slot to handle changes of the selection of guards. + """ + self.removeButton.setEnabled( + len(self.guardsList.selectedItems()) > 0) + + def __getGuard(self, guard): + """ + Private method to get a reference to a named guard. + + @param guard name of the guard (string) + @return reference to the guard item (QListWidgetItem) + """ + items = self.guardsList.findItems(guard, Qt.MatchCaseSensitive) + if items: + return items[0] + else: + return None + + @pyqtSlot(str) + def on_guardCombo_editTextChanged(self, txt): + """ + Private slot to handle changes of the text of the guard combo. + + @param txt contents of the guard combo line edit (string) + """ + self.addButton.setEnabled(txt != "") + + @pyqtSlot() + def on_addButton_clicked(self): + """ + Private slot to add a guard definition to the list or change it. + """ + guard = self.guardCombo.currentText() + if self.plusButton.isChecked(): + sign = "+" + icon = UI.PixmapCache.getIcon("plus.png") + else: + sign = "-" + icon = UI.PixmapCache.getIcon("minus.png") + + guardItem = self.__getGuard(guard) + if guardItem: + # guard already exists, remove it first + row = self.guardsList.row(guardItem) + itm = self.guardsList.takeItem(row) + del itm + + itm = QListWidgetItem(icon, guard, self.guardsList) + itm.setData(Qt.UserRole, sign) + self.guardsList.sortItems() + + self.__dirtyList = True + + @pyqtSlot() + def on_removeButton_clicked(self): + """ + Private slot to remove guard definitions from the list. + """ + res = E5MessageBox.yesNo(self, + self.trUtf8("Remove Guards"), + self.trUtf8("""Do you really want to remove the selected guards?""")) + if res: + for guardItem in self.guardsList.selectedItems(): + row = self.guardsList.row(guardItem) + itm = self.guardsList.takeItem(row) + del itm + + self.__dirtyList = True + + @pyqtSlot(QAbstractButton) + def on_buttonBox_clicked(self, button): + """ + Private slot called by a button of the button box clicked. + + @param button button that was clicked (QAbstractButton) + """ + if button == self.buttonBox.button(QDialogButtonBox.Apply): + self.__applyGuards() + elif button == self.buttonBox.button(QDialogButtonBox.Close): + self.close() + + @pyqtSlot() + def __applyGuards(self): + """ + Private slot to apply the defined guards to the current patch. + """ + if self.__dirtyList: + guardsList = [] + for row in range(self.guardsList.count()): + itm = self.guardsList.item(row) + guard = itm.data(Qt.UserRole) + itm.text() + guardsList.append(guard) + + ioEncoding = Preferences.getSystem("IOEncoding") + process = QProcess() + args = [] + args.append("qguard") + args.append(self.patchNameLabel.text()) + if guardsList: + args.append("--") + args.extend(guardsList) + else: + args.append("--none") + + process.setWorkingDirectory(self.__repodir) + process.start('hg', args) + procStarted = process.waitForStarted() + if procStarted: + finished = process.waitForFinished(30000) + if finished: + if process.exitCode() == 0: + self.__dirtyList = False + self.on_patchSelector_activated(self.patchNameLabel.text()) + else: + error = \ + str(process.readAllStandardError(), ioEncoding, 'replace') + E5MessageBox.warning(self, + self.trUtf8("Apply Guard Definitions"), + self.trUtf8("""<p>The defined guards could not be""" + """ applied.</p><p>Reason: {0}</p>""")\ + .format(error)) + + else: + E5MessageBox.warning(self, + self.trUtf8("Apply Guard Definitions"), + self.trUtf8("""The Mercurial process did not finish in time."""))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesDefineGuardsDialog.ui Sat May 21 16:17:31 2011 +0200 @@ -0,0 +1,204 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>HgQueuesDefineGuardsDialog</class> + <widget class="QDialog" name="HgQueuesDefineGuardsDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>434</height> + </rect> + </property> + <property name="windowTitle"> + <string>Define Guards</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Select patch (leave empty for current patch):</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="patchSelector"> + <property name="toolTip"> + <string>Select the patch to show the guards of</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Patch:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="patchNameLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Shows the name of the patch</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QListWidget" name="guardsList"> + <property name="toolTip"> + <string>This shows the list of guards to be defined for the selected patch</string> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::ExtendedSelection</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QRadioButton" name="plusButton"> + <property name="toolTip"> + <string>Select to define a positive guard</string> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="minusButton"> + <property name="toolTip"> + <string>Select to define a negative guard</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="guardCombo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Enter the guard name</string> + </property> + <property name="editable"> + <bool>true</bool> + </property> + <property name="insertPolicy"> + <enum>QComboBox::InsertAlphabetically</enum> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="addButton"> + <property name="toolTip"> + <string>Press to add the guard to the list or change it</string> + </property> + <property name="text"> + <string>Add/Change</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QPushButton" name="removeButton"> + <property name="toolTip"> + <string>Press to remove the selected guards from the list</string> + </property> + <property name="text"> + <string>Remove</string> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Apply|QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>patchSelector</tabstop> + <tabstop>guardsList</tabstop> + <tabstop>plusButton</tabstop> + <tabstop>minusButton</tabstop> + <tabstop>guardCombo</tabstop> + <tabstop>addButton</tabstop> + <tabstop>removeButton</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>HgQueuesDefineGuardsDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>222</x> + <y>419</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>HgQueuesDefineGuardsDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>290</x> + <y>425</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListAllGuardsDialog.py Sat May 21 16:17:31 2011 +0200 @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2011 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to show all guards for all patches. +""" + +import os + +from PyQt4.QtCore import QProcess, QTimer +from PyQt4.QtGui import QDialog, QTreeWidgetItem + +from .Ui_HgQueuesListAllGuardsDialog import Ui_HgQueuesListAllGuardsDialog + +import Preferences +import UI.PixmapCache + + +class HgQueuesListAllGuardsDialog(QDialog, Ui_HgQueuesListAllGuardsDialog): + """ + Class implementing a dialog to show all guards for all patches. + """ + def __init__(self, vcs, parent=None): + """ + Constructor + + @param parent reference to the parent widget (QWidget) + """ + QDialog.__init__(self, parent) + self.setupUi(self) + + self.process = QProcess() + self.vcs = vcs + + def closeEvent(self, e): + """ + Private slot implementing a close event handler. + + @param e close event (QCloseEvent) + """ + if self.process is not None and \ + self.process.state() != QProcess.NotRunning: + self.process.terminate() + QTimer.singleShot(2000, self.process.kill) + self.process.waitForFinished(3000) + + e.accept() + + def start(self, path): + """ + Public slot to start the list command. + + @param path name of directory to be listed (string) + """ + dname, fname = self.vcs.splitPath(path) + + # find the root of the repo + repodir = dname + while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): + repodir = os.path.dirname(repodir) + if repodir == os.sep: + return + + + ioEncoding = Preferences.getSystem("IOEncoding") + process = QProcess() + args = [] + args.append("qguard") + args.append("--list") + + 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') + if output: + guardsDict = {} + for line in output.splitlines(): + if line: + patchName, guards = line.strip().split(":", 1) + guardsDict[patchName] = guards.strip().split() + for patchName in sorted(guardsDict.keys()): + patchItm = QTreeWidgetItem(self.guardsTree, [patchName]) + patchItm.setExpanded(True) + for guard in guardsDict[patchName]: + if guard.startswith("+"): + icon = UI.PixmapCache.getIcon("plus.png") + guard = guard[1:] + elif guard.startswith("-"): + icon = UI.PixmapCache.getIcon("minus.png") + guard = guard[1:] + else: + icon = None + guard = self.trUtf8("Unguarded") + itm = QTreeWidgetItem(patchItm, [guard]) + if icon: + itm.setIcon(0, icon) + else: + QTreeWidgetItem(self.guardsTree, [self.trUtf8("no patches found")])
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListAllGuardsDialog.ui Sat May 21 16:17:31 2011 +0200 @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>HgQueuesListAllGuardsDialog</class> + <widget class="QDialog" name="HgQueuesListAllGuardsDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>400</height> + </rect> + </property> + <property name="windowTitle"> + <string>List All Guards</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTreeWidget" name="guardsTree"> + <property name="toolTip"> + <string>Show all guards of all patches</string> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::NoSelection</enum> + </property> + <property name="headerHidden"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string notr="true">1</string> + </property> + </column> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>guardsTree</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>HgQueuesListAllGuardsDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>HgQueuesListAllGuardsDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListGuardsDialog.py Sat May 21 16:17:31 2011 +0200 @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2011 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to show the guards of a selected patch. +""" + +import os + +from PyQt4.QtCore import pyqtSlot, QProcess, QTimer +from PyQt4.QtGui import QDialog, QListWidgetItem + +from .Ui_HgQueuesListGuardsDialog import Ui_HgQueuesListGuardsDialog + +import Preferences +import UI.PixmapCache + + +class HgQueuesListGuardsDialog(QDialog, Ui_HgQueuesListGuardsDialog): + """ + Class implementing a dialog to show the guards of a selected patch. + """ + def __init__(self, vcs, patchesList, parent=None): + """ + Constructor + + @param vcs reference to the vcs object + @param patchesList list of patches (list of strings) + @param parent reference to the parent widget (QWidget) + """ + QDialog.__init__(self, parent) + self.setupUi(self) + + self.process = QProcess() + self.vcs = vcs + + self.patchSelector.addItems([""] + patchesList) + + def closeEvent(self, e): + """ + Private slot implementing a close event handler. + + @param e close event (QCloseEvent) + """ + if self.process is not None and \ + self.process.state() != QProcess.NotRunning: + self.process.terminate() + QTimer.singleShot(2000, self.process.kill) + self.process.waitForFinished(3000) + + e.accept() + + def start(self, path): + """ + Public slot to start the list command. + + @param path name of directory to be listed (string) + """ + dname, fname = self.vcs.splitPath(path) + + # find the root of the repo + repodir = dname + while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): + repodir = os.path.dirname(repodir) + if repodir == os.sep: + return + + self.__repodir = repodir + self.on_patchSelector_activated("") + + @pyqtSlot(str) + def on_patchSelector_activated(self, patch): + """ + Private slot to get the list of guards for the given patch name. + + @param patch selected patch name (empty for current patch) + """ + self.guardsList.clear() + self.patchNameLabel.setText("") + + ioEncoding = Preferences.getSystem("IOEncoding") + process = QProcess() + args = [] + args.append("qguard") + if patch: + args.append(patch) + + process.setWorkingDirectory(self.__repodir) + process.start('hg', args) + procStarted = process.waitForStarted() + if procStarted: + finished = process.waitForFinished(30000) + if finished and process.exitCode() == 0: + output = \ + str(process.readAllStandardOutput(), ioEncoding, 'replace').strip() + if output: + patchName, guards = output.split(":", 1) + self.patchNameLabel.setText(patchName) + guardsList = guards.strip().split() + for guard in guardsList: + if guard.startswith("+"): + icon = UI.PixmapCache.getIcon("plus.png") + guard = guard[1:] + elif guard.startswith("-"): + icon = UI.PixmapCache.getIcon("minus.png") + guard = guard[1:] + else: + icon = None + guard = self.trUtf8("Unguarded") + itm = QListWidgetItem(guard, self.guardsList) + if icon: + itm.setIcon(icon)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListGuardsDialog.ui Sat May 21 16:17:31 2011 +0200 @@ -0,0 +1,130 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>HgQueuesListGuardsDialog</class> + <widget class="QDialog" name="HgQueuesListGuardsDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>400</height> + </rect> + </property> + <property name="windowTitle"> + <string>List Guards</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Select patch (leave empty for current patch):</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="patchSelector"> + <property name="toolTip"> + <string>Select the patch to show the guards of</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Patch:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="patchNameLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Shows the name of the patch</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QListWidget" name="guardsList"> + <property name="toolTip"> + <string>This shows the list of guards defined for the selected patch</string> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>patchSelector</tabstop> + <tabstop>guardsList</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>HgQueuesListGuardsDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>HgQueuesListGuardsDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui>
--- a/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/ProjectHelper.py Fri May 20 19:07:30 2011 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/ProjectHelper.py Sat May 21 16:17:31 2011 +0200 @@ -189,6 +189,7 @@ self.__initPushPopActions() self.__initPushPopForceActions() + self.__initGuardsActions() def __initPushPopActions(self): """ @@ -394,6 +395,107 @@ self.hgQueueGotoForceAct.triggered[()].connect(self.__hgQueueGotoPatchForced) self.actions.append(self.hgQueueGotoForceAct) + + def __initGuardsActions(self): + """ + Public method to generate the guards action objects. + """ + self.hgQueueDefineGuardsAct = E5Action(self.trUtf8('Define Guards'), + self.trUtf8('Define Guards...'), + 0, 0, self, 'mercurial_queues_guards_define') + self.hgQueueDefineGuardsAct.setStatusTip(self.trUtf8( + 'Define guards for the current or a named patch' + )) + self.hgQueueDefineGuardsAct.setWhatsThis(self.trUtf8( + """<b>Define Guards</b>""" + """<p>This opens a dialog to define guards for the current""" + """ or a named patch.</p>""" + )) + self.hgQueueDefineGuardsAct.triggered[()].connect(self.__hgQueueGuardsDefine) + self.actions.append(self.hgQueueDefineGuardsAct) + + self.hgQueueDropAllGuardsAct = E5Action(self.trUtf8('Drop All Guards'), + self.trUtf8('Drop All Guards...'), + 0, 0, self, 'mercurial_queues_guards_drop_all') + self.hgQueueDropAllGuardsAct.setStatusTip(self.trUtf8( + 'Drop all guards of the current or a named patch' + )) + self.hgQueueDropAllGuardsAct.setWhatsThis(self.trUtf8( + """<b>Drop All Guards</b>""" + """<p>This drops all guards of the current or a named patch.</p>""" + )) + self.hgQueueDropAllGuardsAct.triggered[()].connect(self.__hgQueueGuardsDropAll) + self.actions.append(self.hgQueueDropAllGuardsAct) + + self.hgQueueListGuardsAct = E5Action(self.trUtf8('List Guards'), + self.trUtf8('List Guards...'), + 0, 0, self, 'mercurial_queues_guards_list') + self.hgQueueListGuardsAct.setStatusTip(self.trUtf8( + 'List guards of the current or a named patch' + )) + self.hgQueueListGuardsAct.setWhatsThis(self.trUtf8( + """<b>List Guards</b>""" + """<p>This lists the guards of the current or a named patch.</p>""" + )) + self.hgQueueListGuardsAct.triggered[()].connect(self.__hgQueueGuardsList) + self.actions.append(self.hgQueueListGuardsAct) + + self.hgQueueListAllGuardsAct = E5Action(self.trUtf8('List All Guards'), + self.trUtf8('List All Guards...'), + 0, 0, self, 'mercurial_queues_guards_list_all') + self.hgQueueListAllGuardsAct.setStatusTip(self.trUtf8( + 'List all guards of all patches' + )) + self.hgQueueListAllGuardsAct.setWhatsThis(self.trUtf8( + """<b>List All Guards</b>""" + """<p>This lists all guards of all patches.</p>""" + )) + self.hgQueueListAllGuardsAct.triggered[()].connect(self.__hgQueueGuardsListAll) + self.actions.append(self.hgQueueListAllGuardsAct) + + self.hgQueueActivateGuardsAct = E5Action(self.trUtf8('Set Active Guards'), + self.trUtf8('Set Active Guards...'), + 0, 0, self, 'mercurial_queues_guards_set_active') + self.hgQueueActivateGuardsAct.setStatusTip(self.trUtf8( + 'Set the list of active guards' + )) + self.hgQueueActivateGuardsAct.setWhatsThis(self.trUtf8( + """<b>Set Active Guards</b>""" + """<p>This opens a dialog to set the active guards.</p>""" + )) + self.hgQueueActivateGuardsAct.triggered[()].connect(self.__hgQueueGuardsSetActive) + self.actions.append(self.hgQueueActivateGuardsAct) + + self.hgQueueDeactivateGuardsAct = E5Action(self.trUtf8('Deactivate Guards'), + self.trUtf8('Deactivate Guards...'), + 0, 0, self, 'mercurial_queues_guards_deactivate') + self.hgQueueDeactivateGuardsAct.setStatusTip(self.trUtf8( + 'Deactivate all active guards' + )) + self.hgQueueDeactivateGuardsAct.setWhatsThis(self.trUtf8( + """<b>Deactivate Guards</b>""" + """<p>This deactivates all active guards.</p>""" + )) + self.hgQueueDeactivateGuardsAct.triggered[()].connect( + self.__hgQueueGuardsDeactivate) + self.actions.append(self.hgQueueDeactivateGuardsAct) + + self.hgQueueIdentifyActiveGuardsAct = E5Action( + self.trUtf8('Identify Active Guards'), + self.trUtf8('Identify Active Guards...'), + 0, 0, self, 'mercurial_queues_guards_identify_active') + self.hgQueueIdentifyActiveGuardsAct.setStatusTip(self.trUtf8( + 'Show a list of active guards and affected patches' + )) + self.hgQueueIdentifyActiveGuardsAct.setWhatsThis(self.trUtf8( + """<b>Identify Active Guards</b>""" + """<p>This opens a dialog show a list of active guards and the""" + """ patches directly affected by them.</p>""" + )) + self.hgQueueIdentifyActiveGuardsAct.triggered[()].connect( + self.__hgQueueGuardsIdentifyActive) + self.actions.append(self.hgQueueIdentifyActiveGuardsAct) + def initMenu(self, mainMenu): """ Public method to generate the VCS menu. @@ -425,6 +527,18 @@ pushPopForceMenu.addSeparator() pushPopForceMenu.addAction(self.hgQueueGotoForceAct) + guardsMenu = QMenu(self.trUtf8("Guards"), menu) + guardsMenu.addAction(self.hgQueueDefineGuardsAct) + guardsMenu.addAction(self.hgQueueDropAllGuardsAct) + guardsMenu.addSeparator() + guardsMenu.addAction(self.hgQueueListGuardsAct) + guardsMenu.addAction(self.hgQueueListAllGuardsAct) + guardsMenu.addSeparator() + guardsMenu.addAction(self.hgQueueActivateGuardsAct) + guardsMenu.addAction(self.hgQueueDeactivateGuardsAct) + guardsMenu.addSeparator() + guardsMenu.addAction(self.hgQueueIdentifyActiveGuardsAct) + menu.addAction(self.hgQueueNewAct) menu.addAction(self.hgQueueRefreshAct) menu.addAction(self.hgQueueRefreshMessageAct) @@ -442,6 +556,8 @@ menu.addAction(self.hgQueueDeleteAct) menu.addSeparator() menu.addAction(self.hgQueueFoldAct) + menu.addSeparator() + menu.addMenu(guardsMenu) return menu @@ -636,3 +752,49 @@ """ self.vcs.getExtensionObject("mq")\ .hgQueueFoldUnappliedPatches(self.project.getProjectPath()) + + def __hgQueueGuardsDefine(self): + """ + Private slot used to define guards for the current or a named patch. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueueGuardsDefine(self.project.getProjectPath()) + + def __hgQueueGuardsDropAll(self): + """ + Private slot used to drop all guards of the current or a named patch. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueueGuardsDropAll(self.project.getProjectPath()) + + def __hgQueueGuardsList(self): + """ + Private slot used to list the guards for the current or a named patch. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueueGuardsList(self.project.getProjectPath()) + + def __hgQueueGuardsListAll(self): + """ + Private slot used to list all guards of all patches. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueueGuardsListAll(self.project.getProjectPath()) + + def __hgQueueGuardsSetActive(self): + """ + Private slot used to set the active guards. + """ + pass + + def __hgQueueGuardsDeactivate(self): + """ + Private slot used to deactivate all active guards. + """ + pass + + def __hgQueueGuardsIdentifyActive(self): + """ + Private slot used to list all active guards and their patches. + """ + pass
--- a/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/queues.py Fri May 20 19:07:30 2011 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/queues.py Sat May 21 16:17:31 2011 +0200 @@ -21,6 +21,9 @@ from .HgQueuesRenamePatchDialog import HgQueuesRenamePatchDialog from .HgQueuesFoldDialog import HgQueuesFoldDialog from .HgQueuesHeaderDialog import HgQueuesHeaderDialog +from .HgQueuesListGuardsDialog import HgQueuesListGuardsDialog +from .HgQueuesListAllGuardsDialog import HgQueuesListAllGuardsDialog +from .HgQueuesDefineGuardsDialog import HgQueuesDefineGuardsDialog import Preferences @@ -47,6 +50,10 @@ self.qdiffDialog = None self.qheaderDialog = None + self.queuesListDialog = None + self.queuesListGuardsDialog = None + self.queuesListAllGuardsDialog = None + self.queuesDefineGuardsDialog = None def shutdown(self): """ @@ -56,6 +63,14 @@ self.qdiffDialog.close() if self.qheaderDialog is not None: self.qheaderDialog.close() + if self.queuesListDialog is not None: + self.queuesListDialog.close() + if self.queuesListGuardsDialog is not None: + self.queuesListGuardsDialog.close() + if self.queuesListAllGuardsDialog is not None: + self.queuesListAllGuardsDialog.close() + if self.queuesDefineGuardsDialog is not None: + self.queuesDefineGuardsDialog.close() def __getPatchesList(self, repodir, listType, withSummary=False): """ @@ -471,3 +486,103 @@ E5MessageBox.information(None, self.trUtf8("Fold Patches"), self.trUtf8("""No patches available to be folded.""")) + + def hgQueueGuardsList(self, name): + """ + Public method to list the guards for the current or a named 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 + + patchnames = sorted( + self.__getPatchesList(repodir, Queues.SERIES_LIST)) + if patchnames: + self.queuesListGuardsDialog = HgQueuesListGuardsDialog(self.vcs, patchnames) + self.queuesListGuardsDialog.show() + self.queuesListGuardsDialog.start(name) + else: + E5MessageBox.information(None, + self.trUtf8("List Guards"), + self.trUtf8("""No patches available to list guards for.""")) + + def hgQueueGuardsListAll(self, name): + """ + Public method to list all guards of all patches. + + @param name file/directory name (string) + """ + self.queuesListAllGuardsDialog = HgQueuesListAllGuardsDialog(self.vcs) + self.queuesListAllGuardsDialog.show() + self.queuesListAllGuardsDialog.start(name) + + def hgQueueGuardsDefine(self, name): + """ + Public method to define guards for the current or a named 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 + + patchnames = sorted( + self.__getPatchesList(repodir, Queues.SERIES_LIST)) + if patchnames: + self.queuesDefineGuardsDialog = HgQueuesDefineGuardsDialog( + self.vcs, patchnames) + self.queuesDefineGuardsDialog.show() + self.queuesDefineGuardsDialog.start(name) + else: + E5MessageBox.information(None, + self.trUtf8("Define Guards"), + self.trUtf8("""No patches available to define guards for.""")) + + def hgQueueGuardsDropAll(self, name): + """ + Public method to drop all guards of the current or a named 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 + + patchnames = sorted( + self.__getPatchesList(repodir, Queues.SERIES_LIST)) + if patchnames: + patch, ok = QInputDialog.getItem( + None, + self.trUtf8("Drop All Guards"), + self.trUtf8("Select the patch to drop guards for" + " (leave empty for the current patch):"), + [""] + patchnames, + 0, False) + if ok: + process = QProcess() + args = [] + args.append("qguard") + if patch: + args.append(patch) + args.append("--none") + + process.setWorkingDirectory(repodir) + process.start('hg', args) + procStarted = process.waitForStarted() + if procStarted: + process.waitForFinished(30000) + else: + E5MessageBox.information(None, + self.trUtf8("Drop All Guards"), + self.trUtf8("""No patches available to define guards for."""))
--- a/eric5.e4p Fri May 20 19:07:30 2011 +0200 +++ b/eric5.e4p Sat May 21 16:17:31 2011 +0200 @@ -891,6 +891,9 @@ <Source>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesRenamePatchDialog.py</Source> <Source>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesFoldDialog.py</Source> <Source>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesHeaderDialog.py</Source> + <Source>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListGuardsDialog.py</Source> + <Source>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListAllGuardsDialog.py</Source> + <Source>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesDefineGuardsDialog.py</Source> </Sources> <Forms> <Form>PyUnit/UnittestDialog.ui</Form> @@ -1139,6 +1142,9 @@ <Form>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesRenamePatchDialog.ui</Form> <Form>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesFoldDialog.ui</Form> <Form>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesHeaderDialog.ui</Form> + <Form>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListGuardsDialog.ui</Form> + <Form>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListAllGuardsDialog.ui</Form> + <Form>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesDefineGuardsDialog.ui</Form> </Forms> <Translations> <Translation>i18n/eric5_cs.qm</Translation>