From ec2657947345c7b76f59bbec4ab0898b658c26cc Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 14:59:32 +0200 Subject: [PATCH 1/4] Remove unused _repopulate function It is replaced by the addMachineExtruders function. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index df31cbacdf..23a72b2c3b 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -80,23 +80,6 @@ class ExtruderManager(QObject): if extruder_trains: self.extrudersChanged.emit() - ## (Re)populates the collections of extruders by machine. - def _repopulate(self): - self._extruder_trains = { } - if not UM.Application.getInstance().getGlobalContainerStack(): #No machine has been added yet. - self.extrudersChanged.emit() #Yes, we just cleared the _extruders list! - return #Then leave them empty! - - extruder_trains = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(type = "extruder_train") - for extruder_train in extruder_trains: - machine_id = extruder_train.getMetaDataEntry("machine") - if not machine_id: - continue - if machine_id not in self._extruder_trains: - self._extruder_trains[machine_id] = { } - self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId() - self.extrudersChanged.emit() - def createExtruderTrain(self, extruder_definition, machine_definition, extruder_train_id, position): container_registry = UM.Settings.ContainerRegistry.getInstance() From f461ed0f5f62f2cbf556c32037298bb5c7052514 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 15:26:51 +0200 Subject: [PATCH 2/4] Document singleton Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 23a72b2c3b..b40bb0f664 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -39,7 +39,18 @@ class ExtruderManager(QObject): except KeyError: #Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong. return None + ## The instance of the singleton pattern. + # + # It's None if the extruder manager hasn't been created yet. __instance = None + + ## Gets an instance of the extruder manager, or creates one if no instance + # exists yet. + # + # This is an implementation of singleton. If an extruder manager already + # exists, it is re-used. + # + # \return The extruder manager. @classmethod def getInstance(cls): if not cls.__instance: From 98a0f90dae4764bfb77ca6feaf92412e7716aaf3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 16:56:55 +0200 Subject: [PATCH 3/4] Remove unused variable _active_extruder_index This index is managed by ExtruderManager. Contributes to issues CURA-340 and CURA-1278. --- cura/MachineManagerModel.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 02d8db8290..e7034412f5 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -36,8 +36,6 @@ class MachineManagerModel(QObject): active_machine_id = Preferences.getInstance().getValue("cura/active_machine") - self._active_extruder_index = 0 - if active_machine_id != "": # An active machine was saved, so restore it. self.setActiveMachine(active_machine_id) From 8b1c36393261608ade3257386d613cb72d5e32cd Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 17:37:25 +0200 Subject: [PATCH 4/4] Load current machine's extruders upon creation, start and switch of machines This requires some trickery of initialising the extruder manager before the machine manager is initialised, so that it properly listens to global container stack changes. Contributes to issues CURA-340 and CURA-1278. --- cura/CuraApplication.py | 1 + cura/ExtruderManager.py | 29 ++++++++++++++++++++++++----- cura/ExtrudersModel.py | 11 ++++++++--- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 7edb0bf8bd..37ba6cf7ad 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -351,6 +351,7 @@ class CuraApplication(QtApplication): self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading interface...")) + ExtruderManager.ExtruderManager.getInstance() #Initialise extruder so as to listen to global container stack changes before the first global container stack is set. qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager", MachineManagerModel.createMachineManagerModel) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index b40bb0f664..c71dd27414 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -1,7 +1,7 @@ # Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. -from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject #For communicating data and events to Qt. +from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject, QVariant #For communicating data and events to Qt. import UM.Application #To get the global container stack to find the current machine. import UM.Logger @@ -13,7 +13,7 @@ import UM.Settings.ContainerRegistry #Finding containers by ID. # This keeps a list of extruder stacks for each machine. class ExtruderManager(QObject): ## Signal to notify other components when the list of extruders changes. - extrudersChanged = pyqtSignal() + extrudersChanged = pyqtSignal(QVariant) ## Notify when the user switches the currently active extruder. activeExtruderChanged = pyqtSignal() @@ -21,8 +21,9 @@ class ExtruderManager(QObject): ## Registers listeners and such to listen to changes to the extruders. def __init__(self, parent = None): super().__init__(parent) - self._extruder_trains = { } #Extruders for the current machine. + self._extruder_trains = { } #Per machine, a dictionary of extruder container stack IDs. self._active_extruder_index = 0 + UM.Application.getInstance().globalContainerStackChanged.connect(self._addCurrentMachineExtruders) ## Gets the unique identifier of the currently active extruder stack. # @@ -79,7 +80,7 @@ class ExtruderManager(QObject): for extruder_definition in container_registry.findDefinitionContainers(machine = machine_definition.getId()): position = extruder_definition.getMetaDataEntry("position", None) if not position: - UM.Logger.Log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.getId()) + UM.Logger.log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.getId()) if not container_registry.findContainerStacks(machine = machine_id, position = position): #Doesn't exist yet. name = container_registry.uniqueName(extruder_definition.getId()) #Make a name based on the ID of the definition. self.createExtruderTrain(extruder_definition, machine_definition, name, position) @@ -89,7 +90,7 @@ class ExtruderManager(QObject): for extruder_train in extruder_trains: self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId() if extruder_trains: - self.extrudersChanged.emit() + self.extrudersChanged.emit(machine_definition) def createExtruderTrain(self, extruder_definition, machine_definition, extruder_train_id, position): container_registry = UM.Settings.ContainerRegistry.getInstance() @@ -156,3 +157,21 @@ class ExtruderManager(QObject): container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) container_registry.addContainer(container_stack) + + ## Generates extruders for a specific machine. + def getMachineExtruders(self, machine_definition): + container_registry = UM.Settings.ContainerRegistry.getInstance() + machine_id = machine_definition.getId() + if not machine_id in self._extruder_trains: + UM.Logger.log("w", "Tried to get the extruder trains for machine %s, which doesn't exist.", machine_id) + return + for extruder_train_id in self._extruder_trains[machine_id]: + extruder_train = container_registry.findContainerStacks(id = extruder_train_id) + if extruder_train: + yield extruder_train[0] + + ## Adds the extruders of the currently active machine. + def _addCurrentMachineExtruders(self): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + if global_stack and global_stack.getBottom(): + self.addMachineExtruders(global_stack.getBottom()) \ No newline at end of file diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index 7e00611742..691a5c7690 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -9,7 +9,8 @@ import UM.Qt.ListModel ## Model that holds extruders. # # This model is designed for use by any list of extruders, but specifically -# intended for drop-down lists of extruders in place of settings. +# intended for drop-down lists of the current machine's extruders in place of +# settings. class ExtrudersModel(UM.Qt.ListModel.ListModel): ## Human-readable name of the extruder. NameRole = Qt.UserRole + 1 @@ -37,7 +38,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): #Listen to changes. manager = cura.ExtruderManager.ExtruderManager.getInstance() - manager.extrudersChanged.connect(self._updateExtruders) + manager.extrudersChanged.connect(self._updateExtruders) #When the list of extruders changes in general. + UM.Application.globalContainerStackChanged.connect(self._updateExtruders) #When the current machine changes. self._updateExtruders() ## Update the list of extruders. @@ -46,7 +48,10 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): def _updateExtruders(self): self.clear() manager = cura.ExtruderManager.ExtruderManager.getInstance() - for index, extruder in enumerate(manager._extruder_trains): + global_container_stack = UM.Application.getInstance().getGlobalContainerStack() + if not global_container_stack: + return #There is no machine to get the extruders of. + for index, extruder in manager.getMachineExtruders(global_container_stack.getBottom()): item = { #Construct an item with only the relevant information. "name": extruder.name, "colour": extruder.material.getMetaDataEntry("color_code", default = "#FFFF00"),