UserChangesModel.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. from UM.Qt.ListModel import ListModel
  2. from PyQt5.QtCore import pyqtSlot, Qt
  3. from UM.Application import Application
  4. from cura.Settings.ExtruderManager import ExtruderManager
  5. from UM.Settings.ContainerRegistry import ContainerRegistry
  6. from UM.i18n import i18nCatalog
  7. from UM.Settings.SettingFunction import SettingFunction
  8. from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext
  9. from collections import OrderedDict
  10. import os
  11. class UserChangesModel(ListModel):
  12. KeyRole = Qt.UserRole + 1
  13. LabelRole = Qt.UserRole + 2
  14. ExtruderRole = Qt.UserRole + 3
  15. OriginalValueRole = Qt.UserRole + 4
  16. UserValueRole = Qt.UserRole + 6
  17. CategoryRole = Qt.UserRole + 7
  18. def __init__(self, parent = None):
  19. super().__init__(parent = parent)
  20. self.addRoleName(self.KeyRole, "key")
  21. self.addRoleName(self.LabelRole, "label")
  22. self.addRoleName(self.ExtruderRole, "extruder")
  23. self.addRoleName(self.OriginalValueRole, "original_value")
  24. self.addRoleName(self.UserValueRole, "user_value")
  25. self.addRoleName(self.CategoryRole, "category")
  26. self._i18n_catalog = None
  27. self._update()
  28. @pyqtSlot()
  29. def forceUpdate(self):
  30. self._update()
  31. def _update(self):
  32. item_dict = OrderedDict()
  33. item_list = []
  34. global_stack = Application.getInstance().getGlobalContainerStack()
  35. if not global_stack:
  36. return
  37. stacks = [global_stack]
  38. stacks.extend(global_stack.extruders.values())
  39. # Check if the definition container has a translation file and ensure it's loaded.
  40. definition = global_stack.getBottom()
  41. definition_suffix = ContainerRegistry.getMimeTypeForContainer(type(definition)).preferredSuffix
  42. catalog = i18nCatalog(os.path.basename(definition.getId() + "." + definition_suffix))
  43. if catalog.hasTranslationLoaded():
  44. self._i18n_catalog = catalog
  45. for file_name in definition.getInheritedFiles():
  46. catalog = i18nCatalog(os.path.basename(file_name))
  47. if catalog.hasTranslationLoaded():
  48. self._i18n_catalog = catalog
  49. for stack in stacks:
  50. # Make a list of all containers in the stack.
  51. containers = []
  52. latest_stack = stack
  53. while latest_stack:
  54. containers.extend(latest_stack.getContainers())
  55. latest_stack = latest_stack.getNextStack()
  56. # Override "getExtruderValue" with "getDefaultExtruderValue" so we can get the default values
  57. user_changes = containers.pop(0)
  58. default_value_resolve_context = PropertyEvaluationContext(stack)
  59. default_value_resolve_context.context["evaluate_from_container_index"] = 1 # skip the user settings container
  60. default_value_resolve_context.context["override_operators"] = {
  61. "extruderValue": ExtruderManager.getDefaultExtruderValue,
  62. "extruderValues": ExtruderManager.getDefaultExtruderValues,
  63. "resolveOrValue": ExtruderManager.getDefaultResolveOrValue
  64. }
  65. for setting_key in user_changes.getAllKeys():
  66. original_value = None
  67. # Find the category of the instance by moving up until we find a category.
  68. category = user_changes.getInstance(setting_key).definition
  69. while category.type != "category":
  70. category = category.parent
  71. # Handle translation (and fallback if we weren't able to find any translation files.
  72. if self._i18n_catalog:
  73. category_label = self._i18n_catalog.i18nc(category.key + " label", category.label)
  74. else:
  75. category_label = category.label
  76. if self._i18n_catalog:
  77. label = self._i18n_catalog.i18nc(setting_key + " label", stack.getProperty(setting_key, "label"))
  78. else:
  79. label = stack.getProperty(setting_key, "label")
  80. for container in containers:
  81. if stack == global_stack:
  82. resolve = global_stack.getProperty(setting_key, "resolve", default_value_resolve_context)
  83. if resolve is not None:
  84. original_value = resolve
  85. break
  86. original_value = container.getProperty(setting_key, "value", default_value_resolve_context)
  87. # If a value is a function, ensure it's called with the stack it's in.
  88. if isinstance(original_value, SettingFunction):
  89. original_value = original_value(stack, default_value_resolve_context)
  90. if original_value is not None:
  91. break
  92. item_to_add = {"key": setting_key,
  93. "label": label,
  94. "user_value": str(user_changes.getProperty(setting_key, "value")),
  95. "original_value": str(original_value),
  96. "extruder": "",
  97. "category": category_label}
  98. if stack != global_stack:
  99. item_to_add["extruder"] = stack.getName()
  100. if category_label not in item_dict:
  101. item_dict[category_label] = []
  102. item_dict[category_label].append(item_to_add)
  103. for each_item_list in item_dict.values():
  104. item_list += each_item_list
  105. self.setItems(item_list)