eric6/MicroPython/UnknownDevicesDialog.py

changeset 8080
218ca8019eb8
child 8099
522946e53835
diff -r 331e717c458e -r 218ca8019eb8 eric6/MicroPython/UnknownDevicesDialog.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric6/MicroPython/UnknownDevicesDialog.py	Sat Feb 06 19:17:25 2021 +0100
@@ -0,0 +1,256 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to manage the list of unknown devices.
+"""
+
+from PyQt5.QtCore import pyqtSlot, Qt, QUrl, QUrlQuery
+from PyQt5.QtGui import QDesktopServices
+from PyQt5.QtWidgets import QDialog, QListWidgetItem
+
+from E5Gui import E5MessageBox
+
+from .Ui_UnknownDevicesDialog import Ui_UnknownDevicesDialog
+
+import Preferences
+from UI.Info import BugAddress
+
+
+class UnknownDevicesDialog(QDialog, Ui_UnknownDevicesDialog):
+    """
+    Class implementing a dialog to manage the list of unknown devices.
+    """
+    DeviceDataRole = Qt.UserRole
+    ModifiedRole = Qt.UserRole + 1
+    
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super(UnknownDevicesDialog, self).__init__(parent)
+        self.setupUi(self)
+        
+        self.__loadDevices()
+    
+    def __loadDevices(self):
+        """
+        Private method to load the list of unknown devices.
+        """
+        self.deviceList.clear()
+        
+        devices = Preferences.getMicroPython("ManualDevices")
+        for device in devices:
+            itm = QListWidgetItem(
+                self.tr("{0} (0x{1:04x}/0x{2:04x})", "description, VID, PID")
+                .format(device["description"], device["vid"], device["pid"]),
+                self.deviceList)
+            itm.setData(self.DeviceDataRole, device)
+            itm.setData(self.ModifiedRole, False)
+        
+        self.__initialDeviceCount = self.deviceList.count()
+        
+        self.__checkButtons()
+    
+    def __isDirty(self):
+        """
+        Private method to check, if the dialog contains unsaved data.
+        
+        @return flag indicating the presence of unsaved data
+        @rtype bool
+        """
+        dirty = False
+        for row in range(self.deviceList.count()):
+            dirty |= self.deviceList.item(row).data(self.ModifiedRole)
+        dirty |= self.deviceList.count() != self.__initialDeviceCount
+        return dirty
+    
+    def __editItem(self, item):
+        """
+        Private method to edit the given item.
+        
+        @param item reference to the item to be edited
+        @type QListWidgetItem
+        """
+        if item is None:
+            # play it safe
+            return
+        
+        from .AddEditDevicesDialog import AddEditDevicesDialog
+        dlg = AddEditDevicesDialog(deviceData=item.data(self.DeviceDataRole))
+        if dlg.exec() == QDialog.Accepted:
+            deviceDict = dlg.getDeviceDict()
+            item.setData(self.DeviceDataRole, deviceDict)
+            item.setData(self.ModifiedRole, True)
+            
+            item.setText(self.tr("{0} (*)", "list entry is modified")
+                         .format(item.text()))
+    
+    def __saveDeviceData(self):
+        """
+        Private method to save the device data.
+        """
+        devices = []
+        
+        for row in range(self.deviceList.count()):
+            devices.append(self.deviceList.item(row).data(
+                self.DeviceDataRole))
+        Preferences.setMicroPython("ManualDevices", devices)
+        
+        return True
+    
+    @pyqtSlot()
+    def __checkButtons(self):
+        """
+        Private slot to set the enabled state of the buttons.
+        """
+        selectedItemsCount = len(self.deviceList.selectedItems())
+        self.editButton.setEnabled(selectedItemsCount == 1)
+        self.deleteButton.setEnabled(selectedItemsCount >= 1)
+    
+    @pyqtSlot(QListWidgetItem)
+    def on_deviceList_itemActivated(self, item):
+        """
+        Private slot to edit the data of the activated item.
+        
+        @param item reference to the activated item
+        @type QListWidgetItem
+        """
+        self.__editItem(item)
+    
+    @pyqtSlot()
+    def on_deviceList_itemSelectionChanged(self):
+        """
+        Private slot to handle a change of selected items.
+        """
+        self.__checkButtons()
+    
+    @pyqtSlot()
+    def on_editButton_clicked(self):
+        """
+        Private slot to edit the selected item.
+        """
+        itm = self.deviceList.selectedItems()[0]
+        self.__editItem(itm)
+    
+    @pyqtSlot()
+    def on_deleteButton_clicked(self):
+        """
+        Private slot to delete the selected entries.
+        """
+        unsaved = False
+        for itm in self.deviceList.selectedItems():
+            unsaved |= itm.data(self.ModifiedRole)
+        if unsaved:
+            ok = E5MessageBox.yesNo(
+                self,
+                self.tr("Delete Unknown Devices"),
+                self.tr("The selected entries contain some with modified"
+                        " data. Shall they really be deleted?"))
+            if not ok:
+                return
+        
+        for itm in self.deviceList.selectedItems():
+            self.deviceList.takeItem(self.deviceList.row(itm))
+            del itm
+    
+    @pyqtSlot()
+    def on_deleteAllButton_clicked(self):
+        """
+        Private slot to delete all devices.
+        """
+        if self.__isDirty():
+            ok = E5MessageBox.yesNo(
+                self,
+                self.tr("Delete Unknown Devices"),
+                self.tr("The list contains some devices with modified"
+                        " data. Shall they really be deleted?"))
+            if not ok:
+                return
+            
+        self.deviceList.clear()
+    
+    @pyqtSlot()
+    def on_restoreButton_clicked(self):
+        """
+        Private slot to restore the list of unknown devices.
+        """
+        if self.__isDirty():
+            ok = E5MessageBox.yesNo(
+                self,
+                self.tr("Restore Unknown Devices"),
+                self.tr("Restoring the list of unknown devices will overwrite"
+                        " all changes made. Do you really want to restore the"
+                        " list?"))
+            if not ok:
+                return
+        
+        self.__loadDevices()
+    
+    @pyqtSlot()
+    def on_reportButton_clicked(self):
+        """
+        Private slot to report the data of all boards to the eric-bugs email
+        address.
+        """
+        if self.deviceList.count() > 0:
+            bodyList = [
+                "These are my MicroPython devices not yet known by eric."
+                " Please add them.",
+                "",
+            ]
+            
+            for row in range(self.deviceList.count()):
+                deviceDict = self.deviceList.item(row).data(
+                    self.DeviceDataRole)
+                bodyList += [
+                    "Board #{0}:".format(row),
+                    "  VID: {0}".format(deviceDict["vid"]),
+                    "  PID: {0}".format(deviceDict["pid"]),
+                    "  Description: {0}".format(deviceDict["description"]),
+                    "  Device Type: {0}".format(deviceDict["type"]),
+                    "  Data Volume: {0}".format(deviceDict["data_volume"]),
+                    "  Flash Volume: {0}".format(deviceDict["flash_volume"]),
+                    ""
+                ]
+            
+            urlQuery = QUrlQuery()
+            urlQuery.addQueryItem("subject", "Unsupported MicroPython Devices")
+            urlQuery.addQueryItem("body", "\r\n".join(bodyList))
+            
+            url = QUrl("mailto:{0}".format(BugAddress))
+            url.setQuery(urlQuery)
+            
+            QDesktopServices.openUrl(url)
+    
+    @pyqtSlot()
+    def on_buttonBox_accepted(self):
+        """
+        Private slot to handle the OK button press.
+        
+        This action saves the edited list to the preferences store.
+        """
+        self.__saveDeviceData()
+        self.accept()
+    
+    @pyqtSlot()
+    def on_buttonBox_rejected(self):
+        """
+        Private slot handling the cancellation of the dialog.
+        """
+        if self.__isDirty():
+            ok = E5MessageBox.okToClearData(
+                self,
+                self.tr("Unsaved Data"),
+                self.tr("""The list of devices contains some with modified"""
+                        """ data."""),
+                self.__saveDeviceData)
+            if not ok:
+                return
+        
+        self.reject()

eric ide

mercurial