IntentSelectionModel.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. # Copyright (c) 2022 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. import collections
  4. from typing import OrderedDict, Optional
  5. from PyQt6.QtCore import Qt, QTimer, QObject
  6. import cura
  7. from UM import i18nCatalog
  8. from UM.Logger import Logger
  9. from UM.Qt.ListModel import ListModel
  10. from UM.Settings.ContainerRegistry import ContainerRegistry
  11. from UM.Settings.Interfaces import ContainerInterface
  12. from cura.Settings.IntentManager import IntentManager
  13. catalog = i18nCatalog("cura")
  14. class IntentSelectionModel(ListModel):
  15. NameRole = Qt.ItemDataRole.UserRole + 1
  16. IntentCategoryRole = Qt.ItemDataRole.UserRole + 2
  17. WeightRole = Qt.ItemDataRole.UserRole + 3
  18. DescriptionRole = Qt.ItemDataRole.UserRole + 4
  19. IconRole = Qt.ItemDataRole.UserRole + 5
  20. def __init__(self, parent: Optional[QObject] = None) -> None:
  21. super().__init__(parent)
  22. self.addRoleName(self.NameRole, "name")
  23. self.addRoleName(self.IntentCategoryRole, "intent_category")
  24. self.addRoleName(self.WeightRole, "weight")
  25. self.addRoleName(self.DescriptionRole, "description")
  26. self.addRoleName(self.IconRole, "icon")
  27. application = cura.CuraApplication.CuraApplication.getInstance()
  28. ContainerRegistry.getInstance().containerAdded.connect(self._onContainerChange)
  29. ContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChange)
  30. machine_manager = cura.CuraApplication.CuraApplication.getInstance().getMachineManager()
  31. machine_manager.activeMaterialChanged.connect(self._update)
  32. machine_manager.activeVariantChanged.connect(self._update)
  33. machine_manager.extruderChanged.connect(self._update)
  34. extruder_manager = application.getExtruderManager()
  35. extruder_manager.extrudersChanged.connect(self._update)
  36. self._update_timer: QTimer = QTimer()
  37. self._update_timer.setInterval(100)
  38. self._update_timer.setSingleShot(True)
  39. self._update_timer.timeout.connect(self._update)
  40. self._onChange()
  41. @staticmethod
  42. def _getDefaultProfileInformation() -> OrderedDict[str, dict]:
  43. """ Default information user-visible string. Ordered by weight. """
  44. default_profile_information = collections.OrderedDict()
  45. default_profile_information["default"] = {
  46. "name": catalog.i18nc("@label", "Default"),
  47. "icon": "GearCheck"
  48. }
  49. default_profile_information["visual"] = {
  50. "name": catalog.i18nc("@label", "Visual"),
  51. "description": catalog.i18nc("@text", "The visual profile is designed to print visual prototypes and models with the intent of high visual and surface quality."),
  52. "icon" : "Visual"
  53. }
  54. default_profile_information["engineering"] = {
  55. "name": catalog.i18nc("@label", "Engineering"),
  56. "description": catalog.i18nc("@text", "The engineering profile is designed to print functional prototypes and end-use parts with the intent of better accuracy and for closer tolerances."),
  57. "icon": "Nut"
  58. }
  59. default_profile_information["quick"] = {
  60. "name": catalog.i18nc("@label", "Draft"),
  61. "description": catalog.i18nc("@text", "The draft profile is designed to print initial prototypes and concept validation with the intent of significant print time reduction."),
  62. "icon": "SpeedOMeter"
  63. }
  64. return default_profile_information
  65. def _onContainerChange(self, container: ContainerInterface) -> None:
  66. """Updates the list of intents if an intent profile was added or removed."""
  67. if container.getMetaDataEntry("type") == "intent":
  68. self._update()
  69. def _onChange(self) -> None:
  70. self._update_timer.start()
  71. def _update(self) -> None:
  72. Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
  73. global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
  74. if global_stack is None:
  75. self.setItems([])
  76. Logger.log("d", "No active GlobalStack, set quality profile model as empty.")
  77. return
  78. # Check for material compatibility
  79. if not cura.CuraApplication.CuraApplication.getInstance().getMachineManager().activeMaterialsCompatible():
  80. Logger.log("d", "No active material compatibility, set quality profile model as empty.")
  81. self.setItems([])
  82. return
  83. default_profile_info = self._getDefaultProfileInformation()
  84. available_categories = IntentManager.getInstance().currentAvailableIntentCategories()
  85. result = []
  86. for i, category in enumerate(available_categories):
  87. profile_info = default_profile_info.get(category, {})
  88. try:
  89. weight = list(default_profile_info.keys()).index(category)
  90. except ValueError:
  91. weight = len(available_categories) + i
  92. result.append({
  93. "name": profile_info.get("name", category.title()),
  94. "description": profile_info.get("description", None),
  95. "icon" : profile_info.get("icon", ""),
  96. "intent_category": category,
  97. "weight": weight,
  98. })
  99. result.sort(key=lambda k: k["weight"])
  100. self.setItems(result)