diff --git a/cura/Settings/ActiveQuality.py b/cura/Settings/ActiveQuality.py new file mode 100644 index 0000000000..420d1f24fc --- /dev/null +++ b/cura/Settings/ActiveQuality.py @@ -0,0 +1,48 @@ +from dataclasses import dataclass +from typing import List + +from UM import i18nCatalog + +catalog = i18nCatalog("cura") + + +@dataclass +class ActiveQuality: + """ Represents the active intent+profile combination, contains all information needed to display active quality. """ + intent_category: str = "" # Name of the base intent. For example "visual" or "engineering". + intent_name: str = "" # Name of the base intent formatted for display. For Example "Visual" or "Engineering" + profile: str = "" # Name of the base profile. For example "Fine" or "Fast" + custom_profile: str = "" # Name of the custom profile, this is based on profile. For example "MyCoolCustomProfile" + layer_height: float = None # Layer height of quality in mm. For example 0.4 + is_experimental: bool = False # If the quality experimental. + + def getMainStringParts(self) -> List[str]: + string_parts = [] + + if self.custom_profile is not None: + string_parts.append(self.custom_profile) + else: + string_parts.append(self.profile) + if self.intent_category is not "default": + string_parts.append(self.intent_name) + + return string_parts + + def getTailStringParts(self) -> List[str]: + string_parts = [] + + if self.custom_profile is not None: + string_parts.append(self.profile) + if self.intent_category is not "default": + string_parts.append(self.intent_name) + + if self.layer_height: + string_parts.append(f"{self.layer_height}mm") + + if self.is_experimental: + string_parts.append(catalog.i18nc("@label", "Experimental")) + + return string_parts + + def getStringParts(self) -> List[str]: + return self.getMainStringParts() + self.getTailStringParts() diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 27d8fbbc78..b8a5e7d885 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -40,6 +40,7 @@ from cura.Settings.cura_empty_instance_containers import (empty_definition_chang empty_material_container, empty_quality_container, empty_quality_changes_container, empty_intent_container) from cura.UltimakerCloud.UltimakerCloudConstants import META_UM_LINKED_TO_ACCOUNT +from .ActiveQuality import ActiveQuality from .CuraStackBuilder import CuraStackBuilder @@ -1631,33 +1632,31 @@ class MachineManager(QObject): # Examples: # - "my_profile - Fine" (only based on a default quality, no intent involved) # - "my_profile - Engineering - Fine" (based on an intent) - @pyqtProperty("QVariantMap", notify = activeQualityDisplayNameChanged) - def activeQualityDisplayNameMap(self) -> Dict[str, str]: + @pyqtProperty("QList", notify = activeQualityDisplayNameChanged) + def activeQualityDisplayNameStringParts(self) -> List[str]: + return self.activeQualityDisplayNameMap().getStringParts() + + @pyqtProperty("QList", notify = activeQualityDisplayNameChanged) + def activeQualityDisplayNameMainStringParts(self) -> List[str]: + return self.activeQualityDisplayNameMap().getMainStringParts() + + @pyqtProperty("QList", notify = activeQualityDisplayNameChanged) + def activeQualityDisplayNameTailStringParts(self) -> List[str]: + return self.activeQualityDisplayNameMap().getTailStringParts() + + def activeQualityDisplayNameMap(self) -> ActiveQuality: global_stack = self._application.getGlobalContainerStack() if global_stack is None: - return {"main": "", - "suffix": ""} + return ActiveQuality() - display_name = global_stack.quality.getName() - - intent_category = self.activeIntentCategory - if intent_category != "default": - intent_display_name = IntentCategoryModel.translation(intent_category, - "name", - intent_category.title()) - display_name = "{intent_name} - {the_rest}".format(intent_name = intent_display_name, - the_rest = display_name) - - main_part = display_name - suffix_part = "" - - # Not a custom quality - if global_stack.qualityChanges != empty_quality_changes_container: - main_part = self.activeQualityOrQualityChangesName - suffix_part = display_name - - return {"main": main_part, - "suffix": suffix_part} + return ActiveQuality( + profile = global_stack.quality.getName(), + intent_category = self.activeIntentCategory, + intent_name = IntentCategoryModel.translation(self.activeIntentCategory, "name", self.activeIntentCategory.title()), + custom_profile = self.activeQualityOrQualityChangesName if global_stack.qualityChanges is not empty_quality_changes_container else None, + layer_height = self.activeQualityLayerHeight if self.isActiveQualitySupported else None, + is_experimental = self.isActiveQualityExperimental and self.isActiveQualitySupported + ) @pyqtSlot(str) def setIntentByCategory(self, intent_category: str) -> None: @@ -1776,7 +1775,9 @@ class MachineManager(QObject): @pyqtProperty(bool, notify = activeQualityGroupChanged) def hasNotSupportedQuality(self) -> bool: global_container_stack = self._application.getGlobalContainerStack() - return (not global_container_stack is None) and global_container_stack.quality == empty_quality_container and global_container_stack.qualityChanges == empty_quality_changes_container + return global_container_stack is not None\ + and global_container_stack.quality == empty_quality_container \ + and global_container_stack.qualityChanges == empty_quality_changes_container @pyqtProperty(bool, notify = activeQualityGroupChanged) def isActiveQualityCustom(self) -> bool: diff --git a/plugins/UFPWriter/UFPWriter.py b/plugins/UFPWriter/UFPWriter.py index d7671d02c8..f90ef823e7 100644 --- a/plugins/UFPWriter/UFPWriter.py +++ b/plugins/UFPWriter/UFPWriter.py @@ -1,6 +1,7 @@ # Copyright (c) 2022 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import json +from dataclasses import asdict from typing import cast, List, Dict from Charon.VirtualFile import VirtualFile # To open UFP files. @@ -225,8 +226,7 @@ class UFPWriter(MeshWriter): "changes": {}, "all_settings": {}, }, - "intent": machine_manager.activeIntentCategory, - "quality": machine_manager.activeQualityOrQualityChangesName, + "quality": asdict(machine_manager.activeQualityDisplayNameMap()), } global_stack = cast(GlobalStack, Application.getInstance().getGlobalContainerStack()) diff --git a/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml b/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml index 0b39d84177..0fecb6b662 100644 --- a/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml +++ b/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml @@ -56,7 +56,7 @@ UM.Dialog UM.Label { id: infoText - text: catalog.i18nc("@text:window, %1 is a profile name", "You have customized some profile settings. Would you like to Keep these changed settings after switching profiles? Alternatively, you can discard the changes to load the defaults from '%1'.").arg(Cura.MachineManager.activeQualityDisplayNameMap["main"]) + text: catalog.i18nc("@text:window, %1 is a profile name", "You have customized some profile settings. Would you like to Keep these changed settings after switching profiles? Alternatively, you can discard the changes to load the defaults from '%1'.").arg(Cura.MachineManager.activeQualityDisplayNameMainStringParts.join(" - ")) anchors.left: parent.left anchors.right: parent.right wrapMode: Text.WordWrap @@ -83,7 +83,7 @@ UM.Dialog columnHeaders: [ catalog.i18nc("@title:column", "Profile settings"), - Cura.MachineManager.activeQualityDisplayNameMap["main"], + Cura.MachineManager.activeQualityDisplayNameMainStringParts.join(" - "), catalog.i18nc("@title:column", "Current changes") ] model: UM.TableModel diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index 554b663a9b..e64f211cd1 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -67,7 +67,7 @@ Item UM.Label { id: textLabel - text: Cura.MachineManager.activeQualityDisplayNameMap["main"] + text: Cura.MachineManager.activeQualityDisplayNameMainStringParts.join(" - ") Layout.margins: 0 Layout.maximumWidth: Math.floor(parent.width * 0.7) // Always leave >= 30% for the rest of the row. height: contentHeight @@ -77,7 +77,19 @@ Item UM.Label { - text: activeQualityDetailText() + text: + { + const string_parts = Cura.MachineManager.activeQualityDisplayNameTailStringParts; + if (string_parts.length === 0) + { + return ""; + } + else + { + ` - ${string_parts.join(" - ")}` + } + } + color: UM.Theme.getColor("text_detail") Layout.margins: 0 Layout.fillWidth: true @@ -85,32 +97,6 @@ Item height: contentHeight elide: Text.ElideRight wrapMode: Text.NoWrap - function activeQualityDetailText() - { - var resultMap = Cura.MachineManager.activeQualityDisplayNameMap - var resultSuffix = resultMap["suffix"] - var result = "" - - if (Cura.MachineManager.isActiveQualityExperimental) - { - resultSuffix += " (Experimental)" - } - - if (Cura.MachineManager.isActiveQualitySupported) - { - if (Cura.MachineManager.activeQualityLayerHeight > 0) - { - if (resultSuffix) - { - result += " - " + resultSuffix - } - result += " - " - result += Cura.MachineManager.activeQualityLayerHeight + "mm" - } - } - - return result - } } } diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml index 41e913a2c1..8804e51bb2 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml @@ -17,26 +17,8 @@ RowLayout { source: UM.Theme.getIcon("Sliders", "medium") iconSize: UM.Theme.getSize("button_icon").width - text: - { - if (Cura.MachineManager.activeStack) - { - var resultMap = Cura.MachineManager.activeQualityDisplayNameMap - var text = resultMap["main"] - if (resultMap["suffix"]) - { - text += " - " + resultMap["suffix"] - } - if (!Cura.MachineManager.hasNotSupportedQuality) - { - text += " - " + layerHeight.properties.value + "mm" - text += Cura.MachineManager.isActiveQualityExperimental ? " - " + catalog.i18nc("@label", "Experimental") : "" - } - return text - } - return "" - } + text: Cura.MachineManager.activeQualityDisplayNameStringParts.join(" - ") font: UM.Theme.getFont("medium") elide: Text.ElideMiddle wrapMode: Text.NoWrap