diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 3cd0ecbf97..f690456913 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -146,8 +146,6 @@ class CuraApplication(QtApplication): DefinitionChangesContainer = Resources.UserType + 10 SettingVisibilityPreset = Resources.UserType + 11 IntentInstanceContainer = Resources.UserType + 12 - AbstractMachineStack = Resources.UserType + 13 - pyqtEnum(ResourceTypes) @@ -426,7 +424,6 @@ class CuraApplication(QtApplication): Resources.addStorageType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes") Resources.addStorageType(self.ResourceTypes.SettingVisibilityPreset, "setting_visibility") Resources.addStorageType(self.ResourceTypes.IntentInstanceContainer, "intent") - Resources.addStorageType(self.ResourceTypes.AbstractMachineStack, "abstract_machine_instances") self._container_registry.addResourceType(self.ResourceTypes.QualityInstanceContainer, "quality") self._container_registry.addResourceType(self.ResourceTypes.QualityChangesInstanceContainer, "quality_changes") @@ -437,7 +434,6 @@ class CuraApplication(QtApplication): self._container_registry.addResourceType(self.ResourceTypes.MachineStack, "machine") self._container_registry.addResourceType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes") self._container_registry.addResourceType(self.ResourceTypes.IntentInstanceContainer, "intent") - self._container_registry.addResourceType(self.ResourceTypes.AbstractMachineStack, "abstract_machine") Resources.addType(self.ResourceTypes.QmlFiles, "qml") Resources.addType(self.ResourceTypes.Firmware, "firmware") @@ -486,7 +482,6 @@ class CuraApplication(QtApplication): ("variant", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.VariantInstanceContainer, "application/x-uranium-instancecontainer"), ("setting_visibility", SettingVisibilityPresetsModel.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.SettingVisibilityPreset, "application/x-uranium-preferences"), ("machine", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer"), - ("abstract_machine", 1): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer"), ("extruder", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer") } ) diff --git a/cura/Machines/Models/MachineListModel.py b/cura/Machines/Models/MachineListModel.py index f3781cfd60..4b80410018 100644 --- a/cura/Machines/Models/MachineListModel.py +++ b/cura/Machines/Models/MachineListModel.py @@ -8,9 +8,8 @@ from UM.Settings.ContainerStack import ContainerStack from UM.i18n import i18nCatalog from UM.Util import parseBool -from cura.Settings.AbstractMachine import AbstractMachine from cura.Settings.CuraContainerRegistry import CuraContainerRegistry -from cura.Settings.GlobalStack import GlobalStack +from cura.Settings.GlobalStack import GlobalStack, getMachinesWithDefinition class MachineListModel(ListModel): @@ -19,8 +18,8 @@ class MachineListModel(ListModel): HasRemoteConnectionRole = Qt.ItemDataRole.UserRole + 3 MetaDataRole = Qt.ItemDataRole.UserRole + 4 IsOnlineRole = Qt.ItemDataRole.UserRole + 5 - MachineTypeRole = Qt.ItemDataRole.UserRole + 6 - MachineCountRole = Qt.ItemDataRole.UserRole + 7 + MachineCountRole = Qt.ItemDataRole.UserRole + 6 + IsAbstractMachine = Qt.ItemDataRole.UserRole + 7 def __init__(self, parent=None) -> None: super().__init__(parent) @@ -32,8 +31,8 @@ class MachineListModel(ListModel): self.addRoleName(self.HasRemoteConnectionRole, "hasRemoteConnection") self.addRoleName(self.MetaDataRole, "metadata") self.addRoleName(self.IsOnlineRole, "isOnline") - self.addRoleName(self.MachineTypeRole, "machineType") self.addRoleName(self.MachineCountRole, "machineCount") + self.addRoleName(self.IsAbstractMachine, "isAbstractMachine") self._change_timer = QTimer() self._change_timer.setInterval(200) @@ -61,14 +60,16 @@ class MachineListModel(ListModel): other_machine_stacks = CuraContainerRegistry.getInstance().findContainerStacks(type="machine") - abstract_machine_stacks = CuraContainerRegistry.getInstance().findContainerStacks(type = "abstract_machine") + abstract_machine_stacks = CuraContainerRegistry.getInstance().findContainerStacks(is_abstract_machine = "True") abstract_machine_stacks.sort(key = lambda machine: machine.getName(), reverse = True) for abstract_machine in abstract_machine_stacks: - online_machine_stacks = AbstractMachine.getMachines(abstract_machine, online_only = True) + definition_id = abstract_machine.definition.getId() + online_machine_stacks = getMachinesWithDefinition(definition_id, online_only = True) # Create a list item for abstract machine self.addItem(abstract_machine, len(online_machine_stacks)) + other_machine_stacks.remove(abstract_machine) # Create list of machines that are children of the abstract machine for stack in online_machine_stacks: @@ -87,6 +88,6 @@ class MachineListModel(ListModel): "id": container_stack.getId(), "metadata": container_stack.getMetaData().copy(), "isOnline": parseBool(container_stack.getMetaDataEntry("is_online", False)), - "machineType": container_stack.getMetaDataEntry("type"), + "isAbstractMachine": parseBool(container_stack.getMetaDataEntry("is_abstract_machine", False)), "machineCount": machine_count, }) diff --git a/cura/Settings/AbstractMachine.py b/cura/Settings/AbstractMachine.py deleted file mode 100644 index 86909b6e29..0000000000 --- a/cura/Settings/AbstractMachine.py +++ /dev/null @@ -1,52 +0,0 @@ -from typing import List - -from UM.Settings.ContainerStack import ContainerStack -from UM.Util import parseBool -from cura.PrinterOutput.PrinterOutputDevice import ConnectionType -from cura.Settings.GlobalStack import GlobalStack -from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase -from UM.Settings.ContainerRegistry import ContainerRegistry - - -class AbstractMachine(GlobalStack): - """ Represents a group of machines of the same type. This allows the user to select settings before selecting a printer. """ - - def __init__(self, container_id: str) -> None: - super().__init__(container_id) - self.setMetaDataEntry("type", "abstract_machine") - - @classmethod - def getMachines(cls, abstract_machine: ContainerStack, online_only = False) -> List[ContainerStack]: - """ Fetches all container stacks that match definition_id with an abstract machine. - - :param abstractMachine: The abstract machine stack. - :return: A list of Containers or an empty list if abstract_machine is not an "abstract_machine" - """ - if not abstract_machine.getMetaDataEntry("type") == "abstract_machine": - return [] - - from cura.CuraApplication import CuraApplication # In function to avoid circular import - application = CuraApplication.getInstance() - registry = application.getContainerRegistry() - - machines = registry.findContainerStacks(type="machine") - # Filter machines that match definition - machines = filter(lambda machine: machine.definition.id == abstract_machine.definition.getId(), machines) - # Filter only LAN and Cloud printers - machines = filter(lambda machine: ConnectionType.CloudConnection in machine.configuredConnectionTypes or ConnectionType.NetworkConnection in machine.configuredConnectionTypes, machines) - if online_only: - # LAN printers have is_online = False but should still be included - machines = filter(lambda machine: parseBool(machine.getMetaDataEntry("is_online", False) or ConnectionType.NetworkConnection in machine.configuredConnectionTypes), machines) - - return list(machines) - - -## private: -_abstract_machine_mime = MimeType( - name = "application/x-cura-abstract-machine", - comment = "Cura Abstract Machine", - suffixes = ["global.cfg"] -) - -MimeTypeDatabase.addMimeType(_abstract_machine_mime) -ContainerRegistry.addContainerTypeByName(AbstractMachine, "abstract_machine", _abstract_machine_mime.name) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index d711a61243..5a745f8f0a 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -9,7 +9,6 @@ from UM.Settings.Interfaces import DefinitionContainerInterface from UM.Settings.InstanceContainer import InstanceContainer from cura.Machines.ContainerTree import ContainerTree -from .AbstractMachine import AbstractMachine from .GlobalStack import GlobalStack from .ExtruderStack import ExtruderStack @@ -268,21 +267,21 @@ class CuraStackBuilder: return definition_changes_container @classmethod - def createAbstractMachine(cls, definition_id: str) -> Optional[AbstractMachine]: + def createAbstractMachine(cls, definition_id: str) -> Optional[GlobalStack]: """Create a new instance of an abstract machine. :param definition_id: The ID of the machine definition to use. :return: The new Abstract Machine or None if an error occurred. """ - abstract_machine_id = definition_id + "_abstract_machine" + abstract_machine_id = f"{definition_id}_abstract_machine" from cura.CuraApplication import CuraApplication application = CuraApplication.getInstance() registry = application.getContainerRegistry() container_tree = ContainerTree.getInstance() - if registry.findContainerStacks(type = "abstract_machine", id = abstract_machine_id): + if registry.findContainerStacks(is_abstract_machine = "True", id = abstract_machine_id): # This abstract machine already exists return None @@ -296,7 +295,8 @@ class CuraStackBuilder: machine_node = container_tree.machines[machine_definition.getId()] name = machine_definition.getName() - stack = AbstractMachine(abstract_machine_id) + stack = GlobalStack(abstract_machine_id) + stack.setMetaDataEntry("is_abstract_machine", True) stack.setMetaDataEntry("is_online", True) stack.setDefinition(machine_definition) cls.createUserContainer( diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py index f0a6946f88..6a14f10fe4 100755 --- a/cura/Settings/GlobalStack.py +++ b/cura/Settings/GlobalStack.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019 Ultimaker B.V. +# Copyright (c) 2022 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from collections import defaultdict @@ -8,10 +8,9 @@ import uuid from PyQt6.QtCore import pyqtProperty, pyqtSlot, pyqtSignal -from UM.Decorators import deprecated, override +from UM.Decorators import override from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase from UM.Settings.ContainerStack import ContainerStack -from UM.Settings.SettingInstance import InstanceState from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.Interfaces import PropertyEvaluationContext from UM.Logger import Logger @@ -344,13 +343,36 @@ class GlobalStack(CuraContainerStack): def getName(self) -> str: return self._metadata.get("group_name", self._metadata.get("name", "")) - def setName(self, name: "str") -> None: + def setName(self, name: str) -> None: super().setName(name) nameChanged = pyqtSignal() name = pyqtProperty(str, fget=getName, fset=setName, notify=nameChanged) +def getMachinesWithDefinition(definition_id: str, online_only = False) -> List[ContainerStack]: + """ Fetches all container stacks that match definition_id. + + :param definition_id: The id of the machine definition. + :return: A list of Containers that match definition_id + """ + from cura.CuraApplication import CuraApplication # In function to avoid circular import + application = CuraApplication.getInstance() + registry = application.getContainerRegistry() + + machines = registry.findContainerStacks(type="machine") + # Filter machines that match definition + machines = filter(lambda machine: machine.definition.id == definition_id, machines) + # Filter only LAN and Cloud printers + machines = filter(lambda machine: ConnectionType.CloudConnection in machine.configuredConnectionTypes or + ConnectionType.NetworkConnection in machine.configuredConnectionTypes, machines) + if online_only: + # LAN printers can have is_online = False but should still be included, their online status is only checked when + # they are the active printer. + machines = filter(lambda machine: parseBool(machine.getMetaDataEntry("is_online", False) or + ConnectionType.NetworkConnection in machine.configuredConnectionTypes), machines) + + return list(machines) ## private: global_stack_mime = MimeType( diff --git a/resources/qml/PrinterSelector/MachineListButton.qml b/resources/qml/PrinterSelector/MachineListButton.qml index 4511c72b4c..55ae5497d9 100644 --- a/resources/qml/PrinterSelector/MachineListButton.qml +++ b/resources/qml/PrinterSelector/MachineListButton.qml @@ -30,8 +30,8 @@ Button height: UM.Theme.getSize("medium_button").height width: UM.Theme.getSize("medium_button").width color: UM.Theme.getColor("machine_selector_printer_icon") - visible: model.machineType == "abstract_machine" || !model.isOnline - source: model.machineType == "abstract_machine" ? UM.Theme.getIcon("PrinterTriple", "medium") : UM.Theme.getIcon("Printer", "medium") + visible: model.isAbstractMachine || !model.isOnline + source: model.isAbstractMachine ? UM.Theme.getIcon("PrinterTriple", "medium") : UM.Theme.getIcon("Printer", "medium") anchors { @@ -51,7 +51,7 @@ Button leftMargin: UM.Theme.getSize("default_margin").width } text: machineListButton.text - font: model.machineType == "abstract_machine" ? UM.Theme.getFont("medium_bold") : UM.Theme.getFont("medium") + font: model.isAbstractMachine ? UM.Theme.getFont("medium_bold") : UM.Theme.getFont("medium") visible: text != "" elide: Text.ElideRight } @@ -68,7 +68,7 @@ Button top: buttonText.top bottom: buttonText.bottom } - visible: model.machineType == "abstract_machine" + visible: model.isAbstractMachine UM.Label {