diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/MicroPython/MicrobitDevices.py --- a/src/eric7/MicroPython/MicrobitDevices.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/MicroPython/MicrobitDevices.py Wed Jul 13 14:55:47 2022 +0200 @@ -28,10 +28,11 @@ """ Class implementing the device for BBC micro:bit and Calliope mini boards. """ + def __init__(self, microPythonWidget, deviceType, parent=None): """ Constructor - + @param microPythonWidget reference to the main MicroPython widget @type MicroPythonWidget @param deviceType type of the device @@ -39,31 +40,31 @@ @param parent reference to the parent object @type QObject """ - super().__init__( - microPythonWidget, deviceType, parent) - + super().__init__(microPythonWidget, deviceType, parent) + def setButtons(self): """ Public method to enable the supported action buttons. """ super().setButtons() self.microPython.setActionButtons( - run=True, repl=True, files=True, chart=HAS_QTCHART) - + run=True, repl=True, files=True, chart=HAS_QTCHART + ) + def forceInterrupt(self): """ Public method to determine the need for an interrupt when opening the serial connection. - + @return flag indicating an interrupt is needed @rtype bool """ return True - + def deviceName(self): """ Public method to get the name of the device. - + @return name of the device @rtype str """ @@ -73,113 +74,113 @@ else: # Calliope mini return self.tr("Calliope mini") - + def canStartRepl(self): """ Public method to determine, if a REPL can be started. - + @return tuple containing a flag indicating it is safe to start a REPL and a reason why it cannot. @rtype tuple of (bool, str) """ return True, "" - + def canStartPlotter(self): """ Public method to determine, if a Plotter can be started. - + @return tuple containing a flag indicating it is safe to start a Plotter and a reason why it cannot. @rtype tuple of (bool, str) """ return True, "" - + def canRunScript(self): """ Public method to determine, if a script can be executed. - + @return tuple containing a flag indicating it is safe to start a Plotter and a reason why it cannot. @rtype tuple of (bool, str) """ return True, "" - + def runScript(self, script): """ Public method to run the given Python script. - + @param script script to be executed @type str """ pythonScript = script.split("\n") self.sendCommands(pythonScript) - + def canStartFileManager(self): """ Public method to determine, if a File Manager can be started. - + @return tuple containing a flag indicating it is safe to start a File Manager and a reason why it cannot. @rtype tuple of (bool, str) """ return True, "" - + def hasTimeCommands(self): """ Public method to check, if the device supports time commands. - + The default returns True. - + @return flag indicating support for time commands @rtype bool """ return False - + def addDeviceMenuEntries(self, menu): """ Public method to add device specific entries to the given menu. - + @param menu reference to the context menu @type QMenu """ connected = self.microPython.isConnected() - - act = menu.addAction(self.tr("Flash MicroPython"), - self.__flashMicroPython) + + act = menu.addAction(self.tr("Flash MicroPython"), self.__flashMicroPython) act.setEnabled(not connected) - act = menu.addAction(self.tr("Flash Firmware"), - lambda: self.__flashMicroPython(firmware=True)) + act = menu.addAction( + self.tr("Flash Firmware"), lambda: self.__flashMicroPython(firmware=True) + ) act.setEnabled(not connected) menu.addSeparator() act = menu.addAction(self.tr("Save Script"), self.__saveScriptToDevice) - act.setToolTip(self.tr( - "Save the current script to the selected device")) + act.setToolTip(self.tr("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( - "Save the current script as 'main.py' on the connected device")) + act = menu.addAction(self.tr("Save Script as 'main.py'"), self.__saveMain) + act.setToolTip( + self.tr("Save the current script as 'main.py' on the connected device") + ) act.setEnabled(connected) menu.addSeparator() - act = menu.addAction(self.tr("Reset {0}").format(self.deviceName()), - self.__resetDevice) + act = menu.addAction( + self.tr("Reset {0}").format(self.deviceName()), self.__resetDevice + ) act.setEnabled(connected) - + def hasFlashMenuEntry(self): """ Public method to check, if the device has its own flash menu entry. - + @return flag indicating a specific flash menu entry @rtype bool """ return True - + @pyqtSlot() def __flashMicroPython(self, firmware=False): """ Private slot to flash MicroPython or the DAPLink firmware to the device. - + @param firmware flag indicating to flash the DAPLink firmware @type bool """ @@ -189,19 +190,15 @@ if self.getDeviceType() == "bbc_microbit": # BBC micro:bit if firmware: - deviceDirectories = Utilities.findVolume("MAINTENANCE", - findAll=True) + deviceDirectories = Utilities.findVolume("MAINTENANCE", findAll=True) else: - deviceDirectories = Utilities.findVolume("MICROBIT", - findAll=True) + deviceDirectories = Utilities.findVolume("MICROBIT", findAll=True) else: # Calliope mini if firmware: - deviceDirectories = Utilities.findVolume("MAINTENANCE", - findAll=True) + deviceDirectories = Utilities.findVolume("MAINTENANCE", findAll=True) else: - deviceDirectories = Utilities.findVolume("MINI", - findAll=True) + deviceDirectories = Utilities.findVolume("MINI", findAll=True) if len(deviceDirectories) == 0: if self.getDeviceType() == "bbc_microbit": # BBC micro:bit is not ready or not mounted @@ -210,31 +207,31 @@ self.microPython, self.tr("Flash MicroPython/Firmware"), self.tr( - '<p>The BBC micro:bit is not ready for flashing' - ' the DAPLink firmware. Follow these' - ' instructions. </p>' - '<ul>' - '<li>unplug USB cable and any batteries</li>' - '<li>keep RESET button pressed an plug USB cable' - ' back in</li>' - '<li>a drive called MAINTENANCE should be' - ' available</li>' - '</ul>' - '<p>See the ' + "<p>The BBC micro:bit is not ready for flashing" + " the DAPLink firmware. Follow these" + " instructions. </p>" + "<ul>" + "<li>unplug USB cable and any batteries</li>" + "<li>keep RESET button pressed an plug USB cable" + " back in</li>" + "<li>a drive called MAINTENANCE should be" + " available</li>" + "</ul>" + "<p>See the " '<a href="https://microbit.org/guide/firmware/">' - 'micro:bit web site</a> for details.</p>' - ) + "micro:bit web site</a> for details.</p>" + ), ) else: EricMessageBox.critical( self.microPython, self.tr("Flash MicroPython/Firmware"), self.tr( - '<p>The BBC micro:bit is not ready for flashing' - ' the MicroPython firmware. Please make sure,' - ' that a drive called MICROBIT is available.' - '</p>' - ) + "<p>The BBC micro:bit is not ready for flashing" + " the MicroPython firmware. Please make sure," + " that a drive called MICROBIT is available." + "</p>" + ), ) else: # Calliope mini is not ready or not mounted @@ -244,16 +241,16 @@ self.tr("Flash MicroPython/Firmware"), self.tr( '<p>The "Calliope mini" is not ready for flashing' - ' the DAPLink firmware. Follow these' - ' instructions. </p>' - '<ul>' - '<li>unplug USB cable and any batteries</li>' - '<li>keep RESET button pressed an plug USB cable' - ' back in</li>' - '<li>a drive called MAINTENANCE should be' - ' available</li>' - '</ul>' - ) + " the DAPLink firmware. Follow these" + " instructions. </p>" + "<ul>" + "<li>unplug USB cable and any batteries</li>" + "<li>keep RESET button pressed an plug USB cable" + " back in</li>" + "<li>a drive called MAINTENANCE should be" + " available</li>" + "</ul>" + ), ) else: EricMessageBox.critical( @@ -261,30 +258,33 @@ self.tr("Flash MicroPython/Firmware"), self.tr( '<p>The "Calliope mini" is not ready for flashing' - ' the MicroPython firmware. Please make sure,' - ' that a drive called MINI is available.' - '</p>' - ) + " the MicroPython firmware. Please make sure," + " that a drive called MINI is available." + "</p>" + ), ) elif len(deviceDirectories) == 1: downloadsPath = QStandardPaths.standardLocations( - QStandardPaths.StandardLocation.DownloadLocation)[0] + QStandardPaths.StandardLocation.DownloadLocation + )[0] firmware = EricFileDialog.getOpenFileName( self.microPython, self.tr("Flash MicroPython/Firmware"), downloadsPath, - self.tr("MicroPython/Firmware Files (*.hex *.bin);;" - "All Files (*)")) + self.tr("MicroPython/Firmware Files (*.hex *.bin);;" "All Files (*)"), + ) if firmware and os.path.exists(firmware): shutil.copy2(firmware, deviceDirectories[0]) else: EricMessageBox.warning( self, self.tr("Flash MicroPython/Firmware"), - self.tr("There are multiple devices ready for flashing." - " Please make sure, that only one device is prepared.") + self.tr( + "There are multiple devices ready for flashing." + " Please make sure, that only one device is prepared." + ), ) - + @pyqtSlot() def __saveMain(self): """ @@ -292,43 +292,45 @@ 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 = ericApp().getObject("ViewManager").activeWindow() if not aw: return - + title = ( self.tr("Save Script as '{0}'").format(scriptName) - if scriptName else - self.tr("Save Script") + if scriptName + else self.tr("Save Script") ) - + if not (aw.isPyFile() or aw.isMicroPythonFile()): yes = EricMessageBox.yesNo( self.microPython, title, - self.tr("""The current editor does not contain a Python""" - """ script. Write it anyway?""")) + self.tr( + """The current editor does not contain a Python""" + """ script. Write it anyway?""" + ), + ) if not yes: return - + script = aw.text().strip() if not script: EricMessageBox.warning( - self.microPython, - title, - self.tr("""The script is empty. Aborting.""")) + self.microPython, title, self.tr("""The script is empty. Aborting.""") + ) return - + if not scriptName: scriptName = os.path.basename(aw.getFileName()) scriptName, ok = QInputDialog.getText( @@ -336,12 +338,13 @@ title, self.tr("Enter a file name on the device:"), QLineEdit.EchoMode.Normal, - scriptName) + scriptName, + ) if not ok or not bool(scriptName): return - + title = self.tr("Save Script as '{0}'").format(scriptName) - + commands = [ "fd = open('{0}', 'wb')".format(scriptName), "f = fd.write", @@ -354,13 +357,15 @@ EricMessageBox.critical( self.microPython, title, - self.tr("""<p>The script could not be saved to the""" - """ device.</p><p>Reason: {0}</p>""") - .format(err.decode("utf-8"))) - + 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.__resetDevice() - + @pyqtSlot() def __resetDevice(self): """ @@ -368,21 +373,25 @@ """ if self.getDeviceType() == "bbc_microbit": # BBC micro:bit - self.microPython.commandsInterface().execute([ - "import microbit", - "microbit.reset()", - ]) + self.microPython.commandsInterface().execute( + [ + "import microbit", + "microbit.reset()", + ] + ) else: # Calliope mini - self.microPython.commandsInterface().execute([ - "import calliope_mini", - "calliope_mini.reset()", - ]) - + self.microPython.commandsInterface().execute( + [ + "import calliope_mini", + "calliope_mini.reset()", + ] + ) + def getDocumentationUrl(self): """ Public method to get the device documentation URL. - + @return documentation URL of the device @rtype str """ @@ -392,28 +401,38 @@ else: # Calliope mini return Preferences.getMicroPython("CalliopeDocuUrl") - + def getDownloadMenuEntries(self): """ Public method to retrieve the entries for the downloads menu. - + @return list of tuples with menu text and URL to be opened for each entry @rtype list of tuple of (str, str) """ if self.getDeviceType() == "bbc_microbit": return [ - (self.tr("MicroPython Firmware for BBC micro:bit V1"), - Preferences.getMicroPython("MicrobitMicroPythonUrl")), - (self.tr("MicroPython Firmware for BBC micro:bit V2"), - Preferences.getMicroPython("MicrobitV2MicroPythonUrl")), - (self.tr("DAPLink Firmware"), - Preferences.getMicroPython("MicrobitFirmwareUrl")) + ( + self.tr("MicroPython Firmware for BBC micro:bit V1"), + Preferences.getMicroPython("MicrobitMicroPythonUrl"), + ), + ( + self.tr("MicroPython Firmware for BBC micro:bit V2"), + Preferences.getMicroPython("MicrobitV2MicroPythonUrl"), + ), + ( + self.tr("DAPLink Firmware"), + Preferences.getMicroPython("MicrobitFirmwareUrl"), + ), ] else: return [ - (self.tr("MicroPython Firmware"), - Preferences.getMicroPython("CalliopeMicroPythonUrl")), - (self.tr("DAPLink Firmware"), - Preferences.getMicroPython("CalliopeDAPLinkUrl")) + ( + self.tr("MicroPython Firmware"), + Preferences.getMicroPython("CalliopeMicroPythonUrl"), + ), + ( + self.tr("DAPLink Firmware"), + Preferences.getMicroPython("CalliopeDAPLinkUrl"), + ), ]