Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml
2022-02-15 15:51:07 +01:00

341 lines
12 KiB
QML

// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import UM 1.5 as UM
import Cura 1.5 as Cura
import QtQuick 2.2
import QtQuick.Controls 2.9
import QtQuick.Layouts 1.1
import QtQuick.Window 2.1
Cura.MachineAction
{
id: base
anchors.fill: parent;
property alias currentItemIndex: listview.currentIndex
property var selectedDevice: null
property bool completeProperties: true
// For validating IP addresses
property var networkingUtil: Cura.NetworkingUtil {}
function connectToPrinter()
{
if (base.selectedDevice && base.completeProperties)
{
manager.associateActiveMachineWithPrinterDevice(base.selectedDevice)
completed()
}
}
Column
{
anchors.fill: parent;
id: discoverUM3Action
spacing: UM.Theme.getSize("default_margin").height
SystemPalette { id: palette }
UM.I18nCatalog { id: catalog; name:"cura" }
UM.Label
{
id: pageTitle
width: parent.width
text: catalog.i18nc("@title:window", "Connect to Networked Printer")
}
UM.Label
{
id: pageDescription
width: parent.width
text: catalog.i18nc("@label", "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.") + "\n\n" + catalog.i18nc("@label", "Select your printer from the list below:")
}
Row
{
spacing: UM.Theme.getSize("default_lining").width
Button
{
id: addButton
text: catalog.i18nc("@action:button", "Add");
onClicked:
{
manualPrinterDialog.showDialog("", "");
}
}
Button
{
id: editButton
text: catalog.i18nc("@action:button", "Edit")
enabled: base.selectedDevice != null && base.selectedDevice.getProperty("manual") == "true"
onClicked:
{
manualPrinterDialog.showDialog(base.selectedDevice.key, base.selectedDevice.ipAddress);
}
}
Button
{
id: removeButton
text: catalog.i18nc("@action:button", "Remove")
enabled: base.selectedDevice != null && base.selectedDevice.getProperty("manual") == "true"
onClicked: manager.removeManualDevice(base.selectedDevice.key, base.selectedDevice.ipAddress)
}
Button
{
id: rediscoverButton
text: catalog.i18nc("@action:button", "Refresh")
onClicked: manager.restartDiscovery()
}
}
Row
{
id: contentRow
width: parent.width
spacing: UM.Theme.getSize("default_margin").width
Column
{
width: Math.round(parent.width * 0.5)
spacing: UM.Theme.getSize("default_margin").height
ListView
{
id: listview
width: parent.width
height: base.height - contentRow.y - discoveryTip.height
ScrollBar.vertical: UM.ScrollBar {}
clip: true
model: manager.foundDevices
currentIndex: -1
onCurrentIndexChanged:
{
base.selectedDevice = listview.model[currentIndex];
// Only allow connecting if the printer has responded to API query since the last refresh
base.completeProperties = base.selectedDevice != null && base.selectedDevice.getProperty("incomplete") != "true";
}
Component.onCompleted: manager.startDiscovery()
delegate: Rectangle
{
height: printNameLabel.height
color: ListView.isCurrentItem ? palette.highlight : index % 2 ? palette.base : palette.alternateBase
width: listview.width
Label
{
id: printNameLabel
height: contentHeight
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.right: parent.right
text: listview.model[index].name
color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text
elide: Text.ElideRight
renderType: Text.NativeRendering
}
MouseArea
{
anchors.fill: parent;
onClicked:
{
if(!parent.ListView.isCurrentItem)
{
parent.ListView.view.currentIndex = index;
}
}
}
}
}
UM.Label
{
id: discoveryTip
anchors.left: parent.left
anchors.right: parent.right
text: catalog.i18nc("@label", "If your printer is not listed, read the <a href='%1'>network printing troubleshooting guide</a>").arg("https://ultimaker.com/en/cura/troubleshooting/network?utm_source=cura&utm_medium=software&utm_campaign=manage-network-printer");
onLinkActivated: Qt.openUrlExternally(link)
}
}
Column
{
width: Math.round(parent.width * 0.5)
visible: base.selectedDevice ? true : false
spacing: UM.Theme.getSize("default_margin").height
UM.Label
{
width: parent.width
text: base.selectedDevice ? base.selectedDevice.name : ""
font: UM.Theme.getFont("large_bold")
elide: Text.ElideRight
}
Grid
{
visible: base.completeProperties
width: parent.width
columns: 2
property real labelWidth: Math.round(width * 0.5)
UM.Label
{
width: labelWidth
text: catalog.i18nc("@label", "Type")
}
UM.Label
{
width: labelWidth
text:
{
if (base.selectedDevice) {
return base.selectedDevice.printerTypeName
}
return ""
}
}
UM.Label
{
width: labelWidth
text: catalog.i18nc("@label", "Firmware version")
}
UM.Label
{
width: labelWidth
text: base.selectedDevice ? base.selectedDevice.firmwareVersion : ""
}
UM.Label
{
width: labelWidth
text: catalog.i18nc("@label", "Address")
}
UM.Label
{
width: labelWidth
text: base.selectedDevice ? base.selectedDevice.ipAddress : ""
}
}
UM.Label
{
width: parent.width
text:{
// The property cluster size does not exist for older UM3 devices.
if(!base.selectedDevice || base.selectedDevice.clusterSize == null || base.selectedDevice.clusterSize == 1)
{
return "";
}
else if (base.selectedDevice.clusterSize === 0)
{
return catalog.i18nc("@label", "This printer is not set up to host a group of printers.");
}
else
{
return catalog.i18nc("@label", "This printer is the host for a group of %1 printers.".arg(base.selectedDevice.clusterSize));
}
}
}
UM.Label
{
width: parent.width
visible: base.selectedDevice != null && !base.completeProperties
text: catalog.i18nc("@label", "The printer at this address has not yet responded." )
}
Button
{
text: catalog.i18nc("@action:button", "Connect")
enabled: (base.selectedDevice && base.completeProperties && base.selectedDevice.clusterSize > 0) ? true : false
onClicked: connectToPrinter()
}
}
}
}
UM.MessageDialog
{
id: invalidIPAddressMessageDialog
title: catalog.i18nc("@title:window", "Invalid IP address")
text: catalog.i18nc("@text", "Please enter a valid IP address.")
standardButtons: Dialog.Ok
}
Dialog
{
id: manualPrinterDialog
property string printerKey
property alias addressText: addressField.text
title: catalog.i18nc("@title:window", "Printer Address")
width: UM.Theme.getSize("small_popup_dialog").width
anchors.centerIn: Overlay.overlay
standardButtons: Dialog.Yes | Dialog.No
signal showDialog(string key, string address)
onShowDialog:
{
printerKey = key;
addressText = address;
manualPrinterDialog.open();
addressField.selectAll();
addressField.focus = true;
}
Column {
anchors.fill: parent
spacing: UM.Theme.getSize("default_margin").height
UM.Label
{
text: catalog.i18nc("@label", "Enter the IP address of your printer on the network.")
renderType: Text.NativeRendering
}
Cura.TextField
{
id: addressField
width: parent.width
validator: RegExpValidator { regExp: /[a-zA-Z0-9\.\-\_]*/ }
onAccepted: btnOk.clicked()
}
}
onRejected:
{
manualPrinterDialog.reject()
manualPrinterDialog.hide()
}
onAccepted:
{
// Validate the input first
if (!networkingUtil.isValidIP(manualPrinterDialog.addressText))
{
invalidIPAddressMessageDialog.open()
return
}
// if the entered IP address has already been discovered, switch the current item to that item
// and do nothing else.
for (var i = 0; i < manager.foundDevices.length; i++)
{
var device = manager.foundDevices[i]
if (device.address == manualPrinterDialog.addressText)
{
currentItemIndex = i
manualPrinterDialog.hide()
return
}
}
manager.setManualDevice(manualPrinterDialog.printerKey, manualPrinterDialog.addressText)
manualPrinterDialog.hide()
}
}
}