Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml
2018-09-19 17:02:46 +02:00

640 lines
22 KiB
QML

import QtQuick 2.2
import QtQuick.Controls 2.0
import QtQuick.Controls.Styles 1.4
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.1
import UM 1.3 as UM
Item
{
id: base
function haveAlert() {
return printJob.configurationChanges.length !== 0;
}
function alertHeight() {
return haveAlert() ? 230 : 0;
}
function alertText() {
if (printJob.configurationChanges.length === 0) {
return "";
}
var topLine;
if (materialsAreKnown(printJob)) {
topLine = catalog.i18nc("@label", "The assigned printer, %1, requires the following configuration change(s):").arg(printJob.assignedPrinter.name);
} else {
topLine = catalog.i18nc("@label", "The printer %1 is assigned, but the job contains an unknown material configuration.").arg(printJob.assignedPrinter.name);
}
var result = "<p>" + topLine +"</p>";
for (var i=0; i<printJob.configurationChanges.length; i++) {
var change = printJob.configurationChanges[i];
var text = "";
if (change.typeOfChange === 'material_change') {
text = catalog.i18nc("@label", "Change material %1 from %2 to %3.").arg(change.index + 1).arg(change.originName).arg(change.targetName);
} else if (change.typeOfChange === 'material_insert') {
text = catalog.i18nc("@label", "Load %3 as material %1 (This cannot be overridden).").arg(change.index + 1).arg(change.targetName);
} else if (change.typeOfChange === 'print_core_change') {
text = catalog.i18nc("@label", "Change print core %1 from %2 to %3.").arg(change.index + 1).arg(change.originName).arg(change.targetName);
} else if (change.typeOfChange === 'buildplate_change') {
var target_name = formatBuildPlateType(change.target_name);
text = catalog.i18nc("@label", "Change build plate to %1 (This cannot be overridden).").arg(target_name);
}
result += "<p><b>" + text + "</b></p>";
}
return result;
}
function materialsAreKnown(printJob) {
var conf0 = printJob.configuration[0];
if (conf0 && !conf0.material.material) {
return false;
}
var conf1 = printJob.configuration[1];
if (conf1 && !conf1.material.material) {
return false;
}
return true;
}
function formatBuildPlateType(buildPlateType) {
var translationText = "";
switch (buildPlateType) {
case 'glass':
translationText = catalog.i18nc("@label", "Glass");
break;
case 'aluminum':
translationText = catalog.i18nc("@label", "Aluminum");
break;
default:
translationText = null;
}
return translationText;
}
function formatPrintJobName(name) {
var extensionsToRemove = [
'.gz',
'.gcode',
'.ufp'
];
for (var i = 0; i < extensionsToRemove.length; i++) {
var extension = extensionsToRemove[i];
if (name.slice(-extension.length) === extension) {
name = name.substring(0, name.length - extension.length);
}
}
return name;
}
function isPrintJobForcable(printJob) {
var forcable = true;
for (var i = 0; i < printJob.configurationChanges.length; i++) {
var typeOfChange = printJob.configurationChanges[i].typeOfChange;
if (typeOfChange === 'material_insert' || typeOfChange === 'buildplate_change') {
forcable = false;
}
}
return forcable;
}
property var cardHeight: 175
height: (cardHeight + alertHeight()) * screenScaleFactor
property var printJob: null
property var shadowRadius: 5 * screenScaleFactor
function getPrettyTime(time)
{
return OutputDevice.formatDuration(time)
}
width: parent.width
UM.I18nCatalog
{
id: catalog
name: "cura"
}
Rectangle
{
id: background
height: (cardHeight + alertHeight()) * screenScaleFactor
anchors
{
top: parent.top
topMargin: 3 * screenScaleFactor
left: parent.left
leftMargin: base.shadowRadius
rightMargin: base.shadowRadius
right: parent.right
//bottom: parent.bottom - alertHeight() * screenScaleFactor
bottomMargin: base.shadowRadius
}
layer.enabled: true
layer.effect: DropShadow
{
radius: base.shadowRadius
verticalOffset: 2 * screenScaleFactor
color: "#3F000000" // 25% shadow
}
Rectangle
{
height: cardHeight * screenScaleFactor
anchors
{
top: parent.top
left: parent.left
right: parent.right
// bottom: parent.bottom
}
Item
{
// Content on the left of the infobox
anchors
{
top: parent.top
bottom: parent.bottom
left: parent.left
right: parent.horizontalCenter
margins: UM.Theme.getSize("wide_margin").width
rightMargin: UM.Theme.getSize("default_margin").width
}
Label
{
id: printJobName
text: printJob.name
font: UM.Theme.getFont("default_bold")
width: parent.width
elide: Text.ElideRight
}
Label
{
id: ownerName
anchors.top: printJobName.bottom
text: printJob.owner
font: UM.Theme.getFont("default")
opacity: 0.6
width: parent.width
elide: Text.ElideRight
}
Image
{
id: printJobPreview
source: printJob.previewImageUrl
anchors.top: ownerName.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: totalTimeLabel.bottom
width: height
opacity: printJob.state == "error" ? 0.5 : 1.0
}
UM.RecolorImage
{
id: statusImage
anchors.centerIn: printJobPreview
source: printJob.state == "error" ? "../svg/aborted-icon.svg" : ""
visible: source != ""
width: 0.5 * printJobPreview.width
height: 0.5 * printJobPreview.height
sourceSize.width: width
sourceSize.height: height
color: "black"
}
Label
{
id: totalTimeLabel
anchors.bottom: parent.bottom
anchors.right: parent.right
font: UM.Theme.getFont("default")
text: printJob != null ? getPrettyTime(printJob.timeTotal) : ""
elide: Text.ElideRight
}
}
Item
{
// Content on the right side of the infobox.
anchors
{
top: parent.top
bottom: parent.bottom
left: parent.horizontalCenter
right: parent.right
margins: 2 * UM.Theme.getSize("default_margin").width
leftMargin: UM.Theme.getSize("default_margin").width
rightMargin: UM.Theme.getSize("default_margin").width / 2
}
Label
{
id: targetPrinterLabel
elide: Text.ElideRight
font: UM.Theme.getFont("default_bold")
text:
{
if(printJob.assignedPrinter == null)
{
if(printJob.state == "error")
{
return catalog.i18nc("@label", "Waiting for: Unavailable printer")
}
return catalog.i18nc("@label", "Waiting for: First available")
}
else
{
return catalog.i18nc("@label", "Waiting for: ") + printJob.assignedPrinter.name
}
}
anchors
{
left: parent.left
right: contextButton.left
rightMargin: UM.Theme.getSize("default_margin").width
}
}
function switchPopupState()
{
popup.visible ? popup.close() : popup.open()
}
Button
{
id: contextButton
text: "\u22EE" //Unicode; Three stacked points.
width: 35
height: width
anchors
{
right: parent.right
top: parent.top
}
hoverEnabled: true
background: Rectangle
{
opacity: contextButton.down || contextButton.hovered ? 1 : 0
width: contextButton.width
height: contextButton.height
radius: 0.5 * width
color: UM.Theme.getColor("viewport_background")
}
contentItem: Label
{
text: contextButton.text
color: UM.Theme.getColor("monitor_text_inactive")
font.pixelSize: 25
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
onClicked: parent.switchPopupState()
}
Popup
{
// TODO Change once updating to Qt5.10 - The 'opened' property is in 5.10 but the behavior is now implemented with the visible property
id: popup
clip: true
closePolicy: Popup.CloseOnPressOutside
x: (parent.width - width) + 26 * screenScaleFactor
y: contextButton.height - 5 * screenScaleFactor // Because shadow
width: 182 * screenScaleFactor
height: contentItem.height + 2 * padding
visible: false
padding: 5 * screenScaleFactor // Because shadow
transformOrigin: Popup.Top
contentItem: Item
{
width: popup.width
height: childrenRect.height + 36 * screenScaleFactor
anchors.topMargin: 10 * screenScaleFactor
anchors.bottomMargin: 10 * screenScaleFactor
Button
{
id: sendToTopButton
text: catalog.i18nc("@label", "Move to top")
onClicked:
{
OutputDevice.sendJobToTop(printJob.key)
popup.close()
}
width: parent.width
enabled: OutputDevice.queuedPrintJobs[0].key != printJob.key
visible: enabled
anchors.top: parent.top
anchors.topMargin: 18 * screenScaleFactor
height: visible ? 39 * screenScaleFactor : 0 * screenScaleFactor
hoverEnabled: true
background: Rectangle
{
opacity: sendToTopButton.down || sendToTopButton.hovered ? 1 : 0
color: UM.Theme.getColor("viewport_background")
}
contentItem: Label
{
text: sendToTopButton.text
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
}
Button
{
id: deleteButton
text: catalog.i18nc("@label", "Delete")
onClicked:
{
OutputDevice.deleteJobFromQueue(printJob.key)
popup.close()
}
width: parent.width
height: 39 * screenScaleFactor
anchors.top: sendToTopButton.bottom
hoverEnabled: true
background: Rectangle
{
opacity: deleteButton.down || deleteButton.hovered ? 1 : 0
color: UM.Theme.getColor("viewport_background")
}
contentItem: Label
{
text: deleteButton.text
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
}
}
background: Item
{
width: popup.width
height: popup.height
DropShadow
{
anchors.fill: pointedRectangle
radius: 5
color: "#3F000000" // 25% shadow
source: pointedRectangle
transparentBorder: true
verticalOffset: 2
}
Item
{
id: pointedRectangle
width: parent.width - 10 * screenScaleFactor // Because of the shadow
height: parent.height - 10 * screenScaleFactor // Because of the shadow
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Rectangle
{
id: point
height: 14 * screenScaleFactor
width: 14 * screenScaleFactor
color: UM.Theme.getColor("setting_control")
transform: Rotation { angle: 45}
anchors.right: bloop.right
anchors.rightMargin: 24
y: 1
}
Rectangle
{
id: bloop
color: UM.Theme.getColor("setting_control")
width: parent.width
anchors.top: parent.top
anchors.topMargin: 8 * screenScaleFactor // Because of the shadow + point
anchors.bottom: parent.bottom
anchors.bottomMargin: 8 * screenScaleFactor // Because of the shadow
}
}
}
exit: Transition
{
// This applies a default NumberAnimation to any changes a state change makes to x or y properties
NumberAnimation { property: "visible"; duration: 75; }
}
enter: Transition
{
// This applies a default NumberAnimation to any changes a state change makes to x or y properties
NumberAnimation { property: "visible"; duration: 75; }
}
onClosed: visible = false
onOpened: visible = true
}
Row
{
id: printerFamilyPills
spacing: 0.5 * UM.Theme.getSize("default_margin").width
anchors
{
left: parent.left
right: parent.right
bottom: extrudersInfo.top
bottomMargin: UM.Theme.getSize("default_margin").height
}
height: childrenRect.height
Repeater
{
model: printJob.compatibleMachineFamilies
delegate: PrinterFamilyPill
{
text: modelData
color: UM.Theme.getColor("viewport_background")
padding: 3 * screenScaleFactor
}
}
}
// PrintCore && Material config
Row
{
id: extrudersInfo
anchors.bottom: parent.bottom
anchors
{
left: parent.left
right: parent.right
}
height: childrenRect.height
spacing: UM.Theme.getSize("default_margin").width
PrintCoreConfiguration
{
id: leftExtruderInfo
width: Math.round(parent.width / 2) * screenScaleFactor
printCoreConfiguration: printJob.configuration.extruderConfigurations[0]
}
PrintCoreConfiguration
{
id: rightExtruderInfo
width: Math.round(parent.width / 2) * screenScaleFactor
printCoreConfiguration: printJob.configuration.extruderConfigurations[1]
}
}
}
}
Rectangle
{
height: cardHeight * screenScaleFactor
color: UM.Theme.getColor("viewport_background")
width: 2 * screenScaleFactor
anchors.top: parent.top
anchors.margins: UM.Theme.getSize("default_margin").height
anchors.horizontalCenter: parent.horizontalCenter
}
// Alert / Configuration change box
Rectangle
{
height: alertHeight() * screenScaleFactor
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
color: "#ff00ff"
ColumnLayout
{
anchors.fill: parent
RowLayout
{
Item
{
Layout.fillWidth: true
}
Label
{
font: UM.Theme.getFont("default_bold")
text: "Configuration change"
}
UM.RecolorImage
{
id: collapseIcon
width: 15
height: 15
sourceSize.width: width
sourceSize.height: height
// FIXME
source: base.collapsed ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom")
color: "black"
}
Item
{
Layout.fillWidth: true
}
}
Rectangle
{
Layout.fillHeight: true
Layout.fillWidth: true
color: "red"
Rectangle
{
color: "green"
width: childrenRect.width
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.bottom: parent.bottom
ColumnLayout
{
width: childrenRect.width
anchors.top: parent.top
anchors.bottom: parent.bottom
Text
{
Layout.alignment: Qt.AlignTop
textFormat: Text.StyledText
font: UM.Theme.getFont("default_bold")
text: alertText()
}
Button
{
visible: isPrintJobForcable(printJob)
text: catalog.i18nc("@label", "Override")
onClicked: {
overrideConfirmationDialog.visible = true;
}
}
// Spacer
Item
{
Layout.fillHeight: true
}
}
}
}
}
}
MessageDialog
{
id: overrideConfirmationDialog
title: catalog.i18nc("@window:title", "Override configuration configuration and start print")
icon: StandardIcon.Warning
text: {
var printJobName = formatPrintJobName(printJob.name);
var confirmText = catalog.i18nc("@label", "Starting a print job with an incompatible configuration could damage your 3D printer. Are you sure you want to override the configuration and print %1?").arg(printJobName);
return confirmText;
}
standardButtons: StandardButton.Yes | StandardButton.No
Component.onCompleted: visible = false
onYes: OutputDevice.forceSendJob(printJob.key)
}
}
}