Skip to content

Commit

Permalink
For cross-stack relations, signal changed properties globally.
Browse files Browse the repository at this point in the history
If a setting depends on a setting that is somehow in another stack (or another part of the global tree), as signalled by 'force_depends_on_settings' (renamed from 'depends_on_settings', as that'd imply you should _always_ add it), use the global container stack instead of the 'local' one (which'd only contain the setting-instances for that stack, not the actual relation _should_ it reside in another part of the currently active machine containers).

This can happen for instance in a dependee like Cura, which has machines with different extruders, and if a setting is locked to an extruder with 'limit_to_extruder', a setting using a formula using such a setting should be updated from what may potentially be the an other extruders' stack.

CURA-12050
  • Loading branch information
rburema committed Jul 30, 2024
1 parent 2d191d9 commit 7a180ab
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 4 deletions.
2 changes: 1 addition & 1 deletion UM/Settings/DefinitionContainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ def _processFunction(self, definition: SettingDefinition, property_name: str) ->
settings_dependencies.update(function.getUsedSettingKeys())

try:
settings_dependencies.update(definition.depends_on_settings)
settings_dependencies.update(definition.force_depends_on_settings)
except AttributeError:
pass

Expand Down
2 changes: 1 addition & 1 deletion UM/Settings/SettingDefinition.py
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ def _updateDescendants(self, definition: "SettingDefinition" = None) -> Dict[str
# For bool type: if the value is the same as the error value, the setting will be in the error state.
"error_value": {"type": DefinitionPropertyType.Function, "required": False, "read_only": True, "default": None, "depends_on": None},
# Optional list of settings that a setting explicitely depends on, which is useful when this can not be fully calculated from the formula.
"depends_on_settings": {"type": DefinitionPropertyType.Any, "required": False, "read_only": True, "default": [], "depends_on": None},
"force_depends_on_settings": {"type": DefinitionPropertyType.Any, "required": False, "read_only": True, "default": [], "depends_on": None},
} # type: Dict[str, Dict[str, Any]]

__type_definitions = {
Expand Down
11 changes: 9 additions & 2 deletions UM/Settings/SettingInstance.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ def updateRelations(self, container: ContainerInterface, emit_signals: bool = Tr
property_names.remove("value") # Move "value" to the front of the list so we always update that first.
property_names.insert(0, "value")

# Note: The global stack is only used in case of cross-stack relations ('force_depends_on_settings'), see below.
from UM.Application import Application
global_stack_container = Application.getInstance().getGlobalContainerStack()

for property_name in property_names:
if SettingDefinition.isReadOnlyProperty(property_name):
continue
Expand All @@ -246,10 +250,13 @@ def updateRelations(self, container: ContainerInterface, emit_signals: bool = Tr
SettingInstance._listRelations(self.definition.key, changed_relations, self._definition.relations, [property_name])

for relation in changed_relations:
container.propertyChanged.emit(relation.target.key, relation.role)
used_container = container
if self.definition.key in relation.target.force_depends_on_settings:
used_container = global_stack_container
used_container.propertyChanged.emit(relation.target.key, relation.role)
# If the value/minimum value/etc state is updated, the validation state must be re-evaluated
if relation.role in {"value", "minimum_value", "maximum_value", "minimum_value_warning", "maximum_value_warning"}:
container.propertyChanged.emit(relation.target.key, "validationState")
used_container.propertyChanged.emit(relation.target.key, "validationState")

@staticmethod
def _listRelations(key: str, relations_set: Set["SettingRelation"], relations: List["SettingRelation"], roles: List[str]) -> None:
Expand Down
1 change: 1 addition & 0 deletions examples/definition_query/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Any, default = True, read_only = True)
SettingDefinition.addSupportedProperty("settable_per_meshgroup", DefinitionPropertyType.Any, default = True, read_only = True)
SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Any, default = True, read_only = True)
SettingDefinition.addSupportedProperty("force_depends_on_settings", DefinitionPropertyType.Any, default = [], read_only = True)
SettingDefinition.addSupportedProperty("limit_to_extruder", DefinitionPropertyType.Function, default = "-1")
SettingDefinition.addSupportedProperty("resolve", DefinitionPropertyType.Function, default = None)
SettingDefinition.addSettingType("extruder", None, str, Validator)
Expand Down

0 comments on commit 7a180ab

Please sign in to comment.