QualityProfilesDropDownMenuModel.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. # Copyright (c) 2018 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. from PyQt5.QtCore import Qt, QTimer
  4. from UM.Application import Application
  5. from UM.Logger import Logger
  6. from UM.Qt.ListModel import ListModel
  7. from UM.Settings.SettingFunction import SettingFunction
  8. from cura.Machines.QualityManager import QualityGroup
  9. #
  10. # QML Model for all built-in quality profiles. This model is used for the drop-down quality menu.
  11. #
  12. class QualityProfilesDropDownMenuModel(ListModel):
  13. NameRole = Qt.UserRole + 1
  14. QualityTypeRole = Qt.UserRole + 2
  15. LayerHeightRole = Qt.UserRole + 3
  16. LayerHeightUnitRole = Qt.UserRole + 4
  17. AvailableRole = Qt.UserRole + 5
  18. QualityGroupRole = Qt.UserRole + 6
  19. QualityChangesGroupRole = Qt.UserRole + 7
  20. IsExperimentalRole = Qt.UserRole + 8
  21. def __init__(self, parent = None):
  22. super().__init__(parent)
  23. self.addRoleName(self.NameRole, "name")
  24. self.addRoleName(self.QualityTypeRole, "quality_type")
  25. self.addRoleName(self.LayerHeightRole, "layer_height")
  26. self.addRoleName(self.LayerHeightUnitRole, "layer_height_unit")
  27. self.addRoleName(self.AvailableRole, "available") #Whether the quality profile is available in our current nozzle + material.
  28. self.addRoleName(self.QualityGroupRole, "quality_group")
  29. self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group")
  30. self.addRoleName(self.IsExperimentalRole, "is_experimental")
  31. self._application = Application.getInstance()
  32. self._machine_manager = self._application.getMachineManager()
  33. self._quality_manager = Application.getInstance().getQualityManager()
  34. self._application.globalContainerStackChanged.connect(self._onChange)
  35. self._machine_manager.activeQualityGroupChanged.connect(self._onChange)
  36. self._machine_manager.extruderChanged.connect(self._onChange)
  37. self._quality_manager.qualitiesUpdated.connect(self._onChange)
  38. self._layer_height_unit = "" # This is cached
  39. self._update_timer = QTimer() # type: QTimer
  40. self._update_timer.setInterval(100)
  41. self._update_timer.setSingleShot(True)
  42. self._update_timer.timeout.connect(self._update)
  43. self._onChange()
  44. def _onChange(self) -> None:
  45. self._update_timer.start()
  46. def _update(self):
  47. Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
  48. global_stack = self._machine_manager.activeMachine
  49. if global_stack is None:
  50. self.setItems([])
  51. Logger.log("d", "No active GlobalStack, set quality profile model as empty.")
  52. return
  53. # Check for material compatibility
  54. if not self._machine_manager.activeMaterialsCompatible():
  55. Logger.log("d", "No active material compatibility, set quality profile model as empty.")
  56. self.setItems([])
  57. return
  58. quality_group_dict = self._quality_manager.getQualityGroups(global_stack)
  59. item_list = []
  60. for key in sorted(quality_group_dict):
  61. quality_group = quality_group_dict[key]
  62. layer_height = self._fetchLayerHeight(quality_group)
  63. item = {"name": quality_group.name,
  64. "quality_type": quality_group.quality_type,
  65. "layer_height": layer_height,
  66. "layer_height_unit": self._layer_height_unit,
  67. "available": quality_group.is_available,
  68. "quality_group": quality_group,
  69. "is_experimental": quality_group.is_experimental}
  70. item_list.append(item)
  71. # Sort items based on layer_height
  72. item_list = sorted(item_list, key = lambda x: x["layer_height"])
  73. self.setItems(item_list)
  74. def _fetchLayerHeight(self, quality_group: "QualityGroup") -> float:
  75. global_stack = self._machine_manager.activeMachine
  76. if not self._layer_height_unit:
  77. unit = global_stack.definition.getProperty("layer_height", "unit")
  78. if not unit:
  79. unit = ""
  80. self._layer_height_unit = unit
  81. default_layer_height = global_stack.definition.getProperty("layer_height", "value")
  82. # Get layer_height from the quality profile for the GlobalStack
  83. if quality_group.node_for_global is None:
  84. return float(default_layer_height)
  85. container = quality_group.node_for_global.getContainer()
  86. layer_height = default_layer_height
  87. if container and container.hasProperty("layer_height", "value"):
  88. layer_height = container.getProperty("layer_height", "value")
  89. else:
  90. # Look for layer_height in the GlobalStack from material -> definition
  91. container = global_stack.definition
  92. if container and container.hasProperty("layer_height", "value"):
  93. layer_height = container.getProperty("layer_height", "value")
  94. if isinstance(layer_height, SettingFunction):
  95. layer_height = layer_height(global_stack)
  96. return float(layer_height)