Cura/cura/Settings/GlobalStack.py
Arjen Hiemstra 462d5fac8d Add setters for properties
Contributes to CURA-3497
2017-03-23 17:55:21 +01:00

156 lines
5.7 KiB
Python

# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
from PyQt5.QtCore import pyqtProperty, pyqtSlot
from UM.Decorators import override
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
from UM.Settings.ContainerStack import ContainerStack, InvalidContainerStackError
from UM.Settings.InstanceContainer import InstanceContainer
from UM.Settings.DefinitionContainer import DefinitionContainer
from UM.Settings.ContainerRegistry import ContainerRegistry
from . import Exceptions
class GlobalStack(ContainerStack):
def __init__(self, container_id: str, *args, **kwargs):
super().__init__(container_id, *args, **kwargs)
self._empty_instance_container = ContainerRegistry.getInstance().getEmptyInstanceContainer()
@pyqtProperty(InstanceContainer)
def userChanges(self) -> InstanceContainer:
return self._containers[_ContainerIndexes.UserChanges]
def setQualtiyChanges(self, new_quality_changes: InstanceContainer) -> None:
self.replaceContainer(_ContainerIndexes.QualityChanges, new_quality_changes)
@pyqtProperty(InstanceContainer)
def qualityChanges(self) -> InstanceContainer:
return self._containers[_ContainerIndexes.QualityChanges]
def setQuality(self, new_quality: InstanceContainer) -> None:
self.replaceContainer(_ContainerIndexes.Quality, new_quality)
@pyqtProperty(InstanceContainer)
def quality(self) -> InstanceContainer:
return self._containers[_ContainerIndexes.Quality]
def setMaterial(self, new_material: InstanceContainer) -> None:
self.replaceContainer(_ContainerIndexes.Material, new_material)
@pyqtProperty(InstanceContainer)
def material(self) -> InstanceContainer:
return self._containers[_ContainerIndexes.Material]
def setVariant(self, new_variant: InstanceContainer) -> None:
self.replaceContainer(_ContainerIndexes.Variant, new_variant)
@pyqtProperty(InstanceContainer)
def variant(self) -> InstanceContainer:
return self._containers[_ContainerIndexes.Variant]
@pyqtProperty(InstanceContainer)
def definitionChanges(self) -> InstanceContainer:
return self._containers[_ContainerIndexes.DefinitionChanges]
@pyqtProperty(DefinitionContainer)
def definition(self) -> DefinitionContainer:
return self._containers[_ContainerIndexes.Definition]
## Check whether the specified setting has a 'user' value.
#
# A user value here is defined as the setting having a value in either
# the UserChanges or QualityChanges container.
#
# \return True if the setting has a user value, False if not.
@pyqtSlot(str, result = bool)
def hasUserValue(self, key: str) -> bool:
if self._containers[_ContainerIndexes.UserChanges].hasProperty(key, "value"):
return True
if self._containers[_ContainerIndexes.QualityChanges].hasProperty(key, "value"):
return True
return False
## Overridden from ContainerStack
@override(ContainerStack)
def getProperty(self, key: str, property_name: str):
if property_name == "value":
if not self.hasUserValue(key):
resolve = super().getProperty(key, "resolve")
if resolve:
return resolve
return super().getProperty(key, property_name)
## Overridden from ContainerStack
@override(ContainerStack)
def setNextStack(self, next_stack: ContainerStack) -> None:
raise Exceptions.InvalidOperationError("Global stack cannot have a next stack!")
## Overridden from ContainerStack
@override(ContainerStack)
def deserialize(self, contents: str) -> None:
super().deserialize(contents)
new_containers = self._containers.copy()
while(len(new_containers) < len(_ContainerIndexes.IndexTypeMap)):
new_containers.append(self._empty_instance_container)
# Validate and ensure the list of containers matches with what we expect
for index, type_name in _ContainerIndexes.IndexTypeMap.items():
try:
container = new_containers[index]
except IndexError:
container = None
if type_name == "definition":
if not container or not isinstance(container, DefinitionContainer):
definition = self.findContainer(container_type = DefinitionContainer, category = "*")
if not definition:
raise InvalidContainerStackError("Stack {id} does not have a definition!".format(id = self._id))
new_containers[index] = definition
continue
if not container or container.getMetaDataEntry("type") != type_name:
actual_container = self.findContainer(type = type_name)
if actual_container:
new_containers[index] = actual_container
self._containers = new_containers
## private:
global_stack_mime = MimeType(
name = "application/x-cura-globalstack",
comment = "Cura Global Stack",
suffixes = [ "global.cfg" ]
)
MimeTypeDatabase.addMimeType(global_stack_mime)
ContainerRegistry.addContainerTypeByName(GlobalStack, "global_stack", global_stack_mime.name)
class _ContainerIndexes:
UserChanges = 0
QualityChanges = 1
Quality = 2
Material = 3
Variant = 4
DefinitionChanges = 5
Definition = 6
# Simple hash map to map from index to "type" metadata entry
IndexTypeMap = {
UserChanges: "user",
QualityChanges: "quality_changes",
Quality: "quality",
Material: "material",
Variant: "variant",
DefinitionChanges: "definition_changes",
Definition: "definition",
}