diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 5ef3d4d1d1..679fe71650 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -525,6 +525,12 @@ class MachineManager(QObject): return has_remote_connection return False + @pyqtProperty("QVariantList", notify=globalContainerChanged) + def activeMachineConfiguredConnectionTypes(self): + if self._global_container_stack: + return self._global_container_stack.configuredConnectionTypes + return [] + @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineIsGroup(self) -> bool: return bool(self._printer_output_devices) and len(self._printer_output_devices[0].printers) > 1 diff --git a/plugins/MonitorStage/MonitorMain.qml b/plugins/MonitorStage/MonitorMain.qml index 5fda32db9e..a73650ed6a 100644 --- a/plugins/MonitorStage/MonitorMain.qml +++ b/plugins/MonitorStage/MonitorMain.qml @@ -2,20 +2,43 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 -import QtQuick.Controls 1.4 - +import QtQuick.Controls 2.0 import UM 1.3 as UM import Cura 1.0 as Cura - // We show a nice overlay on the 3D viewer when the current output device has no monitor view Rectangle { id: viewportOverlay + property bool isConnected: Cura.MachineManager.activeMachineHasActiveNetworkConnection || Cura.MachineManager.activeMachineHasActiveCloudConnection + property bool isNetworkConfigurable: ["Ultimaker 3", "Ultimaker 3 Extended", "Ultimaker S5"].indexOf(Cura.MachineManager.activeMachineDefinitionName) > -1 + property bool isNetworkConfigured: + { + // Readability: + var connectedTypes = [2, 3]; + var types = Cura.MachineManager.activeMachineConfiguredConnectionTypes + + // Check if configured connection types includes either 2 or 3 (LAN or cloud) + for (var i = 0; i < types.length; i++) + { + if (connectedTypes.indexOf(types[i]) >= 0) + { + return true + } + } + return false + } + color: UM.Theme.getColor("viewport_overlay") anchors.fill: parent + UM.I18nCatalog + { + id: catalog + name: "cura" + } + // This mouse area is to prevent mouse clicks to be passed onto the scene. MouseArea { @@ -29,6 +52,8 @@ Rectangle { anchors.fill: parent } + + // CASE 1: CAN MONITOR & CONNECTED Loader { id: monitorViewComponent @@ -42,4 +67,118 @@ Rectangle sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem : null } + + // CASE 2 & 3: Empty states + Column + { + anchors + { + top: parent.top + topMargin: UM.Theme.getSize("monitor_empty_state_offset").height + horizontalCenter: parent.horizontalCenter + } + width: UM.Theme.getSize("monitor_empty_state_size").width + spacing: UM.Theme.getSize("default_margin").height + visible: monitorViewComponent.sourceComponent == null + + // CASE 2: CAN MONITOR & NOT CONNECTED + Label + { + anchors + { + horizontalCenter: parent.horizontalCenter + } + visible: isNetworkConfigured && !isConnected + text: catalog.i18nc("@info", "Please make sure your printer has a connection:\n- Check if the printer is turned on.\n- Check if the printer is connected to the network.") + font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("monitor_text_primary") + wrapMode: Text.WordWrap + lineHeight: UM.Theme.getSize("monitor_text_line_large").height + lineHeightMode: Text.FixedHeight + width: contentWidth + } + + // CASE 3: CAN NOT MONITOR + Label + { + id: noNetworkLabel + anchors + { + horizontalCenter: parent.horizontalCenter + } + visible: !isNetworkConfigured + text: catalog.i18nc("@info", "Please select a network connected printer to monitor.") + font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("monitor_text_primary") + wrapMode: Text.WordWrap + width: contentWidth + lineHeight: UM.Theme.getSize("monitor_text_line_large").height + lineHeightMode: Text.FixedHeight + } + Label + { + id: noNetworkUltimakerLabel + anchors + { + horizontalCenter: parent.horizontalCenter + } + visible: !isNetworkConfigured && isNetworkConfigurable + text: catalog.i18nc("@info", "Please connect your Ultimaker printer to your local network.") + font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("monitor_text_primary") + wrapMode: Text.WordWrap + width: contentWidth + lineHeight: UM.Theme.getSize("monitor_text_line_large").height + lineHeightMode: Text.FixedHeight + } + Item + { + anchors + { + left: noNetworkUltimakerLabel.left + } + visible: !isNetworkConfigured && isNetworkConfigurable + height: UM.Theme.getSize("monitor_text_line").height + width: childrenRect.width + + UM.RecolorImage + { + id: externalLinkIcon + anchors.verticalCenter: parent.verticalCenter + color: UM.Theme.getColor("monitor_text_link") + source: UM.Theme.getIcon("external_link") + width: UM.Theme.getSize("monitor_external_link_icon").width + height: UM.Theme.getSize("monitor_external_link_icon").height + } + Label + { + id: manageQueueText + anchors + { + left: externalLinkIcon.right + leftMargin: UM.Theme.getSize("narrow_margin").width + verticalCenter: externalLinkIcon.verticalCenter + } + color: UM.Theme.getColor("monitor_text_link") + font: UM.Theme.getFont("medium") // 14pt, regular + linkColor: UM.Theme.getColor("monitor_text_link") + text: catalog.i18nc("@label link to technical assistance", "View user manuals online") + renderType: Text.NativeRendering + } + MouseArea + { + anchors.fill: parent + hoverEnabled: true + onClicked: Qt.openUrlExternally("https://ultimaker.com/en/resources/manuals/ultimaker-3d-printers") + onEntered: + { + manageQueueText.font.underline = true + } + onExited: + { + manageQueueText.font.underline = false + } + } + } + } } \ No newline at end of file diff --git a/plugins/UFPWriter/UFPWriter.py b/plugins/UFPWriter/UFPWriter.py index b3088fc863..c0db104c82 100644 --- a/plugins/UFPWriter/UFPWriter.py +++ b/plugins/UFPWriter/UFPWriter.py @@ -95,10 +95,14 @@ class UFPWriter(MeshWriter): added_materials = [] for extruder_stack in global_stack.extruders.values(): material = extruder_stack.material - material_file_name = material.getMetaData()["base_file"] + ".xml.fdm_material" + try: + material_file_name = material.getMetaData()["base_file"] + ".xml.fdm_material" + except KeyError: + Logger.log("w", "Unable to get base_file for the material %s", material.getId()) + continue material_file_name = "/Materials/" + material_file_name - #Same material cannot be added + # The same material should not be added again. if material_file_name in added_materials: continue diff --git a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml index c839e52892..fae8280488 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml @@ -39,6 +39,7 @@ Item color: base.enabled && headerMouseArea.containsMouse ? headerHoverColor : headerBackgroundColor height: childrenRect.height width: parent.width + radius: 2 * screenScaleFactor // TODO: Theme! Behavior on color { ColorAnimation @@ -77,6 +78,7 @@ Item color: headerBackgroundColor height: base.expanded ? childrenRect.height : 0 width: parent.width + radius: 2 * screenScaleFactor // TODO: Theme! Behavior on height { NumberAnimation diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml index c7588b83bc..0bf3d0ca52 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml @@ -58,6 +58,7 @@ Item width: Math.round(parent.width / 2) height: parent.height visible: !printJob + radius: 2 * screenScaleFactor // TODO: Theme! } Label { @@ -84,6 +85,7 @@ Item width: Math.round(parent.width / 3) height: parent.height visible: !printJob + radius: 2 * screenScaleFactor // TODO: Theme! } Label { @@ -111,6 +113,7 @@ Item width: 72 * screenScaleFactor // TODO: Theme! height: parent.height visible: !printJob + radius: 2 * screenScaleFactor // TODO: Theme! } Label diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml index c9996849fb..c75bd4190f 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml @@ -57,9 +57,9 @@ Item verticalCenter: externalLinkIcon.verticalCenter } color: UM.Theme.getColor("monitor_text_link") - font: UM.Theme.getFont("default") // 12pt, regular + font: UM.Theme.getFont("medium") // 14pt, regular linkColor: UM.Theme.getColor("monitor_text_link") - text: catalog.i18nc("@label link to connect manager", "Manage queue in Cura Connect") + text: catalog.i18nc("@label link to connect manager", "Go to Cura Connect") renderType: Text.NativeRendering } } @@ -160,8 +160,101 @@ Item } printJob: modelData } - model: OutputDevice.receivedPrintJobs ? OutputDevice.queuedPrintJobs : [null,null] + model: + { + // When printing over the cloud we don't recieve print jobs until there is one, so + // unless there's at least one print job we'll be stuck with skeleton loading + // indefinitely. + if (Cura.MachineManager.activeMachineHasActiveCloudConnection) + { + return OutputDevice.queuedPrintJobs + } + return OutputDevice.receivedPrintJobs ? OutputDevice.queuedPrintJobs : [null,null] + } spacing: 6 // TODO: Theme! } } + + Rectangle + { + anchors + { + horizontalCenter: parent.horizontalCenter + top: printJobQueueHeadings.bottom + topMargin: 12 * screenScaleFactor // TODO: Theme! + } + height: 48 * screenScaleFactor // TODO: Theme! + width: parent.width + color: UM.Theme.getColor("monitor_card_background") + border.color: UM.Theme.getColor("monitor_card_border") + radius: 2 * screenScaleFactor // TODO: Theme! + + visible: printJobList.model.length == 0 + + Row + { + anchors + { + left: parent.left + leftMargin: 18 * screenScaleFactor // TODO: Theme! + verticalCenter: parent.verticalCenter + } + spacing: 18 * screenScaleFactor // TODO: Theme! + height: 18 * screenScaleFactor // TODO: Theme! + + Label + { + text: "All jobs are printed." + color: UM.Theme.getColor("monitor_text_primary") + font: UM.Theme.getFont("medium") // 14pt, regular + } + + Item + { + id: viewPrintHistoryLabel + + height: 18 * screenScaleFactor // TODO: Theme! + width: childrenRect.width + + UM.RecolorImage + { + id: printHistoryIcon + anchors.verticalCenter: parent.verticalCenter + color: UM.Theme.getColor("monitor_text_link") + source: UM.Theme.getIcon("external_link") + width: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!) + height: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!) + } + Label + { + id: viewPrintHistoryText + anchors + { + left: printHistoryIcon.right + leftMargin: 6 * screenScaleFactor // TODO: Theme! + verticalCenter: printHistoryIcon.verticalCenter + } + color: UM.Theme.getColor("monitor_text_link") + font: UM.Theme.getFont("medium") // 14pt, regular + linkColor: UM.Theme.getColor("monitor_text_link") + text: catalog.i18nc("@label link to connect manager", "View print history") + renderType: Text.NativeRendering + } + MouseArea + { + anchors.fill: parent + hoverEnabled: true + onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel() + onEntered: + { + viewPrintHistoryText.font.underline = true + } + onExited: + { + viewPrintHistoryText.font.underline = false + } + } + } + } + } } \ No newline at end of file diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 2b516fb553..752773723e 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -115,7 +115,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): def requestWrite(self, nodes, file_name = None, filter_by_machine = False, file_handler = None, **kwargs): if self._is_printing: return # Aleady printing - + self.writeStarted.emit(self) # cancel any ongoing preheat timer before starting a print self._printers[0].getController().stopPreheatTimers() diff --git a/resources/qml/ActionPanel/ActionPanelWidget.qml b/resources/qml/ActionPanel/ActionPanelWidget.qml index 1d9ee95548..1f68fe90ed 100644 --- a/resources/qml/ActionPanel/ActionPanelWidget.qml +++ b/resources/qml/ActionPanel/ActionPanelWidget.qml @@ -12,45 +12,85 @@ import Cura 1.0 as Cura // This element hold all the elements needed for the user to trigger the slicing process, and later // to get information about the printing times, material consumption and the output process (such as // saving to a file, printing over network, ... -Rectangle +Item { - id: actionPanelWidget + id: base + width: childrenRect.width + height: childrenRect.height - width: UM.Theme.getSize("action_panel_widget").width - height: childrenRect.height + 2 * UM.Theme.getSize("thick_margin").height - - color: UM.Theme.getColor("main_background") - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - radius: UM.Theme.getSize("default_radius").width - z: 10 - - property bool outputAvailable: UM.Backend.state == UM.Backend.Done || UM.Backend.state == UM.Backend.Disabled - - Loader + Rectangle { - id: loader - anchors + id: actionPanelWidget + + width: UM.Theme.getSize("action_panel_widget").width + height: childrenRect.height + 2 * UM.Theme.getSize("thick_margin").height + anchors. right: parent.right + color: UM.Theme.getColor("main_background") + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + radius: UM.Theme.getSize("default_radius").width + z: 10 + + property bool outputAvailable: UM.Backend.state == UM.Backend.Done || UM.Backend.state == UM.Backend.Disabled + + Loader { - top: parent.top - topMargin: UM.Theme.getSize("thick_margin").height - left: parent.left - leftMargin: UM.Theme.getSize("thick_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("thick_margin").width + id: loader + anchors + { + top: parent.top + topMargin: UM.Theme.getSize("thick_margin").height + left: parent.left + leftMargin: UM.Theme.getSize("thick_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("thick_margin").width + } + sourceComponent: actionPanelWidget.outputAvailable ? outputProcessWidget : sliceProcessWidget + } + + Component + { + id: sliceProcessWidget + SliceProcessWidget { } + } + + Component + { + id: outputProcessWidget + OutputProcessWidget { } } - sourceComponent: outputAvailable ? outputProcessWidget : sliceProcessWidget } - Component + Item { - id: sliceProcessWidget - SliceProcessWidget { } + id: additionalComponents + width: childrenRect.width + anchors.right: actionPanelWidget.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width + anchors.bottom: actionPanelWidget.bottom + anchors.bottomMargin: UM.Theme.getSize("thick_margin").height * 2 + visible: actionPanelWidget.visible + Row + { + id: additionalComponentsRow + anchors.verticalCenter: parent.verticalCenter + spacing: UM.Theme.getSize("default_margin").width + } } - Component + Component.onCompleted: base.addAdditionalComponents() + + Connections { - id: outputProcessWidget - OutputProcessWidget { } + target: CuraApplication + onAdditionalComponentsChanged: base.addAdditionalComponents() + } + + function addAdditionalComponents() + { + for (var component in CuraApplication.additionalComponents["saveButton"]) + { + CuraApplication.additionalComponents["saveButton"][component].parent = additionalComponentsRow + } } } \ No newline at end of file diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 0e98806e5c..3ad8c7692c 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -270,39 +270,6 @@ UM.MainWindow visible: CuraApplication.platformActivity && (main.item == null || !qmlTypeOf(main.item, "QQuickRectangle")) } - Item - { - id: additionalComponents - width: childrenRect.width - anchors.right: actionPanelWidget.left - anchors.rightMargin: UM.Theme.getSize("default_margin").width - anchors.bottom: actionPanelWidget.bottom - anchors.bottomMargin: UM.Theme.getSize("thick_margin").height * 2 - visible: actionPanelWidget.visible - Row - { - id: additionalComponentsRow - anchors.verticalCenter: parent.verticalCenter - spacing: UM.Theme.getSize("default_margin").width - } - } - - Component.onCompleted: contentItem.addAdditionalComponents() - - Connections - { - target: CuraApplication - onAdditionalComponentsChanged: contentItem.addAdditionalComponents("saveButton") - } - - function addAdditionalComponents() - { - for (var component in CuraApplication.additionalComponents["saveButton"]) - { - CuraApplication.additionalComponents["saveButton"][component].parent = additionalComponentsRow - } - } - Loader { // A stage can control this area. If nothing is set, it will therefore show the 3D view. diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 6211320f10..79ee929d6f 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -9,7 +9,7 @@ "wide_lining": [31, 36, 39, 255], "thick_lining": [255, 255, 255, 30], "lining": [64, 69, 72, 255], - "viewport_overlay": [0, 6, 9, 222], + "viewport_overlay": [30, 36, 39, 255], "primary": [12, 169, 227, 255], "primary_hover": [48, 182, 231, 255], diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 3ac7d60fee..7a39c8f418 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -146,7 +146,7 @@ "wide_lining": [245, 245, 245, 255], "thick_lining": [127, 127, 127, 255], "lining": [192, 193, 194, 255], - "viewport_overlay": [0, 0, 0, 192], + "viewport_overlay": [246, 246, 246, 255], "primary": [50, 130, 255, 255], "primary_shadow": [64, 47, 205, 255], @@ -598,10 +598,14 @@ "monitor_config_override_box": [1.0, 14.0], "monitor_extruder_circle": [2.75, 2.75], - "monitor_text_line": [1.16, 1.16], + "monitor_text_line": [1.5, 1.5], + "monitor_text_line_large": [2.33, 2.33], "monitor_thick_lining": [0.16, 0.16], "monitor_corner_radius": [0.3, 0.3], "monitor_shadow_radius": [0.4, 0.4], - "monitor_shadow_offset": [0.15, 0.15] + "monitor_shadow_offset": [0.15, 0.15], + "monitor_empty_state_offset": [5.6, 5.6], + "monitor_empty_state_size": [35.0, 25.0], + "monitor_external_link_icon": [1.16, 1.16] } }