From 3e27c8b791f9da9fc877e773d3d69477d175cfa0 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 10 Jul 2015 15:58:34 +0200 Subject: [PATCH 1/8] Do not store files that fail to load in recent files Contributes to Ultimaker/Cura#103 --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index f5a89df498..3e7ae252c8 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -523,7 +523,7 @@ class CuraApplication(QtApplication): op.push() def _onJobFinished(self, job): - if type(job) is not ReadMeshJob: + if type(job) is not ReadMeshJob or not job.getResult(): return f = QUrl.fromLocalFile(job.getFileName()) From 6859481fd48deb87a3fcb3d3bc77d8a9031f1aa0 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 10 Jul 2015 16:02:01 +0200 Subject: [PATCH 2/8] Send M104 to set the temperature to 0 This makes it possible to continue communication after cancelling a print. Contributes to #82 --- plugins/USBPrinting/PrinterConnection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/USBPrinting/PrinterConnection.py b/plugins/USBPrinting/PrinterConnection.py index 7ef6c759ac..9d3c3334ef 100644 --- a/plugins/USBPrinting/PrinterConnection.py +++ b/plugins/USBPrinting/PrinterConnection.py @@ -468,7 +468,7 @@ class PrinterConnection(SignalEmitter): # Turn of temperatures self._sendCommand("M140 S0") - self._sendCommand("M109 S0") + self._sendCommand("M104 S0") self._is_printing = False ## Check if the process did not encounter an error yet. From a5f00f30ca90d02fbf082abbcebf5ceaf4d23d25 Mon Sep 17 00:00:00 2001 From: Tamara Hogenhout Date: Fri, 10 Jul 2015 17:50:15 +0200 Subject: [PATCH 3/8] Create functions that get & set platform activity The platform activity is determined by whether there is a mesh in the build platform or not Contributes to #128 --- cura/CuraApplication.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 5e2ba4a08a..4021cd2fc8 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -74,6 +74,7 @@ class CuraApplication(QtApplication): self._print_information = None self._i18n_catalog = None self._previous_active_tool = None + self._platform_activity = False self.activeMachineChanged.connect(self._onActiveMachineChanged) @@ -215,6 +216,31 @@ class CuraApplication(QtApplication): self._previous_active_tool = None requestAddPrinter = pyqtSignal() + activityChanged = pyqtSignal() + + @pyqtProperty(bool, notify = activityChanged) + def getPlatformActivity(self): + return self._platform_activity + + @pyqtSlot(bool) + def setPlatformActivity(self, activity): + ##Sets the _platform_activity variable on true or false depending on whether there is a mesh on the platform + if activity == True: + self._platform_activity = activity + elif activity == False: + nodes = [] + for node in DepthFirstIterator(self.getController().getScene().getRoot()): + if type(node) is not SceneNode or not node.getMeshData(): + continue + nodes.append(node) + i = 0 + for node in nodes: + if not node.getMeshData(): + continue + i += 1 + if i <= 1: ## i == 0 when the meshes are removed using the deleteAll function; i == 1 when the last remaining mesh is removed using the deleteObject function + self._platform_activity = activity + self.activityChanged.emit() ## Remove an object from the scene @pyqtSlot("quint64") @@ -227,6 +253,7 @@ class CuraApplication(QtApplication): if object: op = RemoveSceneNodeOperation(object) op.push() + self.setPlatformActivity(False) ## Create a number of copies of existing object. @pyqtSlot("quint64", int) @@ -267,7 +294,6 @@ class CuraApplication(QtApplication): if type(node) is not SceneNode or not node.getMeshData(): continue nodes.append(node) - if nodes: op = GroupedOperation() @@ -275,6 +301,7 @@ class CuraApplication(QtApplication): op.addOperation(RemoveSceneNodeOperation(node)) op.push() + self.setPlatformActivity(False) ## Reset all translation on nodes with mesh data. @pyqtSlot() From c4b923eb743d0f80e8ac762375b33ef70043b40e Mon Sep 17 00:00:00 2001 From: Tamara Hogenhout Date: Fri, 10 Jul 2015 17:52:15 +0200 Subject: [PATCH 4/8] Sets the platform activity on true when a model is loaded Also solved a problem with deleteSelection trigger contributes to #128 --- cura/BuildVolume.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index cf085bfe61..1556ee8d22 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -33,6 +33,7 @@ class BuildVolume(SceneNode): self.setCalculateBoundingBox(False) + def setWidth(self, width): self._width = width From a687c9c89eda846c9754866a87c434240cda0743 Mon Sep 17 00:00:00 2001 From: Tamara Hogenhout Date: Fri, 10 Jul 2015 18:41:24 +0200 Subject: [PATCH 5/8] Sets the platform activity on true when a model is loaded Also solved a problem with the deleteSelection trigger contributes to #128 --- resources/qml/Cura.qml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 226f4f59a9..f8e80367eb 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -41,7 +41,10 @@ UM.MainWindow { var path = modelData.toString() return (index + 1) + ". " + path.slice(path.lastIndexOf("/") + 1); } - onTriggered: UM.MeshFileHandler.readLocalFile(modelData); + onTriggered: { + UM.MeshFileHandler.readLocalFile(modelData); + Printer.setPlatformActivity(true) + } } onObjectAdded: fileMenu.insertItem(index, object) onObjectRemoved: fileMenu.removeItem(object) @@ -318,7 +321,11 @@ UM.MainWindow { redo.onTriggered: UM.OperationStack.redo(); redo.enabled: UM.OperationStack.canRedo; - deleteSelection.onTriggered: UM.Controller.removeSelection(); + deleteSelection.onTriggered: { + if(objectContextMenu.objectId != 0) { + Printer.deleteObject(objectContextMenu.objectId); + } + } deleteObject.onTriggered: { if(objectContextMenu.objectId != 0) { @@ -408,6 +415,7 @@ UM.MainWindow { onAccepted: { UM.MeshFileHandler.readLocalFile(fileUrl) + Printer.setPlatformActivity(true) } } From 81aa047ae38cea1268a704770c83c2980566b4e6 Mon Sep 17 00:00:00 2001 From: Tamara Hogenhout Date: Fri, 10 Jul 2015 18:43:47 +0200 Subject: [PATCH 6/8] Adds an idle-state for the safebutton When there is no model, the safebutton goes back into the idle state contributes to #128 --- resources/qml/SaveButton.qml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml index 4708995308..004b523336 100644 --- a/resources/qml/SaveButton.qml +++ b/resources/qml/SaveButton.qml @@ -14,6 +14,7 @@ Rectangle { property Action saveAction; property real progress: UM.Backend.progress; + property bool activity: Printer.getPlatformActivity; Behavior on progress { NumberAnimation { duration: 250; } } property string currentDevice: "local_file" @@ -76,7 +77,7 @@ Rectangle { color: UM.Theme.colors.save_button_estimated_text; font: UM.Theme.fonts.small; text: - if(base.progress < 0) { + if(base.activity == false) { //: Save button label return qsTr("Please load a 3D model"); } else if (base.progress < 0.99) { @@ -97,7 +98,7 @@ Rectangle { anchors.leftMargin: UM.Theme.sizes.save_button_text_margin.width; color: UM.Theme.colors.save_button_printtime_text; font: UM.Theme.fonts.small; - visible: base.progress < 0.99 ? false : true + visible: base.activity == false || base.progress < 0.99 ? false : true text: (!base.printDuration || !base.printDuration.valid) ? "" : base.printDuration.getDisplayString(UM.DurationFormat.Long); } Label { @@ -107,11 +108,10 @@ Rectangle { anchors.leftMargin: UM.Theme.sizes.save_button_text_margin.width; color: base.printDuration.days > 0 ? UM.Theme.colors.save_button_estimated_text : UM.Theme.colors.save_button_printtime_text; font: UM.Theme.fonts.small; - property bool mediumLengthDuration: base.printDuration.hours > 9 && base.printMaterialAmount > 9.99 && base.printDuration.days == 0 width: mediumLengthDuration ? 50 : undefined elide: mediumLengthDuration ? Text.ElideRight : Text.ElideNone - visible: base.progress < 0.99 ? false : true + visible: base.activity == false || base.progress < 0.99 ? false : true //: Print material amount save button label text: base.printMaterialAmount < 0 ? "" : qsTr("%1m material").arg(base.printMaterialAmount); } @@ -125,7 +125,7 @@ Rectangle { } width: Math.max(infoBox.width * base.progress); color: UM.Theme.colors.save_button_active - visible: base.progress > 0.99 ? false : true + visible: progress > 0.99 ? false : true } Button { @@ -135,7 +135,7 @@ Rectangle { anchors.left: parent.left anchors.leftMargin: UM.Theme.sizes.default_margin.width; tooltip: '' - enabled: progress >= 0.99; + enabled: progress > 0.99 && base.activity == true width: infoBox.width/6*4.5 height: UM.Theme.sizes.save_button_save_to_button.height From 608283f5f42bcc057f0751a811d1922f22ed6fde Mon Sep 17 00:00:00 2001 From: Tamara Hogenhout Date: Fri, 10 Jul 2015 19:28:19 +0200 Subject: [PATCH 7/8] Adds an idle-state for the layerview slider When there is no model, the layerview slider goes back into the idle state fixes #128 --- resources/themes/cura/styles.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/themes/cura/styles.qml b/resources/themes/cura/styles.qml index e40552cd32..e7794746f5 100644 --- a/resources/themes/cura/styles.qml +++ b/resources/themes/cura/styles.qml @@ -389,7 +389,7 @@ QtObject { } Label { id: maxValueLabel - visible: UM.LayerView.getLayerActivity ? true : false + visible: UM.LayerView.getLayerActivity && Printer.getPlatformActivity ? true : false text: control.maximumValue + 1 font: control.maximumValue > 998 ? UM.Theme.fonts.small : UM.Theme.fonts.default transformOrigin: Item.BottomLeft @@ -399,7 +399,7 @@ QtObject { } Label { id: minValueLabel - visible: UM.LayerView.getLayerActivity ? true : false + visible: UM.LayerView.getLayerActivity && Printer.getPlatformActivity ? true : false text: '1' font: control.maximumValue > 998 ? UM.Theme.fonts.small : UM.Theme.fonts.default transformOrigin: Item.BottomLeft @@ -416,7 +416,7 @@ QtObject { Behavior on color { ColorAnimation { duration: 50; } } Label { id: valueLabel - visible: UM.LayerView.getLayerActivity ? true : false + visible: UM.LayerView.getLayerActivity && Printer.getPlatformActivity ? true : false text: control.value + 1 anchors.bottom: layerSliderControl.bottom anchors.right: layerSliderControl.left From fb7b7ca7b8817c94408fa0a66127aebdd791a6fe Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 13 Jul 2015 13:49:07 +0200 Subject: [PATCH 8/8] Do not cause "dictionary changed size during iteration" errors when changing view Connecting to a signal while it is emitting causes errors. --- plugins/CuraEngineBackend/ProcessSlicedObjectListJob.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/CuraEngineBackend/ProcessSlicedObjectListJob.py b/plugins/CuraEngineBackend/ProcessSlicedObjectListJob.py index 6930d9da71..89c5fc5e23 100644 --- a/plugins/CuraEngineBackend/ProcessSlicedObjectListJob.py +++ b/plugins/CuraEngineBackend/ProcessSlicedObjectListJob.py @@ -22,15 +22,15 @@ class ProcessSlicedObjectListJob(Job): super().__init__() self._message = message self._scene = Application.getInstance().getController().getScene() - self._progress = None - Application.getInstance().getController().activeViewChanged.connect(self._onActiveViewChanged) def run(self): if Application.getInstance().getController().getActiveView().getPluginId() == "LayerView": self._progress = Message(catalog.i18nc("Layers View mode", "Layers"), 0, False, 0) self._progress.show() + Application.getInstance().getController().activeViewChanged.connect(self._onActiveViewChanged) + objectIdMap = {} new_node = SceneNode() ## Put all nodes in a dict identified by ID