mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-07 14:04:03 -06:00
Merge master into material marketplace
This commit is contained in:
commit
9a5fb47a6e
228 changed files with 125261 additions and 4020 deletions
|
@ -746,12 +746,6 @@ class CuraApplication(QtApplication):
|
|||
|
||||
controller = self.getController()
|
||||
|
||||
# Initialize UI state
|
||||
controller.setActiveStage("PrepareStage")
|
||||
controller.setActiveView("SolidView")
|
||||
controller.setCameraTool("CameraTool")
|
||||
controller.setSelectionTool("SelectionTool")
|
||||
|
||||
t = controller.getTool("TranslateTool")
|
||||
if t:
|
||||
t.setEnabledAxis([ToolHandle.XAxis, ToolHandle.YAxis, ToolHandle.ZAxis])
|
||||
|
@ -788,8 +782,11 @@ class CuraApplication(QtApplication):
|
|||
self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles))
|
||||
self.initializeEngine()
|
||||
|
||||
# Make sure the correct stage is activated after QML is loaded
|
||||
# Initialize UI state
|
||||
controller.setActiveStage("PrepareStage")
|
||||
controller.setActiveView("SolidView")
|
||||
controller.setCameraTool("CameraTool")
|
||||
controller.setSelectionTool("SelectionTool")
|
||||
|
||||
# Hide the splash screen
|
||||
self.closeSplash()
|
||||
|
@ -1012,7 +1009,7 @@ class CuraApplication(QtApplication):
|
|||
return self._i18n_catalog.i18nc("@info 'width', 'depth' and 'height' are variable names that must NOT be translated; just translate the format of ##x##x## mm.", "%(width).1f x %(depth).1f x %(height).1f mm") % {'width' : self._scene_bounding_box.width.item(), 'depth': self._scene_bounding_box.depth.item(), 'height' : self._scene_bounding_box.height.item()}
|
||||
|
||||
def updatePlatformActivityDelayed(self, node = None):
|
||||
if node is not None and node.getMeshData() is not None:
|
||||
if node is not None and (node.getMeshData() is not None or node.callDecoration("getLayerData")):
|
||||
self._update_platform_activity_timer.start()
|
||||
|
||||
## Update scene bounding box for current build plate
|
||||
|
@ -1380,7 +1377,7 @@ class CuraApplication(QtApplication):
|
|||
try:
|
||||
group_node = Selection.getAllSelectedObjects()[0]
|
||||
except Exception as e:
|
||||
Logger.log("d", "mergeSelected: Exception:", e)
|
||||
Logger.log("e", "mergeSelected: Exception: %s", e)
|
||||
return
|
||||
|
||||
meshes = [node.getMeshData() for node in group_node.getAllChildren() if node.getMeshData()]
|
||||
|
@ -1753,3 +1750,7 @@ class CuraApplication(QtApplication):
|
|||
node = node.getParent()
|
||||
|
||||
Selection.add(node)
|
||||
|
||||
@pyqtSlot()
|
||||
def showMoreInformationDialogForAnonymousDataCollection(self):
|
||||
self._plugin_registry.getPluginObject("SliceInfoPlugin").showMoreInfoDialog()
|
||||
|
|
|
@ -235,7 +235,7 @@ class MaterialManager(QObject):
|
|||
return self._material_group_map.get(root_material_id)
|
||||
|
||||
def getRootMaterialIDForDiameter(self, root_material_id: str, approximate_diameter: str) -> str:
|
||||
return self._material_diameter_map.get(root_material_id).get(approximate_diameter, root_material_id)
|
||||
return self._material_diameter_map.get(root_material_id, {}).get(approximate_diameter, root_material_id)
|
||||
|
||||
def getRootMaterialIDWithoutDiameter(self, root_material_id: str) -> str:
|
||||
return self._diameter_material_map.get(root_material_id)
|
||||
|
|
|
@ -69,9 +69,7 @@ class QualityManagementModel(ListModel):
|
|||
# Create quality_changes group items
|
||||
quality_changes_item_list = []
|
||||
for quality_changes_group in quality_changes_group_dict.values():
|
||||
if quality_changes_group.quality_type not in available_quality_types:
|
||||
continue
|
||||
quality_group = quality_group_dict[quality_changes_group.quality_type]
|
||||
quality_group = quality_group_dict.get(quality_changes_group.quality_type)
|
||||
item = {"name": quality_changes_group.name,
|
||||
"is_read_only": False,
|
||||
"quality_group": quality_group,
|
||||
|
|
|
@ -84,11 +84,14 @@ class QualitySettingsModel(ListModel):
|
|||
quality_group = self._selected_quality_item["quality_group"]
|
||||
quality_changes_group = self._selected_quality_item["quality_changes_group"]
|
||||
|
||||
if self._selected_position == self.GLOBAL_STACK_POSITION:
|
||||
quality_node = quality_group.node_for_global
|
||||
else:
|
||||
quality_node = quality_group.nodes_for_extruders.get(str(self._selected_position))
|
||||
settings_keys = quality_group.getAllKeys()
|
||||
quality_node = None
|
||||
settings_keys = set()
|
||||
if quality_group:
|
||||
if self._selected_position == self.GLOBAL_STACK_POSITION:
|
||||
quality_node = quality_group.node_for_global
|
||||
else:
|
||||
quality_node = quality_group.nodes_for_extruders.get(str(self._selected_position))
|
||||
settings_keys = quality_group.getAllKeys()
|
||||
quality_containers = []
|
||||
if quality_node is not None and quality_node.getContainer() is not None:
|
||||
quality_containers.append(quality_node.getContainer())
|
||||
|
|
|
@ -163,7 +163,7 @@ class QualityManager(QObject):
|
|||
def _updateQualityGroupsAvailability(self, machine: "GlobalStack", quality_group_list):
|
||||
used_extruders = set()
|
||||
for i in range(machine.getProperty("machine_extruder_count", "value")):
|
||||
if machine.extruders[str(i)].isEnabled:
|
||||
if str(i) in machine.extruders and machine.extruders[str(i)].isEnabled:
|
||||
used_extruders.add(str(i))
|
||||
|
||||
# Update the "is_available" flag for each quality group.
|
||||
|
|
|
@ -74,7 +74,11 @@ class VariantManager:
|
|||
for variant_type in ALL_VARIANT_TYPES:
|
||||
self._machine_to_variant_dict_map[variant_definition][variant_type] = dict()
|
||||
|
||||
variant_type = variant_metadata["hardware_type"]
|
||||
try:
|
||||
variant_type = variant_metadata["hardware_type"]
|
||||
except KeyError:
|
||||
Logger.log("w", "Variant %s does not specify a hardware_type; assuming 'nozzle'", variant_metadata["id"])
|
||||
variant_type = VariantType.NOZZLE
|
||||
variant_type = VariantType(variant_type)
|
||||
variant_dict = self._machine_to_variant_dict_map[variant_definition][variant_type]
|
||||
if variant_name in variant_dict:
|
||||
|
|
|
@ -32,14 +32,19 @@ class MultiplyObjectsJob(Job):
|
|||
|
||||
root = scene.getRoot()
|
||||
arranger = Arrange.create(scene_root=root)
|
||||
processed_nodes = []
|
||||
nodes = []
|
||||
|
||||
for node in self._objects:
|
||||
# If object is part of a group, multiply group
|
||||
current_node = node
|
||||
while current_node.getParent() and current_node.getParent().callDecoration("isGroup"):
|
||||
while current_node.getParent() and (current_node.getParent().callDecoration("isGroup") or current_node.getParent().callDecoration("isSliceable")):
|
||||
current_node = current_node.getParent()
|
||||
|
||||
if current_node in processed_nodes:
|
||||
continue
|
||||
processed_nodes.append(current_node)
|
||||
|
||||
node_too_big = False
|
||||
if node.getBoundingBox().width < 300 or node.getBoundingBox().depth < 300:
|
||||
offset_shape_arr, hull_shape_arr = ShapeArray.fromNode(current_node, min_offset=self._min_offset)
|
||||
|
|
|
@ -138,6 +138,7 @@ class PrintInformation(QObject):
|
|||
|
||||
def setPreSliced(self, pre_sliced):
|
||||
self._pre_sliced = pre_sliced
|
||||
self._updateJobName()
|
||||
self.preSlicedChanged.emit()
|
||||
|
||||
@pyqtProperty(Duration, notify = currentPrintTimeChanged)
|
||||
|
@ -322,15 +323,20 @@ class PrintInformation(QObject):
|
|||
# when a file is opened using the terminal; the filename comes from _onFileLoaded and still contains its
|
||||
# extension. This cuts the extension off if necessary.
|
||||
name = os.path.splitext(name)[0]
|
||||
filename_parts = os.path.basename(base_name).split(".")
|
||||
|
||||
# If it's a gcode, also always update the job name
|
||||
is_gcode = False
|
||||
if len(filename_parts) > 1:
|
||||
# Only check the extension(s)
|
||||
is_gcode = "gcode" in filename_parts[1:]
|
||||
|
||||
# if this is a profile file, always update the job name
|
||||
# name is "" when I first had some meshes and afterwards I deleted them so the naming should start again
|
||||
is_empty = name == ""
|
||||
if is_project_file or (is_empty or (self._base_name == "" and self._base_name != name)):
|
||||
# remove ".curaproject" suffix from (imported) the file name
|
||||
if name.endswith(".curaproject"):
|
||||
name = name[:name.rfind(".curaproject")]
|
||||
self._base_name = name
|
||||
if is_gcode or is_project_file or (is_empty or (self._base_name == "" and self._base_name != name)):
|
||||
# Only take the file name part
|
||||
self._base_name = filename_parts[0]
|
||||
self._updateJobName()
|
||||
|
||||
@pyqtProperty(str, fset = setBaseName, notify = baseNameChanged)
|
||||
|
|
|
@ -58,8 +58,7 @@ class GenericOutputController(PrinterOutputController):
|
|||
self._output_device.sendCommand("G90")
|
||||
|
||||
def homeHead(self, printer):
|
||||
self._output_device.sendCommand("G28 X")
|
||||
self._output_device.sendCommand("G28 Y")
|
||||
self._output_device.sendCommand("G28 X Y")
|
||||
|
||||
def homeBed(self, printer):
|
||||
self._output_device.sendCommand("G28 Z")
|
||||
|
@ -152,3 +151,17 @@ class GenericOutputController(PrinterOutputController):
|
|||
for extruder in self._preheat_hotends:
|
||||
self.setTargetHotendTemperature(extruder.getPrinter(), extruder.getPosition(), 0)
|
||||
self._preheat_hotends = set()
|
||||
|
||||
# Cancel any ongoing preheating timers, without setting back the temperature to 0
|
||||
# This can be used eg at the start of a print
|
||||
def stopPreheatTimers(self):
|
||||
if self._preheat_hotends_timer.isActive():
|
||||
for extruder in self._preheat_hotends:
|
||||
extruder.updateIsPreheating(False)
|
||||
self._preheat_hotends = set()
|
||||
|
||||
self._preheat_hotends_timer.stop()
|
||||
|
||||
if self._preheat_bed_timer.isActive():
|
||||
self._preheat_printer.updateIsPreheating(False)
|
||||
self._preheat_bed_timer.stop()
|
||||
|
|
|
@ -59,7 +59,8 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
|
|||
printer_type = self._properties.get(b"machine", b"").decode("utf-8")
|
||||
printer_type_identifiers = {
|
||||
"9066": "ultimaker3",
|
||||
"9511": "ultimaker3_extended"
|
||||
"9511": "ultimaker3_extended",
|
||||
"9051": "ultimaker_s5"
|
||||
}
|
||||
self._printer_type = "Unknown"
|
||||
for key, value in printer_type_identifiers.items():
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from UM.Decorators import deprecated
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.OutputDevice.OutputDevice import OutputDevice
|
||||
from PyQt5.QtCore import pyqtProperty, QObject, QTimer, pyqtSignal, QVariant
|
||||
|
@ -175,6 +175,10 @@ class PrinterOutputDevice(QObject, OutputDevice):
|
|||
def acceptsCommands(self):
|
||||
return self._accepts_commands
|
||||
|
||||
@deprecated("Please use the protected function instead", "3.2")
|
||||
def setAcceptsCommands(self, accepts_commands):
|
||||
self._setAcceptsCommands(accepts_commands)
|
||||
|
||||
## Set a flag to signal the UI that the printer is not (yet) ready to receive commands
|
||||
def _setAcceptsCommands(self, accepts_commands):
|
||||
if self._accepts_commands != accepts_commands:
|
||||
|
|
|
@ -103,6 +103,25 @@ class CuraSceneNode(SceneNode):
|
|||
return True
|
||||
return False
|
||||
|
||||
## Override of SceneNode._calculateAABB to exclude non-printing-meshes from bounding box
|
||||
def _calculateAABB(self):
|
||||
aabb = None
|
||||
if self._mesh_data:
|
||||
aabb = self._mesh_data.getExtents(self.getWorldTransformation())
|
||||
else: # If there is no mesh_data, use a boundingbox that encompasses the local (0,0,0)
|
||||
position = self.getWorldPosition()
|
||||
aabb = AxisAlignedBox(minimum = position, maximum = position)
|
||||
|
||||
for child in self._children:
|
||||
if child.callDecoration("isNonPrintingMesh"):
|
||||
# Non-printing-meshes inside a group should not affect push apart or drop to build plate
|
||||
continue
|
||||
if aabb is None:
|
||||
aabb = child.getBoundingBox()
|
||||
else:
|
||||
aabb = aabb + child.getBoundingBox()
|
||||
self._aabb = aabb
|
||||
|
||||
## Taken from SceneNode, but replaced SceneNode with CuraSceneNode
|
||||
def __deepcopy__(self, memo):
|
||||
copy = CuraSceneNode(no_setting_override = True) # Setting override will be added later
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import os.path
|
||||
|
@ -22,12 +22,10 @@ from UM.Settings.DefinitionContainer import DefinitionContainer
|
|||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
|
||||
from UM.MimeTypeDatabase import MimeTypeNotFoundError
|
||||
from UM.Settings.ContainerFormatError import ContainerFormatError
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
from cura.Settings.ExtruderStack import ExtruderStack
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
|
@ -289,7 +287,9 @@ class ContainerManager(QObject):
|
|||
with open(file_url, "rt", encoding = "utf-8") as f:
|
||||
container.deserialize(f.read())
|
||||
except PermissionError:
|
||||
return {"status": "error", "message": "Permission denied when trying to read the file"}
|
||||
return {"status": "error", "message": "Permission denied when trying to read the file."}
|
||||
except ContainerFormatError:
|
||||
return {"status": "error", "Message": "The material file appears to be corrupt."}
|
||||
except Exception as ex:
|
||||
return {"status": "error", "message": str(ex)}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import os
|
||||
|
@ -10,6 +10,7 @@ from typing import Optional
|
|||
from PyQt5.QtWidgets import QMessageBox
|
||||
|
||||
from UM.Decorators import override
|
||||
from UM.Settings.ContainerFormatError import ContainerFormatError
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.ContainerStack import ContainerStack
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
|
@ -189,7 +190,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
return { "status": "ok", "message": catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "No custom profile to import in file <filename>{0}</filename>", file_name)}
|
||||
except Exception as e:
|
||||
# Note that this will fail quickly. That is, if any profile reader throws an exception, it will stop reading. It will only continue reading if the reader returned None.
|
||||
Logger.log("e", "Failed to import profile from %s: %s while using profile reader. Got exception %s", file_name,profile_reader.getPluginId(), str(e))
|
||||
Logger.log("e", "Failed to import profile from %s: %s while using profile reader. Got exception %s", file_name, profile_reader.getPluginId(), str(e))
|
||||
return { "status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>", file_name, "\n" + str(e))}
|
||||
|
||||
if profile_or_list:
|
||||
|
@ -418,7 +419,6 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
|
||||
Logger.log("d", "Converting ContainerStack {stack} to {type}", stack = container.getId(), type = container_type)
|
||||
|
||||
new_stack = None
|
||||
if container_type == "extruder_train":
|
||||
new_stack = ExtruderStack.ExtruderStack(container.getId())
|
||||
else:
|
||||
|
@ -704,7 +704,11 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
instance_container = InstanceContainer(container_id)
|
||||
with open(file_path, "r", encoding = "utf-8") as f:
|
||||
serialized = f.read()
|
||||
instance_container.deserialize(serialized, file_path)
|
||||
try:
|
||||
instance_container.deserialize(serialized, file_path)
|
||||
except ContainerFormatError:
|
||||
Logger.logException("e", "Unable to deserialize InstanceContainer %s", file_path)
|
||||
continue
|
||||
self.addContainer(instance_container)
|
||||
break
|
||||
|
||||
|
|
|
@ -283,6 +283,13 @@ class CuraContainerStack(ContainerStack):
|
|||
|
||||
self._containers = new_containers
|
||||
|
||||
# CURA-5281
|
||||
# Some stacks can have empty definition_changes containers which will cause problems.
|
||||
# Make sure that all stacks here have non-empty definition_changes containers.
|
||||
if isinstance(new_containers[_ContainerIndexes.DefinitionChanges], type(self._empty_instance_container)):
|
||||
from cura.Settings.CuraStackBuilder import CuraStackBuilder
|
||||
CuraStackBuilder.createDefinitionChangesContainer(self, self.getId() + "_settings")
|
||||
|
||||
## protected:
|
||||
|
||||
# Helper to make sure we emit a PyQt signal on container changes.
|
||||
|
|
|
@ -74,6 +74,7 @@ class MachineManager(QObject):
|
|||
|
||||
self._stacks_have_errors = None # type:Optional[bool]
|
||||
|
||||
self._empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer()
|
||||
self._empty_definition_changes_container = ContainerRegistry.getInstance().findContainers(id = "empty_definition_changes")[0]
|
||||
self._empty_variant_container = ContainerRegistry.getInstance().findContainers(id = "empty_variant")[0]
|
||||
self._empty_material_container = ContainerRegistry.getInstance().findContainers(id = "empty_material")[0]
|
||||
|
@ -310,19 +311,40 @@ class MachineManager(QObject):
|
|||
global_quality_changes = global_stack.qualityChanges
|
||||
global_quality_changes_name = global_quality_changes.getName()
|
||||
|
||||
# Try to set the same quality/quality_changes as the machine specified.
|
||||
# If the quality/quality_changes is not available, switch to the default or the first quality that's available.
|
||||
same_quality_found = False
|
||||
quality_groups = self._application.getQualityManager().getQualityGroups(global_stack)
|
||||
|
||||
if global_quality_changes.getId() != "empty_quality_changes":
|
||||
quality_changes_groups = self._application._quality_manager.getQualityChangesGroups(global_stack)
|
||||
if global_quality_changes_name in quality_changes_groups:
|
||||
new_quality_changes_group = quality_changes_groups[global_quality_changes_name]
|
||||
quality_changes_groups = self._application.getQualityManager().getQualityChangesGroups(global_stack)
|
||||
new_quality_changes_group = quality_changes_groups.get(global_quality_changes_name)
|
||||
if new_quality_changes_group is not None:
|
||||
self._setQualityChangesGroup(new_quality_changes_group)
|
||||
same_quality_found = True
|
||||
Logger.log("i", "Machine '%s' quality changes set to '%s'",
|
||||
global_stack.getName(), new_quality_changes_group.name)
|
||||
else:
|
||||
quality_groups = self._application._quality_manager.getQualityGroups(global_stack)
|
||||
if quality_type not in quality_groups:
|
||||
Logger.log("w", "Quality type [%s] not found in available qualities [%s]", quality_type, ", ".join(quality_groups.keys()))
|
||||
self._setEmptyQuality()
|
||||
return
|
||||
new_quality_group = quality_groups[quality_type]
|
||||
self._setQualityGroup(new_quality_group, empty_quality_changes = True)
|
||||
new_quality_group = quality_groups.get(quality_type)
|
||||
if new_quality_group is not None:
|
||||
self._setQualityGroup(new_quality_group, empty_quality_changes = True)
|
||||
same_quality_found = True
|
||||
Logger.log("i", "Machine '%s' quality set to '%s'",
|
||||
global_stack.getName(), new_quality_group.quality_type)
|
||||
|
||||
# Could not find the specified quality/quality_changes, switch to the preferred quality if available,
|
||||
# otherwise the first quality that's available, otherwise empty (not supported).
|
||||
if not same_quality_found:
|
||||
Logger.log("i", "Machine '%s' could not find quality_type '%s' and quality_changes '%s'. "
|
||||
"Available quality types are [%s]. Switching to default quality.",
|
||||
global_stack.getName(), quality_type, global_quality_changes_name,
|
||||
", ".join(quality_groups.keys()))
|
||||
preferred_quality_type = global_stack.getMetaDataEntry("preferred_quality_type")
|
||||
quality_group = quality_groups.get(preferred_quality_type)
|
||||
if quality_group is None:
|
||||
if quality_groups:
|
||||
quality_group = list(quality_groups.values())[0]
|
||||
self._setQualityGroup(quality_group, empty_quality_changes = True)
|
||||
|
||||
@pyqtSlot(str)
|
||||
def setActiveMachine(self, stack_id: str) -> None:
|
||||
|
@ -1012,6 +1034,10 @@ class MachineManager(QObject):
|
|||
if empty_quality_changes:
|
||||
self._current_quality_changes_group = None
|
||||
|
||||
if quality_group is None:
|
||||
self._setEmptyQuality()
|
||||
return
|
||||
|
||||
# Set quality and quality_changes for the GlobalStack
|
||||
self._global_container_stack.quality = quality_group.node_for_global.getContainer()
|
||||
if empty_quality_changes:
|
||||
|
@ -1123,13 +1149,15 @@ class MachineManager(QObject):
|
|||
|
||||
Logger.log("d", "Current quality type = [%s]", current_quality_type)
|
||||
if not self.activeMaterialsCompatible():
|
||||
Logger.log("i", "Active materials are not compatible, setting all qualities to empty (Not Supported).")
|
||||
self._setEmptyQuality()
|
||||
if current_quality_type is not None:
|
||||
Logger.log("i", "Active materials are not compatible, setting all qualities to empty (Not Supported).")
|
||||
self._setEmptyQuality()
|
||||
return
|
||||
|
||||
if not available_quality_types:
|
||||
Logger.log("i", "No available quality types found, setting all qualities to empty (Not Supported).")
|
||||
self._setEmptyQuality()
|
||||
if self._current_quality_changes_group is None:
|
||||
Logger.log("i", "No available quality types found, setting all qualities to empty (Not Supported).")
|
||||
self._setEmptyQuality()
|
||||
return
|
||||
|
||||
if current_quality_type in available_quality_types:
|
||||
|
|
|
@ -82,8 +82,9 @@ class SettingInheritanceManager(QObject):
|
|||
|
||||
def _onActiveExtruderChanged(self):
|
||||
new_active_stack = ExtruderManager.getInstance().getActiveExtruderStack()
|
||||
# if not new_active_stack:
|
||||
# new_active_stack = self._global_container_stack
|
||||
if not new_active_stack:
|
||||
self._active_container_stack = None
|
||||
return
|
||||
|
||||
if new_active_stack != self._active_container_stack: # Check if changed
|
||||
if self._active_container_stack: # Disconnect signal from old container (if any)
|
||||
|
@ -154,6 +155,8 @@ class SettingInheritanceManager(QObject):
|
|||
has_setting_function = False
|
||||
if not stack:
|
||||
stack = self._active_container_stack
|
||||
if not stack: #No active container stack yet!
|
||||
return False
|
||||
containers = []
|
||||
|
||||
## Check if the setting has a user state. If not, it is never overwritten.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue