Sat, 14 May 2011 20:00:13 +0200
Started with support for Mercurial queues extension.
--- a/Dictionaries/words.dic Fri May 13 20:23:42 2011 +0200 +++ b/Dictionaries/words.dic Sat May 14 20:00:13 2011 +0200 @@ -2,4 +2,5 @@ detlev offenbachs Eric5 -IDE \ No newline at end of file +IDE +unapplied \ No newline at end of file
--- a/Plugins/VcsPlugins/vcsMercurial/HgDiffDialog.py Fri May 13 20:23:42 2011 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/HgDiffDialog.py Sat May 14 20:00:13 2011 +0200 @@ -84,13 +84,14 @@ else: return str(version) - def start(self, fn, versions=None, bundle=None): + def start(self, fn, versions=None, bundle=None, qdiff=False): """ Public slot to start the hg diff command. @param fn filename to be diffed (string) @param versions list of versions to be diffed (list of up to 2 strings or None) @param bundle name of a bundle file (string) + @param qdiff flag indicating qdiff command shall be used (boolean) """ self.errorGroup.hide() self.inputGroup.show() @@ -103,34 +104,38 @@ self.paras = 0 args = [] - args.append('diff') - self.vcs.addArguments(args, self.vcs.options['global']) - self.vcs.addArguments(args, self.vcs.options['diff']) - - if bundle: - args.append('--repository') - args.append(bundle) - elif self.vcs.bundleFile and os.path.exists(self.vcs.bundleFile): - args.append('--repository') - args.append(self.vcs.bundleFile) - - if versions is not None: - self.raise_() - self.activateWindow() + if qdiff: + args.append('qdiff') + self.setWindowTitle(self.trUtf8("Patch Contents")) + else: + args.append('diff') + self.vcs.addArguments(args, self.vcs.options['global']) + self.vcs.addArguments(args, self.vcs.options['diff']) + + if bundle: + args.append('--repository') + args.append(bundle) + elif self.vcs.bundleFile and os.path.exists(self.vcs.bundleFile): + args.append('--repository') + args.append(self.vcs.bundleFile) - rev1 = self.__getVersionArg(versions[0]) - rev2 = None - if len(versions) == 2: - rev2 = self.__getVersionArg(versions[1]) - - if rev1 is not None or rev2 is not None: - args.append('-r') - if rev1 is not None and rev2 is not None: - args.append('{0}:{1}'.format(rev1, rev2)) - elif rev2 is None: - args.append(rev1) - elif rev1 is None: - args.append(':{0}'.format(rev2)) + if versions is not None: + self.raise_() + self.activateWindow() + + rev1 = self.__getVersionArg(versions[0]) + rev2 = None + if len(versions) == 2: + rev2 = self.__getVersionArg(versions[1]) + + if rev1 is not None or rev2 is not None: + args.append('-r') + if rev1 is not None and rev2 is not None: + args.append('{0}:{1}'.format(rev1, rev2)) + elif rev2 is None: + args.append(rev1) + elif rev1 is None: + args.append(':{0}'.format(rev2)) if isinstance(fn, list): dname, fnames = self.vcs.splitPathList(fn)
--- a/Plugins/VcsPlugins/vcsMercurial/ProjectHelper.py Fri May 13 20:23:42 2011 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/ProjectHelper.py Sat May 14 20:00:13 2011 +0200 @@ -17,6 +17,7 @@ from VCS.ProjectHelper import VcsProjectHelper from .BookmarksExtension.ProjectHelper import BookmarksProjectHelper +from .QueuesExtension.ProjectHelper import QueuesProjectHelper from E5Gui.E5Action import E5Action @@ -42,6 +43,7 @@ # instantiate the extensions self.__extensions = { "bookmarks" : BookmarksProjectHelper(), + "mq" : QueuesProjectHelper(), } def setObjects(self, vcsObject, projectObject):
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListDialog.py Sat May 14 20:00:13 2011 +0200 @@ -0,0 +1,355 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2011 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to show a list of applied and unapplied patches. +""" + +import os + +from PyQt4.QtCore import pyqtSlot, QProcess, Qt, QTimer +from PyQt4.QtGui import QDialog, QDialogButtonBox, QHeaderView, QTreeWidgetItem, \ + QLineEdit + +from E5Gui import E5MessageBox + +from .Ui_HgQueuesListDialog import Ui_HgQueuesListDialog + +import Preferences + + +class HgQueuesListDialog(QDialog, Ui_HgQueuesListDialog): + """ + Class implementing a dialog to show a list of applied and unapplied patches. + """ + def __init__(self, vcs, parent=None): + """ + Constructor + + @param vcs reference to the vcs object + @param parent parent widget (QWidget) + """ + QDialog.__init__(self, parent) + self.setupUi(self) + + self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) + self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) + + self.process = QProcess() + self.vcs = vcs + + self.patchesList.header().setSortIndicator(0, Qt.AscendingOrder) + + self.process.finished.connect(self.__procFinished) + self.process.readyReadStandardOutput.connect(self.__readStdout) + self.process.readyReadStandardError.connect(self.__readStderr) + + 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) + """ + self.errorGroup.hide() + + self.intercept = False + self.activateWindow() + + 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.__patchesCount = 0 + self.__getApplied() + + def __getApplied(self): + """ + Private slot to get the list of applied patches. + """ + self.__mode = "qapplied" + + args = [] + args.append('qapplied') + args.append('--summary') + + self.process.kill() + self.process.setWorkingDirectory(self.__repodir) + + self.process.start('hg', args) + procStarted = self.process.waitForStarted() + if not procStarted: + self.inputGroup.setEnabled(False) + self.inputGroup.hide() + E5MessageBox.critical(self, + self.trUtf8('Process Generation Error'), + self.trUtf8( + 'The process {0} could not be started. ' + 'Ensure, that it is in the search path.' + ).format('hg')) + else: + self.inputGroup.setEnabled(True) + self.inputGroup.show() + + def __getUnapplied(self): + """ + Private slot to get the list of unapplied patches. + """ + self.__mode = "qunapplied" + + args = [] + args.append('qunapplied') + args.append('--summary') + + self.process.kill() + self.process.setWorkingDirectory(self.__repodir) + + self.process.start('hg', args) + procStarted = self.process.waitForStarted() + if not procStarted: + self.inputGroup.setEnabled(False) + self.inputGroup.hide() + E5MessageBox.critical(self, + self.trUtf8('Process Generation Error'), + self.trUtf8( + 'The process {0} could not be started. ' + 'Ensure, that it is in the search path.' + ).format('hg')) + else: + self.inputGroup.setEnabled(True) + self.inputGroup.show() + + def __getTop(self): + """ + Private slot to get patch at the top of the stack. + """ + self.__mode = "qtop" + + args = [] + args.append('qtop') + + self.process.kill() + self.process.setWorkingDirectory(self.__repodir) + + self.process.start('hg', args) + procStarted = self.process.waitForStarted() + if not procStarted: + self.inputGroup.setEnabled(False) + self.inputGroup.hide() + E5MessageBox.critical(self, + self.trUtf8('Process Generation Error'), + self.trUtf8( + 'The process {0} could not be started. ' + 'Ensure, that it is in the search path.' + ).format('hg')) + else: + self.inputGroup.setEnabled(True) + self.inputGroup.show() + + def __finish(self): + """ + Private slot called when the process finished or the user pressed the button. + """ + 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) + + self.inputGroup.setEnabled(False) + self.inputGroup.hide() + + self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) + self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) + self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) + self.buttonBox.button(QDialogButtonBox.Close).setFocus(Qt.OtherFocusReason) + + self.process = None + + if self.patchesList.topLevelItemCount() == 0: + # no bookmarks defined + self.__generateItem(self.trUtf8("no patches found"), "") + self.patchesList.doItemsLayout() + self.__resizeColumns() + self.__resort() + + 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.Close): + self.close() + elif button == self.buttonBox.button(QDialogButtonBox.Cancel): + self.__finish() + + def __procFinished(self, exitCode, exitStatus): + """ + Private slot connected to the finished signal. + + @param exitCode exit code of the process (integer) + @param exitStatus exit status of the process (QProcess.ExitStatus) + """ + if self.__mode == "qapplied": + self.__getUnapplied() + elif self.__mode == "qunapplied": + self.__getTop() + else: + self.__finish() + + def __resort(self): + """ + Private method to resort the tree. + """ + self.patchesList.sortItems(self.patchesList.sortColumn(), + self.patchesList.header().sortIndicatorOrder()) + + def __resizeColumns(self): + """ + Private method to resize the list columns. + """ + self.patchesList.header().resizeSections(QHeaderView.ResizeToContents) + self.patchesList.header().setStretchLastSection(True) + + def __generateItem(self, name, summary): + """ + Private method to generate a patch item in the list of patches. + + @param name name of the patch (string) + @param summary first line of the patch header (string) + """ + self.__patchesCount += 1 + itm = QTreeWidgetItem(self.patchesList, [ + "{0:>7}".format(self.__patchesCount), + name, + self.__mode == "qapplied" and \ + self.trUtf8("applied") or \ + self.trUtf8("not applied"), + summary + ]) + itm.setTextAlignment(0, Qt.AlignRight) + itm.setTextAlignment(2, Qt.AlignHCenter) + + def __markTopItem(self, name): + """ + Private slot to mark the top patch entry. + + @param name name of the patch (string) + """ + items = self.patchesList.findItems(name, Qt.MatchCaseSensitive, 1) + if items: + itm = items[0] + for column in range(itm.columnCount()): + font = itm.font(column) + font.setBold(True) + itm.setFont(column, font) + + def __readStdout(self): + """ + Private slot to handle the readyReadStdout signal. + + It reads the output of the process, formats it and inserts it into + the contents pane. + """ + self.process.setReadChannel(QProcess.StandardOutput) + + while self.process.canReadLine(): + s = str(self.process.readLine(), + Preferences.getSystem("IOEncoding"), + 'replace').strip() + if self.__mode == "qtop": + self.__markTopItem(s) + else: + l = s.split(": ", 1) + if len(l) == 1: + name, summary = l[0][:-1], "" + else: + name, summary = l[0], l[1] + self.__generateItem(name, summary) + + def __readStderr(self): + """ + Private slot to handle the readyReadStderr signal. + + It reads the error output of the process and inserts it into the + error pane. + """ + if self.process is not None: + self.errorGroup.show() + s = str(self.process.readAllStandardError(), + Preferences.getSystem("IOEncoding"), + 'replace') + self.errors.insertPlainText(s) + self.errors.ensureCursorVisible() + + def on_passwordCheckBox_toggled(self, isOn): + """ + Private slot to handle the password checkbox toggled. + + @param isOn flag indicating the status of the check box (boolean) + """ + if isOn: + self.input.setEchoMode(QLineEdit.Password) + else: + self.input.setEchoMode(QLineEdit.Normal) + + @pyqtSlot() + def on_sendButton_clicked(self): + """ + Private slot to send the input to the subversion process. + """ + input = self.input.text() + input += os.linesep + + if self.passwordCheckBox.isChecked(): + self.errors.insertPlainText(os.linesep) + self.errors.ensureCursorVisible() + else: + self.errors.insertPlainText(input) + self.errors.ensureCursorVisible() + + self.process.write(input) + + self.passwordCheckBox.setChecked(False) + self.input.clear() + + def on_input_returnPressed(self): + """ + Private slot to handle the press of the return key in the input field. + """ + self.intercept = True + self.on_sendButton_clicked() + + def keyPressEvent(self, evt): + """ + Protected slot to handle a key press event. + + @param evt the key press event (QKeyEvent) + """ + if self.intercept: + self.intercept = False + evt.accept() + return + QDialog.keyPressEvent(self, evt)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListDialog.ui Sat May 14 20:00:13 2011 +0200 @@ -0,0 +1,180 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>HgQueuesListDialog</class> + <widget class="QDialog" name="HgQueuesListDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>634</width> + <height>494</height> + </rect> + </property> + <property name="windowTitle"> + <string>List of Patches</string> + </property> + <property name="whatsThis"> + <string><b>List of Patches</b> +<p>This dialog shows a list of applied and unapplied patches.</p></string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout"> + <item> + <widget class="QTreeWidget" name="patchesList"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>2</verstretch> + </sizepolicy> + </property> + <property name="whatsThis"> + <string><b>Patches List</b> +<p>This shows a list of applied and unapplied patches.</p></string> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="itemsExpandable"> + <bool>false</bool> + </property> + <column> + <property name="text"> + <string notr="true">#</string> + </property> + <property name="toolTip"> + <string/> + </property> + <property name="textAlignment"> + <set>AlignLeft|AlignVCenter</set> + </property> + </column> + <column> + <property name="text"> + <string>Name</string> + </property> + </column> + <column> + <property name="text"> + <string>Status</string> + </property> + </column> + <column> + <property name="text"> + <string>Summary</string> + </property> + </column> + </widget> + </item> + <item> + <widget class="QGroupBox" name="errorGroup"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Errors</string> + </property> + <layout class="QVBoxLayout"> + <item> + <widget class="QTextEdit" name="errors"> + <property name="focusPolicy"> + <enum>Qt::NoFocus</enum> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="acceptRichText"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="inputGroup"> + <property name="title"> + <string>Input</string> + </property> + <layout class="QGridLayout"> + <item row="1" column="1"> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>327</width> + <height>29</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="2"> + <widget class="QPushButton" name="sendButton"> + <property name="toolTip"> + <string>Press to send the input to the hg process</string> + </property> + <property name="text"> + <string>&Send</string> + </property> + <property name="shortcut"> + <string>Alt+S</string> + </property> + </widget> + </item> + <item row="0" column="0" colspan="3"> + <widget class="QLineEdit" name="input"> + <property name="toolTip"> + <string>Enter data to be sent to the hg process</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QCheckBox" name="passwordCheckBox"> + <property name="toolTip"> + <string>Select to switch the input field to password mode</string> + </property> + <property name="text"> + <string>&Password Mode</string> + </property> + <property name="shortcut"> + <string>Alt+P</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <pixmapfunction>qPixmapFromMimeSource</pixmapfunction> + <tabstops> + <tabstop>input</tabstop> + <tabstop>passwordCheckBox</tabstop> + <tabstop>sendButton</tabstop> + </tabstops> + <resources/> + <connections/> +</ui>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesNewPatchDialog.py Sat May 14 20:00:13 2011 +0200 @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2011 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to get the data for a new patch. +""" + +from PyQt4.QtCore import pyqtSlot, QDate +from PyQt4.QtGui import QDialog, QDialogButtonBox + +from .Ui_HgQueuesNewPatchDialog import Ui_HgQueuesNewPatchDialog + + +class HgQueuesNewPatchDialog(QDialog, Ui_HgQueuesNewPatchDialog): + """ + Class implementing a dialog to get the data for a new patch. + """ + def __init__(self, parent=None): + """ + Constructor + + @param parent reference to the parent widget (QWidget) + """ + QDialog.__init__(self, parent) + self.setupUi(self) + + self.dateEdit.setDate(QDate.currentDate()) + + self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) + + def __updateUI(self): + """ + Private slot to update the UI. + """ + enable = self.nameEdit.text() != "" and \ + self.messageEdit.toPlainText() != "" + if self.userGroup.isChecked(): + enable = enable and \ + (self.currentUserCheckBox.isChecked() or \ + self.userEdit.text() != "") + + self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) + + @pyqtSlot(str) + def on_nameEdit_textChanged(self, txt): + """ + Private slot to handle changes of the patch name. + + @param txt text of the edit (string) + """ + self.__updateUI() + + @pyqtSlot() + def on_messageEdit_textChanged(self): + """ + Private slot to handle changes of the patch message. + + @param txt text of the edit (string) + """ + self.__updateUI() + + def getData(self): + """ + Public method to retrieve the entered data. + + @return tuple giving the patch name and message, a tuple giving a + flag indicating to set the user, a flag indicating to use the + current user and the user name and another tuple giving a flag + indicating to set the date, a flag indicating to use the + current date and the date (string, string, (boolean, boolean, string), + (boolean, boolean, string)) + """ + userData = (self.userGroup.isChecked(), + self.currentUserCheckBox.isChecked(), + self.userEdit.text()) + dateData = (self.dateGroup.isChecked(), + self.currentDateCheckBox.isChecked(), + self.dateEdit.date().toString("yyyy-MM-dd")) + return (self.nameEdit.text(), self.messageEdit.toPlainText(), + userData, dateData)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesNewPatchDialog.ui Sat May 14 20:00:13 2011 +0200 @@ -0,0 +1,276 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>HgQueuesNewPatchDialog</class> + <widget class="QDialog" name="HgQueuesNewPatchDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>350</height> + </rect> + </property> + <property name="windowTitle"> + <string>New Patch</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Name:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="nameEdit"> + <property name="toolTip"> + <string>Enter the patch name</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Message:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QPlainTextEdit" name="messageEdit"> + <property name="toolTip"> + <string>Enter the commit message for the patch</string> + </property> + <property name="tabChangesFocus"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="0" colspan="2"> + <widget class="QGroupBox" name="userGroup"> + <property name="toolTip"> + <string>Select to give user information</string> + </property> + <property name="title"> + <string>User</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0" colspan="2"> + <widget class="QCheckBox" name="currentUserCheckBox"> + <property name="toolTip"> + <string>Select to use the name of the current user</string> + </property> + <property name="text"> + <string>Use current user</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Username:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="userEdit"> + <property name="toolTip"> + <string>Enter the user name to be used for the patch</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QGroupBox" name="dateGroup"> + <property name="toolTip"> + <string>Select to give date information</string> + </property> + <property name="title"> + <string>Date</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0" colspan="3"> + <widget class="QCheckBox" name="currentDateCheckBox"> + <property name="toolTip"> + <string>Select to use the current date</string> + </property> + <property name="text"> + <string>Use current date</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Date:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QDateEdit" name="dateEdit"> + <property name="toolTip"> + <string>Enter the date to be used for the patch</string> + </property> + <property name="displayFormat"> + <string notr="true">yyyy-MM-dd</string> + </property> + <property name="calendarPopup"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="2"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>241</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item row="4" column="0" colspan="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>nameEdit</tabstop> + <tabstop>messageEdit</tabstop> + <tabstop>userGroup</tabstop> + <tabstop>currentUserCheckBox</tabstop> + <tabstop>userEdit</tabstop> + <tabstop>dateGroup</tabstop> + <tabstop>currentDateCheckBox</tabstop> + <tabstop>dateEdit</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>HgQueuesNewPatchDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>119</x> + <y>333</y> + </hint> + <hint type="destinationlabel"> + <x>14</x> + <y>333</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>HgQueuesNewPatchDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>157</x> + <y>326</y> + </hint> + <hint type="destinationlabel"> + <x>45</x> + <y>326</y> + </hint> + </hints> + </connection> + <connection> + <sender>currentUserCheckBox</sender> + <signal>toggled(bool)</signal> + <receiver>userEdit</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>50</x> + <y>184</y> + </hint> + <hint type="destinationlabel"> + <x>98</x> + <y>208</y> + </hint> + </hints> + </connection> + <connection> + <sender>currentUserCheckBox</sender> + <signal>toggled(bool)</signal> + <receiver>label_3</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>22</x> + <y>182</y> + </hint> + <hint type="destinationlabel"> + <x>23</x> + <y>204</y> + </hint> + </hints> + </connection> + <connection> + <sender>currentDateCheckBox</sender> + <signal>toggled(bool)</signal> + <receiver>dateEdit</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>55</x> + <y>269</y> + </hint> + <hint type="destinationlabel"> + <x>82</x> + <y>294</y> + </hint> + </hints> + </connection> + <connection> + <sender>currentDateCheckBox</sender> + <signal>toggled(bool)</signal> + <receiver>label_4</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>36</x> + <y>271</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>297</y> + </hint> + </hints> + </connection> + </connections> +</ui>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/ProjectHelper.py Sat May 14 20:00:13 2011 +0200 @@ -0,0 +1,473 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2011 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the queues extension project helper. +""" + +from PyQt4.QtCore import QObject +from PyQt4.QtGui import QMenu + +from E5Gui.E5Action import E5Action + + +class QueuesProjectHelper(QObject): + """ + Class implementing the queues extension project helper. + """ + def __init__(self): + """ + Constructor + """ + QObject.__init__(self) + + self.actions = [] + + self.initActions() + + def setObjects(self, vcsObject, projectObject): + """ + Public method to set references to the vcs and project objects. + + @param vcsObject reference to the vcs object + @param projectObject reference to the project object + """ + self.vcs = vcsObject + self.project = projectObject + + def getActions(self): + """ + Public method to get a list of all actions. + + @return list of all actions (list of E5Action) + """ + return self.actions[:] + + def initActions(self): + """ + Public method to generate the action objects. + """ + self.hgQueueNewAct = E5Action(self.trUtf8('New Patch'), + self.trUtf8('New Patch...'), + 0, 0, self, 'mercurial_queues_new') + self.hgQueueNewAct.setStatusTip(self.trUtf8( + 'Create a new patch' + )) + self.hgQueueNewAct.setWhatsThis(self.trUtf8( + """<b>New Patch</b>""" + """<p>This creates a new named patch.</p>""" + )) + self.hgQueueNewAct.triggered[()].connect(self.__hgQueueNewPatch) + self.actions.append(self.hgQueueNewAct) + + self.hgQueueRefreshAct = E5Action(self.trUtf8('Update Current Patch'), + self.trUtf8('Update Current Patch'), + 0, 0, self, 'mercurial_queues_refresh') + self.hgQueueRefreshAct.setStatusTip(self.trUtf8( + 'Update the current patch' + )) + self.hgQueueRefreshAct.setWhatsThis(self.trUtf8( + """<b>Update Current Patch</b>""" + """<p>This updates the current patch.</p>""" + )) + self.hgQueueRefreshAct.triggered[()].connect(self.__hgQueueRefreshPatch) + self.actions.append(self.hgQueueRefreshAct) + + self.hgQueueDiffAct = E5Action(self.trUtf8('Show Current Patch'), + self.trUtf8('Show Current Patch...'), + 0, 0, self, 'mercurial_queues_show') + self.hgQueueDiffAct.setStatusTip(self.trUtf8( + 'Show the contents the current patch' + )) + self.hgQueueDiffAct.setWhatsThis(self.trUtf8( + """<b>Show Current Patch</b>""" + """<p>This shows the contents of the current patch including""" + """ any changes which have been made in the working directory""" + """ since the last refresh.</p>""" + )) + self.hgQueueDiffAct.triggered[()].connect(self.__hgQueueShowPatch) + self.actions.append(self.hgQueueDiffAct) + + self.hgQueueListAct = E5Action(self.trUtf8('List Patches'), + self.trUtf8('List Patches...'), + 0, 0, self, 'mercurial_queues_list') + self.hgQueueListAct.setStatusTip(self.trUtf8( + 'List applied and unapplied patches' + )) + self.hgQueueListAct.setWhatsThis(self.trUtf8( + """<b>List Patches</b>""" + """<p>This list all applied and unapplied patches.</p>""" + )) + self.hgQueueListAct.triggered[()].connect(self.__hgQueueListPatches) + self.actions.append(self.hgQueueListAct) + + self.hgQueueFinishAct = E5Action(self.trUtf8('Finish Applied Patches'), + self.trUtf8('Finish Applied Patches'), + 0, 0, self, 'mercurial_queues_finish_applied') + self.hgQueueFinishAct.setStatusTip(self.trUtf8( + 'Finish applied patches' + )) + self.hgQueueFinishAct.setWhatsThis(self.trUtf8( + """<b>Finish Applied Patches</b>""" + """<p>This finishes the applied patches) by moving them out of""" + """ mq control into regular repository history.</p>""" + )) + self.hgQueueFinishAct.triggered[()].connect(self.__hgQueueFinishAppliedPatches) + self.actions.append(self.hgQueueFinishAct) + + self.__initPushPopActions() + self.__initPushPopForceActions() + + def __initPushPopActions(self): + """ + Public method to generate the push and pop action objects. + """ + self.hgQueuePushAct = E5Action(self.trUtf8('Push Next Patch'), + self.trUtf8('Push Next Patch'), + 0, 0, self, 'mercurial_queues_push_next') + self.hgQueuePushAct.setStatusTip(self.trUtf8( + 'Push the next patch onto the stack' + )) + self.hgQueuePushAct.setWhatsThis(self.trUtf8( + """<b>Push Next Patch</b>""" + """<p>This pushes the next patch onto the stack of applied patches.</p>""" + )) + self.hgQueuePushAct.triggered[()].connect(self.__hgQueuePushPatch) + self.actions.append(self.hgQueuePushAct) + + self.hgQueuePushAllAct = E5Action(self.trUtf8('Push All Patches'), + self.trUtf8('Push All Patches'), + 0, 0, self, 'mercurial_queues_push_all') + self.hgQueuePushAllAct.setStatusTip(self.trUtf8( + 'Push all patches onto the stack' + )) + self.hgQueuePushAllAct.setWhatsThis(self.trUtf8( + """<b>Push All Patches</b>""" + """<p>This pushes all patches onto the stack of applied patches.</p>""" + )) + self.hgQueuePushAllAct.triggered[()].connect(self.__hgQueuePushAllPatches) + self.actions.append(self.hgQueuePushAllAct) + + self.hgQueuePushUntilAct = E5Action(self.trUtf8('Push Patches'), + self.trUtf8('Push Patches'), + 0, 0, self, 'mercurial_queues_push_until') + self.hgQueuePushUntilAct.setStatusTip(self.trUtf8( + 'Push patches onto the stack' + )) + self.hgQueuePushUntilAct.setWhatsThis(self.trUtf8( + """<b>Push Patches</b>""" + """<p>This pushes patches onto the stack of applied patches until""" + """ a named patch is at the top of the stack.</p>""" + )) + self.hgQueuePushUntilAct.triggered[()].connect(self.__hgQueuePushPatches) + self.actions.append(self.hgQueuePushUntilAct) + + self.hgQueuePopAct = E5Action(self.trUtf8('Pop Current Patch'), + self.trUtf8('Pop Current Patch'), + 0, 0, self, 'mercurial_queues_pop_current') + self.hgQueuePopAct.setStatusTip(self.trUtf8( + 'Pop the current patch off the stack' + )) + self.hgQueuePopAct.setWhatsThis(self.trUtf8( + """<b>Pop Current Patch</b>""" + """<p>This pops the current patch off the stack of applied patches.</p>""" + )) + self.hgQueuePopAct.triggered[()].connect(self.__hgQueuePopPatch) + self.actions.append(self.hgQueuePopAct) + + self.hgQueuePopAllAct = E5Action(self.trUtf8('Pop All Patches'), + self.trUtf8('Pop All Patches'), + 0, 0, self, 'mercurial_queues_pop_all') + self.hgQueuePopAllAct.setStatusTip(self.trUtf8( + 'Pop all patches off the stack' + )) + self.hgQueuePopAllAct.setWhatsThis(self.trUtf8( + """<b>Pop All Patches</b>""" + """<p>This pops all patches off the stack of applied patches.</p>""" + )) + self.hgQueuePopAllAct.triggered[()].connect(self.__hgQueuePopAllPatches) + self.actions.append(self.hgQueuePopAllAct) + + self.hgQueuePopUntilAct = E5Action(self.trUtf8('Pop Patches'), + self.trUtf8('Pop Patches'), + 0, 0, self, 'mercurial_queues_pop_until') + self.hgQueuePopUntilAct.setStatusTip(self.trUtf8( + 'Pop patches off the stack' + )) + self.hgQueuePopUntilAct.setWhatsThis(self.trUtf8( + """<b>Pop Patches</b>""" + """<p>This pops patches off the stack of applied patches until a named""" + """ patch is at the top of the stack.</p>""" + )) + self.hgQueuePopUntilAct.triggered[()].connect(self.__hgQueuePopPatches) + self.actions.append(self.hgQueuePopUntilAct) + + def __initPushPopForceActions(self): + """ + Public method to generate the push and pop (force) action objects. + """ + self.hgQueuePushForceAct = E5Action(self.trUtf8('Push Next Patch'), + self.trUtf8('Push Next Patch'), + 0, 0, self, 'mercurial_queues_push_next_force') + self.hgQueuePushForceAct.setStatusTip(self.trUtf8( + 'Push the next patch onto the stack on top of local changes' + )) + self.hgQueuePushForceAct.setWhatsThis(self.trUtf8( + """<b>Push Next Patch</b>""" + """<p>This pushes the next patch onto the stack of applied patches""" + """ on top of local changes.</p>""" + )) + self.hgQueuePushForceAct.triggered[()].connect(self.__hgQueuePushPatchForced) + self.actions.append(self.hgQueuePushForceAct) + + self.hgQueuePushAllForceAct = E5Action(self.trUtf8('Push All Patches'), + self.trUtf8('Push All Patches'), + 0, 0, self, 'mercurial_queues_push_all_force') + self.hgQueuePushAllForceAct.setStatusTip(self.trUtf8( + 'Push all patches onto the stack on top of local changes' + )) + self.hgQueuePushAllForceAct.setWhatsThis(self.trUtf8( + """<b>Push All Patches</b>""" + """<p>This pushes all patches onto the stack of applied patches""" + """ on top of local changes.</p>""" + )) + self.hgQueuePushAllForceAct.triggered[()].connect( + self.__hgQueuePushAllPatchesForced) + self.actions.append(self.hgQueuePushAllForceAct) + + self.hgQueuePushUntilForceAct = E5Action(self.trUtf8('Push Patches'), + self.trUtf8('Push Patches'), + 0, 0, self, 'mercurial_queues_push_until_force') + self.hgQueuePushUntilForceAct.setStatusTip(self.trUtf8( + 'Push patches onto the stack on top of local changes' + )) + self.hgQueuePushUntilForceAct.setWhatsThis(self.trUtf8( + """<b>Push Patches</b>""" + """<p>This pushes patches onto the stack of applied patches until""" + """ a named patch is at the top of the stack on top of local changes.</p>""" + )) + self.hgQueuePushUntilForceAct.triggered[()].connect( + self.__hgQueuePushPatchesForced) + self.actions.append(self.hgQueuePushUntilForceAct) + + self.hgQueuePopForceAct = E5Action(self.trUtf8('Pop Current Patch'), + self.trUtf8('Pop Current Patch'), + 0, 0, self, 'mercurial_queues_pop_current_force') + self.hgQueuePopForceAct.setStatusTip(self.trUtf8( + 'Pop the current patch off the stack forgetting local changes' + )) + self.hgQueuePopForceAct.setWhatsThis(self.trUtf8( + """<b>Pop Current Patch</b>""" + """<p>This pops the current patch off the stack of applied patches""" + """ forgetting local changes.</p>""" + )) + self.hgQueuePopForceAct.triggered[()].connect(self.__hgQueuePopPatchForced) + self.actions.append(self.hgQueuePopForceAct) + + self.hgQueuePopAllForceAct = E5Action(self.trUtf8('Pop All Patches'), + self.trUtf8('Pop All Patches'), + 0, 0, self, 'mercurial_queues_pop_all_force') + self.hgQueuePopAllForceAct.setStatusTip(self.trUtf8( + 'Pop all patches off the stack forgetting local changes' + )) + self.hgQueuePopAllForceAct.setWhatsThis(self.trUtf8( + """<b>Pop All Patches</b>""" + """<p>This pops all patches off the stack of applied patches""" + """ forgetting local changes.</p>""" + )) + self.hgQueuePopAllForceAct.triggered[()].connect( + self.__hgQueuePopAllPatchesForced) + self.actions.append(self.hgQueuePopAllForceAct) + + self.hgQueuePopUntilForceAct = E5Action(self.trUtf8('Pop Patches'), + self.trUtf8('Pop Patches'), + 0, 0, self, 'mercurial_queues_pop_until_force') + self.hgQueuePopUntilForceAct.setStatusTip(self.trUtf8( + 'Pop patches off the stack forgetting local changes' + )) + self.hgQueuePopUntilForceAct.setWhatsThis(self.trUtf8( + """<b>Pop Patches</b>""" + """<p>This pops patches off the stack of applied patches until a named""" + """ patch is at the top of the stack forgetting local changes.</p>""" + )) + self.hgQueuePopUntilForceAct.triggered[()].connect(self.__hgQueuePopPatchesForced) + self.actions.append(self.hgQueuePopUntilForceAct) + + def initMenu(self, mainMenu): + """ + Public method to generate the VCS menu. + + @param mainMenu reference to the main menu (QMenu) + @return populated menu (QMenu) + """ + menu = QMenu(self.trUtf8("Queues"), mainMenu) + + pushPopMenu = QMenu(self.trUtf8("Push/Pop"), menu) + pushPopMenu.addAction(self.hgQueuePushAct) + pushPopMenu.addAction(self.hgQueuePushUntilAct) + pushPopMenu.addAction(self.hgQueuePushAllAct) + pushPopMenu.addAction(self.hgQueuePopAct) + pushPopMenu.addAction(self.hgQueuePopUntilAct) + pushPopMenu.addAction(self.hgQueuePopAllAct) + + pushPopForceMenu = QMenu(self.trUtf8("Push/Pop (force)"), menu) + pushPopForceMenu.addAction(self.hgQueuePushForceAct) + pushPopForceMenu.addAction(self.hgQueuePushUntilForceAct) + pushPopForceMenu.addAction(self.hgQueuePushAllForceAct) + pushPopForceMenu.addAction(self.hgQueuePopForceAct) + pushPopForceMenu.addAction(self.hgQueuePopUntilForceAct) + pushPopForceMenu.addAction(self.hgQueuePopAllForceAct) + + menu.addAction(self.hgQueueNewAct) + menu.addAction(self.hgQueueRefreshAct) + menu.addAction(self.hgQueueFinishAct) + menu.addSeparator() + menu.addAction(self.hgQueueDiffAct) + menu.addSeparator() + menu.addAction(self.hgQueueListAct) + menu.addSeparator() + menu.addMenu(pushPopMenu) + menu.addMenu(pushPopForceMenu) + + return menu + + def __hgQueueNewPatch(self): + """ + Private slot used to create a new named patch. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueueNewPatch(self.project.getProjectPath()) + + def __hgQueueRefreshPatch(self): + """ + Private slot used to refresh the current patch. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueueRefreshPatch(self.project.getProjectPath()) + + def __hgQueueShowPatch(self): + """ + Private slot used to show the contents of the current patch. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueueShowPatch(self.project.getProjectPath()) + + def __hgQueuePushPatch(self): + """ + Private slot used to push the next patch onto the stack. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueuePushPopPatches(self.project.getProjectPath(), + pop=False, all=False, named=False) + + def __hgQueuePushPatchForced(self): + """ + Private slot used to push the next patch onto the stack on top + of local changes. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueuePushPopPatches(self.project.getProjectPath(), + pop=False, all=False, named=False, force=True) + + def __hgQueuePushAllPatches(self): + """ + Private slot used to push all patches onto the stack. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueuePushPopPatches(self.project.getProjectPath(), + pop=False, all=True, named=False) + + def __hgQueuePushAllPatchesForced(self): + """ + Private slot used to push all patches onto the stack on top + of local changes. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueuePushPopPatches(self.project.getProjectPath(), + pop=False, all=True, named=False, force=True) + + def __hgQueuePushPatches(self): + """ + Private slot used to push patches onto the stack until a named + one is at the top. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueuePushPopPatches(self.project.getProjectPath(), + pop=False, all=False, named=True) + + def __hgQueuePushPatchesForced(self): + """ + Private slot used to push patches onto the stack until a named + one is at the top on top of local changes. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueuePushPopPatches(self.project.getProjectPath(), + pop=False, all=False, named=True, force=True) + + def __hgQueuePopPatch(self): + """ + Private slot used to pop the current patch off the stack. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueuePushPopPatches(self.project.getProjectPath(), + pop=True, all=False, named=False) + + def __hgQueuePopPatchForced(self): + """ + Private slot used to pop the current patch off the stack forgetting + any local changes to patched files. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueuePushPopPatches(self.project.getProjectPath(), + pop=True, all=False, named=False) + + def __hgQueuePopAllPatches(self): + """ + Private slot used to pop all patches off the stack. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueuePushPopPatches(self.project.getProjectPath(), + pop=True, all=True, named=False) + + def __hgQueuePopAllPatchesForced(self): + """ + Private slot used to pop all patches off the stack forgetting + any local changes to patched files. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueuePushPopPatches(self.project.getProjectPath(), + pop=True, all=True, named=False, force=True) + + def __hgQueuePopPatches(self): + """ + Private slot used to pop patches off the stack until a named + one is at the top. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueuePushPopPatches(self.project.getProjectPath(), + pop=True, all=False, named=True) + + def __hgQueuePopPatchesForced(self): + """ + Private slot used to pop patches off the stack until a named + one is at the top forgetting any local changes to patched files. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueuePushPopPatches(self.project.getProjectPath(), + pop=True, all=False, named=True) + + def __hgQueueListPatches(self): + """ + Private slot used to show a list of applied and unapplied patches. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueueListPatches(self.project.getProjectPath()) + + def __hgQueueFinishAppliedPatches(self): + """ + Private slot used to finish all applied patches. + """ + self.vcs.getExtensionObject("mq")\ + .hgQueueFinishAppliedPatches(self.project.getProjectPath())
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/__init__.py Sat May 14 20:00:13 2011 +0200 @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2011 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Package implementing the queues extension support interface. +"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/queues.py Sat May 14 20:00:13 2011 +0200 @@ -0,0 +1,249 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2011 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the queues extension interface. +""" +import os + +from PyQt4.QtCore import QObject, QProcess +from PyQt4.QtGui import QDialog, QApplication, QInputDialog + +from E5Gui import E5MessageBox + +from ..HgDialog import HgDialog +from ..HgDiffDialog import HgDiffDialog + +from .HgQueuesNewPatchDialog import HgQueuesNewPatchDialog +from .HgQueuesListDialog import HgQueuesListDialog + +import Preferences + + +class Queues(QObject): + """ + Class implementing the queues extension interface. + """ + APPLIED_LIST = 0 + UNAPPLIED_LIST = 1 + SERIES_LIST = 2 + + def __init__(self, vcs): + """ + Constructor + """ + QObject.__init__(self, vcs) + + self.vcs = vcs + + self.qdiffDialog = None + + def shutdown(self): + """ + Public method used to shutdown the queues interface. + """ + if self.qdiffDialog is not None: + self.qdiffDialog.close() + + def hgQueueNewPatch(self, name): + """ + Public method to create a new 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 + + dlg = HgQueuesNewPatchDialog() + if dlg.exec_() == QDialog.Accepted: + name, message, (userData, currentUser, userName), \ + (dateData, currentDate, dateStr) = dlg.getData() + + args = [] + args.append("qnew") + if message != "": + args.append("--message") + args.append(message) + if userData: + if currentUser: + args.append("--currentuser") + else: + args.append("--user") + args.append(userName) + if dateData: + if currentDate: + args.append("--currentdate") + else: + args.append("--date") + args.append(dateStr) + args.append(name) + + dia = HgDialog(self.trUtf8('New Patch')) + res = dia.startProcess(args, repodir) + if res: + dia.exec_() + self.vcs.checkVCSStatus() + + def hgQueueRefreshPatch(self, name): + """ + Public method to create a new 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 + + args = [] + args.append("qrefresh") + + dia = HgDialog(self.trUtf8('Update Current Patch')) + res = dia.startProcess(args, repodir) + if res: + dia.exec_() + self.vcs.checkVCSStatus() + + def hgQueueShowPatch(self, name): + """ + Public method to create a new named patch. + + @param name file/directory name (string) + """ + self.qdiffDialog = HgDiffDialog(self.vcs) + self.qdiffDialog.show() + QApplication.processEvents() + self.qdiffDialog.start(name, qdiff=True) + + def hgQueuePushPopPatches(self, name, pop=False, all=False, named=False, force=False): + """ + Public method to push patches onto the stack or pop patches off the stack. + + @param name file/directory name (string) + @keyparam pop flag indicating a pop action (boolean) + @keyparam all flag indicating to push/pop all (boolean) + @keyparam named flag indicating to push/pop until a named patch + is at the top of the stack (boolean) + @keyparam force flag indicating a forceful pop (boolean) + """ + # find the root of the repo + repodir = self.vcs.splitPath(name)[0] + while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): + repodir = os.path.dirname(repodir) + if repodir == os.sep: + return + + args = [] + if pop: + args.append("qpop") + title = self.trUtf8("Pop Patches") + listType = Queues.APPLIED_LIST + else: + args.append("qpush") + title = self.trUtf8("Push Patches") + listType = Queues.UNAPPLIED_LIST + if force: + args.append("--force") + if all: + args.append("--all") + elif named: + patchnames = self.__getUnAppliedPatches(repodir, listType) + if patchnames: + patch, ok = QInputDialog.getItem( + None, + self.trUtf8("Select Patch"), + self.trUtf8("Select the target patch name:"), + patchnames, + 0, False) + if ok and patch: + args.append(patch) + else: + return + else: + E5MessageBox.information(None, + self.trUtf8("Select Patch"), + self.trUtf8("""No patches to select from.""")) + return + + dia = HgDialog(title) + res = dia.startProcess(args, repodir) + if res: + dia.exec_() + self.vcs.checkVCSStatus() + + def __getUnAppliedPatches(self, repodir, listType): + """ + Public method to get the list of applied or unapplied patches. + + @param repodir directory name of the repository (string) + @param listType type of patcheslist to get + (Queues.APPLIED_LIST, Queues.UNAPPLIED_LIST, Queues.SERIES_LIST) + @return list of patches (list of string) + """ + patchesList = [] + + ioEncoding = Preferences.getSystem("IOEncoding") + process = QProcess() + args = [] + if listType == Queues.APPLIED_LIST: + args.append("qapplied") + elif listType == Queues.UNAPPLIED_LIST: + args.append("qunapplied") + elif listType == Queues.SERIES_LIST: + args.append("qseries") + else: + raise ValueError("Illegal value for listType.") + + process.setWorkingDirectory(repodir) + process.start('hg', args) + procStarted = process.waitForStarted() + if procStarted: + finished = process.waitForFinished(30000) + if finished and process.exitCode() == 0: + output = \ + str(process.readAllStandardOutput(), ioEncoding, 'replace') + for line in output.splitlines(): + patchesList.append(line.strip()) + + return patchesList + + def hgQueueListPatches(self, name): + """ + Public method to create a new named patch. + + @param name file/directory name (string) + """ + self.queuesListDialog = HgQueuesListDialog(self.vcs) + self.queuesListDialog.show() + self.queuesListDialog.start(name) + + def hgQueueFinishAppliedPatches(self, name): + """ + Public method to create a new 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 + + args = [] + args.append("qfinish") + args.append("--applied") + + dia = HgDialog(self.trUtf8('Finish Applied Patches')) + res = dia.startProcess(args, repodir) + if res: + dia.exec_() + self.vcs.checkVCSStatus()
--- a/Plugins/VcsPlugins/vcsMercurial/hg.py Fri May 13 20:23:42 2011 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/hg.py Sat May 14 20:00:13 2011 +0200 @@ -47,6 +47,7 @@ from .HgUtilities import getConfigPath from .BookmarksExtension.bookmarks import Bookmarks +from .QueuesExtension.queues import Queues from .ProjectBrowserHelper import HgProjectBrowserHelper @@ -134,6 +135,7 @@ # instantiate the extensions self.__extensions = { "bookmarks" : Bookmarks(self), + "mq" : Queues(self), } def getPlugin(self):
--- a/eric5.e4p Fri May 13 20:23:42 2011 +0200 +++ b/eric5.e4p Sat May 14 20:00:13 2011 +0200 @@ -883,6 +883,11 @@ <Source>Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/HgBookmarkDialog.py</Source> <Source>Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/HgBookmarkRenameDialog.py</Source> <Source>Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/HgBookmarksInOutDialog.py</Source> + <Source>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/__init__.py</Source> + <Source>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/queues.py</Source> + <Source>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/ProjectHelper.py</Source> + <Source>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesNewPatchDialog.py</Source> + <Source>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListDialog.py</Source> </Sources> <Forms> <Form>PyUnit/UnittestDialog.ui</Form> @@ -1126,6 +1131,8 @@ <Form>Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/HgBookmarkDialog.ui</Form> <Form>Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/HgBookmarkRenameDialog.ui</Form> <Form>Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/HgBookmarksInOutDialog.ui</Form> + <Form>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesNewPatchDialog.ui</Form> + <Form>Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListDialog.ui</Form> </Forms> <Translations> <Translation>i18n/eric5_cs.qm</Translation>