diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 17b28c12c8..42bf1b693a 100755 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -269,10 +269,11 @@ class BuildVolume(SceneNode): continue # Mark the node as outside build volume if the set extruder is disabled extruder_position = node.callDecoration("getActiveExtruderPosition") - if extruder_position not in self._global_container_stack.extruders: - continue - if not self._global_container_stack.extruders[extruder_position].isEnabled: - node.setOutsideBuildArea(True) + try: + if not self._global_container_stack.extruderList[int(extruder_position)].isEnabled: + node.setOutsideBuildArea(True) + continue + except IndexError: continue node.setOutsideBuildArea(False) @@ -319,7 +320,7 @@ class BuildVolume(SceneNode): # Mark the node as outside build volume if the set extruder is disabled extruder_position = node.callDecoration("getActiveExtruderPosition") - if not self._global_container_stack.extruders[extruder_position].isEnabled: + if not self._global_container_stack.extruderList[int(extruder_position)].isEnabled: node.setOutsideBuildArea(True) return @@ -549,7 +550,7 @@ class BuildVolume(SceneNode): return old_raft_thickness = self._raft_thickness - if self._global_container_stack.extruders: + if self._global_container_stack.extruderList: # This might be called before the extruder stacks have initialised, in which case getting the adhesion_type fails self._adhesion_type = self._global_container_stack.getProperty("adhesion_type", "value") self._raft_thickness = 0.0 @@ -1098,7 +1099,7 @@ class BuildVolume(SceneNode): # not part of the collision radius, such as bed adhesion (skirt/brim/raft) # and travel avoid distance. def getEdgeDisallowedSize(self): - if not self._global_container_stack or not self._global_container_stack.extruders: + if not self._global_container_stack or not self._global_container_stack.extruderList: return 0 container_stack = self._global_container_stack diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index ef85bf7457..0877aedb1b 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -660,14 +660,14 @@ class CuraApplication(QtApplication): def discardOrKeepProfileChangesClosed(self, option: str) -> None: global_stack = self.getGlobalContainerStack() if option == "discard": - for extruder in global_stack.extruders.values(): + for extruder in global_stack.extruderList: extruder.userChanges.clear() global_stack.userChanges.clear() # if the user decided to keep settings then the user settings should be re-calculated and validated for errors # before slicing. To ensure that slicer uses right settings values elif option == "keep": - for extruder in global_stack.extruders.values(): + for extruder in global_stack.extruderList: extruder.userChanges.update() global_stack.userChanges.update() @@ -1668,7 +1668,7 @@ class CuraApplication(QtApplication): arranger = Arrange.create(x = machine_width, y = machine_depth, fixed_nodes = fixed_nodes) min_offset = 8 default_extruder_position = self.getMachineManager().defaultExtruderPosition - default_extruder_id = self._global_container_stack.extruders[default_extruder_position].getId() + default_extruder_id = self._global_container_stack.extruderList[int(default_extruder_position)].getId() select_models_on_load = self.getPreferences().getValue("cura/select_models_on_load") diff --git a/cura/Machines/MachineErrorChecker.py b/cura/Machines/MachineErrorChecker.py index 964331909c..cfeeb630df 100644 --- a/cura/Machines/MachineErrorChecker.py +++ b/cura/Machines/MachineErrorChecker.py @@ -67,7 +67,7 @@ class MachineErrorChecker(QObject): self._global_stack.propertyChanged.disconnect(self.startErrorCheckPropertyChanged) self._global_stack.containersChanged.disconnect(self.startErrorCheck) - for extruder in self._global_stack.extruders.values(): + for extruder in self._global_stack.extruderList: extruder.propertyChanged.disconnect(self.startErrorCheckPropertyChanged) extruder.containersChanged.disconnect(self.startErrorCheck) @@ -77,7 +77,7 @@ class MachineErrorChecker(QObject): self._global_stack.propertyChanged.connect(self.startErrorCheckPropertyChanged) self._global_stack.containersChanged.connect(self.startErrorCheck) - for extruder in self._global_stack.extruders.values(): + for extruder in self._global_stack.extruderList: extruder.propertyChanged.connect(self.startErrorCheckPropertyChanged) extruder.containersChanged.connect(self.startErrorCheck) @@ -127,7 +127,7 @@ class MachineErrorChecker(QObject): # Populate the (stack, key) tuples to check self._stacks_and_keys_to_check = deque() - for stack in global_stack.extruders.values(): + for stack in global_stack.extruderList: for key in stack.getAllKeys(): self._stacks_and_keys_to_check.append((stack, key)) diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py index e936877923..2c9c7607ad 100644 --- a/cura/Machines/Models/BaseMaterialsModel.py +++ b/cura/Machines/Models/BaseMaterialsModel.py @@ -70,7 +70,12 @@ class BaseMaterialsModel(ListModel): if self._extruder_stack is not None: self._extruder_stack.pyqtContainersChanged.disconnect(self._update) self._extruder_stack.approximateMaterialDiameterChanged.disconnect(self._update) - self._extruder_stack = global_stack.extruders.get(str(self._extruder_position)) + + try: + self._extruder_stack = global_stack.extruderList[self._extruder_position] + except IndexError: + self._extruder_stack = None + if self._extruder_stack is not None: self._extruder_stack.pyqtContainersChanged.connect(self._update) self._extruder_stack.approximateMaterialDiameterChanged.connect(self._update) @@ -113,12 +118,11 @@ class BaseMaterialsModel(ListModel): if global_stack is None or not self._enabled: return False - extruder_position = str(self._extruder_position) - - if extruder_position not in global_stack.extruders: + try: + extruder_stack = global_stack.extruderList[self._extruder_position] + except IndexError: return False - - extruder_stack = global_stack.extruders[extruder_position] + self._available_materials = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, extruder_stack) if self._available_materials is None: return False diff --git a/cura/Machines/Models/UserChangesModel.py b/cura/Machines/Models/UserChangesModel.py index e629295397..ec623f0f38 100644 --- a/cura/Machines/Models/UserChangesModel.py +++ b/cura/Machines/Models/UserChangesModel.py @@ -50,7 +50,7 @@ class UserChangesModel(ListModel): return stacks = [global_stack] - stacks.extend(global_stack.extruders.values()) + stacks.extend(global_stack.extruderList) # Check if the definition container has a translation file and ensure it's loaded. definition = global_stack.getBottom() diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 7da4f4f0d6..70fadc792b 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -154,8 +154,13 @@ class QualityManager(QObject): def _updateQualityGroupsAvailability(self, machine: "GlobalStack", quality_group_list) -> None: used_extruders = set() for i in range(machine.getProperty("machine_extruder_count", "value")): - if str(i) in machine.extruders and machine.extruders[str(i)].isEnabled: - used_extruders.add(str(i)) + try: + extruder = machine.extruderList[int(i)] + except IndexError: + pass + else: + if extruder.isEnabled: + used_extruders.add(str(i)) # Update the "is_available" flag for each quality group. for quality_group in quality_group_list: diff --git a/cura/OAuth2/AuthorizationService.py b/cura/OAuth2/AuthorizationService.py index 95ea47112e..68756f8df6 100644 --- a/cura/OAuth2/AuthorizationService.py +++ b/cura/OAuth2/AuthorizationService.py @@ -199,8 +199,6 @@ class AuthorizationService: self._unable_to_get_data_message.hide() self._unable_to_get_data_message = Message(i18n_catalog.i18nc("@info", "Unable to reach the Ultimaker account server."), title = i18n_catalog.i18nc("@info:title", "Warning")) - self._unable_to_get_data_message.addAction("retry", i18n_catalog.i18nc("@action:button", "Retry"), "[no_icon]", "[no_description]") - self._unable_to_get_data_message.actionTriggered.connect(self._onMessageActionTriggered) self._unable_to_get_data_message.show() except ValueError: Logger.logException("w", "Could not load auth data from preferences") @@ -222,6 +220,3 @@ class AuthorizationService: self.accessTokenChanged.emit() - def _onMessageActionTriggered(self, _, action): - if action == "retry": - self.loadAuthDataFromPreferences() diff --git a/cura/PreviewPass.py b/cura/PreviewPass.py index c1a64cb07c..58205ba708 100644 --- a/cura/PreviewPass.py +++ b/cura/PreviewPass.py @@ -64,7 +64,7 @@ class PreviewPass(RenderPass): self._shader.setUniformValue("u_ambientColor", [0.1, 0.1, 0.1, 1.0]) self._shader.setUniformValue("u_specularColor", [0.6, 0.6, 0.6, 1.0]) self._shader.setUniformValue("u_shininess", 20.0) - self._shader.setUniformValue("u_faceId", -1) # de-select any selected faces + self._shader.setUniformValue("u_faceId", -1) # Don't render any selected faces in the preview. if not self._non_printing_shader: if self._non_printing_shader: diff --git a/cura/Settings/CuraFormulaFunctions.py b/cura/Settings/CuraFormulaFunctions.py index a8b416eeb5..b35069da6f 100644 --- a/cura/Settings/CuraFormulaFunctions.py +++ b/cura/Settings/CuraFormulaFunctions.py @@ -40,8 +40,8 @@ class CuraFormulaFunctions: global_stack = machine_manager.activeMachine try: - extruder_stack = global_stack.extruders[str(extruder_position)] - except KeyError: + extruder_stack = global_stack.extruderList[int(extruder_position)] + except IndexError: if extruder_position != 0: Logger.log("w", "Value for %s of extruder %s was requested, but that extruder is not available. Returning the result form extruder 0 instead" % (property_key, extruder_position)) # This fixes a very specific fringe case; If a profile was created for a custom printer and one of the @@ -104,11 +104,14 @@ class CuraFormulaFunctions: machine_manager = self._application.getMachineManager() global_stack = machine_manager.activeMachine - extruder_stack = global_stack.extruders[str(extruder_position)] + try: + extruder_stack = global_stack.extruderList[extruder_position] + except IndexError: + Logger.log("w", "Unable to find extruder on in index %s", extruder_position) + else: + context = self.createContextForDefaultValueEvaluation(extruder_stack) - context = self.createContextForDefaultValueEvaluation(extruder_stack) - - return self.getValueInExtruder(extruder_position, property_key, context = context) + return self.getValueInExtruder(extruder_position, property_key, context = context) # Gets all default setting values as a list from all extruders of the currently active machine. # The default values are those excluding the values in the user_changes container. diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 2fa90f9636..417f7b01ff 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -74,7 +74,7 @@ class ExtruderManager(QObject): global_container_stack = self._application.getGlobalContainerStack() if global_container_stack: - extruder_stack_ids = {position: extruder.id for position, extruder in global_container_stack.extruders.items()} + extruder_stack_ids = {extruder.getMetaDataEntry("position", ""): extruder.id for extruder in global_container_stack.extruderList} return extruder_stack_ids @@ -360,10 +360,14 @@ class ExtruderManager(QObject): def fixSingleExtrusionMachineExtruderDefinition(self, global_stack: "GlobalStack") -> None: container_registry = ContainerRegistry.getInstance() expected_extruder_definition_0_id = global_stack.getMetaDataEntry("machine_extruder_trains")["0"] - extruder_stack_0 = global_stack.extruders.get("0") + try: + extruder_stack_0 = global_stack.extruderList[0] + except IndexError: + extruder_stack_0 = None + # At this point, extruder stacks for this machine may not have been loaded yet. In this case, need to look in # the container registry as well. - if not global_stack.extruders: + if not global_stack.extruderList: extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = global_stack.getId()) if extruder_trains: diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index edb0e7d41f..9983ab6c98 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -135,12 +135,15 @@ class ExtruderStack(CuraContainerStack): if limit_to_extruder == -1: limit_to_extruder = int(cura.CuraApplication.CuraApplication.getInstance().getMachineManager().defaultExtruderPosition) limit_to_extruder = str(limit_to_extruder) + if (limit_to_extruder is not None and limit_to_extruder != "-1") and self.getMetaDataEntry("position") != str(limit_to_extruder): - if str(limit_to_extruder) in self.getNextStack().extruders: - result = self.getNextStack().extruders[str(limit_to_extruder)].getProperty(key, property_name, context) + try: + result = self.getNextStack().extruderList[int(limit_to_extruder)].getProperty(key, property_name, context) if result is not None: context.popContainer() return result + except IndexError: + pass result = super().getProperty(key, property_name, context) context.popContainer() diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 7b7974e6b2..9bcdc7c4e8 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -184,7 +184,7 @@ class MachineManager(QObject): # Create the configuration model with the current data in Cura self._current_printer_configuration.printerType = self._global_container_stack.definition.getName() self._current_printer_configuration.extruderConfigurations = [] - for extruder in self._global_container_stack.extruders.values(): + for extruder in self._global_container_stack.extruderList: extruder_configuration = ExtruderConfigurationModel() # For compare just the GUID is needed at this moment mat_type = extruder.material.getMetaDataEntry("material") if extruder.material != empty_material_container else None @@ -201,7 +201,8 @@ class MachineManager(QObject): # An empty build plate configuration from the network printer is presented as an empty string, so use "" for an # empty build plate. - 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._current_printer_configuration.buildplateConfiguration = self._global_container_stack.getProperty("machine_buildplate_type", "value")\ + if self._global_container_stack.variant != empty_variant_container else self._global_container_stack.getProperty("machine_buildplate_type", "default_value") self.currentConfigurationChanged.emit() @pyqtSlot(QObject, result = bool) @@ -294,13 +295,13 @@ class MachineManager(QObject): ## Given a global_stack, make sure that it's all valid by searching for this quality group and applying it again def _initMachineState(self, global_stack: "CuraContainerStack") -> None: material_dict = {} - for position, extruder in global_stack.extruders.items(): - material_dict[position] = extruder.material.getMetaDataEntry("base_file") + for position, extruder in enumerate(global_stack.extruderList): + material_dict[str(position)] = extruder.material.getMetaDataEntry("base_file") self._current_root_material_id = material_dict # Update materials to make sure that the diameters match with the machine's - for position in global_stack.extruders: - self.updateMaterialWithVariant(position) + for position, _ in enumerate(global_stack.extruderList): + self.updateMaterialWithVariant(str(position)) global_quality = global_stack.quality quality_type = global_quality.getMetaDataEntry("quality_type") @@ -686,7 +687,7 @@ class MachineManager(QObject): def isCurrentSetupSupported(self) -> bool: if not self._global_container_stack: return False - for stack in [self._global_container_stack] + list(self._global_container_stack.extruders.values()): + for stack in [self._global_container_stack] + self._global_container_stack.extruderList: for container in stack.getContainers(): if not container: return False @@ -712,8 +713,8 @@ class MachineManager(QObject): def copyAllValuesToExtruders(self) -> None: if self._active_container_stack is None or self._global_container_stack is None: return - extruder_stacks = list(self._global_container_stack.extruders.values()) - for extruder_stack in extruder_stacks: + + for extruder_stack in self._global_container_stack.extruderList: if extruder_stack != self._active_container_stack: for key in self._active_container_stack.userChanges.getAllKeys(): new_value = self._active_container_stack.getProperty(key, "value") @@ -843,8 +844,7 @@ class MachineManager(QObject): return True buildplate_compatible = True # It is compatible by default - extruder_stacks = self._global_container_stack.extruders.values() - for stack in extruder_stacks: + for stack in self._global_container_stack.extruderList: if not stack.isEnabled: continue material_container = stack.material @@ -867,8 +867,8 @@ class MachineManager(QObject): # (material_left_compatible or material_left_usable) and # (material_right_compatible or material_right_usable) result = not self.variantBuildplateCompatible - extruder_stacks = self._global_container_stack.extruders.values() - for stack in extruder_stacks: + + for stack in self._global_container_stack.extruderList: material_container = stack.material if material_container == empty_material_container: continue @@ -904,7 +904,7 @@ class MachineManager(QObject): old_value = old_value(self._global_container_stack) if int(old_value) < 0: continue - if int(old_value) >= extruder_count or not self._global_container_stack.extruders[str(old_value)].isEnabled: + if int(old_value) >= extruder_count or not self._global_container_stack.extruderList[int(old_value)].isEnabled: result.append(setting_key) Logger.log("d", "Reset setting [%s] in [%s] because its old value [%s] is no longer valid", setting_key, container, old_value) return result @@ -993,18 +993,21 @@ class MachineManager(QObject): @deprecated("use Cura.MachineManager.activeMachine.extruders instead", "4.2") def _getExtruder(self, position) -> Optional[ExtruderStack]: if self._global_container_stack: - return self._global_container_stack.extruders.get(str(position)) + try: + return self._global_container_stack.extruderList[int(position)] + except IndexError: + return None return None def updateDefaultExtruder(self) -> None: if self._global_container_stack is None: return - extruder_items = sorted(self._global_container_stack.extruders.items()) + old_position = self._default_extruder_position new_default_position = "0" - for position, extruder in extruder_items: + for extruder in self._global_container_stack.extruderList: if extruder.isEnabled: - new_default_position = position + new_default_position = extruder.getMetaDataEntry("position", "0") break if new_default_position != old_position: self._default_extruder_position = new_default_position @@ -1016,7 +1019,7 @@ class MachineManager(QObject): definition_changes_container = self._global_container_stack.definitionChanges machine_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value") extruder_count = 0 - for position, extruder in self._global_container_stack.extruders.items(): + for position, extruder in enumerate(self._global_container_stack.extruderList): if extruder.isEnabled and int(position) < machine_extruder_count: extruder_count += 1 if self.numberExtrudersEnabled != extruder_count: @@ -1040,7 +1043,7 @@ class MachineManager(QObject): return with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): property_names = ["value", "resolve", "validationState"] - for container in [self._global_container_stack] + list(self._global_container_stack.extruders.values()): + for container in [self._global_container_stack] + self._global_container_stack.extruderList: for setting_key in container.getAllKeys(): container.propertiesChanged.emit(setting_key, property_names) @@ -1089,7 +1092,7 @@ class MachineManager(QObject): def setSettingForAllExtruders(self, setting_name: str, property_name: str, property_value: str) -> None: if self._global_container_stack is None: return - for key, extruder in self._global_container_stack.extruders.items(): + for extruder in self._global_container_stack.extruderList: container = extruder.userChanges container.setProperty(setting_name, property_name, property_value) @@ -1099,7 +1102,7 @@ class MachineManager(QObject): def resetSettingForAllExtruders(self, setting_name: str) -> None: if self._global_container_stack is None: return - for key, extruder in self._global_container_stack.extruders.items(): + for extruder in self._global_container_stack.extruderList: container = extruder.userChanges container.removeInstance(setting_name) @@ -1117,8 +1120,9 @@ class MachineManager(QObject): changed = False if self._global_container_stack: - for position in self._global_container_stack.extruders: - material_id = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file") + for extruder in self._global_container_stack.extruderList: + material_id = extruder.material.getMetaDataEntry("base_file") + position = extruder.getMetaDataEntry("position") if position not in self._current_root_material_id or material_id != self._current_root_material_id[position]: changed = True self._current_root_material_id[position] = material_id @@ -1155,7 +1159,7 @@ class MachineManager(QObject): self._current_quality_changes_group = None self._global_container_stack.quality = empty_quality_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.extruderList: extruder.quality = empty_quality_container extruder.qualityChanges = empty_quality_changes_container @@ -1186,9 +1190,12 @@ class MachineManager(QObject): # Set quality and quality_changes for each ExtruderStack for position, node in quality_group.nodes_for_extruders.items(): - self._global_container_stack.extruders[str(position)].quality = node.getContainer() - if empty_quality_changes: - self._global_container_stack.extruders[str(position)].qualityChanges = empty_quality_changes_container + try: + self._global_container_stack.extruderList[int(position)].quality = node.getContainer() + if empty_quality_changes: + self._global_container_stack.extruderList[int(position)].qualityChanges = empty_quality_changes_container + except IndexError: + continue # This can be ignored as in some cases the quality group gets set for an extruder that's not active (eg custom fff printer) self.activeQualityGroupChanged.emit() self.activeQualityChangesGroupChanged.emit() @@ -1224,7 +1231,8 @@ class MachineManager(QObject): self._global_container_stack.quality = quality_container self._global_container_stack.qualityChanges = quality_changes_container - for position, extruder in self._global_container_stack.extruders.items(): + for extruder in self._global_container_stack.extruderList: + position = int(extruder.getMetaDataEntry("position", "0")) quality_changes_node = quality_changes_group.nodes_for_extruders.get(position) quality_node = None if quality_group is not None: @@ -1248,7 +1256,7 @@ class MachineManager(QObject): def _setVariantNode(self, position: str, container_node: "ContainerNode") -> None: if container_node.getContainer() is None or self._global_container_stack is None: return - self._global_container_stack.extruders[position].variant = container_node.getContainer() + self._global_container_stack.extruderList[int(position)].variant = container_node.getContainer() self.activeVariantChanged.emit() def _setGlobalVariant(self, container_node: "ContainerNode") -> None: @@ -1262,10 +1270,10 @@ class MachineManager(QObject): if self._global_container_stack is None: return if container_node and container_node.getContainer(): - self._global_container_stack.extruders[position].material = container_node.getContainer() + self._global_container_stack.extruderList[int(position)].material = container_node.getContainer() root_material_id = container_node.getMetaDataEntry("base_file", None) else: - self._global_container_stack.extruders[position].material = empty_material_container + self._global_container_stack.extruderList[int(position)].material = empty_material_container root_material_id = None # 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]: @@ -1276,7 +1284,7 @@ class MachineManager(QObject): # Check material - variant compatibility if self._global_container_stack is not None: if Util.parseBool(self._global_container_stack.getMetaDataEntry("has_materials", False)): - for position, extruder in self._global_container_stack.extruders.items(): + for extruder in self._global_container_stack.extruderList: if not extruder.isEnabled: continue if not extruder.material.getMetaDataEntry("compatible"): @@ -1336,7 +1344,10 @@ class MachineManager(QObject): buildplate_name = self._global_container_stack.variant.getName() for position_item in position_list: - extruder = self._global_container_stack.extruders[position_item] + try: + extruder = self._global_container_stack.extruderList[int(position_item)] + except IndexError: + continue current_material_base_name = extruder.material.getMetaDataEntry("base_file") current_nozzle_name = None @@ -1421,7 +1432,7 @@ class MachineManager(QObject): extruders_to_disable.add(extruder_configuration.position) # If there's no material and/or nozzle on the printer, enable the first extruder and disable the rest. - if len(extruders_to_disable) == len(self._global_container_stack.extruders): + if len(extruders_to_disable) == len(self._global_container_stack.extruderList): extruders_to_disable.remove(min(extruders_to_disable)) for extruder_configuration in configuration.extruderConfigurations: @@ -1429,7 +1440,7 @@ class MachineManager(QObject): # If the machine doesn't have a hotend or material, disable this extruder if int(position) in extruders_to_disable: - self._global_container_stack.extruders[position].setEnabled(False) + self._global_container_stack.extruderList[int(position)].setEnabled(False) need_to_show_message = True disabled_used_extruder_position_set.add(int(position)) @@ -1445,13 +1456,13 @@ class MachineManager(QObject): if variant_container_node: self._setVariantNode(position, variant_container_node) else: - self._global_container_stack.extruders[position].variant = empty_variant_container + self._global_container_stack.extruderList[int(position)].variant = empty_variant_container if material_container_node: self._setMaterial(position, material_container_node) else: - self._global_container_stack.extruders[position].material = empty_material_container - self._global_container_stack.extruders[position].setEnabled(True) + self._global_container_stack.extruderList[int(position)].material = empty_material_container + self._global_container_stack.extruderList[int(position)].setEnabled(True) self.updateMaterialWithVariant(position) self.updateDefaultExtruder() @@ -1473,7 +1484,7 @@ class MachineManager(QObject): # Show human-readable extruder names such as "Extruder Left", "Extruder Front" instead of "Extruder 1, 2, 3". extruder_names = [] for extruder_position in sorted(disabled_used_extruder_position_set): - extruder_stack = self._global_container_stack.extruders[str(extruder_position)] + extruder_stack = self._global_container_stack.extruderList[int(extruder_position)] extruder_name = extruder_stack.definition.getName() extruder_names.append(extruder_name) extruders_str = ", ".join(extruder_names) @@ -1504,7 +1515,7 @@ class MachineManager(QObject): machine_definition_id = self._global_container_stack.definition.id position = str(position) - extruder_stack = self._global_container_stack.extruders[position] + extruder_stack = self._global_container_stack.extruderList[int(position)] nozzle_name = extruder_stack.variant.getName() material_diameter = extruder_stack.getApproximateMaterialDiameter() material_node = self._material_manager.getMaterialNode(machine_definition_id, nozzle_name, buildplate_name, @@ -1516,7 +1527,7 @@ class MachineManager(QObject): @pyqtSlot(str, "QVariant") def setMaterial(self, position: str, container_node, global_stack: Optional["GlobalStack"] = None) -> None: if global_stack is not None and global_stack != self._global_container_stack: - global_stack.extruders[position].material = container_node.getContainer() + global_stack.extruderList[int(position)].material = container_node.getContainer() return position = str(position) self.blurSettings.emit() diff --git a/cura/Settings/SimpleModeSettingsManager.py b/cura/Settings/SimpleModeSettingsManager.py index b1896a9205..3923435e63 100644 --- a/cura/Settings/SimpleModeSettingsManager.py +++ b/cura/Settings/SimpleModeSettingsManager.py @@ -39,8 +39,8 @@ class SimpleModeSettingsManager(QObject): user_setting_keys.update(global_stack.userChanges.getAllKeys()) # check user settings in the extruder stacks - if global_stack.extruders: - for extruder_stack in global_stack.extruders.values(): + if global_stack.extruderList: + for extruder_stack in global_stack.extruderList: user_setting_keys.update(extruder_stack.userChanges.getAllKeys()) # remove settings that are visible in recommended (we don't show the reset button for those) diff --git a/cura/UI/PrintInformation.py b/cura/UI/PrintInformation.py index 3fafaaba12..abf1083836 100644 --- a/cura/UI/PrintInformation.py +++ b/cura/UI/PrintInformation.py @@ -197,11 +197,7 @@ class PrintInformation(QObject): material_preference_values = json.loads(self._application.getInstance().getPreferences().getValue("cura/material_settings")) - extruder_stacks = global_stack.extruders - - for position in extruder_stacks: - extruder_stack = extruder_stacks[position] - index = int(position) + for index, extruder_stack in enumerate(global_stack.extruderList): if index >= len(self._material_amounts): continue amount = self._material_amounts[index] diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index ddf7864bb3..9d2e4d1506 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -834,9 +834,8 @@ class CuraEngineBackend(QObject, Backend): if self._global_container_stack: self._global_container_stack.propertyChanged.disconnect(self._onSettingChanged) self._global_container_stack.containersChanged.disconnect(self._onChanged) - extruders = list(self._global_container_stack.extruders.values()) - for extruder in extruders: + for extruder in self._global_container_stack.extruderList: extruder.propertyChanged.disconnect(self._onSettingChanged) extruder.containersChanged.disconnect(self._onChanged) @@ -845,8 +844,8 @@ class CuraEngineBackend(QObject, Backend): if self._global_container_stack: self._global_container_stack.propertyChanged.connect(self._onSettingChanged) # Note: Only starts slicing when the value changed. self._global_container_stack.containersChanged.connect(self._onChanged) - extruders = list(self._global_container_stack.extruders.values()) - for extruder in extruders: + + for extruder in self._global_container_stack.extruderList: extruder.propertyChanged.connect(self._onSettingChanged) extruder.containersChanged.connect(self._onChanged) self._onChanged() diff --git a/plugins/ModelChecker/ModelChecker.py b/plugins/ModelChecker/ModelChecker.py index 0619c95d67..0afed28f19 100644 --- a/plugins/ModelChecker/ModelChecker.py +++ b/plugins/ModelChecker/ModelChecker.py @@ -76,7 +76,9 @@ class ModelChecker(QObject, Extension): # This function can be triggered in the middle of a machine change, so do not proceed if the machine change # has not done yet. - if str(node_extruder_position) not in global_container_stack.extruders: + try: + extruder = global_container_stack.extruderList[int(node_extruder_position)] + except IndexError: Application.getInstance().callLater(lambda: self.onChanged.emit()) return False @@ -131,9 +133,9 @@ class ModelChecker(QObject, Extension): material_shrinkage = {} # Get all shrinkage values of materials used - for extruder_position, extruder in global_container_stack.extruders.items(): + for extruder_position, extruder in enumerate(global_container_stack.extruderList): shrinkage = extruder.material.getProperty("material_shrinkage_percentage", "value") if shrinkage is None: shrinkage = 0 - material_shrinkage[extruder_position] = shrinkage + material_shrinkage[str(extruder_position)] = shrinkage return material_shrinkage diff --git a/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py b/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py index ba7b06bb1b..cdbb4a79ef 100644 --- a/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py +++ b/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py @@ -367,6 +367,8 @@ class ChangeAtZ(Script): modified_gcode = "" lines = active_layer.split("\n") for line in lines: + if line.strip() == "": + continue if ";Generated with Cura_SteamEngine" in line: TWinstances += 1 modified_gcode += ";ChangeAtZ instances: %d\n" % TWinstances diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 536006ffaa..61954f5bca 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -57,9 +57,12 @@ class SolidView(View): # As the rendering is called a *lot* we really, dont want to re-evaluate the property every time. So we store em! global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack: - support_extruder_nr = global_container_stack.getExtruderPositionValueWithDefault("support_extruder_nr") - support_angle_stack = global_container_stack.extruders.get(str(support_extruder_nr)) - if support_angle_stack: + support_extruder_nr = int(global_container_stack.getExtruderPositionValueWithDefault("support_extruder_nr")) + try: + support_angle_stack = global_container_stack.extruderList[support_extruder_nr] + except IndexError: + pass + else: self._support_angle = support_angle_stack.getProperty("support_angle", "value") def beginRendering(self): diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index b775d603d8..8d35b41fa2 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -1,10 +1,11 @@ # Copyright (c) 2019 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Dict, List, Optional +from typing import Dict, List, Optional from PyQt5.QtCore import QTimer from UM import i18nCatalog +from UM.Logger import Logger # To log errors talking to the API. from UM.Signal import Signal from cura.API import Account from cura.CuraApplication import CuraApplication @@ -37,7 +38,7 @@ class CloudOutputDeviceManager: # Persistent dict containing the remote clusters for the authenticated user. self._remote_clusters = {} # type: Dict[str, CloudOutputDevice] self._account = CuraApplication.getInstance().getCuraAPI().account # type: Account - self._api = CloudApiClient(self._account, on_error=lambda error: print(error)) + self._api = CloudApiClient(self._account, on_error = lambda error: Logger.log("e", str(error))) self._account.loginStateChanged.connect(self._onLoginStateChanged) # Create a timer to update the remote cluster list diff --git a/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py b/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py index 4f2f7a71a2..311356de8e 100644 --- a/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py +++ b/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py @@ -28,7 +28,7 @@ class CloudFlowMessage(Message): lifetime=0, dismissable=True, option_state=False, - image_source=image_path, + image_source=QUrl.fromLocalFile(image_path), image_caption=I18N_CATALOG.i18nc("@info:status Ultimaker Cloud should not be translated.", "Connect to Ultimaker Cloud"), ) diff --git a/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py b/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py index 0acb6c5066..3a1a9f0e0f 100644 --- a/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py +++ b/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from UM import i18nCatalog from UM.Message import Message - +from cura.CuraApplication import CuraApplication I18N_CATALOG = i18nCatalog("cura") @@ -13,16 +13,25 @@ class CloudPrinterDetectedMessage(Message): # Singleton used to prevent duplicate messages of this type at the same time. __is_visible = False + # Store in preferences to hide this message in the future. + _preference_key = "cloud/block_new_printers_popup" + def __init__(self) -> None: super().__init__( title=I18N_CATALOG.i18nc("@info:title", "New cloud printers found"), text=I18N_CATALOG.i18nc("@info:message", "New printers have been found connected to your account, " "you can find them in your list of discovered printers."), - lifetime=10, - dismissable=True + lifetime=0, + dismissable=True, + option_state=False, + option_text=I18N_CATALOG.i18nc("@info:option_text", "Do not show this message again") ) + self.optionToggled.connect(self._onDontAskMeAgain) + CuraApplication.getInstance().getPreferences().addPreference(self._preference_key, False) def show(self) -> None: + if CuraApplication.getInstance().getPreferences().getValue(self._preference_key): + return if CloudPrinterDetectedMessage.__is_visible: return super().show() @@ -31,3 +40,6 @@ class CloudPrinterDetectedMessage(Message): def hide(self, send_signal = True) -> None: super().hide(send_signal) CloudPrinterDetectedMessage.__is_visible = False + + def _onDontAskMeAgain(self, checked: bool) -> None: + CuraApplication.getInstance().getPreferences().setValue(self._preference_key, checked) diff --git a/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py b/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py index fd9a9e2f60..dd9c0a7d2a 100644 --- a/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py @@ -1,5 +1,6 @@ # Copyright (c) 2019 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. + from typing import Optional, Dict, List, Callable, Any from PyQt5.QtGui import QDesktopServices @@ -8,6 +9,7 @@ from PyQt5.QtNetwork import QNetworkReply from UM.FileHandler.FileHandler import FileHandler from UM.i18n import i18nCatalog +from UM.Logger import Logger from UM.Scene.SceneNode import SceneNode from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState from cura.PrinterOutput.PrinterOutputDevice import ConnectionType @@ -167,5 +169,5 @@ class LocalClusterOutputDevice(UltimakerNetworkedPrinterOutputDevice): ## Get the API client instance. def _getApiClient(self) -> ClusterApiClient: if not self._cluster_api: - self._cluster_api = ClusterApiClient(self.address, on_error=lambda error: print(error)) + self._cluster_api = ClusterApiClient(self.address, on_error = lambda error: Logger.log("e", str(error))) return self._cluster_api diff --git a/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDeviceManager.py index 89fd71d03c..b725224d81 100644 --- a/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDeviceManager.py @@ -1,5 +1,6 @@ # Copyright (c) 2019 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. + from typing import Dict, Optional, Callable, List from UM import i18nCatalog @@ -66,7 +67,7 @@ class LocalClusterOutputDeviceManager: ## Add a networked printer manually by address. def addManualDevice(self, address: str, callback: Optional[Callable[[bool, str], None]] = None) -> None: - api_client = ClusterApiClient(address, lambda error: print(error)) + api_client = ClusterApiClient(address, lambda error: Logger.log("e", str(error))) api_client.getSystem(lambda status: self._onCheckManualDeviceResponse(address, status, callback)) ## Remove a manually added networked printer. diff --git a/resources/bundled_packages/cura.json b/resources/bundled_packages/cura.json index 4d23d56e5c..2e561b6763 100644 --- a/resources/bundled_packages/cura.json +++ b/resources/bundled_packages/cura.json @@ -475,6 +475,23 @@ } } }, + "TrimeshReader": { + "package_info": { + "package_id": "TrimeshReader", + "package_type": "plugin", + "display_name": "Trimesh Reader", + "description": "Provides support for reading model files.", + "package_version": "1.0.0", + "sdk_version": "6.0.0", + "website": "https://ultimaker.com", + "author": { + "author_id": "UltimakerPackages", + "display_name": "Ultimaker B.V.", + "email": "plugins@ultimaker.com", + "website": "https://ultimaker.com" + } + } + }, "Toolbox": { "package_info": { "package_id": "Toolbox", diff --git a/resources/definitions/Mark2_for_Ultimaker2.def.json b/resources/definitions/Mark2_for_Ultimaker2.def.json index 6a385c4b8b..5aada425fd 100644 --- a/resources/definitions/Mark2_for_Ultimaker2.def.json +++ b/resources/definitions/Mark2_for_Ultimaker2.def.json @@ -1,5 +1,4 @@ { - "id": "Mark2_for_Ultimaker2", "version": 2, "name": "Mark2 for Ultimaker2", "inherits": "ultimaker2_plus", diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index b609088afa..2d6848ade8 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -7563,7 +7563,7 @@ "small_feature_speed_factor": { "label": "Small Feature Speed", - "description": "Small features will be printed at this percentage of their normal print speed. Slower printing can help with adhestion and accuracy.", + "description": "Small features will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy.", "unit": "%", "type": "float", "default_value": 50, @@ -7575,7 +7575,7 @@ "small_feature_speed_factor_0": { "label": "First Layer Speed", - "description": "Small features on the first layer will be printed at this percentage of their normal print speed. Slower printing can help with adhestion and accuracy.", + "description": "Small features on the first layer will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy.", "unit": "%", "type": "float", "default_value": 50, diff --git a/resources/definitions/flsun_qq.def.json b/resources/definitions/flsun_qq.def.json index ce69317b33..02b3849c12 100644 --- a/resources/definitions/flsun_qq.def.json +++ b/resources/definitions/flsun_qq.def.json @@ -19,13 +19,13 @@ "default_value": true }, "machine_width": { - "default_value": 240 + "default_value": 260 }, "machine_height": { "default_value": 285 }, "machine_depth": { - "default_value": 240 + "default_value": 260 }, "machine_center_is_zero": { "default_value": true diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index afb3aba82b..b47d77243c 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -107,8 +107,9 @@ Item Cura.PrinterTypeLabel { id: printerTypeLabel - text: Cura.MachineManager.getAbbreviatedMachineName(section) + text: section anchors.verticalCenter: parent.verticalCenter //One default margin above and one below. + autoFit: true } } diff --git a/resources/qml/ObjectItemButton.qml b/resources/qml/ObjectItemButton.qml index 683d0ed52b..b454fd929a 100644 --- a/resources/qml/ObjectItemButton.qml +++ b/resources/qml/ObjectItemButton.qml @@ -51,5 +51,21 @@ Button border.color: objectItemButton.checked ? UM.Theme.getColor("primary") : "transparent" } + TextMetrics + { + id: buttonTextMetrics + text: buttonText.text + font: buttonText.font + elide: buttonText.elide + elideWidth: buttonText.width + } + + Cura.ToolTip + { + id: tooltip + tooltipText: objectItemButton.text + visible: objectItemButton.hovered && buttonTextMetrics.elidedText != buttonText.text + } + onClicked: Cura.SceneController.changeSelection(index) } diff --git a/resources/qml/PrinterSelector/MachineSelectorButton.qml b/resources/qml/PrinterSelector/MachineSelectorButton.qml index c37823ba82..115957dd64 100644 --- a/resources/qml/PrinterSelector/MachineSelectorButton.qml +++ b/resources/qml/PrinterSelector/MachineSelectorButton.qml @@ -72,6 +72,7 @@ Button verticalCenter: parent.verticalCenter } spacing: UM.Theme.getSize("narrow_margin").width + visible: (updatePrinterTypesOnlyWhenChecked && machineSelectorButton.checked) || !updatePrinterTypesOnlyWhenChecked Repeater { diff --git a/run_mypy.py b/run_mypy.py index 27f07cd281..6be424bda8 100644 --- a/run_mypy.py +++ b/run_mypy.py @@ -1,80 +1,82 @@ -#!/usr/bin/env python -import os -import sys -import subprocess - - -# A quick Python implementation of unix 'where' command. -def where(exe_name: str, search_path: str = os.getenv("PATH")) -> str: - if search_path is None: - search_path = "" - paths = search_path.split(os.pathsep) - result = "" - print(" -> sys.executable location: %s" % sys.executable) - sys_exec_dir = os.path.dirname(sys.executable) - root_dir = os.path.dirname(sys_exec_dir) - paths += [sys_exec_dir, - os.path.join(root_dir, "bin"), - os.path.join(root_dir, "scripts"), - ] - paths = set(paths) - - for path in sorted(paths): - print(" -> Searching %s" % path) - candidate_path = os.path.join(path, exe_name) - if os.path.exists(candidate_path): - result = candidate_path - break - return result - - -def findModules(path): - result = [] - for entry in os.scandir(path): - if entry.is_dir() and os.path.exists(os.path.join(path, entry.name, "__init__.py")): - result.append(entry.name) - return result - - -def main(): - # Find Uranium via the PYTHONPATH var - uraniumUMPath = where("UM", os.getenv("PYTHONPATH")) - if uraniumUMPath is None: - uraniumUMPath = os.path.join("..", "Uranium") - uraniumPath = os.path.dirname(uraniumUMPath) - - mypy_path_parts = [".", os.path.join(".", "plugins"), os.path.join(".", "plugins", "VersionUpgrade"), - uraniumPath, os.path.join(uraniumPath, "stubs")] - if sys.platform == "win32": - os.putenv("MYPYPATH", ";".join(mypy_path_parts)) - else: - os.putenv("MYPYPATH", ":".join(mypy_path_parts)) - - # Mypy really needs to be run via its Python script otherwise it can't find its data files. - mypy_exe_name = "mypy.exe" if sys.platform == "win32" else "mypy" - mypy_exe_dir = where(mypy_exe_name) - mypy_module = os.path.join(os.path.dirname(mypy_exe_dir), mypy_exe_name) - print("Found mypy exe path: %s" % mypy_exe_dir) - print("Found mypy module path: %s" % mypy_module) - - plugins = findModules("plugins") - plugins.sort() - - mods = ["cura"] + plugins + findModules("plugins/VersionUpgrade") - - for mod in mods: - print("------------- Checking module {mod}".format(**locals())) - if sys.platform == "win32": - result = subprocess.run([mypy_module, "-p", mod, "--ignore-missing-imports"]) - else: - result = subprocess.run([sys.executable, mypy_module, "-p", mod, "--ignore-missing-imports"]) - if result.returncode != 0: - print("\nModule {mod} failed checking. :(".format(**locals())) - return 1 - else: - print("\n\nDone checking. All is good.") - return 0 - - -if __name__ == "__main__": - sys.exit(main()) +#!/usr/bin/env python +import os +import sys +import subprocess + + +# A quick Python implementation of unix 'where' command. +def where(exe_name: str, search_path: str = os.getenv("PATH")) -> str: + if search_path is None: + search_path = "" + paths = search_path.split(os.pathsep) + result = "" + print(" -> sys.executable location: %s" % sys.executable) + sys_exec_dir = os.path.dirname(sys.executable) + root_dir = os.path.dirname(sys_exec_dir) + paths += [sys_exec_dir, + os.path.join(root_dir, "bin"), + os.path.join(root_dir, "scripts"), + ] + paths = set(paths) + + for path in sorted(paths): + print(" -> Searching %s" % path) + candidate_path = os.path.join(path, exe_name) + if os.path.exists(candidate_path): + result = candidate_path + break + return result + + +def findModules(path): + result = [] + for entry in os.scandir(path): + if entry.is_dir() and os.path.exists(os.path.join(path, entry.name, "__init__.py")): + result.append(entry.name) + return result + + +def main(): + # Find Uranium via the PYTHONPATH var + uraniumUMPath = where("UM", os.getenv("PYTHONPATH")) + if uraniumUMPath is None: + uraniumUMPath = os.path.join("..", "Uranium") + uraniumPath = os.path.dirname(uraniumUMPath) + + mypy_path_parts = [".", os.path.join(".", "plugins"), os.path.join(".", "plugins", "VersionUpgrade"), + uraniumPath, os.path.join(uraniumPath, "stubs")] + if sys.platform == "win32": + os.putenv("MYPYPATH", ";".join(mypy_path_parts)) + else: + os.putenv("MYPYPATH", ":".join(mypy_path_parts)) + + # Mypy really needs to be run via its Python script otherwise it can't find its data files. + mypy_exe_name = "mypy.exe" if sys.platform == "win32" else "mypy" + mypy_exe_dir = where(mypy_exe_name) + mypy_module = os.path.join(os.path.dirname(mypy_exe_dir), mypy_exe_name) + print("Found mypy exe path: %s" % mypy_exe_dir) + print("Found mypy module path: %s" % mypy_module) + + plugins = findModules("plugins") + plugins.sort() + + mods = ["cura"] + plugins + findModules("plugins/VersionUpgrade") + success_code = 0 + for mod in mods: + print("------------- Checking module {mod}".format(**locals())) + if sys.platform == "win32": + result = subprocess.run([mypy_module, "-p", mod, "--ignore-missing-imports"]) + else: + result = subprocess.run([sys.executable, mypy_module, "-p", mod, "--ignore-missing-imports"]) + if result.returncode != 0: + print("\nModule {mod} failed checking. :(".format(**locals())) + success_code = 1 + if success_code: + print("\n\nSome modules failed checking!") + else: + print("\n\nDone checking. All is good.") + return success_code + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tests/TestMachineManager.py b/tests/TestMachineManager.py index 1e8cd8fb12..1d5d1a45cb 100644 --- a/tests/TestMachineManager.py +++ b/tests/TestMachineManager.py @@ -142,7 +142,7 @@ def test_resetSettingForAllExtruders(machine_manager): extruder_2 = createMockedExtruder("extruder_2") extruder_1.userChanges = createMockedInstanceContainer("settings_1") extruder_2.userChanges = createMockedInstanceContainer("settings_2") - global_stack.extruders = {"1": extruder_1, "2": extruder_2} + global_stack.extruderList = [extruder_1, extruder_2] machine_manager.resetSettingForAllExtruders("whatever")