Mon, 22 Jul 2019 18:48:27 +0200
MicroPython: started to implement the file manager widget; added the forgotten MicroPythonFileManagerWidget.[py, ui] files.
eric6/MicroPython/MicroPythonFileManagerWidget.py | file | annotate | diff | comparison | revisions | |
eric6/MicroPython/MicroPythonFileManagerWidget.ui | file | annotate | diff | comparison | revisions |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric6/MicroPython/MicroPythonFileManagerWidget.py Mon Jul 22 18:48:27 2019 +0200 @@ -0,0 +1,232 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a file manager for MicroPython devices. +""" + +from __future__ import unicode_literals + +import os + +from PyQt5.QtCore import pyqtSlot, Qt +from PyQt5.QtWidgets import QWidget, QTreeWidgetItem, QHeaderView + +from E5Gui import E5MessageBox +from E5Gui.E5Application import e5App + +from .Ui_MicroPythonFileManagerWidget import Ui_MicroPythonFileManagerWidget + +from .MicroPythonFileSystem import ( + MicroPythonFileManager, decoratedName, mode2string, mtime2string +) + +import UI.PixmapCache +import Preferences + + +class MicroPythonFileManagerWidget(QWidget, Ui_MicroPythonFileManagerWidget): + """ + Class implementing a file manager for MicroPython devices. + """ + def __init__(self, port, parent=None): + """ + Constructor + + @param port port name of the device + @type str + @param parent reference to the parent widget + @type QWidget + """ + super(MicroPythonFileManagerWidget, self).__init__(parent) + self.setupUi(self) + + self.putButton.setIcon(UI.PixmapCache.getIcon("1rightarrow")) + self.getButton.setIcon(UI.PixmapCache.getIcon("1leftarrow")) + + self.putButton.setEnabled(False) + self.getButton.setEnabled(False) + + self.localFileTreeWidget.header().setSortIndicator( + 0, Qt.AscendingOrder) + self.deviceFileTreeWidget.header().setSortIndicator( + 0, Qt.AscendingOrder) + + self.__fileManager = MicroPythonFileManager(port, self) + + self.__fileManager.longListFiles.connect(self.__handleLongListFiles) + self.__fileManager.currentDir.connect(self.__handleCurrentDir) + + self.__fileManager.longListFilesFailed.connect(self.__handleError) + self.__fileManager.currentDirFailed.connect(self.__handleError) + + def start(self): + """ + Public method to start the widget. + """ + self.__fileManager.connect() + + dirname = "" + vm = e5App().getObject("ViewManager") + aw = vm.activeWindow() + if aw: + dirname = os.path.dirname(aw.getFileName()) + if not dirname: + dirname = (Preferences.getMultiProject("Workspace") or + os.path.expanduser("~")) + self.__listLocalFiles(dirname) + + self.__fileManager.pwd() + + def stop(self): + """ + Public method to stop the widget. + """ + self.__fileManager.disconnect() + + @pyqtSlot(str) + def __handleError(self, error): + """ + Private slot to handle errors. + + @param error error message + @type str + """ + E5MessageBox.warning( + self, + self.tr("Error handling device"), + self.tr("<p>There was an error communicating with the connected" + " device.</p><p>Message: {0}</p>").format(error)) + + @pyqtSlot(str) + def __handleCurrentDir(self, dirname): + """ + Private slot to handle a change of the current directory of the device. + + @param dirname name of the current directory + @type str + """ + self.deviceCwd.setText(dirname) + self.__fileManager.lls(dirname) + + @pyqtSlot(tuple) + def __handleLongListFiles(self, filesList): + """ + Private slot to receive a long directory listing. + + @param filesList tuple containing tuples with name, mode, size and time + for each directory entry + @type tuple of (str, str, str, str) + """ + self.deviceFileTreeWidget.clear() + for name, mode, size, time in filesList: + itm = QTreeWidgetItem(self.deviceFileTreeWidget, + [name, mode, size, time]) + itm.setTextAlignment(1, Qt.AlignHCenter) + itm.setTextAlignment(2, Qt.AlignRight) + self.deviceFileTreeWidget.header().resizeSections( + QHeaderView.ResizeToContents) + + def __listLocalFiles(self, dirname=""): + """ + Private method to populate the local files list. + + @param dirname name of the local directory to be listed + @type str + """ # __IGNORE_WARNING_D234__ + def isvisible(name): + return not name.startswith(".") and not name.endswith("~") + + def stat(filename): + try: + rstat = os.lstat(filename) + except Exception: + rstat = os.stat(filename) + return tuple(rstat) + + def listdir_stat(dirname): + try: + if dirname: + files = os.listdir(dirname) + else: + files = os.listdir() + except OSError: + return [] + if dirname in ('', '/'): + return [(f, stat(f)) for f in files if isvisible(f)] + return [(f, stat(os.path.join(dirname, f))) for f in files + if isvisible(f)] + + if not dirname: + dirname = os.getcwd() + self.localCwd.setText(dirname) + + filesStatList = listdir_stat(dirname) + filesList = [( + decoratedName(f, s[0]), + mode2string(s[0]), + str(s[6]), + mtime2string(s[8])) for f, s in filesStatList] + self.localFileTreeWidget.clear() + for item in filesList: + itm = QTreeWidgetItem(self.localFileTreeWidget, item) + itm.setTextAlignment(1, Qt.AlignHCenter) + itm.setTextAlignment(2, Qt.AlignRight) + self.localFileTreeWidget.header().resizeSections( + QHeaderView.ResizeToContents) + + @pyqtSlot(QTreeWidgetItem, int) + def on_localFileTreeWidget_itemActivated(self, item, column): + """ + Slot documentation goes here. + + @param item DESCRIPTION + @type QTreeWidgetItem + @param column DESCRIPTION + @type int + """ + # TODO: not implemented yet + # show listing of activated directory + + @pyqtSlot() + def on_localFileTreeWidget_itemSelectionChanged(self): + """ + Slot documentation goes here. + """ + # TODO: not implemented yet + + @pyqtSlot(QTreeWidgetItem, int) + def on_deviceFileTreeWidget_itemActivated(self, item, column): + """ + Slot documentation goes here. + + @param item DESCRIPTION + @type QTreeWidgetItem + @param column DESCRIPTION + @type int + """ + # TODO: not implemented yet + # chdir to activated directory triggering a pwd triggering a lls + + @pyqtSlot() + def on_deviceFileTreeWidget_itemSelectionChanged(self): + """ + Slot documentation goes here. + """ + # TODO: not implemented yet + + @pyqtSlot() + def on_putButton_clicked(self): + """ + Slot documentation goes here. + """ + # TODO: not implemented yet + + @pyqtSlot() + def on_getButton_clicked(self): + """ + Slot documentation goes here. + """ + # TODO: not implemented yet
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric6/MicroPython/MicroPythonFileManagerWidget.ui Mon Jul 22 18:48:27 2019 +0200 @@ -0,0 +1,172 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MicroPythonFileManagerWidget</class> + <widget class="QWidget" name="MicroPythonFileManagerWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>675</width> + <height>338</height> + </rect> + </property> + <layout class="QGridLayout" name="gridLayout"> + <property name="leftMargin"> + <number>2</number> + </property> + <property name="topMargin"> + <number>2</number> + </property> + <property name="rightMargin"> + <number>2</number> + </property> + <property name="bottomMargin"> + <number>2</number> + </property> + <item row="0" column="0" colspan="2"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Local Files</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Device Files</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QTreeWidget" name="localFileTreeWidget"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="itemsExpandable"> + <bool>false</bool> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <attribute name="headerShowSortIndicator" stdset="0"> + <bool>true</bool> + </attribute> + <column> + <property name="text"> + <string>Name</string> + </property> + </column> + <column> + <property name="text"> + <string>Mode</string> + </property> + </column> + <column> + <property name="text"> + <string>Size</string> + </property> + </column> + <column> + <property name="text"> + <string>Time</string> + </property> + </column> + </widget> + </item> + <item row="1" column="2"> + <widget class="QTreeWidget" name="deviceFileTreeWidget"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="itemsExpandable"> + <bool>false</bool> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <attribute name="headerShowSortIndicator" stdset="0"> + <bool>true</bool> + </attribute> + <column> + <property name="text"> + <string>Name</string> + </property> + </column> + <column> + <property name="text"> + <string>Mode</string> + </property> + </column> + <column> + <property name="text"> + <string>Size</string> + </property> + </column> + <column> + <property name="text"> + <string>Time</string> + </property> + </column> + </widget> + </item> + <item row="1" column="1"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QToolButton" name="putButton"> + <property name="toolTip"> + <string>Press to copy the selected file to the device</string> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="getButton"> + <property name="toolTip"> + <string>Press to copy the selected file from the device</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="localCwd"/> + </item> + <item row="2" column="2"> + <widget class="QLabel" name="deviceCwd"/> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui>