From 0d8302d864fc36dd466c9f0c481f574da59aae41 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Feb 2018 11:23:04 +0100 Subject: [PATCH 01/66] CURA-4870 Start showing the list of printers separating between local and networked priters. --- resources/qml/Menus/LocalPrinterMenu.qml | 26 +++++++++++++++++ resources/qml/Menus/NetworkPrinterMenu.qml | 26 +++++++++++++++++ resources/qml/Menus/PrinterMenu.qml | 34 +++++++++++----------- resources/qml/Topbar.qml | 2 +- 4 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 resources/qml/Menus/LocalPrinterMenu.qml create mode 100644 resources/qml/Menus/NetworkPrinterMenu.qml diff --git a/resources/qml/Menus/LocalPrinterMenu.qml b/resources/qml/Menus/LocalPrinterMenu.qml new file mode 100644 index 0000000000..ef9a7b13b0 --- /dev/null +++ b/resources/qml/Menus/LocalPrinterMenu.qml @@ -0,0 +1,26 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.4 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Instantiator +{ + model: UM.ContainerStacksModel + { + filter: {"type": "machine", "um_network_key": null} + } + MenuItem + { + text: model.name; + checkable: true; + checked: Cura.MachineManager.activeMachineId == model.id + exclusiveGroup: group; + onTriggered: Cura.MachineManager.setActiveMachine(model.id); + } + onObjectAdded: menu.insertItem(index, object) + onObjectRemoved: menu.removeItem(object) +} diff --git a/resources/qml/Menus/NetworkPrinterMenu.qml b/resources/qml/Menus/NetworkPrinterMenu.qml new file mode 100644 index 0000000000..3dadad3913 --- /dev/null +++ b/resources/qml/Menus/NetworkPrinterMenu.qml @@ -0,0 +1,26 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.4 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Instantiator +{ + model: UM.ContainerStacksModel + { + filter: {"type": "machine", "um_network_key": "*"} + } + MenuItem + { + text: model.name; + checkable: true; + checked: Cura.MachineManager.activeMachineId == model.id + exclusiveGroup: group; + onTriggered: Cura.MachineManager.setActiveMachine(model.id); + } + onObjectAdded: menu.insertItem(index, object) + onObjectRemoved: menu.removeItem(object) +} diff --git a/resources/qml/Menus/PrinterMenu.qml b/resources/qml/Menus/PrinterMenu.qml index 073723a60d..0d60606fb9 100644 --- a/resources/qml/Menus/PrinterMenu.qml +++ b/resources/qml/Menus/PrinterMenu.qml @@ -1,8 +1,8 @@ -// Copyright (c) 2016 Ultimaker B.V. +// Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick.Controls 1.4 import UM 1.2 as UM import Cura 1.0 as Cura @@ -11,24 +11,24 @@ Menu { id: menu; - Instantiator + MenuItem { - model: UM.ContainerStacksModel - { - filter: {"type": "machine"} - } - MenuItem - { - text: model.name; - checkable: true; - checked: Cura.MachineManager.activeMachineId == model.id - exclusiveGroup: group; - onTriggered: Cura.MachineManager.setActiveMachine(model.id); - } - onObjectAdded: menu.insertItem(index, object) - onObjectRemoved: menu.removeItem(object) + text: "Network printers" + checkable: false } + NetworkPrinterMenu { } + + MenuSeparator { } + + MenuItem + { + text: "Local printers" + checkable: false + } + + LocalPrinterMenu { } + ExclusiveGroup { id: group; } MenuSeparator { } diff --git a/resources/qml/Topbar.qml b/resources/qml/Topbar.qml index 950b9ec12d..69d27d483a 100644 --- a/resources/qml/Topbar.qml +++ b/resources/qml/Topbar.qml @@ -150,7 +150,7 @@ Rectangle visible: base.width - allItemsWidth - 1 * this.width > 0 } - // #5 Left view + // #5 Right view Button { iconSource: UM.Theme.getIcon("view_right") From 6fca1f1589677a9bb90bb6dfeab00d82b8e386d2 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Feb 2018 13:14:18 +0100 Subject: [PATCH 02/66] CURA-4870 Add i18n labels --- resources/qml/Menus/PrinterMenu.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/qml/Menus/PrinterMenu.qml b/resources/qml/Menus/PrinterMenu.qml index 0d60606fb9..283063b522 100644 --- a/resources/qml/Menus/PrinterMenu.qml +++ b/resources/qml/Menus/PrinterMenu.qml @@ -13,8 +13,8 @@ Menu MenuItem { - text: "Network printers" - checkable: false + text: catalog.i18nc("@label:category menu label", "Network printers") + enabled: false } NetworkPrinterMenu { } @@ -23,8 +23,8 @@ Menu MenuItem { - text: "Local printers" - checkable: false + text: catalog.i18nc("@label:category menu label", "Local printers") + enabled: false } LocalPrinterMenu { } From ac635ba748239d0f91d85879f659eb0229082db9 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Feb 2018 17:10:19 +0100 Subject: [PATCH 03/66] CURA-4870 Add mock-up for the printer type dropdown selector. Add mock-up for the configuration selection. --- resources/qml/Menus/ConfigurationItem.qml | 45 ++++++++ .../qml/Menus/ConfigurationSelection.qml | 109 ++++++++++++++++++ resources/qml/Sidebar.qml | 12 +- resources/qml/SidebarHeader.qml | 56 +++++++++ 4 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 resources/qml/Menus/ConfigurationItem.qml create mode 100644 resources/qml/Menus/ConfigurationSelection.qml diff --git a/resources/qml/Menus/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationItem.qml new file mode 100644 index 0000000000..aed37facf9 --- /dev/null +++ b/resources/qml/Menus/ConfigurationItem.qml @@ -0,0 +1,45 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.0 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +ItemDelegate +{ + contentItem: Label + { + text: model.name + renderType: Text.NativeRendering + color: UM.Theme.getColor("setting_control_text") + font: UM.Theme.getFont("default") + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + rightPadding: swatch.width + UM.Theme.getSize("setting_unit_margin").width + + background: Rectangle + { + id: swatch + height: Math.round(UM.Theme.getSize("setting_control").height / 2) + width: height + + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4) + + border.width: UM.Theme.getSize("default_lining").width + border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border") + radius: Math.round(width / 2) + + color: control.model.getItem(index).color + } + } + + background: Rectangle + { + color: parent.highlighted ? UM.Theme.getColor("setting_control_highlight") : "transparent" + border.color: parent.highlighted ? UM.Theme.getColor("setting_control_border_highlight") : "transparent" + } +} \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationSelection.qml b/resources/qml/Menus/ConfigurationSelection.qml new file mode 100644 index 0000000000..d0784f4432 --- /dev/null +++ b/resources/qml/Menus/ConfigurationSelection.qml @@ -0,0 +1,109 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.0 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +ComboBox +{ + id: control + + property var panelWidth: control.width + + model: Cura.ExtrudersModel { } + + textRole: "name" + + indicator: UM.RecolorImage + { + id: downArrow + x: control.width - width - control.rightPadding + y: control.topPadding + Math.round((control.availableHeight - height) / 2) + + source: UM.Theme.getIcon("arrow_bottom") + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + 5 * screenScaleFactor + sourceSize.height: width + 5 * screenScaleFactor + + color: UM.Theme.getColor("setting_control_text"); + } + + background: Rectangle + { + color: + { + if (!enabled) + { + return UM.Theme.getColor("setting_control_disabled"); + } + if (control.hovered || control.activeFocus) + { + return UM.Theme.getColor("setting_control_highlight"); + } + return UM.Theme.getColor("setting_control"); + } + border.width: UM.Theme.getSize("default_lining").width + border.color: + { + if (!enabled) + { + return UM.Theme.getColor("setting_control_disabled_border") + } + if (control.hovered || control.activeFocus) + { + return UM.Theme.getColor("setting_control_border_highlight") + } + return UM.Theme.getColor("setting_control_border") + } + } + + contentItem: Label + { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width + anchors.right: downArrow.left + rightPadding: swatch.width + UM.Theme.getSize("setting_unit_margin").width + + text: "HOLA" + renderType: Text.NativeRendering + font: UM.Theme.getFont("default") + color: enabled ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text") + + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + popup: Popup { + y: control.height - UM.Theme.getSize("default_lining").height + x: control.width - width + width: panelWidth + implicitHeight: contentItem.implicitHeight + padding: UM.Theme.getSize("default_lining").width + + contentItem: GridView { + clip: true + implicitHeight: contentHeight + model: control.popup.visible ? control.delegateModel : null + currentIndex: control.highlightedIndex + + ScrollIndicator.vertical: ScrollIndicator { } + } + + background: Rectangle { + color: UM.Theme.getColor("setting_control") + border.color: UM.Theme.getColor("setting_control_border") + } + } + + delegate: ConfigurationItem + { + width: panelWidth - 2 * UM.Theme.getSize("default_lining").width + height: control.height + highlighted: control.highlightedIndex == index + } +} \ No newline at end of file diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index 57a8e8beaa..e5e497276b 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -87,10 +87,20 @@ Rectangle MachineSelection { id: machineSelection - width: base.width + width: base.width - configSelection.width + height: UM.Theme.getSize("sidebar_header").height + anchors.top: base.top + anchors.left: parent.left + } + + ConfigurationSelection { + id: configSelection + visible: printerConnected && !sidebar.monitoringPrint && !sidebar.hideSettings + width: visible ? Math.round(base.width * 0.25) : 0 height: UM.Theme.getSize("sidebar_header").height anchors.top: base.top anchors.right: parent.right + panelWidth: base.width } SidebarHeader { diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index d43b8d3752..52a03b46bb 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -16,6 +16,7 @@ Column property int currentExtruderIndex: Cura.ExtruderManager.activeExtruderIndex; property bool currentExtruderVisible: extrudersList.visible; + property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 spacing: Math.round(UM.Theme.getSize("sidebar_margin").width * 0.9) @@ -34,6 +35,55 @@ Column width: height } + // Printer Type Row + Item + { + id: printerTypeSelectionRow + height: UM.Theme.getSize("sidebar_setup").height + visible: printerConnected && !sidebar.monitoringPrint && !sidebar.hideSettings + + anchors + { + left: parent.left + leftMargin: UM.Theme.getSize("sidebar_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("sidebar_margin").width + } + + Label + { + id: configurationLabel + text: catalog.i18nc("@label", "Printer type"); + width: Math.round(parent.width * 0.4 - UM.Theme.getSize("default_margin").width) + height: parent.height + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default"); + color: UM.Theme.getColor("text"); + } + + ToolButton + { + id: configurationSelection + + text: catalog.i18nc("@label", "Printer type"); + height: UM.Theme.getSize("setting_control").height + width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width + anchors.right: parent.right + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; + menu: Menu { + MenuItem + { + text: "Printer type 1" + } + MenuItem + { + text: "Printer type 2" + } + } + } + } + // Extruder Row Item { @@ -244,6 +294,8 @@ Column id: materialLabel text: catalog.i18nc("@label", "Material"); width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) + height: parent.height + verticalAlignment: Text.AlignVCenter font: UM.Theme.getFont("default"); color: UM.Theme.getColor("text"); } @@ -294,6 +346,8 @@ Column id: variantLabel text: Cura.MachineManager.activeDefinitionVariantsName; width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) + height: parent.height + verticalAlignment: Text.AlignVCenter font: UM.Theme.getFont("default"); color: UM.Theme.getColor("text"); } @@ -347,6 +401,8 @@ Column id: bulidplateLabel text: catalog.i18nc("@label", "Build plate"); width: Math.floor(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) + height: parent.height + verticalAlignment: Text.AlignVCenter font: UM.Theme.getFont("default"); color: UM.Theme.getColor("text"); } From 3aa37296358192ca34f767e1de175dc4d4f2df34 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 28 Feb 2018 13:36:39 +0100 Subject: [PATCH 04/66] CURA-4870 Add printer type selector that show the unique name list of all the types of printers in a group. --- ...erOuputModel.py => ExtruderOutputModel.py} | 0 cura/PrinterOutput/PrinterOutputController.py | 4 +-- cura/PrinterOutput/PrinterOutputModel.py | 2 +- resources/qml/Menus/ConfigurationItem.qml | 2 +- .../qml/Menus/ConfigurationSelection.qml | 24 +++++++++++-- resources/qml/Menus/PrinterTypeMenu.qml | 36 +++++++++++++++++++ resources/qml/SidebarHeader.qml | 11 +----- 7 files changed, 62 insertions(+), 17 deletions(-) rename cura/PrinterOutput/{ExtruderOuputModel.py => ExtruderOutputModel.py} (100%) create mode 100644 resources/qml/Menus/PrinterTypeMenu.qml diff --git a/cura/PrinterOutput/ExtruderOuputModel.py b/cura/PrinterOutput/ExtruderOutputModel.py similarity index 100% rename from cura/PrinterOutput/ExtruderOuputModel.py rename to cura/PrinterOutput/ExtruderOutputModel.py diff --git a/cura/PrinterOutput/PrinterOutputController.py b/cura/PrinterOutput/PrinterOutputController.py index 86ca10e2d3..1d658e79be 100644 --- a/cura/PrinterOutput/PrinterOutputController.py +++ b/cura/PrinterOutput/PrinterOutputController.py @@ -6,7 +6,7 @@ from UM.Logger import Logger MYPY = False if MYPY: from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel - from cura.PrinterOutput.ExtruderOuputModel import ExtruderOuputModel + from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel @@ -18,7 +18,7 @@ class PrinterOutputController: self.can_control_manually = True self._output_device = output_device - def setTargetHotendTemperature(self, printer: "PrinterOutputModel", extruder: "ExtruderOuputModel", temperature: int): + def setTargetHotendTemperature(self, printer: "PrinterOutputModel", extruder: "ExtruderOutputModel", temperature: int): Logger.log("w", "Set target hotend temperature not implemented in controller") def setTargetBedTemperature(self, printer: "PrinterOutputModel", temperature: int): diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py index 8234989519..01a8203c32 100644 --- a/cura/PrinterOutput/PrinterOutputModel.py +++ b/cura/PrinterOutput/PrinterOutputModel.py @@ -5,7 +5,7 @@ from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant, pyqtSlot from UM.Logger import Logger from typing import Optional, List from UM.Math.Vector import Vector -from cura.PrinterOutput.ExtruderOuputModel import ExtruderOutputModel +from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel MYPY = False if MYPY: diff --git a/resources/qml/Menus/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationItem.qml index aed37facf9..8ed2ebafc2 100644 --- a/resources/qml/Menus/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationItem.qml @@ -33,7 +33,7 @@ ItemDelegate border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border") radius: Math.round(width / 2) - color: control.model.getItem(index).color + color: model.color } } diff --git a/resources/qml/Menus/ConfigurationSelection.qml b/resources/qml/Menus/ConfigurationSelection.qml index d0784f4432..e40e8025a4 100644 --- a/resources/qml/Menus/ConfigurationSelection.qml +++ b/resources/qml/Menus/ConfigurationSelection.qml @@ -13,7 +13,25 @@ ComboBox property var panelWidth: control.width - model: Cura.ExtrudersModel { } + model: ListModel { + + ListElement { + name: "Configuration 1" + color: "yellow" + } + ListElement { + name: "Configuration 2" + color: "black" + } + ListElement { + name: "Configuration 3" + color: "green" + } + ListElement { + name: "Configuration 4" + color: "red" + } + } textRole: "name" @@ -85,7 +103,7 @@ ComboBox implicitHeight: contentItem.implicitHeight padding: UM.Theme.getSize("default_lining").width - contentItem: GridView { + contentItem: ListView { clip: true implicitHeight: contentHeight model: control.popup.visible ? control.delegateModel : null @@ -103,7 +121,7 @@ ComboBox delegate: ConfigurationItem { width: panelWidth - 2 * UM.Theme.getSize("default_lining").width - height: control.height + height: control.height - 2 * UM.Theme.getSize("default_lining").height highlighted: control.highlightedIndex == index } } \ No newline at end of file diff --git a/resources/qml/Menus/PrinterTypeMenu.qml b/resources/qml/Menus/PrinterTypeMenu.qml new file mode 100644 index 0000000000..b4fdb0a1d4 --- /dev/null +++ b/resources/qml/Menus/PrinterTypeMenu.qml @@ -0,0 +1,36 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 + +import UM 1.3 as UM +import Cura 1.0 as Cura + +Menu +{ + id: menu + title: "Printer type" + property var outputDevice: Cura.MachineManager.printerOutputDevices[0] + + Instantiator + { + id: printerTypeInstantiator + model: outputDevice != null ? outputDevice.connectedPrintersTypeCount : null + + MenuItem { + text: modelData.machine_type + checkable: true + checked: false + exclusiveGroup: group +// onTriggered: +// { +// TODO +// } + } + onObjectAdded: menu.insertItem(index, object) + onObjectRemoved: menu.removeItem(object) + } + + ExclusiveGroup { id: group } +} diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 52a03b46bb..637db76c4f 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -71,16 +71,7 @@ Column anchors.right: parent.right style: UM.Theme.styles.sidebar_header_button activeFocusOnPress: true; - menu: Menu { - MenuItem - { - text: "Printer type 1" - } - MenuItem - { - text: "Printer type 2" - } - } + menu: PrinterTypeMenu { } } } From 6952e3f5c16985375d24ede3246fde985ea3ced2 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 28 Feb 2018 19:41:23 +0100 Subject: [PATCH 05/66] CURA-4870 Create a customized popup for the sync dropdown and fill it out with the information about the printers in the group --- resources/qml/Menus/ConfigurationItem.qml | 95 +++++++--- resources/qml/Menus/ConfigurationListView.qml | 57 ++++++ .../qml/Menus/ConfigurationSelection.qml | 163 ++++++++---------- 3 files changed, 194 insertions(+), 121 deletions(-) create mode 100644 resources/qml/Menus/ConfigurationListView.qml diff --git a/resources/qml/Menus/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationItem.qml index 8ed2ebafc2..29e3d1263b 100644 --- a/resources/qml/Menus/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationItem.qml @@ -7,39 +7,82 @@ import QtQuick.Controls 2.0 import UM 1.2 as UM import Cura 1.0 as Cura -ItemDelegate +Rectangle { - contentItem: Label + id: configurationItem + + property var printer: null + signal configurationSelected() + + anchors.leftMargin: 25 + border.width: UM.Theme.getSize("default_lining").width + border.color: "black" + + Rectangle { - text: model.name - renderType: Text.NativeRendering - color: UM.Theme.getColor("setting_control_text") - font: UM.Theme.getFont("default") - elide: Text.ElideRight - verticalAlignment: Text.AlignVCenter - rightPadding: swatch.width + UM.Theme.getSize("setting_unit_margin").width + id: printerInformation - background: Rectangle + Label { - id: swatch - height: Math.round(UM.Theme.getSize("setting_control").height / 2) - width: height - - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4) - - border.width: UM.Theme.getSize("default_lining").width - border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border") - radius: Math.round(width / 2) - - color: model.color + text: printer.name } } - background: Rectangle + Rectangle { - color: parent.highlighted ? UM.Theme.getColor("setting_control_highlight") : "transparent" - border.color: parent.highlighted ? UM.Theme.getColor("setting_control_border_highlight") : "transparent" + id: extruderInformation + + Row + { + id: extrudersRow + + Repeater + { + model: printer.extruders + delegate: Item + { + id: extruderInfo + + width: Math.round(parent.width / 2) + height: childrenRect.height + Label + { + id: materialLabel + text: modelData.activeMaterial != null ? modelData.activeMaterial.name : "" + elide: Text.ElideRight + width: parent.width + font: UM.Theme.getFont("very_small") + } + Label + { + id: printCoreLabel + text: modelData.hotendID + anchors.top: materialLabel.bottom + elide: Text.ElideRight + width: parent.width + font: UM.Theme.getFont("very_small") + opacity: 0.5 + } + } + } + } + } + +// Rectangle +// { +// id: buildplateInformation +// +// Label +// { +// text: printer.name + "-" + printer.type +// } +// } + + MouseArea + { + id: mouse + anchors.fill: parent + onClicked: configurationSelected() + hoverEnabled: true } } \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationListView.qml new file mode 100644 index 0000000000..979e6b07b2 --- /dev/null +++ b/resources/qml/Menus/ConfigurationListView.qml @@ -0,0 +1,57 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.0 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Column +{ + id: base + property var outputDevice: Cura.MachineManager.printerOutputDevices[0] + + Rectangle + { + id: header + color: "red" + height: 25 + width: parent.width + } + + Repeater { + height: childrenRect.height + model: outputDevice != null ? outputDevice.connectedPrintersTypeCount : null + delegate: Rectangle + { + height: childrenRect.height + Label + { + id: printerTypeHeader + text: modelData.machine_type + } + + GridView + { + id: grid + anchors.top: printerTypeHeader.bottom + anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + width: base.width + cellWidth: Math.round(base.width / 2) + cellHeight: 100 * screenScaleFactor + model: outputDevice.printers + delegate: ConfigurationItem + { + height: grid.cellHeight + width: grid.cellWidth + printer: modelData + onConfigurationSelected: + { + outputDevice.setActivePrinter(printer) + } + } + } + } + } +} \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationSelection.qml b/resources/qml/Menus/ConfigurationSelection.qml index e40e8025a4..03f005cebe 100644 --- a/resources/qml/Menus/ConfigurationSelection.qml +++ b/resources/qml/Menus/ConfigurationSelection.qml @@ -2,114 +2,94 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 2.0 +import QtQuick.Controls 1.4 +import QtQuick.Controls 2.3 as QQC2 +import QtQuick.Layouts 1.1 +import QtQuick.Controls.Styles 1.4 import UM 1.2 as UM import Cura 1.0 as Cura -ComboBox +Item { - id: control - + id: configurationSelector property var panelWidth: control.width - - model: ListModel { - - ListElement { - name: "Configuration 1" - color: "yellow" - } - ListElement { - name: "Configuration 2" - color: "black" - } - ListElement { - name: "Configuration 3" - color: "green" - } - ListElement { - name: "Configuration 4" - color: "red" - } - } - - textRole: "name" - - indicator: UM.RecolorImage + property var panelVisible: false + Button { - id: downArrow - x: control.width - width - control.rightPadding - y: control.topPadding + Math.round((control.availableHeight - height) / 2) + text: "SYNC" + width: parent.width + height: parent.height - source: UM.Theme.getIcon("arrow_bottom") - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width + 5 * screenScaleFactor - sourceSize.height: width + 5 * screenScaleFactor - - color: UM.Theme.getColor("setting_control_text"); - } - - background: Rectangle - { - color: + style: ButtonStyle { - if (!enabled) + background: Rectangle { - return UM.Theme.getColor("setting_control_disabled"); + color: + { + if(control.pressed) + { + return UM.Theme.getColor("sidebar_header_active"); + } + else if(control.hovered) + { + return UM.Theme.getColor("sidebar_header_hover"); + } + else + { + return UM.Theme.getColor("sidebar_header_bar"); + } + } + Behavior on color { ColorAnimation { duration: 50; } } + + UM.RecolorImage + { + id: downArrow + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("default_margin").width + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + sourceSize.height: width + color: UM.Theme.getColor("text_emphasis") + source: UM.Theme.getIcon("arrow_bottom") + } + Label + { + id: sidebarComboBoxLabel + color: UM.Theme.getColor("sidebar_header_text_active") + text: control.text + elide: Text.ElideRight + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width * 2 + anchors.right: downArrow.left + anchors.rightMargin: control.rightMargin + anchors.verticalCenter: parent.verticalCenter; + font: UM.Theme.getFont("large") + } } - if (control.hovered || control.activeFocus) - { - return UM.Theme.getColor("setting_control_highlight"); - } - return UM.Theme.getColor("setting_control"); + label: Label {} } - border.width: UM.Theme.getSize("default_lining").width - border.color: + + onClicked: { - if (!enabled) - { - return UM.Theme.getColor("setting_control_disabled_border") - } - if (control.hovered || control.activeFocus) - { - return UM.Theme.getColor("setting_control_border_highlight") - } - return UM.Theme.getColor("setting_control_border") + panelVisible = !panelVisible } } - contentItem: Label + QQC2.Popup { - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width - anchors.right: downArrow.left - rightPadding: swatch.width + UM.Theme.getSize("setting_unit_margin").width - - text: "HOLA" - renderType: Text.NativeRendering - font: UM.Theme.getFont("default") - color: enabled ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text") - - elide: Text.ElideRight - verticalAlignment: Text.AlignVCenter - } - - popup: Popup { - y: control.height - UM.Theme.getSize("default_lining").height - x: control.width - width + id: popup + y: configurationSelector.height - UM.Theme.getSize("default_lining").height + x: configurationSelector.width - width width: panelWidth - implicitHeight: contentItem.implicitHeight + height: 300 //contentItem.height + visible: panelVisible padding: UM.Theme.getSize("default_lining").width - contentItem: ListView { - clip: true - implicitHeight: contentHeight - model: control.popup.visible ? control.delegateModel : null - currentIndex: control.highlightedIndex - - ScrollIndicator.vertical: ScrollIndicator { } + contentItem: ConfigurationListView { + width: panelWidth - 2 * UM.Theme.getSize("default_lining").width } background: Rectangle { @@ -117,11 +97,4 @@ ComboBox border.color: UM.Theme.getColor("setting_control_border") } } - - delegate: ConfigurationItem - { - width: panelWidth - 2 * UM.Theme.getSize("default_lining").width - height: control.height - 2 * UM.Theme.getSize("default_lining").height - highlighted: control.highlightedIndex == index - } } \ No newline at end of file From 135208bfeef1de9834e0c00f52c5c168fece6930 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 2 Mar 2018 13:26:04 +0100 Subject: [PATCH 06/66] CURA-4870 Modify the dropdown look and feel --- resources/qml/Menus/ConfigurationItem.qml | 88 ------------------- resources/qml/Menus/ConfigurationListView.qml | 57 ------------ .../ConfigurationMenu/ConfigurationItem.qml | 72 +++++++++++++++ .../ConfigurationListView.qml | 66 ++++++++++++++ .../ConfigurationSelection.qml | 5 +- .../PrintCoreConfiguration.qml | 35 ++++++++ resources/qml/Sidebar.qml | 1 + 7 files changed, 176 insertions(+), 148 deletions(-) delete mode 100644 resources/qml/Menus/ConfigurationItem.qml delete mode 100644 resources/qml/Menus/ConfigurationListView.qml create mode 100644 resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml create mode 100644 resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml rename resources/qml/Menus/{ => ConfigurationMenu}/ConfigurationSelection.qml (95%) create mode 100644 resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml diff --git a/resources/qml/Menus/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationItem.qml deleted file mode 100644 index 29e3d1263b..0000000000 --- a/resources/qml/Menus/ConfigurationItem.qml +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 2.0 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -Rectangle -{ - id: configurationItem - - property var printer: null - signal configurationSelected() - - anchors.leftMargin: 25 - border.width: UM.Theme.getSize("default_lining").width - border.color: "black" - - Rectangle - { - id: printerInformation - - Label - { - text: printer.name - } - } - - Rectangle - { - id: extruderInformation - - Row - { - id: extrudersRow - - Repeater - { - model: printer.extruders - delegate: Item - { - id: extruderInfo - - width: Math.round(parent.width / 2) - height: childrenRect.height - Label - { - id: materialLabel - text: modelData.activeMaterial != null ? modelData.activeMaterial.name : "" - elide: Text.ElideRight - width: parent.width - font: UM.Theme.getFont("very_small") - } - Label - { - id: printCoreLabel - text: modelData.hotendID - anchors.top: materialLabel.bottom - elide: Text.ElideRight - width: parent.width - font: UM.Theme.getFont("very_small") - opacity: 0.5 - } - } - } - } - } - -// Rectangle -// { -// id: buildplateInformation -// -// Label -// { -// text: printer.name + "-" + printer.type -// } -// } - - MouseArea - { - id: mouse - anchors.fill: parent - onClicked: configurationSelected() - hoverEnabled: true - } -} \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationListView.qml deleted file mode 100644 index 979e6b07b2..0000000000 --- a/resources/qml/Menus/ConfigurationListView.qml +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 2.0 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -Column -{ - id: base - property var outputDevice: Cura.MachineManager.printerOutputDevices[0] - - Rectangle - { - id: header - color: "red" - height: 25 - width: parent.width - } - - Repeater { - height: childrenRect.height - model: outputDevice != null ? outputDevice.connectedPrintersTypeCount : null - delegate: Rectangle - { - height: childrenRect.height - Label - { - id: printerTypeHeader - text: modelData.machine_type - } - - GridView - { - id: grid - anchors.top: printerTypeHeader.bottom - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height - width: base.width - cellWidth: Math.round(base.width / 2) - cellHeight: 100 * screenScaleFactor - model: outputDevice.printers - delegate: ConfigurationItem - { - height: grid.cellHeight - width: grid.cellWidth - printer: modelData - onConfigurationSelected: - { - outputDevice.setActivePrinter(printer) - } - } - } - } - } -} \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml new file mode 100644 index 0000000000..45adfb88f2 --- /dev/null +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -0,0 +1,72 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.0 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Rectangle +{ + id: configurationItem + + property var printer: null + signal configurationSelected() + + height: childrenRect.height + border.width: UM.Theme.getSize("default_lining").width + border.color: "black" + + Column + { + id: contentColumn + padding: UM.Theme.getSize("default_margin").width + spacing: UM.Theme.getSize("default_margin").height + + Label + { + text: printer.name + } + + Row + { + id: extruderRow + + width: parent.width + height: childrenRect.height + + spacing: UM.Theme.getSize("default_margin").width + + Repeater + { + height: childrenRect.height + model: printer.extruders + delegate: PrintCoreConfiguration + { + printCoreConfiguration: modelData + } + } + } + +// Rectangle +// { +// id: buildplateInformation +// +// Label +// { +// text: printer.name + "-" + printer.type +// } +// } + } + + MouseArea + { + id: mouse + anchors.fill: parent + onClicked: configurationSelected() + hoverEnabled: true + onEntered: parent.border.color = UM.Theme.getColor("primary_hover") + onExited: parent.border.color = "black" + } +} \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml new file mode 100644 index 0000000000..1575f47ecc --- /dev/null +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -0,0 +1,66 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.0 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Column +{ + id: base + property var outputDevice: Cura.MachineManager.printerOutputDevices[0] + height: childrenRect.height + 2 * padding + padding: UM.Theme.getSize("default_margin").width + spacing: UM.Theme.getSize("default_margin").height + + Label { + text: catalog.i18nc("@label:header configurations", "Available configurations") + font: UM.Theme.getFont("large") + width: parent.width - 2 * parent.padding + } + + Item + { + id: container + width: parent.width - 2 * parent.padding + height: childrenRect.height + + Repeater { + height: childrenRect.height + model: outputDevice != null ? outputDevice.connectedPrintersTypeCount : null + delegate: Rectangle + { + height: childrenRect.height + Label + { + id: printerTypeHeader + text: modelData.machine_type + font: UM.Theme.getFont("default_bold") + } + + ListView + { + id: grid + anchors.top: printerTypeHeader.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height + width: container.width + height: childrenRect.height + model: outputDevice.printers + delegate: ConfigurationItem + { + height: parent.height + width: parent.width + printer: modelData + onConfigurationSelected: + { + print("SELECCIONANDO IMPRESORA", printer.name) + outputDevice.setActivePrinter(printer) + } + } + } + } + } + } +} \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationSelection.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml similarity index 95% rename from resources/qml/Menus/ConfigurationSelection.qml rename to resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml index 03f005cebe..4b2c3800f0 100644 --- a/resources/qml/Menus/ConfigurationSelection.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml @@ -17,7 +17,7 @@ Item property var panelVisible: false Button { - text: "SYNC" + text: "Matched" width: parent.width height: parent.height @@ -84,12 +84,11 @@ Item y: configurationSelector.height - UM.Theme.getSize("default_lining").height x: configurationSelector.width - width width: panelWidth - height: 300 //contentItem.height visible: panelVisible padding: UM.Theme.getSize("default_lining").width contentItem: ConfigurationListView { - width: panelWidth - 2 * UM.Theme.getSize("default_lining").width + width: panelWidth - 2 * popup.padding } background: Rectangle { diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml new file mode 100644 index 0000000000..c9875ae668 --- /dev/null +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -0,0 +1,35 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.0 + +import UM 1.2 as UM + + +Item +{ + id: extruderInfo + property var printCoreConfiguration + + height: childrenRect.height + + Label + { + id: materialLabel + text: printCoreConfiguration.activeMaterial != null ? printCoreConfiguration.activeMaterial.name : "" + elide: Text.ElideRight + width: parent.width + font: UM.Theme.getFont("very_small") + } + Label + { + id: printCoreLabel + text: printCoreConfiguration.hotendID + anchors.top: materialLabel.bottom + elide: Text.ElideRight + width: parent.width + font: UM.Theme.getFont("very_small") + opacity: 0.5 + } +} diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index e5e497276b..ef7b49098a 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -8,6 +8,7 @@ import QtQuick.Layouts 1.3 import UM 1.2 as UM import Cura 1.0 as Cura import "Menus" +import "Menus/ConfigurationMenu" Rectangle { From dead2122dd0db7c34dfb507462f3839c2bcb9a08 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sat, 3 Mar 2018 20:29:06 +0100 Subject: [PATCH 07/66] CURA-4870 Add list of unique configurations to the output device. The printer output model calculates the configuration every time a change is received from the output device --- cura/PrinterOutput/ConfigurationModel.py | 42 +++++++++++++++++++++++ cura/PrinterOutput/ExtruderOutputModel.py | 21 +++++++++++- cura/PrinterOutput/PrinterOutputModel.py | 20 ++++++++++- cura/PrinterOutputDevice.py | 21 ++++++++++++ 4 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 cura/PrinterOutput/ConfigurationModel.py diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/ConfigurationModel.py new file mode 100644 index 0000000000..bb219a0e2f --- /dev/null +++ b/cura/PrinterOutput/ConfigurationModel.py @@ -0,0 +1,42 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from PyQt5.QtCore import pyqtProperty, QObject + + +class ConfigurationModel(QObject): + + def __init__(self): + self._printer_type = None + self._extruder_configurations = [] + self._buildplate_configuration = None + + def setPrinterType(self, printer_type): + self._printer_type = printer_type + + @pyqtProperty(str, fset = setPrinterType, constant = True) + def printerType(self): + return self._printer_type + + def setExtruderConfigurations(self, extruder_configurations): + self._extruder_configurations = extruder_configurations + + @pyqtProperty("QVariantList", fset = setExtruderConfigurations, constant = True) + def extruderConfigurations(self): + return self._extruder_configurations + + def setBuildplateConfiguration(self, buildplate_configuration): + self._buildplate_configuration = buildplate_configuration + + @pyqtProperty(str, fset = setBuildplateConfiguration, constant = True) + def buildplateConfiguration(self): + return self._buildplate_configuration + + def __eq__(self, other): + return hash(self) == hash(other) + + def __hash__(self): + extruder_hash = hash(0) + for configuration in self.extruderConfigurations: + extruder_hash ^= hash(frozenset(configuration.items())) + return hash(self.printerType) ^ extruder_hash ^ hash(self.buildplateConfiguration) \ No newline at end of file diff --git a/cura/PrinterOutput/ExtruderOutputModel.py b/cura/PrinterOutput/ExtruderOutputModel.py index b0be6cbbe4..33f3bf71f5 100644 --- a/cura/PrinterOutput/ExtruderOutputModel.py +++ b/cura/PrinterOutput/ExtruderOutputModel.py @@ -17,14 +17,20 @@ class ExtruderOutputModel(QObject): targetHotendTemperatureChanged = pyqtSignal() hotendTemperatureChanged = pyqtSignal() activeMaterialChanged = pyqtSignal() + extruderConfigurationChanged = pyqtSignal() - def __init__(self, printer: "PrinterOutputModel", parent=None): + def __init__(self, printer: "PrinterOutputModel", position, parent=None): super().__init__(parent) self._printer = printer + self._position = position self._target_hotend_temperature = 0 self._hotend_temperature = 0 self._hotend_id = "" self._active_material = None # type: Optional[MaterialOutputModel] + self._extruder_configuration = {} + # Update the configuration every time the hotend or the active material change + self.hotendIDChanged.connect(self._updateExtruderConfiguration) + self.activeMaterialChanged.connect(self._updateExtruderConfiguration) @pyqtProperty(QObject, notify = activeMaterialChanged) def activeMaterial(self) -> "MaterialOutputModel": @@ -68,3 +74,16 @@ class ExtruderOutputModel(QObject): if self._hotend_id != id: self._hotend_id = id self.hotendIDChanged.emit() + + @pyqtProperty("QVariantMap", notify = extruderConfigurationChanged) + def extruderConfiguration(self): + return self._extruder_configuration + + def _updateExtruderConfiguration(self): + self._extruder_configuration = { + "position": self._position, + "material": self._active_material.type if self.activeMaterial is not None else None, + "hotend_id": self._hotend_id + } + print("Recalculating extruder configuration:", self._extruder_configuration) + self.extruderConfigurationChanged.emit() diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py index 01a8203c32..0cdec88194 100644 --- a/cura/PrinterOutput/PrinterOutputModel.py +++ b/cura/PrinterOutput/PrinterOutputModel.py @@ -5,6 +5,7 @@ from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant, pyqtSlot from UM.Logger import Logger from typing import Optional, List from UM.Math.Vector import Vector +from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel MYPY = False @@ -24,6 +25,7 @@ class PrinterOutputModel(QObject): keyChanged = pyqtSignal() typeChanged = pyqtSignal() cameraChanged = pyqtSignal() + configurationChanged = pyqtSignal() def __init__(self, output_controller: "PrinterOutputController", number_of_extruders: int = 1, parent=None, firmware_version = ""): super().__init__(parent) @@ -32,13 +34,17 @@ class PrinterOutputModel(QObject): self._name = "" self._key = "" # Unique identifier self._controller = output_controller - self._extruders = [ExtruderOutputModel(printer=self) for i in range(number_of_extruders)] + self._extruders = [ExtruderOutputModel(printer = self, position = i) for i in range(number_of_extruders)] + self._printer_configuration = ConfigurationModel() # Indicates the current configuration setup in this printer self._head_position = Vector(0, 0, 0) self._active_print_job = None # type: Optional[PrintJobOutputModel] self._firmware_version = firmware_version self._printer_state = "unknown" self._is_preheating = False self._type = "" + # Update the configuration every time the one of the extruders changes its configuration + for extruder in self._extruders: + extruder.extruderConfigurationChanged.connect(self._updatePrinterConfiguration) self._camera = None @@ -238,3 +244,15 @@ class PrinterOutputModel(QObject): if self._controller: return self._controller.can_control_manually return False + + # Returns the configuration (material, variant and buildplate) of the current printer + @pyqtProperty(QObject, notify = configurationChanged) + def printerConfiguration(self): + return self._printer_configuration + + def _updatePrinterConfiguration(self): + self._printer_configuration.printerType = self._type + self._printer_configuration.extruderConfigurations = [extruder.extruderConfiguration for extruder in self._extruders] + self._printer_configuration.buildplateConfiguration = None # TODO Add the buildplate information + print("Recalculating printer configuration", self.name, ":", self._printer_configuration) + self.configurationChanged.emit() diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 9e603b83ae..ac8f317689 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -17,6 +17,7 @@ from typing import List, Optional MYPY = False if MYPY: from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel + from cura.PrinterOutput.ConfigurationModel import ConfigurationModel i18n_catalog = i18nCatalog("cura") @@ -44,10 +45,14 @@ class PrinterOutputDevice(QObject, OutputDevice): # Signal to indicate that the info text about the connection has changed. connectionTextChanged = pyqtSignal() + # Signal to indicate that the configuration of one of the printers has changed. + configurationChanged = pyqtSignal() + def __init__(self, device_id, parent = None): super().__init__(device_id = device_id, parent = parent) self._printers = [] # type: List[PrinterOutputModel] + self._unique_configurations = [] # type: List[ConfigurationModel] self._monitor_view_qml_path = "" self._monitor_component = None @@ -69,6 +74,7 @@ class PrinterOutputDevice(QObject, OutputDevice): self._address = "" self._connection_text = "" + self.printersChanged.connect(self._onPrintersChanged) @pyqtProperty(str, notify = connectionTextChanged) def address(self): @@ -175,6 +181,21 @@ class PrinterOutputDevice(QObject, OutputDevice): self.acceptsCommandsChanged.emit() + # Returns the unique configurations of the current printers + @pyqtProperty("QVariantList", notify = configurationChanged) + def uniqueConfiguration(self): + return self._unique_configurations + + def _updateUniqueConfigurations(self): + print("Calculating the unique configurations") + self._unique_configurations = list(set([printer.printerConfiguration for printer in self._printers])) + print(self._unique_configurations) + self.configurationChanged.emit() + + def _onPrintersChanged(self): + for printer in self._printers: + printer.configurationChanged.connect(self._updateUniqueConfigurations) + ## The current processing state of the backend. class ConnectionState(IntEnum): From 6e35fc5035b5333157adcd78797de3e0578c8b67 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 4 Mar 2018 12:53:16 +0100 Subject: [PATCH 08/66] CURA-4870 Modify printer menu visibility of the items. Show local or network submenu only when there is local or network printers respectively --- resources/qml/Menus/PrinterMenu.qml | 35 ++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/resources/qml/Menus/PrinterMenu.qml b/resources/qml/Menus/PrinterMenu.qml index 283063b522..741d927c13 100644 --- a/resources/qml/Menus/PrinterMenu.qml +++ b/resources/qml/Menus/PrinterMenu.qml @@ -3,35 +3,58 @@ import QtQuick 2.2 import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 import UM 1.2 as UM import Cura 1.0 as Cura Menu { - id: menu; + id: menu +// TODO Enable custom style to the menu +// style: MenuStyle +// { +// frame: Rectangle +// { +// color: "white" +// } +// } MenuItem { - text: catalog.i18nc("@label:category menu label", "Network printers") + text: catalog.i18nc("@label:category menu label", "Network enabled printers") enabled: false + visible: networkPrinterMenu.count > 0 } - NetworkPrinterMenu { } + NetworkPrinterMenu + { + id: networkPrinterMenu + } - MenuSeparator { } + MenuSeparator + { + visible: networkPrinterMenu.count > 0 + } MenuItem { text: catalog.i18nc("@label:category menu label", "Local printers") enabled: false + visible: localPrinterMenu.count > 0 } - LocalPrinterMenu { } + LocalPrinterMenu + { + id: localPrinterMenu + } ExclusiveGroup { id: group; } - MenuSeparator { } + MenuSeparator + { + visible: localPrinterMenu.count > 0 + } MenuItem { action: Cura.Actions.addMachine; } MenuItem { action: Cura.Actions.configureMachines; } From 49fcf35d9b6e64cb45145c810a14edc47214a422 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 4 Mar 2018 17:26:37 +0100 Subject: [PATCH 09/66] CURA-4870 Prepare the UI to show the list of configurations --- cura/PrinterOutput/ConfigurationModel.py | 8 ++- cura/PrinterOutput/ExtruderOutputModel.py | 7 +- cura/PrinterOutput/PrinterOutputModel.py | 7 +- cura/PrinterOutputDevice.py | 23 +++--- .../ConfigurationMenu/ConfigurationItem.qml | 8 +-- .../ConfigurationListView.qml | 19 ++--- .../ConfigurationSelection.qml | 68 +----------------- .../PrintCoreConfiguration.qml | 2 +- .../Menus/ConfigurationMenu/SyncButton.qml | 71 +++++++++++++++++++ 9 files changed, 113 insertions(+), 100 deletions(-) create mode 100644 resources/qml/Menus/ConfigurationMenu/SyncButton.qml diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/ConfigurationModel.py index bb219a0e2f..a7219c6a55 100644 --- a/cura/PrinterOutput/ConfigurationModel.py +++ b/cura/PrinterOutput/ConfigurationModel.py @@ -1,11 +1,13 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import pyqtProperty, QObject +from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal class ConfigurationModel(QObject): + configurationChanged = pyqtSignal() + def __init__(self): self._printer_type = None self._extruder_configurations = [] @@ -21,14 +23,14 @@ class ConfigurationModel(QObject): def setExtruderConfigurations(self, extruder_configurations): self._extruder_configurations = extruder_configurations - @pyqtProperty("QVariantList", fset = setExtruderConfigurations, constant = True) + @pyqtProperty("QVariantList", fset = setExtruderConfigurations, notify = configurationChanged) def extruderConfigurations(self): return self._extruder_configurations def setBuildplateConfiguration(self, buildplate_configuration): self._buildplate_configuration = buildplate_configuration - @pyqtProperty(str, fset = setBuildplateConfiguration, constant = True) + @pyqtProperty(str, fset = setBuildplateConfiguration, notify = configurationChanged) def buildplateConfiguration(self): return self._buildplate_configuration diff --git a/cura/PrinterOutput/ExtruderOutputModel.py b/cura/PrinterOutput/ExtruderOutputModel.py index 33f3bf71f5..3e415fb47a 100644 --- a/cura/PrinterOutput/ExtruderOutputModel.py +++ b/cura/PrinterOutput/ExtruderOutputModel.py @@ -1,8 +1,7 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant, pyqtSlot -from UM.Logger import Logger +from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot from typing import Optional @@ -83,7 +82,7 @@ class ExtruderOutputModel(QObject): self._extruder_configuration = { "position": self._position, "material": self._active_material.type if self.activeMaterial is not None else None, - "hotend_id": self._hotend_id + "hotendID": self._hotend_id } print("Recalculating extruder configuration:", self._extruder_configuration) self.extruderConfigurationChanged.emit() diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py index 0cdec88194..9d0c9a81b5 100644 --- a/cura/PrinterOutput/PrinterOutputModel.py +++ b/cura/PrinterOutput/PrinterOutputModel.py @@ -1,9 +1,8 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant, pyqtSlot -from UM.Logger import Logger -from typing import Optional, List +from typing import Optional from UM.Math.Vector import Vector from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel @@ -42,7 +41,7 @@ class PrinterOutputModel(QObject): self._printer_state = "unknown" self._is_preheating = False self._type = "" - # Update the configuration every time the one of the extruders changes its configuration + # Update the printer configuration every time any of the extruders changes its configuration for extruder in self._extruders: extruder.extruderConfigurationChanged.connect(self._updatePrinterConfiguration) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index ac8f317689..4600559fe8 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from UM.i18n import i18nCatalog @@ -6,13 +6,12 @@ from UM.OutputDevice.OutputDevice import OutputDevice from PyQt5.QtCore import pyqtProperty, QObject, QTimer, pyqtSignal from PyQt5.QtWidgets import QMessageBox - from UM.Logger import Logger from UM.Signal import signalemitter from UM.Application import Application from enum import IntEnum # For the connection state tracking. -from typing import List, Optional +from typing import List, Set, Optional MYPY = False if MYPY: @@ -46,13 +45,13 @@ class PrinterOutputDevice(QObject, OutputDevice): connectionTextChanged = pyqtSignal() # Signal to indicate that the configuration of one of the printers has changed. - configurationChanged = pyqtSignal() + uniqueConfigurationsChanged = pyqtSignal() def __init__(self, device_id, parent = None): super().__init__(device_id = device_id, parent = parent) self._printers = [] # type: List[PrinterOutputModel] - self._unique_configurations = [] # type: List[ConfigurationModel] + self._unique_configurations = {} # type: Set[ConfigurationModel] self._monitor_view_qml_path = "" self._monitor_component = None @@ -182,20 +181,22 @@ class PrinterOutputDevice(QObject, OutputDevice): self.acceptsCommandsChanged.emit() # Returns the unique configurations of the current printers - @pyqtProperty("QVariantList", notify = configurationChanged) - def uniqueConfiguration(self): + @pyqtProperty("QVariantMap", notify = uniqueConfigurationsChanged) + def uniqueConfigurations(self): return self._unique_configurations def _updateUniqueConfigurations(self): - print("Calculating the unique configurations") - self._unique_configurations = list(set([printer.printerConfiguration for printer in self._printers])) - print(self._unique_configurations) - self.configurationChanged.emit() + self._unique_configurations = set([printer.printerConfiguration for printer in self._printers]) + self.uniqueConfigurationsChanged.emit() def _onPrintersChanged(self): for printer in self._printers: printer.configurationChanged.connect(self._updateUniqueConfigurations) + # If at this point the list of unique configurations is empty, we force the calculation + if not self._unique_configurations: + self._updateUniqueConfigurations() + ## The current processing state of the backend. class ConnectionState(IntEnum): diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 45adfb88f2..7d9c87edf4 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -11,7 +11,7 @@ Rectangle { id: configurationItem - property var printer: null + property var configuration: null signal configurationSelected() height: childrenRect.height @@ -26,7 +26,7 @@ Rectangle Label { - text: printer.name + text: configuration.printerType } Row @@ -41,7 +41,7 @@ Rectangle Repeater { height: childrenRect.height - model: printer.extruders + model: configuration.extruderConfigurations delegate: PrintCoreConfiguration { printCoreConfiguration: modelData @@ -55,7 +55,7 @@ Rectangle // // Label // { -// text: printer.name + "-" + printer.type +// text: configuration.buildplateConfiguration // } // } } diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 1575f47ecc..fa82f43871 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -2,7 +2,8 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 2.0 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 import UM 1.2 as UM import Cura 1.0 as Cura @@ -21,12 +22,13 @@ Column width: parent.width - 2 * parent.padding } - Item - { + ScrollView { id: container width: parent.width - 2 * parent.padding height: childrenRect.height + style: UM.Theme.styles.scrollview + Repeater { height: childrenRect.height model: outputDevice != null ? outputDevice.connectedPrintersTypeCount : null @@ -42,23 +44,24 @@ Column ListView { - id: grid + id: configurationList anchors.top: printerTypeHeader.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height width: container.width height: childrenRect.height - model: outputDevice.printers + model: outputDevice.uniqueConfigurations delegate: ConfigurationItem { height: parent.height width: parent.width - printer: modelData + configuration: modelData onConfigurationSelected: { - print("SELECCIONANDO IMPRESORA", printer.name) - outputDevice.setActivePrinter(printer) + print("SELECCIONANDO CONFIGURACION", JSON.stringify(configuration)) } + Component.onCompleted: {print("$$$$$$$$$$$$$$$$$$ Configuracion", JSON.stringify(configuration))} } + Component.onCompleted: {print("$$$$$$$$$$$$$$$$$$ Elementos del modelo", JSON.stringify(outputDevice.uniqueConfigurations))} } } } diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml index 4b2c3800f0..4097df229b 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml @@ -2,9 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 1.4 -import QtQuick.Controls 2.3 as QQC2 -import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.3 import QtQuick.Controls.Styles 1.4 import UM 1.2 as UM @@ -15,70 +13,10 @@ Item id: configurationSelector property var panelWidth: control.width property var panelVisible: false - Button - { - text: "Matched" - width: parent.width - height: parent.height - style: ButtonStyle - { - background: Rectangle - { - color: - { - if(control.pressed) - { - return UM.Theme.getColor("sidebar_header_active"); - } - else if(control.hovered) - { - return UM.Theme.getColor("sidebar_header_hover"); - } - else - { - return UM.Theme.getColor("sidebar_header_bar"); - } - } - Behavior on color { ColorAnimation { duration: 50; } } + SyncButton { } - UM.RecolorImage - { - id: downArrow - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: width - color: UM.Theme.getColor("text_emphasis") - source: UM.Theme.getIcon("arrow_bottom") - } - Label - { - id: sidebarComboBoxLabel - color: UM.Theme.getColor("sidebar_header_text_active") - text: control.text - elide: Text.ElideRight - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width * 2 - anchors.right: downArrow.left - anchors.rightMargin: control.rightMargin - anchors.verticalCenter: parent.verticalCenter; - font: UM.Theme.getFont("large") - } - } - label: Label {} - } - - onClicked: - { - panelVisible = !panelVisible - } - } - - QQC2.Popup + Popup { id: popup y: configurationSelector.height - UM.Theme.getSize("default_lining").height diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index c9875ae668..670d618849 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -17,7 +17,7 @@ Item Label { id: materialLabel - text: printCoreConfiguration.activeMaterial != null ? printCoreConfiguration.activeMaterial.name : "" + text: printCoreConfiguration.material elide: Text.ElideRight width: parent.width font: UM.Theme.getFont("very_small") diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml new file mode 100644 index 0000000000..79c75bb55d --- /dev/null +++ b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml @@ -0,0 +1,71 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import UM 1.2 as UM + +Button +{ + text: "Matched" + width: parent.width + height: parent.height + + style: ButtonStyle + { + background: Rectangle + { + color: + { + if(control.pressed) + { + return UM.Theme.getColor("sidebar_header_active"); + } + else if(control.hovered) + { + return UM.Theme.getColor("sidebar_header_hover"); + } + else + { + return UM.Theme.getColor("sidebar_header_bar"); + } + } + Behavior on color { ColorAnimation { duration: 50; } } + + UM.RecolorImage + { + id: downArrow + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("default_margin").width + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + sourceSize.height: width + color: UM.Theme.getColor("text_emphasis") + source: UM.Theme.getIcon("arrow_bottom") + } + Label + { + id: sidebarComboBoxLabel + color: UM.Theme.getColor("sidebar_header_text_active") + text: control.text + elide: Text.ElideRight + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width * 2 + anchors.right: downArrow.left + anchors.rightMargin: control.rightMargin + anchors.verticalCenter: parent.verticalCenter; + font: UM.Theme.getFont("large") + } + } + label: Label {} + } + + onClicked: + { + panelVisible = !panelVisible + } +} \ No newline at end of file From 22b1c2127f3afe56fb36b0b1f9a133ec55a81882 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 4 Mar 2018 18:13:27 +0100 Subject: [PATCH 10/66] CURA-4870 Add information of the current configuration selected in the active printer --- cura/PrinterOutputDevice.py | 5 ++--- cura/Settings/MachineManager.py | 29 ++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 4600559fe8..97fa6c01d9 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -193,9 +193,8 @@ class PrinterOutputDevice(QObject, OutputDevice): for printer in self._printers: printer.configurationChanged.connect(self._updateUniqueConfigurations) - # If at this point the list of unique configurations is empty, we force the calculation - if not self._unique_configurations: - self._updateUniqueConfigurations() + # At this point there may be non-updated configurations + self._updateUniqueConfigurations() ## The current processing state of the backend. diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index cc5c4aa539..d487a0605d 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -27,9 +27,9 @@ from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.SettingFunction import SettingFunction from UM.Signal import postponeSignals, CompressTechnique - from cura.QualityManager import QualityManager from cura.PrinterOutputDevice import PrinterOutputDevice +from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.Settings.ExtruderManager import ExtruderManager from .CuraStackBuilder import CuraStackBuilder @@ -115,6 +115,12 @@ class MachineManager(QObject): # There might already be some output devices by the time the signal is connected self._onOutputDevicesChanged() + self._current_printer_configuration = ConfigurationModel() # Indicates the current configuration setup in this printer + self.activeMaterialChanged.connect(self._onCurrentConfigurationChanged) + self.activeVariantChanged.connect(self._onCurrentConfigurationChanged) + # Force to compute the current configuration + self._onCurrentConfigurationChanged() + if active_machine_id != "" and ContainerRegistry.getInstance().findContainerStacksMetadata(id = active_machine_id): # An active machine was saved, so restore it. self.setActiveMachine(active_machine_id) @@ -146,6 +152,7 @@ class MachineManager(QObject): blurSettings = pyqtSignal() # Emitted to force fields in the advanced sidebar to un-focus, so they update properly outputDevicesChanged = pyqtSignal() + currentConfigurationChanged = pyqtSignal() # Emitted every time the current configurations of the machine changes def _onOutputDevicesChanged(self) -> None: for printer_output_device in self._printer_output_devices: @@ -161,6 +168,26 @@ class MachineManager(QObject): self.outputDevicesChanged.emit() + @pyqtProperty(QObject, notify = currentConfigurationChanged) + def currentConfiguration(self): + return self._current_printer_configuration + + def _onCurrentConfigurationChanged(self) -> None: + if not self._global_container_stack: + return + + self._printer_configuration.printerType = self._global_container_stack.definition.getName() + extruder_configurations = [] + for extruder in self._global_container_stack.extruders: + extruder_configurations.append({ + "position": len(extruder_configurations), + "material": extruder.material.getName() if extruder.material != self._empty_material_container else None, + "hotendID": extruder.variant.getName() if extruder.variant != self._empty_variant_container else None + }) + self._printer_configuration.extruderConfigurations = extruder_configurations + self._printer_configuration.buildplateConfiguration = self._global_container_stack.variant.getName() if self._global_container_stack.variant is not None else None + self.currentConfigurationChanged.emit() + @property def newVariant(self): return self._new_variant_container From 1ee5b441878e92225675aa31fb4f49d2a25fe095 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 4 Mar 2018 18:20:42 +0100 Subject: [PATCH 11/66] CURA-4870 Fix references to the extruder stacks --- cura/Settings/MachineManager.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index d487a0605d..f148942336 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -176,16 +176,17 @@ class MachineManager(QObject): if not self._global_container_stack: return - self._printer_configuration.printerType = self._global_container_stack.definition.getName() + self._current_printer_configuration.printerType = self._global_container_stack.definition.getName() extruder_configurations = [] - for extruder in self._global_container_stack.extruders: + for extruder in self._global_container_stack.extruders.values(): extruder_configurations.append({ "position": len(extruder_configurations), "material": extruder.material.getName() if extruder.material != self._empty_material_container else None, "hotendID": extruder.variant.getName() if extruder.variant != self._empty_variant_container else None }) - self._printer_configuration.extruderConfigurations = extruder_configurations - self._printer_configuration.buildplateConfiguration = self._global_container_stack.variant.getName() if self._global_container_stack.variant is not None else None + self._current_printer_configuration.extruderConfigurations = extruder_configurations + self._current_printer_configuration.buildplateConfiguration = self._global_container_stack.variant.getName() if self._global_container_stack.variant is not None else None + print(self._current_printer_configuration.extruderConfigurations) self.currentConfigurationChanged.emit() @property From b8ad0959a744785360a29b0b4824b1952a906521 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 5 Mar 2018 09:41:22 +0100 Subject: [PATCH 12/66] CURA-4870 Add call to the QObject constructor --- cura/PrinterOutput/ConfigurationModel.py | 1 + cura/PrinterOutputDevice.py | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/ConfigurationModel.py index a7219c6a55..5102dff239 100644 --- a/cura/PrinterOutput/ConfigurationModel.py +++ b/cura/PrinterOutput/ConfigurationModel.py @@ -9,6 +9,7 @@ class ConfigurationModel(QObject): configurationChanged = pyqtSignal() def __init__(self): + super().__init__() self._printer_type = None self._extruder_configurations = [] self._buildplate_configuration = None diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 97fa6c01d9..875cc17fe8 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -3,7 +3,7 @@ from UM.i18n import i18nCatalog from UM.OutputDevice.OutputDevice import OutputDevice -from PyQt5.QtCore import pyqtProperty, QObject, QTimer, pyqtSignal +from PyQt5.QtCore import pyqtProperty, QObject, QTimer, pyqtSignal, QVariant from PyQt5.QtWidgets import QMessageBox from UM.Logger import Logger @@ -11,7 +11,7 @@ from UM.Signal import signalemitter from UM.Application import Application from enum import IntEnum # For the connection state tracking. -from typing import List, Set, Optional +from typing import List, Optional MYPY = False if MYPY: @@ -51,7 +51,7 @@ class PrinterOutputDevice(QObject, OutputDevice): super().__init__(device_id = device_id, parent = parent) self._printers = [] # type: List[PrinterOutputModel] - self._unique_configurations = {} # type: Set[ConfigurationModel] + self._unique_configurations = [] # type: List[ConfigurationModel] self._monitor_view_qml_path = "" self._monitor_component = None @@ -180,13 +180,13 @@ class PrinterOutputDevice(QObject, OutputDevice): self.acceptsCommandsChanged.emit() - # Returns the unique configurations of the current printers - @pyqtProperty("QVariantMap", notify = uniqueConfigurationsChanged) + # Returns the unique configurations of the printers within this output device + @pyqtProperty("QVariantList", notify = uniqueConfigurationsChanged) def uniqueConfigurations(self): return self._unique_configurations def _updateUniqueConfigurations(self): - self._unique_configurations = set([printer.printerConfiguration for printer in self._printers]) + self._unique_configurations = list(set([printer.printerConfiguration for printer in self._printers])) self.uniqueConfigurationsChanged.emit() def _onPrintersChanged(self): From 871f0a130edd32d2dff694e2e19f770230ed2d64 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 5 Mar 2018 11:44:26 +0100 Subject: [PATCH 13/66] CURA-4870 Frontend formatting to show the configurations --- .../ConfigurationMenu/ConfigurationItem.qml | 63 ++++++++++++++----- .../ConfigurationListView.qml | 7 +-- .../PrintCoreConfiguration.qml | 57 +++++++++++++++-- .../Menus/ConfigurationMenu/SyncButton.qml | 2 +- 4 files changed, 101 insertions(+), 28 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 7d9c87edf4..3d511e3250 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -16,48 +16,77 @@ Rectangle height: childrenRect.height border.width: UM.Theme.getSize("default_lining").width - border.color: "black" + border.color: UM.Theme.getColor("sidebar_lining_thin") Column { id: contentColumn + width: parent.width padding: UM.Theme.getSize("default_margin").width - spacing: UM.Theme.getSize("default_margin").height - - Label - { - text: configuration.printerType - } + spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) Row { id: extruderRow - width: parent.width + width: parent.width - 2 * parent.padding height: childrenRect.height spacing: UM.Theme.getSize("default_margin").width Repeater { + id: repeater height: childrenRect.height model: configuration.extruderConfigurations delegate: PrintCoreConfiguration { + width: Math.round(parent.width / 2) printCoreConfiguration: modelData } + Component.onCompleted: {print("ELEMENTOS:", repeater.model.count)} } } -// Rectangle -// { -// id: buildplateInformation -// -// Label -// { -// text: configuration.buildplateConfiguration -// } -// } + //Buildplate row separator + Rectangle { + id: separator + + visible: buildplateInformation.visible + width: parent.width - 2 * parent.padding + height: visible ? Math.round(UM.Theme.getSize("sidebar_lining_thin").height / 2) : 0 + color: UM.Theme.getColor("sidebar_lining_thin") + } + + Item + { + id: buildplateInformation + width: parent.width - 2 * parent.padding + height: childrenRect.height + visible: configuration.buildplateConfiguration != "" + + UM.RecolorImage { + id: buildplateIcon + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + sourceSize.height: height + source: UM.Theme.getIcon("extruder_button") + + color: "black" + } + + Label + { + id: buildplateLabel + anchors.left: buildplateIcon.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) + text: configuration.buildplateConfiguration + } + } } MouseArea diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index fa82f43871..f962dbaa9f 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -14,7 +14,7 @@ Column property var outputDevice: Cura.MachineManager.printerOutputDevices[0] height: childrenRect.height + 2 * padding padding: UM.Theme.getSize("default_margin").width - spacing: UM.Theme.getSize("default_margin").height + spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) Label { text: catalog.i18nc("@label:header configurations", "Available configurations") @@ -25,7 +25,7 @@ Column ScrollView { id: container width: parent.width - 2 * parent.padding - height: childrenRect.height + height: 500 //childrenRect.height style: UM.Theme.styles.scrollview @@ -52,16 +52,13 @@ Column model: outputDevice.uniqueConfigurations delegate: ConfigurationItem { - height: parent.height width: parent.width configuration: modelData onConfigurationSelected: { print("SELECCIONANDO CONFIGURACION", JSON.stringify(configuration)) } - Component.onCompleted: {print("$$$$$$$$$$$$$$$$$$ Configuracion", JSON.stringify(configuration))} } - Component.onCompleted: {print("$$$$$$$$$$$$$$$$$$ Elementos del modelo", JSON.stringify(outputDevice.uniqueConfigurations))} } } } diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index 670d618849..8155842349 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -7,29 +7,76 @@ import QtQuick.Controls 2.0 import UM 1.2 as UM -Item +Column { id: extruderInfo property var printCoreConfiguration + spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) height: childrenRect.height + Item + { + id: extruder + width: parent.width + height: childrenRect.height + + Label + { + id: extruderLabel + text: catalog.i18nc("@label:extruder label", "Extruder") + elide: Text.ElideRight + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + font: UM.Theme.getFont("small") + } + + // Rounded item to show the extruder number + Item + { + id: extruderIconItem + anchors.verticalCenter: parent.verticalCenter + anchors.left: extruderLabel.right + anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").width / 2) + + width: UM.Theme.getSize("section_icon").width + height: UM.Theme.getSize("section_icon").height + + UM.RecolorImage { + id: mainCircle + anchors.fill: parent + + sourceSize.width: parent.width + sourceSize.height: parent.height + source: UM.Theme.getIcon("extruder_button") + + color: extruderNumberText.color + } + + Label + { + id: extruderNumberText + anchors.centerIn: parent + text: printCoreConfiguration.position + 1 + font: UM.Theme.getFont("small") + } + } + } + Label { id: materialLabel text: printCoreConfiguration.material elide: Text.ElideRight width: parent.width - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("small") } Label { - id: printCoreLabel + id: printCoreTypeLabel text: printCoreConfiguration.hotendID - anchors.top: materialLabel.bottom elide: Text.ElideRight width: parent.width font: UM.Theme.getFont("very_small") - opacity: 0.5 } } diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml index 79c75bb55d..f9e93b2d22 100644 --- a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml +++ b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml @@ -43,7 +43,7 @@ Button width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height sourceSize.width: width - sourceSize.height: width + sourceSize.height: height color: UM.Theme.getColor("text_emphasis") source: UM.Theme.getIcon("arrow_bottom") } From f779a20a6ea8e762f7c92de7281492eb13c2d993 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 5 Mar 2018 12:13:46 +0100 Subject: [PATCH 14/66] CURA-4870 Cleanup UI and add buildplate icon --- .../ConfigurationMenu/ConfigurationItem.qml | 7 +++---- .../PrintCoreConfiguration.qml | 9 +++++---- .../themes/cura-light/icons/buildplate.svg | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 resources/themes/cura-light/icons/buildplate.svg diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 3d511e3250..4359e4eac7 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -44,7 +44,6 @@ Rectangle width: Math.round(parent.width / 2) printCoreConfiguration: modelData } - Component.onCompleted: {print("ELEMENTOS:", repeater.model.count)} } } @@ -69,11 +68,11 @@ Rectangle id: buildplateIcon anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height + width: UM.Theme.getSize("topbar_button_icon").width + height: UM.Theme.getSize("topbar_button_icon").height sourceSize.width: width sourceSize.height: height - source: UM.Theme.getIcon("extruder_button") + source: UM.Theme.getIcon("buildplate") color: "black" } diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index 8155842349..7b64ab61ac 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -28,7 +28,7 @@ Column elide: Text.ElideRight anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default") } // Rounded item to show the extruder number @@ -58,7 +58,7 @@ Column id: extruderNumberText anchors.centerIn: parent text: printCoreConfiguration.position + 1 - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default") } } } @@ -69,14 +69,15 @@ Column text: printCoreConfiguration.material elide: Text.ElideRight width: parent.width - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") } + Label { id: printCoreTypeLabel text: printCoreConfiguration.hotendID elide: Text.ElideRight width: parent.width - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") } } diff --git a/resources/themes/cura-light/icons/buildplate.svg b/resources/themes/cura-light/icons/buildplate.svg new file mode 100644 index 0000000000..9e61296958 --- /dev/null +++ b/resources/themes/cura-light/icons/buildplate.svg @@ -0,0 +1,17 @@ + + + + icn_buildplate + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file From a992487589ec0992c5b20bb594afe9c11e97031c Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 5 Mar 2018 14:39:49 +0100 Subject: [PATCH 15/66] CURA-4870 Check wether the current configuration matches one of the unique configurations available on the printer output device. Improve some elements in the UI --- cura/Settings/MachineManager.py | 9 ++++++--- .../ConfigurationMenu/ConfigurationItem.qml | 17 ++++++++++++++--- .../PrintCoreConfiguration.qml | 9 +++++++-- .../qml/Menus/ConfigurationMenu/SyncButton.qml | 6 +++--- resources/themes/cura-light/theme.json | 17 ++++++++++++++++- 5 files changed, 46 insertions(+), 12 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index f148942336..0c0187ee98 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -180,15 +180,18 @@ class MachineManager(QObject): extruder_configurations = [] for extruder in self._global_container_stack.extruders.values(): extruder_configurations.append({ - "position": len(extruder_configurations), + "position": int(extruder.getMetaDataEntry("position")), "material": extruder.material.getName() if extruder.material != self._empty_material_container else None, "hotendID": extruder.variant.getName() if extruder.variant != self._empty_variant_container else None }) self._current_printer_configuration.extruderConfigurations = extruder_configurations - self._current_printer_configuration.buildplateConfiguration = self._global_container_stack.variant.getName() if self._global_container_stack.variant is not None else None - print(self._current_printer_configuration.extruderConfigurations) + self._current_printer_configuration.buildplateConfiguration = self._global_container_stack.variant.getName() if self._global_container_stack.variant != self._empty_variant_container else None self.currentConfigurationChanged.emit() + @pyqtSlot(QObject, result = bool) + def matchesConfiguration(self, configuration: ConfigurationModel) -> bool: + return self._current_printer_configuration == configuration + @property def newVariant(self): return self._new_variant_container diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 4359e4eac7..3bb14c3c26 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -12,11 +12,14 @@ Rectangle id: configurationItem property var configuration: null + property var selected: false signal configurationSelected() height: childrenRect.height border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("sidebar_lining_thin") + color: selected ? UM.Theme.getColor("configuration_item_active") : UM.Theme.getColor("configuration_item") + property var textColor: selected ? UM.Theme.getColor("configuration_item_text_active") : UM.Theme.getColor("configuration_item_text") Column { @@ -43,6 +46,7 @@ Rectangle { width: Math.round(parent.width / 2) printCoreConfiguration: modelData + mainColor: textColor } } } @@ -54,7 +58,7 @@ Rectangle visible: buildplateInformation.visible width: parent.width - 2 * parent.padding height: visible ? Math.round(UM.Theme.getSize("sidebar_lining_thin").height / 2) : 0 - color: UM.Theme.getColor("sidebar_lining_thin") + color: textColor } Item @@ -73,8 +77,7 @@ Rectangle sourceSize.width: width sourceSize.height: height source: UM.Theme.getIcon("buildplate") - - color: "black" + color: textColor } Label @@ -84,6 +87,7 @@ Rectangle anchors.verticalCenter: parent.verticalCenter anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) text: configuration.buildplateConfiguration + color: textColor } } } @@ -97,4 +101,11 @@ Rectangle onEntered: parent.border.color = UM.Theme.getColor("primary_hover") onExited: parent.border.color = "black" } + + Connections { + target: Cura.MachineManager + onCurrentConfigurationChanged: { + configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration) + } + } } \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index 7b64ab61ac..74ecc114c7 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -11,6 +11,7 @@ Column { id: extruderInfo property var printCoreConfiguration + property var mainColor: "black" spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) height: childrenRect.height @@ -29,6 +30,7 @@ Column anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left font: UM.Theme.getFont("default") + color: mainColor } // Rounded item to show the extruder number @@ -46,11 +48,11 @@ Column id: mainCircle anchors.fill: parent + anchors.centerIn: parent sourceSize.width: parent.width sourceSize.height: parent.height source: UM.Theme.getIcon("extruder_button") - - color: extruderNumberText.color + color: mainColor } Label @@ -59,6 +61,7 @@ Column anchors.centerIn: parent text: printCoreConfiguration.position + 1 font: UM.Theme.getFont("default") + color: mainColor } } } @@ -70,6 +73,7 @@ Column elide: Text.ElideRight width: parent.width font: UM.Theme.getFont("default_bold") + color: mainColor } Label @@ -79,5 +83,6 @@ Column elide: Text.ElideRight width: parent.width font: UM.Theme.getFont("default") + color: mainColor } } diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml index f9e93b2d22..a82d7cc515 100644 --- a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml +++ b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml @@ -9,7 +9,7 @@ import UM 1.2 as UM Button { - text: "Matched" + text: "No match" width: parent.width height: parent.height @@ -54,11 +54,11 @@ Button text: control.text elide: Text.ElideRight anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width * 2 + anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.right: downArrow.left anchors.rightMargin: control.rightMargin anchors.verticalCenter: parent.verticalCenter; - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("medium_bold") } } label: Label {} diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 8c8e6d1c47..46ea0fc49e 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -14,6 +14,16 @@ "weight": 50, "family": "Noto Sans" }, + "medium": { + "size": 1.16, + "weight": 50, + "family": "Noto Sans" + }, + "medium_bold": { + "size": 1.16, + "weight": 63, + "family": "Noto Sans" + }, "default": { "size": 1.0, "weight": 50, @@ -289,7 +299,12 @@ "layerview_move_combing": [0, 0, 255, 255], "layerview_move_retraction": [128, 128, 255, 255], "layerview_support_interface": [64, 192, 255, 255], - "layerview_nozzle": [181, 166, 66, 50] + "layerview_nozzle": [181, 166, 66, 50], + + "configuration_item": [255, 255, 255, 0], + "configuration_item_active": [31, 36, 39, 255], + "configuration_item_text": [0, 0, 0, 255], + "configuration_item_text_active": [255, 255, 255, 255] }, "sizes": { From 51686943e6a3867a265fa7451b2420e23c26c18b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 5 Mar 2018 17:15:09 +0100 Subject: [PATCH 16/66] CURA-4870 Create an extruder configuration model to store the extruder configuration. Connect the signals coming from the printer to correctly update the UI --- cura/PrinterOutput/ConfigurationModel.py | 11 +++-- .../ExtruderConfigurationModel.py | 42 +++++++++++++++++++ cura/PrinterOutput/ExtruderOutputModel.py | 13 +++--- cura/Settings/MachineManager.py | 17 ++++---- .../ConfigurationMenu/ConfigurationItem.qml | 7 ++++ .../ConfigurationListView.qml | 9 ++++ 6 files changed, 82 insertions(+), 17 deletions(-) create mode 100644 cura/PrinterOutput/ExtruderConfigurationModel.py diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/ConfigurationModel.py index 5102dff239..633986a65c 100644 --- a/cura/PrinterOutput/ConfigurationModel.py +++ b/cura/PrinterOutput/ConfigurationModel.py @@ -2,6 +2,11 @@ # Cura is released under the terms of the LGPLv3 or higher. from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal +from typing import List + +MYPY = False +if MYPY: + from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel class ConfigurationModel(QObject): @@ -11,13 +16,13 @@ class ConfigurationModel(QObject): def __init__(self): super().__init__() self._printer_type = None - self._extruder_configurations = [] + self._extruder_configurations = [] # type: List[ExtruderConfigurationModel] self._buildplate_configuration = None def setPrinterType(self, printer_type): self._printer_type = printer_type - @pyqtProperty(str, fset = setPrinterType, constant = True) + @pyqtProperty(str, fset = setPrinterType, notify = configurationChanged) def printerType(self): return self._printer_type @@ -41,5 +46,5 @@ class ConfigurationModel(QObject): def __hash__(self): extruder_hash = hash(0) for configuration in self.extruderConfigurations: - extruder_hash ^= hash(frozenset(configuration.items())) + extruder_hash ^= configuration.__hash__() return hash(self.printerType) ^ extruder_hash ^ hash(self.buildplateConfiguration) \ No newline at end of file diff --git a/cura/PrinterOutput/ExtruderConfigurationModel.py b/cura/PrinterOutput/ExtruderConfigurationModel.py new file mode 100644 index 0000000000..4871dca3cc --- /dev/null +++ b/cura/PrinterOutput/ExtruderConfigurationModel.py @@ -0,0 +1,42 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal + + +class ExtruderConfigurationModel(QObject): + + extruderConfigurationChanged = pyqtSignal() + + def __init__(self): + super().__init__() + self._position = -1 + self._material = None + self._hotend_id = None + + def setPosition(self, position): + self._position = position + + @pyqtProperty(int, fset = setPosition, notify = extruderConfigurationChanged) + def position(self): + return self._position + + def setMaterial(self, material): + self._material = material + + @pyqtProperty(str, fset = setMaterial, notify = extruderConfigurationChanged) + def material(self): + return self._material + + def setHotendID(self, hotend_id): + self._hotend_id = hotend_id + + @pyqtProperty(str, fset = setHotendID, notify = extruderConfigurationChanged) + def hotendID(self): + return self._hotend_id + + def __eq__(self, other): + return hash(self) == hash(other) + + def __hash__(self): + return hash(self.position) ^ hash(self.material) ^ hash(self.hotendID) \ No newline at end of file diff --git a/cura/PrinterOutput/ExtruderOutputModel.py b/cura/PrinterOutput/ExtruderOutputModel.py index 3e415fb47a..d74b3a90d5 100644 --- a/cura/PrinterOutput/ExtruderOutputModel.py +++ b/cura/PrinterOutput/ExtruderOutputModel.py @@ -2,6 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot +from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel from typing import Optional @@ -26,7 +27,7 @@ class ExtruderOutputModel(QObject): self._hotend_temperature = 0 self._hotend_id = "" self._active_material = None # type: Optional[MaterialOutputModel] - self._extruder_configuration = {} + self._extruder_configuration = ExtruderConfigurationModel() # Update the configuration every time the hotend or the active material change self.hotendIDChanged.connect(self._updateExtruderConfiguration) self.activeMaterialChanged.connect(self._updateExtruderConfiguration) @@ -74,15 +75,13 @@ class ExtruderOutputModel(QObject): self._hotend_id = id self.hotendIDChanged.emit() - @pyqtProperty("QVariantMap", notify = extruderConfigurationChanged) + @pyqtProperty(QObject, notify = extruderConfigurationChanged) def extruderConfiguration(self): return self._extruder_configuration def _updateExtruderConfiguration(self): - self._extruder_configuration = { - "position": self._position, - "material": self._active_material.type if self.activeMaterial is not None else None, - "hotendID": self._hotend_id - } + self._extruder_configuration.position = self._position + self._extruder_configuration.material = self._active_material.type if self.activeMaterial is not None else None + self._extruder_configuration.hotendID = self._hotend_id print("Recalculating extruder configuration:", self._extruder_configuration) self.extruderConfigurationChanged.emit() diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 0c0187ee98..7d5e00f0b5 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -30,6 +30,7 @@ from UM.Signal import postponeSignals, CompressTechnique from cura.QualityManager import QualityManager from cura.PrinterOutputDevice import PrinterOutputDevice from cura.PrinterOutput.ConfigurationModel import ConfigurationModel +from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel from cura.Settings.ExtruderManager import ExtruderManager from .CuraStackBuilder import CuraStackBuilder @@ -177,19 +178,21 @@ class MachineManager(QObject): return self._current_printer_configuration.printerType = self._global_container_stack.definition.getName() - extruder_configurations = [] + self._current_printer_configuration.extruderConfigurations = [] for extruder in self._global_container_stack.extruders.values(): - extruder_configurations.append({ - "position": int(extruder.getMetaDataEntry("position")), - "material": extruder.material.getName() if extruder.material != self._empty_material_container else None, - "hotendID": extruder.variant.getName() if extruder.variant != self._empty_variant_container else None - }) - self._current_printer_configuration.extruderConfigurations = extruder_configurations + extruder_configuration = ExtruderConfigurationModel() + extruder_configuration.position = int(extruder.getMetaDataEntry("position")) + extruder_configuration.material = extruder.material.getName() if extruder.material != self._empty_material_container else None + extruder_configuration.hotendID = extruder.variant.getName() if extruder.variant != self._empty_variant_container else None + self._current_printer_configuration.extruderConfigurations.append(extruder_configuration) + self._current_printer_configuration.buildplateConfiguration = self._global_container_stack.variant.getName() if self._global_container_stack.variant != self._empty_variant_container else None self.currentConfigurationChanged.emit() @pyqtSlot(QObject, result = bool) def matchesConfiguration(self, configuration: ConfigurationModel) -> bool: + # print("@@@@@@@@@@@@@@@@@@", configuration.extruderConfigurations) + # print("##################", self._current_printer_configuration.extruderConfigurations, configuration == self._current_printer_configuration) return self._current_printer_configuration == configuration @property diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 3bb14c3c26..b28c5b4812 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -108,4 +108,11 @@ Rectangle configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration) } } + + Connections { + target: configuration + onConfigurationChanged: { + configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration) + } + } } \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index f962dbaa9f..bc257c8a61 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -42,6 +42,15 @@ Column font: UM.Theme.getFont("default_bold") } + Connections { + target: outputDevice + onUniqueConfigurationsChanged: { + // FIXME For now the model should be removed and then created again, otherwise changes in the printer don't automatically update the UI + configurationList.model = null + configurationList.model = outputDevice.uniqueConfigurations + } + } + ListView { id: configurationList From d83eb383d93f313202dcec3cf104bcc02a66528b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 6 Mar 2018 08:44:43 +0100 Subject: [PATCH 17/66] CURA-4870 Fix an error in the hash function that detects a matching when the extruders are inverted. Add pretty output to the configuration model. --- cura/PrinterOutput/ConfigurationModel.py | 14 +++++++++++--- cura/PrinterOutput/ExtruderConfigurationModel.py | 7 ++++++- cura/Settings/MachineManager.py | 5 +++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/ConfigurationModel.py index 633986a65c..8138543d7b 100644 --- a/cura/PrinterOutput/ConfigurationModel.py +++ b/cura/PrinterOutput/ConfigurationModel.py @@ -40,11 +40,19 @@ class ConfigurationModel(QObject): def buildplateConfiguration(self): return self._buildplate_configuration + def __str__(self): + info = "Printer type: " + self.printerType + "\n" + info += "Extruders: [\n" + for configuration in self.extruderConfigurations: + info += " " + str(configuration) + "\n" + info += "]" + return info + def __eq__(self, other): return hash(self) == hash(other) def __hash__(self): - extruder_hash = hash(0) + extruder_hash = hash(self.extruderConfigurations[0]) # Use the hash of the first extruder as a seed for configuration in self.extruderConfigurations: - extruder_hash ^= configuration.__hash__() - return hash(self.printerType) ^ extruder_hash ^ hash(self.buildplateConfiguration) \ No newline at end of file + extruder_hash ^= hash(configuration) + return hash(self._printer_type) ^ extruder_hash ^ hash(self._buildplate_configuration) \ No newline at end of file diff --git a/cura/PrinterOutput/ExtruderConfigurationModel.py b/cura/PrinterOutput/ExtruderConfigurationModel.py index 4871dca3cc..7aa8785ae9 100644 --- a/cura/PrinterOutput/ExtruderConfigurationModel.py +++ b/cura/PrinterOutput/ExtruderConfigurationModel.py @@ -35,8 +35,13 @@ class ExtruderConfigurationModel(QObject): def hotendID(self): return self._hotend_id + def __str__(self): + if self._material is None or self._hotend_id is None: + return "No information" + return "Position: " + str(self._position) + " - Material: " + self._material + " - HotendID: " + self._hotend_id + def __eq__(self, other): return hash(self) == hash(other) def __hash__(self): - return hash(self.position) ^ hash(self.material) ^ hash(self.hotendID) \ No newline at end of file + return hash(self._position) ^ hash(self._material) ^ hash(self._hotend_id) \ No newline at end of file diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 7d5e00f0b5..39962690bb 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -191,8 +191,9 @@ class MachineManager(QObject): @pyqtSlot(QObject, result = bool) def matchesConfiguration(self, configuration: ConfigurationModel) -> bool: - # print("@@@@@@@@@@@@@@@@@@", configuration.extruderConfigurations) - # print("##################", self._current_printer_configuration.extruderConfigurations, configuration == self._current_printer_configuration) + # print(configuration) + # print(self._current_printer_configuration) + # print("%%%%%%%%", configuration == self._current_printer_configuration) return self._current_printer_configuration == configuration @property From d02d845d1bc8645c9d26f003728690ff95f6b80b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 6 Mar 2018 09:24:42 +0100 Subject: [PATCH 18/66] CURA-4870 Update the selected configuration in the UI when the configuration in the printer changes. Modify again the hash function. --- cura/PrinterOutput/ConfigurationModel.py | 8 +++++++- cura/PrinterOutputDevice.py | 1 + .../qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 11 ++++------- .../Menus/ConfigurationMenu/ConfigurationListView.qml | 3 ++- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/ConfigurationModel.py index 8138543d7b..230a734797 100644 --- a/cura/PrinterOutput/ConfigurationModel.py +++ b/cura/PrinterOutput/ConfigurationModel.py @@ -52,7 +52,13 @@ class ConfigurationModel(QObject): return hash(self) == hash(other) def __hash__(self): - extruder_hash = hash(self.extruderConfigurations[0]) # Use the hash of the first extruder as a seed + extruder_hash = hash(0) + first_extruder = None for configuration in self.extruderConfigurations: extruder_hash ^= hash(configuration) + if configuration.position == 0: + first_extruder = configuration + if first_extruder: + extruder_hash &= hash(first_extruder) + return hash(self._printer_type) ^ extruder_hash ^ hash(self._buildplate_configuration) \ No newline at end of file diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 875cc17fe8..d2916016e0 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -187,6 +187,7 @@ class PrinterOutputDevice(QObject, OutputDevice): def _updateUniqueConfigurations(self): self._unique_configurations = list(set([printer.printerConfiguration for printer in self._printers])) + self._unique_configurations.sort(key = lambda k: k.printerType) self.uniqueConfigurationsChanged.emit() def _onPrintersChanged(self): diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index b28c5b4812..ae97a82207 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -13,7 +13,7 @@ Rectangle property var configuration: null property var selected: false - signal configurationSelected() + signal activateConfiguration() height: childrenRect.height border.width: UM.Theme.getSize("default_lining").width @@ -96,7 +96,7 @@ Rectangle { id: mouse anchors.fill: parent - onClicked: configurationSelected() + onClicked: activateConfiguration() hoverEnabled: true onEntered: parent.border.color = UM.Theme.getColor("primary_hover") onExited: parent.border.color = "black" @@ -109,10 +109,7 @@ Rectangle } } - Connections { - target: configuration - onConfigurationChanged: { - configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration) - } + Component.onCompleted: { + configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration) } } \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index bc257c8a61..2effa5177f 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -46,6 +46,7 @@ Column target: outputDevice onUniqueConfigurationsChanged: { // FIXME For now the model should be removed and then created again, otherwise changes in the printer don't automatically update the UI + print("Update unique configurations") configurationList.model = null configurationList.model = outputDevice.uniqueConfigurations } @@ -63,7 +64,7 @@ Column { width: parent.width configuration: modelData - onConfigurationSelected: + onActivateConfiguration: { print("SELECCIONANDO CONFIGURACION", JSON.stringify(configuration)) } From 731a1092c521a363c6f0fbc3b53ea21848af5ccf Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 6 Mar 2018 10:18:54 +0100 Subject: [PATCH 19/66] CURA-4870 Add callback function to apply remote configuration --- cura/Settings/MachineManager.py | 5 +++++ .../qml/Menus/ConfigurationMenu/ConfigurationListView.qml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 39962690bb..c2b2e2b0dd 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -196,6 +196,11 @@ class MachineManager(QObject): # print("%%%%%%%%", configuration == self._current_printer_configuration) return self._current_printer_configuration == configuration + @pyqtSlot(QObject) + def applyRemoteConfiguration(self, configuration: ConfigurationModel): + print("Applying remote configuration", configuration) + + @property def newVariant(self): return self._new_variant_container diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 2effa5177f..0645567c86 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -66,7 +66,7 @@ Column configuration: modelData onActivateConfiguration: { - print("SELECCIONANDO CONFIGURACION", JSON.stringify(configuration)) + Cura.MachineManager.applyRemoteConfiguration(configuration) } } } From d11d850f7cedf962a6209894f929578bca9ca6a7 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 6 Mar 2018 10:42:24 +0100 Subject: [PATCH 20/66] CURA-4870 Add spacing to the list of configurations --- resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 0645567c86..00de9d0003 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -57,6 +57,7 @@ Column id: configurationList anchors.top: printerTypeHeader.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height + spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) width: container.width height: childrenRect.height model: outputDevice.uniqueConfigurations From f625fa8a90e97a7486ef15f6f264c5f74a56b3b6 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 6 Mar 2018 16:08:50 +0100 Subject: [PATCH 21/66] CURA-4870 Add function to set the configuration from the printer back to Cura. Change the hash function to compare by GUID instead of type. Show the material name instead of type in the list. --- cura/Machines/MaterialGroup.py | 3 +- cura/Machines/MaterialManager.py | 30 +++++++++++++++++++ .../ExtruderConfigurationModel.py | 10 ++++--- cura/PrinterOutput/ExtruderOutputModel.py | 3 +- cura/PrinterOutput/PrinterOutputModel.py | 1 - cura/Settings/MachineManager.py | 30 ++++++++++++++++--- .../ConfigurationListView.qml | 1 - .../PrintCoreConfiguration.qml | 2 +- 8 files changed, 66 insertions(+), 14 deletions(-) diff --git a/cura/Machines/MaterialGroup.py b/cura/Machines/MaterialGroup.py index 009778943a..75ab51182c 100644 --- a/cura/Machines/MaterialGroup.py +++ b/cura/Machines/MaterialGroup.py @@ -15,10 +15,11 @@ # so "generic_abs_ultimaker3", "generic_abs_ultimaker3_AA_0.4", etc. # class MaterialGroup: - __slots__ = ("name", "root_material_node", "derived_material_node_list") + __slots__ = ("name", "is_read_only", "root_material_node", "derived_material_node_list") def __init__(self, name: str): self.name = name + self.is_read_only = False self.root_material_node = None self.derived_material_node_list = [] diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 98e4f67f82..4bad33b890 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -87,6 +87,7 @@ class MaterialManager(QObject): root_material_id = material_metadata.get("base_file") if root_material_id not in self._material_group_map: self._material_group_map[root_material_id] = MaterialGroup(root_material_id) + self._material_group_map[root_material_id].is_read_only = self._container_registry.isReadOnly(root_material_id) group = self._material_group_map[root_material_id] # We only add root materials here @@ -325,6 +326,35 @@ class MaterialManager(QObject): return material_node + # + # Gets MaterialNode for the given extruder and machine with the given material type. + # Returns None if: + # 1. the given machine doesn't have materials; + # 2. cannot find any material InstanceContainers with the given settings. + # + def getMaterialNodeByType(self, global_stack: "GlobalStack", extruder_variant_name: str, material_guid: str) -> Optional["MaterialNode"]: + node = None + machine_definition = global_stack.definition + if parseBool(machine_definition.getMetaDataEntry("has_materials", False)): + material_diameter = machine_definition.getProperty("material_diameter", "value") + if isinstance(material_diameter, SettingFunction): + material_diameter = material_diameter(global_stack) + + # Look at the guid to material dictionary + root_material_id = None + for material_group in self._guid_material_groups_map[material_guid]: + if material_group.is_read_only: + root_material_id = material_group.root_material_node.metadata["id"] + break + + if not root_material_id: + Logger.log("i", "Cannot find materials with guid [%s] ", material_guid) + return None + + node = self.getMaterialNode(machine_definition.getId(), extruder_variant_name, + material_diameter, root_material_id) + return node + # # Used by QualityManager. Built-in quality profiles may be based on generic material IDs such as "generic_pla". # For materials such as ultimaker_pla_orange, no quality profiles may be found, so we should fall back to use diff --git a/cura/PrinterOutput/ExtruderConfigurationModel.py b/cura/PrinterOutput/ExtruderConfigurationModel.py index 7aa8785ae9..072adfc24e 100644 --- a/cura/PrinterOutput/ExtruderConfigurationModel.py +++ b/cura/PrinterOutput/ExtruderConfigurationModel.py @@ -24,7 +24,7 @@ class ExtruderConfigurationModel(QObject): def setMaterial(self, material): self._material = material - @pyqtProperty(str, fset = setMaterial, notify = extruderConfigurationChanged) + @pyqtProperty(QObject, fset = setMaterial, notify = extruderConfigurationChanged) def material(self): return self._material @@ -36,12 +36,14 @@ class ExtruderConfigurationModel(QObject): return self._hotend_id def __str__(self): - if self._material is None or self._hotend_id is None: + if self._material is None or self._hotend_id is None or self.material.type is None: return "No information" - return "Position: " + str(self._position) + " - Material: " + self._material + " - HotendID: " + self._hotend_id + return "Position: " + str(self._position) + " - Material: " + self._material.type + " - HotendID: " + self._hotend_id def __eq__(self, other): return hash(self) == hash(other) + # Calculating a hash function using the position of the extruder, the material GUID and the hotend id to check if is + # unique within a set def __hash__(self): - return hash(self._position) ^ hash(self._material) ^ hash(self._hotend_id) \ No newline at end of file + return hash(self._position) ^ (hash(self._material.guid) if self.material is not None else hash(0)) ^ hash(self._hotend_id) \ No newline at end of file diff --git a/cura/PrinterOutput/ExtruderOutputModel.py b/cura/PrinterOutput/ExtruderOutputModel.py index d74b3a90d5..a639d428f9 100644 --- a/cura/PrinterOutput/ExtruderOutputModel.py +++ b/cura/PrinterOutput/ExtruderOutputModel.py @@ -81,7 +81,6 @@ class ExtruderOutputModel(QObject): def _updateExtruderConfiguration(self): self._extruder_configuration.position = self._position - self._extruder_configuration.material = self._active_material.type if self.activeMaterial is not None else None + self._extruder_configuration.material = self._active_material self._extruder_configuration.hotendID = self._hotend_id - print("Recalculating extruder configuration:", self._extruder_configuration) self.extruderConfigurationChanged.emit() diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py index 19365b9cc6..f59cc1bece 100644 --- a/cura/PrinterOutput/PrinterOutputModel.py +++ b/cura/PrinterOutput/PrinterOutputModel.py @@ -253,5 +253,4 @@ class PrinterOutputModel(QObject): self._printer_configuration.printerType = self._type self._printer_configuration.extruderConfigurations = [extruder.extruderConfiguration for extruder in self._extruders] self._printer_configuration.buildplateConfiguration = None # TODO Add the buildplate information - print("Recalculating printer configuration", self.name, ":", self._printer_configuration) self.configurationChanged.emit() diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 0cde440fd8..6e0679e11c 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -20,7 +20,6 @@ from UM.Logger import Logger from UM.Message import Message from UM.Settings.ContainerRegistry import ContainerRegistry -from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.SettingFunction import SettingFunction from UM.Signal import postponeSignals, CompressTechnique @@ -28,6 +27,7 @@ from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch from cura.PrinterOutputDevice import PrinterOutputDevice from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel +from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.Settings.ExtruderManager import ExtruderManager from .CuraStackBuilder import CuraStackBuilder @@ -124,7 +124,8 @@ class MachineManager(QObject): if containers: containers[0].nameChanged.connect(self._onMaterialNameChanged) - self._material_manager = self._application._material_manager + self._material_manager = self._application.getMaterialManager() + self._variant_manager = self._application.getVariantManager() self._quality_manager = self._application.getQualityManager() # When the materials lookup table gets updated, it can mean that a material has its name changed, which should @@ -176,12 +177,21 @@ class MachineManager(QObject): if not self._global_container_stack: return + # Create the configuration model with the current data in Cura self._current_printer_configuration.printerType = self._global_container_stack.definition.getName() self._current_printer_configuration.extruderConfigurations = [] for extruder in self._global_container_stack.extruders.values(): extruder_configuration = ExtruderConfigurationModel() + # For compare just the GUID is needed at this moment + mat_type = extruder.material.getMetaDataEntry("material") if extruder.material != self._empty_material_container else None + mat_guid = extruder.material.getMetaDataEntry("GUID") if extruder.material != self._empty_material_container else None + mat_color = extruder.material.getMetaDataEntry("color_name") if extruder.material != self._empty_material_container else None + mat_brand = extruder.material.getMetaDataEntry("brand") if extruder.material != self._empty_material_container else None + mat_name = extruder.material.getMetaDataEntry("name") if extruder.material != self._empty_material_container else None + material_model = MaterialOutputModel(mat_guid, mat_type, mat_color, mat_brand, mat_name) + extruder_configuration.position = int(extruder.getMetaDataEntry("position")) - extruder_configuration.material = extruder.material.getName() if extruder.material != self._empty_material_container else None + extruder_configuration.material = material_model extruder_configuration.hotendID = extruder.variant.getName() if extruder.variant != self._empty_variant_container else None self._current_printer_configuration.extruderConfigurations.append(extruder_configuration) @@ -197,7 +207,8 @@ class MachineManager(QObject): @pyqtSlot(QObject) def applyRemoteConfiguration(self, configuration: ConfigurationModel): - print("Applying remote configuration", configuration) + for extruder_configuration in configuration.extruderConfigurations: + self.setConfiguration(extruder_configuration.position, extruder_configuration.hotendID, extruder_configuration.material.guid) @pyqtProperty("QVariantList", notify = outputDevicesChanged) def printerOutputDevices(self): @@ -355,6 +366,7 @@ class MachineManager(QObject): Logger.log("w", "Failed creating a new machine!") def _checkStacksHaveErrors(self) -> bool: + return False time_start = time.time() if self._global_container_stack is None: #No active machine. return False @@ -1018,6 +1030,16 @@ class MachineManager(QObject): self._updateMaterialWithVariant(None) # Update all materials self._updateQualityWithMaterial() + def setConfiguration(self, position, variant_name, material_guid): + position = str(position) + variant_container_node = self._variant_manager.getVariantNode(self._global_container_stack.definition.getId(), variant_name) + material_container_node = self._material_manager.getMaterialNodeByType(self._global_container_stack, variant_name, material_guid) + with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): + self._setVariantNode(position, variant_container_node) + self._setMaterial(position, material_container_node) + self._updateMaterialWithVariant(position) + self._updateQualityWithMaterial() + @pyqtSlot(str, "QVariant") def setMaterial(self, position, container_node): position = str(position) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 00de9d0003..f476383169 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -46,7 +46,6 @@ Column target: outputDevice onUniqueConfigurationsChanged: { // FIXME For now the model should be removed and then created again, otherwise changes in the printer don't automatically update the UI - print("Update unique configurations") configurationList.model = null configurationList.model = outputDevice.uniqueConfigurations } diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index 74ecc114c7..d34252adc4 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -69,7 +69,7 @@ Column Label { id: materialLabel - text: printCoreConfiguration.material + text: printCoreConfiguration.material.name elide: Text.ElideRight width: parent.width font: UM.Theme.getFont("default_bold") From 987794c5158930e76a771dc4b2f4d5315d9f91e3 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 6 Mar 2018 16:59:51 +0100 Subject: [PATCH 22/66] CURA-4870 Update the Sync Button accordingly to changes both in the output device or in the current configuration, in order to check wether a configuration matches or not. --- .../Menus/ConfigurationMenu/SyncButton.qml | 33 ++++++++++++++++++- resources/qml/SidebarHeader.qml | 3 +- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml index a82d7cc515..3834f2ebd2 100644 --- a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml +++ b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml @@ -6,13 +6,30 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.2 as UM +import Cura 1.0 as Cura Button { - text: "No match" + id: base + property var outputDevice: Cura.MachineManager.printerOutputDevices[0] != null ? Cura.MachineManager.printerOutputDevices[0] : null + text: catalog.i18nc("@label:sync indicator", "No match") width: parent.width height: parent.height + function updateOnSync() + { + for (var index in outputDevice.uniqueConfigurations) + { + var configuration = outputDevice.uniqueConfigurations[index] + if (Cura.MachineManager.matchesConfiguration(configuration)) + { + base.text = catalog.i18nc("@label:sync indicator", "Matched") + return + } + } + base.text = catalog.i18nc("@label:sync indicator", "No match") + } + style: ButtonStyle { background: Rectangle @@ -68,4 +85,18 @@ Button { panelVisible = !panelVisible } + + Connections { + target: outputDevice + onUniqueConfigurationsChanged: { + updateOnSync() + } + } + + Connections { + target: Cura.MachineManager + onCurrentConfigurationChanged: { + updateOnSync() + } + } } \ No newline at end of file diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 449600bf61..7acc58c52a 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -63,8 +63,7 @@ Column ToolButton { - id: configurationSelection - + id: printerTypeSelection text: catalog.i18nc("@label", "Printer type"); height: UM.Theme.getSize("setting_control").height width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width From 5b2ff705e79ea365a476e195b8a2b2ac0a7eeb07 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 6 Mar 2018 17:03:44 +0100 Subject: [PATCH 23/66] CURA-4870 Add menu icons --- resources/qml/Menus/LocalPrinterMenu.qml | 10 ++++------ resources/qml/Menus/NetworkPrinterMenu.qml | 11 +++++------ .../themes/cura-light/icons/printer_group.svg | 12 ++++++++++++ .../themes/cura-light/icons/printer_single.svg | 14 ++++++++++++++ 4 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 resources/themes/cura-light/icons/printer_group.svg create mode 100644 resources/themes/cura-light/icons/printer_single.svg diff --git a/resources/qml/Menus/LocalPrinterMenu.qml b/resources/qml/Menus/LocalPrinterMenu.qml index ef9a7b13b0..1c3064499b 100644 --- a/resources/qml/Menus/LocalPrinterMenu.qml +++ b/resources/qml/Menus/LocalPrinterMenu.qml @@ -7,14 +7,12 @@ import QtQuick.Controls 1.4 import UM 1.2 as UM import Cura 1.0 as Cura -Instantiator -{ - model: UM.ContainerStacksModel - { +Instantiator { + model: UM.ContainerStacksModel { filter: {"type": "machine", "um_network_key": null} } - MenuItem - { + MenuItem { + iconSource: UM.Theme.getIcon("printer_single") text: model.name; checkable: true; checked: Cura.MachineManager.activeMachineId == model.id diff --git a/resources/qml/Menus/NetworkPrinterMenu.qml b/resources/qml/Menus/NetworkPrinterMenu.qml index 3dadad3913..fda99d065c 100644 --- a/resources/qml/Menus/NetworkPrinterMenu.qml +++ b/resources/qml/Menus/NetworkPrinterMenu.qml @@ -7,14 +7,13 @@ import QtQuick.Controls 1.4 import UM 1.2 as UM import Cura 1.0 as Cura -Instantiator -{ - model: UM.ContainerStacksModel - { +Instantiator { + model: UM.ContainerStacksModel { filter: {"type": "machine", "um_network_key": "*"} } - MenuItem - { + MenuItem { + // TODO: Use printer_group icon when it's a cluster. + iconSource: UM.Theme.getIcon("printer_single") text: model.name; checkable: true; checked: Cura.MachineManager.activeMachineId == model.id diff --git a/resources/themes/cura-light/icons/printer_group.svg b/resources/themes/cura-light/icons/printer_group.svg new file mode 100644 index 0000000000..614bea90b8 --- /dev/null +++ b/resources/themes/cura-light/icons/printer_group.svg @@ -0,0 +1,12 @@ + + + + icn_groupPrinters + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/icons/printer_single.svg b/resources/themes/cura-light/icons/printer_single.svg new file mode 100644 index 0000000000..f7dc83987d --- /dev/null +++ b/resources/themes/cura-light/icons/printer_single.svg @@ -0,0 +1,14 @@ + + + + icn_singlePrinter + Created with Sketch. + + + + + + + + + \ No newline at end of file From 813f4e83e048679617fd529d7615b9337d79dfca Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 7 Mar 2018 09:56:38 +0100 Subject: [PATCH 24/66] CURA-4870 Adjust colors for the selected configuration Remove the printer icon since it doesn't look as expected --- .../ConfigurationMenu/ConfigurationItem.qml | 22 ++++++++++++++----- resources/qml/Menus/LocalPrinterMenu.qml | 1 - resources/qml/Menus/NetworkPrinterMenu.qml | 4 ++-- resources/themes/cura-light/theme.json | 7 ++++-- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index ae97a82207..e4c4683869 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -17,10 +17,15 @@ Rectangle height: childrenRect.height border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("sidebar_lining_thin") + border.color: updateBorderColor() color: selected ? UM.Theme.getColor("configuration_item_active") : UM.Theme.getColor("configuration_item") property var textColor: selected ? UM.Theme.getColor("configuration_item_text_active") : UM.Theme.getColor("configuration_item_text") + function updateBorderColor() + { + border.color = selected ? UM.Theme.getColor("configuration_item_border_active") : UM.Theme.getColor("configuration_item_border") + } + Column { id: contentColumn @@ -52,7 +57,8 @@ Rectangle } //Buildplate row separator - Rectangle { + Rectangle + { id: separator visible: buildplateInformation.visible @@ -98,18 +104,22 @@ Rectangle anchors.fill: parent onClicked: activateConfiguration() hoverEnabled: true - onEntered: parent.border.color = UM.Theme.getColor("primary_hover") - onExited: parent.border.color = "black" + onEntered: parent.border.color = UM.Theme.getColor("configuration_item_border_hover") + onExited: updateBorderColor() } - Connections { + Connections + { target: Cura.MachineManager onCurrentConfigurationChanged: { configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration) + updateBorderColor() } } - Component.onCompleted: { + Component.onCompleted: + { configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration) + updateBorderColor() } } \ No newline at end of file diff --git a/resources/qml/Menus/LocalPrinterMenu.qml b/resources/qml/Menus/LocalPrinterMenu.qml index 1c3064499b..0bdd4f33b9 100644 --- a/resources/qml/Menus/LocalPrinterMenu.qml +++ b/resources/qml/Menus/LocalPrinterMenu.qml @@ -12,7 +12,6 @@ Instantiator { filter: {"type": "machine", "um_network_key": null} } MenuItem { - iconSource: UM.Theme.getIcon("printer_single") text: model.name; checkable: true; checked: Cura.MachineManager.activeMachineId == model.id diff --git a/resources/qml/Menus/NetworkPrinterMenu.qml b/resources/qml/Menus/NetworkPrinterMenu.qml index fda99d065c..64539c9892 100644 --- a/resources/qml/Menus/NetworkPrinterMenu.qml +++ b/resources/qml/Menus/NetworkPrinterMenu.qml @@ -12,8 +12,8 @@ Instantiator { filter: {"type": "machine", "um_network_key": "*"} } MenuItem { - // TODO: Use printer_group icon when it's a cluster. - iconSource: UM.Theme.getIcon("printer_single") + // TODO: Use printer_group icon when it's a cluster. Not use it for now since it doesn't look as expected +// iconSource: UM.Theme.getIcon("printer_single") text: model.name; checkable: true; checked: Cura.MachineManager.activeMachineId == model.id diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 46ea0fc49e..d97970e566 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -302,9 +302,12 @@ "layerview_nozzle": [181, 166, 66, 50], "configuration_item": [255, 255, 255, 0], - "configuration_item_active": [31, 36, 39, 255], + "configuration_item_active": [12, 169, 227, 32], "configuration_item_text": [0, 0, 0, 255], - "configuration_item_text_active": [255, 255, 255, 255] + "configuration_item_text_active": [0, 0, 0, 255], + "configuration_item_border": [127, 127, 127, 255], + "configuration_item_border_active": [12, 169, 227, 32], + "configuration_item_border_hover": [12, 169, 227, 255] }, "sizes": { From bb3d706c9265f098a2c1523f8c8311c342128ba9 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 7 Mar 2018 11:24:02 +0100 Subject: [PATCH 25/66] CURA-4870 Adapt the size of the sync dropdown to the height of the contents or a maximum size defined manually. Create sections in the list view depending on the machine types that are in the group. --- .../ConfigurationListView.qml | 91 ++++++++++--------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index f476383169..6aa8297e21 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -16,61 +16,68 @@ Column padding: UM.Theme.getSize("default_margin").width spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) - Label { + Label + { text: catalog.i18nc("@label:header configurations", "Available configurations") font: UM.Theme.getFont("large") width: parent.width - 2 * parent.padding } - ScrollView { + Component + { + id: sectionHeading + Rectangle + { + height: childrenRect.height + UM.Theme.getSize("default_margin").height + Label + { + text: section + font: UM.Theme.getFont("default_bold") + } + } + } + + ScrollView + { id: container - width: parent.width - 2 * parent.padding - height: 500 //childrenRect.height + width: parent.width - parent.padding + height: Math.min(configurationList.contentHeight, 300 * screenScaleFactor) style: UM.Theme.styles.scrollview + __wheelAreaScrollSpeed: 75 // Scroll three lines in one scroll event - Repeater { - height: childrenRect.height - model: outputDevice != null ? outputDevice.connectedPrintersTypeCount : null - delegate: Rectangle + ListView + { + id: configurationList + spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) + width: container.width + contentHeight: childrenRect.height + + section.property: "modelData.printerType" + section.criteria: ViewSection.FullString + section.delegate: sectionHeading + + model: outputDevice.uniqueConfigurations + delegate: ConfigurationItem { - height: childrenRect.height - Label + width: parent.width - UM.Theme.getSize("default_margin").width + configuration: modelData + onActivateConfiguration: { - id: printerTypeHeader - text: modelData.machine_type - font: UM.Theme.getFont("default_bold") - } - - Connections { - target: outputDevice - onUniqueConfigurationsChanged: { - // FIXME For now the model should be removed and then created again, otherwise changes in the printer don't automatically update the UI - configurationList.model = null - configurationList.model = outputDevice.uniqueConfigurations - } - } - - ListView - { - id: configurationList - anchors.top: printerTypeHeader.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height - spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) - width: container.width - height: childrenRect.height - model: outputDevice.uniqueConfigurations - delegate: ConfigurationItem - { - width: parent.width - configuration: modelData - onActivateConfiguration: - { - Cura.MachineManager.applyRemoteConfiguration(configuration) - } - } + Cura.MachineManager.applyRemoteConfiguration(configuration) } } } } + + Connections + { + target: outputDevice + onUniqueConfigurationsChanged: + { + // FIXME For now the model should be removed and then created again, otherwise changes in the printer don't automatically update the UI + configurationList.model = null + configurationList.model = outputDevice.uniqueConfigurations + } + } } \ No newline at end of file From 6abbe7381aabeed2b80b17682d60a4abc853561d Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 7 Mar 2018 11:26:50 +0100 Subject: [PATCH 26/66] CURA-4870 Adjust a little bit the maximum size so three printers of two different types can fit --- resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 6aa8297e21..037fadcb22 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -41,7 +41,7 @@ Column { id: container width: parent.width - parent.padding - height: Math.min(configurationList.contentHeight, 300 * screenScaleFactor) + height: Math.min(configurationList.contentHeight, 350 * screenScaleFactor) style: UM.Theme.styles.scrollview __wheelAreaScrollSpeed: 75 // Scroll three lines in one scroll event From 0beee79c3a844d8cd6c1890e276b063052fb9381 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 7 Mar 2018 13:17:55 +0100 Subject: [PATCH 27/66] CURA-4870 Revert skipping stack checks --- cura/Settings/MachineManager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 053b9d033a..0924b1d33b 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -366,7 +366,6 @@ class MachineManager(QObject): Logger.log("w", "Failed creating a new machine!") def _checkStacksHaveErrors(self) -> bool: - return False time_start = time.time() if self._global_container_stack is None: #No active machine. return False From 97740123fa39db5229dd72f7c18d9c9ae8787b9e Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 7 Mar 2018 13:57:13 +0100 Subject: [PATCH 28/66] CURA-4870 Add information about the buildplate in the printer output model so it can be used to show the buildplate name in the configuration list. --- cura/PrinterOutput/ConfigurationModel.py | 8 ++-- .../ExtruderConfigurationModel.py | 2 +- cura/PrinterOutput/PrinterOutputModel.py | 13 ++++++- cura/Settings/MachineManager.py | 39 ++++++++++++------- .../ClusterUM3OutputDevice.py | 2 + 5 files changed, 44 insertions(+), 20 deletions(-) diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/ConfigurationModel.py index 230a734797..30c95f2765 100644 --- a/cura/PrinterOutput/ConfigurationModel.py +++ b/cura/PrinterOutput/ConfigurationModel.py @@ -41,11 +41,13 @@ class ConfigurationModel(QObject): return self._buildplate_configuration def __str__(self): - info = "Printer type: " + self.printerType + "\n" + info = "Printer type: " + self._printer_type + "\n" info += "Extruders: [\n" - for configuration in self.extruderConfigurations: + for configuration in self._extruder_configurations: info += " " + str(configuration) + "\n" info += "]" + if self._buildplate_configuration is not None: + info += "\nBuildplate: " + self._buildplate_configuration return info def __eq__(self, other): @@ -54,7 +56,7 @@ class ConfigurationModel(QObject): def __hash__(self): extruder_hash = hash(0) first_extruder = None - for configuration in self.extruderConfigurations: + for configuration in self._extruder_configurations: extruder_hash ^= hash(configuration) if configuration.position == 0: first_extruder = configuration diff --git a/cura/PrinterOutput/ExtruderConfigurationModel.py b/cura/PrinterOutput/ExtruderConfigurationModel.py index 072adfc24e..34eddb3038 100644 --- a/cura/PrinterOutput/ExtruderConfigurationModel.py +++ b/cura/PrinterOutput/ExtruderConfigurationModel.py @@ -46,4 +46,4 @@ class ExtruderConfigurationModel(QObject): # Calculating a hash function using the position of the extruder, the material GUID and the hotend id to check if is # unique within a set def __hash__(self): - return hash(self._position) ^ (hash(self._material.guid) if self.material is not None else hash(0)) ^ hash(self._hotend_id) \ No newline at end of file + return hash(self._position) ^ (hash(self._material.guid) if self._material is not None else hash(0)) ^ hash(self._hotend_id) \ No newline at end of file diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py index f59cc1bece..8d674c1c5f 100644 --- a/cura/PrinterOutput/PrinterOutputModel.py +++ b/cura/PrinterOutput/PrinterOutputModel.py @@ -23,6 +23,7 @@ class PrinterOutputModel(QObject): headPositionChanged = pyqtSignal() keyChanged = pyqtSignal() typeChanged = pyqtSignal() + buildplateChanged = pyqtSignal() cameraChanged = pyqtSignal() configurationChanged = pyqtSignal() @@ -41,6 +42,7 @@ class PrinterOutputModel(QObject): self._printer_state = "unknown" self._is_preheating = False self._type = "" + self._buildplate_name = None # Update the printer configuration every time any of the extruders changes its configuration for extruder in self._extruders: extruder.extruderConfigurationChanged.connect(self._updatePrinterConfiguration) @@ -78,6 +80,15 @@ class PrinterOutputModel(QObject): self._type = type self.typeChanged.emit() + @pyqtProperty(str, notify = buildplateChanged) + def buildplate(self): + return self._buildplate_name + + def updateBuildplate(self, buildplate_name): + if self._buildplate_name != buildplate_name: + self._buildplate_name = buildplate_name + self.buildplateChanged.emit() + @pyqtProperty(str, notify=keyChanged) def key(self): return self._key @@ -252,5 +263,5 @@ class PrinterOutputModel(QObject): def _updatePrinterConfiguration(self): self._printer_configuration.printerType = self._type self._printer_configuration.extruderConfigurations = [extruder.extruderConfiguration for extruder in self._extruders] - self._printer_configuration.buildplateConfiguration = None # TODO Add the buildplate information + self._printer_configuration.buildplateConfiguration = self._buildplate_name self.configurationChanged.emit() diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 0924b1d33b..12146e927e 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -24,6 +24,7 @@ from UM.Settings.SettingFunction import SettingFunction from UM.Signal import postponeSignals, CompressTechnique from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch +from cura.Machines.VariantManager import VariantType from cura.PrinterOutputDevice import PrinterOutputDevice from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel @@ -205,11 +206,6 @@ class MachineManager(QObject): # print("%%%%%%%%", configuration == self._current_printer_configuration) return self._current_printer_configuration == configuration - @pyqtSlot(QObject) - def applyRemoteConfiguration(self, configuration: ConfigurationModel): - for extruder_configuration in configuration.extruderConfigurations: - self.setConfiguration(extruder_configuration.position, extruder_configuration.hotendID, extruder_configuration.material.guid) - @pyqtProperty("QVariantList", notify = outputDevicesChanged) def printerOutputDevices(self): return self._printer_output_devices @@ -1028,6 +1024,29 @@ class MachineManager(QObject): self._setMaterial(position, new_material) continue + @pyqtSlot(QObject) + def applyRemoteConfiguration(self, configuration: ConfigurationModel): + self.blurSettings.emit() + with postponeSignals(*self._getContainerChangedSignals(), + compress=CompressTechnique.CompressPerParameterValue): + for extruder_configuration in configuration.extruderConfigurations: + position = str(extruder_configuration.position) + variant_container_node = self._variant_manager.getVariantNode( + self._global_container_stack.definition.getId(), extruder_configuration.hotendID) + material_container_node = self._material_manager.getMaterialNodeByType( + self._global_container_stack, extruder_configuration.hotendID, + extruder_configuration.material.guid) + self._setVariantNode(position, variant_container_node) + self._setMaterial(position, material_container_node) + self._updateMaterialWithVariant(position) + + if configuration.buildplateConfiguration is not None: + global_variant_container_node = self._variant_manager.getVariantNode( + self._global_container_stack.definition.getId(), configuration.buildplateConfiguration, + variant_type=VariantType.BUILD_PLATE) + self._setGlobalVariant(global_variant_container_node) + self._updateQualityWithMaterial() + @pyqtSlot("QVariant") def setGlobalVariant(self, container_node): self.blurSettings.emit() @@ -1036,16 +1055,6 @@ class MachineManager(QObject): self._updateMaterialWithVariant(None) # Update all materials self._updateQualityWithMaterial() - def setConfiguration(self, position, variant_name, material_guid): - position = str(position) - variant_container_node = self._variant_manager.getVariantNode(self._global_container_stack.definition.getId(), variant_name) - material_container_node = self._material_manager.getMaterialNodeByType(self._global_container_stack, variant_name, material_guid) - with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): - self._setVariantNode(position, variant_container_node) - self._setMaterial(position, material_container_node) - self._updateMaterialWithVariant(position) - self._updateQualityWithMaterial() - @pyqtSlot(str, "QVariant") def setMaterial(self, position, container_node): position = str(position) diff --git a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py index 7a4c590acc..a79936bdcf 100644 --- a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py @@ -380,6 +380,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): printer.updateName(data["friendly_name"]) printer.updateKey(data["uuid"]) printer.updateType(data["machine_variant"]) + if "build_plate" in data: + printer.updateBuildplate(data["build_plate"]["name"]) if not data["enabled"]: printer.updateState("disabled") else: From a02486e85a71a4aa04cc4820dc649d62fef5041c Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 7 Mar 2018 17:15:56 +0100 Subject: [PATCH 29/66] Added status icon --- resources/qml/MachineSelection.qml | 40 ++++++++++++----------- resources/qml/Menus/PrinterStatusIcon.qml | 27 +++++++++++++++ resources/themes/cura-light/theme.json | 2 ++ 3 files changed, 50 insertions(+), 19 deletions(-) create mode 100644 resources/qml/Menus/PrinterStatusIcon.qml diff --git a/resources/qml/MachineSelection.qml b/resources/qml/MachineSelection.qml index e40731f3ca..b266b0c839 100644 --- a/resources/qml/MachineSelection.qml +++ b/resources/qml/MachineSelection.qml @@ -10,35 +10,28 @@ import UM 1.2 as UM import Cura 1.0 as Cura import "Menus" -ToolButton -{ +ToolButton { + property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 text: Cura.MachineManager.activeMachineName tooltip: Cura.MachineManager.activeMachineName - style: ButtonStyle - { - background: Rectangle - { - color: - { - if(control.pressed) - { + style: ButtonStyle { + background: Rectangle { + color: { + if (control.pressed) { return UM.Theme.getColor("sidebar_header_active"); } - else if(control.hovered) - { + else if (control.hovered) { return UM.Theme.getColor("sidebar_header_hover"); } - else - { + else { return UM.Theme.getColor("sidebar_header_bar"); } } Behavior on color { ColorAnimation { duration: 50; } } - UM.RecolorImage - { + UM.RecolorImage { id: downArrow anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right @@ -50,14 +43,23 @@ ToolButton color: UM.Theme.getColor("text_emphasis") source: UM.Theme.getIcon("arrow_bottom") } - Label - { + + PrinterStatusIcon { + visible: printerConnected + anchors { + verticalCenter: parent.verticalCenter + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + } + } + + Label { id: sidebarComboBoxLabel color: UM.Theme.getColor("sidebar_header_text_active") text: control.text; elide: Text.ElideRight; anchors.left: parent.left; - anchors.leftMargin: UM.Theme.getSize("default_margin").width * 2 + anchors.leftMargin: printerConnected ? UM.Theme.getSize("default_margin").width * 3 : UM.Theme.getSize("default_margin").width * 2 anchors.right: downArrow.left; anchors.rightMargin: control.rightMargin; anchors.verticalCenter: parent.verticalCenter; diff --git a/resources/qml/Menus/PrinterStatusIcon.qml b/resources/qml/Menus/PrinterStatusIcon.qml new file mode 100644 index 0000000000..a8c465dba8 --- /dev/null +++ b/resources/qml/Menus/PrinterStatusIcon.qml @@ -0,0 +1,27 @@ +// Copyright (c) 2017 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Layouts 1.1 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Item { + property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 + width: childrenRect.width + height: childrenRect.height + Image { + id: statusIcon + width: UM.Theme.getSize("status_icon").width + height: UM.Theme.getSize("status_icon").height + sourceSize.width: width + sourceSize.height: width + source: printerConnected ? UM.Theme.getIcon("tab_status_connected") : UM.Theme.getIcon("tab_status_busy") + } +} + + + diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index d97970e566..7c5d7bddec 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -360,6 +360,8 @@ "small_button": [2, 2], "small_button_icon": [1.5, 1.5], + "status_icon": [1.0, 1.0], + "topbar_logo_right_margin": [3, 0], "topbar_button": [8, 4], "topbar_button_icon": [1.2, 1.2], From e7294e1299c03aa54dcaa12ac9eeea22448dfb5e Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 7 Mar 2018 18:52:48 +0100 Subject: [PATCH 30/66] CURA-4870 Correctly look for the buildplate variants using the machine_buildplate_type that is also sent in the gcode and is the information that Cura gets from connect. Create a new dict in the VariantManager that maps the machine_buildplate_type with the right container --- cura/Machines/VariantManager.py | 26 ++++++++++++++++++- cura/Settings/MachineManager.py | 16 ++++-------- .../ClusterUM3OutputDevice.py | 2 +- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/cura/Machines/VariantManager.py b/cura/Machines/VariantManager.py index 6cb0a3d7b2..44ed9614f7 100644 --- a/cura/Machines/VariantManager.py +++ b/cura/Machines/VariantManager.py @@ -25,7 +25,7 @@ ALL_VARIANT_TYPES = (VariantType.BUILD_PLATE, VariantType.NOZZLE) # -# VariantManager is THE place to look for a specific variant. It maintains a variant lookup table with the following +# VariantManager is THE place to look for a specific variant. It maintains two variant lookup tables with the following # structure: # # [machine_definition_id] -> [variant_type] -> [variant_name] -> ContainerNode(metadata / container) @@ -35,6 +35,9 @@ ALL_VARIANT_TYPES = (VariantType.BUILD_PLATE, VariantType.NOZZLE) # -> "BB 0.8" # -> ... # +# [machine_definition_id] -> [machine_buildplate_type] -> ContainerNode(metadata / container) +# Example: "ultimaker3" -> "glass" (this is different from the variant name) -> ContainerNode +# # Note that the "container" field is not loaded in the beginning because it would defeat the purpose of lazy-loading. # A container is loaded when getVariant() is called to load a variant InstanceContainer. # @@ -44,6 +47,7 @@ class VariantManager: self._container_registry = container_registry # type: ContainerRegistry self._machine_to_variant_dict_map = dict() # -> + self._machine_to_buildplate_dict_map = dict() self._exclude_variant_id_list = ["empty_variant"] @@ -53,6 +57,7 @@ class VariantManager: # def initialize(self): self._machine_to_variant_dict_map = OrderedDict() + self._machine_to_buildplate_dict_map = OrderedDict() # Cache all variants from the container registry to a variant map for better searching and organization. variant_metadata_list = self._container_registry.findContainersMetadata(type = "variant") @@ -78,6 +83,22 @@ class VariantManager: variant_dict[variant_name] = ContainerNode(metadata = variant_metadata) + # If the variant is a buildplate then fill also the buildplate map + if variant_type == VariantType.BUILD_PLATE: + if variant_definition not in self._machine_to_buildplate_dict_map: + self._machine_to_buildplate_dict_map[variant_definition] = OrderedDict() + + variant_container = self._container_registry.findContainers(type = "variant", id = variant_metadata["id"]) + if not variant_container: + # ERROR: not variant container. This should never happen + raise RuntimeError("Not variant found [%s], type [%s] for machine [%s]" % + (variant_name, variant_type, variant_definition)) + buildplate_type = variant_container[0].getProperty("machine_buildplate_type", "value") + if buildplate_type not in self._machine_to_buildplate_dict_map[variant_definition]: + self._machine_to_variant_dict_map[variant_definition][buildplate_type] = dict() + + self._machine_to_buildplate_dict_map[variant_definition][buildplate_type] = variant_dict[variant_name] + # # Gets the variant InstanceContainer with the given information. # Almost the same as getVariantMetadata() except that this returns an InstanceContainer if present. @@ -109,3 +130,6 @@ class VariantManager: if preferred_variant_name: node = self.getVariantNode(machine_definition_id, preferred_variant_name, variant_type) return node + + def getBuildplateVariantNode(self, machine_definition_id: str, buildplate_type: str) -> Optional["ContainerNode"]: + return self._machine_to_buildplate_dict_map[machine_definition_id].get(buildplate_type) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 12146e927e..de7a08a65a 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -196,7 +196,7 @@ class MachineManager(QObject): extruder_configuration.hotendID = extruder.variant.getName() if extruder.variant != self._empty_variant_container else None self._current_printer_configuration.extruderConfigurations.append(extruder_configuration) - self._current_printer_configuration.buildplateConfiguration = self._global_container_stack.variant.getName() if self._global_container_stack.variant != self._empty_variant_container else None + self._current_printer_configuration.buildplateConfiguration = self._global_container_stack.getProperty("machine_buildplate_type", "value") if self._global_container_stack.variant != self._empty_variant_container else None self.currentConfigurationChanged.emit() @pyqtSlot(QObject, result = bool) @@ -1027,23 +1027,17 @@ class MachineManager(QObject): @pyqtSlot(QObject) def applyRemoteConfiguration(self, configuration: ConfigurationModel): self.blurSettings.emit() - with postponeSignals(*self._getContainerChangedSignals(), - compress=CompressTechnique.CompressPerParameterValue): + with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): for extruder_configuration in configuration.extruderConfigurations: position = str(extruder_configuration.position) - variant_container_node = self._variant_manager.getVariantNode( - self._global_container_stack.definition.getId(), extruder_configuration.hotendID) - material_container_node = self._material_manager.getMaterialNodeByType( - self._global_container_stack, extruder_configuration.hotendID, - extruder_configuration.material.guid) + variant_container_node = self._variant_manager.getVariantNode(self._global_container_stack.definition.getId(), extruder_configuration.hotendID) + material_container_node = self._material_manager.getMaterialNodeByType(self._global_container_stack, extruder_configuration.hotendID,extruder_configuration.material.guid) self._setVariantNode(position, variant_container_node) self._setMaterial(position, material_container_node) self._updateMaterialWithVariant(position) if configuration.buildplateConfiguration is not None: - global_variant_container_node = self._variant_manager.getVariantNode( - self._global_container_stack.definition.getId(), configuration.buildplateConfiguration, - variant_type=VariantType.BUILD_PLATE) + global_variant_container_node = self._variant_manager.getBuildplateVariantNode(self._global_container_stack.definition.getId(), configuration.buildplateConfiguration) self._setGlobalVariant(global_variant_container_node) self._updateQualityWithMaterial() diff --git a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py index a79936bdcf..8eeb8d91e7 100644 --- a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py @@ -381,7 +381,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): printer.updateKey(data["uuid"]) printer.updateType(data["machine_variant"]) if "build_plate" in data: - printer.updateBuildplate(data["build_plate"]["name"]) + printer.updateBuildplate(data["build_plate"]["type"]) if not data["enabled"]: printer.updateState("disabled") else: From 2818ff7f31d16d2affe89a118aef5bb83b70bb33 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 7 Mar 2018 19:40:44 +0100 Subject: [PATCH 31/66] CURA-4870 Fix binding loop in some components with the height property by changing the vertical alignments --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 3 +-- .../qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml | 3 +-- resources/qml/Menus/ConfigurationMenu/SyncButton.qml | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index e4c4683869..be8c8bcb45 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -77,7 +77,6 @@ Rectangle UM.RecolorImage { id: buildplateIcon anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter width: UM.Theme.getSize("topbar_button_icon").width height: UM.Theme.getSize("topbar_button_icon").height sourceSize.width: width @@ -90,7 +89,7 @@ Rectangle { id: buildplateLabel anchors.left: buildplateIcon.right - anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenter: buildplateIcon.verticalCenter anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) text: configuration.buildplateConfiguration color: textColor diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index d34252adc4..ca1b666e69 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -27,7 +27,6 @@ Column id: extruderLabel text: catalog.i18nc("@label:extruder label", "Extruder") elide: Text.ElideRight - anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left font: UM.Theme.getFont("default") color: mainColor @@ -37,7 +36,7 @@ Column Item { id: extruderIconItem - anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenter: extruderLabel.verticalCenter anchors.left: extruderLabel.right anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").width / 2) diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml index 3834f2ebd2..43cf4529cb 100644 --- a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml +++ b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml @@ -11,7 +11,7 @@ import Cura 1.0 as Cura Button { id: base - property var outputDevice: Cura.MachineManager.printerOutputDevices[0] != null ? Cura.MachineManager.printerOutputDevices[0] : null + property var outputDevice: Cura.MachineManager.printerOutputDevices[0] text: catalog.i18nc("@label:sync indicator", "No match") width: parent.width height: parent.height From be8fc9f3f1c5eb2e7dcda6cae3a10c0762783ba4 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 7 Mar 2018 19:59:06 +0100 Subject: [PATCH 32/66] CURA-4870 Manage the case when there is an empty material or variant in the printer and Cura needs to apply this configuration --- cura/Settings/MachineManager.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index de7a08a65a..767021e2df 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1032,13 +1032,22 @@ class MachineManager(QObject): position = str(extruder_configuration.position) variant_container_node = self._variant_manager.getVariantNode(self._global_container_stack.definition.getId(), extruder_configuration.hotendID) material_container_node = self._material_manager.getMaterialNodeByType(self._global_container_stack, extruder_configuration.hotendID,extruder_configuration.material.guid) - self._setVariantNode(position, variant_container_node) - self._setMaterial(position, material_container_node) + if variant_container_node: + self._setVariantNode(position, variant_container_node) + else: + self._global_container_stack.extruders[position].variant = self._empty_variant_container + + if material_container_node: + self._setMaterial(position, material_container_node) + else: + self._global_container_stack.extruders[position].material = self._empty_material_container self._updateMaterialWithVariant(position) if configuration.buildplateConfiguration is not None: global_variant_container_node = self._variant_manager.getBuildplateVariantNode(self._global_container_stack.definition.getId(), configuration.buildplateConfiguration) self._setGlobalVariant(global_variant_container_node) + else: + self._global_container_stack.variant = self._empty_variant_container self._updateQualityWithMaterial() @pyqtSlot("QVariant") From 3629c3959e54fe10d7dedb37fe67421d81bf25ef Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 7 Mar 2018 22:33:15 +0100 Subject: [PATCH 33/66] CURA-4870 Match the printer type in the dropdown with one of the available printer types in the group --- cura/Settings/MachineManager.py | 17 ++++ .../ConfigurationListView.qml | 2 +- .../Menus/ConfigurationMenu/SyncButton.qml | 13 +-- resources/qml/Menus/PrinterTypeMenu.qml | 8 +- resources/qml/SidebarHeader.qml | 81 ++++++++++--------- 5 files changed, 72 insertions(+), 49 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 767021e2df..be30c83dda 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -451,6 +451,12 @@ class MachineManager(QObject): def stacksHaveErrors(self) -> bool: return bool(self._stacks_have_errors) + @pyqtProperty(str, notify = globalContainerChanged) + def activeMachineDefinitionName(self) -> str: + if self._global_container_stack: + return self._global_container_stack.definition.getName() + return "" + @pyqtProperty(str, notify = globalContainerChanged) def activeMachineName(self) -> str: if self._global_container_stack: @@ -1024,6 +1030,17 @@ class MachineManager(QObject): self._setMaterial(position, new_material) continue + def switchPrinterType(self, machine_type): + container_registry = ContainerRegistry.getInstance() + machine_definition = container_registry.findDefinitionContainers(name = machine_type)[0] + self._global_container_stack.definition = machine_definition + self.globalContainerChanged.emit() + # machine_stack = CuraStackBuilder.createMachine("ultimaker_s5" + "_instance", "ultimaker_s5") + # # if not machine_stack: + # # raise Exception("No machine found for ID {}".format(machine_id)) + # Logger.log("d", "Setting active machine to %s", machine_stack.getId()) + # self.setActiveMachine(machine_stack.getId()) + @pyqtSlot(QObject) def applyRemoteConfiguration(self, configuration: ConfigurationModel): self.blurSettings.emit() diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 037fadcb22..be11240831 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -57,7 +57,7 @@ Column section.criteria: ViewSection.FullString section.delegate: sectionHeading - model: outputDevice.uniqueConfigurations + model: (ouputDevice != null) ? outputDevice.uniqueConfigurations : [] delegate: ConfigurationItem { width: parent.width - UM.Theme.getSize("default_margin").width diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml index 43cf4529cb..58b738323e 100644 --- a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml +++ b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml @@ -18,13 +18,16 @@ Button function updateOnSync() { - for (var index in outputDevice.uniqueConfigurations) + if (outputDevice != undefined) { - var configuration = outputDevice.uniqueConfigurations[index] - if (Cura.MachineManager.matchesConfiguration(configuration)) + for (var index in outputDevice.uniqueConfigurations) { - base.text = catalog.i18nc("@label:sync indicator", "Matched") - return + var configuration = outputDevice.uniqueConfigurations[index] + if (Cura.MachineManager.matchesConfiguration(configuration)) + { + base.text = catalog.i18nc("@label:sync indicator", "Matched") + return + } } } base.text = catalog.i18nc("@label:sync indicator", "No match") diff --git a/resources/qml/Menus/PrinterTypeMenu.qml b/resources/qml/Menus/PrinterTypeMenu.qml index b4fdb0a1d4..e84f53a4ba 100644 --- a/resources/qml/Menus/PrinterTypeMenu.qml +++ b/resources/qml/Menus/PrinterTypeMenu.qml @@ -1,8 +1,8 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick 2.7 +import QtQuick.Controls 1.4 import UM 1.3 as UM import Cura 1.0 as Cura @@ -16,12 +16,12 @@ Menu Instantiator { id: printerTypeInstantiator - model: outputDevice != null ? outputDevice.connectedPrintersTypeCount : null + model: outputDevice != null ? outputDevice.connectedPrintersTypeCount : [] MenuItem { text: modelData.machine_type checkable: true - checked: false + checked: Cura.MachineManager.activeMachineDefinitionName == modelData.machine_type exclusiveGroup: group // onTriggered: // { diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 7acc58c52a..8e12cd017b 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -17,6 +17,7 @@ Column property int currentExtruderIndex: Cura.ExtruderManager.activeExtruderIndex; property bool currentExtruderVisible: extrudersList.visible; property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 + property bool hasManyPrinterTypes: printerConnected ? Cura.MachineManager.printerOutputDevices[0].connectedPrintersTypeCount.length > 1 : false spacing: Math.round(UM.Theme.getSize("sidebar_margin").width * 0.9) @@ -35,45 +36,6 @@ Column width: height } - // Printer Type Row - Item - { - id: printerTypeSelectionRow - height: UM.Theme.getSize("sidebar_setup").height - visible: printerConnected && !sidebar.monitoringPrint && !sidebar.hideSettings - - anchors - { - left: parent.left - leftMargin: UM.Theme.getSize("sidebar_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("sidebar_margin").width - } - - Label - { - id: configurationLabel - text: catalog.i18nc("@label", "Printer type"); - width: Math.round(parent.width * 0.4 - UM.Theme.getSize("default_margin").width) - height: parent.height - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - } - - ToolButton - { - id: printerTypeSelection - text: catalog.i18nc("@label", "Printer type"); - height: UM.Theme.getSize("setting_control").height - width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width - anchors.right: parent.right - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - menu: PrinterTypeMenu { } - } - } - // Extruder Row Item { @@ -264,6 +226,47 @@ Column visible: !extruderSelectionRow.visible } + // Printer Type Row + Item + { + id: printerTypeSelectionRow + height: UM.Theme.getSize("sidebar_setup").height + visible: printerConnected && hasManyPrinterTypes && !sidebar.monitoringPrint && !sidebar.hideSettings + + anchors + { + left: parent.left + leftMargin: UM.Theme.getSize("sidebar_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("sidebar_margin").width + } + + Label + { + id: configurationLabel + text: catalog.i18nc("@label", "Printer type"); + width: Math.round(parent.width * 0.4 - UM.Theme.getSize("default_margin").width) + height: parent.height + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default"); + color: UM.Theme.getColor("text"); + } + + ToolButton + { + id: printerTypeSelection + text: Cura.MachineManager.activeMachineDefinitionName + tooltip: Cura.MachineManager.activeMachineDefinitionName + height: UM.Theme.getSize("setting_control").height + width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width + anchors.right: parent.right + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; + + menu: PrinterTypeMenu { } + } + } + // Material Row Item { From ae5f1c34080aa1983697b33c119d3be146ea28c8 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 7 Mar 2018 22:49:27 +0100 Subject: [PATCH 34/66] CURA-4870 Add line separator between machine selector and sync button --- resources/qml/Sidebar.qml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index 7a65a278eb..a93048cb26 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -88,12 +88,22 @@ Rectangle MachineSelection { id: machineSelection - width: base.width - configSelection.width + width: base.width - configSelection.width - separator.width height: UM.Theme.getSize("sidebar_header").height anchors.top: base.top anchors.left: parent.left } + Rectangle + { + id: separator + visible: configSelection.visible + width: visible ? Math.round(UM.Theme.getSize("sidebar_lining_thin").height / 2) : 0 + height: UM.Theme.getSize("sidebar_header").height + color: UM.Theme.getColor("sidebar_lining_thin") + anchors.left: machineSelection.right + } + ConfigurationSelection { id: configSelection visible: printerConnected && !sidebar.monitoringPrint && !sidebar.hideSettings From 86103b4a0f5db416985a1056c451e48e781a7f9a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 7 Mar 2018 22:54:03 +0100 Subject: [PATCH 35/66] CURA-4870 Change text size of the selected printer --- resources/qml/MachineSelection.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/MachineSelection.qml b/resources/qml/MachineSelection.qml index b266b0c839..b9d8840f2f 100644 --- a/resources/qml/MachineSelection.qml +++ b/resources/qml/MachineSelection.qml @@ -63,7 +63,7 @@ ToolButton { anchors.right: downArrow.left; anchors.rightMargin: control.rightMargin; anchors.verticalCenter: parent.verticalCenter; - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("medium_bold") } } label: Label {} From 4c7ec3920d4acb178e037f7c9ba2defe210be34b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 8 Mar 2018 09:25:14 +0100 Subject: [PATCH 36/66] CURA-4870 Reduce text size of the Machine selector menu --- resources/qml/Menus/ConfigurationMenu/SyncButton.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml index 58b738323e..4a92db6e6b 100644 --- a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml +++ b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml @@ -78,7 +78,7 @@ Button anchors.right: downArrow.left anchors.rightMargin: control.rightMargin anchors.verticalCenter: parent.verticalCenter; - font: UM.Theme.getFont("medium_bold") + font: UM.Theme.getFont("medium") } } label: Label {} From ffccdd99c03d74f060a49a608009f7e706876fa8 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 8 Mar 2018 10:55:29 +0100 Subject: [PATCH 37/66] Added status icon --- cura/Settings/MachineManager.py | 6 ++++++ resources/qml/MachineSelection.qml | 8 +++++--- resources/qml/Menus/PrinterStatusIcon.qml | 11 ++++++----- resources/themes/cura-light/theme.json | 11 +++++++++-- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index be30c83dda..7b9a4191ed 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -469,6 +469,12 @@ class MachineManager(QObject): return self._global_container_stack.getId() return "" + @pyqtProperty(str, notify = globalContainerChanged) + def activeMachineNetworkKey(self) -> str: + if self._global_container_stack: + return self._global_container_stack.getMetaDataEntry("um_network_key") + return "" + @pyqtProperty(QObject, notify = globalContainerChanged) def activeMachine(self) -> Optional["GlobalStack"]: return self._global_container_stack diff --git a/resources/qml/MachineSelection.qml b/resources/qml/MachineSelection.qml index b9d8840f2f..5ca6cda406 100644 --- a/resources/qml/MachineSelection.qml +++ b/resources/qml/MachineSelection.qml @@ -11,7 +11,8 @@ import Cura 1.0 as Cura import "Menus" ToolButton { - property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 + property var isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey ? true : false + property var printerStatus: Cura.MachineManager.printerOutputDevices.length != 0 ? "connected" : "unknown" text: Cura.MachineManager.activeMachineName tooltip: Cura.MachineManager.activeMachineName @@ -45,7 +46,8 @@ ToolButton { } PrinterStatusIcon { - visible: printerConnected + visible: isNetworkPrinter + status: printerStatus anchors { verticalCenter: parent.verticalCenter left: parent.left @@ -59,7 +61,7 @@ ToolButton { text: control.text; elide: Text.ElideRight; anchors.left: parent.left; - anchors.leftMargin: printerConnected ? UM.Theme.getSize("default_margin").width * 3 : UM.Theme.getSize("default_margin").width * 2 + anchors.leftMargin: isNetworkPrinter ? UM.Theme.getSize("default_margin").width * 3 : UM.Theme.getSize("default_margin").width * 2 anchors.right: downArrow.left; anchors.rightMargin: control.rightMargin; anchors.verticalCenter: parent.verticalCenter; diff --git a/resources/qml/Menus/PrinterStatusIcon.qml b/resources/qml/Menus/PrinterStatusIcon.qml index a8c465dba8..d7106bf33d 100644 --- a/resources/qml/Menus/PrinterStatusIcon.qml +++ b/resources/qml/Menus/PrinterStatusIcon.qml @@ -10,16 +10,17 @@ import UM 1.2 as UM import Cura 1.0 as Cura Item { - property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 + property var status: "unknown" width: childrenRect.width height: childrenRect.height - Image { + UM.RecolorImage { id: statusIcon - width: UM.Theme.getSize("status_icon").width - height: UM.Theme.getSize("status_icon").height + width: UM.Theme.getSize("printer_status_icon").width + height: UM.Theme.getSize("printer_status_icon").height sourceSize.width: width sourceSize.height: width - source: printerConnected ? UM.Theme.getIcon("tab_status_connected") : UM.Theme.getIcon("tab_status_busy") + color: UM.Theme.getColor("tab_status_" + parent.status ) + source: UM.Theme.getIcon("tab_status_" + parent.status ) } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 7c5d7bddec..1e3f9ce79a 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -307,7 +307,14 @@ "configuration_item_text_active": [0, 0, 0, 255], "configuration_item_border": [127, 127, 127, 255], "configuration_item_border_active": [12, 169, 227, 32], - "configuration_item_border_hover": [12, 169, 227, 255] + "configuration_item_border_hover": [12, 169, 227, 255], + + "tab_status_busy": [255, 255, 255, 255], + "tab_status_connected": [12, 169, 227, 255], + "tab_status_finished": [255, 255, 255, 255], + "tab_status_paused": [255, 255, 255, 255], + "tab_status_stopped": [255, 255, 255, 255], + "tab_status_unknown": [200, 200, 200, 255] }, "sizes": { @@ -360,7 +367,7 @@ "small_button": [2, 2], "small_button_icon": [1.5, 1.5], - "status_icon": [1.0, 1.0], + "printer_status_icon": [1.0, 1.0], "topbar_logo_right_margin": [3, 0], "topbar_button": [8, 4], From 1a57e9323b3acf7f69e7b3b732c93b6a669062dd Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 8 Mar 2018 12:54:59 +0100 Subject: [PATCH 38/66] Improved status icon size --- resources/qml/MachineSelection.qml | 7 ++++--- resources/themes/cura-light/theme.json | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/resources/qml/MachineSelection.qml b/resources/qml/MachineSelection.qml index 5ca6cda406..cce2bbea7b 100644 --- a/resources/qml/MachineSelection.qml +++ b/resources/qml/MachineSelection.qml @@ -46,12 +46,13 @@ ToolButton { } PrinterStatusIcon { + id: printerStatusIcon visible: isNetworkPrinter status: printerStatus anchors { verticalCenter: parent.verticalCenter left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width + leftMargin: UM.Theme.getSize("sidebar_margin").width } } @@ -60,8 +61,8 @@ ToolButton { color: UM.Theme.getColor("sidebar_header_text_active") text: control.text; elide: Text.ElideRight; - anchors.left: parent.left; - anchors.leftMargin: isNetworkPrinter ? UM.Theme.getSize("default_margin").width * 3 : UM.Theme.getSize("default_margin").width * 2 + anchors.left: isNetworkPrinter ? printerStatusIcon.right : parent.left; + anchors.leftMargin: isNetworkPrinter ? UM.Theme.getSize("sidebar_lining").width : UM.Theme.getSize("sidebar_margin").width anchors.right: downArrow.left; anchors.rightMargin: control.rightMargin; anchors.verticalCenter: parent.verticalCenter; diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 1e3f9ce79a..4cdff3c296 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -367,7 +367,7 @@ "small_button": [2, 2], "small_button_icon": [1.5, 1.5], - "printer_status_icon": [1.0, 1.0], + "printer_status_icon": [1.2, 1.2], "topbar_logo_right_margin": [3, 0], "topbar_button": [8, 4], From 1bde7a6228cef6b9ba7ac87d531ec239ca8dd01a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 8 Mar 2018 14:01:19 +0100 Subject: [PATCH 39/66] CURA-4870 Set the correct version of the QtQuick.Controls to be compliant with v5.8 --- .../qml/Menus/ConfigurationMenu/ConfigurationSelection.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml index 4097df229b..10d8f60e90 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml @@ -2,7 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 2.3 +import QtQuick.Controls 2.0 import QtQuick.Controls.Styles 1.4 import UM 1.2 as UM From ae094c8201c639c62a89168eaaf417d6fed90d31 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 8 Mar 2018 14:02:22 +0100 Subject: [PATCH 40/66] CURA-4870 Disable the connect button in the discovery list when the printer is not a host of printers. --- plugins/UM3NetworkPrinting/DiscoverUM3Action.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml index c0cb5a78b7..a5d13b2cdf 100644 --- a/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml @@ -303,7 +303,7 @@ Cura.MachineAction Button { text: catalog.i18nc("@action:button", "Connect") - enabled: (base.selectedDevice && base.completeProperties) ? true : false + enabled: (base.selectedDevice && base.completeProperties && base.selectedDevice.clusterSize > 0) ? true : false onClicked: connectToPrinter() } } From 591d3f29ec860a940e5c1ba73a23ea26b4ca95b1 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 8 Mar 2018 15:36:12 +0100 Subject: [PATCH 41/66] CURA-4870 Don't crash when there is not buildplate variant for the current machine --- cura/Machines/VariantManager.py | 4 +++- cura/Settings/MachineManager.py | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cura/Machines/VariantManager.py b/cura/Machines/VariantManager.py index 44ed9614f7..196c2e7b1d 100644 --- a/cura/Machines/VariantManager.py +++ b/cura/Machines/VariantManager.py @@ -132,4 +132,6 @@ class VariantManager: return node def getBuildplateVariantNode(self, machine_definition_id: str, buildplate_type: str) -> Optional["ContainerNode"]: - return self._machine_to_buildplate_dict_map[machine_definition_id].get(buildplate_type) + if machine_definition_id in self._machine_to_buildplate_dict_map: + return self._machine_to_buildplate_dict_map[machine_definition_id].get(buildplate_type) + return None diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 7b9a4191ed..aa86311259 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1068,7 +1068,10 @@ class MachineManager(QObject): if configuration.buildplateConfiguration is not None: global_variant_container_node = self._variant_manager.getBuildplateVariantNode(self._global_container_stack.definition.getId(), configuration.buildplateConfiguration) - self._setGlobalVariant(global_variant_container_node) + if global_variant_container_node: + self._setGlobalVariant(global_variant_container_node) + else: + self._global_container_stack.variant = self._empty_variant_container else: self._global_container_stack.variant = self._empty_variant_container self._updateQualityWithMaterial() From a2773ca8974471d768e59d1584984ea662f8c749 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 8 Mar 2018 16:30:05 +0100 Subject: [PATCH 42/66] Animated popup --- .../ConfigurationListView.qml | 2 ++ .../ConfigurationSelection.qml | 36 ++++++++++++++++--- resources/qml/Menus/PrinterStatusIcon.qml | 3 -- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index be11240831..1bb81656a3 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -12,12 +12,14 @@ Column { id: base property var outputDevice: Cura.MachineManager.printerOutputDevices[0] + property var computedHeight: container.height + configurationListHeading.height + 3 * padding height: childrenRect.height + 2 * padding padding: UM.Theme.getSize("default_margin").width spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) Label { + id: configurationListHeading text: catalog.i18nc("@label:header configurations", "Available configurations") font: UM.Theme.getFont("large") width: parent.width - 2 * parent.padding diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml index 10d8f60e90..3b053afb15 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml @@ -14,24 +14,50 @@ Item property var panelWidth: control.width property var panelVisible: false - SyncButton { } + SyncButton { + onClicked: configurationSelector.state == "open" ? configurationSelector.state = "closed" : configurationSelector.state = "open" + } - Popup - { + Popup { id: popup + clip: true y: configurationSelector.height - UM.Theme.getSize("default_lining").height x: configurationSelector.width - width width: panelWidth visible: panelVisible padding: UM.Theme.getSize("default_lining").width - contentItem: ConfigurationListView { + id: configList width: panelWidth - 2 * popup.padding } - background: Rectangle { color: UM.Theme.getColor("setting_control") border.color: UM.Theme.getColor("setting_control_border") } } + + states: [ + // This adds a second state to the container where the rectangle is farther to the right + State { + name: "open" + PropertyChanges { + target: popup + height: configList.computedHeight + } + }, + State { + name: "closed" + PropertyChanges { + target: popup + height: 0 + } + } + ] + transitions: [ + // This adds a transition that defaults to applying to all state changes + Transition { + // This applies a default NumberAnimation to any changes a state change makes to x or y properties + NumberAnimation { properties: "height"; duration: 200; easing.type: Easing.InOutQuad; } + } + ] } \ No newline at end of file diff --git a/resources/qml/Menus/PrinterStatusIcon.qml b/resources/qml/Menus/PrinterStatusIcon.qml index d7106bf33d..23459386d9 100644 --- a/resources/qml/Menus/PrinterStatusIcon.qml +++ b/resources/qml/Menus/PrinterStatusIcon.qml @@ -2,9 +2,6 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 import UM 1.2 as UM import Cura 1.0 as Cura From fa5aa0a53f2b884c72bca30c7ce0917905bc5e09 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 8 Mar 2018 16:55:40 +0100 Subject: [PATCH 43/66] CURA-4870 React to outputdeviceschanged signal, to update the list of the configurations. --- cura/PrinterOutputDevice.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index d2916016e0..453cb4d78a 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -74,6 +74,7 @@ class PrinterOutputDevice(QObject, OutputDevice): self._address = "" self._connection_text = "" self.printersChanged.connect(self._onPrintersChanged) + Application.getInstance().getOutputDeviceManager().outputDevicesChanged.connect(self._updateUniqueConfigurations) @pyqtProperty(str, notify = connectionTextChanged) def address(self): From 4be4d08d97a5f90ec5f981f7cab7a972cb00fcfb Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 9 Mar 2018 10:47:08 +0100 Subject: [PATCH 44/66] CURA-4870 Add the ability in Cura to switch between different types of printers. Create a new container stack if it doesn't exist with the same network connection key. --- cura/Settings/MachineManager.py | 47 ++++++++++++++++++------- resources/qml/Menus/PrinterTypeMenu.qml | 8 ++--- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index c95f9d28f9..c42a0152ef 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -352,12 +352,25 @@ class MachineManager(QObject): self.__emitChangedSignals() + ## Given a definition id, return the machine with this id. + # Optional: add a list of keys and values to filter the list of machines with the given definition id + # \param definition_id \type{str} definition id that needs to look for + # \param metadata_filter \type{dict} list of metadata keys and values used for filtering @staticmethod - def getMachine(definition_id: str) -> Optional["GlobalStack"]: + def getMachine(definition_id: str, metadata_filter: Dict[str, str] = None) -> Optional["GlobalStack"]: machines = ContainerRegistry.getInstance().findContainerStacks(type = "machine") for machine in machines: if machine.definition.getId() == definition_id: - return machine + if metadata_filter: + pass_all_filters = True + for key in metadata_filter: + if machine.getMetaDataEntry(key) != metadata_filter[key]: + pass_all_filters = False + break + if pass_all_filters: + return machine + else: + return machine return None @pyqtSlot(str, str) @@ -1044,21 +1057,31 @@ class MachineManager(QObject): self._setMaterial(position, new_material) continue - def switchPrinterType(self, machine_type): - container_registry = ContainerRegistry.getInstance() - machine_definition = container_registry.findDefinitionContainers(name = machine_type)[0] - self._global_container_stack.definition = machine_definition - self.globalContainerChanged.emit() - # machine_stack = CuraStackBuilder.createMachine("ultimaker_s5" + "_instance", "ultimaker_s5") - # # if not machine_stack: - # # raise Exception("No machine found for ID {}".format(machine_id)) - # Logger.log("d", "Setting active machine to %s", machine_stack.getId()) - # self.setActiveMachine(machine_stack.getId()) + ## Given a printer definition name, select the right machine instance. In case it doesn't exist, create a new + # instance with the same network key. + @pyqtSlot(str) + def switchPrinterType(self, machine_name): + # Don't switch if the user tries to change to the same type of printer + if self.activeMachineDefinitionName == machine_name: + return + # Get the definition id corresponding to this machine name + machine_definition_id = ContainerRegistry.getInstance().findDefinitionContainers(name = machine_name)[0].getId() + # Try to find a machine with the same network key + new_machine = self.getMachine(machine_definition_id, metadata_filter = {"um_network_key": self.activeMachineNetworkKey}) + # If there is no machine, then create a new one + if not new_machine: + new_machine = CuraStackBuilder.createMachine(machine_definition_id + "_instance", machine_definition_id) + new_machine.addMetaDataEntry("um_network_key", self.activeMachineNetworkKey) + else: + Logger.log("i", "Found a %s with the key %s. Let's use it!", machine_name, self.activeMachineNetworkKey) + + self.setActiveMachine(new_machine.getId()) @pyqtSlot(QObject) def applyRemoteConfiguration(self, configuration: ConfigurationModel): self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): + self.switchPrinterType(configuration.printerType) for extruder_configuration in configuration.extruderConfigurations: position = str(extruder_configuration.position) variant_container_node = self._variant_manager.getVariantNode(self._global_container_stack.definition.getId(), extruder_configuration.hotendID) diff --git a/resources/qml/Menus/PrinterTypeMenu.qml b/resources/qml/Menus/PrinterTypeMenu.qml index e84f53a4ba..0cb98bc1aa 100644 --- a/resources/qml/Menus/PrinterTypeMenu.qml +++ b/resources/qml/Menus/PrinterTypeMenu.qml @@ -23,10 +23,10 @@ Menu checkable: true checked: Cura.MachineManager.activeMachineDefinitionName == modelData.machine_type exclusiveGroup: group -// onTriggered: -// { -// TODO -// } + onTriggered: + { + Cura.MachineManager.switchPrinterType(modelData.machine_type) + } } onObjectAdded: menu.insertItem(index, object) onObjectRemoved: menu.removeItem(object) From 260cad36cb4dd09643b822ec177ae009c11a5161 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 9 Mar 2018 12:42:49 +0100 Subject: [PATCH 45/66] CURA-4870 Add name of the group and hidden property to the network printers. The printer menu shows the printers grouped by group and the hidden printers are never listed. --- cura/Settings/MachineManager.py | 10 +++++++++- .../UM3NetworkPrinting/DiscoverUM3Action.py | 18 ++++++++++++++++++ .../UM3NetworkPrinting/DiscoverUM3Action.qml | 6 ++++-- resources/qml/Menus/NetworkPrinterMenu.qml | 6 +++--- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index c42a0152ef..0b9362af59 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -496,6 +496,12 @@ class MachineManager(QObject): return self._global_container_stack.getMetaDataEntry("um_network_key") return "" + @pyqtProperty(str, notify = globalContainerChanged) + def activeMachineNetworkGroupName(self) -> str: + if self._global_container_stack: + return self._global_container_stack.getMetaDataEntry("connect_group_name") + return "" + @pyqtProperty(QObject, notify = globalContainerChanged) def activeMachine(self) -> Optional["GlobalStack"]: return self._global_container_stack @@ -1070,8 +1076,10 @@ class MachineManager(QObject): new_machine = self.getMachine(machine_definition_id, metadata_filter = {"um_network_key": self.activeMachineNetworkKey}) # If there is no machine, then create a new one if not new_machine: - new_machine = CuraStackBuilder.createMachine(machine_definition_id + "_instance", machine_definition_id) + new_machine = CuraStackBuilder.createMachine(machine_definition_id + "_sync", machine_definition_id) new_machine.addMetaDataEntry("um_network_key", self.activeMachineNetworkKey) + new_machine.addMetaDataEntry("connect_group_name", self.activeMachineNetworkGroupName) + new_machine.addMetaDataEntry("hidden", True) else: Logger.log("i", "Found a %s with the key %s. Let's use it!", machine_name, self.activeMachineNetworkKey) diff --git a/plugins/UM3NetworkPrinting/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/DiscoverUM3Action.py index 0e872fed43..4b972e9040 100644 --- a/plugins/UM3NetworkPrinting/DiscoverUM3Action.py +++ b/plugins/UM3NetworkPrinting/DiscoverUM3Action.py @@ -97,6 +97,23 @@ class DiscoverUM3Action(MachineAction): else: return [] + @pyqtSlot(str) + def setGroupName(self, group_name): + Logger.log("d", "Attempting to set the group name of the active machine to %s", group_name) + global_container_stack = Application.getInstance().getGlobalContainerStack() + if global_container_stack: + meta_data = global_container_stack.getMetaData() + if "connect_group_name" in meta_data: + global_container_stack.setMetaDataEntry("connect_group_name", group_name) + # TODO Find all the places where there is the same group name and change it accordingly + else: + global_container_stack.addMetaDataEntry("connect_group_name", group_name) + global_container_stack.addMetaDataEntry("hidden", False) + + if self._network_plugin: + # Ensure that the connection states are refreshed. + self._network_plugin.reCheckConnections() + @pyqtSlot(str) def setKey(self, key): Logger.log("d", "Attempting to set the network key of the active machine to %s", key) @@ -109,6 +126,7 @@ class DiscoverUM3Action(MachineAction): Logger.log("d", "Removing old authentication id %s for device %s", global_container_stack.getMetaDataEntry("network_authentication_id", None), key) global_container_stack.removeMetaDataEntry("network_authentication_id") global_container_stack.removeMetaDataEntry("network_authentication_key") + # TODO Find all the places where there is the same key and change it accordingly else: global_container_stack.addMetaDataEntry("um_network_key", key) diff --git a/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml index a5d13b2cdf..079e5dcdd3 100644 --- a/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml @@ -32,10 +32,12 @@ Cura.MachineAction if(base.selectedDevice && base.completeProperties) { var printerKey = base.selectedDevice.key + var printerName = base.selectedDevice.name // TODO To change when the groups have a name if(manager.getStoredKey() != printerKey) { - manager.setKey(printerKey); - completed(); + manager.setKey(printerKey) + manager.setGroupName(printerName) // TODO To change when the groups have a name + completed() } } } diff --git a/resources/qml/Menus/NetworkPrinterMenu.qml b/resources/qml/Menus/NetworkPrinterMenu.qml index 64539c9892..07a22202e4 100644 --- a/resources/qml/Menus/NetworkPrinterMenu.qml +++ b/resources/qml/Menus/NetworkPrinterMenu.qml @@ -9,14 +9,14 @@ import Cura 1.0 as Cura Instantiator { model: UM.ContainerStacksModel { - filter: {"type": "machine", "um_network_key": "*"} + filter: {"type": "machine", "um_network_key": "*", "hidden": "False"} } MenuItem { // TODO: Use printer_group icon when it's a cluster. Not use it for now since it doesn't look as expected // iconSource: UM.Theme.getIcon("printer_single") - text: model.name; + text: model.metadata["connect_group_name"] checkable: true; - checked: Cura.MachineManager.activeMachineId == model.id + checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] exclusiveGroup: group; onTriggered: Cura.MachineManager.setActiveMachine(model.id); } From ebbb30a5be75e4fc3c7f80e317d346e57302ee0a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 9 Mar 2018 13:37:15 +0100 Subject: [PATCH 46/66] CURA-4870 Replace network key and connect group name metadata values when the connection changes. --- cura/Settings/MachineManager.py | 7 +++++++ plugins/UM3NetworkPrinting/DiscoverUM3Action.py | 7 +++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 0b9362af59..3bc2df0da1 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1115,6 +1115,13 @@ class MachineManager(QObject): self._global_container_stack.variant = self._empty_variant_container self._updateQualityWithMaterial() + ## Find all container stacks that has the pair 'key = value' in its metadata and replaces the value with 'new_value' + def replaceContainersMetadata(self, key: str, value: str, new_value: str): + machines = ContainerRegistry.getInstance().findContainerStacks(type = "machine") + for machine in machines: + if machine.getMetaDataEntry(key) == value: + machine.setMetaDataEntry(key, new_value) + @pyqtSlot("QVariant") def setGlobalVariant(self, container_node): self.blurSettings.emit() diff --git a/plugins/UM3NetworkPrinting/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/DiscoverUM3Action.py index 4b972e9040..76e8721fdd 100644 --- a/plugins/UM3NetworkPrinting/DiscoverUM3Action.py +++ b/plugins/UM3NetworkPrinting/DiscoverUM3Action.py @@ -104,8 +104,10 @@ class DiscoverUM3Action(MachineAction): if global_container_stack: meta_data = global_container_stack.getMetaData() if "connect_group_name" in meta_data: + previous_connect_group_name = meta_data["connect_group_name"] global_container_stack.setMetaDataEntry("connect_group_name", group_name) - # TODO Find all the places where there is the same group name and change it accordingly + # Find all the places where there is the same group name and change it accordingly + Application.getInstance().getMachineManager().replaceContainersMetadata(key = "connect_group_name", value = previous_connect_group_name, new_value = group_name) else: global_container_stack.addMetaDataEntry("connect_group_name", group_name) global_container_stack.addMetaDataEntry("hidden", False) @@ -121,12 +123,13 @@ class DiscoverUM3Action(MachineAction): if global_container_stack: meta_data = global_container_stack.getMetaData() if "um_network_key" in meta_data: + previous_network_key= meta_data["um_network_key"] global_container_stack.setMetaDataEntry("um_network_key", key) # Delete old authentication data. Logger.log("d", "Removing old authentication id %s for device %s", global_container_stack.getMetaDataEntry("network_authentication_id", None), key) global_container_stack.removeMetaDataEntry("network_authentication_id") global_container_stack.removeMetaDataEntry("network_authentication_key") - # TODO Find all the places where there is the same key and change it accordingly + Application.getInstance().getMachineManager().replaceContainersMetadata(key = "um_network_key", value = previous_network_key, new_value = key) else: global_container_stack.addMetaDataEntry("um_network_key", key) From fe2a08a46bc8817a5c967cd80f66f4e356e80423 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 9 Mar 2018 13:38:06 +0100 Subject: [PATCH 47/66] CURA-4870 Do not store buildplate information coming from connect if the printer don't have buildplate in its definition. --- plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py index 8eeb8d91e7..942bc82280 100644 --- a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py @@ -376,11 +376,14 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): # 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. self._printer_uuid_to_unique_name_mapping[data["uuid"]] = data["unique_name"] + machine_definition = ContainerRegistry.getInstance().findDefinitionContainers(name = data["machine_variant"])[0] printer.updateName(data["friendly_name"]) printer.updateKey(data["uuid"]) printer.updateType(data["machine_variant"]) - if "build_plate" in data: + + # Do not store the buildplate information that comes from connect if the current printer has not buildplate information + if "build_plate" in data and machine_definition.getMetaDataEntry("has_variant_buildplates", False): printer.updateBuildplate(data["build_plate"]["type"]) if not data["enabled"]: printer.updateState("disabled") From ae2a286e3f83f22e85f46a3abba64d1cfa6c6924 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 9 Mar 2018 14:07:29 +0100 Subject: [PATCH 48/66] Improved Icons & Styling --- resources/qml/MachineSelection.qml | 2 +- .../Menus/ConfigurationMenu/SyncButton.qml | 38 +++++++++---------- resources/qml/Menus/PrinterStatusIcon.qml | 4 +- resources/qml/Sidebar.qml | 2 +- .../themes/cura-light/icons/connected.svg | 14 +++++++ .../themes/cura-light/icons/disconnected.svg | 13 +++++++ resources/themes/cura-light/theme.json | 5 ++- 7 files changed, 53 insertions(+), 25 deletions(-) create mode 100644 resources/themes/cura-light/icons/connected.svg create mode 100644 resources/themes/cura-light/icons/disconnected.svg diff --git a/resources/qml/MachineSelection.qml b/resources/qml/MachineSelection.qml index cce2bbea7b..a48045fdbc 100644 --- a/resources/qml/MachineSelection.qml +++ b/resources/qml/MachineSelection.qml @@ -12,7 +12,7 @@ import "Menus" ToolButton { property var isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey ? true : false - property var printerStatus: Cura.MachineManager.printerOutputDevices.length != 0 ? "connected" : "unknown" + property var printerStatus: Cura.MachineManager.printerOutputDevices.length != 0 ? "connected" : "disconnected" text: Cura.MachineManager.activeMachineName tooltip: Cura.MachineManager.activeMachineName diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml index 4a92db6e6b..d22dcb1247 100644 --- a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml +++ b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml @@ -12,25 +12,22 @@ Button { id: base property var outputDevice: Cura.MachineManager.printerOutputDevices[0] - text: catalog.i18nc("@label:sync indicator", "No match") + property var matched: updateOnSync() + text: matched == true ? "Yes" : "No" width: parent.width height: parent.height - function updateOnSync() - { - if (outputDevice != undefined) - { - for (var index in outputDevice.uniqueConfigurations) - { + function updateOnSync() { + if (outputDevice != undefined) { + for (var index in outputDevice.uniqueConfigurations) { var configuration = outputDevice.uniqueConfigurations[index] - if (Cura.MachineManager.matchesConfiguration(configuration)) - { - base.text = catalog.i18nc("@label:sync indicator", "Matched") - return + if (Cura.MachineManager.matchesConfiguration(configuration)) { + base.matched = true; + return; } } } - base.text = catalog.i18nc("@label:sync indicator", "No match") + base.matched = false; } style: ButtonStyle @@ -67,18 +64,19 @@ Button color: UM.Theme.getColor("text_emphasis") source: UM.Theme.getIcon("arrow_bottom") } - Label - { + UM.RecolorImage { id: sidebarComboBoxLabel - color: UM.Theme.getColor("sidebar_header_text_active") - text: control.text - elide: Text.ElideRight anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.right: downArrow.left - anchors.rightMargin: control.rightMargin anchors.verticalCenter: parent.verticalCenter; - font: UM.Theme.getFont("medium") + + width: UM.Theme.getSize("printer_status_icon").width + height: UM.Theme.getSize("printer_status_icon").height + + color: control.matched ? UM.Theme.getColor("printer_config_matched") : UM.Theme.getColor("printer_config_mismatch") + source: control.matched ? UM.Theme.getIcon("tab_status_connected") : UM.Theme.getIcon("tab_status_unknown") + sourceSize.width: width + sourceSize.height: height } } label: Label {} diff --git a/resources/qml/Menus/PrinterStatusIcon.qml b/resources/qml/Menus/PrinterStatusIcon.qml index 23459386d9..c76ed8bdcb 100644 --- a/resources/qml/Menus/PrinterStatusIcon.qml +++ b/resources/qml/Menus/PrinterStatusIcon.qml @@ -7,7 +7,7 @@ import UM 1.2 as UM import Cura 1.0 as Cura Item { - property var status: "unknown" + property var status: "disconnected" width: childrenRect.width height: childrenRect.height UM.RecolorImage { @@ -17,7 +17,7 @@ Item { sourceSize.width: width sourceSize.height: width color: UM.Theme.getColor("tab_status_" + parent.status ) - source: UM.Theme.getIcon("tab_status_" + parent.status ) + source: UM.Theme.getIcon( parent.status ) } } diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index a93048cb26..d13de1f7e6 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -107,7 +107,7 @@ Rectangle ConfigurationSelection { id: configSelection visible: printerConnected && !sidebar.monitoringPrint && !sidebar.hideSettings - width: visible ? Math.round(base.width * 0.25) : 0 + width: visible ? Math.round(base.width * 0.15) : 0 height: UM.Theme.getSize("sidebar_header").height anchors.top: base.top anchors.right: parent.right diff --git a/resources/themes/cura-light/icons/connected.svg b/resources/themes/cura-light/icons/connected.svg new file mode 100644 index 0000000000..4f0f10bff4 --- /dev/null +++ b/resources/themes/cura-light/icons/connected.svg @@ -0,0 +1,14 @@ + + + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/icons/disconnected.svg b/resources/themes/cura-light/icons/disconnected.svg new file mode 100644 index 0000000000..2a045c5f1d --- /dev/null +++ b/resources/themes/cura-light/icons/disconnected.svg @@ -0,0 +1,13 @@ + + + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 4cdff3c296..ce6b406d3d 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -314,7 +314,10 @@ "tab_status_finished": [255, 255, 255, 255], "tab_status_paused": [255, 255, 255, 255], "tab_status_stopped": [255, 255, 255, 255], - "tab_status_unknown": [200, 200, 200, 255] + "tab_status_disconnected": [200, 200, 200, 255], + + "printer_config_matched": [12, 169, 227, 255], + "printer_config_mismatch": [255, 145, 62, 255] }, "sizes": { From 16a5b652f44469840408ea0655170b8d9306152b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 9 Mar 2018 15:08:51 +0100 Subject: [PATCH 49/66] CURA-4870 Make the machine selection toolbutton react to changes in the output devices --- resources/qml/MachineSelection.qml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/resources/qml/MachineSelection.qml b/resources/qml/MachineSelection.qml index cce2bbea7b..96b40f7191 100644 --- a/resources/qml/MachineSelection.qml +++ b/resources/qml/MachineSelection.qml @@ -11,9 +11,10 @@ import Cura 1.0 as Cura import "Menus" ToolButton { - property var isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey ? true : false + id: base + property var isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" property var printerStatus: Cura.MachineManager.printerOutputDevices.length != 0 ? "connected" : "unknown" - text: Cura.MachineManager.activeMachineName + text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName tooltip: Cura.MachineManager.activeMachineName @@ -73,4 +74,14 @@ ToolButton { } menu: PrinterMenu { } + + // Make the toolbutton react when the outputdevice changes + Connections + { + target: Cura.MachineManager + onOutputDevicesChanged: + { + base.isNetworkPrinter = Cura.MachineManager.activeMachineNetworkKey != "" + } + } } From 472ae8e044bb45a884cbfb3be027e55ae10a3211 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 9 Mar 2018 16:35:23 +0100 Subject: [PATCH 50/66] CURA-4870 Create a custom model for the machines in order to show the printers grouped by local or networked. --- cura/CuraApplication.py | 8 +- .../Machines/Models/MachineManagementModel.py | 90 +++++++++++++++++++ resources/qml/Preferences/MachinesPage.qml | 5 +- 3 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 cura/Machines/Models/MachineManagementModel.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 2ca321e4cc..965e3ed33d 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -59,18 +59,18 @@ from cura.Machines.Models.BuildPlateModel import BuildPlateModel from cura.Machines.Models.NozzleModel import NozzleModel from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfilesDropDownMenuModel from cura.Machines.Models.CustomQualityProfilesDropDownMenuModel import CustomQualityProfilesDropDownMenuModel - from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel - from cura.Machines.Models.MaterialManagementModel import MaterialManagementModel from cura.Machines.Models.GenericMaterialsModel import GenericMaterialsModel from cura.Machines.Models.BrandMaterialsModel import BrandMaterialsModel +from cura.Machines.Models.QualityManagementModel import QualityManagementModel +from cura.Machines.Models.QualitySettingsModel import QualitySettingsModel +from cura.Machines.Models.MachineManagementModel import MachineManagementModel from cura.Settings.SettingInheritanceManager import SettingInheritanceManager from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager from cura.Machines.VariantManager import VariantManager -from cura.Machines.Models.QualityManagementModel import QualityManagementModel from . import PlatformPhysics from . import BuildVolume @@ -87,7 +87,6 @@ from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.UserChangesModel import UserChangesModel from cura.Settings.ExtrudersModel import ExtrudersModel from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler -from cura.Machines.Models.QualitySettingsModel import QualitySettingsModel from cura.Settings.ContainerManager import ContainerManager from cura.ObjectsModel import ObjectsModel @@ -960,6 +959,7 @@ class CuraApplication(QtApplication): qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") qmlRegisterType(MaterialManagementModel, "Cura", 1, 0, "MaterialManagementModel") qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel") + qmlRegisterType(MachineManagementModel, "Cura", 1, 0, "MachineManagementModel") qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0, "QualityProfilesDropDownMenuModel", self.getQualityProfilesDropDownMenuModel) diff --git a/cura/Machines/Models/MachineManagementModel.py b/cura/Machines/Models/MachineManagementModel.py new file mode 100644 index 0000000000..0ca47f2ef3 --- /dev/null +++ b/cura/Machines/Models/MachineManagementModel.py @@ -0,0 +1,90 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from UM.Qt.ListModel import ListModel + +from PyQt5.QtCore import pyqtSlot, pyqtProperty, Qt, pyqtSignal + +from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.ContainerStack import ContainerStack + +from UM.i18n import i18nCatalog +catalog = i18nCatalog("cura") + +# +# This the QML model for the quality management page. +# +class MachineManagementModel(ListModel): + NameRole = Qt.UserRole + 1 + IdRole = Qt.UserRole + 2 + MetaDataRole = Qt.UserRole + 3 + GroupRole = Qt.UserRole + 4 + + def __init__(self, parent = None): + super().__init__(parent) + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.IdRole, "id") + self.addRoleName(self.MetaDataRole, "metadata") + self.addRoleName(self.GroupRole, "group") + self._local_container_stacks = [] + self._network_container_stacks = [] + + # Listen to changes + ContainerRegistry.getInstance().containerAdded.connect(self._onContainerChanged) + ContainerRegistry.getInstance().containerMetaDataChanged.connect(self._onContainerChanged) + ContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChanged) + self._filter_dict = {} + self._update() + + ## Handler for container added/removed events from registry + def _onContainerChanged(self, container): + # We only need to update when the added / removed container is a stack. + if isinstance(container, ContainerStack): + self._update() + + ## Handler for container name change events. + def _onContainerNameChanged(self): + self._update() + + ## Private convenience function to reset & repopulate the model. + def _update(self): + items = [] + # Remove all connections + for container in self._local_container_stacks: + container.nameChanged.disconnect(self._onContainerNameChanged) + for container in self._network_container_stacks: + container.nameChanged.disconnect(self._onContainerNameChanged) + + # Get first the network enabled printers + network_filter_printers = {"type": "machine", "um_network_key": "*", "hidden": "False"} + self._network_container_stacks = ContainerRegistry.getInstance().findContainerStacks(**network_filter_printers) + self._network_container_stacks.sort(key = lambda i: i.getMetaDataEntry("connect_group_name")) + + for container in self._network_container_stacks: + metadata = container.getMetaData().copy() + if container.getBottom(): + metadata["definition_name"] = container.getBottom().getName() + + container.nameChanged.connect(self._onContainerNameChanged) + items.append({"name": metadata["connect_group_name"], + "id": container.getId(), + "metadata": metadata, + "group": catalog.i18nc("@info:title", "Network enabled printers")}) + + # Get now the local printes + local_filter_printers = {"type": "machine", "um_network_key": None} + self._local_container_stacks = ContainerRegistry.getInstance().findContainerStacks(**local_filter_printers) + self._local_container_stacks.sort(key = lambda i: i.getName()) + + for container in self._local_container_stacks: + metadata = container.getMetaData().copy() + if container.getBottom(): + metadata["definition_name"] = container.getBottom().getName() + + container.nameChanged.connect(self._onContainerNameChanged) + items.append({"name": container.getName(), + "id": container.getId(), + "metadata": metadata, + "group": catalog.i18nc("@info:title", "Local printers")}) + + self.setItems(items) diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml index 62e5ef98b4..df9482b84d 100644 --- a/resources/qml/Preferences/MachinesPage.qml +++ b/resources/qml/Preferences/MachinesPage.qml @@ -14,10 +14,7 @@ UM.ManagementPage id: base; title: catalog.i18nc("@title:tab", "Printers"); - model: UM.ContainerStacksModel - { - filter: {"type": "machine"} - } + model: Cura.MachineManagementModel { } activeId: Cura.MachineManager.activeMachineId activeIndex: activeMachineIndex() From 87380e007c943f00ad3a15bf765aca978d4958d4 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 9 Mar 2018 16:44:46 +0100 Subject: [PATCH 51/66] CURA-4870 Switch the hidden metadata entry also when switching printes so the active printer is correctly shown in the machines page. --- cura/Settings/MachineManager.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 3bc2df0da1..1522e5f6c0 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1074,14 +1074,18 @@ class MachineManager(QObject): machine_definition_id = ContainerRegistry.getInstance().findDefinitionContainers(name = machine_name)[0].getId() # Try to find a machine with the same network key new_machine = self.getMachine(machine_definition_id, metadata_filter = {"um_network_key": self.activeMachineNetworkKey}) - # If there is no machine, then create a new one + # If there is no machine, then create a new one and set it to the non-hidden instance if not new_machine: new_machine = CuraStackBuilder.createMachine(machine_definition_id + "_sync", machine_definition_id) new_machine.addMetaDataEntry("um_network_key", self.activeMachineNetworkKey) new_machine.addMetaDataEntry("connect_group_name", self.activeMachineNetworkGroupName) - new_machine.addMetaDataEntry("hidden", True) + new_machine.addMetaDataEntry("hidden", False) else: Logger.log("i", "Found a %s with the key %s. Let's use it!", machine_name, self.activeMachineNetworkKey) + new_machine.setMetaDataEntry("hidden", False) + + # Set the current printer instance to hidden (the metadata entry must exist) + self._global_container_stack.setMetaDataEntry("hidden", True) self.setActiveMachine(new_machine.getId()) From 9613103591897cb436b140270136507650be8646 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 12 Mar 2018 10:45:49 +0100 Subject: [PATCH 52/66] CURA-4870 Remove Monitor stage status icons --- plugins/MonitorStage/MonitorStage.py | 63 ---------------------------- 1 file changed, 63 deletions(-) diff --git a/plugins/MonitorStage/MonitorStage.py b/plugins/MonitorStage/MonitorStage.py index 1a1d37cbdf..ed84a8d2ce 100644 --- a/plugins/MonitorStage/MonitorStage.py +++ b/plugins/MonitorStage/MonitorStage.py @@ -22,14 +22,7 @@ class MonitorStage(CuraStage): def _setActivePrintJob(self, print_job): if self._active_print_job != print_job: - if self._active_print_job: - self._active_print_job.stateChanged.disconnect(self._updateIconSource) self._active_print_job = print_job - if self._active_print_job: - self._active_print_job.stateChanged.connect(self._updateIconSource) - - # Ensure that the right icon source is returned. - self._updateIconSource() def _setActivePrinter(self, printer): if self._active_printer != printer: @@ -43,9 +36,6 @@ class MonitorStage(CuraStage): else: self._setActivePrintJob(None) - # Ensure that the right icon source is returned. - self._updateIconSource() - def _onActivePrintJobChanged(self): self._setActivePrintJob(self._active_printer.activePrintJob) @@ -58,22 +48,13 @@ class MonitorStage(CuraStage): new_output_device = Application.getInstance().getMachineManager().printerOutputDevices[0] if new_output_device != self._printer_output_device: if self._printer_output_device: - self._printer_output_device.acceptsCommandsChanged.disconnect(self._updateIconSource) - self._printer_output_device.connectionStateChanged.disconnect(self._updateIconSource) self._printer_output_device.printersChanged.disconnect(self._onActivePrinterChanged) self._printer_output_device = new_output_device - self._printer_output_device.acceptsCommandsChanged.connect(self._updateIconSource) self._printer_output_device.printersChanged.connect(self._onActivePrinterChanged) - self._printer_output_device.connectionStateChanged.connect(self._updateIconSource) self._setActivePrinter(self._printer_output_device.activePrinter) - - # Force an update of the icon source - self._updateIconSource() except IndexError: - #If index error occurs, then the icon on monitor button also should be updated - self._updateIconSource() pass def _onEngineCreated(self): @@ -82,7 +63,6 @@ class MonitorStage(CuraStage): self._onOutputDevicesChanged() self._updateMainOverlay() self._updateSidebar() - self._updateIconSource() def _updateMainOverlay(self): main_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("MonitorStage"), "MonitorMainView.qml") @@ -92,46 +72,3 @@ class MonitorStage(CuraStage): # TODO: currently the sidebar component for prepare and monitor stages is the same, this will change with the printer output device refactor! sidebar_component_path = os.path.join(Resources.getPath(Application.getInstance().ResourceTypes.QmlFiles), "Sidebar.qml") self.addDisplayComponent("sidebar", sidebar_component_path) - - def _updateIconSource(self): - if Application.getInstance().getTheme() is not None: - icon_name = self._getActiveOutputDeviceStatusIcon() - self.setIconSource(Application.getInstance().getTheme().getIcon(icon_name)) - - ## Find the correct status icon depending on the active output device state - def _getActiveOutputDeviceStatusIcon(self): - # We assume that you are monitoring the device with the highest priority. - try: - output_device = Application.getInstance().getMachineManager().printerOutputDevices[0] - except IndexError: - return "tab_status_unknown" - - if not output_device.acceptsCommands: - return "tab_status_unknown" - - if output_device.activePrinter is None: - return "tab_status_connected" - - # TODO: refactor to use enum instead of hardcoded strings? - if output_device.activePrinter.state == "maintenance": - return "tab_status_busy" - - if output_device.activePrinter.activePrintJob is None: - return "tab_status_connected" - - if output_device.activePrinter.activePrintJob.state in ["printing", "pre_print", "pausing", "resuming"]: - return "tab_status_busy" - - if output_device.activePrinter.activePrintJob.state == "wait_cleanup": - return "tab_status_finished" - - if output_device.activePrinter.activePrintJob.state in ["ready", ""]: - return "tab_status_connected" - - if output_device.activePrinter.activePrintJob.state == "paused": - return "tab_status_paused" - - if output_device.activePrinter.activePrintJob.state == "error": - return "tab_status_stopped" - - return "tab_status_unknown" From ec2201b57c6c0638382932a0af43af394bb4f2b6 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 12 Mar 2018 11:57:53 +0100 Subject: [PATCH 53/66] CURA-4870 Move the printer type and the buildplate selector to the top of the sidebar and set them separate from the extruder related selectors. --- resources/qml/SidebarHeader.qml | 198 ++++++++++++++++---------------- 1 file changed, 97 insertions(+), 101 deletions(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 8e12cd017b..2323202305 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -26,16 +26,111 @@ Column Item { + id: initialSeparator anchors { left: parent.left right: parent.right } - visible: extruderSelectionRow.visible + visible: printerTypeSelectionRow.visible || buildplateRow.visible || extruderSelectionRow.visible height: UM.Theme.getSize("default_lining").height width: height } + // Printer Type Row + Item + { + id: printerTypeSelectionRow + height: UM.Theme.getSize("sidebar_setup").height + visible: printerConnected && hasManyPrinterTypes && !sidebar.monitoringPrint && !sidebar.hideSettings + + anchors + { + left: parent.left + leftMargin: UM.Theme.getSize("sidebar_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("sidebar_margin").width + } + + Label + { + id: configurationLabel + text: catalog.i18nc("@label", "Printer type"); + width: Math.round(parent.width * 0.4 - UM.Theme.getSize("default_margin").width) + height: parent.height + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default"); + color: UM.Theme.getColor("text"); + } + + ToolButton + { + id: printerTypeSelection + text: Cura.MachineManager.activeMachineDefinitionName + tooltip: Cura.MachineManager.activeMachineDefinitionName + height: UM.Theme.getSize("setting_control").height + width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width + anchors.right: parent.right + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; + + menu: PrinterTypeMenu { } + } + } + + //Buildplate row + Item + { + id: buildplateRow + height: UM.Theme.getSize("sidebar_setup").height + visible: Cura.MachineManager.hasVariantBuildplates && !sidebar.monitoringPrint && !sidebar.hideSettings + + anchors + { + left: parent.left + leftMargin: UM.Theme.getSize("sidebar_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("sidebar_margin").width + } + + Label + { + id: bulidplateLabel + text: catalog.i18nc("@label", "Build plate"); + width: Math.floor(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) + height: parent.height + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default"); + color: UM.Theme.getColor("text"); + } + + ToolButton { + id: buildplateSelection + text: Cura.MachineManager.activeVariantBuildplateName + tooltip: Cura.MachineManager.activeVariantBuildplateName + visible: Cura.MachineManager.hasVariantBuildplates + + height: UM.Theme.getSize("setting_control").height + width: Math.floor(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width) + anchors.right: parent.right + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; + + menu: BuildplateMenu {} + + property var valueError: !Cura.MachineManager.variantBuildplateCompatible && !Cura.MachineManager.variantBuildplateUsable + property var valueWarning: Cura.MachineManager.variantBuildplateUsable + } + } + + Rectangle { + id: headerSeparator + width: parent.width + visible: printerTypeSelectionRow.visible || buildplateRow.visible + height: visible ? UM.Theme.getSize("sidebar_lining").height : 0 + color: UM.Theme.getColor("sidebar_lining") + } + // Extruder Row Item { @@ -223,48 +318,7 @@ Column id: variantRowSpacer height: Math.round(UM.Theme.getSize("sidebar_margin").height / 4) width: height - visible: !extruderSelectionRow.visible - } - - // Printer Type Row - Item - { - id: printerTypeSelectionRow - height: UM.Theme.getSize("sidebar_setup").height - visible: printerConnected && hasManyPrinterTypes && !sidebar.monitoringPrint && !sidebar.hideSettings - - anchors - { - left: parent.left - leftMargin: UM.Theme.getSize("sidebar_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("sidebar_margin").width - } - - Label - { - id: configurationLabel - text: catalog.i18nc("@label", "Printer type"); - width: Math.round(parent.width * 0.4 - UM.Theme.getSize("default_margin").width) - height: parent.height - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - } - - ToolButton - { - id: printerTypeSelection - text: Cura.MachineManager.activeMachineDefinitionName - tooltip: Cura.MachineManager.activeMachineDefinitionName - height: UM.Theme.getSize("setting_control").height - width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width - anchors.right: parent.right - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - - menu: PrinterTypeMenu { } - } + visible: !extruderSelectionRow.visible && !initialSeparator.visible } // Material Row @@ -371,64 +425,6 @@ Column } } - //Buildplate row separator - Rectangle { - id: separator - - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width - anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width - anchors.horizontalCenter: parent.horizontalCenter - visible: buildplateRow.visible - width: parent.width - UM.Theme.getSize("sidebar_margin").width * 2 - height: visible ? Math.floor(UM.Theme.getSize("sidebar_lining_thin").height / 2) : 0 - color: UM.Theme.getColor("sidebar_lining_thin") - } - - //Buildplate row - Item - { - id: buildplateRow - height: UM.Theme.getSize("sidebar_setup").height - visible: Cura.MachineManager.hasVariantBuildplates && !sidebar.monitoringPrint && !sidebar.hideSettings - - anchors - { - left: parent.left - leftMargin: UM.Theme.getSize("sidebar_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("sidebar_margin").width - } - - Label - { - id: bulidplateLabel - text: catalog.i18nc("@label", "Build plate"); - width: Math.floor(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) - height: parent.height - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - } - - ToolButton { - id: buildplateSelection - text: Cura.MachineManager.activeVariantBuildplateName - tooltip: Cura.MachineManager.activeVariantBuildplateName - visible: Cura.MachineManager.hasVariantBuildplates - - height: UM.Theme.getSize("setting_control").height - width: Math.floor(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width) - anchors.right: parent.right - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - - menu: BuildplateMenu {} - - property var valueError: !Cura.MachineManager.variantBuildplateCompatible && !Cura.MachineManager.variantBuildplateUsable - property var valueWarning: Cura.MachineManager.variantBuildplateUsable - } - } - // Material info row Item { From cc009a94eef9b2cd3970423ba5435d45cc59c8e7 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 12 Mar 2018 14:19:06 +0100 Subject: [PATCH 54/66] CURA-4870 Remove "check compatibility" message. Move the buildplate information to the bottom, below the extruders. --- resources/qml/SidebarHeader.qml | 136 +++++++++----------------------- 1 file changed, 39 insertions(+), 97 deletions(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 2323202305..c93dd3a89b 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -78,55 +78,10 @@ Column } } - //Buildplate row - Item - { - id: buildplateRow - height: UM.Theme.getSize("sidebar_setup").height - visible: Cura.MachineManager.hasVariantBuildplates && !sidebar.monitoringPrint && !sidebar.hideSettings - - anchors - { - left: parent.left - leftMargin: UM.Theme.getSize("sidebar_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("sidebar_margin").width - } - - Label - { - id: bulidplateLabel - text: catalog.i18nc("@label", "Build plate"); - width: Math.floor(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) - height: parent.height - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - } - - ToolButton { - id: buildplateSelection - text: Cura.MachineManager.activeVariantBuildplateName - tooltip: Cura.MachineManager.activeVariantBuildplateName - visible: Cura.MachineManager.hasVariantBuildplates - - height: UM.Theme.getSize("setting_control").height - width: Math.floor(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width) - anchors.right: parent.right - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - - menu: BuildplateMenu {} - - property var valueError: !Cura.MachineManager.variantBuildplateCompatible && !Cura.MachineManager.variantBuildplateUsable - property var valueWarning: Cura.MachineManager.variantBuildplateUsable - } - } - Rectangle { id: headerSeparator width: parent.width - visible: printerTypeSelectionRow.visible || buildplateRow.visible + visible: printerTypeSelectionRow.visible height: visible ? UM.Theme.getSize("sidebar_lining").height : 0 color: UM.Theme.getColor("sidebar_lining") } @@ -425,12 +380,22 @@ Column } } - // Material info row + Rectangle { + id: buildplateSeparator + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width + visible: buildplateRow.visible + height: visible ? UM.Theme.getSize("sidebar_lining_thin").height : 0 + color: UM.Theme.getColor("sidebar_lining") + } + + //Buildplate row Item { - id: materialInfoRow - height: Math.round(UM.Theme.getSize("sidebar_setup").height / 2) - visible: (Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials) && !sidebar.monitoringPrint && !sidebar.hideSettings + id: buildplateRow + height: UM.Theme.getSize("sidebar_setup").height + visible: Cura.MachineManager.hasVariantBuildplates && !sidebar.monitoringPrint && !sidebar.hideSettings anchors { @@ -440,56 +405,33 @@ Column rightMargin: UM.Theme.getSize("sidebar_margin").width } - Item { - height: UM.Theme.getSize("sidebar_setup").height + Label + { + id: bulidplateLabel + text: catalog.i18nc("@label", "Build plate"); + width: Math.floor(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) + height: parent.height + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default"); + color: UM.Theme.getColor("text"); + } + + ToolButton { + id: buildplateSelection + text: Cura.MachineManager.activeVariantBuildplateName + tooltip: Cura.MachineManager.activeVariantBuildplateName + visible: Cura.MachineManager.hasVariantBuildplates + + height: UM.Theme.getSize("setting_control").height + width: Math.floor(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width) anchors.right: parent.right - width: Math.round(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width) + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; - UM.RecolorImage { - id: warningImage - anchors.right: materialInfoLabel.left - anchors.rightMargin: UM.Theme.getSize("default_margin").width - anchors.verticalCenter: parent.Bottom - source: UM.Theme.getIcon("warning") - width: UM.Theme.getSize("section_icon").width - height: UM.Theme.getSize("section_icon").height - color: UM.Theme.getColor("material_compatibility_warning") - visible: !Cura.MachineManager.isCurrentSetupSupported - } + menu: BuildplateMenu {} - Label { - id: materialInfoLabel - wrapMode: Text.WordWrap - text: "" + catalog.i18nc("@label", "Check compatibility") + "" - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - linkColor: UM.Theme.getColor("text_link") - verticalAlignment: Text.AlignTop - anchors.top: parent.top - anchors.right: parent.right - anchors.bottom: parent.bottom - - MouseArea { - anchors.fill: parent - hoverEnabled: true - onClicked: { - // open the material URL with web browser - var version = UM.Application.version; - var machineName = Cura.MachineManager.activeMachine.definition.id; - var url = "https://ultimaker.com/materialcompatibility/" + version + "/" + machineName + "?utm_source=cura&utm_medium=software&utm_campaign=resources"; - Qt.openUrlExternally(url); - } - onEntered: { - var content = catalog.i18nc("@tooltip", "Click to check the material compatibility on Ultimaker.com."); - base.showTooltip( - materialInfoRow, - Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), - catalog.i18nc("@tooltip", content) - ); - } - onExited: base.hideTooltip(); - } - } + property var valueError: !Cura.MachineManager.variantBuildplateCompatible && !Cura.MachineManager.variantBuildplateUsable + property var valueWarning: Cura.MachineManager.variantBuildplateUsable } } From a5ba4799f0ce613b92414db66b278036d4e88ffc Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 12 Mar 2018 14:48:39 +0100 Subject: [PATCH 55/66] CURA-4870 Final icon changes from Luke --- .../qml/Menus/ConfigurationMenu/SyncButton.qml | 6 +++--- resources/qml/Menus/PrinterStatusIcon.qml | 4 ++-- resources/themes/cura-light/icons/connected.svg | 15 +++------------ .../themes/cura-light/icons/disconnected.svg | 15 ++++----------- resources/themes/cura-light/theme.json | 9 +++------ 5 files changed, 15 insertions(+), 34 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml index d22dcb1247..3748fd0cb4 100644 --- a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml +++ b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml @@ -70,11 +70,11 @@ Button anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter; - width: UM.Theme.getSize("printer_status_icon").width - height: UM.Theme.getSize("printer_status_icon").height + width: UM.Theme.getSize("printer_sync_icon").width + height: UM.Theme.getSize("printer_sync_icon").height color: control.matched ? UM.Theme.getColor("printer_config_matched") : UM.Theme.getColor("printer_config_mismatch") - source: control.matched ? UM.Theme.getIcon("tab_status_connected") : UM.Theme.getIcon("tab_status_unknown") + source: UM.Theme.getIcon("tab_status_connected") sourceSize.width: width sourceSize.height: height } diff --git a/resources/qml/Menus/PrinterStatusIcon.qml b/resources/qml/Menus/PrinterStatusIcon.qml index c76ed8bdcb..f66834d0c0 100644 --- a/resources/qml/Menus/PrinterStatusIcon.qml +++ b/resources/qml/Menus/PrinterStatusIcon.qml @@ -16,8 +16,8 @@ Item { height: UM.Theme.getSize("printer_status_icon").height sourceSize.width: width sourceSize.height: width - color: UM.Theme.getColor("tab_status_" + parent.status ) - source: UM.Theme.getIcon( parent.status ) + color: UM.Theme.getColor("tab_status_" + parent.status) + source: UM.Theme.getIcon(parent.status) } } diff --git a/resources/themes/cura-light/icons/connected.svg b/resources/themes/cura-light/icons/connected.svg index 4f0f10bff4..18423bb6c4 100644 --- a/resources/themes/cura-light/icons/connected.svg +++ b/resources/themes/cura-light/icons/connected.svg @@ -1,14 +1,5 @@ - - Created with Sketch. - - - - - - - - - - + + + \ No newline at end of file diff --git a/resources/themes/cura-light/icons/disconnected.svg b/resources/themes/cura-light/icons/disconnected.svg index 2a045c5f1d..019dff117e 100644 --- a/resources/themes/cura-light/icons/disconnected.svg +++ b/resources/themes/cura-light/icons/disconnected.svg @@ -1,13 +1,6 @@ - - Created with Sketch. - - - - - - - - - + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index ce6b406d3d..c0b71ac618 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -309,15 +309,11 @@ "configuration_item_border_active": [12, 169, 227, 32], "configuration_item_border_hover": [12, 169, 227, 255], - "tab_status_busy": [255, 255, 255, 255], "tab_status_connected": [12, 169, 227, 255], - "tab_status_finished": [255, 255, 255, 255], - "tab_status_paused": [255, 255, 255, 255], - "tab_status_stopped": [255, 255, 255, 255], "tab_status_disconnected": [200, 200, 200, 255], "printer_config_matched": [12, 169, 227, 255], - "printer_config_mismatch": [255, 145, 62, 255] + "printer_config_mismatch": [127, 127, 127, 255] }, "sizes": { @@ -370,7 +366,8 @@ "small_button": [2, 2], "small_button_icon": [1.5, 1.5], - "printer_status_icon": [1.2, 1.2], + "printer_status_icon": [1.8, 1.8], + "printer_sync_icon": [1.2, 1.2], "topbar_logo_right_margin": [3, 0], "topbar_button": [8, 4], From da54c93fda6a9c795020607d69718e292524cfb6 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 12 Mar 2018 15:12:27 +0100 Subject: [PATCH 56/66] CURA-4870 Remove commented code --- cura/Settings/MachineManager.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index ba93810b7c..7753dfced1 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -201,9 +201,6 @@ class MachineManager(QObject): @pyqtSlot(QObject, result = bool) def matchesConfiguration(self, configuration: ConfigurationModel) -> bool: - # print(configuration) - # print(self._current_printer_configuration) - # print("%%%%%%%%", configuration == self._current_printer_configuration) return self._current_printer_configuration == configuration @pyqtProperty("QVariantList", notify = outputDevicesChanged) From 39a7f5a53d55ba356efb3ebbb1ec170378a93060 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 12 Mar 2018 16:37:35 +0100 Subject: [PATCH 57/66] CURA-4870 Update the configuration also when the type or the buildplate changed signal is emitted. --- cura/PrinterOutput/PrinterOutputModel.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py index 8d674c1c5f..3453eca608 100644 --- a/cura/PrinterOutput/PrinterOutputModel.py +++ b/cura/PrinterOutput/PrinterOutputModel.py @@ -46,6 +46,8 @@ class PrinterOutputModel(QObject): # Update the printer configuration every time any of the extruders changes its configuration for extruder in self._extruders: extruder.extruderConfigurationChanged.connect(self._updatePrinterConfiguration) + self.typeChanged.connect(self._updatePrinterConfiguration) + self.buildplateChanged.connect(self._updatePrinterConfiguration) self._camera = None From 54882402adcf00a7cd6a844173d34ef975f9656b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 13 Mar 2018 09:41:26 +0100 Subject: [PATCH 58/66] CURA-4870 Change the name of the signal to be more related with the context. --- cura/PrinterOutput/PrinterOutputModel.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py index 3453eca608..04f2c1eb62 100644 --- a/cura/PrinterOutput/PrinterOutputModel.py +++ b/cura/PrinterOutput/PrinterOutputModel.py @@ -22,7 +22,7 @@ class PrinterOutputModel(QObject): nameChanged = pyqtSignal() headPositionChanged = pyqtSignal() keyChanged = pyqtSignal() - typeChanged = pyqtSignal() + printerTypeChanged = pyqtSignal() buildplateChanged = pyqtSignal() cameraChanged = pyqtSignal() configurationChanged = pyqtSignal() @@ -41,12 +41,12 @@ class PrinterOutputModel(QObject): self._firmware_version = firmware_version self._printer_state = "unknown" self._is_preheating = False - self._type = "" + self._printer_type = "" self._buildplate_name = None # Update the printer configuration every time any of the extruders changes its configuration for extruder in self._extruders: extruder.extruderConfigurationChanged.connect(self._updatePrinterConfiguration) - self.typeChanged.connect(self._updatePrinterConfiguration) + self.printerTypeChanged.connect(self._updatePrinterConfiguration) self.buildplateChanged.connect(self._updatePrinterConfiguration) self._camera = None @@ -73,14 +73,14 @@ class PrinterOutputModel(QObject): def camera(self): return self._camera - @pyqtProperty(str, notify = typeChanged) + @pyqtProperty(str, notify = printerTypeChanged) def type(self): - return self._type + return self._printer_type - def updateType(self, type): - if self._type != type: - self._type = type - self.typeChanged.emit() + def updateType(self, printer_type): + if self._printer_type != printer_type: + self._printer_type = printer_type + self.printerTypeChanged.emit() @pyqtProperty(str, notify = buildplateChanged) def buildplate(self): @@ -263,7 +263,7 @@ class PrinterOutputModel(QObject): return self._printer_configuration def _updatePrinterConfiguration(self): - self._printer_configuration.printerType = self._type + self._printer_configuration.printerType = self._printer_type self._printer_configuration.extruderConfigurations = [extruder.extruderConfiguration for extruder in self._extruders] self._printer_configuration.buildplateConfiguration = self._buildplate_name self.configurationChanged.emit() From b3f9679a5fddd94bc6ca1e3ddccc221ad911f2a4 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 13 Mar 2018 09:43:44 +0100 Subject: [PATCH 59/66] CURA-4870 Style the __str__ function --- cura/PrinterOutput/ConfigurationModel.py | 17 +++++++++++------ cura/PrinterOutput/ExtruderOutputModel.py | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/ConfigurationModel.py index 30c95f2765..23ed687fb8 100644 --- a/cura/PrinterOutput/ConfigurationModel.py +++ b/cura/PrinterOutput/ConfigurationModel.py @@ -41,18 +41,22 @@ class ConfigurationModel(QObject): return self._buildplate_configuration def __str__(self): - info = "Printer type: " + self._printer_type + "\n" - info += "Extruders: [\n" + message_chunks = [] + message_chunks.append("Printer type: " + self._printer_type) + message_chunks.append("Extruders: [") for configuration in self._extruder_configurations: - info += " " + str(configuration) + "\n" - info += "]" + message_chunks.append(" " + str(configuration)) + message_chunks.append("]") if self._buildplate_configuration is not None: - info += "\nBuildplate: " + self._buildplate_configuration - return info + message_chunks.append("Buildplate: " + self._buildplate_configuration) + + return "\n".join(message_chunks) def __eq__(self, other): return hash(self) == hash(other) + ## The hash function is used to compare and create unique sets. The configuration is unique if the configuration + # of the extruders is unique (the order of the extruders matters), and the type and buildplate is the same. def __hash__(self): extruder_hash = hash(0) first_extruder = None @@ -60,6 +64,7 @@ class ConfigurationModel(QObject): extruder_hash ^= hash(configuration) if configuration.position == 0: first_extruder = configuration + # To ensure the correct order of the extruders, we add an "and" operation using the first extruder hash value if first_extruder: extruder_hash &= hash(first_extruder) diff --git a/cura/PrinterOutput/ExtruderOutputModel.py b/cura/PrinterOutput/ExtruderOutputModel.py index a639d428f9..df47bca71a 100644 --- a/cura/PrinterOutput/ExtruderOutputModel.py +++ b/cura/PrinterOutput/ExtruderOutputModel.py @@ -62,7 +62,7 @@ class ExtruderOutputModel(QObject): def targetHotendTemperature(self) -> float: return self._target_hotend_temperature - @pyqtProperty(float, notify=hotendTemperatureChanged) + @pyqtProperty(float, notify = hotendTemperatureChanged) def hotendTemperature(self) -> float: return self._hotend_temperature From fa2b5f141c9c87cc533e7cf3f355450c470a832a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 13 Mar 2018 10:35:48 +0100 Subject: [PATCH 60/66] CURA-4870 Remove dinamic connections to the signals in the machine model. The model is still updated when the container changed. --- cura/Machines/Models/MachineManagementModel.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/cura/Machines/Models/MachineManagementModel.py b/cura/Machines/Models/MachineManagementModel.py index 0ca47f2ef3..481a692675 100644 --- a/cura/Machines/Models/MachineManagementModel.py +++ b/cura/Machines/Models/MachineManagementModel.py @@ -42,18 +42,9 @@ class MachineManagementModel(ListModel): if isinstance(container, ContainerStack): self._update() - ## Handler for container name change events. - def _onContainerNameChanged(self): - self._update() - ## Private convenience function to reset & repopulate the model. def _update(self): items = [] - # Remove all connections - for container in self._local_container_stacks: - container.nameChanged.disconnect(self._onContainerNameChanged) - for container in self._network_container_stacks: - container.nameChanged.disconnect(self._onContainerNameChanged) # Get first the network enabled printers network_filter_printers = {"type": "machine", "um_network_key": "*", "hidden": "False"} @@ -65,7 +56,6 @@ class MachineManagementModel(ListModel): if container.getBottom(): metadata["definition_name"] = container.getBottom().getName() - container.nameChanged.connect(self._onContainerNameChanged) items.append({"name": metadata["connect_group_name"], "id": container.getId(), "metadata": metadata, @@ -81,7 +71,6 @@ class MachineManagementModel(ListModel): if container.getBottom(): metadata["definition_name"] = container.getBottom().getName() - container.nameChanged.connect(self._onContainerNameChanged) items.append({"name": container.getName(), "id": container.getId(), "metadata": metadata, From d807ce57a51a010565bc42c3174da3fc6832d3ba Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 13 Mar 2018 10:49:29 +0100 Subject: [PATCH 61/66] CURA-4870 Disable rename button in MachinesPage when the selected item is a network printer since the name is the name of the host printer (or group) --- resources/qml/Preferences/MachinesPage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml index df9482b84d..665586d29f 100644 --- a/resources/qml/Preferences/MachinesPage.qml +++ b/resources/qml/Preferences/MachinesPage.qml @@ -54,7 +54,7 @@ UM.ManagementPage { text: catalog.i18nc("@action:button", "Rename"); iconName: "edit-rename"; - enabled: base.currentItem != null + enabled: base.currentItem != null && base.currentItem.metadata.connect_group_name == null onClicked: renameDialog.open(); } ] From dfb903fb8113b2694085d95f80d3982ab4707a16 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 13 Mar 2018 13:14:29 +0100 Subject: [PATCH 62/66] CURA-4870 Wait until the configuration has all the mandatory data before add it to the list of unique configurations. Remove some connections to signals and reuse already defined listeners. --- cura/PrinterOutput/ConfigurationModel.py | 10 ++++++++++ .../ExtruderConfigurationModel.py | 7 ++++++- cura/PrinterOutput/ExtruderOutputModel.py | 18 ++++++++---------- cura/PrinterOutput/PrinterOutputModel.py | 18 ++++++++++-------- cura/PrinterOutputDevice.py | 2 +- .../ClusterUM3OutputDevice.py | 2 +- 6 files changed, 36 insertions(+), 21 deletions(-) diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/ConfigurationModel.py index 23ed687fb8..c03d968b9e 100644 --- a/cura/PrinterOutput/ConfigurationModel.py +++ b/cura/PrinterOutput/ConfigurationModel.py @@ -40,6 +40,16 @@ class ConfigurationModel(QObject): def buildplateConfiguration(self): return self._buildplate_configuration + ## This method is intended to indicate whether the configuration is valid or not. + # The method checks if the mandatory fields are or not set + def isValid(self): + if not self._extruder_configurations: + return False + for configuration in self._extruder_configurations: + if configuration is None: + return False + return self._printer_type is not None + def __str__(self): message_chunks = [] message_chunks.append("Printer type: " + self._printer_type) diff --git a/cura/PrinterOutput/ExtruderConfigurationModel.py b/cura/PrinterOutput/ExtruderConfigurationModel.py index 34eddb3038..e49ffe13d7 100644 --- a/cura/PrinterOutput/ExtruderConfigurationModel.py +++ b/cura/PrinterOutput/ExtruderConfigurationModel.py @@ -35,8 +35,13 @@ class ExtruderConfigurationModel(QObject): def hotendID(self): return self._hotend_id + ## This method is intended to indicate whether the configuration is valid or not. + # The method checks if the mandatory fields are or not set + def isValid(self): + return self._material is not None and self._hotend_id is not None and self.material.guid is not None + def __str__(self): - if self._material is None or self._hotend_id is None or self.material.type is None: + if not self.isValid(): return "No information" return "Position: " + str(self._position) + " - Material: " + self._material.type + " - HotendID: " + self._hotend_id diff --git a/cura/PrinterOutput/ExtruderOutputModel.py b/cura/PrinterOutput/ExtruderOutputModel.py index df47bca71a..e4c7f1608e 100644 --- a/cura/PrinterOutput/ExtruderOutputModel.py +++ b/cura/PrinterOutput/ExtruderOutputModel.py @@ -28,9 +28,7 @@ class ExtruderOutputModel(QObject): self._hotend_id = "" self._active_material = None # type: Optional[MaterialOutputModel] self._extruder_configuration = ExtruderConfigurationModel() - # Update the configuration every time the hotend or the active material change - self.hotendIDChanged.connect(self._updateExtruderConfiguration) - self.activeMaterialChanged.connect(self._updateExtruderConfiguration) + self._extruder_configuration.position = self._position @pyqtProperty(QObject, notify = activeMaterialChanged) def activeMaterial(self) -> "MaterialOutputModel": @@ -39,7 +37,9 @@ class ExtruderOutputModel(QObject): def updateActiveMaterial(self, material: Optional["MaterialOutputModel"]): if self._active_material != material: self._active_material = material + self._extruder_configuration.material = self._active_material self.activeMaterialChanged.emit() + self.extruderConfigurationChanged.emit() ## Update the hotend temperature. This only changes it locally. def updateHotendTemperature(self, temperature: float): @@ -73,14 +73,12 @@ class ExtruderOutputModel(QObject): def updateHotendID(self, id: str): if self._hotend_id != id: self._hotend_id = id + self._extruder_configuration.hotendID = self._hotend_id self.hotendIDChanged.emit() + self.extruderConfigurationChanged.emit() @pyqtProperty(QObject, notify = extruderConfigurationChanged) def extruderConfiguration(self): - return self._extruder_configuration - - def _updateExtruderConfiguration(self): - self._extruder_configuration.position = self._position - self._extruder_configuration.material = self._active_material - self._extruder_configuration.hotendID = self._hotend_id - self.extruderConfigurationChanged.emit() + if self._extruder_configuration.isValid(): + return self._extruder_configuration + return None diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py index 04f2c1eb62..712f9b5b1e 100644 --- a/cura/PrinterOutput/PrinterOutputModel.py +++ b/cura/PrinterOutput/PrinterOutputModel.py @@ -45,9 +45,7 @@ class PrinterOutputModel(QObject): self._buildplate_name = None # Update the printer configuration every time any of the extruders changes its configuration for extruder in self._extruders: - extruder.extruderConfigurationChanged.connect(self._updatePrinterConfiguration) - self.printerTypeChanged.connect(self._updatePrinterConfiguration) - self.buildplateChanged.connect(self._updatePrinterConfiguration) + extruder.extruderConfigurationChanged.connect(self._updateExtruderConfiguration) self._camera = None @@ -80,16 +78,20 @@ class PrinterOutputModel(QObject): def updateType(self, printer_type): if self._printer_type != printer_type: self._printer_type = printer_type + self._printer_configuration.printerType = self._printer_type self.printerTypeChanged.emit() + self.configurationChanged.emit() @pyqtProperty(str, notify = buildplateChanged) def buildplate(self): return self._buildplate_name - def updateBuildplate(self, buildplate_name): + def updateBuildplateName(self, buildplate_name): if self._buildplate_name != buildplate_name: self._buildplate_name = buildplate_name + self._printer_configuration.buildplateConfiguration = self._buildplate_name self.buildplateChanged.emit() + self.configurationChanged.emit() @pyqtProperty(str, notify=keyChanged) def key(self): @@ -260,10 +262,10 @@ class PrinterOutputModel(QObject): # Returns the configuration (material, variant and buildplate) of the current printer @pyqtProperty(QObject, notify = configurationChanged) def printerConfiguration(self): - return self._printer_configuration + if self._printer_configuration.isValid(): + return self._printer_configuration + return None - def _updatePrinterConfiguration(self): - self._printer_configuration.printerType = self._printer_type + def _updateExtruderConfiguration(self): self._printer_configuration.extruderConfigurations = [extruder.extruderConfiguration for extruder in self._extruders] - self._printer_configuration.buildplateConfiguration = self._buildplate_name self.configurationChanged.emit() diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 453cb4d78a..4d6ddb8dfa 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -187,7 +187,7 @@ class PrinterOutputDevice(QObject, OutputDevice): return self._unique_configurations def _updateUniqueConfigurations(self): - self._unique_configurations = list(set([printer.printerConfiguration for printer in self._printers])) + self._unique_configurations = list(set([printer.printerConfiguration for printer in self._printers if printer.printerConfiguration is not None])) self._unique_configurations.sort(key = lambda k: k.printerType) self.uniqueConfigurationsChanged.emit() diff --git a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py index 942bc82280..77b64ee080 100644 --- a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py @@ -384,7 +384,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): # Do not store the buildplate information that comes from connect if the current printer has not buildplate information if "build_plate" in data and machine_definition.getMetaDataEntry("has_variant_buildplates", False): - printer.updateBuildplate(data["build_plate"]["type"]) + printer.updateBuildplateName(data["build_plate"]["type"]) if not data["enabled"]: printer.updateState("disabled") else: From 9196802e8353a832f35a7a2fbc19c30f9deda449 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 13 Mar 2018 13:40:31 +0100 Subject: [PATCH 63/66] CURA-4870 Clean the error messages from qml by not rendering components if there is no outputDevice defined. --- .../qml/Menus/ConfigurationMenu/ConfigurationListView.qml | 4 ++-- .../qml/Menus/ConfigurationMenu/ConfigurationSelection.qml | 5 ++++- resources/qml/Menus/ConfigurationMenu/SyncButton.qml | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 1bb81656a3..4a2d4cd062 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -11,7 +11,7 @@ import Cura 1.0 as Cura Column { id: base - property var outputDevice: Cura.MachineManager.printerOutputDevices[0] + property var outputDevice: null property var computedHeight: container.height + configurationListHeading.height + 3 * padding height: childrenRect.height + 2 * padding padding: UM.Theme.getSize("default_margin").width @@ -78,7 +78,7 @@ Column onUniqueConfigurationsChanged: { // FIXME For now the model should be removed and then created again, otherwise changes in the printer don't automatically update the UI - configurationList.model = null + configurationList.model = [] configurationList.model = outputDevice.uniqueConfigurations } } diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml index 3b053afb15..eb0d5f5cff 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml @@ -11,11 +11,13 @@ import Cura 1.0 as Cura Item { id: configurationSelector + property var connectedDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null property var panelWidth: control.width property var panelVisible: false SyncButton { onClicked: configurationSelector.state == "open" ? configurationSelector.state = "closed" : configurationSelector.state = "open" + outputDevice: connectedDevice } Popup { @@ -24,11 +26,12 @@ Item y: configurationSelector.height - UM.Theme.getSize("default_lining").height x: configurationSelector.width - width width: panelWidth - visible: panelVisible + visible: panelVisible && connectedDevice != null padding: UM.Theme.getSize("default_lining").width contentItem: ConfigurationListView { id: configList width: panelWidth - 2 * popup.padding + outputDevice: connectedDevice } background: Rectangle { color: UM.Theme.getColor("setting_control") diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml index 3748fd0cb4..a2d1d53b78 100644 --- a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml +++ b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml @@ -11,7 +11,7 @@ import Cura 1.0 as Cura Button { id: base - property var outputDevice: Cura.MachineManager.printerOutputDevices[0] + property var outputDevice: null property var matched: updateOnSync() text: matched == true ? "Yes" : "No" width: parent.width From 180139090a085be88ce4aa2e8b5ff2712589917f Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 13 Mar 2018 15:54:00 +0100 Subject: [PATCH 64/66] CURA-4870 Reuse the filter in findContainerStacks to find specific printers. Allow to show configurations with empty material or variant. --- cura/PrinterOutput/ExtruderConfigurationModel.py | 13 +++++++++---- cura/Settings/MachineManager.py | 13 ++----------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/cura/PrinterOutput/ExtruderConfigurationModel.py b/cura/PrinterOutput/ExtruderConfigurationModel.py index e49ffe13d7..bc7f1a7c07 100644 --- a/cura/PrinterOutput/ExtruderConfigurationModel.py +++ b/cura/PrinterOutput/ExtruderConfigurationModel.py @@ -37,13 +37,18 @@ class ExtruderConfigurationModel(QObject): ## This method is intended to indicate whether the configuration is valid or not. # The method checks if the mandatory fields are or not set + # At this moment is always valid since we allow to have empty material and variants. def isValid(self): - return self._material is not None and self._hotend_id is not None and self.material.guid is not None + return True def __str__(self): - if not self.isValid(): - return "No information" - return "Position: " + str(self._position) + " - Material: " + self._material.type + " - HotendID: " + self._hotend_id + 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("-") + message_chunks.append("HotendID: " + self.hotendID if self.hotendID else "empty") + return " ".join(message_chunks) def __eq__(self, other): return hash(self) == hash(other) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index e8ee0b6657..cc7852ede4 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -361,19 +361,10 @@ class MachineManager(QObject): # \param metadata_filter \type{dict} list of metadata keys and values used for filtering @staticmethod def getMachine(definition_id: str, metadata_filter: Dict[str, str] = None) -> Optional["GlobalStack"]: - machines = ContainerRegistry.getInstance().findContainerStacks(type = "machine") + machines = ContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter) for machine in machines: if machine.definition.getId() == definition_id: - if metadata_filter: - pass_all_filters = True - for key in metadata_filter: - if machine.getMetaDataEntry(key) != metadata_filter[key]: - pass_all_filters = False - break - if pass_all_filters: - return machine - else: - return machine + return machine return None @pyqtSlot(str, str) From 855df814d83b368907e7c537bbdd18b161f6ffb5 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 13 Mar 2018 16:11:51 +0100 Subject: [PATCH 65/66] CURA-4870 Fix some style with brackets in QML --- resources/qml/Menus/PrinterStatusIcon.qml | 6 ++++-- resources/qml/Menus/PrinterTypeMenu.qml | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/resources/qml/Menus/PrinterStatusIcon.qml b/resources/qml/Menus/PrinterStatusIcon.qml index f66834d0c0..6ff6b07af8 100644 --- a/resources/qml/Menus/PrinterStatusIcon.qml +++ b/resources/qml/Menus/PrinterStatusIcon.qml @@ -6,11 +6,13 @@ import QtQuick 2.2 import UM 1.2 as UM import Cura 1.0 as Cura -Item { +Item +{ property var status: "disconnected" width: childrenRect.width height: childrenRect.height - UM.RecolorImage { + UM.RecolorImage + { id: statusIcon width: UM.Theme.getSize("printer_status_icon").width height: UM.Theme.getSize("printer_status_icon").height diff --git a/resources/qml/Menus/PrinterTypeMenu.qml b/resources/qml/Menus/PrinterTypeMenu.qml index 0cb98bc1aa..28bdca54d9 100644 --- a/resources/qml/Menus/PrinterTypeMenu.qml +++ b/resources/qml/Menus/PrinterTypeMenu.qml @@ -18,7 +18,8 @@ Menu id: printerTypeInstantiator model: outputDevice != null ? outputDevice.connectedPrintersTypeCount : [] - MenuItem { + MenuItem + { text: modelData.machine_type checkable: true checked: Cura.MachineManager.activeMachineDefinitionName == modelData.machine_type From 5adb769cf8ebc828bb017c55acfe60b7a9e20b7c Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 13 Mar 2018 16:48:17 +0100 Subject: [PATCH 66/66] Fix value function for extruders_enabled_count CIRA-5056 --- resources/definitions/fdmprinter.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 6d4688bb52..8567dab08b 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -215,7 +215,7 @@ { "label": "Number of Extruders that are enabled", "description": "Number of extruder trains that are enabled; automatically set in software", - "default_value": "machine_extruder_count", + "value": "machine_extruder_count", "minimum_value": "1", "maximum_value": "16", "type": "int",