Sun, 17 Jun 2012 13:34:46 +0200
Continued implementing support for Mercurial sub-repositories.
--- a/Plugins/VcsPlugins/vcsMercurial/HgAddSubrepositoryDialog.py Sat Jun 16 18:28:31 2012 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/HgAddSubrepositoryDialog.py Sun Jun 17 13:34:46 2012 +0200 @@ -4,7 +4,7 @@ # """ -Module implementing a dialog to add a subrepository. +Module implementing a dialog to add a sub-repository. """ import os @@ -21,7 +21,7 @@ class HgAddSubrepositoryDialog(QDialog, Ui_HgAddSubrepositoryDialog): """ - Class implementing a dialog to add a subrepository. + Class implementing a dialog to add a sub-repository. """ def __init__(self, projectPath, parent=None): """ @@ -79,7 +79,7 @@ """ path = E5FileDialog.getExistingDirectory( self, - self.trUtf8("Add Subrepository"), + self.trUtf8("Add Sub-repository"), os.path.join(self.__projectPath, self.pathEdit.text()), E5FileDialog.Options(E5FileDialog.Option(0))) @@ -89,16 +89,17 @@ self.pathEdit.setText(Utilities.toNativeSeparators(path)) else: E5MessageBox.critical(self, - self.trUtf8("Add Subrepository"), - self.trUtf8("""The subrepository path must be inside the project.""")) + self.trUtf8("Add Sub-repository"), + self.trUtf8("""The sub-repository path must be inside""" + """ the project.""")) return def getData(self): """ Public method to get the data. - @return tuple containing the relative path within the project, the subrepository - type and the subrepository URL (string, string, string) + @return tuple containing the relative path within the project, the sub-repository + type and the sub-repository URL (string, string, string) """ return ( self.pathEdit.text(),
--- a/Plugins/VcsPlugins/vcsMercurial/HgAddSubrepositoryDialog.ui Sat Jun 16 18:28:31 2012 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/HgAddSubrepositoryDialog.ui Sun Jun 17 13:34:46 2012 +0200 @@ -11,7 +11,7 @@ </rect> </property> <property name="windowTitle"> - <string>Add Subrepository</string> + <string>Add Sub-repository</string> </property> <property name="sizeGripEnabled"> <bool>true</bool> @@ -32,14 +32,14 @@ <item> <widget class="QLineEdit" name="pathEdit"> <property name="toolTip"> - <string>Enter the path of the subrepository relative to the project</string> + <string>Enter the path of the sub-repository relative to the project</string> </property> </widget> </item> <item> <widget class="QToolButton" name="pathButton"> <property name="toolTip"> - <string>Select the path of the subrepository with a directory selection dialog</string> + <string>Select the path of the sub-repository with a directory selection dialog</string> </property> <property name="text"> <string notr="true">...</string> @@ -63,7 +63,7 @@ <item> <widget class="QComboBox" name="typeCombo"> <property name="toolTip"> - <string>Select the type of the subrepository</string> + <string>Select the type of the sub-repository</string> </property> </widget> </item> @@ -95,7 +95,7 @@ <item row="2" column="1"> <widget class="QLineEdit" name="urlEdit"> <property name="toolTip"> - <string>Enter the URL of the subrepository</string> + <string>Enter the URL of the sub-repository</string> </property> </widget> </item>
--- a/Plugins/VcsPlugins/vcsMercurial/HgCommitDialog.py Sat Jun 16 18:28:31 2012 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/HgCommitDialog.py Sun Jun 17 13:34:46 2012 +0200 @@ -37,6 +37,8 @@ if vcs.version < (2, 2): self.amendCheckBox.setEnabled(False) + + self.subrepoCheckBox.setVisible(vcs.hasSubrepositories()) def showEvent(self, evt): """ @@ -76,6 +78,14 @@ """ return self.amendCheckBox.isChecked() + def commitSubrepositories(self): + """ + Public method to retrieve the state of the commit sub-repositories flag. + + @return state of the sub-repositories flag (boolean) + """ + return self.subrepoCheckBox.isChecked() + def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked.
--- a/Plugins/VcsPlugins/vcsMercurial/HgCommitDialog.ui Sat Jun 16 18:28:31 2012 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/HgCommitDialog.ui Sun Jun 17 13:34:46 2012 +0200 @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>450</width> - <height>353</height> + <height>350</height> </rect> </property> <property name="windowTitle"> @@ -65,6 +65,16 @@ </widget> </item> <item> + <widget class="QCheckBox" name="subrepoCheckBox"> + <property name="toolTip"> + <string>Select to commit sub-repositories as well</string> + </property> + <property name="text"> + <string>Commit sub-repositories</string> + </property> + </widget> + </item> + <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="orientation"> <enum>Qt::Horizontal</enum> @@ -82,6 +92,7 @@ <tabstop>logEdit</tabstop> <tabstop>recentComboBox</tabstop> <tabstop>amendCheckBox</tabstop> + <tabstop>subrepoCheckBox</tabstop> <tabstop>buttonBox</tabstop> </tabstops> <resources/>
--- a/Plugins/VcsPlugins/vcsMercurial/HgDiffDialog.py Sat Jun 16 18:28:31 2012 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/HgDiffDialog.py Sun Jun 17 13:34:46 2012 +0200 @@ -118,6 +118,9 @@ self.vcs.addArguments(args, self.vcs.options['global']) self.vcs.addArguments(args, self.vcs.options['diff']) + if self.vcs.hasSubrepositories(): + args.append("--subrepos") + if bundle: args.append('--repository') args.append(bundle)
--- a/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py Sat Jun 16 18:28:31 2012 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py Sun Jun 17 13:34:46 2012 +0200 @@ -634,6 +634,8 @@ args.append(str(self.limitSpinBox.value())) if self.commandMode in ("incoming", "outgoing"): args.append("--newest-first") + if self.vcs.hasSubrepositories(): + args.append("--subrepos") if startRev is not None: args.append('--rev') args.append('{0}:0'.format(startRev)) @@ -656,7 +658,7 @@ if self.commandMode == "incoming": if self.bundle: args.append(self.bundle) - else: + elif not self.vcs.hasSubrepositories(): project = e5App().getObject("Project") self.vcs.bundleFile = os.path.join( project.getProjectManagementDir(), "hg-bundle.hg")
--- a/Plugins/VcsPlugins/vcsMercurial/HgLogDialog.py Sat Jun 16 18:28:31 2012 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/HgLogDialog.py Sun Jun 17 13:34:46 2012 +0200 @@ -128,6 +128,8 @@ args.append(str(noEntries)) if self.mode in ("incoming", "outgoing"): args.append("--newest-first") + if self.vcs.hasSubrepositories(): + args.append("--subrepos") if self.mode == "log": args.append('--copies') args.append('--style') @@ -143,7 +145,7 @@ if self.mode == "incoming": if self.bundle: args.append(self.bundle) - else: + elif not self.vcs.hasSubrepositories(): project = e5App().getObject("Project") self.vcs.bundleFile = os.path.join( project.getProjectManagementDir(), "hg-bundle.hg")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/HgRemoveSubrepositoriesDialog.py Sun Jun 17 13:34:46 2012 +0200 @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to remove sub-repositories. +""" + +from PyQt4.QtCore import pyqtSlot +from PyQt4.QtGui import QDialog + +from .Ui_HgRemoveSubrepositoriesDialog import Ui_HgRemoveSubrepositoriesDialog + + +class HgRemoveSubrepositoriesDialog(QDialog, Ui_HgRemoveSubrepositoriesDialog): + """ + Class implementing a dialog to remove sub-repositories. + """ + def __init__(self, subrepositories, parent=None): + """ + Constructor + + @param subrepositories list of sub-repository entries (list of strings) + @param parent reference to the parent widget (QWidget) + """ + super().__init__(parent) + self.setupUi(self) + + self.subrepositories.addItems(subrepositories) + self.__removed = [] + + @pyqtSlot() + def on_subrepositories_itemSelectionChanged(self): + """ + Private slot handling the selection of entries. + """ + self.removeButton.setEnabled(len(self.subrepositories.selectedItems()) > 0) + + @pyqtSlot() + def on_removeButton_clicked(self): + """ + Private slot handling the removal of the selected entries. + """ + for itm in self.subrepositories.selectedItems(): + self.__removed.append(itm.text()) + row = self.subrepositories.row(itm) + self.subrepositories.takeItem(row) + del itm + + def getData(self): + """ + Public method to retrieve the data. + + @return tuple giving the remaining sub-repositories, the removed ones + and a flag indicating to delete the removed ones from disc (list of strings, + list of strings, boolean) + """ + return ( + [self.subrepositories.item(row).text() + for row in range(self.subrepositories.count())], + self.__removed, + self.deleteCheckBox.isChecked() + )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/VcsPlugins/vcsMercurial/HgRemoveSubrepositoriesDialog.ui Sun Jun 17 13:34:46 2012 +0200 @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>HgRemoveSubrepositoriesDialog</class> + <widget class="QDialog" name="HgRemoveSubrepositoriesDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>500</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Remove Sub-repositories</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QListWidget" name="subrepositories"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::ExtendedSelection</enum> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="removeButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Press to remove the selected entries</string> + </property> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="deleteCheckBox"> + <property name="toolTip"> + <string>Select to delete the removed entries from disc</string> + </property> + <property name="text"> + <string>Delete removed entries from disc</string> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>subrepositories</tabstop> + <tabstop>removeButton</tabstop> + <tabstop>deleteCheckBox</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>HgRemoveSubrepositoriesDialog</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>HgRemoveSubrepositoriesDialog</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/HgStatusDialog.py Sat Jun 16 18:28:31 2012 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/HgStatusDialog.py Sun Jun 17 13:34:46 2012 +0200 @@ -199,6 +199,9 @@ self.vcs.addArguments(args, self.vcs.options['global']) self.vcs.addArguments(args, self.vcs.options['status']) + if self.vcs.hasSubrepositories(): + args.append("--subrepos") + if isinstance(fn, list): self.dname, fnames = self.vcs.splitPathList(fn) self.vcs.addArguments(args, fn)
--- a/Plugins/VcsPlugins/vcsMercurial/ProjectHelper.py Sat Jun 16 18:28:31 2012 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/ProjectHelper.py Sun Jun 17 13:34:46 2012 +0200 @@ -876,17 +876,32 @@ self.hgAddSubrepoAct = E5Action( self.trUtf8('Add'), UI.PixmapCache.getIcon("vcsAdd.png"), - self.trUtf8('Add'), + self.trUtf8('Add...'), 0, 0, self, 'mercurial_add_subrepo') self.hgAddSubrepoAct.setStatusTip(self.trUtf8( - 'Add a subrepository' + 'Add a sub-repository' )) self.hgAddSubrepoAct.setWhatsThis(self.trUtf8( - """<b>Add</b>""" - """<p>Add a subrepository to the project.</p>""" + """<b>Add...</b>""" + """<p>Add a sub-repository to the project.</p>""" )) self.hgAddSubrepoAct.triggered[()].connect(self.__hgAddSubrepository) self.actions.append(self.hgAddSubrepoAct) + + self.hgRemoveSubreposAct = E5Action( + self.trUtf8('Remove'), + UI.PixmapCache.getIcon("vcsRemove.png"), + self.trUtf8('Remove...'), + 0, 0, self, 'mercurial_remove_subrepos') + self.hgRemoveSubreposAct.setStatusTip(self.trUtf8( + 'Remove sub-repositories' + )) + self.hgRemoveSubreposAct.setWhatsThis(self.trUtf8( + """<b>Remove...</b>""" + """<p>Remove sub-repositories from the project.</p>""" + )) + self.hgRemoveSubreposAct.triggered[()].connect(self.__hgRemoveSubrepositories) + self.actions.append(self.hgRemoveSubreposAct) def initMenu(self, menu): """ @@ -973,6 +988,7 @@ subrepoMenu = QMenu(self.trUtf8("Sub-Repository"), menu) subrepoMenu.setTearOffEnabled(True) subrepoMenu.addAction(self.hgAddSubrepoAct) + subrepoMenu.addAction(self.hgRemoveSubreposAct) else: subrepoMenu = None @@ -1388,3 +1404,9 @@ Private slot used to add a sub-repository. """ self.vcs.hgAddSubrepository() + + def __hgRemoveSubrepositories(self): + """ + Private slot used to remove sub-repositories. + """ + self.vcs.hgRemoveSubrepositories()
--- a/Plugins/VcsPlugins/vcsMercurial/hg.py Sat Jun 16 18:28:31 2012 +0200 +++ b/Plugins/VcsPlugins/vcsMercurial/hg.py Sun Jun 17 13:34:46 2012 +0200 @@ -53,6 +53,7 @@ from .HgPhaseDialog import HgPhaseDialog from .HgGraftDialog import HgGraftDialog from .HgAddSubrepositoryDialog import HgAddSubrepositoryDialog +from .HgRemoveSubrepositoriesDialog import HgRemoveSubrepositoriesDialog from .BookmarksExtension.bookmarks import Bookmarks from .QueuesExtension.queues import Queues @@ -315,8 +316,9 @@ status = dia.normalExit() if status: - status = self.hgCreateIgnoreFile(projectDir) - # TODO: only call this, if the file is not present + ignoreName = os.path.join(projectDir, Hg.IgnoreFileName) + if not os.path.exists(ignoreName): + status = self.hgCreateIgnoreFile(projectDir) if status: args = [] @@ -432,10 +434,12 @@ if self.__commitDialog is not None: msg = self.__commitDialog.logMessage() amend = self.__commitDialog.amend() + commitSubrepositories = self.__commitDialog.commitSubrepositories() self.__commitDialog.accepted.disconnect(self.__vcsCommit_Step2) self.__commitDialog = None else: amend = False + commitSubrepositories = False if not msg and not amend: msg = '***' @@ -449,6 +453,8 @@ args.append("--close-branch") if amend: args.append("--amend") + if commitSubrepositories: + args.append("--subrepos") if msg: args.append("--message") args.append(msg) @@ -2636,7 +2642,7 @@ def getHgSubPath(self): """ Public method to get the path to the .hgsub file containing the definitions - of subrepositories. + of sub-repositories. @return full path of the .hgsub file (string) """ @@ -2645,16 +2651,16 @@ def hasSubrepositories(self): """ - Public method to check, if the project might have subrepositories. + Public method to check, if the project might have sub-repositories. - @return flag indicating the existence of subrepositories (boolean) + @return flag indicating the existence of sub-repositories (boolean) """ hgsub = self.getHgSubPath() return os.path.isfile(hgsub) and os.stat(hgsub).st_size > 0 def hgAddSubrepository(self): """ - Public method to add a subrepository. + Public method to add a sub-repository. """ ppath = self.__projectHelper.getProject().getProjectPath() hgsub = self.getHgSubPath() @@ -2677,16 +2683,16 @@ f.close() except IOError as err: E5MessageBox.critical(self.__ui, - self.trUtf8("Add Subrepository"), - self.trUtf8("""<p>The subrepositories file .hgsub could not""" + self.trUtf8("Add Sub-repository"), + self.trUtf8("""<p>The sub-repositories file .hgsub could not""" """ be read.</p><p>Reason: {0}</p>""") .format(str(err))) return if entry in contents: E5MessageBox.critical(self.__ui, - self.trUtf8("Add Subrepository"), - self.trUtf8("""<p>The subrepositories file .hgsub already""" + self.trUtf8("Add Sub-repository"), + self.trUtf8("""<p>The sub-repositories file .hgsub already""" """ contains an entry <b>{0}</b>. Aborting...</p>""") .format(entry)) return @@ -2702,8 +2708,8 @@ f.close() except IOError as err: E5MessageBox.critical(self.__ui, - self.trUtf8("Add Subrepository"), - self.trUtf8("""<p>The subrepositories file .hgsub could not""" + self.trUtf8("Add Sub-repository"), + self.trUtf8("""<p>The sub-repositories file .hgsub could not""" """ be written to.</p><p>Reason: {0}</p>""") .format(str(err))) return @@ -2712,6 +2718,55 @@ self.vcsAdd(hgsub) self.__projectHelper.getProject().appendFile(hgsub) + def hgRemoveSubrepositories(self): + """ + Public method to remove sub-repositories. + """ + hgsub = self.getHgSubPath() + + subrepositories = [] + if not os.path.isfile(hgsub): + E5MessageBox.critical(self.__ui, + self.trUtf8("Remove Sub-repositories"), + self.trUtf8("""<p>The sub-repositories file .hgsub does not""" + """ exist. Aborting...</p>""")) + return + + try: + f = open(hgsub, "r") + subrepositories = [line.strip() for line in f.readlines()] + f.close() + except IOError as err: + E5MessageBox.critical(self.__ui, + self.trUtf8("Remove Sub-repositories"), + self.trUtf8("""<p>The sub-repositories file .hgsub could not""" + """ be read.</p><p>Reason: {0}</p>""") + .format(str(err))) + return + + dlg = HgRemoveSubrepositoriesDialog(subrepositories) + if dlg.exec_() == QDialog.Accepted: + subrepositories, removedSubrepos, deleteSubrepos = dlg.getData() + contents = "\n".join(subrepositories) + "\n" + try: + f = open(hgsub, "w") + f.write(contents) + f.close() + except IOError as err: + E5MessageBox.critical(self.__ui, + self.trUtf8("Remove Sub-repositories"), + self.trUtf8("""<p>The sub-repositories file .hgsub could not""" + """ be written to.</p><p>Reason: {0}</p>""") + .format(str(err))) + return + + if deleteSubrepos: + ppath = self.__projectHelper.getProject().getProjectPath() + for removedSubrepo in removedSubrepos: + subrepoPath = removedSubrepo.split("=", 1)[0].strip() + subrepoAbsPath = os.path.join(ppath, subrepoPath) + shutil.rmtree(subrepoAbsPath, True) + ############################################################################ ## Methods to handle extensions are below. ############################################################################
--- a/eric5.e4p Sat Jun 16 18:28:31 2012 +0200 +++ b/eric5.e4p Sun Jun 17 13:34:46 2012 +0200 @@ -1015,6 +1015,7 @@ <Source>Plugins/VcsPlugins/vcsPySvn/SvnChangeListsDialog.py</Source> <Source>Plugins/VcsPlugins/vcsSubversion/SvnChangeListsDialog.py</Source> <Source>Plugins/VcsPlugins/vcsMercurial/HgAddSubrepositoryDialog.py</Source> + <Source>Plugins/VcsPlugins/vcsMercurial/HgRemoveSubrepositoriesDialog.py</Source> </Sources> <Forms> <Form>PyUnit/UnittestDialog.ui</Form> @@ -1307,6 +1308,7 @@ <Form>Plugins/VcsPlugins/vcsPySvn/SvnChangeListsDialog.ui</Form> <Form>Plugins/VcsPlugins/vcsSubversion/SvnChangeListsDialog.ui</Form> <Form>Plugins/VcsPlugins/vcsMercurial/HgAddSubrepositoryDialog.ui</Form> + <Form>Plugins/VcsPlugins/vcsMercurial/HgRemoveSubrepositoriesDialog.ui</Form> </Forms> <Translations> <Translation>i18n/eric5_cs.qm</Translation>