--- a/src/eric7/MicroPython/Devices/MicrobitDevices.py Tue Feb 14 18:10:30 2023 +0100 +++ b/src/eric7/MicroPython/Devices/MicrobitDevices.py Wed Feb 15 15:55:37 2023 +0100 @@ -15,7 +15,7 @@ from PyQt6.QtCore import QStandardPaths, QUrl, pyqtSlot from PyQt6.QtNetwork import QNetworkRequest -from PyQt6.QtWidgets import QInputDialog, QLineEdit, QMenu +from PyQt6.QtWidgets import QMenu from eric7 import Globals, Preferences from eric7.EricWidgets import EricFileDialog, EricMessageBox @@ -147,11 +147,7 @@ @return flag indicating support for time commands @rtype bool """ - if ( - self.microPython.isConnected() - and self.checkDeviceData() - and self._deviceData["mpy_name"] == "circuitpython" - ): + if self.microPython.isConnected() and self.hasCircuitPython(): return True return False @@ -200,12 +196,6 @@ self.tr("Flash Firmware"), lambda: self.__flashMicroPython(firmware=True) ) self.__microbitMenu.addSeparator() - self.__saveScripAct = self.__microbitMenu.addAction( - self.tr("Save Script"), self.__saveScriptToDevice - ) - self.__saveScripAct.setToolTip( - self.tr("Save the current script to the selected device") - ) self.__saveMainScriptAct = self.__microbitMenu.addAction( self.tr("Save Script as 'main.py'"), self.__saveMain ) @@ -227,11 +217,17 @@ connected = self.microPython.isConnected() linkConnected = self.microPython.isLinkConnected() + aw = ericApp().getObject("ViewManager").activeWindow() + canSaveMain = ( + aw is not None + and (aw.isPyFile() or aw.isMicroPythonFile()) + and bool(aw.text().strip()) + ) + self.__showMpyAct.setEnabled(connected and self.getDeviceType() != "calliope") self.__flashMpyAct.setEnabled(not linkConnected) self.__flashDAPLinkAct.setEnabled(not linkConnected) - self.__saveScripAct.setEnabled(connected) - self.__saveMainScriptAct.setEnabled(connected) + self.__saveMainScriptAct.setEnabled(connected and canSaveMain) self.__resetAct.setEnabled(connected) menu.addMenu(self.__microbitMenu) @@ -470,26 +466,11 @@ 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 = ericApp().getObject("ViewManager").activeWindow() if not aw: return - title = ( - self.tr("Save Script as '{0}'").format(scriptName) - if scriptName - else self.tr("Save Script") - ) + title = self.tr("Save Script as 'main.py'") if not (aw.isPyFile() or aw.isMicroPythonFile()): yes = EricMessageBox.yesNo( @@ -510,37 +491,7 @@ ) 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.EchoMode.Normal, - 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", - ] - for line in script.splitlines(): - commands.append("f(" + repr(line + "\n") + ")") - commands.append("fd.close()") - out, err = self.microPython.deviceInterface().execute(commands) - if err: - 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.putData("main.py", script.encode("utf-8")) # reset the device self.__resetDevice() @@ -553,18 +504,12 @@ if self.getDeviceType() == "bbc_microbit": # BBC micro:bit self.microPython.deviceInterface().execute( - [ - "import microbit", - "microbit.reset()", - ] + "import microbit\nmicrobit.reset()\n" ) else: # Calliope mini self.microPython.deviceInterface().execute( - [ - "import calliope_mini", - "calliope_mini.reset()", - ] + "import calliope_mini\ncalliope_mini.reset()\n" ) def getDocumentationUrl(self): @@ -647,16 +592,19 @@ @rtype tuple of str @exception OSError raised to indicate an issue with the device """ - # BBC micro:bit does not support directories - commands = [ - "import os as __os_", - "print(__os_.listdir())", - "del __os_", - ] - out, err = self._interface.execute(commands) - if err: - raise OSError(self._shortError(err)) - return ast.literal_eval(out.decode("utf-8")) + if self.hasCircuitPython(): + return super().ls(dirname=dirname) + else: + # BBC micro:bit with MicroPython does not support directories + command = """ +import os as __os_ +print(__os_.listdir()) +del __os_ +""" + out, err = self._interface.execute(command) + if err: + raise OSError(self._shortError(err)) + return ast.literal_eval(out.decode("utf-8")) def lls(self, dirname="", fullstat=False, showHidden=False): """ @@ -676,45 +624,42 @@ @rtype tuple of (str, tuple) @exception OSError raised to indicate an issue with the device """ - # BBC micro:bit does not support directories - commands = [ - "import os as __os_", - "\n".join( - [ - "def is_visible(filename, showHidden):", - " return showHidden or " - "(filename[0] != '.' and filename[-1] != '~')", - ] - ), - "\n".join( - [ - "def stat(filename):", - " size = __os_.size(filename)", - " return (0, 0, 0, 0, 0, 0, size, 0, 0, 0)", - ] - ), - "\n".join( - [ - "def listdir_stat(showHidden):", - " files = __os_.listdir()", - " return list((f, stat(f)) for f in files if" - " is_visible(f,showHidden))", - ] - ), - "print(listdir_stat({0}))".format(showHidden), - "del __os_, stat, listdir_stat, is_visible", - ] - out, err = self._interface.execute(commands) - if err: - raise OSError(self._shortError(err)) - fileslist = ast.literal_eval(out.decode("utf-8")) - if fileslist is None: - return None + if self.hasCircuitPython(): + return super().lls( + dirname=dirname, fullstat=fullstat, showHidden=showHidden + ) else: - if fullstat: - return fileslist + # BBC micro:bit with MicroPython does not support directories + command = """ +import os as __os_ + +def is_visible(filename, showHidden): + return showHidden or (filename[0] != '.' and filename[-1] != '~') + +def stat(filename): + size = __os_.size(filename) + return (0, 0, 0, 0, 0, 0, size, 0, 0, 0) + +def listdir_stat(showHidden): + files = __os_.listdir() + return list((f, stat(f)) for f in files if is_visible(f,showHidden)) + +print(listdir_stat({0})) +del __os_, stat, listdir_stat, is_visible +""".format( + showHidden + ) + out, err = self._interface.execute(command) + if err: + raise OSError(self._shortError(err)) + fileslist = ast.literal_eval(out.decode("utf-8")) + if fileslist is None: + return None else: - return [(f, (s[0], s[6], s[8])) for f, s in fileslist] + if fullstat: + return fileslist + else: + return [(f, (s[0], s[6], s[8])) for f, s in fileslist] def pwd(self): """ @@ -723,8 +668,11 @@ @return current directory @rtype str """ - # BBC micro:bit does not support directories - return "" + if self.hasCircuitPython(): + return super().pwd() + else: + # BBC micro:bit with MicroPython does not support directories + return "" ################################################################## ## time related methods below @@ -749,7 +697,10 @@ # rtc_time[6] - second 0..59 # rtc_time[7] - yearday 1..366 # rtc_time[8] - isdst 0, 1, or -1 - return "" + if self.hasCircuitPython(): + return super()._getSetTimeCode() + else: + return "" def createDevice(microPythonWidget, deviceType, vid, pid, boardName, serialNumber):