Merged with UserInterface changes supplied by Christos Sevastiadisi.

Fri, 23 Aug 2019 12:44:37 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Fri, 23 Aug 2019 12:44:37 +0200
changeset 7154
2d90de2056ec
parent 7153
ca02892fde13 (diff)
parent 7151
fcd3fcaecbef (current diff)
child 7155
334c7d0b5036

Merged with UserInterface changes supplied by Christos Sevastiadisi.

Binary file eric6/Documentation/Help/source.qch has changed
--- a/eric6/Documentation/Help/source.qhp	Thu Aug 22 20:41:32 2019 +0300
+++ b/eric6/Documentation/Help/source.qhp	Fri Aug 23 12:44:37 2019 +0200
@@ -11551,6 +11551,7 @@
       <keyword name="MicroPythonWidget.__doZoom" id="MicroPythonWidget.__doZoom" ref="eric6.MicroPython.MicroPythonWidget.html#MicroPythonWidget.__doZoom" />
       <keyword name="MicroPythonWidget.__getDeviceTime" id="MicroPythonWidget.__getDeviceTime" ref="eric6.MicroPython.MicroPythonWidget.html#MicroPythonWidget.__getDeviceTime" />
       <keyword name="MicroPythonWidget.__handlePreferencesChanged" id="MicroPythonWidget.__handlePreferencesChanged" ref="eric6.MicroPython.MicroPythonWidget.html#MicroPythonWidget.__handlePreferencesChanged" />
+      <keyword name="MicroPythonWidget.__mpyCrossAvailable" id="MicroPythonWidget.__mpyCrossAvailable" ref="eric6.MicroPython.MicroPythonWidget.html#MicroPythonWidget.__mpyCrossAvailable" />
       <keyword name="MicroPythonWidget.__paste" id="MicroPythonWidget.__paste" ref="eric6.MicroPython.MicroPythonWidget.html#MicroPythonWidget.__paste" />
       <keyword name="MicroPythonWidget.__populateDeviceTypeComboBox" id="MicroPythonWidget.__populateDeviceTypeComboBox" ref="eric6.MicroPython.MicroPythonWidget.html#MicroPythonWidget.__populateDeviceTypeComboBox" />
       <keyword name="MicroPythonWidget.__processData" id="MicroPythonWidget.__processData" ref="eric6.MicroPython.MicroPythonWidget.html#MicroPythonWidget.__processData" />
--- a/eric6/Documentation/Source/eric6.MicroPython.MicroPythonWidget.html	Thu Aug 22 20:41:32 2019 +0300
+++ b/eric6/Documentation/Source/eric6.MicroPython.MicroPythonWidget.html	Fri Aug 23 12:44:37 2019 +0200
@@ -97,6 +97,9 @@
 <td><a href="#MicroPythonWidget.__handlePreferencesChanged">__handlePreferencesChanged</a></td>
 <td>Private slot to handle a change in preferences.</td>
 </tr><tr>
+<td><a href="#MicroPythonWidget.__mpyCrossAvailable">__mpyCrossAvailable</a></td>
+<td>Private method to check the availability of mpy-cross.</td>
+</tr><tr>
 <td><a href="#MicroPythonWidget.__paste">__paste</a></td>
 <td>Private slot to perform a paste operation.</td>
 </tr><tr>
@@ -276,7 +279,22 @@
 <b>__handlePreferencesChanged</b>(<i></i>)
 <p>
         Private slot to handle a change in preferences.
-</p><a NAME="MicroPythonWidget.__paste" ID="MicroPythonWidget.__paste"></a>
+</p><a NAME="MicroPythonWidget.__mpyCrossAvailable" ID="MicroPythonWidget.__mpyCrossAvailable"></a>
+<h4>MicroPythonWidget.__mpyCrossAvailable</h4>
+<b>__mpyCrossAvailable</b>(<i></i>)
+<p>
+        Private method to check the availability of mpy-cross.
+</p><dl>
+<dt>Returns:</dt>
+<dd>
+flag indicating the availability of mpy-cross
+</dd>
+</dl><dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl><a NAME="MicroPythonWidget.__paste" ID="MicroPythonWidget.__paste"></a>
 <h4>MicroPythonWidget.__paste</h4>
 <b>__paste</b>(<i></i>)
 <p>
--- a/eric6/MicroPython/MicroPythonWidget.py	Thu Aug 22 20:41:32 2019 +0300
+++ b/eric6/MicroPython/MicroPythonWidget.py	Fri Aug 23 12:44:37 2019 +0200
@@ -847,7 +847,8 @@
         if self.__interface.connectToDevice(port):
             self.__setConnected(True)
             
-            if Preferences.getMicroPython("SyncTimeAfterConnect"):
+            if (Preferences.getMicroPython("SyncTimeAfterConnect") and
+                    self.__device.hasTimeCommands()):
                 self.__synchronizeTime(quiet=True)
         else:
             E5MessageBox.warning(
@@ -1107,16 +1108,18 @@
             act = self.__superMenu.addAction(
                 self.tr("Show Device Time"), self.__showDeviceTime)
             act.setEnabled(self.__connected)
-            self.__superMenu.addAction(
-                self.tr("Show Local Time"), self.__showLocalTime)
-            self.__superMenu.addSeparator()
+        self.__superMenu.addAction(
+            self.tr("Show Local Time"), self.__showLocalTime)
+        self.__superMenu.addSeparator()
         if not Globals.isWindowsPlatform():
-            self.__superMenu.addAction(
+            available = self.__mpyCrossAvailable()
+            act = self.__superMenu.addAction(
                 self.tr("Compile Python File"), self.__compileFile2Mpy)
+            act.setEnabled(available)
             act = self.__superMenu.addAction(
                 self.tr("Compile Current Editor"), self.__compileEditor2Mpy)
             aw = e5App().getObject("ViewManager").activeWindow()
-            act.setEnabled(bool(aw))
+            act.setEnabled(available and bool(aw))
             self.__superMenu.addSeparator()
         if self.__device:
             self.__device.addDeviceMenuEntries(self.__superMenu)
@@ -1275,6 +1278,25 @@
                     " device.</p><p>Method: {0}</p><p>Message: {1}</p>")
             .format(method, error))
     
+    def __mpyCrossAvailable(self):
+        """
+        Private method to check the availability of mpy-cross.
+        
+        @return flag indicating the availability of mpy-cross
+        @rtype bool
+        """
+        available = False
+        program = Preferences.getMicroPython("MpyCrossCompiler")
+        if not program:
+            program = "mpy-cross"
+            if Utilities.isinpath(program):
+                available = True
+        else:
+            if Utilities.isExecutable(program):
+                available = True
+        
+        return available
+    
     def __crossCompile(self, pythonFile="", title=""):
         """
         Private method to cross compile a Python file to a .mpy file.
--- a/eric6/Plugins/VcsPlugins/vcsMercurial/HgCommitDialog.py	Thu Aug 22 20:41:32 2019 +0300
+++ b/eric6/Plugins/VcsPlugins/vcsMercurial/HgCommitDialog.py	Fri Aug 23 12:44:37 2019 +0200
@@ -25,13 +25,14 @@
     accepted = pyqtSignal()
     rejected = pyqtSignal()
     
-    def __init__(self, vcs, msg, mq, parent=None):
+    def __init__(self, vcs, msg, mq, merge, parent=None):
         """
         Constructor
         
         @param vcs reference to the vcs object
         @param msg initial message (string)
         @param mq flag indicating a queue commit (boolean)
+        @param merge flag indicating a merge commit (boolean)
         @param parent parent widget (QWidget)
         """
         super(HgCommitDialog, self).__init__(parent, Qt.WindowFlags(Qt.Window))
@@ -41,7 +42,7 @@
         
         self.logEdit.setPlainText(msg)
         
-        if mq:
+        if mq or merge:
             self.amendCheckBox.setVisible(False)
             self.subrepoCheckBox.setVisible(False)
         else:
--- a/eric6/Plugins/VcsPlugins/vcsMercurial/ProjectHelper.py	Thu Aug 22 20:41:32 2019 +0300
+++ b/eric6/Plugins/VcsPlugins/vcsMercurial/ProjectHelper.py	Fri Aug 23 12:44:37 2019 +0200
@@ -419,20 +419,34 @@
         self.vcsMergeAct.triggered.connect(self._vcsMerge)
         self.actions.append(self.vcsMergeAct)
         
-        self.hgCancelMergeAct = E5Action(
-            self.tr('Cancel uncommitted merge'),
-            self.tr('Cancel uncommitted merge'),
+        self.hgCommitMergeAct = E5Action(
+            self.tr('Commit Merge'),
+            self.tr('Commit Merge'),
+            0, 0, self, 'mercurial_commit_merge')
+        self.hgCommitMergeAct.setStatusTip(self.tr(
+            'Commit a merge.'
+            ))
+        self.hgCommitMergeAct.setWhatsThis(self.tr(
+            """<b>Commit a merge</b>"""
+            """<p>This commits a merge working directory</p>"""
+            ))
+        self.hgCommitMergeAct.triggered.connect(self.__hgCommitMerge)
+        self.actions.append(self.hgCommitMergeAct)
+        
+        self.hgAbortMergeAct = E5Action(
+            self.tr('Abort Merge'),
+            self.tr('Abort Merge'),
             0, 0, self, 'mercurial_cancel_merge')
-        self.hgCancelMergeAct.setStatusTip(self.tr(
-            'Cancel an uncommitted merge and lose all changes'
+        self.hgAbortMergeAct.setStatusTip(self.tr(
+            'Abort an uncommitted merge and lose all changes'
         ))
-        self.hgCancelMergeAct.setWhatsThis(self.tr(
-            """<b>Cancel uncommitted merge</b>"""
-            """<p>This cancels an uncommitted merge causing all changes"""
+        self.hgAbortMergeAct.setWhatsThis(self.tr(
+            """<b>Abort uncommitted merge</b>"""
+            """<p>This aborts an uncommitted merge causing all changes"""
             """ to be lost.</p>"""
         ))
-        self.hgCancelMergeAct.triggered.connect(self.__hgCancelMerge)
-        self.actions.append(self.hgCancelMergeAct)
+        self.hgAbortMergeAct.triggered.connect(self.__hgAbortMerge)
+        self.actions.append(self.hgAbortMergeAct)
         
         self.hgReMergeAct = E5Action(
             self.tr('Re-Merge'),
@@ -1298,6 +1312,8 @@
         self.hgBookmarkOutgoingAct.setEnabled(self.vcs.canPush())
         if self.vcs.version >= (3, 8):
             self.hgBookmarkPushCurrentAct.setEnabled(self.vcs.canPull())
+        self.hgCommitMergeAct.setEnabled(
+            self.vcs.canCommitMerge(self.project.ppath))
     
     def initMenu(self, menu):
         """
@@ -1434,7 +1450,8 @@
         mergeMenu.addAction(self.vcsResolveAct)
         mergeMenu.addAction(self.hgUnresolveAct)
         mergeMenu.addAction(self.hgReMergeAct)
-        mergeMenu.addAction(self.hgCancelMergeAct)
+        mergeMenu.addAction(self.hgCommitMergeAct)
+        mergeMenu.addAction(self.hgAbortMergeAct)
         
         act = menu.addAction(
             UI.PixmapCache.getIcon(
@@ -1533,6 +1550,7 @@
         toolbarManager.addAction(self.vcsRevertAct, title)
         toolbarManager.addAction(self.vcsMergeAct, title)
         toolbarManager.addAction(self.hgReMergeAct, title)
+        toolbarManager.addAction(self.hgCommitMergeAct, title)
         toolbarManager.addAction(self.vcsTagAct, title)
         toolbarManager.addAction(self.hgBranchAct, title)
         toolbarManager.addAction(self.vcsSwitchAct, title)
@@ -1705,12 +1723,18 @@
         unresolved.
         """
         self.vcs.hgResolved(self.project.ppath, unresolve=True)
-    
-    def __hgCancelMerge(self):
+
+    def __hgCommitMerge(self):
+        """
+        Private slot used to commit a merge.
         """
-        Private slot used to cancel an uncommitted merge.
+        self.vcs.vcsCommit(self.project.ppath, 'Merge', merge=True)
+    
+    def __hgAbortMerge(self):
         """
-        self.vcs.hgCancelMerge(self.project.ppath)
+        Private slot used to abort an uncommitted merge.
+        """
+        self.vcs.hgAbortMerge(self.project.ppath)
     
     def __hgShowConflicts(self):
         """
--- a/eric6/Plugins/VcsPlugins/vcsMercurial/hg.py	Thu Aug 22 20:41:32 2019 +0300
+++ b/eric6/Plugins/VcsPlugins/vcsMercurial/hg.py	Fri Aug 23 12:44:37 2019 +0200
@@ -394,7 +394,7 @@
         return status
     
     def vcsCommit(self, name, message, noDialog=False, closeBranch=False,
-                  mq=False):
+                  mq=False, merge=False):
         """
         Public method used to make the change of a file/directory permanent
         in the Mercurial repository.
@@ -405,10 +405,11 @@
         @param noDialog flag indicating quiet operations
         @keyparam closeBranch flag indicating a close branch commit (boolean)
         @keyparam mq flag indicating a queue commit (boolean)
+        @keyparam merge flag indicating a merge commit (boolean)
         """
         msg = message
         
-        if mq:
+        if mq or merge:
             # ensure dialog is shown for a queue commit
             noDialog = False
         
@@ -416,7 +417,8 @@
             # call CommitDialog and get message from there
             if self.__commitDialog is None:
                 from .HgCommitDialog import HgCommitDialog
-                self.__commitDialog = HgCommitDialog(self, msg, mq, self.__ui)
+                self.__commitDialog = HgCommitDialog(self, msg, mq, merge, 
+                                                     self.__ui)
                 self.__commitDialog.accepted.connect(self.__vcsCommit_Step2)
             self.__commitDialog.show()
             self.__commitDialog.raise_()
@@ -427,6 +429,7 @@
         self.__commitData["noDialog"] = noDialog
         self.__commitData["closeBranch"] = closeBranch
         self.__commitData["mq"] = mq
+        self.__commitData["merge"] = merge
         
         if noDialog:
             self.__vcsCommit_Step2()
@@ -440,6 +443,7 @@
         noDialog = self.__commitData["noDialog"]
         closeBranch = self.__commitData["closeBranch"]
         mq = self.__commitData["mq"]
+        merge = self.__commitData["merge"]
         
         if not noDialog:
             # check, if there are unsaved changes, that should be committed
@@ -509,6 +513,13 @@
         args.append("-v")
         if mq:
             args.append("--mq")
+        elif merge:
+            if author:
+                args.append("--user")
+                args.append(author)
+            if dateTime:
+                args.append("--date")
+                args.append(dateTime)
         else:
             if closeBranch:
                 args.append("--close-branch")
@@ -2134,12 +2145,12 @@
             dia.exec_()
         self.checkVCSStatus()
     
-    def hgCancelMerge(self, name):
+    def hgAbortMerge(self, name):
         """
-        Public method to cancel an uncommitted merge.
+        Public method to abort an uncommitted merge.
         
         @param name file/directory name (string)
-        @return flag indicating, that the cancellation contained an add
+        @return flag indicating, that the abortion contained an add
             or delete (boolean)
         """
         dname, fname = self.splitPath(name)
@@ -2159,7 +2170,7 @@
             args.append("--clean")
         
         dia = HgDialog(
-            self.tr('Canceling uncommitted merge'),
+            self.tr('Aborting uncommitted merge'),
             self)
         res = dia.startProcess(args, repodir, False)
         if res:
@@ -3350,6 +3361,44 @@
                         not line.strip().endswith("="):
                     self.__defaultPushConfigured = True
     
+    def canCommitMerge(self, name):
+        """
+        Public method to check if the working directory is uncommitted merge.
+ 
+        @param name file/directory name (string)
+ 
+        @return flag indicating commit merge capability (boolean)
+        """
+        dname, fname = self.splitPath(name)
+        
+        # find the root of the repo
+        repodir = dname
+        while not os.path.isdir(os.path.join(repodir, self.adminDir)):
+            repodir = os.path.dirname(repodir)
+            if os.path.splitdrive(repodir)[1] == os.sep:
+                return
+        
+        args = self.initCommand("identify")
+        
+        output = ""
+        if self.__client is None:
+            process = QProcess()
+            process.setWorkingDirectory(repodir)
+            process.start('hg', args)
+            procStarted = process.waitForStarted(5000)
+            if procStarted:
+                finished = process.waitForFinished(30000)
+                if finished and process.exitCode() == 0:
+                    output = str(process.readAllStandardOutput(),
+                                 self.getEncoding(), 'replace')
+        else:
+            output, error = self.__client.runcommand(args)
+        
+        if output.count('+') == 2:
+            return True
+        else:
+            return False
+
     def canPull(self):
         """
         Public method to check, if pull is possible.

eric ide

mercurial