QualitySettingsModel.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. # Copyright (c) 2018 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
  4. from UM.Application import Application
  5. from UM.Logger import Logger
  6. from UM.Qt.ListModel import ListModel
  7. from UM.Settings.ContainerRegistry import ContainerRegistry
  8. #
  9. # This model is used to show details settings of the selected quality in the quality management page.
  10. #
  11. class QualitySettingsModel(ListModel):
  12. KeyRole = Qt.UserRole + 1
  13. LabelRole = Qt.UserRole + 2
  14. UnitRole = Qt.UserRole + 3
  15. ProfileValueRole = Qt.UserRole + 4
  16. ProfileValueSourceRole = Qt.UserRole + 5
  17. UserValueRole = Qt.UserRole + 6
  18. CategoryRole = Qt.UserRole + 7
  19. def __init__(self, parent = None):
  20. super().__init__(parent = parent)
  21. self.addRoleName(self.KeyRole, "key")
  22. self.addRoleName(self.LabelRole, "label")
  23. self.addRoleName(self.UnitRole, "unit")
  24. self.addRoleName(self.ProfileValueRole, "profile_value")
  25. self.addRoleName(self.ProfileValueSourceRole, "profile_value_source")
  26. self.addRoleName(self.UserValueRole, "user_value")
  27. self.addRoleName(self.CategoryRole, "category")
  28. self._container_registry = ContainerRegistry.getInstance()
  29. self._application = Application.getInstance()
  30. self._quality_manager = self._application.getQualityManager()
  31. self._selected_position = "" # empty string means GlobalStack
  32. # strings such as "0", "1", etc. mean extruder positions
  33. self._selected_quality_item = None # The selected quality in the quality management page
  34. self._i18n_catalog = None
  35. self._quality_manager.qualitiesUpdated.connect(self._update)
  36. self._update()
  37. selectedPositionChanged = pyqtSignal()
  38. selectedQualityItemChanged = pyqtSignal()
  39. def setSelectedPosition(self, selected_position):
  40. if selected_position != self._selected_position:
  41. self._selected_position = selected_position
  42. self.selectedPositionChanged.emit()
  43. self._update()
  44. @pyqtProperty(str, fset = setSelectedPosition, notify = selectedPositionChanged)
  45. def selectedPosition(self):
  46. return self._selected_position
  47. def setSelectedQualityItem(self, selected_quality_item):
  48. if selected_quality_item != self._selected_quality_item:
  49. self._selected_quality_item = selected_quality_item
  50. self.selectedQualityItemChanged.emit()
  51. self._update()
  52. @pyqtProperty("QVariantMap", fset = setSelectedQualityItem, notify = selectedQualityItemChanged)
  53. def selectedQualityItem(self):
  54. return self._selected_quality_item
  55. def _update(self):
  56. Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
  57. if not self._selected_quality_item:
  58. self.setItems([])
  59. return
  60. items = []
  61. global_container_stack = self._application.getGlobalContainerStack()
  62. definition_container = global_container_stack.definition
  63. quality_group = self._selected_quality_item["quality_group"]
  64. quality_changes_group = self._selected_quality_item["quality_changes_group"]
  65. if self._selected_position == "":
  66. quality_node = quality_group.node_for_global
  67. else:
  68. quality_node = quality_group.nodes_for_extruders.get(self._selected_position)
  69. settings_keys = quality_group.getAllKeys()
  70. quality_containers = [quality_node.getContainer()]
  71. # Here, if the user has selected a quality changes, then "quality_changes_group" will not be None, and we fetch
  72. # the settings in that quality_changes_group.
  73. if quality_changes_group is not None:
  74. if self._selected_position == "":
  75. quality_changes_node = quality_changes_group.node_for_global
  76. else:
  77. quality_changes_node = quality_changes_group.nodes_for_extruders.get(self._selected_position)
  78. if quality_changes_node is not None: # it can be None if number of extruders are changed during runtime
  79. try:
  80. quality_containers.insert(0, quality_changes_node.getContainer())
  81. except:
  82. # FIXME: This is to prevent incomplete update of QualityManager
  83. Logger.logException("d", "Failed to get container for quality changes node %s", quality_changes_node)
  84. return
  85. settings_keys.update(quality_changes_group.getAllKeys())
  86. # We iterate over all definitions instead of settings in a quality/qualtiy_changes group is because in the GUI,
  87. # the settings are grouped together by categories, and we had to go over all the definitions to figure out
  88. # which setting belongs in which category.
  89. current_category = ""
  90. for definition in definition_container.findDefinitions():
  91. if definition.type == "category":
  92. current_category = definition.label
  93. if self._i18n_catalog:
  94. current_category = self._i18n_catalog.i18nc(definition.key + " label", definition.label)
  95. continue
  96. profile_value = None
  97. profile_value_source = ""
  98. for quality_container in quality_containers:
  99. new_value = quality_container.getProperty(definition.key, "value")
  100. if new_value is not None:
  101. profile_value_source = quality_container.getMetaDataEntry("type")
  102. profile_value = new_value
  103. # Global tab should use resolve (if there is one)
  104. if self._selected_position == "":
  105. resolve_value = global_container_stack.getProperty(definition.key, "resolve")
  106. if resolve_value is not None and definition.key in settings_keys:
  107. profile_value = resolve_value
  108. if profile_value is not None:
  109. break
  110. if not self._selected_position:
  111. user_value = global_container_stack.userChanges.getProperty(definition.key, "value")
  112. else:
  113. extruder_stack = global_container_stack.extruders[self._selected_position]
  114. user_value = extruder_stack.userChanges.getProperty(definition.key, "value")
  115. if profile_value is None and user_value is None:
  116. continue
  117. label = definition.label
  118. if self._i18n_catalog:
  119. label = self._i18n_catalog.i18nc(definition.key + " label", label)
  120. items.append({
  121. "key": definition.key,
  122. "label": label,
  123. "unit": definition.unit,
  124. "profile_value": "" if profile_value is None else str(profile_value), # it is for display only
  125. "profile_value_source": profile_value_source,
  126. "user_value": "" if user_value is None else str(user_value),
  127. "category": current_category
  128. })
  129. self.setItems(items)