diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 34f2fb5744..a4e86626dc 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -62,7 +62,10 @@ from cura.Machines.Models.CustomQualityProfilesModel import CustomQualityProfile from cura.Machines.Models.Other.MultiBuildPlateModel import MultiBuildPlateModel -from cura.Machines.Models.MaterialsModel import BrandMaterialsModel, GenericMaterialsModel, MaterialsModel +from cura.Machines.Models.MaterialManagementModel import MaterialManagementModel +from cura.Machines.Models.GenericMaterialsModel import GenericMaterialsModel +from cura.Machines.Models.BrandMaterialsModel import BrandMaterialsModel + from cura.Settings.SettingInheritanceManager import SettingInheritanceManager from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager @@ -954,7 +957,7 @@ class CuraApplication(QtApplication): qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") - qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel") + qmlRegisterType(MaterialManagementModel, "Cura", 1, 0, "MaterialManagementModel") qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel") qmlRegisterSingletonType(QualityProfilesModel, "Cura", 1, 0, "QualityProfilesModel", self.getQualityProfileModel) diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py new file mode 100644 index 0000000000..1ad4da8513 --- /dev/null +++ b/cura/Machines/Models/BaseMaterialsModel.py @@ -0,0 +1,71 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from typing import Optional +from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty + +from UM.Logger import Logger +from UM.Qt.ListModel import ListModel + + +def getAvailableMaterials(extruder_position: Optional[int] = None): + from cura.CuraApplication import CuraApplication + machine_manager = CuraApplication.getInstance().getMachineManager() + extruder_manager = CuraApplication.getInstance().getExtruderManager() + + material_manager = CuraApplication.getInstance()._material_manager + + active_global_stack = machine_manager._global_container_stack + extruder_stack = extruder_manager.getActiveExtruderStack() + if extruder_position is not None: + if active_global_stack is not None: + extruder_stack = active_global_stack.extruders.get(str(extruder_position)) + + if active_global_stack is None or extruder_stack is None: + Logger.log("d", "Active global stack [%s] or extruder stack [%s] is None, setting material list to empty.", + active_global_stack, extruder_stack) + return + + machine_definition_id = active_global_stack.definition.getId() + variant_name = None + if extruder_stack.variant.getId() != "empty_variant": + variant_name = extruder_stack.variant.getName() + diameter = extruder_stack.approximateMaterialDiameter + + # Fetch the available materials (ContainerNode) for the current active machine and extruder setup. + result_dict = material_manager.getAvailableMaterials(machine_definition_id, variant_name, diameter) + return result_dict + + +class BaseMaterialsModel(ListModel): + RootMaterialIdRole = Qt.UserRole + 1 + IdRole = Qt.UserRole + 2 + NameRole = Qt.UserRole + 3 + BrandRole = Qt.UserRole + 4 + MaterialRole = Qt.UserRole + 5 + ColorRole = Qt.UserRole + 6 + ContainerNodeRole = Qt.UserRole + 7 + + extruderPositionChanged = pyqtSignal() + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.RootMaterialIdRole, "root_material_id") + self.addRoleName(self.IdRole, "id") + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.BrandRole, "brand") + self.addRoleName(self.MaterialRole, "material") + self.addRoleName(self.ColorRole, "color_name") + self.addRoleName(self.ContainerNodeRole, "container_node") + + self._extruder_position = 0 + + def setExtruderPosition(self, position: int): + if self._extruder_position != position: + self._extruder_position = position + self.extruderPositionChanged.emit() + + @pyqtProperty(int, fset = setExtruderPosition, notify = extruderPositionChanged) + def extruderPosition(self) -> int: + return self._extruder_positoin diff --git a/cura/Machines/Models/BrandMaterialsModel.py b/cura/Machines/Models/BrandMaterialsModel.py new file mode 100644 index 0000000000..9e2aaa02e8 --- /dev/null +++ b/cura/Machines/Models/BrandMaterialsModel.py @@ -0,0 +1,112 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty + +from UM.Qt.ListModel import ListModel + +from .BaseMaterialsModel import BaseMaterialsModel, getAvailableMaterials + + +class MaterialsModelGroupedByType(ListModel): + NameRole = Qt.UserRole + 1 + ColorsRole = Qt.UserRole + 2 + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.ColorsRole, "colors") + + +## Brand --> Material Type -> list of materials +class BrandMaterialsModel(ListModel): + NameRole = Qt.UserRole + 1 + MaterialsRole = Qt.UserRole + 2 + + extruderPositionChanged = pyqtSignal() + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.MaterialsRole, "materials") + + self._extruder_position = 0 + + from cura.CuraApplication import CuraApplication + self._machine_manager = CuraApplication.getInstance().getMachineManager() + extruder_manager = CuraApplication.getInstance().getExtruderManager() + material_manager = CuraApplication.getInstance()._material_manager + + self._machine_manager.globalContainerChanged.connect(self._update) + extruder_manager.activeExtruderChanged.connect(self._update) + material_manager.materialsUpdated.connect(self._update) + + self._update() + + def setExtruderPosition(self, position: int): + if self._extruder_position != position: + self._extruder_position = position + self.extruderPositionChanged.emit() + + @pyqtProperty(int, fset = setExtruderPosition, notify = extruderPositionChanged) + def extruderPosition(self) -> int: + return self._extruder_position + + def _update(self): + global_stack = self._machine_manager.activeMachine + if global_stack is None: + self.setItems([]) + return + + result_dict = getAvailableMaterials(self._extruder_position) + if result_dict is None: + self.setItems([]) + return + + brand_item_list = [] + brand_group_dict = {} + for root_material_id, container_node in result_dict.items(): + metadata = container_node.metadata + brand = metadata["brand"] + # Only add results for generic materials + if brand.lower() == "generic": + continue + + if brand not in brand_group_dict: + brand_group_dict[brand] = {} + + material_type = metadata["material"] + if material_type not in brand_group_dict[brand]: + brand_group_dict[brand][material_type] = [] + + item = {"root_material_id": root_material_id, + "id": metadata["id"], + "name": metadata["name"], + "brand": metadata["brand"], + "material": metadata["material"], + "color_name": metadata["color_name"], + "container_node": container_node + } + brand_group_dict[brand][material_type].append(item) + + for brand, material_dict in brand_group_dict.items(): + brand_item = {"name": brand, + "materials": MaterialsModelGroupedByType(self)} + + material_type_item_list = [] + for material_type, material_list in material_dict.items(): + material_type_item = {"name": material_type, + "colors": BaseMaterialsModel(self)} + material_type_item["colors"].clear() + material_type_item["colors"].setItems(material_list) + + material_type_item_list.append(material_type_item) + + brand_item["materials"].setItems(material_type_item_list) + + brand_item_list.append(brand_item) + + self.setItems(brand_item_list) + diff --git a/cura/Machines/Models/GenericMaterialsModel.py b/cura/Machines/Models/GenericMaterialsModel.py new file mode 100644 index 0000000000..dd18abe7c3 --- /dev/null +++ b/cura/Machines/Models/GenericMaterialsModel.py @@ -0,0 +1,54 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from .BaseMaterialsModel import BaseMaterialsModel, getAvailableMaterials + + +class GenericMaterialsModel(BaseMaterialsModel): + + def __init__(self, parent = None): + super().__init__(parent) + + from cura.CuraApplication import CuraApplication + self._machine_manager = CuraApplication.getInstance().getMachineManager() + self._extruder_manager = CuraApplication.getInstance().getExtruderManager() + self._material_manager = CuraApplication.getInstance()._material_manager + + self._machine_manager.globalContainerChanged.connect(self._update) + self._extruder_manager.activeExtruderChanged.connect(self._update) + self._material_manager.materialsUpdated.connect(self._update) + + self._update() + + def _update(self): + global_stack = self._machine_manager.activeMachine + if global_stack is None: + self.setItems([]) + return + + result_dict = getAvailableMaterials(self._extruder_position) + if result_dict is None: + self.setItems([]) + return + + item_list = [] + for root_material_id, container_node in result_dict.items(): + metadata = container_node.metadata + # Only add results for generic materials + if metadata["brand"].lower() != "generic": + continue + + item = {"root_material_id": root_material_id, + "id": metadata["id"], + "name": metadata["name"], + "brand": metadata["brand"], + "material": metadata["material"], + "color_name": metadata["color_name"], + "container_node": container_node + } + item_list.append(item) + + # Sort the item list by material name alphabetically + item_list = sorted(item_list, key = lambda d: d["name"]) + + self.setItems(item_list) diff --git a/cura/Machines/Models/MaterialManagementModel.py b/cura/Machines/Models/MaterialManagementModel.py new file mode 100644 index 0000000000..35173129e0 --- /dev/null +++ b/cura/Machines/Models/MaterialManagementModel.py @@ -0,0 +1,101 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from PyQt5.QtCore import Qt, pyqtProperty + +from UM.Qt.ListModel import ListModel + +from .BaseMaterialsModel import getAvailableMaterials + + +# +# This model is for the Material management page. +# +class MaterialManagementModel(ListModel): + RootMaterialIdRole = Qt.UserRole + 1 + DisplayNameRole = Qt.UserRole + 2 + BrandRole = Qt.UserRole + 3 + MaterialTypeRole = Qt.UserRole + 4 + ColorNameRole = Qt.UserRole + 5 + ColorCodeRole = Qt.UserRole + 6 + ContainerNodeRole = Qt.UserRole + 7 + ContainerIdRole = Qt.UserRole + 8 + + DescriptionRole = Qt.UserRole + 9 + AdhesionInfoRole = Qt.UserRole + 10 + ApproximateDiameterRole = Qt.UserRole + 11 + GuidRole = Qt.UserRole + 12 + DensityRole = Qt.UserRole + 13 + DiameterRole = Qt.UserRole + 14 + IsReadOnlyRole = Qt.UserRole + 15 + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.RootMaterialIdRole, "root_material_id") + self.addRoleName(self.DisplayNameRole, "name") + self.addRoleName(self.BrandRole, "brand") + self.addRoleName(self.MaterialTypeRole, "material") + self.addRoleName(self.ColorNameRole, "color_name") + self.addRoleName(self.ColorCodeRole, "color_code") + self.addRoleName(self.ContainerNodeRole, "container_node") + self.addRoleName(self.ContainerIdRole, "container_id") + + self.addRoleName(self.DescriptionRole, "description") + self.addRoleName(self.AdhesionInfoRole, "adhesion_info") + self.addRoleName(self.ApproximateDiameterRole, "approximate_diameter") + self.addRoleName(self.GuidRole, "guid") + self.addRoleName(self.DensityRole, "density") + self.addRoleName(self.DiameterRole, "diameter") + self.addRoleName(self.IsReadOnlyRole, "is_read_only") + + from cura.CuraApplication import CuraApplication + self._container_registry = CuraApplication.getInstance().getContainerRegistry() + self._machine_manager = CuraApplication.getInstance().getMachineManager() + extruder_manager = CuraApplication.getInstance().getExtruderManager() + material_manager = CuraApplication.getInstance()._material_manager + + self._machine_manager.globalContainerChanged.connect(self._update) + extruder_manager.activeExtruderChanged.connect(self._update) + material_manager.materialsUpdated.connect(self._update) + + self._update() + + def _update(self): + global_stack = self._machine_manager.activeMachine + if global_stack is None: + self.setItems([]) + return + + result_dict = getAvailableMaterials() + if result_dict is None: + self.setItems([]) + return + + material_list = [] + for root_material_id, container_node in result_dict.items(): + keys_to_fetch = ("name", + "brand", + "material", + "color_name", + "color_code", + "description", + "adhesion_info", + "approximate_diameter",) + + item = {"root_material_id": container_node.metadata["base_file"], + "container_node": container_node, + "guid": container_node.metadata["GUID"], + "container_id": container_node.metadata["id"], + "density": container_node.metadata.get("properties", {}).get("density", ""), + "diameter": container_node.metadata.get("properties", {}).get("diameter", ""), + "is_read_only": self._container_registry.isReadOnly(container_node.metadata["id"]), + } + + for key in keys_to_fetch: + item[key] = container_node.metadata.get(key, "") + + material_list.append(item) + + material_list = sorted(material_list, key = lambda k: (k["brand"].lower(), k["name"])) + self.setItems(material_list) diff --git a/cura/Machines/Models/MaterialsModel.py b/cura/Machines/Models/MaterialsModel.py deleted file mode 100644 index 5ef5845371..0000000000 --- a/cura/Machines/Models/MaterialsModel.py +++ /dev/null @@ -1,317 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from typing import Optional -from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty - -from UM.Logger import Logger -from UM.Qt.ListModel import ListModel - - -def getAvailableMaterials(extruder_position: Optional[int] = None): - from cura.CuraApplication import CuraApplication - machine_manager = CuraApplication.getInstance().getMachineManager() - extruder_manager = CuraApplication.getInstance().getExtruderManager() - - material_manager = CuraApplication.getInstance()._material_manager - - active_global_stack = machine_manager._global_container_stack - extruder_stack = extruder_manager.getActiveExtruderStack() - if extruder_position is not None: - if active_global_stack is not None: - extruder_stack = active_global_stack.extruders.get(str(extruder_position)) - - if active_global_stack is None or extruder_stack is None: - Logger.log("d", "Active global stack [%s] or extruder stack [%s] is None, setting material list to empty.", - active_global_stack, extruder_stack) - return - - machine_definition_id = active_global_stack.definition.getId() - variant_name = None - if extruder_stack.variant.getId() != "empty_variant": - variant_name = extruder_stack.variant.getName() - diameter = extruder_stack.approximateMaterialDiameter - - # Fetch the available materials (ContainerNode) for the current active machine and extruder setup. - result_dict = material_manager.getAvailableMaterials(machine_definition_id, variant_name, diameter) - return result_dict - - -class BaseMaterialsModel(ListModel): - RootMaterialIdRole = Qt.UserRole + 1 - IdRole = Qt.UserRole + 2 - NameRole = Qt.UserRole + 3 - BrandRole = Qt.UserRole + 4 - MaterialRole = Qt.UserRole + 5 - ColorRole = Qt.UserRole + 6 - ContainerNodeRole = Qt.UserRole + 7 - - extruderPositionChanged = pyqtSignal() - - def __init__(self, parent = None): - super().__init__(parent) - - self.addRoleName(self.RootMaterialIdRole, "root_material_id") - self.addRoleName(self.IdRole, "id") - self.addRoleName(self.NameRole, "name") - self.addRoleName(self.BrandRole, "brand") - self.addRoleName(self.MaterialRole, "material") - self.addRoleName(self.ColorRole, "color_name") - self.addRoleName(self.ContainerNodeRole, "container_node") - - self._extruder_position = 0 - - def setExtruderPosition(self, position: int): - if self._extruder_position != position: - self._extruder_position = position - self.extruderPositionChanged.emit() - - @pyqtProperty(int, fset = setExtruderPosition, notify = extruderPositionChanged) - def extruderPosition(self) -> int: - return self._extruder_positoin - - -class GenericMaterialsModel(BaseMaterialsModel): - - def __init__(self, parent = None): - super().__init__(parent) - - from cura.CuraApplication import CuraApplication - self._machine_manager = CuraApplication.getInstance().getMachineManager() - self._extruder_manager = CuraApplication.getInstance().getExtruderManager() - self._material_manager = CuraApplication.getInstance()._material_manager - - self._machine_manager.globalContainerChanged.connect(self._update) - self._extruder_manager.activeExtruderChanged.connect(self._update) - self._material_manager.materialsUpdated.connect(self._update) - - self._update() - - def _update(self): - global_stack = self._machine_manager.activeMachine - if global_stack is None: - self.setItems([]) - return - - result_dict = getAvailableMaterials(self._extruder_position) - if result_dict is None: - self.setItems([]) - return - - item_list = [] - for root_material_id, container_node in result_dict.items(): - metadata = container_node.metadata - # Only add results for generic materials - if metadata["brand"].lower() != "generic": - continue - - item = {"root_material_id": root_material_id, - "id": metadata["id"], - "name": metadata["name"], - "brand": metadata["brand"], - "material": metadata["material"], - "color_name": metadata["color_name"], - "container_node": container_node - } - item_list.append(item) - - # Sort the item list by material name alphabetically - item_list = sorted(item_list, key = lambda d: d["name"]) - - self.setItems(item_list) - - -class MaterialsModelGroupedByType(ListModel): - NameRole = Qt.UserRole + 1 - ColorsRole = Qt.UserRole + 2 - - def __init__(self, parent = None): - super().__init__(parent) - - self.addRoleName(self.NameRole, "name") - self.addRoleName(self.ColorsRole, "colors") - - -## Brand --> Material Type -> list of materials -class BrandMaterialsModel(ListModel): - NameRole = Qt.UserRole + 1 - MaterialsRole = Qt.UserRole + 2 - - extruderPositionChanged = pyqtSignal() - - def __init__(self, parent = None): - super().__init__(parent) - - self.addRoleName(self.NameRole, "name") - self.addRoleName(self.MaterialsRole, "materials") - - self._extruder_position = 0 - - from cura.CuraApplication import CuraApplication - self._machine_manager = CuraApplication.getInstance().getMachineManager() - extruder_manager = CuraApplication.getInstance().getExtruderManager() - material_manager = CuraApplication.getInstance()._material_manager - - self._machine_manager.globalContainerChanged.connect(self._update) - extruder_manager.activeExtruderChanged.connect(self._update) - material_manager.materialsUpdated.connect(self._update) - - self._update() - - def setExtruderPosition(self, position: int): - if self._extruder_position != position: - self._extruder_position = position - self.extruderPositionChanged.emit() - - @pyqtProperty(int, fset = setExtruderPosition, notify = extruderPositionChanged) - def extruderPosition(self) -> int: - return self._extruder_position - - def _update(self): - global_stack = self._machine_manager.activeMachine - if global_stack is None: - self.setItems([]) - return - - result_dict = getAvailableMaterials(self._extruder_position) - if result_dict is None: - self.setItems([]) - return - - brand_item_list = [] - brand_group_dict = {} - for root_material_id, container_node in result_dict.items(): - metadata = container_node.metadata - brand = metadata["brand"] - # Only add results for generic materials - if brand.lower() == "generic": - continue - - if brand not in brand_group_dict: - brand_group_dict[brand] = {} - - material_type = metadata["material"] - if material_type not in brand_group_dict[brand]: - brand_group_dict[brand][material_type] = [] - - item = {"root_material_id": root_material_id, - "id": metadata["id"], - "name": metadata["name"], - "brand": metadata["brand"], - "material": metadata["material"], - "color_name": metadata["color_name"], - "container_node": container_node - } - brand_group_dict[brand][material_type].append(item) - - for brand, material_dict in brand_group_dict.items(): - brand_item = {"name": brand, - "materials": MaterialsModelGroupedByType(self)} - - material_type_item_list = [] - for material_type, material_list in material_dict.items(): - material_type_item = {"name": material_type, - "colors": BaseMaterialsModel(self)} - material_type_item["colors"].clear() - material_type_item["colors"].setItems(material_list) - - material_type_item_list.append(material_type_item) - - brand_item["materials"].setItems(material_type_item_list) - - brand_item_list.append(brand_item) - - self.setItems(brand_item_list) - - -# -# This model is for the Material management page. -# -class MaterialsModel(ListModel): - RootMaterialIdRole = Qt.UserRole + 1 - DisplayNameRole = Qt.UserRole + 2 - BrandRole = Qt.UserRole + 3 - MaterialTypeRole = Qt.UserRole + 4 - ColorNameRole = Qt.UserRole + 5 - ColorCodeRole = Qt.UserRole + 6 - ContainerNodeRole = Qt.UserRole + 7 - ContainerIdRole = Qt.UserRole + 8 - - DescriptionRole = Qt.UserRole + 9 - AdhesionInfoRole = Qt.UserRole + 10 - ApproximateDiameterRole = Qt.UserRole + 11 - GuidRole = Qt.UserRole + 12 - DensityRole = Qt.UserRole + 13 - DiameterRole = Qt.UserRole + 14 - IsReadOnlyRole = Qt.UserRole + 15 - - def __init__(self, parent = None): - super().__init__(parent) - - self.addRoleName(self.RootMaterialIdRole, "root_material_id") - self.addRoleName(self.DisplayNameRole, "name") - self.addRoleName(self.BrandRole, "brand") - self.addRoleName(self.MaterialTypeRole, "material") - self.addRoleName(self.ColorNameRole, "color_name") - self.addRoleName(self.ColorCodeRole, "color_code") - self.addRoleName(self.ContainerNodeRole, "container_node") - self.addRoleName(self.ContainerIdRole, "container_id") - - self.addRoleName(self.DescriptionRole, "description") - self.addRoleName(self.AdhesionInfoRole, "adhesion_info") - self.addRoleName(self.ApproximateDiameterRole, "approximate_diameter") - self.addRoleName(self.GuidRole, "guid") - self.addRoleName(self.DensityRole, "density") - self.addRoleName(self.DiameterRole, "diameter") - self.addRoleName(self.IsReadOnlyRole, "is_read_only") - - from cura.CuraApplication import CuraApplication - self._container_registry = CuraApplication.getInstance().getContainerRegistry() - self._machine_manager = CuraApplication.getInstance().getMachineManager() - extruder_manager = CuraApplication.getInstance().getExtruderManager() - material_manager = CuraApplication.getInstance()._material_manager - - self._machine_manager.globalContainerChanged.connect(self._update) - extruder_manager.activeExtruderChanged.connect(self._update) - material_manager.materialsUpdated.connect(self._update) - - self._update() - - def _update(self): - global_stack = self._machine_manager.activeMachine - if global_stack is None: - self.setItems([]) - return - - result_dict = getAvailableMaterials() - if result_dict is None: - self.setItems([]) - return - - material_list = [] - for root_material_id, container_node in result_dict.items(): - keys_to_fetch = ("name", - "brand", - "material", - "color_name", - "color_code", - "description", - "adhesion_info", - "approximate_diameter",) - - item = {"root_material_id": container_node.metadata["base_file"], - "container_node": container_node, - "guid": container_node.metadata["GUID"], - "container_id": container_node.metadata["id"], - "density": container_node.metadata.get("properties", {}).get("density", ""), - "diameter": container_node.metadata.get("properties", {}).get("diameter", ""), - "is_read_only": self._container_registry.isReadOnly(container_node.metadata["id"]), - } - - for key in keys_to_fetch: - item[key] = container_node.metadata.get(key, "") - - material_list.append(item) - - material_list = sorted(material_list, key = lambda k: (k["brand"].lower(), k["name"])) - self.setItems(material_list) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 671b5c6b9b..1177f20334 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -17,7 +17,7 @@ Item UM.I18nCatalog { id: catalog; name: "cura"; } - Cura.MaterialsModel { + Cura.MaterialManagementModel { id: materialsModel }