QualitySettingsModel.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. # Copyright (c) 2016 Ultimaker B.V.
  2. # Cura is released under the terms of the AGPLv3 or higher.
  3. import collections
  4. from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
  5. import UM.Application
  6. import UM.Logger
  7. import UM.Qt
  8. import UM.Settings
  9. class QualitySettingsModel(UM.Qt.ListModel.ListModel):
  10. KeyRole = Qt.UserRole + 1
  11. LabelRole = Qt.UserRole + 2
  12. UnitRole = Qt.UserRole + 3
  13. ProfileValueRole = Qt.UserRole + 4
  14. ProfileValueSourceRole = Qt.UserRole + 5
  15. UserValueRole = Qt.UserRole + 6
  16. CategoryRole = Qt.UserRole + 7
  17. def __init__(self, parent = None):
  18. super().__init__(parent = parent)
  19. self._container_registry = UM.Settings.ContainerRegistry.getInstance()
  20. self._extruder_id = None
  21. self._extruder_definition_id = None
  22. self._quality_id = None
  23. self._material_id = None
  24. self.addRoleName(self.KeyRole, "key")
  25. self.addRoleName(self.LabelRole, "label")
  26. self.addRoleName(self.UnitRole, "unit")
  27. self.addRoleName(self.ProfileValueRole, "profile_value")
  28. self.addRoleName(self.ProfileValueSourceRole, "profile_value_source")
  29. self.addRoleName(self.UserValueRole, "user_value")
  30. self.addRoleName(self.CategoryRole, "category")
  31. def setExtruderId(self, extruder_id):
  32. if extruder_id != self._extruder_id:
  33. self._extruder_id = extruder_id
  34. self._update()
  35. self.extruderIdChanged.emit()
  36. extruderIdChanged = pyqtSignal()
  37. @pyqtProperty(str, fset = setExtruderId, notify = extruderIdChanged)
  38. def extruderId(self):
  39. return self._extruder_id
  40. def setExtruderDefinition(self, extruder_definition):
  41. if extruder_definition != self._extruder_definition_id:
  42. self._extruder_definition_id = extruder_definition
  43. self._update()
  44. self.extruderDefinitionChanged.emit()
  45. extruderDefinitionChanged = pyqtSignal()
  46. @pyqtProperty(str, fset = setExtruderDefinition, notify = extruderDefinitionChanged)
  47. def extruderDefinition(self):
  48. return self._extruder_definition_id
  49. def setQuality(self, quality):
  50. if quality != self._quality_id:
  51. self._quality_id = quality
  52. self._update()
  53. self.qualityChanged.emit()
  54. qualityChanged = pyqtSignal()
  55. @pyqtProperty(str, fset = setQuality, notify = qualityChanged)
  56. def quality(self):
  57. return self._quality_id
  58. def setMaterial(self, material):
  59. if material != self._material_id:
  60. self._material_id = material
  61. self._update()
  62. self.materialChanged.emit()
  63. materialChanged = pyqtSignal()
  64. @pyqtProperty(str, fset = setMaterial, notify = materialChanged)
  65. def material(self):
  66. return self._material_id
  67. def _update(self):
  68. if not self._quality_id:
  69. return
  70. items = []
  71. settings = collections.OrderedDict()
  72. definition_container = UM.Application.getInstance().getGlobalContainerStack().getBottom()
  73. containers = self._container_registry.findInstanceContainers(id = self._quality_id)
  74. if not containers:
  75. UM.Logger.log("w", "Could not find a quality container with id %s", self._quality_id)
  76. return
  77. quality_container = None
  78. quality_changes_container = None
  79. if containers[0].getMetaDataEntry("type") == "quality":
  80. quality_container = containers[0]
  81. else:
  82. quality_changes_container = containers[0]
  83. criteria = {
  84. "type": "quality",
  85. "quality_type": quality_changes_container.getMetaDataEntry("quality_type"),
  86. "definition": quality_changes_container.getDefinition().getId()
  87. }
  88. if self._material_id and self._material_id != "empty_material":
  89. criteria["material"] = self._material_id
  90. quality_container = self._container_registry.findInstanceContainers(**criteria)
  91. if not quality_container:
  92. UM.Logger.log("w", "Could not find a quality container matching quality changes %s", quality_changes_container.getId())
  93. return
  94. quality_container = quality_container[0]
  95. quality_type = quality_container.getMetaDataEntry("quality_type")
  96. definition = quality_container.getDefinition()
  97. if definition:
  98. definition_id = definition.getId()
  99. else:
  100. definition_id = "empty_quality"
  101. criteria = {"type": "quality", "quality_type": quality_type, "definition": definition_id}
  102. if self._material_id and self._material_id != "empty_material":
  103. criteria["material"] = self._material_id
  104. criteria["extruder"] = self._extruder_id
  105. containers = self._container_registry.findInstanceContainers(**criteria)
  106. if not containers:
  107. # Try again, this time without extruder
  108. new_criteria = criteria.copy()
  109. new_criteria.pop("extruder")
  110. containers = self._container_registry.findInstanceContainers(**new_criteria)
  111. if not containers and "material" in criteria:
  112. # Try again, this time without material
  113. criteria.pop("material", None)
  114. containers = self._container_registry.findInstanceContainers(**criteria)
  115. if not containers:
  116. # Try again, this time without material or extruder
  117. criteria.pop("extruder") # "material" has already been popped
  118. containers = self._container_registry.findInstanceContainers(**criteria)
  119. if not containers:
  120. UM.Logger.log("w", "Could not find any quality containers matching the search criteria %s" % str(criteria))
  121. return
  122. if quality_changes_container:
  123. criteria = {"type": "quality_changes", "quality_type": quality_type, "definition": definition_id, "name": quality_changes_container.getName()}
  124. if self._extruder_definition_id != "":
  125. criteria["extruder"] = self._extruder_definition_id
  126. criteria["name"] = quality_changes_container.getName()
  127. else:
  128. criteria["extruder"] = None
  129. changes = self._container_registry.findInstanceContainers(**criteria)
  130. if changes:
  131. containers.extend(changes)
  132. global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
  133. is_multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
  134. current_category = ""
  135. for definition in definition_container.findDefinitions():
  136. if definition.type == "category":
  137. current_category = definition.label
  138. continue
  139. profile_value = None
  140. profile_value_source = ""
  141. for container in containers:
  142. new_value = container.getProperty(definition.key, "value")
  143. if new_value is not None:
  144. profile_value_source = container.getMetaDataEntry("type")
  145. profile_value = new_value
  146. user_value = None
  147. if not self._extruder_id:
  148. user_value = global_container_stack.getTop().getProperty(definition.key, "value")
  149. else:
  150. extruder_stack = self._container_registry.findContainerStacks(id = self._extruder_id)
  151. if extruder_stack:
  152. user_value = extruder_stack[0].getTop().getProperty(definition.key, "value")
  153. if profile_value is None and user_value is None:
  154. continue
  155. if is_multi_extrusion:
  156. settable_per_extruder = global_container_stack.getProperty(definition.key, "settable_per_extruder")
  157. # If a setting is not settable per extruder (global) and we're looking at an extruder tab, don't show this value.
  158. if self._extruder_id != "" and not settable_per_extruder:
  159. continue
  160. # If a setting is settable per extruder (not global) and we're looking at global tab, don't show this value.
  161. if self._extruder_id == "" and settable_per_extruder:
  162. continue
  163. items.append({
  164. "key": definition.key,
  165. "label": definition.label,
  166. "unit": definition.unit,
  167. "profile_value": "" if profile_value is None else str(profile_value), # it is for display only
  168. "profile_value_source": profile_value_source,
  169. "user_value": "" if user_value is None else str(user_value),
  170. "category": current_category
  171. })
  172. self.setItems(items)