diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 78986d82ee..df25522be3 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -123,7 +123,7 @@ except ImportError: CuraVersion = "master" # [CodeStyle: Reflecting imported value] CuraBuildType = "" CuraDebugMode = False - CuraSDKVerion = "" + CuraSDKVersion = "" class CuraApplication(QtApplication): diff --git a/cura/PrinterOutput/ExtruderConfigurationModel.py b/cura/PrinterOutput/ExtruderConfigurationModel.py index 250237403f..2a7844b629 100644 --- a/cura/PrinterOutput/ExtruderConfigurationModel.py +++ b/cura/PrinterOutput/ExtruderConfigurationModel.py @@ -30,7 +30,7 @@ class ExtruderConfigurationModel(QObject): self.extruderConfigurationChanged.emit() @pyqtProperty(QObject, fset = setMaterial, notify = extruderConfigurationChanged) - def material(self) -> MaterialOutputModel: + def activeMaterial(self) -> MaterialOutputModel: return self._material def setHotendID(self, hotend_id: Optional[str]) -> None: @@ -52,7 +52,7 @@ class ExtruderConfigurationModel(QObject): message_chunks = [] message_chunks.append("Position: " + str(self._position)) message_chunks.append("-") - message_chunks.append("Material: " + self.material.type if self.material else "empty") + message_chunks.append("Material: " + self.activeMaterial.type if self.activeMaterial else "empty") message_chunks.append("-") message_chunks.append("HotendID: " + self.hotendID if self.hotendID else "empty") return " ".join(message_chunks) diff --git a/cura/PrinterOutput/ExtruderOutputModel.py b/cura/PrinterOutput/ExtruderOutputModel.py index 546227123e..c7fd58c098 100644 --- a/cura/PrinterOutput/ExtruderOutputModel.py +++ b/cura/PrinterOutput/ExtruderOutputModel.py @@ -48,7 +48,7 @@ class ExtruderOutputModel(QObject): @pyqtProperty(QObject, notify = extruderConfigurationChanged) def activeMaterial(self) -> Optional["MaterialOutputModel"]: - return self._extruder_configuration.material + return self._extruder_configuration.activeMaterial def updateActiveMaterial(self, material: Optional["MaterialOutputModel"]): self._extruder_configuration.setMaterial(material) @@ -111,4 +111,4 @@ class ExtruderOutputModel(QObject): @pyqtSlot() def cancelPreheatHotend(self) -> None: - self._printer._controller.cancelPreheatHotend(self) \ No newline at end of file + self._printer._controller.cancelPreheatHotend(self) diff --git a/cura/PrinterOutput/PrintJobOutputModel.py b/cura/PrinterOutput/PrintJobOutputModel.py index b77600f85c..8057965013 100644 --- a/cura/PrinterOutput/PrintJobOutputModel.py +++ b/cura/PrinterOutput/PrintJobOutputModel.py @@ -7,6 +7,7 @@ from typing import Optional, TYPE_CHECKING if TYPE_CHECKING: from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel + from cura.PrinterOutput.ConfigurationModel import ConfigurationModel class PrintJobOutputModel(QObject): @@ -17,6 +18,7 @@ class PrintJobOutputModel(QObject): keyChanged = pyqtSignal() assignedPrinterChanged = pyqtSignal() ownerChanged = pyqtSignal() + configurationChanged =pyqtSignal() def __init__(self, output_controller: "PrinterOutputController", key: str = "", name: str = "", parent=None) -> None: super().__init__(parent) @@ -29,6 +31,17 @@ class PrintJobOutputModel(QObject): self._assigned_printer = None # type: Optional[PrinterOutputModel] self._owner = "" # Who started/owns the print job? + self._configuration = None # type: Optional[ConfigurationModel] + + @pyqtProperty(QObject, notify=configurationChanged) + def configuration(self) -> Optional["ConfigurationModel"]: + return self._configuration + + def updateConfiguration(self, configuration: Optional["ConfigurationModel"]) -> None: + if self._configuration != configuration: + self._configuration = configuration + self.configurationChanged.emit() + @pyqtProperty(str, notify=ownerChanged) def owner(self): return self._owner diff --git a/plugins/UM3NetworkPrinting/ClusterControlItem.qml b/plugins/UM3NetworkPrinting/ClusterControlItem.qml index 3d7b25d59c..5531e99d57 100644 --- a/plugins/UM3NetworkPrinting/ClusterControlItem.qml +++ b/plugins/UM3NetworkPrinting/ClusterControlItem.qml @@ -27,13 +27,14 @@ Component { id: activePrintersLabel font: UM.Theme.getFont("large") - anchors.horizontalCenter: parent.horizontalCenter - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.top: parent.top - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.right:parent.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width + anchors + { + margins: UM.Theme.getSize("default_margin").width + top: parent.top + left: parent.left + right: parent.right + } + text: Cura.MachineManager.printerOutputDevices[0].name elide: Text.ElideRight } diff --git a/plugins/UM3NetworkPrinting/ClusterMonitorItem.qml b/plugins/UM3NetworkPrinting/ClusterMonitorItem.qml index 0e86d55de8..51301b7e8d 100644 --- a/plugins/UM3NetworkPrinting/ClusterMonitorItem.qml +++ b/plugins/UM3NetworkPrinting/ClusterMonitorItem.qml @@ -28,7 +28,8 @@ Component id: activePrintersLabel font: UM.Theme.getFont("large") - anchors { + anchors + { top: parent.top topMargin: UM.Theme.getSize("default_margin").height * 2 // a bit more spacing to give it some breathing room horizontalCenter: parent.horizontalCenter @@ -71,25 +72,28 @@ Component ScrollView { - id: printerScrollView - anchors.margins: UM.Theme.getSize("default_margin").width - anchors.top: activePrintersLabel.bottom - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_lining").width // To ensure border can be drawn. - anchors.rightMargin: UM.Theme.getSize("default_lining").width - anchors.right: parent.right + id: queuedPrintJobs + + anchors + { + margins: UM.Theme.getSize("default_margin").width + top: activePrintersLabel.bottom + left: parent.left + leftMargin: UM.Theme.getSize("default_lining").width // To ensure border can be drawn. + rightMargin: UM.Theme.getSize("default_lining").width + right: parent.right + } ListView { anchors.fill: parent spacing: -UM.Theme.getSize("default_lining").height - model: OutputDevice.printers + model: OutputDevice.queuedPrintJobs - delegate: PrinterInfoBlock + delegate: PrintJobInfoBlock { - printer: modelData + printJob: modelData width: Math.min(800 * screenScaleFactor, maximumWidth) height: 125 * screenScaleFactor @@ -102,7 +106,7 @@ Component PrinterVideoStream { visible: OutputDevice.activePrinter != null - anchors.fill:parent + anchors.fill: parent } onVisibleChanged: diff --git a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py index 84e0a66170..d91e7e1d93 100644 --- a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py @@ -17,6 +17,8 @@ from UM.Scene.SceneNode import SceneNode #For typing. from UM.Version import Version #To check against firmware versions for support. from cura.CuraApplication import CuraApplication +from cura.PrinterOutput.ConfigurationModel import ConfigurationModel +from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel @@ -478,6 +480,23 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): def _createPrintJobModel(self, data: Dict[str, Any]) -> PrintJobOutputModel: print_job = PrintJobOutputModel(output_controller=ClusterUM3PrinterOutputController(self), key=data["uuid"], name= data["name"]) + + configuration = ConfigurationModel() + extruders = [] + for index in range(0, self._number_of_extruders): + extruder = ExtruderConfigurationModel() + extruder.setPosition(index) + try: + extruder_data = data["configuration"][index] + except IndexError: + break + + extruder.setHotendID(extruder_data.get("print_core_id", "")) + extruder.setMaterial(self._createMaterialOutputModel(extruder_data.get("material", {}))) + extruders.append(extruder) + configuration.setExtruderConfigurations(extruders) + print_job.updateConfiguration(configuration) + print_job.stateChanged.connect(self._printJobStateChanged) self._print_jobs.append(print_job) return print_job @@ -488,6 +507,24 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): print_job.updateState(data["status"]) print_job.updateOwner(data["owner"]) + def _createMaterialOutputModel(self, material_data) -> MaterialOutputModel: + containers = ContainerRegistry.getInstance().findInstanceContainers(type="material", GUID=material_data["guid"]) + if containers: + color = containers[0].getMetaDataEntry("color_code") + brand = containers[0].getMetaDataEntry("brand") + material_type = containers[0].getMetaDataEntry("material") + name = containers[0].getName() + else: + Logger.log("w", + "Unable to find material with guid {guid}. Using data as provided by cluster".format( + guid=material_data["guid"])) + color = material_data["color"] + brand = material_data["brand"] + material_type = material_data["material"] + name = "Empty" if material_data["material"] == "empty" else "Unknown" + return MaterialOutputModel(guid=material_data["guid"], type=material_type, + brand=brand, color=color, name=name) + def _updatePrinter(self, printer: PrinterOutputModel, data: Dict[str, Any]) -> None: # For some unknown reason the cluster wants UUID for everything, except for sending a job directly to a printer. # Then we suddenly need the unique name. So in order to not have to mess up all the other code, we save a mapping. @@ -523,24 +560,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): material_data = extruder_data["material"] if extruder.activeMaterial is None or extruder.activeMaterial.guid != material_data["guid"]: - containers = ContainerRegistry.getInstance().findInstanceContainers(type="material", - GUID=material_data["guid"]) - if containers: - color = containers[0].getMetaDataEntry("color_code") - brand = containers[0].getMetaDataEntry("brand") - material_type = containers[0].getMetaDataEntry("material") - name = containers[0].getName() - else: - Logger.log("w", - "Unable to find material with guid {guid}. Using data as provided by cluster".format( - guid=material_data["guid"])) - color = material_data["color"] - brand = material_data["brand"] - material_type = material_data["material"] - name = "Empty" if material_data["material"] == "empty" else "Unknown" - - material = MaterialOutputModel(guid=material_data["guid"], type=material_type, - brand=brand, color=color, name=name) + material = self._createMaterialOutputModel(material_data) extruder.updateActiveMaterial(material) def _removeJob(self, job: PrintJobOutputModel) -> bool: diff --git a/plugins/UM3NetworkPrinting/PrintCoreConfiguration.qml b/plugins/UM3NetworkPrinting/PrintCoreConfiguration.qml index 267516091b..6ff5c6327f 100644 --- a/plugins/UM3NetworkPrinting/PrintCoreConfiguration.qml +++ b/plugins/UM3NetworkPrinting/PrintCoreConfiguration.qml @@ -12,14 +12,16 @@ Item width: Math.round(parent.width / 2) height: childrenRect.height + Label { id: materialLabel - text: printCoreConfiguration.activeMaterial != null ? printCoreConfiguration.activeMaterial.name : "" + text: printCoreConfiguration.activeMaterial != null ? printCoreConfiguration.activeMaterial.name : ":(" elide: Text.ElideRight width: parent.width font: UM.Theme.getFont("very_small") } + Label { id: printCoreLabel diff --git a/plugins/UM3NetworkPrinting/PrintJobInfoBlock.qml b/plugins/UM3NetworkPrinting/PrintJobInfoBlock.qml new file mode 100644 index 0000000000..f88b917954 --- /dev/null +++ b/plugins/UM3NetworkPrinting/PrintJobInfoBlock.qml @@ -0,0 +1,140 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import UM 1.3 as UM + + +Item +{ + property var printJob: null + + function getPrettyTime(time) + { + return OutputDevice.formatDuration(time) + } + + Rectangle + { + id: background + anchors.fill: parent + + Item + { + // Content on the left of the infobox + anchors + { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.horizontalCenter + margins: UM.Theme.getSize("default_margin").width + } + + Label + { + id: printJobName + text: "printJobName" + } + + Label + { + id: ownerName + anchors.top: printJobName.bottom + text: "OwnerName" + } + + Label + { + id: totalTimeLabel + + anchors.bottom: parent.bottom + anchors.right: parent.right + + text: printJob != null ? getPrettyTime(printJob.timeTotal) : "3h 12m" + elide: Text.ElideRight + } + } + + Item + { + // Content on the right side of the infobox. + anchors + { + top: parent.top + bottom: parent.bottom + left: parent.horizontalCenter + right: parent.right + margins: UM.Theme.getSize("default_margin").width + } + + Label + { + id: targetPrinterLabel + text: "Waiting for: first available" + } + + Button + { + text: "..." + anchors + { + right: parent.right + top: parent.top + } + } + + // PrintCore && Material config + Row + { + id: extruderInfo + anchors.bottom: parent.bottom + + anchors + { + left: parent.left + right: parent.right + } + height: childrenRect.height + + spacing: UM.Theme.getSize("default_margin").width + + PrintCoreConfiguration + { + id: leftExtruderInfo + width: Math.round((parent.width - extruderSeperator.width) / 2) + printCoreConfiguration: printJob.configuration.extruderConfigurations[0] + } + + Rectangle + { + id: extruderSeperator + width: UM.Theme.getSize("default_lining").width + height: parent.height + color: lineColor + } + + PrintCoreConfiguration + { + id: rightExtruderInfo + width: Math.round((parent.width - extruderSeperator.width) / 2) + printCoreConfiguration: printJob.configuration.extruderConfigurations[1] + } + } + + } + + Rectangle + { + color: "grey" + width: 1 + + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.margins: UM.Theme.getSize("default_margin").height + anchors.horizontalCenter: parent.horizontalCenter + + } + + } +} \ No newline at end of file