MachineActionManager.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. # Copyright (c) 2016 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. from UM.Logger import Logger
  4. from UM.PluginRegistry import PluginRegistry # So MachineAction can be added as plugin type
  5. from UM.Settings.ContainerRegistry import ContainerRegistry
  6. from UM.Settings.DefinitionContainer import DefinitionContainer
  7. from PyQt5.QtCore import QObject
  8. from UM.FlameProfiler import pyqtSlot
  9. ## Raised when trying to add an unknown machine action as a required action
  10. class UnknownMachineActionError(Exception):
  11. pass
  12. ## Raised when trying to add a machine action that does not have an unique key.
  13. class NotUniqueMachineActionError(Exception):
  14. pass
  15. class MachineActionManager(QObject):
  16. def __init__(self, parent = None):
  17. super().__init__(parent)
  18. self._machine_actions = {} # Dict of all known machine actions
  19. self._required_actions = {} # Dict of all required actions by definition ID
  20. self._supported_actions = {} # Dict of all supported actions by definition ID
  21. self._first_start_actions = {} # Dict of all actions that need to be done when first added by definition ID
  22. # Add machine_action as plugin type
  23. PluginRegistry.addType("machine_action", self.addMachineAction)
  24. # Ensure that all containers that were registered before creation of this registry are also handled.
  25. # This should not have any effect, but it makes it safer if we ever refactor the order of things.
  26. for container in ContainerRegistry.getInstance().findDefinitionContainers():
  27. self._onContainerAdded(container)
  28. ContainerRegistry.getInstance().containerAdded.connect(self._onContainerAdded)
  29. def _onContainerAdded(self, container):
  30. ## Ensure that the actions are added to this manager
  31. if isinstance(container, DefinitionContainer):
  32. supported_actions = container.getMetaDataEntry("supported_actions", [])
  33. for action in supported_actions:
  34. self.addSupportedAction(container.getId(), action)
  35. required_actions = container.getMetaDataEntry("required_actions", [])
  36. for action in required_actions:
  37. self.addRequiredAction(container.getId(), action)
  38. first_start_actions = container.getMetaDataEntry("first_start_actions", [])
  39. for action in first_start_actions:
  40. self.addFirstStartAction(container.getId(), action)
  41. ## Add a required action to a machine
  42. # Raises an exception when the action is not recognised.
  43. def addRequiredAction(self, definition_id, action_key):
  44. if action_key in self._machine_actions:
  45. if definition_id in self._required_actions:
  46. if self._machine_actions[action_key] not in self._required_actions[definition_id]:
  47. self._required_actions[definition_id].append(self._machine_actions[action_key])
  48. else:
  49. self._required_actions[definition_id] = [self._machine_actions[action_key]]
  50. else:
  51. raise UnknownMachineActionError("Action %s, which is required for %s is not known." % (action_key, definition_id))
  52. ## Add a supported action to a machine.
  53. def addSupportedAction(self, definition_id, action_key):
  54. if action_key in self._machine_actions:
  55. if definition_id in self._supported_actions:
  56. if self._machine_actions[action_key] not in self._supported_actions[definition_id]:
  57. self._supported_actions[definition_id].append(self._machine_actions[action_key])
  58. else:
  59. self._supported_actions[definition_id] = [self._machine_actions[action_key]]
  60. else:
  61. Logger.log("w", "Unable to add %s to %s, as the action is not recognised", action_key, definition_id)
  62. ## Add an action to the first start list of a machine.
  63. def addFirstStartAction(self, definition_id, action_key, index = None):
  64. if action_key in self._machine_actions:
  65. if definition_id in self._first_start_actions:
  66. if index is not None:
  67. self._first_start_actions[definition_id].insert(index, self._machine_actions[action_key])
  68. else:
  69. self._first_start_actions[definition_id].append(self._machine_actions[action_key])
  70. else:
  71. self._first_start_actions[definition_id] = [self._machine_actions[action_key]]
  72. else:
  73. Logger.log("w", "Unable to add %s to %s, as the action is not recognised", action_key, definition_id)
  74. ## Add a (unique) MachineAction
  75. # if the Key of the action is not unique, an exception is raised.
  76. def addMachineAction(self, action):
  77. if action.getKey() not in self._machine_actions:
  78. self._machine_actions[action.getKey()] = action
  79. else:
  80. raise NotUniqueMachineActionError("MachineAction with key %s was already added. Actions must have unique keys.", action.getKey())
  81. ## Get all actions supported by given machine
  82. # \param definition_id The ID of the definition you want the supported actions of
  83. # \returns set of supported actions.
  84. @pyqtSlot(str, result = "QVariantList")
  85. def getSupportedActions(self, definition_id):
  86. if definition_id in self._supported_actions:
  87. return list(self._supported_actions[definition_id])
  88. else:
  89. return list()
  90. ## Get all actions required by given machine
  91. # \param definition_id The ID of the definition you want the required actions of
  92. # \returns set of required actions.
  93. def getRequiredActions(self, definition_id):
  94. if definition_id in self._required_actions:
  95. return self._required_actions[definition_id]
  96. else:
  97. return set()
  98. ## Get all actions that need to be performed upon first start of a given machine.
  99. # Note that contrary to required / supported actions a list is returned (as it could be required to run the same
  100. # action multiple times).
  101. # \param definition_id The ID of the definition that you want to get the "on added" actions for.
  102. # \returns List of actions.
  103. @pyqtSlot(str, result="QVariantList")
  104. def getFirstStartActions(self, definition_id):
  105. if definition_id in self._first_start_actions:
  106. return self._first_start_actions[definition_id]
  107. else:
  108. return []
  109. ## Remove Machine action from manager
  110. # \param action to remove
  111. def removeMachineAction(self, action):
  112. try:
  113. del self._machine_actions[action.getKey()]
  114. except KeyError:
  115. Logger.log("w", "Trying to remove MachineAction (%s) that was already removed", action.getKey())
  116. ## Get MachineAction by key
  117. # \param key String of key to select
  118. # \return Machine action if found, None otherwise
  119. def getMachineAction(self, key):
  120. if key in self._machine_actions:
  121. return self._machine_actions[key]
  122. else:
  123. return None