diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 58c82b6c38..e38338172a 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -45,6 +45,10 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self._cached_multiparts = {} + self._sending_gcode = False + self._compressing_gcode = False + self._gcode = [] + def requestWrite(self, nodes, file_name=None, filter_by_machine=False, file_handler=None, **kwargs): raise NotImplementedError("requestWrite needs to be implemented") @@ -57,6 +61,34 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): def authenticationState(self): return self._authentication_state + def _compressGCode(self): + self._compressing_gcode = True + + ## Mash the data into single string + max_chars_per_line = int(1024 * 1024 / 4) # 1/4 MB per line. + byte_array_file_data = b"" + batched_line = "" + + for line in self._gcode: + if not self._compressing_gcode: + self._progress_message.hide() + # Stop trying to zip / send as abort was called. + return + batched_line += line + # if the gcode was read from a gcode file, self._gcode will be a list of all lines in that file. + # Compressing line by line in this case is extremely slow, so we need to batch them. + if len(batched_line) < max_chars_per_line: + continue + byte_array_file_data += self.__compressDataAndNotifyQt(batched_line) + batched_line = "" + + # Don't miss the last batch (If any) + if batched_line: + byte_array_file_data += self.__compressDataAndNotifyQt(batched_line) + + self._compressing_gcode = False + return byte_array_file_data + def _update(self): if self._last_response_time: time_since_last_response = time() - self._last_response_time diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 3ce9782355..bf912ad4a5 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -138,7 +138,7 @@ class PrinterOutputDevice(QObject, OutputDevice): def acceptsCommands(self): return self._accepts_commands - ## Set a flag to signal the UI that the printer is not (yet) ready to receive commands + ## Set a flag to signal the UI that the printer is not (yet) ready to receive commands def setAcceptsCommands(self, accepts_commands): if self._accepts_commands != accepts_commands: self._accepts_commands = accepts_commands diff --git a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py index c43855ce61..7d95acc920 100644 --- a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py @@ -2,10 +2,12 @@ # Cura is released under the terms of the LGPLv3 or higher. from UM.Logger import Logger - +from UM.Application import Application from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.i18n import i18nCatalog +from UM.Message import Message -from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice +from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel @@ -17,6 +19,8 @@ from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty import json import os +i18n_catalog = i18nCatalog("cura") + class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): printJobsChanged = pyqtSignal() @@ -39,6 +43,49 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): # See comments about this hack with the clusterPrintersChanged signal self.printersChanged.connect(self.clusterPrintersChanged) + self._accepts_commands = True + + # Cluster does not have authentication, so default to authenticated + self._authentication_state = AuthState.Authenticated + + self._error_message = None + self._progress_message = None + + def requestWrite(self, nodes, file_name=None, filter_by_machine=False, file_handler=None, **kwargs): + # Notify the UI that a switch to the print monitor should happen + Application.getInstance().showPrintMonitor.emit(True) + self.writeStarted.emit(self) + + self._gcode = getattr(Application.getInstance().getController().getScene(), "gcode_list", []) + if not self._gcode: + # Unable to find g-code. Nothing to send + return + + @pyqtSlot() + def sendPrintJob(self): + Logger.log("i", "Sending print job to printer.") + if self._sending_gcode: + self._error_message = Message( + i18n_catalog.i18nc("@info:status", + "Sending new jobs (temporarily) blocked, still sending the previous print job.")) + self._error_message.show() + return + + self._sending_gcode = True + + self._progress_message = Message(i18n_catalog.i18nc("@info:status", "Sending data to printer"), 0, False, -1, + i18n_catalog.i18nc("@info:title", "Sending Data")) + self._progress_message.addAction("Abort", i18n_catalog.i18nc("@action:button", "Cancel"), None, "") + self._progress_message.actionTriggered.connect(self._progressMessageActionTriggered) + + compressed_gcode = self._compressGCode() + if compressed_gcode is None: + # Abort was called. + return + + + + @pyqtSlot() def openPrintJobControlPanel(self): Logger.log("d", "Opening print job control panel...") diff --git a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py index e1acd1bede..642a67d729 100644 --- a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py @@ -63,10 +63,6 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self._authentication_succeeded_message = None self._not_authenticated_message = None - self._sending_gcode = False - self._compressing_gcode = False - self._gcode = [] - self.authenticationStateChanged.connect(self._onAuthenticationStateChanged) self.setPriority(3) # Make sure the output device gets selected above local file output @@ -286,34 +282,6 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self._progress_message.hide() - def _compressGCode(self): - self._compressing_gcode = True - - ## Mash the data into single string - max_chars_per_line = 1024 * 1024 / 4 # 1/4 MB per line. - byte_array_file_data = b"" - batched_line = "" - - for line in self._gcode: - if not self._compressing_gcode: - self._progress_message.hide() - # Stop trying to zip / send as abort was called. - return - batched_line += line - # if the gcode was read from a gcode file, self._gcode will be a list of all lines in that file. - # Compressing line by line in this case is extremely slow, so we need to batch them. - if len(batched_line) < max_chars_per_line: - continue - byte_array_file_data += self.__compressDataAndNotifyQt(batched_line) - batched_line = "" - - # Don't miss the last batch (If any) - if batched_line: - byte_array_file_data += self.__compressDataAndNotifyQt(batched_line) - - self._compressing_gcode = False - return byte_array_file_data - def _messageBoxCallback(self, button): def delayedCallback(): if button == QMessageBox.Yes: