diff --git a/plugins/SimulationView/LayerSlider.qml b/plugins/SimulationView/LayerSlider.qml index 6dcaa3f475..1540f053f5 100644 --- a/plugins/SimulationView/LayerSlider.qml +++ b/plugins/SimulationView/LayerSlider.qml @@ -39,6 +39,7 @@ Item { property real lowerValue: minimumValue property bool layersVisible: true + property bool manuallyChanged: true // Indicates whether the value was changed manually or during simulation function getUpperValueFromSliderHandle() { return upperHandle.getValue() @@ -96,7 +97,8 @@ Item { visible: sliderRoot.layersVisible // set the new value when dragging - function onHandleDragged () { + function onHandleDragged() { + sliderRoot.manuallyChanged = true upperHandle.y = y - upperHandle.height lowerHandle.y = y + height @@ -109,7 +111,7 @@ Item { UM.SimulationView.setMinimumLayer(lowerValue) } - function setValue (value) { + function setValue(value) { var range = sliderRoot.upperValue - sliderRoot.lowerValue value = Math.min(value, sliderRoot.maximumValue) value = Math.max(value, sliderRoot.minimumValue + range) @@ -168,7 +170,8 @@ Item { color: upperHandleLabel.activeFocus ? sliderRoot.handleActiveColor : sliderRoot.upperHandleColor visible: sliderRoot.layersVisible - function onHandleDragged () { + function onHandleDragged() { + sliderRoot.manuallyChanged = true // don't allow the lower handle to be heigher than the upper handle if (lowerHandle.y - (y + height) < sliderRoot.minimumRangeHandleSize) { @@ -183,7 +186,7 @@ Item { } // get the upper value based on the slider position - function getValue () { + function getValue() { var result = y / (sliderRoot.height - (2 * sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize)) result = sliderRoot.maximumValue + result * (sliderRoot.minimumValue - (sliderRoot.maximumValue - sliderRoot.minimumValue)) result = sliderRoot.roundValues ? Math.round(result) : result @@ -191,7 +194,7 @@ Item { } // set the slider position based on the upper value - function setValue (value) { + function setValue(value) { // Normalize values between range, since using arrow keys will create out-of-the-range values value = sliderRoot.normalizeValue(value) @@ -205,8 +208,16 @@ Item { sliderRoot.updateRangeHandle() } - Keys.onUpPressed: upperHandleLabel.setValue(upperHandleLabel.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) - Keys.onDownPressed: upperHandleLabel.setValue(upperHandleLabel.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) + Keys.onUpPressed: + { + sliderRoot.manuallyChanged = true + upperHandleLabel.setValue(upperHandleLabel.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) + } + Keys.onDownPressed: + { + sliderRoot.manuallyChanged = true + upperHandleLabel.setValue(upperHandleLabel.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) + } // dragging MouseArea { @@ -256,7 +267,8 @@ Item { visible: sliderRoot.layersVisible - function onHandleDragged () { + function onHandleDragged() { + sliderRoot.manuallyChanged = true // don't allow the upper handle to be lower than the lower handle if (y - (upperHandle.y + upperHandle.height) < sliderRoot.minimumRangeHandleSize) { @@ -271,7 +283,7 @@ Item { } // get the lower value from the current slider position - function getValue () { + function getValue() { var result = (y - (sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize)) / (sliderRoot.height - (2 * sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize)); result = sliderRoot.maximumValue - sliderRoot.minimumRange + result * (sliderRoot.minimumValue - (sliderRoot.maximumValue - sliderRoot.minimumRange)) result = sliderRoot.roundValues ? Math.round(result) : result @@ -279,7 +291,7 @@ Item { } // set the slider position based on the lower value - function setValue (value) { + function setValue(value) { // Normalize values between range, since using arrow keys will create out-of-the-range values value = sliderRoot.normalizeValue(value) diff --git a/plugins/SimulationView/PathSlider.qml b/plugins/SimulationView/PathSlider.qml index 999912e3ba..7eb56cc0b8 100644 --- a/plugins/SimulationView/PathSlider.qml +++ b/plugins/SimulationView/PathSlider.qml @@ -34,6 +34,7 @@ Item { property real handleValue: maximumValue property bool pathsVisible: true + property bool manuallyChanged: true // Indicates whether the value was changed manually or during simulation function getHandleValueFromSliderHandle () { return handle.getValue() @@ -97,6 +98,7 @@ Item { visible: sliderRoot.pathsVisible function onHandleDragged () { + sliderRoot.manuallyChanged = true // update the range handle sliderRoot.updateRangeHandle() @@ -128,8 +130,16 @@ Item { sliderRoot.updateRangeHandle() } - Keys.onRightPressed: handleLabel.setValue(handleLabel.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) - Keys.onLeftPressed: handleLabel.setValue(handleLabel.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) + Keys.onRightPressed: + { + sliderRoot.manuallyChanged = true + handleLabel.setValue(handleLabel.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) + } + Keys.onLeftPressed: + { + sliderRoot.manuallyChanged = true + handleLabel.setValue(handleLabel.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) + } // dragging MouseArea { diff --git a/plugins/SimulationView/SimulationView.qml b/plugins/SimulationView/SimulationView.qml index b4ca9584c7..be124157fb 100644 --- a/plugins/SimulationView/SimulationView.qml +++ b/plugins/SimulationView/SimulationView.qml @@ -623,7 +623,15 @@ Item { target: UM.SimulationView onMaxPathsChanged: pathSlider.setHandleValue(UM.SimulationView.currentPath) - onCurrentPathChanged: pathSlider.setHandleValue(UM.SimulationView.currentPath) + onCurrentPathChanged: + { + // Only pause the simulation when the layer was changed manually, not when the simulation is running + if (pathSlider.manuallyChanged) + { + playButton.pauseSimulation() + } + pathSlider.setHandleValue(UM.SimulationView.currentPath) + } } // make sure the slider handlers show the correct value after switching views @@ -667,9 +675,14 @@ Item { target: UM.SimulationView onMaxLayersChanged: layerSlider.setUpperValue(UM.SimulationView.currentLayer) + onMinimumLayerChanged: layerSlider.setLowerValue(UM.SimulationView.minimumLayer) onCurrentLayerChanged: { - playButton.pauseSimulation() + // Only pause the simulation when the layer was changed manually, not when the simulation is running + if (layerSlider.manuallyChanged) + { + playButton.pauseSimulation() + } layerSlider.setUpperValue(UM.SimulationView.currentLayer) } } @@ -719,6 +732,8 @@ Item iconSource = "./resources/simulation_resume.svg" simulationTimer.stop() status = 0 + layerSlider.manuallyChanged = true + pathSlider.manuallyChanged = true } function resumeSimulation() @@ -726,7 +741,8 @@ Item UM.SimulationView.setSimulationRunning(true) iconSource = "./resources/simulation_pause.svg" simulationTimer.start() - status = 1 + layerSlider.manuallyChanged = false + pathSlider.manuallyChanged = false } } @@ -770,7 +786,6 @@ Item { UM.SimulationView.setCurrentLayer(currentLayer+1) UM.SimulationView.setCurrentPath(0) - playButton.resumeSimulation() } } else @@ -778,6 +793,8 @@ Item UM.SimulationView.setCurrentPath(currentPath+1) } } + // The status must be set here instead of in the resumeSimulation function otherwise it won't work + // correctly, because part of the logic is in this trigger function. playButton.status = 1 } } diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 4a1203c412..91984aa148 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -5,7 +5,7 @@ import json import os import tempfile import platform -from typing import cast, Any, Dict, List, Set, TYPE_CHECKING, Tuple, Optional +from typing import cast, Any, Dict, List, Set, TYPE_CHECKING, Tuple, Optional, Union from PyQt5.QtCore import QUrl, QObject, pyqtProperty, pyqtSignal, pyqtSlot from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply @@ -39,7 +39,7 @@ class Toolbox(QObject, Extension): self._application = application # type: CuraApplication - self._sdk_version = None # type: Optional[int] + self._sdk_version = None # type: Optional[Union[str, int]] self._cloud_api_version = None # type: Optional[int] self._cloud_api_root = None # type: Optional[str] self._api_url = None # type: Optional[str] @@ -207,14 +207,14 @@ class Toolbox(QObject, Extension): return cura.CuraVersion.CuraCloudAPIVersion # type: ignore # Get the packages version depending on Cura version settings. - def _getSDKVersion(self) -> int: + def _getSDKVersion(self) -> Union[int, str]: if not hasattr(cura, "CuraVersion"): return self._plugin_registry.APIVersion - if not hasattr(cura.CuraVersion, "CuraSDKVersion"): # type: ignore + if not hasattr(cura.CuraVersion, "CuraSDKVersion"): # type: ignore return self._plugin_registry.APIVersion - if not cura.CuraVersion.CuraSDKVersion: # type: ignore + if not cura.CuraVersion.CuraSDKVersion: # type: ignore return self._plugin_registry.APIVersion - return cura.CuraVersion.CuraSDKVersion # type: ignore + return cura.CuraVersion.CuraSDKVersion # type: ignore @pyqtSlot() def browsePackages(self) -> None: @@ -498,18 +498,14 @@ class Toolbox(QObject, Extension): local_version = Version(local_package["package_version"]) remote_version = Version(remote_package["package_version"]) - if self._getSDKVersion() == "dev": - sdk_version = int(self._plugin_registry.APIVersion) - else: - sdk_version = int(self._getSDKVersion()) can_upgrade = False if remote_version > local_version: can_upgrade = True # A package with the same version can be built to have different SDK versions. So, for a package with the same # version, we also need to check if the current one has a lower SDK version. If so, this package should also # be upgradable. - elif remote_version == local_version and local_package.get("sdk_version", 0) < sdk_version: - can_upgrade = True + elif remote_version == local_version: + can_upgrade = local_package.get("sdk_version", 0) < remote_package.get("sdk_version", 0) return can_upgrade @@ -531,7 +527,11 @@ class Toolbox(QObject, Extension): @pyqtSlot(str, result = bool) def isInstalled(self, package_id: str) -> bool: - return self._package_manager.isPackageInstalled(package_id) + result = self._package_manager.isPackageInstalled(package_id) + # Also check the old plugins list if it's not found in the package manager. + if not result: + result = self.isOldPlugin(package_id) + return result @pyqtSlot(str, result = int) def getNumberOfInstalledPackagesByAuthor(self, author_id: str) -> int: diff --git a/plugins/USBPrinting/AutoDetectBaudJob.py b/plugins/USBPrinting/AutoDetectBaudJob.py index f8af61c567..8b37c4b29d 100644 --- a/plugins/USBPrinting/AutoDetectBaudJob.py +++ b/plugins/USBPrinting/AutoDetectBaudJob.py @@ -77,6 +77,7 @@ class AutoDetectBaudJob(Job): self.setResult(baud_rate) Logger.log("d", "Detected baud rate {baud_rate} on serial {serial} on retry {retry} with after {time_elapsed:0.2f} seconds.".format( serial = self._serial_port, baud_rate = baud_rate, retry = retry, time_elapsed = time() - start_timeout_time)) + serial.close() # close serial port so it can be opened by the USBPrinterOutputDevice return serial.write(b"M105\n") diff --git a/resources/qml/Preferences/Materials/MaterialsPage.qml b/resources/qml/Preferences/Materials/MaterialsPage.qml index 2050f59739..a00a2340cd 100644 --- a/resources/qml/Preferences/Materials/MaterialsPage.qml +++ b/resources/qml/Preferences/Materials/MaterialsPage.qml @@ -45,7 +45,11 @@ Item Component.onCompleted: materialListView.expandActiveMaterial(active_root_material_id) // Every time the selected item has changed, notify to the details panel - onCurrentItemChanged: materialDetailsPanel.currentItem = currentItem + onCurrentItemChanged: + { + forceActiveFocus() + materialDetailsPanel.currentItem = currentItem + } // Main layout Label