QualitySettingsModel.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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_id = quality_container.getDefinition().getId()
  97. criteria = {"type": "quality", "quality_type": quality_type, "definition": definition_id}
  98. if self._material_id and self._material_id != "empty_material":
  99. criteria["material"] = self._material_id
  100. criteria["extruder"] = self._extruder_id
  101. containers = self._container_registry.findInstanceContainers(**criteria)
  102. if not containers:
  103. # Try again, this time without extruder
  104. new_criteria = criteria.copy()
  105. new_criteria.pop("extruder")
  106. containers = self._container_registry.findInstanceContainers(**new_criteria)
  107. if not containers and "material" in criteria:
  108. # Try again, this time without material
  109. criteria.pop("material", None)
  110. containers = self._container_registry.findInstanceContainers(**criteria)
  111. if not containers:
  112. # Try again, this time without material or extruder
  113. criteria.pop("extruder") # "material" has already been popped
  114. containers = self._container_registry.findInstanceContainers(**criteria)
  115. if not containers:
  116. UM.Logger.log("w", "Could not find any quality containers matching the search criteria %s" % str(criteria))
  117. return
  118. if quality_changes_container:
  119. criteria = {"type": "quality_changes", "quality_type": quality_type, "definition": definition_id, "name": quality_changes_container.getName()}
  120. if self._extruder_definition_id != "":
  121. criteria["extruder"] = self._extruder_definition_id
  122. criteria["name"] = quality_changes_container.getName()
  123. else:
  124. criteria["extruder"] = None
  125. changes = self._container_registry.findInstanceContainers(**criteria)
  126. if changes:
  127. containers.extend(changes)
  128. global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
  129. is_multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
  130. current_category = ""
  131. for definition in definition_container.findDefinitions():
  132. if definition.type == "category":
  133. current_category = definition.label
  134. continue
  135. profile_value = None
  136. profile_value_source = ""
  137. for container in containers:
  138. new_value = container.getProperty(definition.key, "value")
  139. if new_value is not None:
  140. profile_value_source = container.getMetaDataEntry("type")
  141. profile_value = new_value
  142. user_value = None
  143. if not self._extruder_id:
  144. user_value = global_container_stack.getTop().getProperty(definition.key, "value")
  145. else:
  146. extruder_stack = self._container_registry.findContainerStacks(id = self._extruder_id)
  147. if extruder_stack:
  148. user_value = extruder_stack[0].getTop().getProperty(definition.key, "value")
  149. if profile_value is None and user_value is None:
  150. continue
  151. if is_multi_extrusion:
  152. settable_per_extruder = global_container_stack.getProperty(definition.key, "settable_per_extruder")
  153. # If a setting is not settable per extruder (global) and we're looking at an extruder tab, don't show this value.
  154. if self._extruder_id != "" and not settable_per_extruder:
  155. continue
  156. # If a setting is settable per extruder (not global) and we're looking at global tab, don't show this value.
  157. if self._extruder_id == "" and settable_per_extruder:
  158. continue
  159. items.append({
  160. "key": definition.key,
  161. "label": definition.label,
  162. "unit": definition.unit,
  163. "profile_value": "" if profile_value is None else str(profile_value), # it is for display only
  164. "profile_value_source": profile_value_source,
  165. "user_value": "" if user_value is None else str(user_value),
  166. "category": current_category
  167. })
  168. self.setItems(items)