From 98688bf0133daf380e06e792cb9a7ed6bf9e6e49 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 19 Oct 2016 15:46:22 +0200 Subject: [PATCH 1/2] Changed MachineManager.isActiveStackValid to MachineManager.areStacksValid. CURA-2730 --- cura/Settings/MachineManager.py | 63 ++++++++++++++-------- plugins/CuraEngineBackend/StartSliceJob.py | 2 +- resources/qml/Actions.qml | 4 +- resources/qml/Preferences/ProfilesPage.qml | 2 +- 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 0028ace4cd..4d4deddb68 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -34,7 +34,7 @@ class MachineManager(QObject): self.globalContainerChanged.connect(self.activeVariantChanged) self.globalContainerChanged.connect(self.activeQualityChanged) - self._active_stack_valid = None + self._stacks_valid = None self._onGlobalContainerChanged() ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) @@ -85,6 +85,7 @@ class MachineManager(QObject): globalValueChanged = pyqtSignal() # Emitted whenever a value inside global container is changed. activeStackValueChanged = pyqtSignal() # Emitted whenever a value inside the active stack is changed. activeStackValidationChanged = pyqtSignal() # Emitted whenever a validation inside active container is changed + stacksValidationChanged = pyqtSignal() # Emitted whenever a validation is changed blurSettings = pyqtSignal() # Emitted to force fields in the advanced sidebar to un-focus, so they update properly @@ -231,6 +232,13 @@ class MachineManager(QObject): quality = self._global_container_stack.findContainer({"type": "quality"}) quality.nameChanged.connect(self._onQualityNameChanged) + ## Update self._stacks_valid according to _checkStacksForErrors and emit if change. + def _updateStacksValid(self): + old_stacks_valid = self._stacks_valid + self._stacks_valid = self._checkStacksValid() + if old_stacks_valid != self._stacks_valid: + self.stacksValidationChanged.emit() + def _onActiveExtruderStackChanged(self): self.blurSettings.emit() # Ensure no-one has focus. @@ -246,10 +254,7 @@ class MachineManager(QObject): else: self._active_container_stack = self._global_container_stack - old_active_stack_valid = self._active_stack_valid - self._active_stack_valid = not self._checkStackForErrors(self._active_container_stack) - if old_active_stack_valid != self._active_stack_valid: - self.activeStackValidationChanged.emit() + self._updateStacksValid() if old_active_container_stack != self._active_container_stack: # Many methods and properties related to the active quality actually depend @@ -272,18 +277,18 @@ class MachineManager(QObject): self.activeStackValueChanged.emit() if property_name == "validationState": - if self._active_stack_valid: + if self._stacks_valid: + # fast update, we only have to look at the current changed property if self._active_container_stack.getProperty(key, "settable_per_extruder"): changed_validation_state = self._active_container_stack.getProperty(key, property_name) else: changed_validation_state = self._global_container_stack.getProperty(key, property_name) if changed_validation_state in (UM.Settings.ValidatorState.Exception, UM.Settings.ValidatorState.MaximumError, UM.Settings.ValidatorState.MinimumError): - self._active_stack_valid = False - self.activeStackValidationChanged.emit() + self._stacks_valid = False + self.stacksValidationChanged.emit() else: - if not self._checkStackForErrors(self._active_container_stack) and not self._checkStackForErrors(self._global_container_stack): - self._active_stack_valid = True - self.activeStackValidationChanged.emit() + # Normal check + self._updateStacksValid() @pyqtSlot(str) def setActiveMachine(self, stack_id): @@ -337,16 +342,30 @@ class MachineManager(QObject): def _createUniqueName(self, container_type, current_name, new_name, fallback_name): return UM.Settings.ContainerRegistry.getInstance().createUniqueName(container_type, current_name, new_name, fallback_name) - ## Convenience function to check if a stack has errors. - def _checkStackForErrors(self, stack): + ## Convenience function to check if a stack is valid. + def _checkStackValid(self, stack): if stack is None: - return False + return True for key in stack.getAllKeys(): validation_state = stack.getProperty(key, "validationState") if validation_state in (UM.Settings.ValidatorState.Exception, UM.Settings.ValidatorState.MaximumError, UM.Settings.ValidatorState.MinimumError): - return True - return False + return False + return True + + ## Return True if used stacks are valid. + def _checkStacksValid(self): + if not self._checkStackValid(self._global_container_stack): + return False + + if self._global_container_stack is None: + return True + stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())) + for stack in stacks: + if not self._checkStackValid(stack): + return False + + return True ## Remove all instances from the top instanceContainer (effectively removing all user-changed settings) @pyqtSlot() @@ -405,12 +424,12 @@ class MachineManager(QObject): for container in send_emits_containers: container.sendPostponedEmits() - ## Check if the global profile does not contain error states - # Note that the _active_stack_valid is cached due to performance issues - # Calling _checkStackForErrors on every change is simply too expensive - @pyqtProperty(bool, notify = activeStackValidationChanged) - def isActiveStackValid(self): - return bool(self._active_stack_valid) + ## Check if none of the stacks contain error states + # Note that the _stacks_valid is cached due to performance issues + # Calling _checkStack(s)ForErrors on every change is simply too expensive + @pyqtProperty(bool, notify = stacksValidationChanged) + def areStacksValid(self): + return bool(self._stacks_valid) @pyqtProperty(str, notify = activeStackChanged) def activeUserProfileId(self): diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 18c7fb1f5c..a610fe879a 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -75,7 +75,7 @@ class StartSliceJob(Job): return # Don't slice if there is a setting with an error value. - if not Application.getInstance().getMachineManager().isActiveStackValid: + if not Application.getInstance().getMachineManager().areStacksValid: self.setResult(StartJobResult.SettingError) return diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 3ee8630183..8d3936fb9c 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -121,7 +121,7 @@ Item Action { id: updateProfileAction; - enabled: Cura.MachineManager.isActiveStackValid && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) + enabled: Cura.MachineManager.areStacksValid && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) text: catalog.i18nc("@action:inmenu menubar:profile","&Update profile with current settings"); onTriggered: Cura.ContainerManager.updateQualityChanges(); } @@ -137,7 +137,7 @@ Item Action { id: addProfileAction; - enabled: Cura.MachineManager.isActiveStackValid && Cura.MachineManager.hasUserSettings + enabled: Cura.MachineManager.areStacksValid && Cura.MachineManager.hasUserSettings text: catalog.i18nc("@action:inmenu menubar:profile","&Create profile from current settings..."); } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 621ecb3184..3e1ee400a6 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -62,7 +62,7 @@ UM.ManagementPage Button { text: catalog.i18nc("@label", "Create") - enabled: base.canCreateProfile() + enabled: base.canCreateProfile() && Cura.MachineManager.areStacksValid visible: base.canCreateProfile() iconName: "list-add"; From d308cd45bc518cd685cf4a62144cab82c66adb00 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Thu, 20 Oct 2016 16:16:33 +0200 Subject: [PATCH 2/2] Moved function out of MachineManager, changed "Valid" to "HaveErrors". CURA-2730 --- cura/Settings/MachineManager.py | 48 ++++++++-------------- plugins/CuraEngineBackend/StartSliceJob.py | 2 +- resources/qml/Actions.qml | 4 +- resources/qml/Preferences/ProfilesPage.qml | 2 +- 4 files changed, 22 insertions(+), 34 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 4d4deddb68..317b68fd47 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -34,7 +34,7 @@ class MachineManager(QObject): self.globalContainerChanged.connect(self.activeVariantChanged) self.globalContainerChanged.connect(self.activeQualityChanged) - self._stacks_valid = None + self._stacks_have_errors = None self._onGlobalContainerChanged() ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) @@ -233,10 +233,10 @@ class MachineManager(QObject): quality.nameChanged.connect(self._onQualityNameChanged) ## Update self._stacks_valid according to _checkStacksForErrors and emit if change. - def _updateStacksValid(self): - old_stacks_valid = self._stacks_valid - self._stacks_valid = self._checkStacksValid() - if old_stacks_valid != self._stacks_valid: + def _updateStacksHaveErrors(self): + old_stacks_have_errors = self._stacks_have_errors + self._stacks_have_errors = self._checkStacksHaveErrors() + if old_stacks_have_errors != self._stacks_have_errors: self.stacksValidationChanged.emit() def _onActiveExtruderStackChanged(self): @@ -254,7 +254,7 @@ class MachineManager(QObject): else: self._active_container_stack = self._global_container_stack - self._updateStacksValid() + self._updateStacksHaveErrors() if old_active_container_stack != self._active_container_stack: # Many methods and properties related to the active quality actually depend @@ -277,18 +277,18 @@ class MachineManager(QObject): self.activeStackValueChanged.emit() if property_name == "validationState": - if self._stacks_valid: + if not self._stacks_have_errors: # fast update, we only have to look at the current changed property if self._active_container_stack.getProperty(key, "settable_per_extruder"): changed_validation_state = self._active_container_stack.getProperty(key, property_name) else: changed_validation_state = self._global_container_stack.getProperty(key, property_name) if changed_validation_state in (UM.Settings.ValidatorState.Exception, UM.Settings.ValidatorState.MaximumError, UM.Settings.ValidatorState.MinimumError): - self._stacks_valid = False + self._stacks_have_errors = True self.stacksValidationChanged.emit() else: # Normal check - self._updateStacksValid() + self._updateStacksHaveErrors() @pyqtSlot(str) def setActiveMachine(self, stack_id): @@ -342,30 +342,18 @@ class MachineManager(QObject): def _createUniqueName(self, container_type, current_name, new_name, fallback_name): return UM.Settings.ContainerRegistry.getInstance().createUniqueName(container_type, current_name, new_name, fallback_name) - ## Convenience function to check if a stack is valid. - def _checkStackValid(self, stack): - if stack is None: + def _checkStacksHaveErrors(self): + if self._global_container_stack is not None and self._global_container_stack.hasErrors(): return True - for key in stack.getAllKeys(): - validation_state = stack.getProperty(key, "validationState") - if validation_state in (UM.Settings.ValidatorState.Exception, UM.Settings.ValidatorState.MaximumError, UM.Settings.ValidatorState.MinimumError): - return False - return True - - ## Return True if used stacks are valid. - def _checkStacksValid(self): - if not self._checkStackValid(self._global_container_stack): - return False - if self._global_container_stack is None: - return True + return False stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())) for stack in stacks: - if not self._checkStackValid(stack): - return False + if stack.hasErrors(): + return True - return True + return False ## Remove all instances from the top instanceContainer (effectively removing all user-changed settings) @pyqtSlot() @@ -425,11 +413,11 @@ class MachineManager(QObject): container.sendPostponedEmits() ## Check if none of the stacks contain error states - # Note that the _stacks_valid is cached due to performance issues + # Note that the _stacks_have_errors is cached due to performance issues # Calling _checkStack(s)ForErrors on every change is simply too expensive @pyqtProperty(bool, notify = stacksValidationChanged) - def areStacksValid(self): - return bool(self._stacks_valid) + def stacksHaveErrors(self): + return bool(self._stacks_have_errors) @pyqtProperty(str, notify = activeStackChanged) def activeUserProfileId(self): diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index a610fe879a..650bc9e45d 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -75,7 +75,7 @@ class StartSliceJob(Job): return # Don't slice if there is a setting with an error value. - if not Application.getInstance().getMachineManager().areStacksValid: + if Application.getInstance().getMachineManager().stacksHaveErrors: self.setResult(StartJobResult.SettingError) return diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 8d3936fb9c..0ca775ad09 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -121,7 +121,7 @@ Item Action { id: updateProfileAction; - enabled: Cura.MachineManager.areStacksValid && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) + enabled: !Cura.MachineManager.stacksHaveErrors && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) text: catalog.i18nc("@action:inmenu menubar:profile","&Update profile with current settings"); onTriggered: Cura.ContainerManager.updateQualityChanges(); } @@ -137,7 +137,7 @@ Item Action { id: addProfileAction; - enabled: Cura.MachineManager.areStacksValid && Cura.MachineManager.hasUserSettings + enabled: !Cura.MachineManager.stacksHaveErrors && Cura.MachineManager.hasUserSettings text: catalog.i18nc("@action:inmenu menubar:profile","&Create profile from current settings..."); } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 3e1ee400a6..47d49849b4 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -62,7 +62,7 @@ UM.ManagementPage Button { text: catalog.i18nc("@label", "Create") - enabled: base.canCreateProfile() && Cura.MachineManager.areStacksValid + enabled: base.canCreateProfile() && !Cura.MachineManager.stacksHaveErrors visible: base.canCreateProfile() iconName: "list-add";