diff --git a/cura/Machines/Models/IntentCategoryModel.py b/cura/Machines/Models/IntentCategoryModel.py index 9a520a2d31..5211889801 100644 --- a/cura/Machines/Models/IntentCategoryModel.py +++ b/cura/Machines/Models/IntentCategoryModel.py @@ -5,9 +5,11 @@ from PyQt5.QtCore import Qt import collections from typing import TYPE_CHECKING +from cura.Machines.Models.IntentModel import IntentModel from cura.Settings.IntentManager import IntentManager from UM.Qt.ListModel import ListModel from UM.Settings.ContainerRegistry import ContainerRegistry #To update the list if anything changes. +from PyQt5.QtCore import pyqtProperty, pyqtSignal if TYPE_CHECKING: from UM.Settings.ContainerRegistry import ContainerInterface @@ -15,12 +17,14 @@ if TYPE_CHECKING: from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") + ## Lists the intent categories that are available for the current printer # configuration. class IntentCategoryModel(ListModel): NameRole = Qt.UserRole + 1 IntentCategoryRole = Qt.UserRole + 2 WeightRole = Qt.UserRole + 3 + QualitiesRole = Qt.UserRole + 4 #Translations to user-visible string. Ordered by weight. #TODO: Create a solution for this name and weight to be used dynamically. @@ -29,6 +33,8 @@ class IntentCategoryModel(ListModel): name_translation["engineering"] = catalog.i18nc("@label", "Engineering") name_translation["smooth"] = catalog.i18nc("@label", "Smooth") + modelUpdated = pyqtSignal() + ## Creates a new model for a certain intent category. # \param The category to list the intent profiles for. def __init__(self, intent_category: str) -> None: @@ -38,6 +44,7 @@ class IntentCategoryModel(ListModel): self.addRoleName(self.NameRole, "name") self.addRoleName(self.IntentCategoryRole, "intent_category") self.addRoleName(self.WeightRole, "weight") + self.addRoleName(self.QualitiesRole, "qualities") ContainerRegistry.getInstance().containerAdded.connect(self._onContainerChange) ContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChange) @@ -55,9 +62,13 @@ class IntentCategoryModel(ListModel): available_categories = IntentManager.getInstance().currentAvailableIntentCategories() result = [] for category in available_categories: + qualities = IntentModel() + qualities.setIntentCategory(category) result.append({ "name": self.name_translation.get(category, catalog.i18nc("@label", "Unknown")), "intent_category": category, - "weight": list(self.name_translation.keys()).index(category) + "weight": list(self.name_translation.keys()).index(category), + "qualities": qualities }) - self.setItems(result) \ No newline at end of file + result.sort(key = lambda k: k["weight"]) + self.setItems(result) diff --git a/cura/Machines/Models/IntentModel.py b/cura/Machines/Models/IntentModel.py index 5a44883b76..b310ec47a6 100644 --- a/cura/Machines/Models/IntentModel.py +++ b/cura/Machines/Models/IntentModel.py @@ -7,6 +7,7 @@ from PyQt5.QtCore import Qt, QObject, pyqtProperty, pyqtSignal from UM.Qt.ListModel import ListModel from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.SettingFunction import SettingFunction from cura.Machines.ContainerTree import ContainerTree from cura.Settings.IntentManager import IntentManager @@ -16,18 +17,22 @@ import cura.CuraApplication class IntentModel(ListModel): NameRole = Qt.UserRole + 1 QualityTypeRole = Qt.UserRole + 2 + LayerHeightRole = Qt.UserRole + 3 + AvailableRole = Qt.UserRole + 4 def __init__(self, parent: Optional[QObject] = None) -> None: super().__init__(parent) self.addRoleName(self.NameRole, "name") self.addRoleName(self.QualityTypeRole, "quality_type") + self.addRoleName(self.LayerHeightRole, "layer_height") + self.addRoleName(self.AvailableRole, "available") self._intent_category = "engineering" ContainerRegistry.getInstance().containerAdded.connect(self._onChanged) ContainerRegistry.getInstance().containerRemoved.connect(self._onChanged) - + self._layer_height_unit = "" # This is cached self._update() intentCategoryChanged = pyqtSignal() @@ -54,11 +59,42 @@ class IntentModel(ListModel): return quality_groups = ContainerTree.getInstance().getCurrentQualityGroups() - for intent_category, quality_type in IntentManager.getInstance().getCurrentAvailableIntents(): - if intent_category == self._intent_category: - new_items.append({"name": quality_groups[quality_type].name, "quality_type": quality_type}) - if self._intent_category == "default": #For Default we always list all quality types. We can't filter on available profiles since the empty intent is not a specific quality type. - for quality_type in quality_groups.keys(): - new_items.append({"name": quality_groups[quality_type].name, "quality_type": quality_type}) + for quality_tuple, quality_group in quality_groups.items(): + new_items.append({"name": quality_group.name, + "quality_type": quality_tuple[1], + "layer_height": self._fetchLayerHeight(quality_group), + "available": True + }) + new_items = sorted(new_items, key=lambda x: x["layer_height"]) self.setItems(new_items) + + #TODO: Copied this from QualityProfilesDropdownMenuModel for the moment. This code duplication should be fixed. + def _fetchLayerHeight(self, quality_group) -> float: + global_stack = cura.CuraApplication.CuraApplication.getInstance().getMachineManager().activeMachine + if not self._layer_height_unit: + unit = global_stack.definition.getProperty("layer_height", "unit") + if not unit: + unit = "" + self._layer_height_unit = unit + + default_layer_height = global_stack.definition.getProperty("layer_height", "value") + + # Get layer_height from the quality profile for the GlobalStack + if quality_group.node_for_global is None: + return float(default_layer_height) + container = quality_group.node_for_global.getContainer() + + layer_height = default_layer_height + if container and container.hasProperty("layer_height", "value"): + layer_height = container.getProperty("layer_height", "value") + else: + # Look for layer_height in the GlobalStack from material -> definition + container = global_stack.definition + if container and container.hasProperty("layer_height", "value"): + layer_height = container.getProperty("layer_height", "value") + + if isinstance(layer_height, SettingFunction): + layer_height = layer_height(global_stack) + + return float(layer_height)