ExtrudersModel.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. # Copyright (c) 2016 Ultimaker B.V.
  2. # Cura is released under the terms of the AGPLv3 or higher.
  3. from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty
  4. import cura.ExtruderManager
  5. import UM.Qt.ListModel
  6. ## Model that holds extruders.
  7. #
  8. # This model is designed for use by any list of extruders, but specifically
  9. # intended for drop-down lists of the current machine's extruders in place of
  10. # settings.
  11. class ExtrudersModel(UM.Qt.ListModel.ListModel):
  12. # The ID of the container stack for the extruder.
  13. IdRole = Qt.UserRole + 1
  14. ## Human-readable name of the extruder.
  15. NameRole = Qt.UserRole + 2
  16. ## Colour of the material loaded in the extruder.
  17. ColourRole = Qt.UserRole + 3
  18. ## Index of the extruder, which is also the value of the setting itself.
  19. #
  20. # An index of 0 indicates the first extruder, an index of 1 the second
  21. # one, and so on. This is the value that will be saved in instance
  22. # containers.
  23. IndexRole = Qt.UserRole + 4
  24. ## List of colours to display if there is no material or the material has no known
  25. # colour.
  26. defaultColours = ["#ffc924", "#86ec21", "#22eeee", "#245bff", "#9124ff", "#ff24c8"]
  27. ## Initialises the extruders model, defining the roles and listening for
  28. # changes in the data.
  29. #
  30. # \param parent Parent QtObject of this list.
  31. def __init__(self, parent = None):
  32. super().__init__(parent)
  33. self.addRoleName(self.IdRole, "id")
  34. self.addRoleName(self.NameRole, "name")
  35. self.addRoleName(self.ColourRole, "colour")
  36. self.addRoleName(self.IndexRole, "index")
  37. self._add_global = False
  38. self._active_extruder_stack = None
  39. #Listen to changes.
  40. manager = cura.ExtruderManager.ExtruderManager.getInstance()
  41. manager.extrudersChanged.connect(self._updateExtruders) #When the list of extruders changes in general.
  42. UM.Application.getInstance().globalContainerStackChanged.connect(self._updateExtruders) #When the current machine changes.
  43. self._updateExtruders()
  44. manager.activeExtruderChanged.connect(self._onActiveExtruderChanged)
  45. self._onActiveExtruderChanged()
  46. def setAddGlobal(self, add):
  47. if add != self._add_global:
  48. self._add_global = add
  49. self._updateExtruders()
  50. self.addGlobalChanged.emit()
  51. addGlobalChanged = pyqtSignal()
  52. @pyqtProperty(bool, fset = setAddGlobal, notify = addGlobalChanged)
  53. def addGlobal(self):
  54. return self._add_global
  55. def _onActiveExtruderChanged(self):
  56. manager = cura.ExtruderManager.ExtruderManager.getInstance()
  57. active_extruder_stack = manager.getActiveExtruderStack()
  58. if self._active_extruder_stack != active_extruder_stack:
  59. if self._active_extruder_stack:
  60. self._active_extruder_stack.containersChanged.disconnect(self._onExtruderStackContainersChanged)
  61. if active_extruder_stack:
  62. # Update the model when the material container is changed
  63. active_extruder_stack.containersChanged.connect(self._onExtruderStackContainersChanged)
  64. self._active_extruder_stack = active_extruder_stack
  65. def _onExtruderStackContainersChanged(self, container):
  66. # The ExtrudersModel needs to be updated when the material-name or -color changes, because the user identifies extruders by material-name
  67. if container.getMetaDataEntry("type") == "material":
  68. self._updateExtruders()
  69. modelChanged = pyqtSignal()
  70. ## Update the list of extruders.
  71. #
  72. # This should be called whenever the list of extruders changes.
  73. def _updateExtruders(self):
  74. self.clear()
  75. manager = cura.ExtruderManager.ExtruderManager.getInstance()
  76. global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
  77. if not global_container_stack:
  78. return #There is no machine to get the extruders of.
  79. if self._add_global:
  80. material = global_container_stack.findContainer({ "type": "material" })
  81. colour = material.getMetaDataEntry("color_code", default = self.defaultColours[0]) if material else self.defaultColours[0]
  82. item = {
  83. "id": global_container_stack.getId(),
  84. "name": "Global",
  85. "colour": colour,
  86. "index": -1
  87. }
  88. self.appendItem(item)
  89. for extruder in manager.getMachineExtruders(global_container_stack.getBottom().getId()):
  90. extruder_name = extruder.getName()
  91. material = extruder.findContainer({ "type": "material" })
  92. if material:
  93. extruder_name = "%s (%s)" % (material.getName(), extruder_name)
  94. position = extruder.getBottom().getMetaDataEntry("position", default = "0") #Position in the definition.
  95. try:
  96. position = int(position)
  97. except ValueError: #Not a proper int.
  98. position = -1
  99. default_colour = self.defaultColours[position] if position >= 0 and position < len(self.defaultColours) else defaultColours[0]
  100. colour = material.getMetaDataEntry("color_code", default = default_colour) if material else default_colour
  101. item = { #Construct an item with only the relevant information.
  102. "id": extruder.getId(),
  103. "name": extruder_name,
  104. "colour": colour,
  105. "index": position
  106. }
  107. self.appendItem(item)
  108. self.sort(lambda item: item["index"])
  109. self.modelChanged.emit()