diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py
index a97522389a..a6d0a3b827 100644
--- a/cura/CuraApplication.py
+++ b/cura/CuraApplication.py
@@ -97,7 +97,8 @@ class CuraApplication(QtApplication):
SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Any, default = True)
SettingDefinition.addSupportedProperty("settable_per_meshgroup", DefinitionPropertyType.Any, default = True)
SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Any, default = True)
- SettingDefinition.addSettingType("extruder", None, str, Validator)
+ SettingDefinition.addSupportedProperty("global_inherits_stack", DefinitionPropertyType.Function, default = "-1")
+ SettingDefinition.addSettingType("extruder", int, str, Validator)
## Add the 4 types of profiles to storage.
Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality")
diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py
index 744a6811c5..47359a5e97 100644
--- a/cura/Settings/ExtruderManager.py
+++ b/cura/Settings/ExtruderManager.py
@@ -22,7 +22,7 @@ class ExtruderManager(QObject):
def __init__(self, parent = None):
super().__init__(parent)
self._extruder_trains = { } #Per machine, a dictionary of extruder container stack IDs.
- self._active_extruder_index = -1
+ self._active_extruder_index = 0
UM.Application.getInstance().globalContainerStackChanged.connect(self.__globalContainerStackChanged)
self._addCurrentMachineExtruders()
@@ -41,6 +41,19 @@ class ExtruderManager(QObject):
except KeyError: # Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong.
return None
+ @pyqtProperty(int, notify = extrudersChanged)
+ def extruderCount(self):
+ if not UM.Application.getInstance().getGlobalContainerStack():
+ return 0 # No active machine, so no extruders.
+ return len(self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()])
+
+ @pyqtProperty("QVariantMap", notify=extrudersChanged)
+ def extruderIds(self):
+ map = {}
+ for position in self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()]:
+ map[position] = self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][position].getId()
+ return map
+
## The instance of the singleton pattern.
#
# It's None if the extruder manager hasn't been created yet.
@@ -106,8 +119,11 @@ class ExtruderManager(QObject):
for extruder_train in extruder_trains:
self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train
- # Ensure that the extruder train stacks are linked to global stack.
- extruder_train.setNextStack(UM.Application.getInstance().getGlobalContainerStack())
+ # Make sure the next stack is a stack that contains only the machine definition
+ if not extruder_train.getNextStack():
+ shallowStack = UM.Settings.ContainerStack(machine_id + "_shallow")
+ shallowStack.addContainer(machine_definition)
+ extruder_train.setNextStack(shallowStack)
changed = True
if changed:
self.extrudersChanged.emit(machine_id)
@@ -220,7 +236,11 @@ class ExtruderManager(QObject):
container_registry.addContainer(user_profile)
container_stack.addContainer(user_profile)
- container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack())
+ # Make sure the next stack is a stack that contains only the machine definition
+ if not container_stack.getNextStack():
+ shallowStack = UM.Settings.ContainerStack(machine_id + "_shallow")
+ shallowStack.addContainer(machine_definition)
+ container_stack.setNextStack(shallowStack)
container_registry.addContainer(container_stack)
diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py
index 0c435ba2b9..9f51591a58 100644
--- a/cura/Settings/MachineManager.py
+++ b/cura/Settings/MachineManager.py
@@ -50,6 +50,8 @@ class MachineManager(QObject):
Preferences.getInstance().addPreference("cura/active_machine", "")
+ self._global_event_keys = set()
+
active_machine_id = Preferences.getInstance().getValue("cura/active_machine")
self._printer_output_devices = []
@@ -58,7 +60,9 @@ class MachineManager(QObject):
if active_machine_id != "":
# An active machine was saved, so restore it.
self.setActiveMachine(active_machine_id)
- pass
+ if self._global_container_stack and self._global_container_stack.getProperty("machine_extruder_count", "value") > 1:
+ # Make sure _active_container_stack is properly initiated
+ ExtruderManager.getInstance().setActiveExtruderIndex(0)
self._auto_change_material_hotend_flood_window = 10 # The minimum number of seconds between asking if the material or hotend on the machine should be used
self._auto_change_material_hotend_flood_time = 0 # The last timestamp (in seconds) when the user was asked about changing the material or hotend to whatis loaded on the machine
@@ -197,7 +201,85 @@ class MachineManager(QObject):
def _onGlobalPropertyChanged(self, key, property_name):
if property_name == "value":
+ ## We can get recursion issues. So we store a list of keys that we are still handling to prevent this.
+ if key in self._global_event_keys:
+ return
+ self._global_event_keys.add(key)
self.globalValueChanged.emit()
+
+ if self._active_container_stack and self._active_container_stack != self._global_container_stack:
+ # Make the global current settings mirror the stack values appropriate for this setting
+ if self._active_container_stack.getProperty("extruder_nr", "value") == int(self._active_container_stack.getProperty(key, "global_inherits_stack")):
+
+ new_value = self._active_container_stack.getProperty(key, "value")
+ self._global_container_stack.getTop().setProperty(key, "value", new_value)
+
+ # Global-only setting values should be set on all extruders and the global stack
+ if not self._global_container_stack.getProperty(key, "settable_per_extruder"):
+ extruder_stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
+ target_stack_position = int(self._active_container_stack.getProperty(key, "global_inherits_stack"))
+ if target_stack_position == -1: # Prevent -1 from selecting wrong stack.
+ target_stack = self._active_container_stack
+ else:
+ target_stack = extruder_stacks[target_stack_position]
+ new_value = target_stack.getProperty(key, "value")
+ target_stack_has_user_value = target_stack.getTop().getInstance(key) != None
+ for extruder_stack in extruder_stacks:
+ if extruder_stack != target_stack:
+ if target_stack_has_user_value:
+ extruder_stack.getTop().setProperty(key, "value", new_value)
+ else:
+ # Remove from the value from the other stacks as well, unless the
+ # top value from the other stacklevels is different than the new value
+ for container in extruder_stack.getContainers():
+ if container.__class__ == UM.Settings.InstanceContainer and container.getInstance(key) != None:
+ if container.getProperty(key, "value") != new_value:
+ # It could be that the setting needs to be removed instead of updated.
+ temp = extruder_stack
+ containers = extruder_stack.getContainers()
+ # Ensure we have the entire 'chain'
+ while temp.getNextStack():
+ temp = temp.getNextStack()
+ containers.extend(temp.getContainers())
+ instance_needs_removal = False
+
+ if len(containers) > 1:
+ for index in range(1, len(containers)):
+ deeper_container = containers[index]
+ if deeper_container.getProperty(key, "value") is None:
+ continue # Deeper container does not have the value, so continue.
+ if deeper_container.getProperty(key, "value") == new_value:
+ # Removal will result in correct value, so do that.
+ # We do this to prevent the reset from showing up unneeded.
+ instance_needs_removal = True
+ break
+ else:
+ # Container has the value, but it's not the same. Stop looking.
+ break
+ if instance_needs_removal:
+ extruder_stack.getTop().removeInstance(key)
+ else:
+ extruder_stack.getTop().setProperty(key, "value", new_value)
+ else:
+ # Check if we really need to remove something.
+ if extruder_stack.getProperty(key, "value") != new_value:
+ extruder_stack.getTop().removeInstance(key)
+ break
+ if self._global_container_stack.getProperty(key, "value") != new_value:
+ self._global_container_stack.getTop().setProperty(key, "value", new_value)
+ self._global_event_keys.remove(key)
+
+ if property_name == "global_inherits_stack":
+ if self._active_container_stack and self._active_container_stack != self._global_container_stack:
+ # Update the global user value when the "global_inherits_stack" function points to a different stack
+ stack_index = int(self._active_container_stack.getProperty(key, property_name))
+ extruder_stacks = [stack for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())]
+
+ if len(extruder_stacks) > stack_index:
+ new_value = extruder_stacks[stack_index].getProperty(key, "value")
+ if self._global_container_stack.getProperty(key, "value") != new_value:
+ self._global_container_stack.getTop().setProperty(key, "value", new_value)
+
if property_name == "validationState":
if self._global_stack_valid:
changed_validation_state = self._active_container_stack.getProperty(key, property_name)
@@ -209,7 +291,6 @@ class MachineManager(QObject):
if not has_errors:
self._global_stack_valid = True
self.globalValidationChanged.emit()
-
def _onGlobalContainerChanged(self):
if self._global_container_stack:
self._global_container_stack.nameChanged.disconnect(self._onMachineNameChanged)
@@ -254,6 +335,18 @@ class MachineManager(QObject):
def _onInstanceContainersChanged(self, container):
container_type = container.getMetaDataEntry("type")
+
+ if self._active_container_stack and self._active_container_stack != self._global_container_stack:
+ if int(self._active_container_stack.getProperty("extruder_nr", "value")) == 0:
+ global_container = self._global_container_stack.findContainer({"type": container_type})
+ if global_container and global_container != container:
+ container_index = self._global_container_stack.getContainerIndex(global_container)
+ self._global_container_stack.replaceContainer(container_index, container)
+
+ for key in container.getAllKeys():
+ # Make sure the values in this profile are distributed to other stacks if necessary
+ self._onGlobalPropertyChanged(key, "value")
+
if container_type == "material":
self.activeMaterialChanged.emit()
elif container_type == "variant":
@@ -269,13 +362,14 @@ class MachineManager(QObject):
@pyqtSlot(str, str)
def addMachine(self, name, definition_id):
- definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = definition_id)
+ container_registry = UM.Settings.ContainerRegistry.getInstance()
+ definitions = container_registry.findDefinitionContainers(id = definition_id)
if definitions:
definition = definitions[0]
name = self._createUniqueName("machine", "", name, definition.getName())
new_global_stack = UM.Settings.ContainerStack(name)
new_global_stack.addMetaDataEntry("type", "machine")
- UM.Settings.ContainerRegistry.getInstance().addContainer(new_global_stack)
+ container_registry.addContainer(new_global_stack)
variant_instance_container = self._updateVariantContainer(definition)
material_instance_container = self._updateMaterialContainer(definition, variant_instance_container)
@@ -285,7 +379,7 @@ class MachineManager(QObject):
current_settings_instance_container.addMetaDataEntry("machine", name)
current_settings_instance_container.addMetaDataEntry("type", "user")
current_settings_instance_container.setDefinition(definitions[0])
- UM.Settings.ContainerRegistry.getInstance().addContainer(current_settings_instance_container)
+ container_registry.addContainer(current_settings_instance_container)
# If a definition is found, its a list. Should only have one item.
new_global_stack.addContainer(definition)
@@ -418,6 +512,19 @@ class MachineManager(QObject):
return True
return containers[0].isReadOnly()
+ ## Copy the value of the setting of the current extruder to all other extruders as well as the global container.
+ @pyqtSlot(str)
+ def copyValueToExtruders(self, key):
+ if not self._active_container_stack or self._global_container_stack.getProperty("machine_extruder_count", "value") <= 1:
+ return
+
+ new_value = self._active_container_stack.getProperty(key, "value")
+ stacks = [stack for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())]
+ stacks.append(self._global_container_stack)
+ for extruder_stack in stacks:
+ if extruder_stack != self._active_container_stack and extruder_stack.getProperty(key, "value") != new_value:
+ extruder_stack.getTop().setProperty(key, "value", new_value)
+
@pyqtSlot(result = str)
def newQualityContainerFromQualityAndUser(self):
new_container_id = self.duplicateContainer(self.activeQualityId)
diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
index 546b7086e6..54783f02b0 100644
--- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
+++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
@@ -181,6 +181,7 @@ Item {
onLoaded: {
settingLoader.item.showRevertButton = false
settingLoader.item.showInheritButton = false
+ settingLoader.item.showLinkedSettingIcon = false
settingLoader.item.doDepthIndentation = false
}
diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json
index 024d679315..a963b1614b 100644
--- a/resources/definitions/fdmprinter.def.json
+++ b/resources/definitions/fdmprinter.def.json
@@ -630,6 +630,7 @@
"type": "float",
"enabled": "support_enable",
"value": "line_width",
+ "global_inherits_stack": "support_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": false
},
@@ -644,6 +645,7 @@
"type": "float",
"enabled": "support_roof_enable",
"value": "line_width",
+ "global_inherits_stack": "support_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": false
},
@@ -1443,6 +1445,7 @@
"maximum_value_warning": "150",
"default_value": 60,
"value": "speed_print",
+ "global_inherits_stack": "support_extruder_nr",
"enabled": "support_enable",
"settable_per_mesh": false,
"settable_per_extruder": false,
@@ -1459,6 +1462,7 @@
"maximum_value": "299792458000",
"maximum_value_warning": "150",
"value": "speed_support",
+ "global_inherits_stack": "support_extruder_nr",
"enabled": "support_enable",
"settable_per_mesh": false,
"settable_per_extruder": false
@@ -1475,6 +1479,7 @@
"maximum_value_warning": "150",
"enabled": "support_roof_enable and support_enable",
"value": "speed_support / 1.5",
+ "global_inherits_stack": "support_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": false
}
@@ -1646,6 +1651,7 @@
"maximum_value_warning": "10000",
"default_value": 3000,
"value": "acceleration_print",
+ "global_inherits_stack": "support_extruder_nr",
"enabled": "acceleration_enabled and support_enable",
"settable_per_mesh": false,
"settable_per_extruder": false,
@@ -1657,6 +1663,7 @@
"type": "float",
"default_value": 3000,
"value": "acceleration_support",
+ "global_inherits_stack": "support_extruder_nr",
"minimum_value": "0.1",
"minimum_value_warning": "100",
"maximum_value_warning": "10000",
@@ -1671,6 +1678,7 @@
"type": "float",
"default_value": 3000,
"value": "acceleration_support",
+ "global_inherits_stack": "support_extruder_nr",
"minimum_value": "0.1",
"minimum_value_warning": "100",
"maximum_value_warning": "10000",
@@ -1834,6 +1842,7 @@
"maximum_value_warning": "50",
"default_value": 20,
"value": "jerk_print",
+ "global_inherits_stack": "support_extruder_nr",
"enabled": "jerk_enabled and support_enable",
"settable_per_mesh": false,
"settable_per_extruder": false,
@@ -1845,6 +1854,7 @@
"type": "float",
"default_value": 20,
"value": "jerk_support",
+ "global_inherits_stack": "support_extruder_nr",
"minimum_value": "0.1",
"minimum_value_warning": "5",
"maximum_value_warning": "50",
@@ -1859,6 +1869,7 @@
"type": "float",
"default_value": 20,
"value": "jerk_support",
+ "global_inherits_stack": "support_extruder_nr",
"minimum_value": "0.1",
"minimum_value_warning": "5",
"maximum_value_warning": "50",
@@ -2123,7 +2134,8 @@
"description": "Enable support structures. These structures support parts of the model with severe overhangs.",
"type": "bool",
"default_value": false,
- "settable_per_mesh": true
+ "settable_per_mesh": true,
+ "settable_per_extruder": false
},
"support_type":
{
@@ -2149,6 +2161,7 @@
"minimum_value": "0",
"maximum_value": "90",
"default_value": 50,
+ "global_inherits_stack": "support_extruder_nr",
"enabled": "support_enable",
"settable_per_mesh": true
},
@@ -2217,6 +2230,7 @@
"minimum_value": "0",
"maximum_value_warning": "10",
"default_value": 0.15,
+ "global_inherits_stack": "support_extruder_nr",
"enabled": "support_enable",
"settable_per_mesh": true,
"children":
@@ -2232,6 +2246,7 @@
"type": "float",
"enabled": "support_enable",
"value": "support_z_distance",
+ "global_inherits_stack": "support_extruder_nr",
"settable_per_mesh": true
},
"support_bottom_distance":
@@ -2243,6 +2258,7 @@
"maximum_value_warning": "10",
"default_value": 0.1,
"value": "0.1 if support_type == 'everywhere' else 0",
+ "global_inherits_stack": "support_extruder_nr",
"type": "float",
"enabled": "support_enable and support_type == 'everywhere'",
"settable_per_mesh": true
@@ -2258,6 +2274,7 @@
"minimum_value": "0",
"maximum_value_warning": "10",
"default_value": 0.7,
+ "global_inherits_stack": "support_extruder_nr",
"enabled": "support_enable",
"settable_per_mesh": true
},
@@ -2270,6 +2287,7 @@
"z_overrides_xy": "Z overrides X/Y"
},
"default_value": "z_overrides_xy",
+ "global_inherits_stack": "support_extruder_nr",
"enabled": "support_enable",
"settable_per_mesh": true
},
@@ -2282,6 +2300,7 @@
"maximum_value_warning": "10",
"default_value": 0.2,
"value": "machine_nozzle_size / 2",
+ "global_inherits_stack": "support_extruder_nr",
"enabled": "support_enable and support_xy_overrides_z=='z_overrides_xy'",
"settable_per_mesh": true
},
@@ -2292,6 +2311,7 @@
"unit": "mm",
"type": "float",
"default_value": 0.3,
+ "global_inherits_stack": "support_extruder_nr",
"minimum_value": "0",
"maximum_value_warning": "1.0",
"enabled": "support_enable",
@@ -2304,6 +2324,7 @@
"unit": "mm",
"type": "float",
"default_value": 2.0,
+ "global_inherits_stack": "support_extruder_nr",
"minimum_value_warning": "0",
"maximum_value_warning": "10",
"enabled": "support_enable",
@@ -2316,6 +2337,7 @@
"unit": "mm",
"type": "float",
"default_value": 0.2,
+ "global_inherits_stack": "support_extruder_nr",
"minimum_value_warning": "-0.5",
"maximum_value_warning": "5.0",
"enabled": "support_enable",
@@ -2328,6 +2350,7 @@
"unit": "mm",
"type": "float",
"default_value": 0.6,
+ "global_inherits_stack": "support_extruder_nr",
"minimum_value": "0",
"maximum_value_warning": "1.0",
"enabled": "support_enable",
@@ -2339,6 +2362,7 @@
"description": "Generate a dense top skin at the top of the support on which the model is printed.",
"type": "bool",
"default_value": false,
+ "global_inherits_stack": "support_extruder_nr",
"enabled": "support_enable",
"settable_per_mesh": true
},
@@ -2350,6 +2374,7 @@
"type": "float",
"default_value": 1,
"minimum_value": "0",
+ "global_inherits_stack": "support_extruder_nr",
"maximum_value_warning": "10",
"enabled": "support_roof_enable and support_enable",
"settable_per_mesh": true
@@ -2407,6 +2432,7 @@
"description": "Use specialized towers to support tiny overhang areas. These towers have a larger diameter than the region they support. Near the overhang the towers' diameter decreases, forming a roof.",
"type": "bool",
"default_value": true,
+ "global_inherits_stack": "support_extruder_nr",
"enabled": "support_enable",
"settable_per_mesh": true
},
@@ -2417,6 +2443,7 @@
"unit": "mm",
"type": "float",
"default_value": 3.0,
+ "global_inherits_stack": "support_extruder_nr",
"minimum_value": "0",
"maximum_value_warning": "10",
"enabled": "support_enable and support_use_towers",
@@ -2429,6 +2456,7 @@
"unit": "mm",
"type": "float",
"default_value": 3.0,
+ "global_inherits_stack": "support_extruder_nr",
"minimum_value": "0",
"maximum_value_warning": "10",
"maximum_value": "support_tower_diameter",
@@ -2444,6 +2472,7 @@
"minimum_value": "0",
"maximum_value": "90",
"default_value": 65,
+ "global_inherits_stack": "support_extruder_nr",
"enabled": "support_enable and support_use_towers",
"settable_per_mesh": true
}
diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml
index a7bdabb3c5..1609e30080 100644
--- a/resources/qml/Settings/SettingItem.qml
+++ b/resources/qml/Settings/SettingItem.qml
@@ -21,10 +21,12 @@ Item {
property var showRevertButton: true
property var showInheritButton: true
+ property var showLinkedSettingIcon: true
property var doDepthIndentation: true
// Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise)
property var state: propertyProvider.properties.state
+ property var settablePerExtruder: propertyProvider.properties.settable_per_extruder
property var stackLevels: propertyProvider.stackLevels
property var stackLevel: stackLevels[0]
@@ -131,6 +133,26 @@ Item {
verticalCenter: parent.verticalCenter
}
+ UM.SimpleButton
+ {
+ id: linkedSettingIcon;
+
+ visible: base.settablePerExtruder != "True" && base.showLinkedSettingIcon
+
+ height: parent.height;
+ width: height;
+
+ backgroundColor: UM.Theme.getColor("setting_control");
+ hoverBackgroundColor: UM.Theme.getColor("setting_control")
+ color: UM.Theme.getColor("setting_control_button")
+ hoverColor: UM.Theme.getColor("setting_control_button")
+
+ iconSource: UM.Theme.getIcon("link")
+
+ onEntered: { hoverTimer.stop(); base.showTooltip(catalog.i18nc("@label", "This setting is always shared between all extruders. Changing it here will change the value for all extruders")) }
+ onExited: base.showTooltip(base.tooltipText);
+ }
+
UM.SimpleButton
{
id: revertButton;
@@ -231,7 +253,6 @@ Item {
onEntered: { hoverTimer.stop(); base.showTooltip(catalog.i18nc("@label", "This setting is normally calculated, but it currently has an absolute value set.\n\nClick to restore the calculated value.")) }
onExited: base.showTooltip(base.tooltipText);
}
-
}
Item
diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml
index 39f0f833b8..957a68b94c 100644
--- a/resources/qml/Settings/SettingView.qml
+++ b/resources/qml/Settings/SettingView.qml
@@ -34,14 +34,7 @@ ScrollView
expanded: Printer.expandedCategories
onExpandedChanged: Printer.setExpandedCategories(expanded)
- filter:
- {
- if(ExtruderManager.activeExtruderStackId)
- {
- return { "settable_per_extruder": true }
- }
- return { }
- }
+ filter: {}
}
delegate: Loader
@@ -53,7 +46,15 @@ ScrollView
Behavior on height { NumberAnimation { duration: 100 } }
opacity: provider.properties.enabled == "True" ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } }
- enabled: provider.properties.enabled == "True"
+ enabled:
+ {
+ if(!ExtruderManager.activeExtruderStackId && ExtruderManager.extruderCount > 0)
+ {
+ // disable all controls on the global tab, except categories
+ return model.type == "category"
+ }
+ return provider.properties.enabled == "True"
+ }
property var definition: model
property var settingDefinitionsModel: definitionsModel
@@ -88,20 +89,59 @@ ScrollView
}
}
+ // Binding to ensure that the right containerstack ID is set for the provider.
+ // This ensures that if a setting has a global_inherits_stack id (for instance; Support speed points to the
+ // extruder that actually prints the support, as that is the setting we need to use to calculate the value)
+ Binding
+ {
+ target: provider
+ property: "containerStackId"
+ value:
+ {
+ if(inheritStackProvider.properties.global_inherits_stack == -1 || inheritStackProvider.properties.global_inherits_stack == null)
+ {
+ if( ExtruderManager.activeExtruderStackId)
+ {
+ return ExtruderManager.activeExtruderStackId
+ }
+ else
+ {
+ return Cura.MachineManager.activeMachineId
+ }
+ }
+ return ExtruderManager.extruderIds[String(inheritStackProvider.properties.global_inherits_stack)]
+ }
+ }
+
+ // Specialty provider that only watches global_inherits (we cant filter on what property changed we get events
+ // so we bypass that to make a dedicated provider.
+ UM.SettingPropertyProvider
+ {
+ id: inheritStackProvider
+ containerStackId: Cura.MachineManager.activeMachineId
+ key: model.key
+ watchedProperties: [ "global_inherits_stack"]
+ }
+
UM.SettingPropertyProvider
{
id: provider
- containerStackId: ExtruderManager.activeExtruderStackId ? ExtruderManager.activeExtruderStackId : Cura.MachineManager.activeMachineId
+ containerStackId: delegate.stackId
key: model.key ? model.key : ""
- watchedProperties: [ "value", "enabled", "state", "validationState" ]
+ watchedProperties: [ "value", "enabled", "state", "validationState", "settable_per_extruder" ]
storeIndex: 0
}
Connections
{
target: item
- onContextMenuRequested: { contextMenu.key = model.key; contextMenu.popup() }
+ onContextMenuRequested:
+ {
+ contextMenu.key = model.key;
+ contextMenu.provider = provider
+ contextMenu.popup();
+ }
onShowTooltip: base.showTooltip(delegate, { x: 0, y: delegate.height / 2 }, text)
onHideTooltip: base.hideTooltip()
}
@@ -133,9 +173,24 @@ ScrollView
Menu
{
- id: contextMenu;
+ id: contextMenu
- property string key;
+ property string key
+ property var provider
+
+ MenuItem
+ {
+ //: Settings context menu action
+ text: catalog.i18nc("@action:menu", "Copy value to all extruders")
+ visible: machineExtruderCount.properties.value > 1
+ enabled: contextMenu.provider.properties.settable_per_extruder != "False"
+ onTriggered: Cura.MachineManager.copyValueToExtruders(contextMenu.key)
+ }
+
+ MenuSeparator
+ {
+ visible: machineExtruderCount.properties.value > 1
+ }
MenuItem
{
@@ -151,5 +206,15 @@ ScrollView
onTriggered: Cura.Actions.configureSettingVisibility.trigger(contextMenu);
}
}
+
+ UM.SettingPropertyProvider
+ {
+ id: machineExtruderCount
+
+ containerStackId: Cura.MachineManager.activeMachineId
+ key: "machine_extruder_count"
+ watchedProperties: [ "value" ]
+ storeIndex: 0
+ }
}
}
diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml
index aa6f2c0067..1f7fa00b54 100644
--- a/resources/qml/SidebarHeader.qml
+++ b/resources/qml/SidebarHeader.qml
@@ -84,15 +84,15 @@ Column
orientation: ListView.Horizontal
- model: Cura.ExtrudersModel { id: extrudersModel; addGlobal: true }
+ model: Cura.ExtrudersModel { id: extrudersModel; addGlobal: false }
Connections
{
target: Cura.MachineManager
onGlobalContainerChanged:
{
- base.currentExtruderIndex = -1;
- forceActiveFocus()
+ forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values.
+ base.currentExtruderIndex = (machineExtruderCount.properties.value == 1) ? -1 : 0;
ExtruderManager.setActiveExtruderIndex(base.currentExtruderIndex);
}
}
@@ -110,7 +110,7 @@ Column
onClicked:
{
- forceActiveFocus() //Changing focus applies the currently-being-typed values so it can change the displayed setting values.
+ forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values.
base.currentExtruderIndex = index;
ExtruderManager.setActiveExtruderIndex(index);
}
@@ -258,6 +258,8 @@ Column
{
id: globalProfileSelection
text: Cura.MachineManager.activeQualityName
+ enabled: !extrudersList.visible || base.currentExtruderIndex > -1
+
width: parent.width * 0.55 + UM.Theme.getSize("default_margin").width
height: UM.Theme.getSize("setting_control").height
tooltip: Cura.MachineManager.activeQualityName
diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml
index 04b93e7d2a..0e1b04cdeb 100644
--- a/resources/qml/SidebarSimple.qml
+++ b/resources/qml/SidebarSimple.qml
@@ -19,6 +19,7 @@ Item
property Action configureSettings;
property variant minimumPrintTime: PrintInformation.minimumPrintTime;
property variant maximumPrintTime: PrintInformation.maximumPrintTime;
+ property bool settingsEnabled: ExtruderManager.activeExtruderStackId || ExtruderManager.extruderCount == 0
Component.onCompleted: PrintInformation.enabled = true
Component.onDestruction: PrintInformation.enabled = false
@@ -81,7 +82,11 @@ Item
height: width
border.color: {
- if(infillListView.activeIndex == index)
+ if(!base.settingsEnabled)
+ {
+ return UM.Theme.getColor("setting_control_disabled_border")
+ }
+ else if(infillListView.activeIndex == index)
{
return UM.Theme.getColor("setting_control_selected")
}
@@ -92,7 +97,17 @@ Item
return UM.Theme.getColor("setting_control_border")
}
border.width: UM.Theme.getSize("default_lining").width
- color: infillListView.activeIndex == index ? UM.Theme.getColor("setting_control_selected") : "transparent"
+ color: {
+ if(infillListView.activeIndex == index)
+ {
+ if(!base.settingsEnabled)
+ {
+ return UM.Theme.getColor("setting_control_disabled_text")
+ }
+ return UM.Theme.getColor("setting_control_selected")
+ }
+ return "transparent"
+ }
UM.RecolorImage {
id: infillIcon
@@ -102,13 +117,24 @@ Item
sourceSize.width: width
sourceSize.height: width
source: UM.Theme.getIcon(model.icon);
- color: (infillListView.activeIndex == index) ? UM.Theme.getColor("text_white") : UM.Theme.getColor("text")
+ color: {
+ if(infillListView.activeIndex == index)
+ {
+ return UM.Theme.getColor("text_reversed")
+ }
+ if(!base.settingsEnabled)
+ {
+ return UM.Theme.getColor("setting_control_disabled_text")
+ }
+ return UM.Theme.getColor("text")
+ }
}
MouseArea {
id: infillMouseArea
anchors.fill: parent
hoverEnabled: true
+ enabled: base.settingsEnabled
onClicked: {
if (infillListView.activeIndex != index)
{
@@ -206,6 +232,7 @@ Item
//: Setting enable skirt adhesion checkbox
text: catalog.i18nc("@option:check", "Print Brim");
style: UM.Theme.styles.checkbox;
+ enabled: base.settingsEnabled
checked: platformAdhesionType.properties.value == "brim"
@@ -213,6 +240,7 @@ Item
id: brimMouseArea
anchors.fill: parent
hoverEnabled: true
+ enabled: base.settingsEnabled
onClicked:
{
platformAdhesionType.setPropertyValue("value", !parent.checked ? "brim" : "skirt")
@@ -254,12 +282,14 @@ Item
//: Setting enable support checkbox
text: catalog.i18nc("@option:check", "Print Support Structure");
style: UM.Theme.styles.checkbox;
+ enabled: base.settingsEnabled
checked: supportEnabled.properties.value == "True"
MouseArea {
id: supportMouseArea
anchors.fill: parent
hoverEnabled: true
+ enabled: base.settingsEnabled
onClicked:
{
supportEnabled.setPropertyValue("value", !parent.checked)
@@ -288,6 +318,7 @@ Item
width: parent.width / 100 * 45
style: UM.Theme.styles.combobox
+ enabled: base.settingsEnabled
property alias _hovered: supportExtruderMouseArea.containsMouse
currentIndex: supportEnabled.properties.value == "True" ? parseFloat(supportExtruderNr.properties.value) + 1 : 0
@@ -303,6 +334,7 @@ Item
id: supportExtruderMouseArea
anchors.fill: parent
hoverEnabled: true
+ enabled: base.settingsEnabled
acceptedButtons: Qt.NoButton
onEntered:
{
@@ -382,7 +414,7 @@ Item
{
id: platformAdhesionType
- containerStackId: Cura.MachineManager.activeMachineId
+ containerStackId: Cura.MachineManager.activeStackId
key: "adhesion_type"
watchedProperties: [ "value" ]
storeIndex: 0
@@ -392,7 +424,7 @@ Item
{
id: supportEnabled
- containerStackId: Cura.MachineManager.activeMachineId
+ containerStackId: Cura.MachineManager.activeStackId
key: "support_enable"
watchedProperties: [ "value" ]
storeIndex: 0
@@ -412,7 +444,7 @@ Item
{
id: supportExtruderNr
- containerStackId: Cura.MachineManager.activeMachineId
+ containerStackId: Cura.MachineManager.activeStackId
key: "support_extruder_nr"
watchedProperties: [ "value" ]
storeIndex: 0
diff --git a/resources/themes/cura/icons/link.svg b/resources/themes/cura/icons/link.svg
new file mode 100644
index 0000000000..7cc2778846
--- /dev/null
+++ b/resources/themes/cura/icons/link.svg
@@ -0,0 +1,43 @@
+
+
\ No newline at end of file
diff --git a/resources/themes/cura/icons/reset.svg b/resources/themes/cura/icons/reset.svg
index fae303d2a1..4772d446d7 100644
--- a/resources/themes/cura/icons/reset.svg
+++ b/resources/themes/cura/icons/reset.svg
@@ -27,10369 +27,4 @@
c-1.128,0.65-2.448,0.967-3.679,1.439C-0.113,107.552-0.113,69.744-0.113,31.935z"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/resources/themes/cura/theme.json b/resources/themes/cura/theme.json
index 053e5e3d84..69fc2c2c71 100644
--- a/resources/themes/cura/theme.json
+++ b/resources/themes/cura/theme.json
@@ -56,7 +56,7 @@
"text_inactive": [174, 174, 174, 255],
"text_hover": [70, 84, 113, 255],
"text_pressed": [12, 169, 227, 255],
- "text_white": [255, 255, 255, 255],
+ "text_reversed": [255, 255, 255, 255],
"text_subtext": [70, 84, 113, 255],
"error": [255, 140, 0, 255],