Continued implementing support for Mercurial largefiles.

Sat, 01 Mar 2014 18:35:24 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 01 Mar 2014 18:35:24 +0100
changeset 3315
bd1a25ead18d
parent 3314
be841c05a7f3
child 3316
aaa864fa5c1e

Continued implementing support for Mercurial largefiles.

Plugins/VcsPlugins/vcsMercurial/HgExtensionProjectHelper.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgNewProjectOptionsDialog.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgNewProjectOptionsDialog.ui file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgStatusDialog.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/HgSummaryDialog.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfRevisionsInputDialog.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfRevisionsInputDialog.ui file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/ProjectHelper.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/largefiles.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/ProjectHelper.py file | annotate | diff | comparison | revisions
Plugins/VcsPlugins/vcsMercurial/hg.py file | annotate | diff | comparison | revisions
eric5.e4p file | annotate | diff | comparison | revisions
--- a/Plugins/VcsPlugins/vcsMercurial/HgExtensionProjectHelper.py	Sat Mar 01 16:23:51 2014 +0100
+++ b/Plugins/VcsPlugins/vcsMercurial/HgExtensionProjectHelper.py	Sat Mar 01 18:35:24 2014 +0100
@@ -81,3 +81,11 @@
             reimplemented
         """
         raise NotImplementedError
+    
+    def shutdown(self):
+        """
+        Public method to perform shutdown actions.
+        
+        Note: Derived class may implement this method if needed.
+        """
+        pass
--- a/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py	Sat Mar 01 16:23:51 2014 +0100
+++ b/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py	Sat Mar 01 18:35:24 2014 +0100
@@ -154,6 +154,14 @@
         self.__switchAct.setToolTip(self.tr(
             "Switch the working directory to the selected revision"))
         
+        if self.vcs.version >= (2, 0):
+            self.__lfPullAct = self.__actionsMenu.addAction(
+                self.tr("Pull Large Files"), self.__lfPullActTriggered)
+            self.__lfPullAct.setToolTip(self.tr(
+                "Pull large files for selected revisions"))
+        else:
+            self.__lfPullAct = None
+        
         self.actionsButton.setIcon(
             UI.PixmapCache.getIcon("actionsToolButton.png"))
         self.actionsButton.setMenu(self.__actionsMenu)
@@ -1144,6 +1152,13 @@
             self.__tagAct.setEnabled(len(self.logTree.selectedItems()) == 1)
             self.__switchAct.setEnabled(len(self.logTree.selectedItems()) == 1)
             
+            if self.__lfPullAct is not None:
+                if self.vcs.isExtensionActive("largefiles"):
+                    self.__lfPullAct.setEnabled(bool(
+                        self.logTree.selectedItems()))
+                else:
+                    self.__lfPullAct.setEnabled(False)
+            
             self.actionsButton.setEnabled(True)
         else:
             self.actionsButton.setEnabled(False)
@@ -1521,3 +1536,17 @@
                         return
                 
                 self.on_refreshButton_clicked()
+    
+    def __lfPullActTriggered(self):
+        """
+        Private slot to pull large files of selected revisions.
+        """
+        revs = []
+        for itm in self.logTree.selectedItems():
+            rev = itm.text(self.RevisionColumn).strip().split(":", 1)[0]
+            if rev:
+                revs.append(rev)
+        
+        if revs:
+            self.vcs.getExtensionObject("largefiles").hgLfPull(
+                self.repodir, revisions=revs)
--- a/Plugins/VcsPlugins/vcsMercurial/HgNewProjectOptionsDialog.py	Sat Mar 01 16:23:51 2014 +0100
+++ b/Plugins/VcsPlugins/vcsMercurial/HgNewProjectOptionsDialog.py	Sat Mar 01 18:35:24 2014 +0100
@@ -61,6 +61,10 @@
             Utilities.toNativeSeparators(
                 Preferences.getMultiProject("Workspace") or
                 Utilities.getHomeDir()))
+        
+        self.largeCheckBox.setEnabled(self.vcs.isExtensionActive("largefiles"))
+        
+        self.resize(self.width(), self.minimumSizeHint().height())
     
     @pyqtSlot()
     def on_vcsUrlButton_clicked(self):
@@ -135,5 +139,6 @@
         vcsdatadict = {
             "url": '{0}{1}'.format(scheme, url),
             "revision": self.vcsRevisionEdit.text(),
+            "largefiles": self.largeCheckBox.isChecked(),
         }
         return (self.vcsProjectDirEdit.text(), vcsdatadict)
--- a/Plugins/VcsPlugins/vcsMercurial/HgNewProjectOptionsDialog.ui	Sat Mar 01 16:23:51 2014 +0100
+++ b/Plugins/VcsPlugins/vcsMercurial/HgNewProjectOptionsDialog.ui	Sat Mar 01 18:35:24 2014 +0100
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>562</width>
-    <height>176</height>
+    <height>221</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -21,98 +21,111 @@
   <property name="sizeGripEnabled">
    <bool>true</bool>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <layout class="QGridLayout" name="gridLayout">
-     <item row="0" column="0">
-      <widget class="QLabel" name="textLabel1">
-       <property name="text">
-        <string>&amp;Protocol:</string>
-       </property>
-       <property name="buddy">
-        <cstring>protocolCombo</cstring>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="1">
-      <widget class="QComboBox" name="protocolCombo">
-       <property name="toolTip">
-        <string>Select the protocol to access the repository</string>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="0">
-      <widget class="QLabel" name="TextLabel2">
-       <property name="text">
-        <string>&amp;URL:</string>
-       </property>
-       <property name="buddy">
-        <cstring>vcsUrlEdit</cstring>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="1">
-      <widget class="QLineEdit" name="vcsUrlEdit">
-       <property name="toolTip">
-        <string>Enter the url path of the repository (without protocol part)</string>
-       </property>
-      </widget>
-     </item>
-     <item row="2" column="0">
-      <widget class="QLabel" name="vcsRevisionLabel">
-       <property name="text">
-        <string>&amp;Revision:</string>
-       </property>
-       <property name="buddy">
-        <cstring>vcsRevisionEdit</cstring>
-       </property>
-      </widget>
-     </item>
-     <item row="2" column="1">
-      <widget class="QLineEdit" name="vcsRevisionEdit">
-       <property name="toolTip">
-        <string>Enter the revision the new project should be generated from</string>
-       </property>
-       <property name="whatsThis">
-        <string/>
-       </property>
-      </widget>
-     </item>
-     <item row="3" column="0">
-      <widget class="QLabel" name="TextLabel4">
-       <property name="text">
-        <string>Project &amp;Directory:</string>
-       </property>
-       <property name="buddy">
-        <cstring>vcsProjectDirEdit</cstring>
-       </property>
-      </widget>
-     </item>
-     <item row="3" column="1">
-      <widget class="QLineEdit" name="vcsProjectDirEdit">
-       <property name="toolTip">
-        <string>Enter the directory of the new project.</string>
-       </property>
-       <property name="whatsThis">
-        <string>&lt;b&gt;Project Directory&lt;/b&gt;
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="textLabel1">
+     <property name="text">
+      <string>&amp;Protocol:</string>
+     </property>
+     <property name="buddy">
+      <cstring>protocolCombo</cstring>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1" colspan="2">
+    <widget class="QComboBox" name="protocolCombo">
+     <property name="toolTip">
+      <string>Select the protocol to access the repository</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="TextLabel2">
+     <property name="text">
+      <string>&amp;URL:</string>
+     </property>
+     <property name="buddy">
+      <cstring>vcsUrlEdit</cstring>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QLineEdit" name="vcsUrlEdit">
+     <property name="toolTip">
+      <string>Enter the url path of the repository (without protocol part)</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="2">
+    <widget class="QToolButton" name="vcsUrlButton">
+     <property name="toolTip">
+      <string>Select the repository url via a directory selection dialog</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QLabel" name="vcsRevisionLabel">
+     <property name="text">
+      <string>&amp;Revision:</string>
+     </property>
+     <property name="buddy">
+      <cstring>vcsRevisionEdit</cstring>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="1" colspan="2">
+    <widget class="QLineEdit" name="vcsRevisionEdit">
+     <property name="toolTip">
+      <string>Enter the revision the new project should be generated from</string>
+     </property>
+     <property name="whatsThis">
+      <string/>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="0">
+    <widget class="QLabel" name="TextLabel4">
+     <property name="text">
+      <string>Project &amp;Directory:</string>
+     </property>
+     <property name="buddy">
+      <cstring>vcsProjectDirEdit</cstring>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="1">
+    <widget class="QLineEdit" name="vcsProjectDirEdit">
+     <property name="toolTip">
+      <string>Enter the directory of the new project.</string>
+     </property>
+     <property name="whatsThis">
+      <string>&lt;b&gt;Project Directory&lt;/b&gt;
 &lt;p&gt;Enter the directory of the new project. It will be retrieved from 
 the repository and be placed in this directory.&lt;/p&gt;</string>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="2">
-      <widget class="QToolButton" name="vcsUrlButton">
-       <property name="toolTip">
-        <string>Select the repository url via a directory selection dialog</string>
-       </property>
-      </widget>
-     </item>
-     <item row="3" column="2">
-      <widget class="QToolButton" name="projectDirButton"/>
-     </item>
-    </layout>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="2">
+    <widget class="QToolButton" name="projectDirButton"/>
    </item>
-   <item>
+   <item row="4" column="0" colspan="3">
+    <widget class="QCheckBox" name="largeCheckBox">
+     <property name="text">
+      <string>Download all versions of all large files</string>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="0" colspan="3">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>&lt;b&gt;Note:&lt;/b&gt; This option increases the download time and volume.</string>
+     </property>
+     <property name="wordWrap">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="6" column="0" colspan="3">
     <widget class="QDialogButtonBox" name="buttonBox">
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
@@ -133,6 +146,8 @@
   <tabstop>vcsRevisionEdit</tabstop>
   <tabstop>vcsProjectDirEdit</tabstop>
   <tabstop>projectDirButton</tabstop>
+  <tabstop>largeCheckBox</tabstop>
+  <tabstop>buttonBox</tabstop>
  </tabstops>
  <resources/>
  <connections>
--- a/Plugins/VcsPlugins/vcsMercurial/HgStatusDialog.py	Sat Mar 01 16:23:51 2014 +0100
+++ b/Plugins/VcsPlugins/vcsMercurial/HgStatusDialog.py	Sat Mar 01 18:35:24 2014 +0100
@@ -72,6 +72,7 @@
             self.restoreButton.setVisible(False)
         
         self.menuactions = []
+        self.lfActions = []
         self.menu = QMenu()
         if not mq:
             self.menuactions.append(self.menu.addAction(
@@ -84,6 +85,13 @@
             self.menu.addSeparator()
             self.menuactions.append(self.menu.addAction(
                 self.tr("Add to repository"), self.__add))
+            if self.vcs.version >= (2, 0):
+                self.lfActions.append(self.menu.addAction(
+                    self.tr("Add as Large File"),
+                    lambda: self.__lfAdd("large")))
+                self.lfActions.append(self.menu.addAction(
+                    self.tr("Add as Normal File"),
+                    lambda: self.__lfAdd("normal")))
             self.menuactions.append(self.menu.addAction(
                 self.tr("Show differences"), self.__diff))
             self.menuactions.append(self.menu.addAction(
@@ -99,11 +107,22 @@
                 self.tr("Adjust column sizes"), self.__resizeColumns))
             for act in self.menuactions:
                 act.setEnabled(False)
+            for act in self.lfActions:
+                act.setEnabled(False)
             
             self.statusList.setContextMenuPolicy(Qt.CustomContextMenu)
             self.statusList.customContextMenuRequested.connect(
                 self.__showContextMenu)
         
+        if not mq and self.vcs.version >= (2, 0):
+            self.__addButtonMenu = QMenu()
+            self.__addButtonMenu.addAction(self.tr("Add"), self.__add)
+            self.__addButtonMenu.addAction(self.tr("Add as Large File"),
+                                           lambda: self.__lfAdd("large"))
+            self.__addButtonMenu.addAction(self.tr("Add as Normal File"),
+                                           lambda: self.__lfAdd("normal"))
+            self.addButton.setMenu(self.__addButtonMenu)
+        
         self.modifiedIndicators = [
             self.tr('added'),
             self.tr('modified'),
@@ -200,6 +219,8 @@
         
         for act in self.menuactions:
             act.setEnabled(False)
+        for act in self.lfActions:
+            act.setEnabled(False)
         
         self.addButton.setEnabled(False)
         self.commitButton.setEnabled(False)
@@ -573,6 +594,11 @@
         
         @param coord the position of the mouse pointer (QPoint)
         """
+        # TODO: set status of menu entries according to their conditions
+        if self.vcs.isExtensionActive("largefiles"):
+            enable = len(self.__getUnversionedItems()) > 0
+            for act in self.lfActions:
+                act.setEnabled(enable)
         self.menu.popup(self.mapToGlobal(coord))
     
     def __commit(self):
@@ -640,6 +666,31 @@
             project.getModel().updateVCSStatus(name)
         self.vcs.checkVCSStatus()
     
+    def __lfAdd(self, mode):
+        """
+        Private slot to add a file to the repository.
+        
+        @param mode add mode (string one of 'normal' or 'large')
+        """
+        names = [os.path.join(self.dname, itm.text(self.__pathColumn))
+                 for itm in self.__getUnversionedItems()]
+        if not names:
+            E5MessageBox.information(
+                self,
+                self.tr("Add"),
+                self.tr("""There are no unversioned entries"""
+                        """ available/selected."""))
+            return
+        
+        self.vcs.getExtensionObject("largefiles").hgAdd(
+            names, mode)
+        self.on_refreshButton_clicked()
+        
+        project = e5App().getObject("Project")
+        for name in names:
+            project.getModel().updateVCSStatus(name)
+        self.vcs.checkVCSStatus()
+    
     def __forget(self):
         """
         Private slot to handle the Remove context menu entry.
--- a/Plugins/VcsPlugins/vcsMercurial/HgSummaryDialog.py	Sat Mar 01 16:23:51 2014 +0100
+++ b/Plugins/VcsPlugins/vcsMercurial/HgSummaryDialog.py	Sat Mar 01 18:35:24 2014 +0100
@@ -59,21 +59,26 @@
         
         e.accept()
     
-    def start(self, path, mq=False):
+    def start(self, path, mq=False, largefiles=False):
         """
         Public slot to start the hg summary command.
         
         @param path path name of the working directory (string)
         @param mq flag indicating to show the queue status as well (boolean)
+        @param mq flag indicating to show the largefiles status as well
+            (boolean)
         """
         self.errorGroup.hide()
         self.__path = path
         self.__mq = mq
+        self.__largefiles = largefiles
         
         args = self.vcs.initCommand("summary")
         args.append("--remote")
         if self.__mq:
             args.append("--mq")
+        if self.__largefiles:
+            args.append("--large")
         
         # find the root of the repo
         repodir = self.__path
@@ -206,6 +211,8 @@
         # step 1: parse the output
         while output:
             line = output.pop(0)
+            if ':' not in line:
+                continue
             name, value = line.split(": ", 1)
             value = value.strip()
             
@@ -296,6 +303,11 @@
                         elif category == "unapplied":
                             unapplied = int(count)
                     value = (applied, unapplied)
+            elif name == "largefiles":
+                if not value[0].isdigit():
+                    value = 0
+                else:
+                    value = int(value.split(None, 1)[0])
             else:
                 # ignore unknown entries
                 continue
@@ -440,6 +452,15 @@
                 info.append(self.tr(
                     "<tr><td><b>Queues Status</b></td><td>{0}</td></tr>")
                     .format(qinfo))
+            if "largefiles" in infoDict:
+                if infoDict["largefiles"] == 0:
+                    lfInfo = self.tr("No files to upload")
+                else:
+                    lfInfo = self.tr("%n file(s) to upload", "",
+                                     infoDict["largefiles"])
+                info.append(self.tr(
+                    "<tr><td><b>Large Files</b></td><td>{0}</td></tr>")
+                    .format(lfInfo))
             info.append("</table>")
         else:
             info = [self.tr("<p>No status information available.</p>")]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfRevisionsInputDialog.py	Sat Mar 01 18:35:24 2014 +0100
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to enter a series of revisions.
+"""
+
+from PyQt4.QtCore import pyqtSlot
+from PyQt4.QtGui import QDialog, QDialogButtonBox
+
+from .Ui_LfRevisionsInputDialog import Ui_LfRevisionsInputDialog
+
+
+class LfRevisionsInputDialog(QDialog, Ui_LfRevisionsInputDialog):
+    """
+    Class implementing a dialog to enter a series of revisions.
+    """
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget (QWidget)
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+        
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
+    
+    @pyqtSlot()
+    def on_revisionsEdit_textChanged(self):
+        """
+        Private slot handling a change of revisions.
+        """
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(
+            bool(self.revisionsEdit.toPlainText()))
+    
+    def getRevisions(self):
+        """
+        Public method to retrieve the entered revisions.
+        
+        @return list of revisions (list of string)
+        """
+        return self.revisionsEdit.toPlainText().splitlines()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfRevisionsInputDialog.ui	Sat Mar 01 18:35:24 2014 +0100
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>LfRevisionsInputDialog</class>
+ <widget class="QDialog" name="LfRevisionsInputDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Revisions Input</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Enter revisions to pull large files for (one per line):</string>
+     </property>
+     <property name="wordWrap">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QPlainTextEdit" name="revisionsEdit">
+     <property name="toolTip">
+      <string>Enter changesets by number, id, range or revset expression one per line</string>
+     </property>
+     <property name="tabChangesFocus">
+      <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::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>revisionsEdit</tabstop>
+  <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>LfRevisionsInputDialog</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>LfRevisionsInputDialog</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/LargefilesExtension/ProjectHelper.py	Sat Mar 01 16:23:51 2014 +0100
+++ b/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/ProjectHelper.py	Sat Mar 01 18:35:24 2014 +0100
@@ -13,6 +13,8 @@
 
 from ..HgExtensionProjectHelper import HgExtensionProjectHelper
 
+import UI.PixmapCache
+
 
 class LargefilesProjectHelper(HgExtensionProjectHelper):
     """
@@ -61,6 +63,85 @@
         self.hgConvertToNormalAct.triggered[()].connect(
             lambda: self.__hgLfconvert("normal"))
         self.actions.append(self.hgConvertToNormalAct)
+        
+        self.hgLfPullAct = E5Action(
+            self.tr('Pull Large Files'),
+            UI.PixmapCache.getIcon("vcsUpdate.png"),
+            self.tr('Pull Large Files'),
+            0, 0, self, 'mercurial_pull_largefiles')
+        self.hgLfPullAct.setStatusTip(self.tr(
+            'Pull large files from a remote repository'
+        ))
+        self.hgLfPullAct.setWhatsThis(self.tr(
+            """<b>Pull Large Files</b>"""
+            """<p>This pulls missing large files from a remote repository"""
+            """ into the local repository.</p>"""
+        ))
+        self.hgLfPullAct.triggered[()].connect(self.__hgLfPull)
+        self.actions.append(self.hgLfPullAct)
+        
+        self.hgLfSummaryAct = E5Action(
+            self.tr('Show Summary'),
+            UI.PixmapCache.getIcon("vcsSummary.png"),
+            self.tr('Show summary...'),
+            0, 0, self, 'mercurial_summary_largefiles')
+        self.hgLfSummaryAct.setStatusTip(self.tr(
+            'Show summary information of the working directory status'
+        ))
+        self.hgLfSummaryAct.setWhatsThis(self.tr(
+            """<b>Show summary</b>"""
+            """<p>This shows some summary information of the working"""
+            """ directory status.</p>"""
+        ))
+        self.hgLfSummaryAct.triggered[()].connect(self.__hgLfSummary)
+        self.actions.append(self.hgLfSummaryAct)
+        
+        self.hgVerifyLargeAct = E5Action(
+            self.tr('Verify large files of current revision'),
+            self.tr('Verify large files of current revision...'),
+            0, 0, self, 'mercurial_verify_large')
+        self.hgVerifyLargeAct.setStatusTip(self.tr(
+            'Verify that all large files in the current revision exist'
+        ))
+        self.hgVerifyLargeAct.setWhatsThis(self.tr(
+            """<b>Verify large files of current revision</b>"""
+            """<p>This verifies that all large files in the current"""
+            """ revision exist.</p>"""
+        ))
+        self.hgVerifyLargeAct.triggered[()].connect(
+            lambda: self.__hgLfVerify("large"))
+        self.actions.append(self.hgVerifyLargeAct)
+        
+        self.hgVerifyLfaAct = E5Action(
+            self.tr('Verify large files of all revision'),
+            self.tr('Verify large files of all revision...'),
+            0, 0, self, 'mercurial_verify_lfa')
+        self.hgVerifyLfaAct.setStatusTip(self.tr(
+            'Verify that all large files in all revisions exist'
+        ))
+        self.hgVerifyLfaAct.setWhatsThis(self.tr(
+            """<b>Verify large files of all revision</b>"""
+            """<p>This verifies that all large files in all"""
+            """ revisions exist.</p>"""
+        ))
+        self.hgVerifyLfaAct.triggered[()].connect(
+            lambda: self.__hgLfVerify("lfa"))
+        self.actions.append(self.hgVerifyLfaAct)
+        
+        self.hgVerifyLfcAct = E5Action(
+            self.tr('Verify large files contents'),
+            self.tr('Verify large files contents...'),
+            0, 0, self, 'mercurial_verify_lfc')
+        self.hgVerifyLfcAct.setStatusTip(self.tr(
+            'Verify the contents of all large files'
+        ))
+        self.hgVerifyLfcAct.setWhatsThis(self.tr(
+            """<b>Verify large files contents</b>"""
+            """<p>This verifies the contents of all large files.</p>"""
+        ))
+        self.hgVerifyLfcAct.triggered[()].connect(
+            lambda: self.__hgLfVerify("lfc"))
+        self.actions.append(self.hgVerifyLfcAct)
     
     def initMenu(self, mainMenu):
         """
@@ -72,8 +153,20 @@
         menu = QMenu(self.menuTitle(), mainMenu)
         menu.setTearOffEnabled(True)
         
+        self.__adminMenu = QMenu(self.tr("Administration"), menu)
+        self.__adminMenu.setTearOffEnabled(True)
+        self.__adminMenu.addAction(self.hgVerifyLargeAct)
+        self.__adminMenu.addAction(self.hgVerifyLfaAct)
+        self.__adminMenu.addAction(self.hgVerifyLfcAct)
+        
         menu.addAction(self.hgConvertToLargefilesAct)
         menu.addAction(self.hgConvertToNormalAct)
+        menu.addSeparator()
+        menu.addAction(self.hgLfPullAct)
+        menu.addSeparator()
+        menu.addAction(self.hgLfSummaryAct)
+        menu.addSeparator()
+        menu.addMenu(self.__adminMenu)
         
         return menu
     
@@ -85,14 +178,47 @@
         """
         return self.tr("Large Files")
     
+    def shutdown(self):
+        """
+        Public method to perform shutdown actions.
+        
+        Note: Derived class may implement this method if needed.
+        """
+        if self.__adminMenu.isTearOffMenuVisible():
+            self.__adminMenu.hideTearOffMenu()
+    
     def __hgLfconvert(self, direction):
         """
         Private slot to convert the repository format of the current project.
         
-        @param direction direction of the conversion (string, one of
+        @param direction direction of the conversion (string; one of
             'largefiles' or 'normal')
         """
         assert direction in ["largefiles", "normal"]
         
         self.vcs.getExtensionObject("largefiles").hgLfconvert(
             direction, self.project.getProjectFile())
+    
+    def __hgLfPull(self):
+        """
+        Private slot to pull missing large files into the local repository.
+        """
+        self.vcs.getExtensionObject("largefiles").hgLfPull(
+            self.project.getProjectPath())
+    
+    def __hgLfSummary(self):
+        """
+        Private slot to show a working directory summary.
+        """
+        self.vcs.hgSummary(largefiles=True)
+    
+    def __hgLfVerify(self, mode):
+        """
+        Private slot to verify large files integrity.
+        
+        @param mode verify mode (string; one of 'large', 'lfa' or 'lfc')
+        """
+        assert mode in ['large', 'lfa', 'lfc']
+        
+        self.vcs.getExtensionObject("largefiles").hgLfVerify(
+            self.project.getProjectPath(), mode)
--- a/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/largefiles.py	Sat Mar 01 16:23:51 2014 +0100
+++ b/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/largefiles.py	Sat Mar 01 18:35:24 2014 +0100
@@ -131,3 +131,69 @@
         res = dia.startProcess(args, repodir)
         if res:
             dia.exec_()
+    
+    def hgLfPull(self, projectDir, revisions=None):
+        """
+        Public method to pull missing large files into the local repository.
+        
+        @param projectDir directory name of the project (string)
+        @param revisions list of revisions to pull (list of string)
+        """
+        # find the root of the repo
+        repodir = projectDir
+        while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)):
+            repodir = os.path.dirname(repodir)
+            if os.path.splitdrive(repodir)[1] == os.sep:
+                return
+        
+        revs = []
+        if revisions:
+            revs = revisions
+        else:
+            from .LfRevisionsInputDialog import LfRevisionsInputDialog
+            dlg = LfRevisionsInputDialog()
+            if dlg.exec_() == QDialog.Accepted:
+                revs = dlg.getRevisions()
+        
+        if revs:
+            args = self.vcs.initCommand("lfpull")
+            args.append("-v")
+            for rev in revs:
+                args.append("--rev")
+                args.append(rev)
+            
+            dia = HgDialog(self.tr("Pulling large files"), self.vcs)
+            res = dia.startProcess(args, repodir)
+            if res:
+                dia.exec_()
+    
+    def hgLfVerify(self, projectDir, mode):
+        """
+        Public method to verify large files integrity.
+        
+        @param projectDir directory name of the project (string)
+        @param mode verify mode (string; one of 'large', 'lfa' or 'lfc')
+        """
+        # find the root of the repo
+        repodir = projectDir
+        while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)):
+            repodir = os.path.dirname(repodir)
+            if os.path.splitdrive(repodir)[1] == os.sep:
+                return
+        
+        args = self.vcs.initCommand("verify")
+        if mode == "large":
+            args.append("--large")
+        elif mode == "lfa":
+            args.append("--lfa")
+        elif mode == "lfc":
+            args.append("--lfc")
+        else:
+            return
+        
+        dia = HgDialog(
+            self.tr('Verifying the integrity of large files'),
+            self.vcs)
+        res = dia.startProcess(args, repodir)
+        if res:
+            dia.exec_()
--- a/Plugins/VcsPlugins/vcsMercurial/ProjectHelper.py	Sat Mar 01 16:23:51 2014 +0100
+++ b/Plugins/VcsPlugins/vcsMercurial/ProjectHelper.py	Sat Mar 01 18:35:24 2014 +0100
@@ -1007,7 +1007,7 @@
         
         self.subMenus = []
         
-        adminMenu = QMenu(self.tr("Repository Administration"), menu)
+        adminMenu = QMenu(self.tr("Administration"), menu)
         adminMenu.setTearOffEnabled(True)
         adminMenu.addAction(self.hgHeadsAct)
         adminMenu.addAction(self.hgParentsAct)
@@ -1186,6 +1186,7 @@
         
         # close torn off extension menus
         for extensionName in self.extensionMenus:
+            self.__extensions[extensionName].shutdown()
             menu = self.extensionMenus[extensionName].menu()
             if menu.isTearOffMenuVisible():
                 menu.hideTearOffMenu()
--- a/Plugins/VcsPlugins/vcsMercurial/hg.py	Sat Mar 01 16:23:51 2014 +0100
+++ b/Plugins/VcsPlugins/vcsMercurial/hg.py	Sat Mar 01 18:35:24 2014 +0100
@@ -373,6 +373,8 @@
         if rev:
             args.append("--rev")
             args.append(rev)
+        if vcsDataDict["largefiles"]:
+            args.append("--all-largefiles")
         args.append(self.__hgURL(vcsUrl))
         args.append(projectDir)
         
@@ -878,18 +880,20 @@
         self.status.show()
         self.status.start(name)
     
-    def hgSummary(self, mq=False):
+    def hgSummary(self, mq=False, largefiles=False):
         """
         Public method used to show some summary information of the
         working directory state.
         
         @param mq flag indicating to show the queue status as well (boolean)
+        @param mq flag indicating to show the largefiles status as well
+            (boolean)
         """
         from .HgSummaryDialog import HgSummaryDialog
         self.summary = HgSummaryDialog(self)
         self.summary.show()
         self.summary.start(self.__projectHelper.getProject().getProjectPath(),
-                           mq=mq)
+                           mq=mq, largefiles=largefiles)
     
     def vcsTag(self, name, revision=None, tagName=None):
         """
--- a/eric5.e4p	Sat Mar 01 16:23:51 2014 +0100
+++ b/eric5.e4p	Sat Mar 01 18:35:24 2014 +0100
@@ -1126,6 +1126,7 @@
     <Source>Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/ProjectHelper.py</Source>
     <Source>Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfConvertDataDialog.py</Source>
     <Source>Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/ProjectBrowserHelper.py</Source>
+    <Source>Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfRevisionsInputDialog.py</Source>
   </Sources>
   <Forms>
     <Form>PyUnit/UnittestDialog.ui</Form>
@@ -1452,6 +1453,7 @@
     <Form>Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelveBrowserDialog.ui</Form>
     <Form>Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelvesSelectionDialog.ui</Form>
     <Form>Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfConvertDataDialog.ui</Form>
+    <Form>Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfRevisionsInputDialog.ui</Form>
   </Forms>
   <Translations>
     <Translation>i18n/eric5_cs.ts</Translation>

eric ide

mercurial