Merge branch '2.7_stack_context' of github.com:Ultimaker/Cura into 2.7

This commit is contained in:
Jaime van Kessel 2017-08-28 16:05:59 +02:00
commit 8a0f6d969e
6 changed files with 135 additions and 43 deletions

View File

@ -7,7 +7,7 @@ from UM.Decorators import override
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
from UM.Settings.ContainerStack import ContainerStack from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.Interfaces import ContainerInterface from UM.Settings.Interfaces import ContainerInterface, PropertyEvaluationContext
from . import Exceptions from . import Exceptions
from .CuraContainerStack import CuraContainerStack from .CuraContainerStack import CuraContainerStack
@ -57,21 +57,32 @@ class ExtruderStack(CuraContainerStack):
# \throws Exceptions.NoGlobalStackError Raised when trying to get a property from an extruder without # \throws Exceptions.NoGlobalStackError Raised when trying to get a property from an extruder without
# having a next stack set. # having a next stack set.
@override(ContainerStack) @override(ContainerStack)
def getProperty(self, key: str, property_name: str) -> Any: def getProperty(self, key: str, property_name: str, context: Optional[PropertyEvaluationContext] = None) -> Any:
if not self._next_stack: if not self._next_stack:
raise Exceptions.NoGlobalStackError("Extruder {id} is missing the next stack!".format(id = self.id)) raise Exceptions.NoGlobalStackError("Extruder {id} is missing the next stack!".format(id = self.id))
if not super().getProperty(key, "settable_per_extruder"): if context is None:
return self.getNextStack().getProperty(key, property_name) context = PropertyEvaluationContext()
context.pushContainer(self)
limit_to_extruder = super().getProperty(key, "limit_to_extruder") if not super().getProperty(key, "settable_per_extruder", context):
if (limit_to_extruder is not None and limit_to_extruder != "-1") and self.getMetaDataEntry("position") != str(limit_to_extruder): result = self.getNextStack().getProperty(key, property_name, context)
if str(limit_to_extruder) in self.getNextStack().extruders: context.popContainer()
result = self.getNextStack().extruders[str(limit_to_extruder)].getProperty(key, property_name)
if result is not None:
return result return result
return super().getProperty(key, property_name) limit_to_extruder = super().getProperty(key, "limit_to_extruder", context)
if limit_to_extruder is not None:
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)
if result is not None:
context.popContainer()
return result
result = super().getProperty(key, property_name, context)
context.popContainer()
return result
@override(CuraContainerStack) @override(CuraContainerStack)
def _getMachineDefinition(self) -> ContainerInterface: def _getMachineDefinition(self) -> ContainerInterface:

View File

@ -11,6 +11,7 @@ from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
from UM.Settings.ContainerStack import ContainerStack from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.SettingInstance import InstanceState from UM.Settings.SettingInstance import InstanceState
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.Interfaces import PropertyEvaluationContext
from UM.Logger import Logger from UM.Logger import Logger
from . import Exceptions from . import Exceptions
@ -91,29 +92,38 @@ class GlobalStack(CuraContainerStack):
# #
# \return The value of the property for the specified setting, or None if not found. # \return The value of the property for the specified setting, or None if not found.
@override(ContainerStack) @override(ContainerStack)
def getProperty(self, key: str, property_name: str) -> Any: def getProperty(self, key: str, property_name: str, context: Optional[PropertyEvaluationContext] = None) -> Any:
if not self.definition.findDefinitions(key = key): if not self.definition.findDefinitions(key = key):
return None return None
# Handle the "resolve" property. # Handle the "resolve" property.
if self._shouldResolve(key, property_name): if self._shouldResolve(key, property_name):
self._resolving_settings.add(key) self._resolving_settings.add(key)
resolve = super().getProperty(key, "resolve") resolve = super().getProperty(key, "resolve", context)
self._resolving_settings.remove(key) self._resolving_settings.remove(key)
if resolve is not None: if resolve is not None:
return resolve return resolve
if context is None:
context = PropertyEvaluationContext()
context.pushContainer(self)
# Handle the "limit_to_extruder" property. # Handle the "limit_to_extruder" property.
limit_to_extruder = super().getProperty(key, "limit_to_extruder") limit_to_extruder = super().getProperty(key, "limit_to_extruder", context)
if limit_to_extruder is not None:
limit_to_extruder = str(limit_to_extruder)
if limit_to_extruder is not None and limit_to_extruder != "-1" and limit_to_extruder in self._extruders: if limit_to_extruder is not None and limit_to_extruder != "-1" and limit_to_extruder in self._extruders:
if super().getProperty(key, "settable_per_extruder"): if super().getProperty(key, "settable_per_extruder", context):
result = self._extruders[str(limit_to_extruder)].getProperty(key, property_name) result = self._extruders[str(limit_to_extruder)].getProperty(key, property_name, context)
if result is not None: if result is not None:
context.popContainer()
return result return result
else: else:
Logger.log("e", "Setting {setting} has limit_to_extruder but is not settable per extruder!", setting = key) Logger.log("e", "Setting {setting} has limit_to_extruder but is not settable per extruder!", setting = key)
return super().getProperty(key, property_name) result = super().getProperty(key, property_name, context)
context.popContainer()
return result
## Overridden from ContainerStack ## Overridden from ContainerStack
# #

View File

@ -0,0 +1,65 @@
from typing import Any, Optional
from UM.Application import Application
from UM.Decorators import override
from UM.Settings.Interfaces import PropertyEvaluationContext
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.SettingInstance import InstanceState
class PerObjectContainerStack(ContainerStack):
@override(ContainerStack)
def getProperty(self, key: str, property_name: str, context: Optional[PropertyEvaluationContext] = None) -> Any:
if context is None:
context = PropertyEvaluationContext()
context.pushContainer(self)
global_stack = Application.getInstance().getGlobalContainerStack()
# Return the user defined value if present, otherwise, evaluate the value according to the default routine.
if self.getContainer(0).hasProperty(key, property_name):
if self.getContainer(0)._instances[key].state == InstanceState.User:
result = super().getProperty(key, property_name, context)
context.popContainer()
return result
# Handle the "limit_to_extruder" property.
limit_to_extruder = super().getProperty(key, "limit_to_extruder", context)
if limit_to_extruder is not None:
limit_to_extruder = str(limit_to_extruder)
# if this stack has the limit_to_extruder "not overriden", use the original limit_to_extruder as the current
# limit_to_extruder, so the values retrieved will be from the perspective of the original limit_to_extruder
# stack.
if limit_to_extruder == "-1":
if "original_limit_to_extruder" in context.context:
limit_to_extruder = context.context["original_limit_to_extruder"]
if limit_to_extruder is not None and limit_to_extruder != "-1" and limit_to_extruder in global_stack.extruders:
# set the original limit_to_extruder if this is the first stack that has a non-overriden limit_to_extruder
if "original_limit_to_extruder" not in context.context:
context.context["original_limit_to_extruder"] = limit_to_extruder
if super().getProperty(key, "settable_per_extruder", context):
result = global_stack.extruders[str(limit_to_extruder)].getProperty(key, property_name, context)
if result is not None:
context.popContainer()
return result
result = super().getProperty(key, property_name, context)
context.popContainer()
return result
@override(ContainerStack)
def setNextStack(self, stack: ContainerStack):
super().setNextStack(stack)
# trigger signal to re-evaluate all default settings
for key, instance in self.getContainer(0)._instances.items():
# only evaluate default settings
if instance.state != InstanceState.Default:
continue
self._collectPropertyChanges(key, "value")
self._emitCollectedPropertyChanges()

View File

@ -5,13 +5,13 @@ import copy
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
from UM.Signal import Signal, signalemitter from UM.Signal import Signal, signalemitter
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.InstanceContainer import InstanceContainer
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Logger import Logger from UM.Logger import Logger
from UM.Application import Application from UM.Application import Application
from cura.Settings.PerObjectContainerStack import PerObjectContainerStack
from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.ExtruderManager import ExtruderManager
## A decorator that adds a container stack to a Node. This stack should be queried for all settings regarding ## A decorator that adds a container stack to a Node. This stack should be queried for all settings regarding
@ -24,7 +24,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self._stack = ContainerStack(stack_id = id(self)) self._stack = PerObjectContainerStack(stack_id = id(self))
self._stack.setDirty(False) # This stack does not need to be saved. self._stack.setDirty(False) # This stack does not need to be saved.
self._stack.addContainer(InstanceContainer(container_id = "SettingOverrideInstanceContainer")) self._stack.addContainer(InstanceContainer(container_id = "SettingOverrideInstanceContainer"))

View File

@ -135,6 +135,8 @@ Item {
} }
} }
// 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 UM.SettingPropertyProvider
{ {
id: provider id: provider
@ -146,8 +148,6 @@ Item {
removeUnusedValue: false removeUnusedValue: false
} }
// 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 UM.SettingPropertyProvider
{ {
id: inheritStackProvider id: inheritStackProvider
@ -156,36 +156,42 @@ Item {
watchedProperties: [ "limit_to_extruder" ] watchedProperties: [ "limit_to_extruder" ]
} }
Binding Connections
{ {
target: provider target: inheritStackProvider
property: "containerStackId" onPropertiesChanged:
when: model.settable_per_extruder || (inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0);
value:
{ {
// associate this binding with Cura.MachineManager.activeMachineId in the beginning so this provider.forcePropertiesChanged();
// binding will be triggered when activeMachineId is changed too. }
// Otherwise, if this value only depends on the extruderIds, it won't get updated when the }
// machine gets changed.
var activeMachineId = Cura.MachineManager.activeMachineId;
if(!model.settable_per_extruder || machineExtruderCount.properties.value == 1) Connections
{ {
//Not settable per extruder or there only is global, so we must pick global. target: UM.ActiveTool
return activeMachineId; onPropertiesChanged:
}
if(inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0)
{ {
//We have limit_to_extruder, so pick that stack. // the values cannot be bound with UM.ActiveTool.properties.getValue() calls,
return ExtruderManager.extruderIds[String(inheritStackProvider.properties.limit_to_extruder)]; // so here we connect to the signal and update the those values.
} if (typeof UM.ActiveTool.properties.getValue("SelectedObjectId") !== "undefined")
if(UM.ActiveTool.properties.getValue("ContainerID"))
{ {
//We're on an extruder tab. Pick the current extruder. const selectedObjectId = UM.ActiveTool.properties.getValue("SelectedObjectId");
return UM.ActiveTool.properties.getValue("ContainerID"); if (addedSettingsModel.visibilityHandler.selectedObjectId != selectedObjectId)
{
addedSettingsModel.visibilityHandler.selectedObjectId = selectedObjectId;
}
}
if (typeof UM.ActiveTool.properties.getValue("ContainerID") !== "undefined")
{
const containerId = UM.ActiveTool.properties.getValue("ContainerID");
if (provider.containerStackId != containerId)
{
provider.containerStackId = containerId;
}
if (inheritStackProvider.containerStackId != containerId)
{
inheritStackProvider.containerStackId = containerId;
}
} }
//No extruder tab is selected. Pick the global stack. Shouldn't happen any more since we removed the global tab.
return activeMachineId;
} }
} }
} }

View File

@ -142,7 +142,7 @@ Item {
{ {
id: linkedSettingIcon; id: linkedSettingIcon;
visible: Cura.MachineManager.activeStackId != Cura.MachineManager.activeMachineId && (!definition.settable_per_extruder || globalPropertyProvider.properties.limit_to_extruder != "-1") && base.showLinkedSettingIcon visible: Cura.MachineManager.activeStackId != Cura.MachineManager.activeMachineId && (!definition.settable_per_extruder || String(globalPropertyProvider.properties.limit_to_extruder) != "-1") && base.showLinkedSettingIcon
height: parent.height; height: parent.height;
width: height; width: height;
@ -222,7 +222,7 @@ Item {
} }
// If the setting does not have a limit_to_extruder property (or is -1), use the active stack. // If the setting does not have a limit_to_extruder property (or is -1), use the active stack.
if(globalPropertyProvider.properties.limit_to_extruder == null || globalPropertyProvider.properties.limit_to_extruder == -1) if(globalPropertyProvider.properties.limit_to_extruder == null || String(globalPropertyProvider.properties.limit_to_extruder) == "-1")
{ {
return Cura.SettingInheritanceManager.settingsWithInheritanceWarning.indexOf(definition.key) >= 0; return Cura.SettingInheritanceManager.settingsWithInheritanceWarning.indexOf(definition.key) >= 0;
} }
@ -232,7 +232,7 @@ Item {
// Observed when loading workspace, probably when SettingItems are removed. // Observed when loading workspace, probably when SettingItems are removed.
return false; return false;
} }
return Cura.SettingInheritanceManager.getOverridesForExtruder(definition.key, globalPropertyProvider.properties.limit_to_extruder).indexOf(definition.key) >= 0; return Cura.SettingInheritanceManager.getOverridesForExtruder(definition.key, String(globalPropertyProvider.properties.limit_to_extruder)).indexOf(definition.key) >= 0;
} }
height: parent.height; height: parent.height;