src/eric7/MicroPython/Devices/CircuitPythonUpdater/ShowOutdatedDialog.py

branch
eric7
changeset 9756
9854647c8c5c
parent 9740
90072e10ae9b
child 9768
e2b622afb5ff
diff -r 1a09700229e7 -r 9854647c8c5c src/eric7/MicroPython/Devices/CircuitPythonUpdater/ShowOutdatedDialog.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/Devices/CircuitPythonUpdater/ShowOutdatedDialog.py	Mon Feb 13 17:49:52 2023 +0100
@@ -0,0 +1,156 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to show outdated modules of a connected device.
+"""
+
+import circup
+
+from PyQt6.QtCore import Qt, pyqtSlot
+from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QTreeWidgetItem
+from semver import VersionInfo
+
+from .Ui_ShowOutdatedDialog import Ui_ShowOutdatedDialog
+
+
+class ShowOutdatedDialog(QDialog, Ui_ShowOutdatedDialog):
+    """
+    Class implementing a dialog to show outdated modules of a connected device.
+    """
+
+    def __init__(self, devicePath, selectionMode=False, parent=None):
+        """
+        Constructor
+
+        @param devicePath path to the connected board
+        @type str
+        @param selectionMode flag indicating the activation of the selection mode
+            (defaults to False)
+        @type bool (optional)
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+
+        self.header.clear()
+        self.modulesList.clear()
+
+        self.__checkCount = 0
+        self.__selectionMode = selectionMode
+        if self.__selectionMode:
+            self.buttonBox.setStandardButtons(
+                QDialogButtonBox.StandardButton.Ok
+                | QDialogButtonBox.StandardButton.Cancel
+            )
+        else:
+            self.buttonBox.setStandardButtons(QDialogButtonBox.StandardButton.Close)
+
+        self.__modules = {
+            m.name: m
+            for m in circup.find_modules(devicePath, circup.get_bundles_list())
+            if m.outofdate
+        }
+        if self.__modules:
+            self.header.setText(
+                self.tr(
+                    "The following modules are out of date or probably need an update."
+                    "\nMajor Updates may include breaking changes. Review before"
+                    " updating.\nMPY Format changes require an update."
+                )
+            )
+            for module in self.__modules.values():
+                if isinstance(module.bundle_version, str) and not VersionInfo.isvalid(
+                    module.bundle_version
+                ):
+                    reason = self.tr("Incorrect '__version__' Metadata")
+                    needsUpdate = True
+                elif module.bad_format:
+                    reason = self.tr("Corrupted or Unknown MPY Format")
+                    needsUpdate = True
+                elif module.mpy_mismatch:
+                    reason = self.tr("MPY Format")
+                    needsUpdate = True
+                elif module.major_update:
+                    reason = self.tr("Major Version")
+                    needsUpdate = False
+                else:
+                    reason = self.tr("Minor Version")
+                    needsUpdate = False
+                itm = QTreeWidgetItem(
+                    self.modulesList,
+                    [
+                        module.name,
+                        module.device_version
+                        if module.device_version
+                        else self.tr("unknown"),
+                        module.bundle_version
+                        if module.bundle_version
+                        else self.tr("unknown"),
+                        reason,
+                    ],
+                )
+                if self.__selectionMode:
+                    itm.setFlags(itm.flags() | Qt.ItemFlag.ItemIsUserCheckable)
+                    itm.setCheckState(
+                        0,
+                        Qt.CheckState.Checked
+                        if needsUpdate
+                        else Qt.CheckState.Unchecked,
+                    )
+                    if needsUpdate:
+                        self.__checkCount += 1
+        else:
+            self.header.setText(self.tr("All modules are up-to-date."))
+
+        self.modulesList.sortItems(0, Qt.SortOrder.AscendingOrder)
+        for column in range(self.modulesList.columnCount()):
+            self.modulesList.resizeColumnToContents(column)
+
+        self.__checkCountUpdated()
+
+    @pyqtSlot(QTreeWidgetItem, int)
+    def on_modulesList_itemChanged(self, item, column):
+        """
+        Private slot to handle a change of the check state of an item.
+
+        @param item reference to the changed item
+        @type QTreeWidgetItem
+        @param column changed column
+        @type int
+        """
+        if self.__selectionMode:
+            if item.checkState(0) == Qt.CheckState.Checked:
+                self.__checkCount += 1
+            else:
+                self.__checkCount -= 1
+
+            self.__checkCountUpdated()
+
+    def __checkCountUpdated(self):
+        """
+        Private method to handle an update of the check count.
+        """
+        if self.__selectionMode:
+            self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
+                self.__checkCount > 0
+            )
+
+    def getSelection(self):
+        """
+        Public method to get the list of selected modules.
+
+        @return list of selected modules
+        @rtype circup.Module
+        """
+        results = []
+        if self.__selectionMode:
+            for row in range(self.modulesList.topLevelItemCount()):
+                itm = self.modulesList.topLevelItem(row)
+                if itm.checkState(0) == Qt.CheckState.Checked:
+                    results.append(self.__modules[itm.text(0)])
+
+        return results

eric ide

mercurial