diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 9a74cde13f..44d4761321 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -53,7 +53,7 @@ from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.SettingFunction import SettingFunction from cura.Settings.MachineNameValidator import MachineNameValidator from cura.Settings.NozzleModel import NozzleModel -from cura.Settings.ProfilesModel import ProfilesModel, NewQualityProfilesModel +from cura.Settings.ProfilesModel import ProfilesModel, NewQualityProfilesModel, NewCustomQualityProfilesModel from cura.Settings.MaterialsModel import MaterialsModel, BrandMaterialsModel, GenericMaterialsModel from cura.Settings.QualityAndUserProfilesModel import QualityAndUserProfilesModel from cura.Settings.SettingInheritanceManager import SettingInheritanceManager @@ -389,6 +389,7 @@ class CuraApplication(QtApplication): self.getCuraSceneController().setActiveBuildPlate(0) # Initialize self._new_quality_profile_model = None + self._new_custom_quality_profile_model = None CuraApplication.Created = True @@ -903,6 +904,11 @@ class CuraApplication(QtApplication): self._new_quality_profile_model = NewQualityProfilesModel(self) return self._new_quality_profile_model + def getNewCustomQualityProfilesModel(self, *args, **kwargs): + if self._new_custom_quality_profile_model is None: + self._new_custom_quality_profile_model = NewCustomQualityProfilesModel(self) + return self._new_custom_quality_profile_model + ## Registers objects for the QML engine to use. # # \param engine The QML engine. @@ -936,6 +942,7 @@ class CuraApplication(QtApplication): qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") qmlRegisterSingletonType(NewQualityProfilesModel, "Cura", 1, 0, "NewQualityProfilesModel", self.getNewQualityProfileModel) + qmlRegisterSingletonType(NewCustomQualityProfilesModel, "Cura", 1, 0, "NewCustomQualityProfilesModel", self.getNewCustomQualityProfilesModel) qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel") qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel") diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 0e9bf99bd4..1c7f82550a 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -27,10 +27,18 @@ from cura.Machines.ContainerNode import ContainerNode # -class QualityChangesGroup(ContainerGroup): +class QualityGroup(ContainerGroup): - def __init__(self, name: str, parent = None): + def __init__(self, name: str, quality_type: str, parent = None): super().__init__(name, parent) + self.quality_type = quality_type + self.is_available = False + + +class QualityChangesGroup(QualityGroup): + + def __init__(self, name: str, quality_type: str, parent = None): + super().__init__(name, quality_type, parent) def addNode(self, node: "QualityNode"): # TODO: in 3.2 and earlier, a quality_changes container may have a field called "extruder" which contains the @@ -70,13 +78,9 @@ class QualityChangesGroup(ContainerGroup): (self, self.node_for_global, node)) self.node_for_global = node + def __str__(self) -> str: + return "%s[<%s>, available = %s]" % (self.__class__.__name__, self.name, self.is_available) -class QualityGroup(ContainerGroup): - - def __init__(self, name: str, quality_type: str, parent = None): - super().__init__(name, parent) - self.quality_type = quality_type - self.is_available = False # # QualityNode is used for BOTH quality and quality_changes containers. @@ -101,7 +105,7 @@ class QualityNode(ContainerNode): name = metadata["name"] if name not in quality_type_node.children_map: - quality_type_node.children_map[name] = QualityChangesGroup(name) + quality_type_node.children_map[name] = QualityChangesGroup(name, quality_type) quality_changes_group = quality_type_node.children_map[name] quality_changes_group.addNode(QualityNode(metadata)) @@ -224,7 +228,7 @@ class QualityManager(QObject): quality_group.is_available = is_available # Returns a dict of "custom profile name" -> QualityChangesGroup - def getQualityChangesGroup(self, machine: "GlobalStack") -> dict: + def getQualityChangesGroups(self, machine: "GlobalStack") -> dict: # TODO: How to make this simpler? # Get machine definition ID machine_definition_id = self._default_machine_definition_id @@ -237,14 +241,17 @@ class QualityManager(QObject): if not machine_node: raise RuntimeError("Cannot find node for machine def [%s] in QualityChanges lookup table" % machine_definition_id) - # iterate over all quality_types in the machine node + # Update availability for each QualityChangesGroup: + # A custom profile is always available as long as the quality_type it's based on is available + quality_group_dict = self.getQualityGroups(machine) + available_quality_type_list = [qt for qt, qg in quality_group_dict.items() if qg.is_available] + + # Iterate over all quality_types in the machine node quality_changes_group_dict = dict() for quality_type, quality_changes_node in machine_node.quality_type_map.items(): for quality_changes_name, quality_changes_group in quality_changes_node.children_map.items(): quality_changes_group_dict[quality_changes_name] = quality_changes_group - - # Update availabilities for each quality group - self._updateQualityGroupsAvailability(machine, quality_changes_group_dict.values()) + quality_changes_group.is_available = quality_type in available_quality_type_list return quality_changes_group_dict diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index bb2f8cbd79..3b37afd328 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -134,11 +134,13 @@ class MachineManager(QObject): containers[0].nameChanged.connect(self._onMaterialNameChanged) ### NEW - self._current_quality_group = None self._current_root_material_id = {} + self._current_quality_group = None + self._current_quality_changes_group = None ### NEW activeQualityGroupChanged = pyqtSignal() + activeQualityChangesGroupChanged = pyqtSignal() globalContainerChanged = pyqtSignal() # Emitted whenever the global stack is changed (ie: when changing between printers, changing a global profile, but not when changing a value) activeMaterialChanged = pyqtSignal() @@ -1502,6 +1504,27 @@ class MachineManager(QObject): self._current_root_material_id[position] = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file") return self._current_root_material_id + def _setQualityChangesGroup(self, quality_changes_group): + self._current_quality_changes_group = quality_changes_group + + # TODO: quality_changes groups depend on a quality_type. Here it's fetching the quality_types every time. + # Can we do this better, like caching the quality group a quality_changes group depends on? + quality_manager = Application.getInstance()._quality_manager + quality_group_dict = quality_manager.getQualityGroups(self._global_container_stack) + + quality_type = quality_changes_group.quality_type + + container = self._empty_quality_changes_container + if quality_changes_group.node_for_global is not None: + container = quality_changes_group.node_for_global.getContainer() + self._global_container_stack.qualityChanges = container + self._global_container_stack.quality = quality_group_dict[quality_type] + + for position, extruder in self._global_container_stack.extruders.items(): + container = quality_changes_group.nodes_for_extruders.get(position, + self._empty_quality_changes_container) + extruder.qualityChanges = container + def _setEmptyQuality(self): self._current_quality_group = None self._global_container_stack.quality = self._empty_quality_container @@ -1510,9 +1533,13 @@ class MachineManager(QObject): extruder.quality = self._empty_quality_container extruder.qualityChanges = self._empty_quality_changes_container + self.activeQualityGroupChanged.emit() + def _setQualityGroup(self, quality_group, empty_quality_changes = True): self._current_quality_group = quality_group + #TODO: check quality_changes + # Set quality and quality_changes for the GlobalStack self._global_container_stack.quality = quality_group.node_for_global.getContainer() if empty_quality_changes: diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index fd508f247a..b05bc46dd5 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -101,6 +101,35 @@ class NewQualityProfilesModel(ListModel): return str(layer_height) +class NewCustomQualityProfilesModel(NewQualityProfilesModel): + + def _update(self): + Logger.log("d", "Updating %s ...", self.__class__.__name__) + + active_global_stack = Application.getInstance().getMachineManager()._global_container_stack + if active_global_stack is None: + self.setItems([]) + Logger.log("d", "No active GlobalStack, set %s as empty.", self.__class__.__name__) + return + + quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(active_global_stack) + + item_list = [] + for key in sorted(quality_changes_group_dict): + quality_changes_group = quality_changes_group_dict[key] + + item = {"id": "TODO", # TODO: probably will be removed + "name": quality_changes_group.name, + "layer_height": "", + "layer_height_without_unit": "", + "available": quality_changes_group.is_available, + "quality_changes_group": quality_changes_group} + + item_list.append(item) + + self.setItems(item_list) + + ## QML Model for listing the current list of valid quality profiles. # class ProfilesModel(InstanceContainersModel): diff --git a/plugins/TestTools/TestTool.py b/plugins/TestTools/TestTool.py index e2312e578f..a8812c21ba 100644 --- a/plugins/TestTools/TestTool.py +++ b/plugins/TestTools/TestTool.py @@ -33,5 +33,6 @@ class TestTool(Extension, QObject): from cura.CuraApplication import CuraApplication result_dict = {} global_stack = CuraApplication.getInstance().getMachineManager()._global_container_stack - result = CuraApplication.getInstance()._quality_manager.getQualityChangesGroup(global_stack) - print("!!!!!!!!!!!!!!!!!!!") + result = CuraApplication.getInstance()._quality_manager.getQualityChangesGroups(global_stack) + for name, r in result.items(): + print("!!!!!!!!!! [%s] - %s" % (name, r)) diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index 9013216e32..f212d82b6e 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -40,18 +40,21 @@ Menu Instantiator { id: customProfileInstantiator - model: Cura.UserProfilesModel + model: Cura.NewCustomQualityProfilesModel + + Connections { - onModelReset: customSeparator.visible = rowCount() > 0 + target: Cura.NewCustomQualityProfilesModel + onModelReset: customSeparator.visible = Cura.NewCustomQualityProfilesModel.rowCount() > 0 } MenuItem { text: model.name - checkable: true - checked: Cura.MachineManager.activeQualityChangesId == model.id + checkable: model.available + checked: Cura.MachineManager.activeQualityChangesId == model.id // TODO: fix for new exclusiveGroup: group - onTriggered: Cura.MachineManager.setActiveQuality(model.id) + onTriggered: Cura.MachineManager.setActiveQuality(model.id) // TODO: fix for new } onObjectAdded: