diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index f8d2ec66e2..58c82b6c38 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -98,7 +98,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): if id(reply) in self._cached_multiparts: del self._cached_multiparts[id(reply)] - def _put(self, target: str, data: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]): + def put(self, target: str, data: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]): if self._manager is None: self._createNetworkManager() request = self._createEmptyRequest(target) @@ -107,7 +107,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): if onFinished is not None: self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished - def _get(self, target: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]): + def get(self, target: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]): if self._manager is None: self._createNetworkManager() request = self._createEmptyRequest(target) @@ -116,13 +116,13 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): if onFinished is not None: self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished - def _delete(self, target: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]): + def delete(self, target: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]): if self._manager is None: self._createNetworkManager() self._last_request_time = time() pass - def _post(self, target: str, data: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]], onProgress: Callable = None): + def post(self, target: str, data: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]], onProgress: Callable = None): if self._manager is None: self._createNetworkManager() request = self._createEmptyRequest(target) @@ -133,7 +133,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): if onFinished is not None: self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished - def _postForm(self, target: str, header_data: str, body_data: bytes, onFinished: Optional[Callable[[Any, QNetworkReply], None]], onProgress: Callable = None): + def postForm(self, target: str, header_data: str, body_data: bytes, onFinished: Optional[Callable[[Any, QNetworkReply], None]], onProgress: Callable = None): if self._manager is None: self._createNetworkManager() request = self._createEmptyFormRequest(target) diff --git a/cura/PrinterOutput/PrintJobOutputModel.py b/cura/PrinterOutput/PrintJobOutputModel.py index 7c38782788..00641ab89a 100644 --- a/cura/PrinterOutput/PrintJobOutputModel.py +++ b/cura/PrinterOutput/PrintJobOutputModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant +from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot MYPY = False if MYPY: from cura.PrinterOutput.PrinterOutputController import PrinterOutputController @@ -80,5 +80,6 @@ class PrintJobOutputModel(QObject): self._state = new_state self.stateChanged.emit() + @pyqtSlot(str) def setState(self, state): self._output_controller.setJobState(self, state) \ No newline at end of file diff --git a/cura/PrinterOutput/PrinterOutputController.py b/cura/PrinterOutput/PrinterOutputController.py index 525c8db102..982c41f293 100644 --- a/cura/PrinterOutput/PrinterOutputController.py +++ b/cura/PrinterOutput/PrinterOutputController.py @@ -1,4 +1,5 @@ - +# Copyright (c) 2017 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. MYPY = False if MYPY: @@ -8,11 +9,13 @@ if MYPY: class PrinterOutputController: - def __init__(self): + def __init__(self, output_device): self.can_pause = True self.can_abort = True self.can_pre_heat_bed = True self.can_control_manually = True + self._output_device = output_device + def setTargetHotendTemperature(self, printer: "PrinterOutputModel", extruder: "ExtruderOuputModel", temperature: int): # TODO: implement diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py index 97f5c69723..d4b9d9c99a 100644 --- a/cura/PrinterOutput/PrinterOutputModel.py +++ b/cura/PrinterOutput/PrinterOutputModel.py @@ -177,19 +177,19 @@ class PrinterOutputModel(QObject): @pyqtProperty(bool, constant=True) def canPause(self): if self._controller: - return self.can_pause + return self._controller.can_pause return False # Does the printer support abort at all @pyqtProperty(bool, constant=True) def canAbort(self): if self._controller: - return self.can_abort + return self._controller.can_abort return False # Does the printer support manual control at all @pyqtProperty(bool, constant=True) def canControlManually(self): if self._controller: - return self.can_control_manually + return self._controller.can_control_manually return False diff --git a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py index 8f9a92384f..91acdc28af 100644 --- a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py @@ -21,8 +21,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): def _update(self): if not super()._update(): return - self._get("printers/", onFinished=self._onGetPrintersDataFinished) - self._get("print_jobs/", onFinished=self._onGetPrintJobsFinished) + self.get("printers/", onFinished=self._onGetPrintersDataFinished) + self.get("print_jobs/", onFinished=self._onGetPrintJobsFinished) def _onGetPrintJobsFinished(self, reply: QNetworkReply): status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) diff --git a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py index 67b2032e6a..de0a8d6eff 100644 --- a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py @@ -16,6 +16,8 @@ from PyQt5.QtNetwork import QNetworkRequest from PyQt5.QtCore import QTimer, QCoreApplication from PyQt5.QtWidgets import QMessageBox +from .LegacyUM3PrinterOutputController import LegacyUM3PrinterOutputController + from time import time import json @@ -74,6 +76,8 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self.setIconName("print") + self._output_controller = LegacyUM3PrinterOutputController(self) + def _onAuthenticationStateChanged(self): # We only accept commands if we are authenticated. if self._authentication_state == AuthState.Authenticated: @@ -143,7 +147,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): continue # If it's not readonly, it's created by user, so skip it. file_name = "none.xml" - self._postForm("materials", "form-data; name=\"file\";filename=\"%s\"" % file_name, xml_data.encode(), onFinished=None) + self.postForm("materials", "form-data; name=\"file\";filename=\"%s\"" % file_name, xml_data.encode(), onFinished=None) except NotImplementedError: # If the material container is not the most "generic" one it can't be serialized an will raise a @@ -241,8 +245,8 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): return file_name = "%s.gcode.gz" % Application.getInstance().getPrintInformation().jobName - self._postForm("print_job", "form-data; name=\"file\";filename=\"%s\"" % file_name, compressed_gcode, - onFinished=self._onPostPrintJobFinished) + self.postForm("print_job", "form-data; name=\"file\";filename=\"%s\"" % file_name, compressed_gcode, + onFinished=self._onPostPrintJobFinished) return @@ -392,8 +396,8 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self._checkAuthentication() # We don't need authentication for requesting info, so we can go right ahead with requesting this. - self._get("printer", onFinished=self._onGetPrinterDataFinished) - self._get("print_job", onFinished=self._onGetPrintJobFinished) + self.get("printer", onFinished=self._onGetPrinterDataFinished) + self.get("print_job", onFinished=self._onGetPrintJobFinished) def _resetAuthenticationRequestedMessage(self): if self._authentication_requested_message: @@ -415,7 +419,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): def _verifyAuthentication(self): Logger.log("d", "Attempting to verify authentication") # This will ensure that the "_onAuthenticationRequired" is triggered, which will setup the authenticator. - self._get("auth/verify", onFinished=self._onVerifyAuthenticationCompleted) + self.get("auth/verify", onFinished=self._onVerifyAuthenticationCompleted) def _onVerifyAuthenticationCompleted(self, reply): status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) @@ -438,7 +442,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): def _checkAuthentication(self): Logger.log("d", "Checking if authentication is correct for id %s and key %s", self._authentication_id, self._getSafeAuthKey()) - self._get("auth/check/" + str(self._authentication_id), onFinished=self._onCheckAuthenticationFinished) + self.get("auth/check/" + str(self._authentication_id), onFinished=self._onCheckAuthenticationFinished) def _onCheckAuthenticationFinished(self, reply): if str(self._authentication_id) not in reply.url().toString(): @@ -511,10 +515,10 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self._authentication_key = None self._authentication_id = None - self._post("auth/request", - json.dumps({"application": "Cura-" + Application.getInstance().getVersion(), + self.post("auth/request", + json.dumps({"application": "Cura-" + Application.getInstance().getVersion(), "user": self._getUserName()}).encode(), - onFinished=self._onRequestAuthenticationFinished) + onFinished=self._onRequestAuthenticationFinished) self.setAuthenticationState(AuthState.AuthenticationRequested) @@ -542,7 +546,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): Logger.log("w", "Received an invalid print job state message: Not valid JSON.") return if printer.activePrintJob is None: - print_job = PrintJobOutputModel(output_controller=None) + print_job = PrintJobOutputModel(output_controller=self._output_controller) printer.updateActivePrintJob(print_job) else: print_job = printer.activePrintJob @@ -567,7 +571,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): return if not self._printers: - self._printers = [PrinterOutputModel(output_controller=None, number_of_extruders=self._number_of_extruders)] + self._printers = [PrinterOutputModel(output_controller=self._output_controller, number_of_extruders=self._number_of_extruders)] self.printersChanged.emit() # LegacyUM3 always has a single printer. diff --git a/plugins/UM3NetworkPrinting/LegacyUM3PrinterOutputController.py b/plugins/UM3NetworkPrinting/LegacyUM3PrinterOutputController.py new file mode 100644 index 0000000000..e303d237ce --- /dev/null +++ b/plugins/UM3NetworkPrinting/LegacyUM3PrinterOutputController.py @@ -0,0 +1,13 @@ +# Copyright (c) 2017 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from cura.PrinterOutput.PrinterOutputController import PrinterOutputController + + +class LegacyUM3PrinterOutputController(PrinterOutputController): + def __init__(self, output_device): + super().__init__(output_device) + + def setJobState(self, job: "PrintJobOutputModel", state: str): + data = "{\"target\": \"%s\"}" % state + self._output_device.put("print_job/state", data, onFinished=None) diff --git a/resources/qml/MonitorButton.qml b/resources/qml/MonitorButton.qml index 07a9e1913b..6166f9b62f 100644 --- a/resources/qml/MonitorButton.qml +++ b/resources/qml/MonitorButton.qml @@ -263,18 +263,17 @@ Item property string lastJobState: "" visible: printerConnected && activePrinter.canPause - enabled: (!userClicked) && printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands && - (["paused", "printing"].indexOf(Cura.MachineManager.printerOutputDevices[0].jobState) >= 0) + enabled: (!userClicked) && printerConnected && printerAcceptsCommands && activePrintJob != null && + (["paused", "printing"].indexOf(activePrintJob.state) >= 0) text: { var result = ""; - if (!printerConnected) + if (!printerConnected || activePrintJob == null) { return ""; } - var jobState = Cura.MachineManager.printerOutputDevices[0].jobState; - if (jobState == "paused") + if (activePrintJob.state == "paused") { return catalog.i18nc("@label:", "Resume"); } @@ -285,14 +284,17 @@ Item } onClicked: { - var current_job_state = Cura.MachineManager.printerOutputDevices[0].jobState - if(current_job_state == "paused") + if(activePrintJob == null) { - Cura.MachineManager.printerOutputDevices[0].setJobState("print"); + return // Do nothing! } - else if(current_job_state == "printing") + if(activePrintJob.state == "paused") { - Cura.MachineManager.printerOutputDevices[0].setJobState("pause"); + activePrintJob.setState("print"); + } + else if(activePrintJob.state == "printing") + { + activePrintJob.setState("pause"); } } @@ -304,8 +306,8 @@ Item id: abortButton visible: printerConnected && activePrinter.canAbort - enabled: printerConnected && activePrinter.acceptsCommands && - (["paused", "printing", "pre_print"].indexOf(Cura.MachineManager.printerOutputDevices[0].jobState) >= 0) + enabled: printerConnected && printerAcceptsCommands && activePrintJob != null && + (["paused", "printing", "pre_print"].indexOf(activePrintJob.state) >= 0) height: UM.Theme.getSize("save_button_save_to_button").height @@ -324,7 +326,7 @@ Item text: catalog.i18nc("@label", "Are you sure you want to abort the print?") standardButtons: StandardButton.Yes | StandardButton.No Component.onCompleted: visible = false - onYes: Cura.MachineManager.printerOutputDevices[0].setJobState("abort") + onYes: activePrintJob.setState("abort") } } }