1# Copyright (c) 2020 Ultimaker B.V. 2# Uranium is released under the terms of the LGPLv3 or higher. 3 4from PyQt5.QtCore import Qt, pyqtSlot, pyqtProperty, pyqtSignal 5 6from UM.Application import Application 7from UM.Qt.ListModel import ListModel 8 9from PyQt5.QtQml import QQmlEngine 10 11 12class OutputDevicesModel(ListModel): 13 """A list model providing a list of all registered OutputDevice instances. 14 15 This list model wraps OutputDeviceManager's list of OutputDevice instances. 16 Additionally it provides a function to set OutputDeviceManager's active device. 17 18 Exposes the following roles: 19 * id - The device ID 20 * name - The human-readable name of the device 21 * short_description - The short description of the device 22 * description - The full description of the device 23 * icon_name - The name of the icon used to identify the device 24 * priority - The device priority 25 26 """ 27 28 IdRole = Qt.UserRole + 1 29 NameRole = Qt.UserRole + 2 30 ShortDescriptionRole = Qt.UserRole + 3 31 DescriptionRole = Qt.UserRole + 4 32 IconNameRole = Qt.UserRole + 5 33 PriorityRole = Qt.UserRole + 6 34 35 def __init__(self, parent = None): 36 super().__init__(parent) 37 # Ensure that this model doesn't get garbage collected (Now the bound object is destroyed when the wrapper is) 38 QQmlEngine.setObjectOwnership(self, QQmlEngine.CppOwnership) 39 self._device_manager = Application.getInstance().getOutputDeviceManager() 40 41 self.addRoleName(self.IdRole, "id") 42 self.addRoleName(self.NameRole, "name") 43 self.addRoleName(self.ShortDescriptionRole, "short_description") 44 self.addRoleName(self.DescriptionRole, "description") 45 self.addRoleName(self.IconNameRole, "icon_name") 46 self.addRoleName(self.PriorityRole, "priority") 47 48 self._device_manager.outputDevicesChanged.connect(self._update) 49 self._update() 50 51 @pyqtSlot(str, result = "QVariantMap") 52 def getDevice(self, device_id): 53 index = self.find("id", device_id) 54 if index != -1: 55 return self.getItem(index) 56 57 return { "id": "", "name": "", "short_description": "", "description": "", "icon_name": "save", "priority": -1 } 58 59 outputDevicesChanged = pyqtSignal() 60 61 @pyqtProperty(int, notify = outputDevicesChanged) 62 def deviceCount(self): 63 return self.count 64 65 def _update(self): 66 try: 67 self.beginResetModel() 68 except RuntimeError: 69 # Don't break if the object was garbage collected. 70 return 71 72 self._items.clear() 73 devices = list(self._device_manager.getOutputDevices())[:] # Make a copy here, because we could discover devices during iteration. 74 for device in devices: 75 self._items.append({ 76 "id": device.getId(), 77 "name": device.getName(), 78 "short_description": device.getShortDescription(), 79 "description": device.getDescription(), 80 "icon_name": device.getIconName(), 81 "priority": device.getPriority() 82 }) 83 84 self.sort(lambda i: -i["priority"]) 85 self.endResetModel() 86 87 self.outputDevicesChanged.emit() 88