eric6/MicroPython/MicrobitDevices.py

changeset 7299
a22b87b46128
parent 7229
53054eb5b15a
child 7328
e2d85ef3fadb
diff -r 9d15757d06ac -r a22b87b46128 eric6/MicroPython/MicrobitDevices.py
--- a/eric6/MicroPython/MicrobitDevices.py	Sun Oct 13 15:30:10 2019 +0200
+++ b/eric6/MicroPython/MicrobitDevices.py	Sat Oct 19 20:32:26 2019 +0200
@@ -8,17 +8,17 @@
 """
 
 
-import sys
 import os
+import shutil
 
 from PyQt5.QtCore import pyqtSlot, QStandardPaths
+from PyQt5.QtWidgets import QInputDialog, QLineEdit
 
 from .MicroPythonDevices import MicroPythonDevice
 from .MicroPythonWidget import HAS_QTCHART
 
 from E5Gui import E5MessageBox, E5FileDialog
 from E5Gui.E5Application import e5App
-from E5Gui.E5ProcessDialog import E5ProcessDialog
 
 import Utilities
 import Preferences
@@ -160,17 +160,14 @@
         """
         connected = self.microPython.isConnected()
         
-        act = menu.addAction(self.tr("Flash Default MicroPython Firmware"),
+        act = menu.addAction(self.tr("Flash MicroPython Firmware"),
                              self.__flashMicroPython)
         act.setEnabled(not connected)
-        act = menu.addAction(self.tr("Flash Custom MicroPython Firmware"),
-                             self.__flashCustomMicroPython)
-        act.setEnabled(not connected)
         menu.addSeparator()
-        act = menu.addAction(self.tr("Flash Script"), self.__flashScript)
+        act = menu.addAction(self.tr("Save Script"), self.__saveScriptToDevice)
         act.setToolTip(self.tr(
-            "Flash the current script to the selected device."))
-        act.setEnabled(not connected)
+            "Save the current script to the selected device"))
+        act.setEnabled(connected)
         act = menu.addAction(self.tr("Save Script as 'main.py'"),
                              self.__saveMain)
         act.setToolTip(self.tr(
@@ -179,87 +176,35 @@
         menu.addSeparator()
         act = menu.addAction(self.tr("Reset micro:bit"), self.__resetDevice)
         act.setEnabled(connected)
-        menu.addSeparator()
-        menu.addAction(self.tr("Install 'uflash'"), self.__installUflashTool)
     
     @pyqtSlot()
     def __flashMicroPython(self):
         """
         Private slot to flash the default MicroPython firmware to the device.
         """
-        flashArgs = [
-            "-u",
-            "-m", "uflash",
-        ]
-        dlg = E5ProcessDialog(self.tr("'uflash' Output"),
-                              self.tr("Flash Default MicroPython Firmware"))
-        res = dlg.startProcess(sys.executable, flashArgs)
-        if res:
-            dlg.exec_()
-    
-    @pyqtSlot()
-    def __flashCustomMicroPython(self):
-        """
-        Private slot to flash a custom MicroPython firmware to the device.
-        """
-        downloadsPath = QStandardPaths.standardLocations(
-            QStandardPaths.DownloadLocation)[0]
-        firmware = E5FileDialog.getOpenFileName(
-            self.microPython,
-            self.tr("Flash Custom MicroPython Firmware"),
-            downloadsPath,
-            self.tr("MicroPython Firmware Files (*.hex);;All Files (*)"))
-        if firmware and os.path.exists(firmware):
-            flashArgs = [
-                "-u",
-                "-m", "uflash",
-                "--runtime", firmware,
-            ]
-            dlg = E5ProcessDialog(
-                self.tr("'uflash' Output"),
-                self.tr("Flash Default MicroPython Firmware"))
-            res = dlg.startProcess(sys.executable, flashArgs)
-            if res:
-                dlg.exec_()
-    
-    @pyqtSlot()
-    def __flashScript(self):
-        """
-        Private slot to flash the current script onto the selected device.
-        """
-        aw = e5App().getObject("ViewManager").activeWindow()
-        if not aw:
-            return
-        
-        if not (aw.isPyFile() or aw.isMicroPythonFile()):
-            yes = E5MessageBox.yesNo(
+        # Attempts to find the path on the filesystem that represents the
+        # plugged in micro:bit board in maintenance mode.
+        deviceDirectory = Utilities.findVolume("MAINTENANCE")
+        if not deviceDirectory:
+            # BBC micro:bit is not ready or not mounted
+            E5MessageBox.critical(
                 self.microPython,
-                self.tr("Flash Script"),
-                self.tr("""The current editor does not contain a Python"""
-                        """ script. Flash it anyway?"""))
-            if not yes:
-                return
-        
-        script = aw.text().strip()
-        if not script:
-            E5MessageBox.warning(
+                self.tr("Flash MicroPython Firmware"),
+                self.tr(
+                    'The BBC micro:bit is not ready for flashing. See the'
+                    ' <a href="https://microbit.org/guide/firmware/">'
+                    'micro:bit web site</a> for details.'
+                ))
+        else:
+            downloadsPath = QStandardPaths.standardLocations(
+                QStandardPaths.DownloadLocation)[0]
+            firmware = E5FileDialog.getOpenFileName(
                 self.microPython,
-                self.tr("Flash Script"),
-                self.tr("""The script is empty. Aborting."""))
-            return
-        
-        if aw.checkDirty():
-            filename = aw.getFileName()
-            flashArgs = [
-                "-u",
-                "-m", "uflash",
-                filename,
-            ]
-            dlg = E5ProcessDialog(self.tr("'uflash' Output"),
-                                  self.tr("Flash Script"))
-            res = dlg.startProcess(sys.executable, flashArgs)
-            if res:
-                dlg.exec_()
+                self.tr("Flash MicroPython Firmware"),
+                downloadsPath,
+                self.tr("MicroPython Firmware Files (*.hex);;All Files (*)"))
+            if firmware and os.path.exists(firmware):
+                shutil.copy2(firmware, deviceDirectory)
     
     @pyqtSlot()
     def __saveMain(self):
@@ -267,14 +212,30 @@
         Private slot to copy the current script as 'main.py' onto the
         connected device.
         """
+        self.__saveScriptToDevice("main.py")
+    
+    @pyqtSlot()
+    def __saveScriptToDevice(self, scriptName=""):
+        """
+        Private method to save the current script onto the connected
+        device.
+        
+        @param scriptName name of the file on the device
+        @type str
+        """
         aw = e5App().getObject("ViewManager").activeWindow()
         if not aw:
             return
         
+        if scriptName:
+            title = self.tr("Save Script as '{0}'").format(scriptName)
+        else:
+            title = self.tr("Save Script")
+        
         if not (aw.isPyFile() or aw.isMicroPythonFile()):
             yes = E5MessageBox.yesNo(
                 self.microPython,
-                self.tr("Save Script as 'main.py'"),
+                title,
                 self.tr("""The current editor does not contain a Python"""
                         """ script. Write it anyway?"""))
             if not yes:
@@ -284,12 +245,25 @@
         if not script:
             E5MessageBox.warning(
                 self.microPython,
-                self.tr("Save Script as 'main.py'"),
+                title,
                 self.tr("""The script is empty. Aborting."""))
             return
         
+        if not scriptName:
+            scriptName = os.path.basename(aw.getFileName())
+            scriptName, ok = QInputDialog.getText(
+                self.microPython,
+                title,
+                self.tr("Enter a file name on the device:"),
+                QLineEdit.Normal,
+                scriptName)
+            if not ok or not bool(scriptName):
+                return
+            
+            title = self.tr("Save Script as '{0}'").format(scriptName)
+        
         commands = [
-            "fd = open('main.py', 'wb')",
+            "fd = open('{0}', 'wb')".format(scriptName),
             "f = fd.write",
         ]
         for line in script.splitlines():
@@ -299,16 +273,13 @@
         if err:
             E5MessageBox.critical(
                 self.microPython,
-                self.tr("Save Script as 'main.py'"),
+                title,
                 self.tr("""<p>The script could not be saved to the"""
                         """ device.</p><p>Reason: {0}</p>""")
                 .format(err.decode("utf-8")))
         
         # reset the device
-        self.microPython.commandsInterface().execute([
-            "import microbit",
-            "microbit.reset()",
-        ])
+        self.__resetDevice()
     
     @pyqtSlot()
     def __resetDevice(self):
@@ -320,14 +291,6 @@
             "microbit.reset()",
         ])
     
-    @pyqtSlot()
-    def __installUflashTool(self):
-        """
-        Private slot to install the uflash package via pip.
-        """
-        pip = e5App().getObject("Pip")
-        pip.installPackages(["uflash"], interpreter=sys.executable)
-    
     def getDocumentationUrl(self):
         """
         Public method to get the device documentation URL.

eric ide

mercurial