Let Quality/Material/Variant Managers be a proper singleton

Rather than a singleton contained within the CuraApplication class.

Contributes to issue CURA-6600.
This commit is contained in:
Ghostkeeper 2019-08-08 17:04:53 +02:00
parent f31d7798ce
commit 65360c31ef
No known key found for this signature in database
GPG key ID: 86BEF881AE2CF276
4 changed files with 88 additions and 76 deletions

View file

@ -15,7 +15,7 @@ from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qm
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Application import Application from UM.Application import Application
from UM.Decorators import override from UM.Decorators import override, deprecated
from UM.FlameProfiler import pyqtSlot from UM.FlameProfiler import pyqtSlot
from UM.Logger import Logger from UM.Logger import Logger
from UM.Message import Message from UM.Message import Message
@ -23,7 +23,6 @@ from UM.Platform import Platform
from UM.PluginError import PluginNotFoundError from UM.PluginError import PluginNotFoundError
from UM.Resources import Resources from UM.Resources import Resources
from UM.Preferences import Preferences from UM.Preferences import Preferences
from UM.Qt.Bindings import MainWindow
from UM.Qt.QtApplication import QtApplication # The class we're inheriting from. from UM.Qt.QtApplication import QtApplication # The class we're inheriting from.
import UM.Util import UM.Util
from UM.View.SelectionPass import SelectionPass # For typing. from UM.View.SelectionPass import SelectionPass # For typing.
@ -47,7 +46,6 @@ from UM.Scene.Selection import Selection
from UM.Scene.ToolHandle import ToolHandle from UM.Scene.ToolHandle import ToolHandle
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.InstanceContainer import InstanceContainer
from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType
from UM.Settings.SettingFunction import SettingFunction from UM.Settings.SettingFunction import SettingFunction
@ -73,6 +71,8 @@ from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
from cura.Scene import ZOffsetDecorator from cura.Scene import ZOffsetDecorator
from cura.Machines.MachineErrorChecker import MachineErrorChecker from cura.Machines.MachineErrorChecker import MachineErrorChecker
import cura.Machines.MaterialManager #Imported like this to prevent circular imports.
import cura.Machines.QualityManager #Imported like this to prevent circular imports.
from cura.Machines.VariantManager import VariantManager from cura.Machines.VariantManager import VariantManager
from cura.Machines.Models.BuildPlateModel import BuildPlateModel from cura.Machines.Models.BuildPlateModel import BuildPlateModel
@ -136,8 +136,6 @@ from cura import ApplicationMetadata, UltimakerCloudAuthentication
from cura.Settings.GlobalStack import GlobalStack from cura.Settings.GlobalStack import GlobalStack
if TYPE_CHECKING: if TYPE_CHECKING:
from cura.Machines.MaterialManager import MaterialManager
from cura.Machines.QualityManager import QualityManager
from UM.Settings.EmptyInstanceContainer import EmptyInstanceContainer from UM.Settings.EmptyInstanceContainer import EmptyInstanceContainer
numpy.seterr(all = "ignore") numpy.seterr(all = "ignore")
@ -205,9 +203,7 @@ class CuraApplication(QtApplication):
self.empty_quality_container = None # type: EmptyInstanceContainer self.empty_quality_container = None # type: EmptyInstanceContainer
self.empty_quality_changes_container = None # type: EmptyInstanceContainer self.empty_quality_changes_container = None # type: EmptyInstanceContainer
self._variant_manager = None
self._material_manager = None self._material_manager = None
self._quality_manager = None
self._machine_manager = None self._machine_manager = None
self._extruder_manager = None self._extruder_manager = None
self._container_manager = None self._container_manager = None
@ -734,21 +730,6 @@ class CuraApplication(QtApplication):
def run(self): def run(self):
super().run() super().run()
container_registry = self._container_registry
Logger.log("i", "Initializing variant manager")
self._variant_manager = VariantManager(container_registry)
self._variant_manager.initialize()
Logger.log("i", "Initializing material manager")
from cura.Machines.MaterialManager import MaterialManager
self._material_manager = MaterialManager(container_registry, parent = self)
self._material_manager.initialize()
Logger.log("i", "Initializing quality manager")
from cura.Machines.QualityManager import QualityManager
self._quality_manager = QualityManager(self, parent = self)
self._quality_manager.initialize()
Logger.log("i", "Initializing machine manager") Logger.log("i", "Initializing machine manager")
self._machine_manager = MachineManager(self, parent = self) self._machine_manager = MachineManager(self, parent = self)
@ -928,16 +909,19 @@ class CuraApplication(QtApplication):
self._extruder_manager = ExtruderManager() self._extruder_manager = ExtruderManager()
return self._extruder_manager return self._extruder_manager
@deprecated("Use the ContainerTree structure instead.", since = "4.3")
def getVariantManager(self, *args) -> VariantManager: def getVariantManager(self, *args) -> VariantManager:
return self._variant_manager return VariantManager.getInstance()
# Can't deprecate this function since the deprecation marker collides with pyqtSlot!
@pyqtSlot(result = QObject) @pyqtSlot(result = QObject)
def getMaterialManager(self, *args) -> "MaterialManager": def getMaterialManager(self, *args) -> "MaterialManager":
return self._material_manager return cura.Machines.MaterialManager.MaterialManager.getInstance()
# Can't deprecate this function since the deprecation marker collides with pyqtSlot!
@pyqtSlot(result = QObject) @pyqtSlot(result = QObject)
def getQualityManager(self, *args) -> "QualityManager": def getQualityManager(self, *args) -> "QualityManager":
return self._quality_manager return cura.Machines.QualityManager.QualityManager.getInstance()
def getIntentManager(self, *args) -> IntentManager: def getIntentManager(self, *args) -> IntentManager:
return IntentManager.getInstance() return IntentManager.getInstance()

View file

@ -1,4 +1,4 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from collections import defaultdict, OrderedDict from collections import defaultdict, OrderedDict
@ -8,12 +8,13 @@ from typing import Dict, Optional, TYPE_CHECKING, Any, Set, List, cast, Tuple
from PyQt5.Qt import QTimer, QObject, pyqtSignal, pyqtSlot from PyQt5.Qt import QTimer, QObject, pyqtSignal, pyqtSlot
from UM.Application import Application
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
from UM.Decorators import deprecated
from UM.Logger import Logger from UM.Logger import Logger
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.SettingFunction import SettingFunction from UM.Settings.SettingFunction import SettingFunction
from UM.Util import parseBool from UM.Util import parseBool
import cura.CuraApplication #Imported like this to prevent circular imports.
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
from .MaterialNode import MaterialNode from .MaterialNode import MaterialNode
from .MaterialGroup import MaterialGroup from .MaterialGroup import MaterialGroup
@ -37,15 +38,20 @@ if TYPE_CHECKING:
# because it's simple. # because it's simple.
# #
class MaterialManager(QObject): class MaterialManager(QObject):
__instance = None
@classmethod
@deprecated("Use the ContainerTree structure instead.", since = "4.3")
def getInstance(cls) -> "MaterialManager":
if cls.__instance is None:
cls.__instance = MaterialManager()
return cls.__instance
materialsUpdated = pyqtSignal() # Emitted whenever the material lookup tables are updated. materialsUpdated = pyqtSignal() # Emitted whenever the material lookup tables are updated.
favoritesUpdated = pyqtSignal() # Emitted whenever the favorites are changed favoritesUpdated = pyqtSignal() # Emitted whenever the favorites are changed
def __init__(self, container_registry, parent = None): def __init__(self, parent = None):
super().__init__(parent) super().__init__(parent)
self._application = Application.getInstance()
self._container_registry = container_registry # type: ContainerRegistry
# Material_type -> generic material metadata # Material_type -> generic material metadata
self._fallback_materials_map = dict() # type: Dict[str, Dict[str, Any]] self._fallback_materials_map = dict() # type: Dict[str, Dict[str, Any]]
@ -81,16 +87,18 @@ class MaterialManager(QObject):
self._update_timer.setSingleShot(True) self._update_timer.setSingleShot(True)
self._update_timer.timeout.connect(self._updateMaps) self._update_timer.timeout.connect(self._updateMaps)
self._container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged) container_registry = CuraContainerRegistry.getInstance()
self._container_registry.containerAdded.connect(self._onContainerMetadataChanged) container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged)
self._container_registry.containerRemoved.connect(self._onContainerMetadataChanged) container_registry.containerAdded.connect(self._onContainerMetadataChanged)
container_registry.containerRemoved.connect(self._onContainerMetadataChanged)
self._favorites = set() # type: Set[str] self._favorites = set() # type: Set[str]
def initialize(self) -> None: def initialize(self) -> None:
# Find all materials and put them in a matrix for quick search. # Find all materials and put them in a matrix for quick search.
container_registry = CuraContainerRegistry.getInstance()
material_metadatas = {metadata["id"]: metadata for metadata in material_metadatas = {metadata["id"]: metadata for metadata in
self._container_registry.findContainersMetadata(type = "material") if container_registry.findContainersMetadata(type = "material") if
metadata.get("GUID")} # type: Dict[str, Dict[str, Any]] metadata.get("GUID")} # type: Dict[str, Dict[str, Any]]
self._material_group_map = dict() # type: Dict[str, MaterialGroup] self._material_group_map = dict() # type: Dict[str, MaterialGroup]
@ -107,7 +115,7 @@ class MaterialManager(QObject):
continue continue
if root_material_id not in self._material_group_map: if root_material_id not in self._material_group_map:
self._material_group_map[root_material_id] = MaterialGroup(root_material_id, MaterialNode(material_metadatas[root_material_id])) self._material_group_map[root_material_id] = MaterialGroup(root_material_id, MaterialNode(material_metadatas[root_material_id]))
self._material_group_map[root_material_id].is_read_only = self._container_registry.isReadOnly(root_material_id) self._material_group_map[root_material_id].is_read_only = container_registry.isReadOnly(root_material_id)
group = self._material_group_map[root_material_id] group = self._material_group_map[root_material_id]
# Store this material in the group of the appropriate root material. # Store this material in the group of the appropriate root material.
@ -206,7 +214,7 @@ class MaterialManager(QObject):
for material_metadata in material_metadatas.values(): for material_metadata in material_metadatas.values():
self.__addMaterialMetadataIntoLookupTree(material_metadata) self.__addMaterialMetadataIntoLookupTree(material_metadata)
favorites = self._application.getPreferences().getValue("cura/favorite_materials") favorites = cura.CuraApplication.CuraApplication.getInstance().getPreferences().getValue("cura/favorite_materials")
for item in favorites.split(";"): for item in favorites.split(";"):
self._favorites.add(item) self._favorites.add(item)
@ -239,7 +247,7 @@ class MaterialManager(QObject):
(buildplate_name, VariantType.BUILD_PLATE), (buildplate_name, VariantType.BUILD_PLATE),
] ]
variant_manager = self._application.getVariantManager() variant_manager = cura.CuraApplication.CuraApplication.getInstance().getVariantManager()
machine_node = machine_nozzle_buildplate_material_map[definition] machine_node = machine_nozzle_buildplate_material_map[definition]
current_node = machine_node current_node = machine_node
@ -264,7 +272,7 @@ class MaterialManager(QObject):
if error_message is not None: if error_message is not None:
Logger.log("e", "%s It will not be added into the material lookup tree.", error_message) Logger.log("e", "%s It will not be added into the material lookup tree.", error_message)
self._container_registry.addWrongContainerId(material_metadata["id"]) CuraContainerRegistry.getInstance().addWrongContainerId(material_metadata["id"])
return return
# Add the material to the current tree node, which is the deepest (the most specific) branch we can find. # Add the material to the current tree node, which is the deepest (the most specific) branch we can find.
@ -537,6 +545,7 @@ class MaterialManager(QObject):
Logger.log("i", "Unable to remove the material with id %s, because it doesn't exist.", root_material_id) Logger.log("i", "Unable to remove the material with id %s, because it doesn't exist.", root_material_id)
return return
container_registry = CuraContainerRegistry.getInstance()
nodes_to_remove = [material_group.root_material_node] + material_group.derived_material_node_list nodes_to_remove = [material_group.root_material_node] + material_group.derived_material_node_list
# Sort all nodes with respect to the container ID lengths in the ascending order so the base material container # Sort all nodes with respect to the container ID lengths in the ascending order so the base material container
# will be the first one to be removed. We need to do this to ensure that all containers get loaded & deleted. # will be the first one to be removed. We need to do this to ensure that all containers get loaded & deleted.
@ -545,11 +554,11 @@ class MaterialManager(QObject):
# list, so removeContainer() can ignore those ones. # list, so removeContainer() can ignore those ones.
for node in nodes_to_remove: for node in nodes_to_remove:
container_id = node.getMetaDataEntry("id", "") container_id = node.getMetaDataEntry("id", "")
results = self._container_registry.findContainers(id = container_id) results = container_registry.findContainers(id = container_id)
if not results: if not results:
self._container_registry.addWrongContainerId(container_id) container_registry.addWrongContainerId(container_id)
for node in nodes_to_remove: for node in nodes_to_remove:
self._container_registry.removeContainer(node.getMetaDataEntry("id", "")) container_registry.removeContainer(node.getMetaDataEntry("id", ""))
# #
# Methods for GUI # Methods for GUI
@ -567,7 +576,7 @@ class MaterialManager(QObject):
nodes_to_remove = [material_group.root_material_node] + material_group.derived_material_node_list nodes_to_remove = [material_group.root_material_node] + material_group.derived_material_node_list
ids_to_remove = [node.getMetaDataEntry("id", "") for node in nodes_to_remove] ids_to_remove = [node.getMetaDataEntry("id", "") for node in nodes_to_remove]
for extruder_stack in self._container_registry.findContainerStacks(type="extruder_train"): for extruder_stack in CuraContainerRegistry.getInstance().findContainerStacks(type = "extruder_train"):
if extruder_stack.material.getId() in ids_to_remove: if extruder_stack.material.getId() in ids_to_remove:
return False return False
return True return True
@ -577,7 +586,7 @@ class MaterialManager(QObject):
root_material_id = material_node.getMetaDataEntry("base_file") root_material_id = material_node.getMetaDataEntry("base_file")
if root_material_id is None: if root_material_id is None:
return return
if self._container_registry.isReadOnly(root_material_id): if CuraContainerRegistry.getInstance().isReadOnly(root_material_id):
Logger.log("w", "Cannot set name of read-only container %s.", root_material_id) Logger.log("w", "Cannot set name of read-only container %s.", root_material_id)
return return
@ -614,12 +623,13 @@ class MaterialManager(QObject):
return None return None
# Ensure all settings are saved. # Ensure all settings are saved.
self._application.saveSettings() cura.CuraApplication.CuraApplication.getInstance().saveSettings()
# Create a new ID & container to hold the data. # Create a new ID & container to hold the data.
new_containers = [] new_containers = []
container_registry = CuraContainerRegistry.getInstance()
if new_base_id is None: if new_base_id is None:
new_base_id = self._container_registry.uniqueName(base_container.getId()) new_base_id = container_registry.uniqueName(base_container.getId())
new_base_container = copy.deepcopy(base_container) new_base_container = copy.deepcopy(base_container)
new_base_container.getMetaData()["id"] = new_base_id new_base_container.getMetaData()["id"] = new_base_id
new_base_container.getMetaData()["base_file"] = new_base_id new_base_container.getMetaData()["base_file"] = new_base_id
@ -652,7 +662,7 @@ class MaterialManager(QObject):
for container_to_add in new_containers: for container_to_add in new_containers:
container_to_add.setDirty(True) container_to_add.setDirty(True)
self._container_registry.addContainer(container_to_add) container_registry.addContainer(container_to_add)
# if the duplicated material was favorite then the new material should also be added to favorite. # if the duplicated material was favorite then the new material should also be added to favorite.
if root_material_id in self.getFavorites(): if root_material_id in self.getFavorites():
@ -668,12 +678,13 @@ class MaterialManager(QObject):
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")
# Ensure all settings are saved. # Ensure all settings are saved.
self._application.saveSettings() application = cura.CuraApplication.CuraApplication.getInstance()
application.saveSettings()
machine_manager = self._application.getMachineManager() machine_manager = application.getMachineManager()
extruder_stack = machine_manager.activeStack extruder_stack = machine_manager.activeStack
machine_definition = self._application.getGlobalContainerStack().definition machine_definition = application.getGlobalContainerStack().definition
root_material_id = machine_definition.getMetaDataEntry("preferred_material", default = "generic_pla") root_material_id = machine_definition.getMetaDataEntry("preferred_material", default = "generic_pla")
approximate_diameter = str(extruder_stack.approximateMaterialDiameter) approximate_diameter = str(extruder_stack.approximateMaterialDiameter)
@ -685,7 +696,7 @@ class MaterialManager(QObject):
return "" return ""
# Create a new ID & container to hold the data. # Create a new ID & container to hold the data.
new_id = self._container_registry.uniqueName("custom_material") new_id = CuraContainerRegistry.getInstance().uniqueName("custom_material")
new_metadata = {"name": catalog.i18nc("@label", "Custom Material"), new_metadata = {"name": catalog.i18nc("@label", "Custom Material"),
"brand": catalog.i18nc("@label", "Custom"), "brand": catalog.i18nc("@label", "Custom"),
"GUID": str(uuid.uuid4()), "GUID": str(uuid.uuid4()),
@ -702,8 +713,8 @@ class MaterialManager(QObject):
self.materialsUpdated.emit() self.materialsUpdated.emit()
# Ensure all settings are saved. # Ensure all settings are saved.
self._application.getPreferences().setValue("cura/favorite_materials", ";".join(list(self._favorites))) cura.CuraApplication.CuraApplication.getInstance().getPreferences().setValue("cura/favorite_materials", ";".join(list(self._favorites)))
self._application.saveSettings() cura.CuraApplication.CuraApplication.getInstance().saveSettings()
@pyqtSlot(str) @pyqtSlot(str)
def removeFavorite(self, root_material_id: str) -> None: def removeFavorite(self, root_material_id: str) -> None:
@ -715,8 +726,8 @@ class MaterialManager(QObject):
self.materialsUpdated.emit() self.materialsUpdated.emit()
# Ensure all settings are saved. # Ensure all settings are saved.
self._application.getPreferences().setValue("cura/favorite_materials", ";".join(list(self._favorites))) cura.CuraApplication.CuraApplication.getInstance().getPreferences().setValue("cura/favorite_materials", ";".join(list(self._favorites)))
self._application.saveSettings() cura.CuraApplication.CuraApplication.getInstance().saveSettings()
@pyqtSlot() @pyqtSlot()
def getFavorites(self): def getFavorites(self):

View file

@ -1,4 +1,4 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import TYPE_CHECKING, Optional, cast, Dict, List, Set from typing import TYPE_CHECKING, Optional, cast, Dict, List, Set
@ -9,10 +9,11 @@ from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
from UM.Logger import Logger from UM.Logger import Logger
from UM.Util import parseBool from UM.Util import parseBool
from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.InstanceContainer import InstanceContainer
from UM.Decorators import deprecated
import cura.CuraApplication
from cura.Settings.ExtruderStack import ExtruderStack from cura.Settings.ExtruderStack import ExtruderStack
from cura.Machines.ContainerTree import ContainerTree
from .QualityGroup import QualityGroup from .QualityGroup import QualityGroup
from .QualityNode import QualityNode from .QualityNode import QualityNode
@ -20,7 +21,6 @@ if TYPE_CHECKING:
from UM.Settings.Interfaces import DefinitionContainerInterface from UM.Settings.Interfaces import DefinitionContainerInterface
from cura.Settings.GlobalStack import GlobalStack from cura.Settings.GlobalStack import GlobalStack
from .QualityChangesGroup import QualityChangesGroup from .QualityChangesGroup import QualityChangesGroup
from cura.CuraApplication import CuraApplication
# #
@ -34,17 +34,25 @@ if TYPE_CHECKING:
# because it's simple. # because it's simple.
# #
class QualityManager(QObject): class QualityManager(QObject):
__instance = None
@classmethod
@deprecated("Use the ContainerTree structure instead.", since = "4.3")
def getInstance(cls) -> "QualityManager":
if cls.__instance is None:
cls.__instance = QualityManager()
return cls.__instance
qualitiesUpdated = pyqtSignal() qualitiesUpdated = pyqtSignal()
def __init__(self, application: "CuraApplication", parent = None) -> None: def __init__(self, parent = None) -> None:
super().__init__(parent) super().__init__(parent)
self._application = application application = cura.CuraApplication.CuraApplication.getInstance()
self._material_manager = self._application.getMaterialManager() self._material_manager = application.getMaterialManager()
self._container_registry = self._application.getContainerRegistry() self._container_registry = application.getContainerRegistry()
self._empty_quality_container = self._application.empty_quality_container self._empty_quality_container = application.empty_quality_container
self._empty_quality_changes_container = self._application.empty_quality_changes_container self._empty_quality_changes_container = application.empty_quality_changes_container
# For quality lookup # For quality lookup
self._machine_nozzle_buildplate_material_quality_type_to_quality_dict = {} # type: Dict[str, QualityNode] self._machine_nozzle_buildplate_material_quality_type_to_quality_dict = {} # type: Dict[str, QualityNode]
@ -422,8 +430,9 @@ class QualityManager(QObject):
quality_changes_group.name = new_name quality_changes_group.name = new_name
self._application.getMachineManager().activeQualityChanged.emit() application = cura.CuraApplication.CuraApplication.getInstance()
self._application.getMachineManager().activeQualityGroupChanged.emit() application.getMachineManager().activeQualityChanged.emit()
application.getMachineManager().activeQualityGroupChanged.emit()
return new_name return new_name
@ -432,7 +441,7 @@ class QualityManager(QObject):
# #
@pyqtSlot(str, "QVariantMap") @pyqtSlot(str, "QVariantMap")
def duplicateQualityChanges(self, quality_changes_name: str, quality_model_item) -> None: def duplicateQualityChanges(self, quality_changes_name: str, quality_model_item) -> None:
global_stack = self._application.getGlobalContainerStack() global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
if not global_stack: if not global_stack:
Logger.log("i", "No active global stack, cannot duplicate quality changes.") Logger.log("i", "No active global stack, cannot duplicate quality changes.")
return return
@ -461,7 +470,7 @@ class QualityManager(QObject):
# stack and clear the user settings. # stack and clear the user settings.
@pyqtSlot(str) @pyqtSlot(str)
def createQualityChanges(self, base_name: str) -> None: def createQualityChanges(self, base_name: str) -> None:
machine_manager = self._application.getMachineManager() machine_manager = cura.CuraApplication.CuraApplication.getInstance().getMachineManager()
global_stack = machine_manager.activeMachine global_stack = machine_manager.activeMachine
if not global_stack: if not global_stack:
@ -522,7 +531,7 @@ class QualityManager(QObject):
machine_definition_id = getMachineDefinitionIDForQualitySearch(machine.definition) machine_definition_id = getMachineDefinitionIDForQualitySearch(machine.definition)
quality_changes.setDefinition(machine_definition_id) quality_changes.setDefinition(machine_definition_id)
quality_changes.setMetaDataEntry("setting_version", self._application.SettingVersion) quality_changes.setMetaDataEntry("setting_version", cura.CuraApplication.CuraApplication.getInstance().SettingVersion)
return quality_changes return quality_changes

View file

@ -1,16 +1,17 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from collections import OrderedDict from collections import OrderedDict
from typing import Optional, TYPE_CHECKING, Dict from typing import Optional, TYPE_CHECKING, Dict
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
from UM.Decorators import deprecated
from UM.Logger import Logger from UM.Logger import Logger
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Util import parseBool from UM.Util import parseBool
from cura.Machines.ContainerNode import ContainerNode from cura.Machines.ContainerNode import ContainerNode
from cura.Machines.VariantType import VariantType, ALL_VARIANT_TYPES from cura.Machines.VariantType import VariantType, ALL_VARIANT_TYPES
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
from cura.Settings.GlobalStack import GlobalStack from cura.Settings.GlobalStack import GlobalStack
if TYPE_CHECKING: if TYPE_CHECKING:
@ -35,10 +36,16 @@ if TYPE_CHECKING:
# A container is loaded when getVariant() is called to load a variant InstanceContainer. # A container is loaded when getVariant() is called to load a variant InstanceContainer.
# #
class VariantManager: class VariantManager:
__instance = None
def __init__(self, container_registry: ContainerRegistry) -> None: @classmethod
self._container_registry = container_registry @deprecated("Use the ContainerTree structure instead.", since = "4.3")
def getInstance(cls) -> "VariantManager":
if cls.__instance is None:
cls.__instance = VariantManager()
return cls.__instance
def __init__(self) -> None:
self._machine_to_variant_dict_map = dict() # type: Dict[str, Dict["VariantType", Dict[str, ContainerNode]]] self._machine_to_variant_dict_map = dict() # type: Dict[str, Dict["VariantType", Dict[str, ContainerNode]]]
self._machine_to_buildplate_dict_map = dict() # type: Dict[str, Dict[str, ContainerNode]] self._machine_to_buildplate_dict_map = dict() # type: Dict[str, Dict[str, ContainerNode]]
@ -53,7 +60,8 @@ class VariantManager:
self._machine_to_buildplate_dict_map = OrderedDict() self._machine_to_buildplate_dict_map = OrderedDict()
# Cache all variants from the container registry to a variant map for better searching and organization. # Cache all variants from the container registry to a variant map for better searching and organization.
variant_metadata_list = self._container_registry.findContainersMetadata(type = "variant") container_registry = CuraContainerRegistry.getInstance
variant_metadata_list = container_registry.findContainersMetadata(type = "variant")
for variant_metadata in variant_metadata_list: for variant_metadata in variant_metadata_list:
if variant_metadata["id"] in self._exclude_variant_id_list: if variant_metadata["id"] in self._exclude_variant_id_list:
Logger.log("d", "Exclude variant [%s]", variant_metadata["id"]) Logger.log("d", "Exclude variant [%s]", variant_metadata["id"])
@ -85,7 +93,7 @@ class VariantManager:
if variant_definition not in self._machine_to_buildplate_dict_map: if variant_definition not in self._machine_to_buildplate_dict_map:
self._machine_to_buildplate_dict_map[variant_definition] = OrderedDict() self._machine_to_buildplate_dict_map[variant_definition] = OrderedDict()
variant_container = self._container_registry.findContainers(type = "variant", id = variant_metadata["id"])[0] variant_container = container_registry.findContainers(type = "variant", id = variant_metadata["id"])[0]
buildplate_type = variant_container.getProperty("machine_buildplate_type", "value") buildplate_type = variant_container.getProperty("machine_buildplate_type", "value")
if buildplate_type not in self._machine_to_buildplate_dict_map[variant_definition]: if buildplate_type not in self._machine_to_buildplate_dict_map[variant_definition]:
self._machine_to_variant_dict_map[variant_definition][buildplate_type] = dict() self._machine_to_variant_dict_map[variant_definition][buildplate_type] = dict()