def addContainer(self, container: ContainerInterface) -> None: containers = self.findContainers(container_type = container.__class__, id = container.getId()) if containers: Logger.log("w", "Container of type %s and id %s already added", repr(container.__class__), container.getId()) return if hasattr(container, "metaDataChanged"): container.metaDataChanged.connect(self._onContainerMetaDataChanged) self._containers.append(container) self._id_container_cache[container.getId()] = container self._clearQueryCache() self.containerAdded.emit(container)
def addContainer(self, container: ContainerInterface) -> None: containers = self.findContainers(container_type = container.__class__, id = container.getId()) if containers: Logger.log("w", "Container of type %s and id %s already added", repr(container.__class__), container.getId()) return if hasattr(container, "metaDataChanged"): # Since queries are based on metadata, we need to make sure to clear the cache when a container's metadata changes. container.metaDataChanged.connect(self._clearQueryCache) self._containers.append(container) self._id_container_cache[container.getId()] = container self._clearQueryCache() self.containerAdded.emit(container)
def _onMetadataChanged(self, container: ContainerInterface, **kwargs: Any) -> None: """Triggered when any metadata changed in any container, but only handles it when the metadata of this node is changed. :param container: The container whose metadata changed. :param kwargs: Key-word arguments provided when changing the metadata. These are ignored. As far as I know they are never provided to this call. """ if container.getId() != self.container_id: return new_metadata = container.getMetaData() old_base_file = self.base_file if new_metadata["base_file"] != old_base_file: self.base_file = new_metadata["base_file"] if old_base_file in self.variant.materials: # Move in parent node. del self.variant.materials[old_base_file] self.variant.materials[self.base_file] = self old_material_type = self.material_type self.material_type = new_metadata["material"] old_guid = self.guid self.guid = new_metadata["GUID"] if self.base_file != old_base_file or self.material_type != old_material_type or self.guid != old_guid: # List of quality profiles could've changed. self.qualities = {} self._loadAll() # Re-load the quality profiles for this node. self.materialChanged.emit(self)
def _materialAdded(self, container: ContainerInterface) -> None: if container.getMetaDataEntry("type") != "material": return # Not interested. if not self.machine.has_materials: return # We won't add any materials. material_definition = container.getMetaDataEntry("definition") base_file = container.getMetaDataEntry("base_file") if base_file in self.machine.exclude_materials: return # Material is forbidden for this printer. if base_file not in self.materials: # Completely new base file. Always better than not having a file as long as it matches our set-up. if material_definition != "fdmprinter" and material_definition != self.machine.container_id: return material_variant = container.getMetaDataEntry("variant_name", "empty") if material_variant != "empty" and material_variant != self.variant_name: return else: # We already have this base profile. Replace the base profile if the new one is more specific. new_definition = container.getMetaDataEntry("definition") if new_definition == "fdmprinter": return # Just as unspecific or worse. if new_definition != self.machine.container_id: return # Doesn't match this set-up. original_metadata = ContainerRegistry.getInstance().findContainersMetadata(id = self.materials[base_file].container_id)[0] original_variant = original_metadata.get("variant_name", "empty") if original_variant != "empty" or container.getMetaDataEntry("variant_name", "empty") == "empty": return # Original was already specific or just as unspecific as the new one. if "empty_material" in self.materials: del self.materials["empty_material"] self.materials[base_file] = MaterialNode(container.getId(), variant = self) self.materials[base_file].materialChanged.connect(self.materialsChanged) self.materialsChanged.emit(self.materials[base_file])
def replaceContainer(self, index: int, container: ContainerInterface, postpone_emit: bool = False) -> None: """Overridden from ContainerStack Replaces the container at the specified index with another container. This version performs checks to make sure the new container has the expected metadata and type. :throws Exception.InvalidContainerError Raised when trying to replace a container with a container that has an incorrect type. """ expected_type = _ContainerIndexes.IndexTypeMap[index] if expected_type == "definition": if not isinstance(container, DefinitionContainer): raise Exceptions.InvalidContainerError( "Cannot replace container at index {index} with a container that is not a DefinitionContainer" .format(index=index)) elif container != self._empty_instance_container and container.getMetaDataEntry( "type") != expected_type: raise Exceptions.InvalidContainerError( "Cannot replace container at index {index} with a container that is not of {type} type, but {actual_type} type." .format(index=index, type=expected_type, actual_type=container.getMetaDataEntry("type"))) current_container = self._containers[index] if current_container.getId() == container.getId(): return super().replaceContainer(index, container, postpone_emit)
def _materialAdded(self, container: ContainerInterface) -> None: if container.getMetaDataEntry("type") != "material": return # Not interested. if not ContainerRegistry.getInstance().findContainersMetadata( id=container.getId()): # CURA-6889 # containerAdded and removed signals may be triggered in the next event cycle. If a container gets added # and removed in the same event cycle, in the next cycle, the connections should just ignore the signals. # The check here makes sure that the container in the signal still exists. Logger.log( "d", "Got container added signal for container [%s] but it no longer exists, do nothing.", container.getId()) return if not self.machine.has_materials: return # We won't add any materials. material_definition = container.getMetaDataEntry("definition") base_file = container.getMetaDataEntry("base_file") if base_file in self.machine.exclude_materials: return # Material is forbidden for this printer. if base_file not in self.materials: # Completely new base file. Always better than not having a file as long as it matches our set-up. if material_definition != "fdmprinter" and material_definition != self.machine.container_id: return material_variant = container.getMetaDataEntry("variant_name") if material_variant is not None and material_variant != self.variant_name: return else: # We already have this base profile. Replace the base profile if the new one is more specific. new_definition = container.getMetaDataEntry("definition") if new_definition == "fdmprinter": return # Just as unspecific or worse. material_variant = container.getMetaDataEntry("variant_name") if new_definition != self.machine.container_id or material_variant != self.variant_name: return # Doesn't match this set-up. original_metadata = ContainerRegistry.getInstance( ).findContainersMetadata( id=self.materials[base_file].container_id)[0] if "variant_name" in original_metadata or material_variant is None: return # Original was already specific or just as unspecific as the new one. if "empty_material" in self.materials: del self.materials["empty_material"] self.materials[base_file] = MaterialNode(container.getId(), variant=self) self.materials[base_file].materialChanged.connect( self.materialsChanged) self.materialsChanged.emit(self.materials[base_file])
def _onRemoved(self, container: ContainerInterface) -> None: if container.getId() == self.container_id: # Remove myself from my parent. if self.base_file in self.variant.materials: del self.variant.materials[self.base_file] if not self.variant.materials: self.variant.materials["empty_material"] = MaterialNode("empty_material", variant = self.variant) self.materialChanged.emit(self)
def replaceContainer(self, index: int, container: ContainerInterface, postpone_emit: bool = False) -> None: expected_type = _ContainerIndexes.IndexTypeMap[index] if expected_type == "definition": if not isinstance(container, DefinitionContainer): raise Exceptions.InvalidContainerError("Cannot replace container at index {index} with a container that is not a DefinitionContainer".format(index = index)) elif container != self._empty_instance_container and container.getMetaDataEntry("type") != expected_type: raise Exceptions.InvalidContainerError("Cannot replace container at index {index} with a container that is not of {type} type, but {actual_type} type.".format(index = index, type = expected_type, actual_type = container.getMetaDataEntry("type"))) current_container = self._containers[index] if current_container.getId() == container.getId(): return super().replaceContainer(index, container, postpone_emit)
def _onRemoved(self, container: ContainerInterface) -> None: """Triggered when any container is removed, but only handles it when the container is removed that this node represents. :param container: The container that was allegedly removed. """ if container.getId() == self.container_id: # Remove myself from my parent. if self.base_file in self.variant.materials: del self.variant.materials[self.base_file] if not self.variant.materials: self.variant.materials["empty_material"] = MaterialNode( "empty_material", variant=self.variant) self.materialChanged.emit(self)
def addContainer(self, container: ContainerInterface) -> None: container_id = container.getId() if container_id in self._containers: Logger.log("w", "Container with ID %s was already added.", container_id) return if hasattr(container, "metaDataChanged"): container.metaDataChanged.connect(self._onContainerMetaDataChanged) self.metadata[container_id] = container.getMetaData() self._containers[container_id] = container if container_id not in self.source_provider: self.source_provider[container_id] = None #Added during runtime. self._clearQueryCacheByContainer(container) self.containerAdded.emit(container) Logger.log("d", "Container [%s] added.", container_id)
def _onContainerAdded(self, container: ContainerInterface) -> None: # We don't have all the machines loaded in the beginning, so in order to add the missing extruder stack # for single extrusion machines, we subscribe to the containerAdded signal, and whenever a global stack # is added, we check to see if an extruder stack needs to be added. if not isinstance(container, ContainerStack ) or container.getMetaDataEntry("type") != "machine": return machine_extruder_trains = container.getMetaDataEntry( "machine_extruder_trains") if machine_extruder_trains is not None and machine_extruder_trains != { "0": "fdmextruder" }: return extruder_stacks = self.findContainerStacks(type="extruder_train", machine=container.getId()) if not extruder_stacks: self.addExtruderStackForSingleExtrusionMachine( container, "fdmextruder")
def addContainer(self, container: ContainerInterface) -> None: container_id = container.getId() if container_id in self._containers: return if hasattr(container, "metaDataChanged"): container.metaDataChanged.connect(self._onContainerMetaDataChanged) self.metadata[container_id] = container.getMetaData() self._containers[container_id] = container if container_id not in self.source_provider: self.source_provider[container_id] = None #Added during runtime. self._clearQueryCacheByContainer(container) # containerAdded is a custom signal and can trigger direct calls to its subscribers. This should be avoided # because with the direct calls, the subscribers need to know everything about what it tries to do to avoid # triggering this signal again, which eventually can end up exceeding the max recursion limit. # We avoid the direct calls here to make sure that the subscribers do not need to take into account any max # recursion problem. self._application.callLater(self.containerAdded.emit, container)
def _onMetadataChanged(self, container: ContainerInterface, **kwargs: Any) -> None: if container.getId() != self.container_id: return new_metadata = container.getMetaData() old_base_file = self.base_file if new_metadata["base_file"] != old_base_file: self.base_file = new_metadata["base_file"] if old_base_file in self.variant.materials: # Move in parent node. del self.variant.materials[old_base_file] self.variant.materials[self.base_file] = self old_material_type = self.material_type self.material_type = new_metadata["material"] old_guid = self.guid self.guid = new_metadata["GUID"] if self.base_file != old_base_file or self.material_type != old_material_type or self.guid != old_guid: # List of quality profiles could've changed. self.qualities = {} self._loadAll() # Re-load the quality profiles for this node. self.materialChanged.emit(self)
def addContainer(self, container: ContainerInterface) -> None: container_id = container.getId() if container_id in self._containers: Logger.log("w", "Container with ID %s was already added.", container_id) return if hasattr(container, "metaDataChanged"): container.metaDataChanged.connect(self._onContainerMetaDataChanged) self.metadata[container_id] = container.getMetaData() self._containers[container_id] = container if container_id not in self.source_provider: self.source_provider[container_id] = None #Added during runtime. self._clearQueryCacheByContainer(container) Logger.log("d", "Container [%s] added.", container_id) # containerAdded is a custom signal and can trigger direct calls to its subscribers. This should be avoided # because with the direct calls, the subscribers need to know everything about what it tries to do to avoid # triggering this signal again, which eventually can end up exceeding the max recursion limit. # We avoid the direct calls here to make sure that the subscribers do not need to take into account any max # recursion problem. self._application.callLater(self.containerAdded.emit, container)
def addContainer(self, container: ContainerInterface) -> None: # Note: Intentional check with type() because we want to ignore subclasses if type(container) == ContainerStack: container = self._convertContainerStack( cast(ContainerStack, container)) if isinstance(container, InstanceContainer) and type(container) != type( self.getEmptyInstanceContainer()): # Check against setting version of the definition. required_setting_version = cura.CuraApplication.CuraApplication.SettingVersion actual_setting_version = int( container.getMetaDataEntry("setting_version", default=0)) if required_setting_version != actual_setting_version: Logger.log( "w", "Instance container {container_id} is outdated. Its setting version is {actual_setting_version} but it should be {required_setting_version}." .format(container_id=container.getId(), actual_setting_version=actual_setting_version, required_setting_version=required_setting_version)) return # Don't add. super().addContainer(container)