QualitySettingsModel.py 7.3 KB

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