# UNDF: UNDF-2026-000001206 --- a/cura/Settings/SettingInheritanceManager.py +++ b/cura/Settings/SettingInheritanceManager.py @@ -1,6 +1,6 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import List, Optional, Set, TYPE_CHECKING +from typing import List, Optional, Set, TYPE_CHECKING, cast from PyQt6.QtCore import QObject, QTimer, pyqtProperty, pyqtSignal from UM.FlameProfiler import pyqtSlot @@ -29,7 +29,9 @@ class SettingInheritanceManager(QObject): def __init__(self, parent = None) -> None: super().__init__(parent) self._global_container_stack = None # type: Optional[ContainerStack] - self._settings_with_inheritance_warning = [] # type: List[str] + # Use a set for O(1) membership checks — fired on every property change. + self._settings_with_inheritance_warning = set() # type: Set[str] self._active_container_stack = None # type: Optional[ExtruderStack] self._update_timer = QTimer() @@ -57,7 +59,7 @@ class SettingInheritanceManager(QObject): result = [] for key in definitions[0].getAllKeys(): if key in self._settings_with_inheritance_warning: result.append(key) return result @pyqtSlot(str, str, result = bool) @@ -87,19 +89,19 @@ class SettingInheritanceManager(QObject): @pyqtSlot(str) def manualRemoveOverride(self, key: str) -> None: - if key in self._settings_with_inheritance_warning: - self._settings_with_inheritance_warning.remove(key) + if key in self._settings_with_inheritance_warning: # O(1) set lookup + self._settings_with_inheritance_warning.discard(key) self.settingsWithIntheritanceChanged.emit() @pyqtProperty("QVariantList", notify = settingsWithIntheritanceChanged) def settingsWithInheritanceWarning(self) -> List[str]: - return self._settings_with_inheritance_warning + return list(self._settings_with_inheritance_warning) def _onPropertyChanged(self, key: str, property_name: str) -> None: if (property_name == "value" or property_name == "enabled") and self._global_container_stack: definitions = self._global_container_stack.definition.findDefinitions(key = key) # type: List["SettingDefinition"] if not definitions: return has_overwritten_inheritance = self._settingIsOverwritingInheritance(key) settings_with_inheritance_warning_changed = False # Check if the setting needs to be in the list. - if key not in self._settings_with_inheritance_warning and has_overwritten_inheritance: - self._settings_with_inheritance_warning.append(key) + if has_overwritten_inheritance: + added = key not in self._settings_with_inheritance_warning + self._settings_with_inheritance_warning.add(key) # O(1) no-op if present settings_with_inheritance_warning_changed = True - elif key in self._settings_with_inheritance_warning and not has_overwritten_inheritance: - self._settings_with_inheritance_warning.remove(key) + elif not has_overwritten_inheritance and key in self._settings_with_inheritance_warning: + self._settings_with_inheritance_warning.discard(key) # O(1) remove settings_with_inheritance_warning_changed = True parent = definitions[0].parent @@ -110,12 +112,12 @@ class SettingInheritanceManager(QObject): else: parent = definitions[0] # Already at a category - if parent.key not in self._settings_with_inheritance_warning and has_overwritten_inheritance: + if has_overwritten_inheritance and parent.key not in self._settings_with_inheritance_warning: # Category was not in the list yet, so needs to be added now. - self._settings_with_inheritance_warning.append(parent.key) + self._settings_with_inheritance_warning.add(parent.key) # O(1) settings_with_inheritance_warning_changed = True - elif parent.key in self._settings_with_inheritance_warning and not has_overwritten_inheritance: + elif not has_overwritten_inheritance and parent.key in self._settings_with_inheritance_warning: # Category was in the list and one of it's settings is not overwritten. if not self._recursiveCheck(parent): # Check if any of it's children have overwritten inheritance. - self._settings_with_inheritance_warning.remove(parent.key) + self._settings_with_inheritance_warning.discard(parent.key) # O(1) settings_with_inheritance_warning_changed = True # Emit the signal if there was any change to the list. @@ -140,7 +142,7 @@ class SettingInheritanceManager(QObject): def _update(self) -> None: - self._settings_with_inheritance_warning = [] # Reset previous data. + self._settings_with_inheritance_warning = set() # Reset previous data. # Make sure that the GlobalStack is not None. sometimes the globalContainerChanged signal gets here late. if self._global_container_stack is None or self._active_container_stack is None: @@ -151,13 +153,13 @@ class SettingInheritanceManager(QObject): all_keys = self._active_container_stack.getAllKeys() for setting_key in self._active_container_stack.getAllKeysWithUserState(): if self._userSettingIsOverwritingInheritance(setting_key, self._active_container_stack, all_keys): - self._settings_with_inheritance_warning.append(setting_key) + self._settings_with_inheritance_warning.add(setting_key) # O(1) insert # Check all the categories if any of their children have their inheritance overwritten. for category in self._global_container_stack.definition.findDefinitions(type = "category"): if self._recursiveCheck(category): - self._settings_with_inheritance_warning.append(category.key) + self._settings_with_inheritance_warning.add(category.key) # O(1) insert, dedup free # Notify others that things have changed. self.settingsWithIntheritanceChanged.emit()