diff --git a/cura/Machines/Models/GlobalStacksModel.py b/cura/Machines/Models/GlobalStacksModel.py index 8f13d34ccf..69f2ec3822 100644 --- a/cura/Machines/Models/GlobalStacksModel.py +++ b/cura/Machines/Models/GlobalStacksModel.py @@ -44,6 +44,7 @@ class GlobalStacksModel(ListModel): self._filter_connection_type = None # type: Optional[ConnectionType] self._filter_online_only = False self._filter_capabilities: List[str] = [] # Required capabilities that all listed printers must have. + self._filter_abstract_machines: Optional[bool] = None # Listen to changes CuraContainerRegistry.getInstance().containerAdded.connect(self._onContainerChanged) @@ -54,6 +55,7 @@ class GlobalStacksModel(ListModel): filterConnectionTypeChanged = pyqtSignal() filterCapabilitiesChanged = pyqtSignal() filterOnlineOnlyChanged = pyqtSignal() + filterAbstractMachinesChanged = pyqtSignal() def setFilterConnectionType(self, new_filter: Optional[ConnectionType]) -> None: if self._filter_connection_type != new_filter: @@ -98,6 +100,22 @@ class GlobalStacksModel(ListModel): """ return self._filter_capabilities + def setFilterAbstractMachines(self, new_filter: Optional[bool]) -> None: + if self._filter_abstract_machines != new_filter: + self._filter_abstract_machines = new_filter + self.filterAbstractMachinesChanged.emit() + + @pyqtProperty(bool, fset = setFilterAbstractMachines, notify = filterAbstractMachinesChanged) + def filterAbstractMachines(self) -> Optional[bool]: + """ + Weather we include abstract printers, non-abstract printers or both + + if this is set to None both abstract and non-abstract printers will be included in the list + set to True will only include abstract printers + set to False will only inclde non-abstract printers + """ + return self._filter_abstract_machines + def _onContainerChanged(self, container) -> None: """Handler for container added/removed events from registry""" @@ -130,6 +148,10 @@ class GlobalStacksModel(ListModel): if self._filter_online_only and not is_online: continue + is_abstract_machine = parseBool(container_stack.getMetaDataEntry("is_abstract_machine", False)) + if self._filter_abstract_machines is not None and self._filter_abstract_machines is not is_abstract_machine: + continue + capabilities = set(container_stack.getMetaDataEntry(META_CAPABILITIES, "").split(",")) if set(self._filter_capabilities) - capabilities: # Not all required capabilities are met. continue diff --git a/cura/Machines/Models/MachineListModel.py b/cura/Machines/Models/MachineListModel.py index 55db072180..919d593200 100644 --- a/cura/Machines/Models/MachineListModel.py +++ b/cura/Machines/Models/MachineListModel.py @@ -89,16 +89,19 @@ class MachineListModel(ListModel): machines_manager = CuraApplication.getInstance().getMachineManager() online_machine_stacks = machines_manager.getMachinesWithDefinition(definition_id, online_only = True) - # Create a list item for abstract machine - self.addItem(abstract_machine, len(online_machine_stacks)) + online_machine_stacks = list(filter(lambda machine: machine.hasNetworkedConnection(), online_machine_stacks)) + other_machine_stacks.remove(abstract_machine) if abstract_machine in online_machine_stacks: online_machine_stacks.remove(abstract_machine) + # Create a list item for abstract machine + self.addItem(abstract_machine, True, len(online_machine_stacks)) + # Create list of machines that are children of the abstract machine for stack in online_machine_stacks: if self._show_cloud_printers: - self.addItem(stack) + self.addItem(stack, True) # Remove this machine from the other stack list if stack in other_machine_stacks: other_machine_stacks.remove(stack) @@ -118,25 +121,18 @@ class MachineListModel(ListModel): }) for stack in other_machine_stacks: - self.addItem(stack) + self.addItem(stack, False) - def addItem(self, container_stack: ContainerStack, machine_count: int = 0) -> None: + def addItem(self, container_stack: ContainerStack, is_online: bool, machine_count: int = 0) -> None: if parseBool(container_stack.getMetaDataEntry("hidden", False)): return - # This is required because machines loaded from projects have the is_online="True" but no connection type. - # We want to display them the same way as unconnected printers in this case. - has_connection = False - has_connection |= parseBool(container_stack.getMetaDataEntry("is_abstract_machine", False)) - for connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value]: - has_connection |= connection_type in container_stack.configuredConnectionTypes - self.appendItem({ "componentType": "MACHINE", "name": container_stack.getName(), "id": container_stack.getId(), "metadata": container_stack.getMetaData().copy(), - "isOnline": parseBool(container_stack.getMetaDataEntry("is_online", False)) and has_connection, + "isOnline": is_online, "isAbstractMachine": parseBool(container_stack.getMetaDataEntry("is_abstract_machine", False)), "machineCount": machine_count, }) diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py index b94ca45763..041bd19d3a 100755 --- a/cura/Settings/GlobalStack.py +++ b/cura/Settings/GlobalStack.py @@ -347,6 +347,12 @@ class GlobalStack(CuraContainerStack): nameChanged = pyqtSignal() name = pyqtProperty(str, fget=getName, fset=setName, notify=nameChanged) + def hasNetworkedConnection(self) -> bool: + has_connection = False + for connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value]: + has_connection |= connection_type in self.configuredConnectionTypes + return has_connection + ## private: global_stack_mime = MimeType( name = "application/x-cura-globalstack", diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml index c77545bc03..258b45292e 100644 --- a/resources/qml/Preferences/MachinesPage.qml +++ b/resources/qml/Preferences/MachinesPage.qml @@ -17,7 +17,7 @@ UM.ManagementPage title: catalog.i18nc("@title:tab", "Printers") detailsPlaneCaption: base.currentItem && base.currentItem.name ? base.currentItem.name : "" - model: Cura.GlobalStacksModel { } + model: Cura.GlobalStacksModel { filterAbstractMachines: false } sectionRole: "discoverySource"