mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-06-30 19:25:13 +08:00
Merge pull request #4613 from Ultimaker/CURA-5812_fix_machine_actions
CURA-5808 Fix machine actions
This commit is contained in:
commit
41edfe85b5
@ -168,6 +168,8 @@ class CuraApplication(QtApplication):
|
|||||||
|
|
||||||
self.default_theme = "cura-light"
|
self.default_theme = "cura-light"
|
||||||
|
|
||||||
|
self.change_log_url = "https://ultimaker.com/ultimaker-cura-latest-features"
|
||||||
|
|
||||||
self._boot_loading_time = time.time()
|
self._boot_loading_time = time.time()
|
||||||
|
|
||||||
self._on_exit_callback_manager = OnExitCallbackManager(self)
|
self._on_exit_callback_manager = OnExitCallbackManager(self)
|
||||||
@ -304,8 +306,6 @@ class CuraApplication(QtApplication):
|
|||||||
self._machine_action_manager = MachineActionManager.MachineActionManager(self)
|
self._machine_action_manager = MachineActionManager.MachineActionManager(self)
|
||||||
self._machine_action_manager.initialize()
|
self._machine_action_manager.initialize()
|
||||||
|
|
||||||
self.change_log_url = "https://ultimaker.com/ultimaker-cura-latest-features"
|
|
||||||
|
|
||||||
def __sendCommandToSingleInstance(self):
|
def __sendCommandToSingleInstance(self):
|
||||||
self._single_instance = SingleInstance(self, self._files_to_open)
|
self._single_instance = SingleInstance(self, self._files_to_open)
|
||||||
|
|
||||||
@ -701,7 +701,7 @@ class CuraApplication(QtApplication):
|
|||||||
self._quality_manager.initialize()
|
self._quality_manager.initialize()
|
||||||
|
|
||||||
Logger.log("i", "Initializing machine manager")
|
Logger.log("i", "Initializing machine manager")
|
||||||
self._machine_manager = MachineManager(self)
|
self._machine_manager = MachineManager(self, parent = self)
|
||||||
|
|
||||||
Logger.log("i", "Initializing container manager")
|
Logger.log("i", "Initializing container manager")
|
||||||
self._container_manager = ContainerManager(self)
|
self._container_manager = ContainerManager(self)
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
# Copyright (c) 2016 Ultimaker B.V.
|
# Copyright (c) 2016 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal
|
from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal
|
||||||
|
|
||||||
|
from UM.Logger import Logger
|
||||||
from UM.PluginObject import PluginObject
|
from UM.PluginObject import PluginObject
|
||||||
from UM.PluginRegistry import PluginRegistry
|
from UM.PluginRegistry import PluginRegistry
|
||||||
from UM.Application import Application
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
## Machine actions are actions that are added to a specific machine type. Examples of such actions are
|
## Machine actions are actions that are added to a specific machine type. Examples of such actions are
|
||||||
@ -19,7 +19,7 @@ class MachineAction(QObject, PluginObject):
|
|||||||
## Create a new Machine action.
|
## Create a new Machine action.
|
||||||
# \param key unique key of the machine action
|
# \param key unique key of the machine action
|
||||||
# \param label Human readable label used to identify the machine action.
|
# \param label Human readable label used to identify the machine action.
|
||||||
def __init__(self, key, label = ""):
|
def __init__(self, key: str, label: str = "") -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._key = key
|
self._key = key
|
||||||
self._label = label
|
self._label = label
|
||||||
@ -30,14 +30,14 @@ class MachineAction(QObject, PluginObject):
|
|||||||
labelChanged = pyqtSignal()
|
labelChanged = pyqtSignal()
|
||||||
onFinished = pyqtSignal()
|
onFinished = pyqtSignal()
|
||||||
|
|
||||||
def getKey(self):
|
def getKey(self) -> str:
|
||||||
return self._key
|
return self._key
|
||||||
|
|
||||||
@pyqtProperty(str, notify = labelChanged)
|
@pyqtProperty(str, notify = labelChanged)
|
||||||
def label(self):
|
def label(self) -> str:
|
||||||
return self._label
|
return self._label
|
||||||
|
|
||||||
def setLabel(self, label):
|
def setLabel(self, label: str) -> None:
|
||||||
if self._label != label:
|
if self._label != label:
|
||||||
self._label = label
|
self._label = label
|
||||||
self.labelChanged.emit()
|
self.labelChanged.emit()
|
||||||
@ -46,29 +46,35 @@ class MachineAction(QObject, PluginObject):
|
|||||||
# This should not be re-implemented by child classes, instead re-implement _reset.
|
# This should not be re-implemented by child classes, instead re-implement _reset.
|
||||||
# /sa _reset
|
# /sa _reset
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def reset(self):
|
def reset(self) -> None:
|
||||||
self._finished = False
|
self._finished = False
|
||||||
self._reset()
|
self._reset()
|
||||||
|
|
||||||
## Protected implementation of reset.
|
## Protected implementation of reset.
|
||||||
# /sa reset()
|
# /sa reset()
|
||||||
def _reset(self):
|
def _reset(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def setFinished(self):
|
def setFinished(self) -> None:
|
||||||
self._finished = True
|
self._finished = True
|
||||||
self._reset()
|
self._reset()
|
||||||
self.onFinished.emit()
|
self.onFinished.emit()
|
||||||
|
|
||||||
@pyqtProperty(bool, notify = onFinished)
|
@pyqtProperty(bool, notify = onFinished)
|
||||||
def finished(self):
|
def finished(self) -> bool:
|
||||||
return self._finished
|
return self._finished
|
||||||
|
|
||||||
## Protected helper to create a view object based on provided QML.
|
## Protected helper to create a view object based on provided QML.
|
||||||
def _createViewFromQML(self):
|
def _createViewFromQML(self) -> None:
|
||||||
path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), self._qml_url)
|
plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId())
|
||||||
self._view = Application.getInstance().createQmlComponent(path, {"manager": self})
|
if plugin_path is None:
|
||||||
|
Logger.log("e", "Cannot create QML view: cannot find plugin path for plugin [%s]", self.getPluginId())
|
||||||
|
return
|
||||||
|
path = os.path.join(plugin_path, self._qml_url)
|
||||||
|
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
self._view = CuraApplication.getInstance().createQmlComponent(path, {"manager": self})
|
||||||
|
|
||||||
@pyqtProperty(QObject, constant = True)
|
@pyqtProperty(QObject, constant = True)
|
||||||
def displayItem(self):
|
def displayItem(self):
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
# Copyright (c) 2018 Ultimaker B.V.
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Optional, List, Set, Dict
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject
|
from PyQt5.QtCore import QObject
|
||||||
|
|
||||||
from UM.FlameProfiler import pyqtSlot
|
from UM.FlameProfiler import pyqtSlot
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.PluginRegistry import PluginRegistry # So MachineAction can be added as plugin type
|
from UM.PluginRegistry import PluginRegistry # So MachineAction can be added as plugin type
|
||||||
from UM.Settings.DefinitionContainer import DefinitionContainer
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
from .MachineAction import MachineAction
|
||||||
|
|
||||||
|
|
||||||
## Raised when trying to add an unknown machine action as a required action
|
## Raised when trying to add an unknown machine action as a required action
|
||||||
@ -20,46 +26,54 @@ class NotUniqueMachineActionError(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class MachineActionManager(QObject):
|
class MachineActionManager(QObject):
|
||||||
def __init__(self, application, parent = None):
|
def __init__(self, application: "CuraApplication", parent: Optional["QObject"] = None) -> None:
|
||||||
super().__init__(parent)
|
super().__init__(parent = parent)
|
||||||
self._application = application
|
self._application = application
|
||||||
|
self._container_registry = self._application.getContainerRegistry()
|
||||||
|
|
||||||
self._machine_actions = {} # Dict of all known machine actions
|
# Keeps track of which machines have already been processed so we don't do that again.
|
||||||
self._required_actions = {} # Dict of all required actions by definition ID
|
self._definition_ids_with_default_actions_added = set() # type: Set[str]
|
||||||
self._supported_actions = {} # Dict of all supported actions by definition ID
|
|
||||||
self._first_start_actions = {} # Dict of all actions that need to be done when first added by definition ID
|
# Dict of all known machine actions
|
||||||
|
self._machine_actions = {} # type: Dict[str, MachineAction]
|
||||||
|
# Dict of all required actions by definition ID
|
||||||
|
self._required_actions = {} # type: Dict[str, List[MachineAction]]
|
||||||
|
# Dict of all supported actions by definition ID
|
||||||
|
self._supported_actions = {} # type: Dict[str, List[MachineAction]]
|
||||||
|
# Dict of all actions that need to be done when first added by definition ID
|
||||||
|
self._first_start_actions = {} # type: Dict[str, List[MachineAction]]
|
||||||
|
|
||||||
def initialize(self):
|
def initialize(self):
|
||||||
container_registry = self._application.getContainerRegistry()
|
|
||||||
|
|
||||||
# Add machine_action as plugin type
|
# Add machine_action as plugin type
|
||||||
PluginRegistry.addType("machine_action", self.addMachineAction)
|
PluginRegistry.addType("machine_action", self.addMachineAction)
|
||||||
|
|
||||||
# Ensure that all containers that were registered before creation of this registry are also handled.
|
# Adds all default machine actions that are defined in the machine definition for the given machine.
|
||||||
# This should not have any effect, but it makes it safer if we ever refactor the order of things.
|
def addDefaultMachineActions(self, global_stack: "GlobalStack") -> None:
|
||||||
for container in container_registry.findDefinitionContainers():
|
definition_id = global_stack.definition.getId()
|
||||||
self._onContainerAdded(container)
|
|
||||||
|
|
||||||
container_registry.containerAdded.connect(self._onContainerAdded)
|
if definition_id in self._definition_ids_with_default_actions_added:
|
||||||
|
Logger.log("i", "Default machine actions have been added for machine definition [%s], do nothing.",
|
||||||
|
definition_id)
|
||||||
|
return
|
||||||
|
|
||||||
def _onContainerAdded(self, container):
|
supported_actions = global_stack.getMetaDataEntry("supported_actions", [])
|
||||||
## Ensure that the actions are added to this manager
|
for action_key in supported_actions:
|
||||||
if isinstance(container, DefinitionContainer):
|
self.addSupportedAction(definition_id, action_key)
|
||||||
supported_actions = container.getMetaDataEntry("supported_actions", [])
|
|
||||||
for action in supported_actions:
|
|
||||||
self.addSupportedAction(container.getId(), action)
|
|
||||||
|
|
||||||
required_actions = container.getMetaDataEntry("required_actions", [])
|
required_actions = global_stack.getMetaDataEntry("required_actions", [])
|
||||||
for action in required_actions:
|
for action_key in required_actions:
|
||||||
self.addRequiredAction(container.getId(), action)
|
self.addRequiredAction(definition_id, action_key)
|
||||||
|
|
||||||
first_start_actions = container.getMetaDataEntry("first_start_actions", [])
|
first_start_actions = global_stack.getMetaDataEntry("first_start_actions", [])
|
||||||
for action in first_start_actions:
|
for action_key in first_start_actions:
|
||||||
self.addFirstStartAction(container.getId(), action)
|
self.addFirstStartAction(definition_id, action_key)
|
||||||
|
|
||||||
|
self._definition_ids_with_default_actions_added.add(definition_id)
|
||||||
|
Logger.log("i", "Default machine actions added for machine definition [%s]", definition_id)
|
||||||
|
|
||||||
## Add a required action to a machine
|
## Add a required action to a machine
|
||||||
# Raises an exception when the action is not recognised.
|
# Raises an exception when the action is not recognised.
|
||||||
def addRequiredAction(self, definition_id, action_key):
|
def addRequiredAction(self, definition_id: str, action_key: str) -> None:
|
||||||
if action_key in self._machine_actions:
|
if action_key in self._machine_actions:
|
||||||
if definition_id in self._required_actions:
|
if definition_id in self._required_actions:
|
||||||
if self._machine_actions[action_key] not in self._required_actions[definition_id]:
|
if self._machine_actions[action_key] not in self._required_actions[definition_id]:
|
||||||
@ -70,7 +84,7 @@ class MachineActionManager(QObject):
|
|||||||
raise UnknownMachineActionError("Action %s, which is required for %s is not known." % (action_key, definition_id))
|
raise UnknownMachineActionError("Action %s, which is required for %s is not known." % (action_key, definition_id))
|
||||||
|
|
||||||
## Add a supported action to a machine.
|
## Add a supported action to a machine.
|
||||||
def addSupportedAction(self, definition_id, action_key):
|
def addSupportedAction(self, definition_id: str, action_key: str) -> None:
|
||||||
if action_key in self._machine_actions:
|
if action_key in self._machine_actions:
|
||||||
if definition_id in self._supported_actions:
|
if definition_id in self._supported_actions:
|
||||||
if self._machine_actions[action_key] not in self._supported_actions[definition_id]:
|
if self._machine_actions[action_key] not in self._supported_actions[definition_id]:
|
||||||
@ -81,13 +95,10 @@ class MachineActionManager(QObject):
|
|||||||
Logger.log("w", "Unable to add %s to %s, as the action is not recognised", action_key, definition_id)
|
Logger.log("w", "Unable to add %s to %s, as the action is not recognised", action_key, definition_id)
|
||||||
|
|
||||||
## Add an action to the first start list of a machine.
|
## Add an action to the first start list of a machine.
|
||||||
def addFirstStartAction(self, definition_id, action_key, index = None):
|
def addFirstStartAction(self, definition_id: str, action_key: str) -> None:
|
||||||
if action_key in self._machine_actions:
|
if action_key in self._machine_actions:
|
||||||
if definition_id in self._first_start_actions:
|
if definition_id in self._first_start_actions:
|
||||||
if index is not None:
|
self._first_start_actions[definition_id].append(self._machine_actions[action_key])
|
||||||
self._first_start_actions[definition_id].insert(index, self._machine_actions[action_key])
|
|
||||||
else:
|
|
||||||
self._first_start_actions[definition_id].append(self._machine_actions[action_key])
|
|
||||||
else:
|
else:
|
||||||
self._first_start_actions[definition_id] = [self._machine_actions[action_key]]
|
self._first_start_actions[definition_id] = [self._machine_actions[action_key]]
|
||||||
else:
|
else:
|
||||||
@ -95,7 +106,7 @@ class MachineActionManager(QObject):
|
|||||||
|
|
||||||
## Add a (unique) MachineAction
|
## Add a (unique) MachineAction
|
||||||
# if the Key of the action is not unique, an exception is raised.
|
# if the Key of the action is not unique, an exception is raised.
|
||||||
def addMachineAction(self, action):
|
def addMachineAction(self, action: "MachineAction") -> None:
|
||||||
if action.getKey() not in self._machine_actions:
|
if action.getKey() not in self._machine_actions:
|
||||||
self._machine_actions[action.getKey()] = action
|
self._machine_actions[action.getKey()] = action
|
||||||
else:
|
else:
|
||||||
@ -105,7 +116,7 @@ class MachineActionManager(QObject):
|
|||||||
# \param definition_id The ID of the definition you want the supported actions of
|
# \param definition_id The ID of the definition you want the supported actions of
|
||||||
# \returns set of supported actions.
|
# \returns set of supported actions.
|
||||||
@pyqtSlot(str, result = "QVariantList")
|
@pyqtSlot(str, result = "QVariantList")
|
||||||
def getSupportedActions(self, definition_id):
|
def getSupportedActions(self, definition_id: str) -> List["MachineAction"]:
|
||||||
if definition_id in self._supported_actions:
|
if definition_id in self._supported_actions:
|
||||||
return list(self._supported_actions[definition_id])
|
return list(self._supported_actions[definition_id])
|
||||||
else:
|
else:
|
||||||
@ -114,11 +125,11 @@ class MachineActionManager(QObject):
|
|||||||
## Get all actions required by given machine
|
## Get all actions required by given machine
|
||||||
# \param definition_id The ID of the definition you want the required actions of
|
# \param definition_id The ID of the definition you want the required actions of
|
||||||
# \returns set of required actions.
|
# \returns set of required actions.
|
||||||
def getRequiredActions(self, definition_id):
|
def getRequiredActions(self, definition_id: str) -> List["MachineAction"]:
|
||||||
if definition_id in self._required_actions:
|
if definition_id in self._required_actions:
|
||||||
return self._required_actions[definition_id]
|
return self._required_actions[definition_id]
|
||||||
else:
|
else:
|
||||||
return set()
|
return list()
|
||||||
|
|
||||||
## Get all actions that need to be performed upon first start of a given machine.
|
## Get all actions that need to be performed upon first start of a given machine.
|
||||||
# Note that contrary to required / supported actions a list is returned (as it could be required to run the same
|
# Note that contrary to required / supported actions a list is returned (as it could be required to run the same
|
||||||
@ -126,7 +137,7 @@ class MachineActionManager(QObject):
|
|||||||
# \param definition_id The ID of the definition that you want to get the "on added" actions for.
|
# \param definition_id The ID of the definition that you want to get the "on added" actions for.
|
||||||
# \returns List of actions.
|
# \returns List of actions.
|
||||||
@pyqtSlot(str, result="QVariantList")
|
@pyqtSlot(str, result="QVariantList")
|
||||||
def getFirstStartActions(self, definition_id):
|
def getFirstStartActions(self, definition_id: str) -> List["MachineAction"]:
|
||||||
if definition_id in self._first_start_actions:
|
if definition_id in self._first_start_actions:
|
||||||
return self._first_start_actions[definition_id]
|
return self._first_start_actions[definition_id]
|
||||||
else:
|
else:
|
||||||
@ -134,7 +145,7 @@ class MachineActionManager(QObject):
|
|||||||
|
|
||||||
## Remove Machine action from manager
|
## Remove Machine action from manager
|
||||||
# \param action to remove
|
# \param action to remove
|
||||||
def removeMachineAction(self, action):
|
def removeMachineAction(self, action: "MachineAction") -> None:
|
||||||
try:
|
try:
|
||||||
del self._machine_actions[action.getKey()]
|
del self._machine_actions[action.getKey()]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@ -143,7 +154,7 @@ class MachineActionManager(QObject):
|
|||||||
## Get MachineAction by key
|
## Get MachineAction by key
|
||||||
# \param key String of key to select
|
# \param key String of key to select
|
||||||
# \return Machine action if found, None otherwise
|
# \return Machine action if found, None otherwise
|
||||||
def getMachineAction(self, key):
|
def getMachineAction(self, key: str) -> Optional["MachineAction"]:
|
||||||
if key in self._machine_actions:
|
if key in self._machine_actions:
|
||||||
return self._machine_actions[key]
|
return self._machine_actions[key]
|
||||||
else:
|
else:
|
||||||
|
@ -50,7 +50,7 @@ class PrinterOutputModel(QObject):
|
|||||||
self._printer_configuration.extruderConfigurations = [extruder.extruderConfiguration for extruder in
|
self._printer_configuration.extruderConfigurations = [extruder.extruderConfiguration for extruder in
|
||||||
self._extruders]
|
self._extruders]
|
||||||
|
|
||||||
self._camera = None
|
self._camera = None # type: Optional[NetworkCamera]
|
||||||
|
|
||||||
@pyqtProperty(str, constant = True)
|
@pyqtProperty(str, constant = True)
|
||||||
def firmwareVersion(self) -> str:
|
def firmwareVersion(self) -> str:
|
||||||
|
@ -145,13 +145,11 @@ class CuraContainerStack(ContainerStack):
|
|||||||
def setDefinition(self, new_definition: DefinitionContainerInterface) -> None:
|
def setDefinition(self, new_definition: DefinitionContainerInterface) -> None:
|
||||||
self.replaceContainer(_ContainerIndexes.Definition, new_definition)
|
self.replaceContainer(_ContainerIndexes.Definition, new_definition)
|
||||||
|
|
||||||
## Get the definition container.
|
def getDefinition(self) -> "DefinitionContainer":
|
||||||
#
|
|
||||||
# \return The definition container. Should always be a valid container, but can be equal to the empty InstanceContainer.
|
|
||||||
@pyqtProperty(QObject, fset = setDefinition, notify = pyqtContainersChanged)
|
|
||||||
def definition(self) -> DefinitionContainer:
|
|
||||||
return cast(DefinitionContainer, self._containers[_ContainerIndexes.Definition])
|
return cast(DefinitionContainer, self._containers[_ContainerIndexes.Definition])
|
||||||
|
|
||||||
|
definition = pyqtProperty(QObject, fget = getDefinition, fset = setDefinition, notify = pyqtContainersChanged)
|
||||||
|
|
||||||
@override(ContainerStack)
|
@override(ContainerStack)
|
||||||
def getBottom(self) -> "DefinitionContainer":
|
def getBottom(self) -> "DefinitionContainer":
|
||||||
return self.definition
|
return self.definition
|
||||||
|
@ -20,7 +20,6 @@ from UM.Message import Message
|
|||||||
from UM.Settings.SettingFunction import SettingFunction
|
from UM.Settings.SettingFunction import SettingFunction
|
||||||
from UM.Signal import postponeSignals, CompressTechnique
|
from UM.Signal import postponeSignals, CompressTechnique
|
||||||
|
|
||||||
import cura.CuraApplication
|
|
||||||
from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
|
from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
|
||||||
from cura.PrinterOutputDevice import PrinterOutputDevice
|
from cura.PrinterOutputDevice import PrinterOutputDevice
|
||||||
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
|
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
|
||||||
@ -29,6 +28,9 @@ from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
|
|||||||
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
|
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
|
||||||
from cura.Settings.ExtruderManager import ExtruderManager
|
from cura.Settings.ExtruderManager import ExtruderManager
|
||||||
from cura.Settings.ExtruderStack import ExtruderStack
|
from cura.Settings.ExtruderStack import ExtruderStack
|
||||||
|
from cura.Settings.cura_empty_instance_containers import (empty_definition_changes_container, empty_variant_container,
|
||||||
|
empty_material_container, empty_quality_container,
|
||||||
|
empty_quality_changes_container)
|
||||||
|
|
||||||
from .CuraStackBuilder import CuraStackBuilder
|
from .CuraStackBuilder import CuraStackBuilder
|
||||||
|
|
||||||
@ -36,6 +38,7 @@ from UM.i18n import i18nCatalog
|
|||||||
catalog = i18nCatalog("cura")
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
from cura.Settings.CuraContainerStack import CuraContainerStack
|
from cura.Settings.CuraContainerStack import CuraContainerStack
|
||||||
from cura.Settings.GlobalStack import GlobalStack
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
from cura.Machines.MaterialManager import MaterialManager
|
from cura.Machines.MaterialManager import MaterialManager
|
||||||
@ -47,7 +50,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
class MachineManager(QObject):
|
class MachineManager(QObject):
|
||||||
def __init__(self, parent: QObject = None) -> None:
|
def __init__(self, application: "CuraApplication", parent: Optional["QObject"] = None) -> None:
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
self._active_container_stack = None # type: Optional[ExtruderStack]
|
self._active_container_stack = None # type: Optional[ExtruderStack]
|
||||||
@ -66,9 +69,10 @@ class MachineManager(QObject):
|
|||||||
self._instance_container_timer.setSingleShot(True)
|
self._instance_container_timer.setSingleShot(True)
|
||||||
self._instance_container_timer.timeout.connect(self.__emitChangedSignals)
|
self._instance_container_timer.timeout.connect(self.__emitChangedSignals)
|
||||||
|
|
||||||
self._application = cura.CuraApplication.CuraApplication.getInstance() #type: cura.CuraApplication.CuraApplication
|
self._application = application
|
||||||
|
self._container_registry = self._application.getContainerRegistry()
|
||||||
self._application.globalContainerStackChanged.connect(self._onGlobalContainerChanged)
|
self._application.globalContainerStackChanged.connect(self._onGlobalContainerChanged)
|
||||||
self._application.getContainerRegistry().containerLoadComplete.connect(self._onContainersChanged)
|
self._container_registry.containerLoadComplete.connect(self._onContainersChanged)
|
||||||
|
|
||||||
## When the global container is changed, active material probably needs to be updated.
|
## When the global container is changed, active material probably needs to be updated.
|
||||||
self.globalContainerChanged.connect(self.activeMaterialChanged)
|
self.globalContainerChanged.connect(self.activeMaterialChanged)
|
||||||
@ -80,13 +84,6 @@ class MachineManager(QObject):
|
|||||||
|
|
||||||
self._stacks_have_errors = None # type: Optional[bool]
|
self._stacks_have_errors = None # type: Optional[bool]
|
||||||
|
|
||||||
self._empty_container = CuraContainerRegistry.getInstance().getEmptyInstanceContainer() #type: InstanceContainer
|
|
||||||
self._empty_definition_changes_container = CuraContainerRegistry.getInstance().findContainers(id = "empty_definition_changes")[0] #type: InstanceContainer
|
|
||||||
self._empty_variant_container = CuraContainerRegistry.getInstance().findContainers(id = "empty_variant")[0] #type: InstanceContainer
|
|
||||||
self._empty_material_container = CuraContainerRegistry.getInstance().findContainers(id = "empty_material")[0] #type: InstanceContainer
|
|
||||||
self._empty_quality_container = CuraContainerRegistry.getInstance().findContainers(id = "empty_quality")[0] #type: InstanceContainer
|
|
||||||
self._empty_quality_changes_container = CuraContainerRegistry.getInstance().findContainers(id = "empty_quality_changes")[0] #type: InstanceContainer
|
|
||||||
|
|
||||||
self._onGlobalContainerChanged()
|
self._onGlobalContainerChanged()
|
||||||
|
|
||||||
ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged)
|
ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged)
|
||||||
@ -192,21 +189,21 @@ class MachineManager(QObject):
|
|||||||
for extruder in self._global_container_stack.extruders.values():
|
for extruder in self._global_container_stack.extruders.values():
|
||||||
extruder_configuration = ExtruderConfigurationModel()
|
extruder_configuration = ExtruderConfigurationModel()
|
||||||
# For compare just the GUID is needed at this moment
|
# For compare just the GUID is needed at this moment
|
||||||
mat_type = extruder.material.getMetaDataEntry("material") if extruder.material != self._empty_material_container else None
|
mat_type = extruder.material.getMetaDataEntry("material") if extruder.material != empty_material_container else None
|
||||||
mat_guid = extruder.material.getMetaDataEntry("GUID") if extruder.material != self._empty_material_container else None
|
mat_guid = extruder.material.getMetaDataEntry("GUID") if extruder.material != empty_material_container else None
|
||||||
mat_color = extruder.material.getMetaDataEntry("color_name") if extruder.material != self._empty_material_container else None
|
mat_color = extruder.material.getMetaDataEntry("color_name") if extruder.material != empty_material_container else None
|
||||||
mat_brand = extruder.material.getMetaDataEntry("brand") if extruder.material != self._empty_material_container else None
|
mat_brand = extruder.material.getMetaDataEntry("brand") if extruder.material != empty_material_container else None
|
||||||
mat_name = extruder.material.getMetaDataEntry("name") if extruder.material != self._empty_material_container else None
|
mat_name = extruder.material.getMetaDataEntry("name") if extruder.material != empty_material_container else None
|
||||||
material_model = MaterialOutputModel(mat_guid, mat_type, mat_color, mat_brand, mat_name)
|
material_model = MaterialOutputModel(mat_guid, mat_type, mat_color, mat_brand, mat_name)
|
||||||
|
|
||||||
extruder_configuration.position = int(extruder.getMetaDataEntry("position"))
|
extruder_configuration.position = int(extruder.getMetaDataEntry("position"))
|
||||||
extruder_configuration.material = material_model
|
extruder_configuration.material = material_model
|
||||||
extruder_configuration.hotendID = extruder.variant.getName() if extruder.variant != self._empty_variant_container else None
|
extruder_configuration.hotendID = extruder.variant.getName() if extruder.variant != empty_variant_container else None
|
||||||
self._current_printer_configuration.extruderConfigurations.append(extruder_configuration)
|
self._current_printer_configuration.extruderConfigurations.append(extruder_configuration)
|
||||||
|
|
||||||
# an empty build plate configuration from the network printer is presented as an empty string, so use "" for an
|
# an empty build plate configuration from the network printer is presented as an empty string, so use "" for an
|
||||||
# empty build plate.
|
# empty build plate.
|
||||||
self._current_printer_configuration.buildplateConfiguration = self._global_container_stack.getProperty("machine_buildplate_type", "value") if self._global_container_stack.variant != self._empty_variant_container else ""
|
self._current_printer_configuration.buildplateConfiguration = self._global_container_stack.getProperty("machine_buildplate_type", "value") if self._global_container_stack.variant != empty_variant_container else ""
|
||||||
self.currentConfigurationChanged.emit()
|
self.currentConfigurationChanged.emit()
|
||||||
|
|
||||||
@pyqtSlot(QObject, result = bool)
|
@pyqtSlot(QObject, result = bool)
|
||||||
@ -260,14 +257,14 @@ class MachineManager(QObject):
|
|||||||
|
|
||||||
# Global stack can have only a variant if it is a buildplate
|
# Global stack can have only a variant if it is a buildplate
|
||||||
global_variant = self._global_container_stack.variant
|
global_variant = self._global_container_stack.variant
|
||||||
if global_variant != self._empty_variant_container:
|
if global_variant != empty_variant_container:
|
||||||
if global_variant.getMetaDataEntry("hardware_type") != "buildplate":
|
if global_variant.getMetaDataEntry("hardware_type") != "buildplate":
|
||||||
self._global_container_stack.setVariant(self._empty_variant_container)
|
self._global_container_stack.setVariant(empty_variant_container)
|
||||||
|
|
||||||
# set the global material to empty as we now use the extruder stack at all times - CURA-4482
|
# set the global material to empty as we now use the extruder stack at all times - CURA-4482
|
||||||
global_material = self._global_container_stack.material
|
global_material = self._global_container_stack.material
|
||||||
if global_material != self._empty_material_container:
|
if global_material != empty_material_container:
|
||||||
self._global_container_stack.setMaterial(self._empty_material_container)
|
self._global_container_stack.setMaterial(empty_material_container)
|
||||||
|
|
||||||
# Listen for changes on all extruder stacks
|
# Listen for changes on all extruder stacks
|
||||||
for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks():
|
for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks():
|
||||||
@ -369,6 +366,10 @@ class MachineManager(QObject):
|
|||||||
return
|
return
|
||||||
|
|
||||||
global_stack = containers[0]
|
global_stack = containers[0]
|
||||||
|
|
||||||
|
# Make sure that the default machine actions for this machine have been added
|
||||||
|
self._application.getMachineActionManager().addDefaultMachineActions(global_stack)
|
||||||
|
|
||||||
ExtruderManager.getInstance()._fixSingleExtrusionMachineExtruderDefinition(global_stack)
|
ExtruderManager.getInstance()._fixSingleExtrusionMachineExtruderDefinition(global_stack)
|
||||||
if not global_stack.isValid():
|
if not global_stack.isValid():
|
||||||
# Mark global stack as invalid
|
# Mark global stack as invalid
|
||||||
@ -595,7 +596,7 @@ class MachineManager(QObject):
|
|||||||
def globalVariantName(self) -> str:
|
def globalVariantName(self) -> str:
|
||||||
if self._global_container_stack:
|
if self._global_container_stack:
|
||||||
variant = self._global_container_stack.variant
|
variant = self._global_container_stack.variant
|
||||||
if variant and not isinstance(variant, type(self._empty_variant_container)):
|
if variant and not isinstance(variant, type(empty_variant_container)):
|
||||||
return variant.getName()
|
return variant.getName()
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
@ -783,7 +784,7 @@ class MachineManager(QObject):
|
|||||||
if not stack.isEnabled:
|
if not stack.isEnabled:
|
||||||
continue
|
continue
|
||||||
material_container = stack.material
|
material_container = stack.material
|
||||||
if material_container == self._empty_material_container:
|
if material_container == empty_material_container:
|
||||||
continue
|
continue
|
||||||
if material_container.getMetaDataEntry("buildplate_compatible"):
|
if material_container.getMetaDataEntry("buildplate_compatible"):
|
||||||
buildplate_compatible = buildplate_compatible and material_container.getMetaDataEntry("buildplate_compatible")[self.activeVariantBuildplateName]
|
buildplate_compatible = buildplate_compatible and material_container.getMetaDataEntry("buildplate_compatible")[self.activeVariantBuildplateName]
|
||||||
@ -805,7 +806,7 @@ class MachineManager(QObject):
|
|||||||
extruder_stacks = self._global_container_stack.extruders.values()
|
extruder_stacks = self._global_container_stack.extruders.values()
|
||||||
for stack in extruder_stacks:
|
for stack in extruder_stacks:
|
||||||
material_container = stack.material
|
material_container = stack.material
|
||||||
if material_container == self._empty_material_container:
|
if material_container == empty_material_container:
|
||||||
continue
|
continue
|
||||||
buildplate_compatible = material_container.getMetaDataEntry("buildplate_compatible")[self.activeVariantBuildplateName] if material_container.getMetaDataEntry("buildplate_compatible") else True
|
buildplate_compatible = material_container.getMetaDataEntry("buildplate_compatible")[self.activeVariantBuildplateName] if material_container.getMetaDataEntry("buildplate_compatible") else True
|
||||||
buildplate_usable = material_container.getMetaDataEntry("buildplate_recommended")[self.activeVariantBuildplateName] if material_container.getMetaDataEntry("buildplate_recommended") else True
|
buildplate_usable = material_container.getMetaDataEntry("buildplate_recommended")[self.activeVariantBuildplateName] if material_container.getMetaDataEntry("buildplate_recommended") else True
|
||||||
@ -875,7 +876,7 @@ class MachineManager(QObject):
|
|||||||
extruder_manager = self._application.getExtruderManager()
|
extruder_manager = self._application.getExtruderManager()
|
||||||
|
|
||||||
definition_changes_container = self._global_container_stack.definitionChanges
|
definition_changes_container = self._global_container_stack.definitionChanges
|
||||||
if not self._global_container_stack or definition_changes_container == self._empty_definition_changes_container:
|
if not self._global_container_stack or definition_changes_container == empty_definition_changes_container:
|
||||||
return
|
return
|
||||||
|
|
||||||
previous_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value")
|
previous_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value")
|
||||||
@ -1074,7 +1075,7 @@ class MachineManager(QObject):
|
|||||||
for stack in active_stacks:
|
for stack in active_stacks:
|
||||||
variant_container = stack.variant
|
variant_container = stack.variant
|
||||||
position = stack.getMetaDataEntry("position")
|
position = stack.getMetaDataEntry("position")
|
||||||
if variant_container and variant_container != self._empty_variant_container:
|
if variant_container and variant_container != empty_variant_container:
|
||||||
result[position] = variant_container.getName()
|
result[position] = variant_container.getName()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@ -1088,11 +1089,11 @@ class MachineManager(QObject):
|
|||||||
return
|
return
|
||||||
self._current_quality_group = None
|
self._current_quality_group = None
|
||||||
self._current_quality_changes_group = None
|
self._current_quality_changes_group = None
|
||||||
self._global_container_stack.quality = self._empty_quality_container
|
self._global_container_stack.quality = empty_quality_container
|
||||||
self._global_container_stack.qualityChanges = self._empty_quality_changes_container
|
self._global_container_stack.qualityChanges = empty_quality_changes_container
|
||||||
for extruder in self._global_container_stack.extruders.values():
|
for extruder in self._global_container_stack.extruders.values():
|
||||||
extruder.quality = self._empty_quality_container
|
extruder.quality = empty_quality_container
|
||||||
extruder.qualityChanges = self._empty_quality_changes_container
|
extruder.qualityChanges = empty_quality_changes_container
|
||||||
|
|
||||||
self.activeQualityGroupChanged.emit()
|
self.activeQualityGroupChanged.emit()
|
||||||
self.activeQualityChangesGroupChanged.emit()
|
self.activeQualityChangesGroupChanged.emit()
|
||||||
@ -1117,13 +1118,13 @@ class MachineManager(QObject):
|
|||||||
# Set quality and quality_changes for the GlobalStack
|
# Set quality and quality_changes for the GlobalStack
|
||||||
self._global_container_stack.quality = quality_group.node_for_global.getContainer()
|
self._global_container_stack.quality = quality_group.node_for_global.getContainer()
|
||||||
if empty_quality_changes:
|
if empty_quality_changes:
|
||||||
self._global_container_stack.qualityChanges = self._empty_quality_changes_container
|
self._global_container_stack.qualityChanges = empty_quality_changes_container
|
||||||
|
|
||||||
# Set quality and quality_changes for each ExtruderStack
|
# Set quality and quality_changes for each ExtruderStack
|
||||||
for position, node in quality_group.nodes_for_extruders.items():
|
for position, node in quality_group.nodes_for_extruders.items():
|
||||||
self._global_container_stack.extruders[str(position)].quality = node.getContainer()
|
self._global_container_stack.extruders[str(position)].quality = node.getContainer()
|
||||||
if empty_quality_changes:
|
if empty_quality_changes:
|
||||||
self._global_container_stack.extruders[str(position)].qualityChanges = self._empty_quality_changes_container
|
self._global_container_stack.extruders[str(position)].qualityChanges = empty_quality_changes_container
|
||||||
|
|
||||||
self.activeQualityGroupChanged.emit()
|
self.activeQualityGroupChanged.emit()
|
||||||
self.activeQualityChangesGroupChanged.emit()
|
self.activeQualityChangesGroupChanged.emit()
|
||||||
@ -1149,8 +1150,8 @@ class MachineManager(QObject):
|
|||||||
if quality_group is None:
|
if quality_group is None:
|
||||||
self._fixQualityChangesGroupToNotSupported(quality_changes_group)
|
self._fixQualityChangesGroupToNotSupported(quality_changes_group)
|
||||||
|
|
||||||
quality_changes_container = self._empty_quality_changes_container
|
quality_changes_container = empty_quality_changes_container
|
||||||
quality_container = self._empty_quality_container # type: Optional[InstanceContainer]
|
quality_container = empty_quality_container # type: Optional[InstanceContainer]
|
||||||
if quality_changes_group.node_for_global and quality_changes_group.node_for_global.getContainer():
|
if quality_changes_group.node_for_global and quality_changes_group.node_for_global.getContainer():
|
||||||
quality_changes_container = cast(InstanceContainer, quality_changes_group.node_for_global.getContainer())
|
quality_changes_container = cast(InstanceContainer, quality_changes_group.node_for_global.getContainer())
|
||||||
if quality_group is not None and quality_group.node_for_global and quality_group.node_for_global.getContainer():
|
if quality_group is not None and quality_group.node_for_global and quality_group.node_for_global.getContainer():
|
||||||
@ -1165,8 +1166,8 @@ class MachineManager(QObject):
|
|||||||
if quality_group is not None:
|
if quality_group is not None:
|
||||||
quality_node = quality_group.nodes_for_extruders.get(position)
|
quality_node = quality_group.nodes_for_extruders.get(position)
|
||||||
|
|
||||||
quality_changes_container = self._empty_quality_changes_container
|
quality_changes_container = empty_quality_changes_container
|
||||||
quality_container = self._empty_quality_container
|
quality_container = empty_quality_container
|
||||||
if quality_changes_node and quality_changes_node.getContainer():
|
if quality_changes_node and quality_changes_node.getContainer():
|
||||||
quality_changes_container = cast(InstanceContainer, quality_changes_node.getContainer())
|
quality_changes_container = cast(InstanceContainer, quality_changes_node.getContainer())
|
||||||
if quality_node and quality_node.getContainer():
|
if quality_node and quality_node.getContainer():
|
||||||
@ -1200,7 +1201,7 @@ class MachineManager(QObject):
|
|||||||
self._global_container_stack.extruders[position].material = container_node.getContainer()
|
self._global_container_stack.extruders[position].material = container_node.getContainer()
|
||||||
root_material_id = container_node.getMetaDataEntry("base_file", None)
|
root_material_id = container_node.getMetaDataEntry("base_file", None)
|
||||||
else:
|
else:
|
||||||
self._global_container_stack.extruders[position].material = self._empty_material_container
|
self._global_container_stack.extruders[position].material = empty_material_container
|
||||||
root_material_id = None
|
root_material_id = None
|
||||||
# The _current_root_material_id is used in the MaterialMenu to see which material is selected
|
# The _current_root_material_id is used in the MaterialMenu to see which material is selected
|
||||||
if root_material_id != self._current_root_material_id[position]:
|
if root_material_id != self._current_root_material_id[position]:
|
||||||
@ -1275,7 +1276,7 @@ class MachineManager(QObject):
|
|||||||
|
|
||||||
current_material_base_name = extruder.material.getMetaDataEntry("base_file")
|
current_material_base_name = extruder.material.getMetaDataEntry("base_file")
|
||||||
current_nozzle_name = None
|
current_nozzle_name = None
|
||||||
if extruder.variant.getId() != self._empty_variant_container.getId():
|
if extruder.variant.getId() != empty_variant_container.getId():
|
||||||
current_nozzle_name = extruder.variant.getMetaDataEntry("name")
|
current_nozzle_name = extruder.variant.getMetaDataEntry("name")
|
||||||
|
|
||||||
from UM.Settings.Interfaces import PropertyEvaluationContext
|
from UM.Settings.Interfaces import PropertyEvaluationContext
|
||||||
@ -1350,12 +1351,12 @@ class MachineManager(QObject):
|
|||||||
if variant_container_node:
|
if variant_container_node:
|
||||||
self._setVariantNode(position, variant_container_node)
|
self._setVariantNode(position, variant_container_node)
|
||||||
else:
|
else:
|
||||||
self._global_container_stack.extruders[position].variant = self._empty_variant_container
|
self._global_container_stack.extruders[position].variant = empty_variant_container
|
||||||
|
|
||||||
if material_container_node:
|
if material_container_node:
|
||||||
self._setMaterial(position, material_container_node)
|
self._setMaterial(position, material_container_node)
|
||||||
else:
|
else:
|
||||||
self._global_container_stack.extruders[position].material = self._empty_material_container
|
self._global_container_stack.extruders[position].material = empty_material_container
|
||||||
self.updateMaterialWithVariant(position)
|
self.updateMaterialWithVariant(position)
|
||||||
|
|
||||||
if configuration.buildplateConfiguration is not None:
|
if configuration.buildplateConfiguration is not None:
|
||||||
@ -1363,9 +1364,9 @@ class MachineManager(QObject):
|
|||||||
if global_variant_container_node:
|
if global_variant_container_node:
|
||||||
self._setGlobalVariant(global_variant_container_node)
|
self._setGlobalVariant(global_variant_container_node)
|
||||||
else:
|
else:
|
||||||
self._global_container_stack.variant = self._empty_variant_container
|
self._global_container_stack.variant = empty_variant_container
|
||||||
else:
|
else:
|
||||||
self._global_container_stack.variant = self._empty_variant_container
|
self._global_container_stack.variant = empty_variant_container
|
||||||
self._updateQualityWithMaterial()
|
self._updateQualityWithMaterial()
|
||||||
|
|
||||||
# See if we need to show the Discard or Keep changes screen
|
# See if we need to show the Discard or Keep changes screen
|
||||||
@ -1483,7 +1484,7 @@ class MachineManager(QObject):
|
|||||||
# This is not changing the quality for the active machine !!!!!!!!
|
# This is not changing the quality for the active machine !!!!!!!!
|
||||||
global_stack.quality = quality_group.node_for_global.getContainer()
|
global_stack.quality = quality_group.node_for_global.getContainer()
|
||||||
for extruder_nr, extruder_stack in global_stack.extruders.items():
|
for extruder_nr, extruder_stack in global_stack.extruders.items():
|
||||||
quality_container = self._empty_quality_container
|
quality_container = empty_quality_container
|
||||||
if extruder_nr in quality_group.nodes_for_extruders:
|
if extruder_nr in quality_group.nodes_for_extruders:
|
||||||
container = quality_group.nodes_for_extruders[extruder_nr].getContainer()
|
container = quality_group.nodes_for_extruders[extruder_nr].getContainer()
|
||||||
quality_container = container if container is not None else quality_container
|
quality_container = container if container is not None else quality_container
|
||||||
@ -1527,7 +1528,7 @@ class MachineManager(QObject):
|
|||||||
|
|
||||||
@pyqtProperty(str, notify = activeQualityGroupChanged)
|
@pyqtProperty(str, notify = activeQualityGroupChanged)
|
||||||
def activeQualityOrQualityChangesName(self) -> str:
|
def activeQualityOrQualityChangesName(self) -> str:
|
||||||
name = self._empty_quality_container.getName()
|
name = empty_quality_container.getName()
|
||||||
if self._current_quality_changes_group:
|
if self._current_quality_changes_group:
|
||||||
name = self._current_quality_changes_group.name
|
name = self._current_quality_changes_group.name
|
||||||
elif self._current_quality_group:
|
elif self._current_quality_group:
|
||||||
|
@ -5,6 +5,19 @@ import pytest
|
|||||||
|
|
||||||
from cura.MachineAction import MachineAction
|
from cura.MachineAction import MachineAction
|
||||||
from cura.MachineActionManager import NotUniqueMachineActionError, UnknownMachineActionError
|
from cura.MachineActionManager import NotUniqueMachineActionError, UnknownMachineActionError
|
||||||
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def global_stack():
|
||||||
|
gs = GlobalStack("test_global_stack")
|
||||||
|
gs._metadata = {
|
||||||
|
"supported_actions": ["supported_action_1", "supported_action_2"],
|
||||||
|
"required_actions": ["required_action_1", "required_action_2"],
|
||||||
|
"first_start_actions": ["first_start_actions_1", "first_start_actions_2"]
|
||||||
|
}
|
||||||
|
return gs
|
||||||
|
|
||||||
|
|
||||||
class Machine:
|
class Machine:
|
||||||
def __init__(self, key = ""):
|
def __init__(self, key = ""):
|
||||||
@ -13,6 +26,32 @@ class Machine:
|
|||||||
def getKey(self):
|
def getKey(self):
|
||||||
return self._key
|
return self._key
|
||||||
|
|
||||||
|
|
||||||
|
def test_addDefaultMachineActions(machine_action_manager, global_stack):
|
||||||
|
# The actions need to be registered first as "available actions" in the manager,
|
||||||
|
# same as the "machine_action" type does when registering a plugin.
|
||||||
|
all_actions = []
|
||||||
|
for action_key_list in global_stack._metadata.values():
|
||||||
|
for key in action_key_list:
|
||||||
|
all_actions.append(MachineAction(key = key))
|
||||||
|
for action in all_actions:
|
||||||
|
machine_action_manager.addMachineAction(action)
|
||||||
|
|
||||||
|
# Only the actions in the definition that were registered first will be added to the machine.
|
||||||
|
# For the sake of this test, all the actions were previouly added.
|
||||||
|
machine_action_manager.addDefaultMachineActions(global_stack)
|
||||||
|
definition_id = global_stack.getDefinition().getId()
|
||||||
|
|
||||||
|
support_action_keys = [a.getKey() for a in machine_action_manager.getSupportedActions(definition_id)]
|
||||||
|
assert support_action_keys == global_stack.getMetaDataEntry("supported_actions")
|
||||||
|
|
||||||
|
required_action_keys = [a.getKey() for a in machine_action_manager.getRequiredActions(definition_id)]
|
||||||
|
assert required_action_keys == global_stack.getMetaDataEntry("required_actions")
|
||||||
|
|
||||||
|
first_start_action_keys = [a.getKey() for a in machine_action_manager.getFirstStartActions(definition_id)]
|
||||||
|
assert first_start_action_keys == global_stack.getMetaDataEntry("first_start_actions")
|
||||||
|
|
||||||
|
|
||||||
def test_addMachineAction(machine_action_manager):
|
def test_addMachineAction(machine_action_manager):
|
||||||
|
|
||||||
test_action = MachineAction(key = "test_action")
|
test_action = MachineAction(key = "test_action")
|
||||||
@ -44,7 +83,7 @@ def test_addMachineAction(machine_action_manager):
|
|||||||
assert machine_action_manager.getSupportedActions(test_machine) == [test_action, test_action_2]
|
assert machine_action_manager.getSupportedActions(test_machine) == [test_action, test_action_2]
|
||||||
|
|
||||||
# Check that the machine has no required actions yet.
|
# Check that the machine has no required actions yet.
|
||||||
assert machine_action_manager.getRequiredActions(test_machine) == set()
|
assert machine_action_manager.getRequiredActions(test_machine) == list()
|
||||||
|
|
||||||
## Ensure that only known actions can be added.
|
## Ensure that only known actions can be added.
|
||||||
with pytest.raises(UnknownMachineActionError):
|
with pytest.raises(UnknownMachineActionError):
|
||||||
@ -65,12 +104,3 @@ def test_addMachineAction(machine_action_manager):
|
|||||||
machine_action_manager.addFirstStartAction(test_machine, "test_action")
|
machine_action_manager.addFirstStartAction(test_machine, "test_action")
|
||||||
machine_action_manager.addFirstStartAction(test_machine, "test_action")
|
machine_action_manager.addFirstStartAction(test_machine, "test_action")
|
||||||
assert machine_action_manager.getFirstStartActions(test_machine) == [test_action, test_action]
|
assert machine_action_manager.getFirstStartActions(test_machine) == [test_action, test_action]
|
||||||
|
|
||||||
# Check if inserting an action works
|
|
||||||
machine_action_manager.addFirstStartAction(test_machine, "test_action_2", index = 1)
|
|
||||||
assert machine_action_manager.getFirstStartActions(test_machine) == [test_action, test_action_2, test_action]
|
|
||||||
|
|
||||||
# Check that adding a unknown action doesn't change anything.
|
|
||||||
machine_action_manager.addFirstStartAction(test_machine, "key_that_doesnt_exist", index = 1)
|
|
||||||
assert machine_action_manager.getFirstStartActions(test_machine) == [test_action, test_action_2, test_action]
|
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@ from cura.CuraApplication import CuraApplication
|
|||||||
from cura.MachineActionManager import MachineActionManager
|
from cura.MachineActionManager import MachineActionManager
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Create a CuraApplication object that will be shared among all tests. It needs to be initialized.
|
# Create a CuraApplication object that will be shared among all tests. It needs to be initialized.
|
||||||
# Since we need to use it more that once, we create the application the first time and use its instance afterwards.
|
# Since we need to use it more that once, we create the application the first time and use its instance afterwards.
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user