diff --git a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml index adf5ea5e1c..31b3f4d4f5 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml @@ -130,7 +130,7 @@ Component verticalCenter: externalLinkIcon.verticalCenter } color: UM.Theme.getColor("primary") - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("default") // 12pt, regular linkColor: UM.Theme.getColor("primary") text: catalog.i18nc("@label link to connect manager", "Manage queue in Cura Connect") } diff --git a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml index bb710127fc..e5f668c70d 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml @@ -57,7 +57,7 @@ Cura.MachineAction spacing: UM.Theme.getSize("default_margin").height SystemPalette { id: palette } - UM.I18nCatalog { id: catalog; name: "cura" } + UM.I18nCatalog { id: catalog; name:"cura" } Label { id: pageTitle diff --git a/plugins/UM3NetworkPrinting/resources/qml/HorizontalLine.qml b/plugins/UM3NetworkPrinting/resources/qml/HorizontalLine.qml deleted file mode 100644 index aeb92697ad..0000000000 --- a/plugins/UM3NetworkPrinting/resources/qml/HorizontalLine.qml +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.3 -import QtQuick.Controls 2.0 -import UM 1.3 as UM - -Rectangle { - color: UM.Theme.getColor("monitor_lining_light"); // TODO: Maybe theme separately? Maybe not. - height: UM.Theme.getSize("default_lining").height; - width: parent.width; -} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml new file mode 100644 index 0000000000..aa62afa083 --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml @@ -0,0 +1,131 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.3 +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.3 +import QtQuick.Dialogs 1.2 +import UM 1.3 as UM + +UM.Dialog +{ + id: overrideConfirmationDialog + + property var printer: null + + minimumWidth: screenScaleFactor * 640; + minimumHeight: screenScaleFactor * 320; + width: minimumWidth + height: minimumHeight + title: catalog.i18nc("@title:window", "Configuration Changes") + rightButtons: + [ + Button + { + id: overrideButton + anchors.margins: UM.Theme.getSize("default_margin").width + text: catalog.i18nc("@action:button", "Override") + onClicked: + { + OutputDevice.forceSendJob(printer.activePrintJob.key) + overrideConfirmationDialog.close() + } + }, + Button + { + id: cancelButton + anchors.margins: UM.Theme.getSize("default_margin").width + text: catalog.i18nc("@action:button", "Cancel") + onClicked: + { + overrideConfirmationDialog.reject() + } + } + ] + + Label + { + anchors + { + fill: parent + leftMargin: 60 + rightMargin: 60 + topMargin: 18 + bottomMargin: 56 + } + wrapMode: Text.WordWrap + text: + { + var topLine + if (materialsAreKnown(printer.activePrintJob)) + { + topLine = catalog.i18nc("@label", "The assigned printer, %1, requires the following configuration change(s):").arg(printer.name) + } + else + { + topLine = catalog.i18nc("@label", "The printer %1 is assigned, but the job contains an unknown material configuration.").arg(printer.name) + } + var result = "
" + topLine +"
" + for (var i = 0; i < printer.activePrintJob.configurationChanges.length; i++) + { + var change = printer.activePrintJob.configurationChanges[i] + var text + switch (change.typeOfChange) + { + case "material_change": + text = catalog.i18nc("@label", "Change material %1 from %2 to %3.").arg(change.index + 1).arg(change.originName).arg(change.targetName) + break + case "material_insert": + text = catalog.i18nc("@label", "Load %3 as material %1 (This cannot be overridden).").arg(change.index + 1).arg(change.targetName) + break + case "print_core_change": + text = catalog.i18nc("@label", "Change print core %1 from %2 to %3.").arg(change.index + 1).arg(change.originName).arg(change.targetName) + break + case "buildplate_change": + text = catalog.i18nc("@label", "Change build plate to %1 (This cannot be overridden).").arg(formatBuildPlateType(change.target_name)) + break + default: + text = "unknown" + } + result += "" + text + "
" + } + return result + } + } + // Utils + function formatPrintJobName(name) { + var extensions = [ ".gz", ".gcode", ".ufp" ]; + for (var i = 0; i < extensions.length; i++) { + var extension = extensions[i]; + if (name.slice(-extension.length) === extension) { + name = name.substring(0, name.length - extension.length); + } + } + return name; + } + function materialsAreKnown(job) { + var conf0 = job.configuration[0]; + if (conf0 && !conf0.material.material) { + return false; + } + var conf1 = job.configuration[1]; + if (conf1 && !conf1.material.material) { + return false; + } + return true; + } + function formatBuildPlateType(buildPlateType) { + var translationText = ""; + switch (buildPlateType) { + case "glass": + translationText = catalog.i18nc("@label", "Glass"); + break; + case "aluminum": + translationText = catalog.i18nc("@label", "Aluminum"); + break; + default: + translationText = null; + } + return translationText; + } +} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml index 8231870c21..5eaeff2e84 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml @@ -26,6 +26,7 @@ Item ExpandableCard { + borderColor: printJob.configurationChanges.length !== 0 ? "#f5a623" : "#EAEAEC" // TODO: Theme! headerItem: Row { height: 48 * screenScaleFactor // TODO: Theme! diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml index ec26bbe568..5acd350abb 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml @@ -23,7 +23,7 @@ Item anchors.fill: parent opacity: { - if (printJob && (printJob.state == "error" || !printJob.isActive)) + if (printJob && (printJob.state == "error" || printJob.configurationChanges.length > 0 || !printJob.isActive)) { return 0.5 } @@ -60,6 +60,10 @@ Item height: 0.5 * printJobPreview.height source: { + if (printJob.configurationChanges.length > 0) + { + return "../svg/warning-icon.svg" + } switch(printJob.state) { case "error": @@ -75,6 +79,7 @@ Item default: return "" } + return "" } sourceSize { diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml index 88418516ed..e646172a6c 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml @@ -88,6 +88,8 @@ Item return catalog.i18nc("@label:status", "Aborted") } return catalog.i18nc("@label:status", "Finished") + case "finished": + return catalog.i18nc("@label:status", "Finished") case "sent_to_printer": return catalog.i18nc("@label:status", "Preparing...") case "pre_print": diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index 567fff8489..1676c51edf 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -3,6 +3,7 @@ import QtQuick 2.3 import QtQuick.Controls 2.0 +import QtQuick.Dialogs 1.1 import UM 1.3 as UM /** @@ -66,7 +67,7 @@ Item { verticalCenter: parent.verticalCenter } - width: 216 * screenScaleFactor // TODO: Theme! + width: 180 * screenScaleFactor // TODO: Theme! height: printerNameLabel.height + printerFamilyPill.height + 6 * screenScaleFactor // TODO: Theme! Label @@ -150,7 +151,7 @@ Item } border { - color: "#EAEAEC" // TODO: Theme! + color: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 ? "#f5a623" : "#EAEAEC" // TODO: Theme! width: borderSize // TODO: Remove once themed } color: "white" // TODO: Theme! @@ -185,14 +186,15 @@ Item } if (printer && printer.state == "unreachable") { - return catalog.i18nc("@label:status", "Unreachable") + return catalog.i18nc("@label:status", "Unavailable") } - if (printer && printer.state == "idle") + if (printer && !printer.activePrintJob && printer.state == "idle") { return catalog.i18nc("@label:status", "Idle") } return "" } + visible: text !== "" } Item @@ -218,7 +220,7 @@ Item { verticalCenter: parent.verticalCenter } - width: 216 * screenScaleFactor // TODO: Theme! + width: 180 * screenScaleFactor // TODO: Theme! height: printerNameLabel.height + printerFamilyPill.height + 6 * screenScaleFactor // TODO: Theme! visible: printer.activePrintJob @@ -247,7 +249,7 @@ Item } color: printer.activePrintJob && printer.activePrintJob.isActive ? "#53657d" : "#babac1" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("very_small") // 12pt, regular + font: UM.Theme.getFont("default") // 12pt, regular text: printer.activePrintJob ? printer.activePrintJob.owner : "Anonymous" // TODO: I18N width: parent.width @@ -264,8 +266,67 @@ Item verticalCenter: parent.verticalCenter } printJob: printer.activePrintJob - visible: printer.activePrintJob + visible: printer.activePrintJob && printer.activePrintJob.configurationChanges.length === 0 + } + + Label + { + anchors + { + verticalCenter: parent.verticalCenter + } + font: UM.Theme.getFont("default") + text: "Requires configuration changes" + visible: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter } } + + Button + { + id: detailsButton + anchors + { + verticalCenter: parent.verticalCenter + right: parent.right + rightMargin: 18 * screenScaleFactor // TODO: Theme! + } + background: Rectangle + { + color: "#d8d8d8" // TODO: Theme! + radius: 2 * screenScaleFactor // Todo: Theme! + Rectangle + { + anchors.fill: parent + anchors.bottomMargin: 2 * screenScaleFactor // TODO: Theme! + color: detailsButton.hovered ? "#e4e4e4" : "#f0f0f0" // TODO: Theme! + radius: 2 * screenScaleFactor // Todo: Theme! + } + } + contentItem: Label + { + anchors.fill: parent + anchors.bottomMargin: 2 * screenScaleFactor // TODO: Theme! + color: "#1e66d7" // TODO: Theme! + font: UM.Theme.getFont("medium") // 14pt, regular + text: "Details" // TODO: I18NC! + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + height: 18 * screenScaleFactor // TODO: Theme! + } + implicitHeight: 32 * screenScaleFactor // TODO: Theme! + implicitWidth: 96 * screenScaleFactor // TODO: Theme! + visible: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 + onClicked: overrideConfirmationDialog.open() + } + } + + MonitorConfigOverrideDialog + { + id: overrideConfirmationDialog + printer: base.printer } } \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index e31229680c..292011929d 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -608,16 +608,6 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): def _createMaterialOutputModel(self, material_data: Dict[str, Any]) -> "MaterialOutputModel": material_manager = CuraApplication.getInstance().getMaterialManager() material_group_list = material_manager.getMaterialGroupListByGUID(material_data["guid"]) - # This can happen if the connected machine has no material in one or more extruders (if GUID is empty), or the - # material is unknown to Cura, so we should return an "empty" or "unknown" material model. - if material_group_list is None: - material_name = "Empty" if len(material_data["guid"]) == 0 else "Unknown" - return MaterialOutputModel(guid = material_data["guid"], - type = material_data.get("type", ""), - color = material_data.get("color", ""), - brand = material_data.get("brand", ""), - name = material_data.get("name", material_name) - ) # Sort the material groups by "is_read_only = True" first, and then the name alphabetically. read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list))