Cura/plugins/PerObjectSettingsTool/SettingOverrideModel.py
Ghostkeeper 64aa977696 Properly update global_only on profile switch
In the setting override model for per-object settings now gets its global_only property also updated on a profile switch. This is needed because the settings also change during a profile switch but the change event is not triggered.

Contributes to issue CURA-458.
2016-02-24 13:05:52 +01:00

137 lines
5.8 KiB
Python

# Copyright (c) 2015 Ultimaker B.V.
# Uranium is released under the terms of the AGPLv3 or higher.
from PyQt5.QtCore import Qt, pyqtSlot, QUrl
from UM.Application import Application
from UM.Qt.ListModel import ListModel
from UM.Settings.SettingOverrideDecorator import SettingOverrideDecorator
class SettingOverrideModel(ListModel):
KeyRole = Qt.UserRole + 1
LabelRole = Qt.UserRole + 2
DescriptionRole = Qt.UserRole + 3
ValueRole = Qt.UserRole + 4
TypeRole = Qt.UserRole + 5
UnitRole = Qt.UserRole + 6
ValidRole = Qt.UserRole + 7
OptionsRole = Qt.UserRole + 8
WarningDescriptionRole = Qt.UserRole + 9
ErrorDescriptionRole = Qt.UserRole + 10
GlobalOnlyRole = Qt.UserRole + 11
def __init__(self, node, parent = None):
super().__init__(parent)
self._ignore_setting_change = None
self._node = node
self._node.decoratorsChanged.connect(self._onDecoratorsChanged)
self._onDecoratorsChanged(None)
self._activeProfile = Application.getInstance().getMachineManager().getWorkingProfile() #To be able to get notified when a setting changes.
self._activeProfile.settingValueChanged.connect(self._onProfileSettingValueChanged)
Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onProfileChanged)
self.addRoleName(self.KeyRole, "key")
self.addRoleName(self.LabelRole, "label")
self.addRoleName(self.DescriptionRole, "description")
self.addRoleName(self.ValueRole,"value")
self.addRoleName(self.TypeRole, "type")
self.addRoleName(self.UnitRole, "unit")
self.addRoleName(self.ValidRole, "valid")
self.addRoleName(self.OptionsRole, "options")
self.addRoleName(self.WarningDescriptionRole, "warning_description")
self.addRoleName(self.ErrorDescriptionRole, "error_description")
self.addRoleName(self.GlobalOnlyRole, "global_only")
@pyqtSlot(str, "QVariant")
def setSettingValue(self, key, value):
if not self._decorator:
return
self._decorator.setSettingValue(key, value)
def _onDecoratorsChanged(self, node):
if not self._node.getDecorator(SettingOverrideDecorator):
self.clear()
return
self._decorator = self._node.getDecorator(SettingOverrideDecorator)
self._decorator.settingAdded.connect(self._onSettingsChanged)
self._decorator.settingRemoved.connect(self._onSettingsChanged)
self._decorator.settingValueChanged.connect(self._onSettingValueChanged)
self._onSettingsChanged()
def _createOptionsModel(self, options):
if not options:
return None
model = ListModel()
model.addRoleName(Qt.UserRole + 1, "value")
model.addRoleName(Qt.UserRole + 2, "name")
for value, name in options.items():
model.appendItem({"value": str(value), "name": str(name)})
return model
## Updates the active profile in this model if the active profile is
# changed.
#
# This links the settingValueChanged of the new profile to this model's
# _onSettingValueChanged function, so that it properly listens to those
# events again.
def _onProfileChanged(self):
if self._activeProfile: #Unlink from the old profile.
self._activeProfile.settingValueChanged.disconnect(self._onProfileSettingValueChanged)
old_profile = self._activeProfile
self._activeProfile = Application.getInstance().getMachineManager().getWorkingProfile()
self._activeProfile.settingValueChanged.connect(self._onProfileSettingValueChanged) #Re-link to the new profile.
for setting_name in old_profile.getChangedSettings().keys(): #Update all changed settings in the old and new profiles.
self._onProfileSettingValueChanged(setting_name)
for setting_name in self._activeProfile.getChangedSettings().keys():
self._onProfileSettingValueChanged(setting_name)
## Updates the global_only property of a setting once a setting value
# changes.
#
# This method should only get called on settings that are dependent on the
# changed setting.
#
# \param setting_name The setting that needs to be updated.
def _onProfileSettingValueChanged(self, setting_name):
index = self.find("key", setting_name)
if index != -1:
self.setProperty(index, "global_only", Application.getInstance().getMachineManager().getActiveMachineInstance().getMachineDefinition().getSetting(setting_name).getGlobalOnly())
def _onSettingsChanged(self):
self.clear()
items = []
for key, setting in self._decorator.getAllSettings().items():
value = self._decorator.getSettingValue(key)
items.append({
"key": key,
"label": setting.getLabel(),
"description": setting.getDescription(),
"value": str(value),
"type": setting.getType(),
"unit": setting.getUnit(),
"valid": setting.validate(value),
"options": self._createOptionsModel(setting.getOptions()),
"warning_description": setting.getWarningDescription(),
"error_description": setting.getErrorDescription(),
"global_only": setting.getGlobalOnly()
})
items.sort(key = lambda i: i["key"])
for item in items:
self.appendItem(item)
def _onSettingValueChanged(self, setting):
index = self.find("key", setting.getKey())
value = self._decorator.getSettingValue(setting.getKey())
if index != -1:
self.setProperty(index, "value", str(value))
self.setProperty(index, "valid", setting.validate(value))
self.setProperty(index, "global_only", setting.getGlobalOnly())