Browse Source

Remove AbstractMachine

Having a separate class for the AbstractMachine complicated things; it's behaviour was extremely similar to the GlobalStack so adding one more stack container type in addition to the many similar setting container types we already have adds complexity to the system. Having these different classes for machines and abstract machines also add complexity to the update script as the abstract machines were stored in a separate folder from the machine types.

Because of these reasons we decided to replace the AbstractMachine by a GlobalStack where the is_abstract_machine property metadata property is set to True.

CURA-9514, CURA-9277

Co-authored-by: joeydelarago <joeydelarago@gmail.com>
c.lamboo 2 years ago
parent
commit
8b84db7059

+ 0 - 5
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")
             }
         )

+ 9 - 8
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,
                          })

+ 0 - 52
cura/Settings/AbstractMachine.py

@@ -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)

+ 5 - 5
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(

+ 26 - 4
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(

+ 4 - 4
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
             {