UserChangesModel.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. # Copyright (c) 2020 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. import os
  4. from collections import OrderedDict
  5. from PyQt6.QtCore import pyqtSlot, Qt
  6. from UM.Application import Application
  7. from UM.Logger import Logger
  8. from UM.Settings.ContainerRegistry import ContainerRegistry
  9. from UM.i18n import i18nCatalog
  10. from UM.Settings.SettingFunction import SettingFunction
  11. from UM.Qt.ListModel import ListModel
  12. class UserChangesModel(ListModel):
  13. KeyRole = Qt.ItemDataRole.UserRole + 1
  14. LabelRole = Qt.ItemDataRole.UserRole + 2
  15. ExtruderRole = Qt.ItemDataRole.UserRole + 3
  16. OriginalValueRole = Qt.ItemDataRole.UserRole + 4
  17. UserValueRole = Qt.ItemDataRole.UserRole + 6
  18. CategoryRole = Qt.ItemDataRole.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.ExtruderRole, "extruder")
  24. self.addRoleName(self.OriginalValueRole, "original_value")
  25. self.addRoleName(self.UserValueRole, "user_value")
  26. self.addRoleName(self.CategoryRole, "category")
  27. self._i18n_catalog = None
  28. self._update()
  29. @pyqtSlot()
  30. def forceUpdate(self):
  31. self._update()
  32. def _update(self):
  33. application = Application.getInstance()
  34. machine_manager = application.getMachineManager()
  35. cura_formula_functions = application.getCuraFormulaFunctions()
  36. item_dict = OrderedDict()
  37. item_list = []
  38. global_stack = machine_manager.activeMachine
  39. if not global_stack:
  40. return
  41. stacks = [global_stack]
  42. stacks.extend(global_stack.extruderList)
  43. # Check if the definition container has a translation file and ensure it's loaded.
  44. definition = global_stack.getBottom()
  45. definition_suffix = ContainerRegistry.getMimeTypeForContainer(type(definition)).preferredSuffix
  46. catalog = i18nCatalog(os.path.basename(definition.getId() + "." + definition_suffix))
  47. if catalog.hasTranslationLoaded():
  48. self._i18n_catalog = catalog
  49. for file_name in definition.getInheritedFiles():
  50. catalog = i18nCatalog(os.path.basename(file_name))
  51. if catalog.hasTranslationLoaded():
  52. self._i18n_catalog = catalog
  53. for stack in stacks:
  54. # Make a list of all containers in the stack.
  55. containers = []
  56. latest_stack = stack
  57. while latest_stack:
  58. containers.extend(latest_stack.getContainers())
  59. latest_stack = latest_stack.getNextStack()
  60. # Override "getExtruderValue" with "getDefaultExtruderValue" so we can get the default values
  61. user_changes = containers.pop(0)
  62. default_value_resolve_context = cura_formula_functions.createContextForDefaultValueEvaluation(stack)
  63. for setting_key in user_changes.getAllKeys():
  64. original_value = None
  65. # Find the category of the instance by moving up until we find a category.
  66. category = user_changes.getInstance(setting_key).definition
  67. while category is not None and category.type != "category":
  68. category = category.parent
  69. # Handle translation (and fallback if we weren't able to find any translation files.
  70. if category is not None:
  71. if self._i18n_catalog:
  72. category_label = self._i18n_catalog.i18nc(category.key + " label", category.label)
  73. else:
  74. category_label = category.label
  75. else: # Setting is not in any category. Shouldn't happen, but it do. See https://sentry.io/share/issue/d735884370154166bc846904d9b812ff/
  76. Logger.error("Setting {key} is not in any setting category.".format(key = setting_key))
  77. category_label = ""
  78. if self._i18n_catalog:
  79. label = self._i18n_catalog.i18nc(setting_key + " label", stack.getProperty(setting_key, "label"))
  80. else:
  81. label = stack.getProperty(setting_key, "label")
  82. for container in containers:
  83. if stack == global_stack:
  84. resolve = global_stack.getProperty(setting_key, "resolve", default_value_resolve_context)
  85. if resolve is not None:
  86. original_value = resolve
  87. break
  88. original_value = container.getProperty(setting_key, "value", default_value_resolve_context)
  89. # If a value is a function, ensure it's called with the stack it's in.
  90. if isinstance(original_value, SettingFunction):
  91. original_value = original_value(stack, default_value_resolve_context)
  92. if original_value is not None:
  93. break
  94. item_to_add = {
  95. "key": setting_key,
  96. "label": label,
  97. "user_value": str(user_changes.getProperty(setting_key, "value", default_value_resolve_context)),
  98. "original_value": str(original_value),
  99. "extruder": "",
  100. "category": category_label,
  101. }
  102. if stack != global_stack:
  103. item_to_add["extruder"] = stack.getName()
  104. if category_label not in item_dict:
  105. item_dict[category_label] = []
  106. item_dict[category_label].append(item_to_add)
  107. for each_item_list in item_dict.values():
  108. item_list += each_item_list
  109. self.setItems(item_list)