Allow getContainer() to return None

And in the rest of the locations we must then check if it's None and handle that gracefully.
Here we assume that the getContainer message shows a message to the user if necessary. For now we'll just log it.

Contributes to issue CURA-5045.
This commit is contained in:
Ghostkeeper 2018-03-26 15:48:03 +02:00
parent 2a39d81a3c
commit 6d3fed8f52
No known key found for this signature in database
GPG key ID: 5252B696FB5E7C7A
9 changed files with 52 additions and 23 deletions

View file

@ -30,9 +30,10 @@ class ContainerNode:
def getChildNode(self, child_key: str) -> Optional["ContainerNode"]: def getChildNode(self, child_key: str) -> Optional["ContainerNode"]:
return self.children_map.get(child_key) return self.children_map.get(child_key)
def getContainer(self) -> "InstanceContainer": def getContainer(self) -> Optional["InstanceContainer"]:
if self.metadata is None: if self.metadata is None:
raise RuntimeError("Cannot get container for a ContainerNode without metadata") Logger.log("e", "Cannot get container for a ContainerNode without metadata.")
return None
if self.container is None: if self.container is None:
container_id = self.metadata["id"] container_id = self.metadata["id"]
@ -40,7 +41,8 @@ class ContainerNode:
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
container_list = ContainerRegistry.getInstance().findInstanceContainers(id = container_id) container_list = ContainerRegistry.getInstance().findInstanceContainers(id = container_id)
if not container_list: if not container_list:
raise RuntimeError("Failed to lazy-load container [%s], cannot find it" % container_id) Logger.log("e", "Failed to lazy-load container [{container_id}]. Cannot find it.".format(container_id = container_id))
return None
self.container = container_list[0] self.container = container_list[0]
return self.container return self.container

View file

@ -423,6 +423,7 @@ class MaterialManager(QObject):
return return
material_group = self.getMaterialGroup(root_material_id) material_group = self.getMaterialGroup(root_material_id)
if material_group:
material_group.root_material_node.getContainer().setName(name) material_group.root_material_node.getContainer().setName(name)
# #
@ -447,6 +448,8 @@ class MaterialManager(QObject):
return None return None
base_container = material_group.root_material_node.getContainer() base_container = material_group.root_material_node.getContainer()
if not base_container:
return None
# Ensure all settings are saved. # Ensure all settings are saved.
self._application.saveSettings() self._application.saveSettings()
@ -466,6 +469,8 @@ class MaterialManager(QObject):
# Clone all of them. # Clone all of them.
for node in material_group.derived_material_node_list: for node in material_group.derived_material_node_list:
container_to_copy = node.getContainer() container_to_copy = node.getContainer()
if not container_to_copy:
continue
# Create unique IDs for every clone. # Create unique IDs for every clone.
new_id = new_base_id new_id = new_base_id
if container_to_copy.getMetaDataEntry("definition") != "fdmprinter": if container_to_copy.getMetaDataEntry("definition") != "fdmprinter":

View file

@ -90,7 +90,7 @@ class QualitySettingsModel(ListModel):
quality_node = quality_group.nodes_for_extruders.get(str(self._selected_position)) quality_node = quality_group.nodes_for_extruders.get(str(self._selected_position))
settings_keys = quality_group.getAllKeys() settings_keys = quality_group.getAllKeys()
quality_containers = [] quality_containers = []
if quality_node is not None: if quality_node is not None and quality_node.getContainer() is not None:
quality_containers.append(quality_node.getContainer()) quality_containers.append(quality_node.getContainer())
# Here, if the user has selected a quality changes, then "quality_changes_group" will not be None, and we fetch # Here, if the user has selected a quality changes, then "quality_changes_group" will not be None, and we fetch
@ -100,7 +100,7 @@ class QualitySettingsModel(ListModel):
quality_changes_node = quality_changes_group.node_for_global quality_changes_node = quality_changes_group.node_for_global
else: else:
quality_changes_node = quality_changes_group.nodes_for_extruders.get(str(self._selected_position)) quality_changes_node = quality_changes_group.nodes_for_extruders.get(str(self._selected_position))
if quality_changes_node is not None: # it can be None if number of extruders are changed during runtime if quality_changes_node is not None and quality_changes_node.getContainer() is not None: # it can be None if number of extruders are changed during runtime
try: try:
quality_containers.insert(0, quality_changes_node.getContainer()) quality_containers.insert(0, quality_changes_node.getContainer())
except RuntimeError: except RuntimeError:

View file

@ -393,6 +393,8 @@ class QualityManager(QObject):
new_name = self._container_registry.uniqueName(quality_changes_name) new_name = self._container_registry.uniqueName(quality_changes_name)
for node in quality_changes_group.getAllNodes(): for node in quality_changes_group.getAllNodes():
container = node.getContainer() container = node.getContainer()
if not container:
continue
new_id = self._container_registry.uniqueName(container.getId()) new_id = self._container_registry.uniqueName(container.getId())
self._container_registry.addContainer(container.duplicate(new_id, new_name)) self._container_registry.addContainer(container.duplicate(new_id, new_name))

View file

@ -98,6 +98,7 @@ class ContainerManager(QObject):
entry_value = root entry_value = root
container = material_group.root_material_node.getContainer() container = material_group.root_material_node.getContainer()
if container is not None:
container.setMetaDataEntry(entry_name, entry_value) container.setMetaDataEntry(entry_name, entry_value)
if sub_item_changed: #If it was only a sub-item that has changed then the setMetaDataEntry won't correctly notice that something changed, and we must manually signal that the metadata changed. if sub_item_changed: #If it was only a sub-item that has changed then the setMetaDataEntry won't correctly notice that something changed, and we must manually signal that the metadata changed.
container.metaDataChanged.emit(container) container.metaDataChanged.emit(container)
@ -377,6 +378,7 @@ class ContainerManager(QObject):
# NOTE: We only need to set the root material container because XmlMaterialProfile.setMetaDataEntry() will # NOTE: We only need to set the root material container because XmlMaterialProfile.setMetaDataEntry() will
# take care of the derived containers too # take care of the derived containers too
container = material_group.root_material_node.getContainer() container = material_group.root_material_node.getContainer()
if container is not None:
container.setMetaDataEntry("GUID", new_guid) container.setMetaDataEntry("GUID", new_guid)
## Get the singleton instance for this class. ## Get the singleton instance for this class.
@ -466,5 +468,5 @@ class ContainerManager(QObject):
if not path: if not path:
return return
container_list = [n.getContainer() for n in quality_changes_group.getAllNodes()] container_list = [n.getContainer() for n in quality_changes_group.getAllNodes() if n.getContainer() is not None]
self._container_registry.exportQualityProfile(container_list, path, file_type) self._container_registry.exportQualityProfile(container_list, path, file_type)

View file

@ -44,6 +44,8 @@ class CuraStackBuilder:
global_variant_node = variant_manager.getDefaultVariantNode(machine_definition, VariantType.BUILD_PLATE) global_variant_node = variant_manager.getDefaultVariantNode(machine_definition, VariantType.BUILD_PLATE)
if global_variant_node: if global_variant_node:
global_variant_container = global_variant_node.getContainer() global_variant_container = global_variant_node.getContainer()
if not global_variant_container:
global_variant_container = application.empty_variant_container
# get variant container for extruders # get variant container for extruders
extruder_variant_container = application.empty_variant_container extruder_variant_container = application.empty_variant_container
@ -51,6 +53,8 @@ class CuraStackBuilder:
extruder_variant_name = None extruder_variant_name = None
if extruder_variant_node: if extruder_variant_node:
extruder_variant_container = extruder_variant_node.getContainer() extruder_variant_container = extruder_variant_node.getContainer()
if not extruder_variant_container:
extruder_variant_container = application.empty_variant_container
extruder_variant_name = extruder_variant_container.getName() extruder_variant_name = extruder_variant_container.getName()
generated_name = registry.createUniqueName("machine", "", name, machine_definition.getName()) generated_name = registry.createUniqueName("machine", "", name, machine_definition.getName())
@ -72,7 +76,7 @@ class CuraStackBuilder:
# get material container for extruders # get material container for extruders
material_container = application.empty_material_container material_container = application.empty_material_container
material_node = material_manager.getDefaultMaterial(new_global_stack, extruder_variant_name) material_node = material_manager.getDefaultMaterial(new_global_stack, extruder_variant_name)
if material_node: if material_node and material_node.getContainer():
material_container = material_node.getContainer() material_container = material_node.getContainer()
# Create ExtruderStacks # Create ExtruderStacks
@ -107,8 +111,10 @@ class CuraStackBuilder:
quality_group = quality_group_dict.get(preferred_quality_type) quality_group = quality_group_dict.get(preferred_quality_type)
new_global_stack.quality = quality_group.node_for_global.getContainer() new_global_stack.quality = quality_group.node_for_global.getContainer()
if not new_global_stack.quality:
new_global_stack.quality = application.empty_quality_container
for position, extruder_stack in new_global_stack.extruders.items(): for position, extruder_stack in new_global_stack.extruders.items():
if position in quality_group.nodes_for_extruders: if position in quality_group.nodes_for_extruders and quality_group.nodes_for_extruders[position].getContainer():
extruder_stack.quality = quality_group.nodes_for_extruders[position].getContainer() extruder_stack.quality = quality_group.nodes_for_extruders[position].getContainer()
else: else:
extruder_stack.quality = application.empty_quality_container extruder_stack.quality = application.empty_quality_container

View file

@ -987,6 +987,12 @@ class MachineManager(QObject):
self.activeQualityChangesGroupChanged.emit() self.activeQualityChangesGroupChanged.emit()
def _setQualityGroup(self, quality_group, empty_quality_changes = True): def _setQualityGroup(self, quality_group, empty_quality_changes = True):
if quality_group.node_for_global.getContainer() is None:
return
for node in quality_group.nodes_for_extruders.values():
if node.getContainer() is None:
return
self._current_quality_group = quality_group self._current_quality_group = quality_group
if empty_quality_changes: if empty_quality_changes:
self._current_quality_changes_group = None self._current_quality_changes_group = None
@ -1012,9 +1018,9 @@ class MachineManager(QObject):
quality_changes_container = self._empty_quality_changes_container quality_changes_container = self._empty_quality_changes_container
quality_container = self._empty_quality_changes_container quality_container = self._empty_quality_changes_container
if quality_changes_group.node_for_global: if quality_changes_group.node_for_global and quality_changes_group.node_for_global.getContainer():
quality_changes_container = quality_changes_group.node_for_global.getContainer() quality_changes_container = quality_changes_group.node_for_global.getContainer()
if quality_group.node_for_global: if quality_group.node_for_global and quality_group.node_for_global.getContainer():
quality_container = quality_group.node_for_global.getContainer() quality_container = quality_group.node_for_global.getContainer()
self._global_container_stack.quality = quality_container self._global_container_stack.quality = quality_container
@ -1026,9 +1032,9 @@ class MachineManager(QObject):
quality_changes_container = self._empty_quality_changes_container quality_changes_container = self._empty_quality_changes_container
quality_container = self._empty_quality_container quality_container = self._empty_quality_container
if quality_changes_node: if quality_changes_node and quality_changes_node.getContainer():
quality_changes_container = quality_changes_node.getContainer() quality_changes_container = quality_changes_node.getContainer()
if quality_node: if quality_node and quality_node.getContainer():
quality_container = quality_node.getContainer() quality_container = quality_node.getContainer()
extruder.quality = quality_container extruder.quality = quality_container
@ -1040,14 +1046,18 @@ class MachineManager(QObject):
self.activeQualityChangesGroupChanged.emit() self.activeQualityChangesGroupChanged.emit()
def _setVariantNode(self, position, container_node): def _setVariantNode(self, position, container_node):
if container_node.getContainer() is None:
return
self._global_container_stack.extruders[position].variant = container_node.getContainer() self._global_container_stack.extruders[position].variant = container_node.getContainer()
self.activeVariantChanged.emit() self.activeVariantChanged.emit()
def _setGlobalVariant(self, container_node): def _setGlobalVariant(self, container_node):
self._global_container_stack.variant = container_node.getContainer() self._global_container_stack.variant = container_node.getContainer()
if not self._global_container_stack.variant:
self._global_container_stack.variant = Application.getInstance().empty_variant_container
def _setMaterial(self, position, container_node = None): def _setMaterial(self, position, container_node = None):
if container_node: if container_node and container_node.getContainer():
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.metadata["base_file"] root_material_id = container_node.metadata["base_file"]
else: else:

View file

@ -895,7 +895,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
variant_type = VariantType.BUILD_PLATE variant_type = VariantType.BUILD_PLATE
node = variant_manager.getVariantNode(global_stack.definition.getId(), variant_name, variant_type) node = variant_manager.getVariantNode(global_stack.definition.getId(), variant_name, variant_type)
if node is not None: if node is not None and node.getContainer() is not None:
global_stack.variant = node.getContainer() global_stack.variant = node.getContainer()
for position, extruder_stack in extruder_stack_dict.items(): for position, extruder_stack in extruder_stack_dict.items():
@ -911,7 +911,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
variant_type = VariantType.NOZZLE variant_type = VariantType.NOZZLE
node = variant_manager.getVariantNode(global_stack.definition.getId(), variant_name, variant_type) node = variant_manager.getVariantNode(global_stack.definition.getId(), variant_name, variant_type)
if node is not None: if node is not None and node.getContainer() is not None:
extruder_stack.variant = node.getContainer() extruder_stack.variant = node.getContainer()
def _applyMaterials(self, global_stack, extruder_stack_dict): def _applyMaterials(self, global_stack, extruder_stack_dict):
@ -937,7 +937,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
extruder_stack.variant.getName(), extruder_stack.variant.getName(),
machine_material_diameter, machine_material_diameter,
root_material_id) root_material_id)
if material_node is not None: if material_node is not None and material_node.getContainer() is not None:
extruder_stack.material = material_node.getContainer() extruder_stack.material = material_node.getContainer()
def _applyChangesToMachine(self, global_stack, extruder_stack_dict): def _applyChangesToMachine(self, global_stack, extruder_stack_dict):

View file

@ -71,11 +71,13 @@ class XmlMaterialProfile(InstanceContainer):
# Update the root material container # Update the root material container
root_material_container = material_group.root_material_node.getContainer() root_material_container = material_group.root_material_node.getContainer()
if root_material_container is not None:
root_material_container.setMetaDataEntry(key, value, apply_to_all = False) root_material_container.setMetaDataEntry(key, value, apply_to_all = False)
# Update all containers derived from it # Update all containers derived from it
for node in material_group.derived_material_node_list: for node in material_group.derived_material_node_list:
container = node.getContainer() container = node.getContainer()
if container is not None:
container.setMetaDataEntry(key, value, apply_to_all = False) container.setMetaDataEntry(key, value, apply_to_all = False)
## Overridden from InstanceContainer, similar to setMetaDataEntry. ## Overridden from InstanceContainer, similar to setMetaDataEntry.