Browse Source

Changed MachineManager.isActiveStackValid to MachineManager.areStacksValid. CURA-2730

Jack Ha 8 years ago
parent
commit
98688bf013

+ 41 - 22
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):

+ 1 - 1
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
 

+ 2 - 2
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...");
     }
 

+ 1 - 1
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";