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.