Browse Source

Merge branch 'cura4.0_action_panel' into cura4.0_header

Remco Burema 6 years ago
parent
commit
aef5c67652

+ 2 - 0
resources/qml/Account/GeneralOperations.qml

@@ -21,6 +21,7 @@ Row
         textColor: UM.Theme.getColor("main_window_header_button_text_active")
         textHoverColor: UM.Theme.getColor("main_window_header_button_text_active")
         onClicked: Qt.openUrlExternally("https://account.ultimaker.com")
+        fixedWidthMode: true
     }
 
     Cura.ActionButton
@@ -29,5 +30,6 @@ Row
         height: UM.Theme.getSize("account_button").height
         text: catalog.i18nc("@button", "Login")
         onClicked: Cura.API.account.login()
+        fixedWidthMode: true
     }
 }

+ 2 - 0
resources/qml/Account/UserOperations.qml

@@ -21,6 +21,7 @@ Row
         textColor: UM.Theme.getColor("main_window_header_button_text_active")
         textHoverColor: UM.Theme.getColor("main_window_header_button_text_active")
         onClicked: Qt.openUrlExternally("https://account.ultimaker.com")
+        fixedWidthMode: true
     }
 
     Cura.ActionButton
@@ -29,5 +30,6 @@ Row
         height: UM.Theme.getSize("account_button").height
         text: catalog.i18nc("@button", "Logout")
         onClicked: Cura.API.account.logout()
+        fixedWidthMode: true
     }
 }

+ 16 - 0
resources/qml/ActionButton.qml

@@ -14,6 +14,7 @@ Button
     property alias iconSource: buttonIcon.source
     property alias textFont: buttonText.font
     property alias cornerRadius: backgroundRect.radius
+    property alias tooltip: tooltip.text
     property var color: UM.Theme.getColor("primary")
     property var hoverColor: UM.Theme.getColor("primary_hover")
     property var disabledColor: color
@@ -23,6 +24,10 @@ Button
     property var outlineColor: color
     property var outlineHoverColor: hoverColor
     property var outlineDisabledColor: outlineColor
+    // This property is used to indicate whether the button has a fixed width or the width would depend on the contents
+    // Be careful when using fixedWidthMode, the translated texts can be too long that they won't fit. In any case,
+    // we elide the text to the right so the text will be cut off with the three dots at the end.
+    property var fixedWidthMode: false
 
     contentItem: Row
     {
@@ -48,6 +53,9 @@ Button
             visible: text != ""
             renderType: Text.NativeRendering
             anchors.verticalCenter: parent.verticalCenter
+            width: fixedWidthMode ? button.width - button.leftPadding - button.rightPadding : undefined
+            horizontalAlignment: Text.AlignHCenter
+            elide: Text.ElideRight
         }
     }
 
@@ -60,6 +68,14 @@ Button
         border.color: button.enabled ? (button.hovered ? button.outlineHoverColor : button.outlineColor) : button.outlineDisabledColor
     }
 
+    ToolTip
+    {
+        id: tooltip
+        text: ""
+        delay: 500
+        visible: text != "" && button.hovered
+    }
+
     MouseArea
     {
         id: mouseArea

+ 56 - 0
resources/qml/ActionPanel/ActionPanelWidget.qml

@@ -0,0 +1,56 @@
+// 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.1
+import QtQuick.Layouts 1.3
+
+import UM 1.2 as UM
+import Cura 1.0 as Cura
+
+
+// This element hold all the elements needed for the user to trigger the slicing process, and later
+// to get information about the printing times, material consumption and the output process (such as
+// saving to a file, printing over network, ...
+Rectangle
+{
+    id: actionPanelWidget
+
+    width: UM.Theme.getSize("action_panel_widget").width
+    height: childrenRect.height + 2 * UM.Theme.getSize("thick_margin").height
+
+    color: UM.Theme.getColor("main_background")
+    border.width: UM.Theme.getSize("default_lining").width
+    border.color: UM.Theme.getColor("lining")
+    radius: UM.Theme.getSize("default_radius").width
+    visible: CuraApplication.platformActivity
+
+    property bool outputAvailable: UM.Backend.state == UM.Backend.Done || UM.Backend.state == UM.Backend.Disabled
+
+    Loader
+    {
+        id: loader
+        anchors
+        {
+            top: parent.top
+            topMargin: UM.Theme.getSize("thick_margin").height
+            left: parent.left
+            leftMargin: UM.Theme.getSize("thick_margin").width
+            right: parent.right
+            rightMargin: UM.Theme.getSize("thick_margin").width
+        }
+        sourceComponent: outputAvailable ? outputProcessWidget : sliceProcessWidget
+    }
+
+    Component
+    {
+        id: sliceProcessWidget
+        SliceProcessWidget { }
+    }
+
+    Component
+    {
+        id: outputProcessWidget
+        OutputProcessWidget { }
+    }
+}

+ 103 - 0
resources/qml/ActionPanel/OutputDevicesActionButton.qml

@@ -0,0 +1,103 @@
+// 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.1
+import QtQuick.Layouts 1.3
+
+import UM 1.1 as UM
+import Cura 1.0 as Cura
+
+Item
+{
+    id: widget
+
+    Cura.ActionButton
+    {
+        id: saveToButton
+        height: parent.height
+        fixedWidthMode: true
+
+        anchors
+        {
+            top: parent.top
+            left: parent.left
+            right: deviceSelectionMenu.visible ? deviceSelectionMenu.left : parent.right
+        }
+
+        tooltip: UM.OutputDeviceManager.activeDeviceDescription
+
+        text: UM.OutputDeviceManager.activeDeviceShortDescription
+
+        onClicked:
+        {
+            forceActiveFocus();
+            UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName,
+                { "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats });
+        }
+    }
+
+    Cura.ActionButton
+    {
+        id: deviceSelectionMenu
+        height: parent.height
+
+        anchors
+        {
+            top: parent.top
+            right: parent.right
+        }
+
+        tooltip: catalog.i18nc("@info:tooltip", "Select the active output device")
+        iconSource: popup.opened ? UM.Theme.getIcon("arrow_top") : UM.Theme.getIcon("arrow_bottom")
+        color: UM.Theme.getColor("action_panel_secondary")
+        visible: (devicesModel.deviceCount > 1)
+
+        onClicked: popup.opened ? popup.close() : popup.open()
+
+        Popup
+        {
+            id: popup
+            padding: 0
+
+            y: -height
+            x: parent.width - width
+
+            closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
+
+            contentItem: Column
+            {
+                Repeater
+                {
+                    model: devicesModel
+
+                    delegate: Cura.ActionButton
+                    {
+                        text: model.description
+                        color: "transparent"
+                        cornerRadius: 0
+                        hoverColor: UM.Theme.getColor("primary")
+
+                        onClicked:
+                        {
+                            UM.OutputDeviceManager.setActiveDevice(model.id)
+                            popup.close()
+                        }
+                    }
+                }
+            }
+
+            background: Rectangle
+            {
+                opacity: visible ? 1 : 0
+                Behavior on opacity { NumberAnimation { duration: 100 } }
+                radius: UM.Theme.getSize("default_radius").width
+                color: UM.Theme.getColor("action_panel_secondary")
+                border.color: UM.Theme.getColor("lining")
+                border.width: UM.Theme.getSize("default_lining").width
+            }
+        }
+    }
+
+    UM.OutputDevicesModel { id: devicesModel }
+}

+ 122 - 0
resources/qml/ActionPanel/OutputProcessWidget.qml

@@ -0,0 +1,122 @@
+// 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.1
+import QtQuick.Layouts 1.3
+
+import UM 1.1 as UM
+import Cura 1.0 as Cura
+
+
+// This element contains all the elements the user needs to visualize the data
+// that is gather after the slicing process, such as printint time, material usage, ...
+// There are also two buttons: one to previsualize the output layers, and the other to
+// select what to do with it (such as print over network, save to file, ...)
+Column
+{
+    id: widget
+
+    spacing: UM.Theme.getSize("thin_margin").height
+
+    UM.I18nCatalog
+    {
+        id: catalog
+        name: "cura"
+    }
+
+    Item
+    {
+        id: information
+        width: parent.width
+        height: childrenRect.height
+
+        Column
+        {
+            id: timeAndCostsInformation
+            spacing: UM.Theme.getSize("thin_margin").height
+
+            anchors
+            {
+                left: parent.left
+                right: printInformationPanel.left
+                rightMargin: UM.Theme.getSize("thin_margin").height
+            }
+
+            Cura.IconLabel
+            {
+                id: estimatedTime
+                width: parent.width
+
+                text: PrintInformation.currentPrintTime.getDisplayString(UM.DurationFormat.Long)
+                source: UM.Theme.getIcon("clock")
+                font: UM.Theme.getFont("small")
+            }
+
+            Cura.IconLabel
+            {
+                id: estimatedCosts
+                width: parent.width
+
+                property var printMaterialLengths: PrintInformation.materialLengths
+                property var printMaterialWeights: PrintInformation.materialWeights
+
+                text:
+                {
+                    var totalLengths = 0
+                    var totalWeights = 0
+                    if (printMaterialLengths)
+                    {
+                        for(var index = 0; index < printMaterialLengths.length; index++)
+                        {
+                            if(printMaterialLengths[index] > 0)
+                            {
+                                totalLengths += printMaterialLengths[index]
+                                totalWeights += Math.round(printMaterialWeights[index])
+                            }
+                        }
+                    }
+                    return totalWeights + "g · " + totalLengths.toFixed(2) + "m"
+                }
+                source: UM.Theme.getIcon("spool")
+                font: UM.Theme.getFont("very_small")
+            }
+        }
+
+        PrintInformationWidget
+        {
+            id: printInformationPanel
+
+            anchors
+            {
+                right: parent.right
+                verticalCenter: timeAndCostsInformation.verticalCenter
+            }
+        }
+    }
+
+    Row
+    {
+        id: buttonRow
+        spacing: UM.Theme.getSize("default_margin").width
+
+        Cura.ActionButton
+        {
+            leftPadding: UM.Theme.getSize("default_margin").width
+            rightPadding: UM.Theme.getSize("default_margin").width
+            height: UM.Theme.getSize("action_panel_button").height
+            text: catalog.i18nc("@button", "Preview")
+            color: UM.Theme.getColor("secondary")
+            hoverColor: UM.Theme.getColor("secondary")
+            textColor: UM.Theme.getColor("primary")
+            textHoverColor: UM.Theme.getColor("text")
+            onClicked: UM.Controller.setActiveStage("MonitorStage")
+        }
+
+        Cura.OutputDevicesActionButton
+        {
+            width: UM.Theme.getSize("action_panel_button").width
+            height: UM.Theme.getSize("action_panel_button").height
+        }
+    }
+}

+ 62 - 0
resources/qml/ActionPanel/PrintInformationWidget.qml

@@ -0,0 +1,62 @@
+// 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.1
+
+import UM 1.1 as UM
+import Cura 1.0 as Cura
+
+Button
+{
+    id: widget
+
+    implicitHeight: UM.Theme.getSize("section_icon").height
+    implicitWidth: UM.Theme.getSize("section_icon").width
+
+    background: UM.RecolorImage
+    {
+        id: moreInformationIcon
+
+        source: UM.Theme.getIcon("info")
+        width: UM.Theme.getSize("section_icon").width
+        height: UM.Theme.getSize("section_icon").height
+
+        sourceSize.width: width
+        sourceSize.height: height
+
+        color: widget.hovered ? UM.Theme.getColor("primary") : UM.Theme.getColor("text_medium")
+    }
+
+    onClicked: popup.opened ? popup.close() : popup.open()
+
+    Popup
+    {
+        id: popup
+
+        y: -(height + UM.Theme.getSize("default_arrow").height + UM.Theme.getSize("thin_margin").height)
+        x: parent.width - width + UM.Theme.getSize("thin_margin").width
+
+        closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
+
+        contentItem: PrintJobInformation
+        {
+            id: printJobInformation
+            width: UM.Theme.getSize("action_panel_information_widget").width
+        }
+
+        background: UM.PointingRectangle
+        {
+            opacity: visible ? 1 : 0
+            Behavior on opacity { NumberAnimation { duration: 100 } }
+            color: UM.Theme.getColor("tool_panel_background")
+            borderColor: UM.Theme.getColor("lining")
+            borderWidth: UM.Theme.getSize("default_lining").width
+
+            target: Qt.point(width - (widget.width / 2) - UM.Theme.getSize("thin_margin").width,
+                            height + UM.Theme.getSize("default_arrow").height - UM.Theme.getSize("thin_margin").height)
+
+            arrowSize: UM.Theme.getSize("default_arrow").width
+        }
+    }
+}

+ 161 - 0
resources/qml/ActionPanel/PrintJobInformation.qml

@@ -0,0 +1,161 @@
+// 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.1
+
+import UM 1.1 as UM
+import Cura 1.0 as Cura
+
+Column
+{
+    id: base
+    spacing: UM.Theme.getSize("default_margin").width
+
+    UM.I18nCatalog
+    {
+        id: catalog
+        name: "cura"
+    }
+
+    Column
+    {
+        id: timeSpecification
+        spacing: UM.Theme.getSize("thin_margin").width
+        width: parent.width
+        topPadding: UM.Theme.getSize("default_margin").height
+        leftPadding: UM.Theme.getSize("default_margin").width
+        rightPadding: UM.Theme.getSize("default_margin").width
+
+        Label
+        {
+            text: catalog.i18nc("@label", "Time specification").toUpperCase()
+            color: UM.Theme.getColor("primary")
+            font: UM.Theme.getFont("small")
+            renderType: Text.NativeRendering
+        }
+
+        Label
+        {
+            property var printDuration: PrintInformation.currentPrintTime
+
+            text:
+            {
+                // All the time information for the different features is achieved
+                var printTime = PrintInformation.getFeaturePrintTimes()
+                var totalSeconds = parseInt(printDuration.getDisplayString(UM.DurationFormat.Seconds))
+
+                // A message is created and displayed when the user hover the time label
+                var text = "<table width=\"100%\">"
+                for(var feature in printTime)
+                {
+                    if(!printTime[feature].isTotalDurationZero)
+                    {
+                        text += "<tr><td>" + feature + ":</td>" +
+                            "<td align=\"right\" valign=\"bottom\">&nbsp;&nbsp;%1</td>".arg(printTime[feature].getDisplayString(UM.DurationFormat.ISO8601).slice(0,-3)) +
+                            "<td align=\"right\" valign=\"bottom\">&nbsp;&nbsp;%1%</td>".arg(Math.round(100 * parseInt(printTime[feature].getDisplayString(UM.DurationFormat.Seconds)) / totalSeconds)) +
+                            "</tr>"
+                    }
+                }
+                text += "</table>"
+                return text
+            }
+            width: parent.width - 2 * UM.Theme.getSize("default_margin").width
+            color: UM.Theme.getColor("text")
+            font: UM.Theme.getFont("very_small")
+            renderType: Text.NativeRendering
+            textFormat: Text.RichText
+        }
+    }
+
+    Column
+    {
+        id: materialSpecification
+        spacing: UM.Theme.getSize("thin_margin").width
+        width: parent.width
+        bottomPadding: UM.Theme.getSize("default_margin").height
+        leftPadding: UM.Theme.getSize("default_margin").width
+        rightPadding: UM.Theme.getSize("default_margin").width
+
+        Label
+        {
+            text: catalog.i18nc("@label", "Material specification").toUpperCase()
+            color: UM.Theme.getColor("primary")
+            font: UM.Theme.getFont("small")
+            renderType: Text.NativeRendering
+        }
+        
+        Label
+        {
+            property var printMaterialLengths: PrintInformation.materialLengths
+            property var printMaterialWeights: PrintInformation.materialWeights
+            property var printMaterialCosts: PrintInformation.materialCosts
+            property var printMaterialNames: PrintInformation.materialNames
+
+            function formatRow(items)
+            {
+                var rowHTML = "<tr>"
+                for(var item = 0; item < items.length; item++)
+                {
+                    if (item == 0)
+                    {
+                        rowHTML += "<td valign=\"bottom\">%1</td>".arg(items[item])
+                    }
+                    else
+                    {
+                        rowHTML += "<td align=\"right\" valign=\"bottom\">&nbsp;&nbsp;%1</td>".arg(items[item])
+                    }
+                }
+                rowHTML += "</tr>"
+                return rowHTML
+            }
+
+            text:
+            {
+                var lengths = []
+                var weights = []
+                var costs = []
+                var names = []
+                if(printMaterialLengths)
+                {
+                    for(var index = 0; index < printMaterialLengths.length; index++)
+                    {
+                        if(printMaterialLengths[index] > 0)
+                        {
+                            names.push(printMaterialNames[index])
+                            lengths.push(printMaterialLengths[index].toFixed(2))
+                            weights.push(String(Math.round(printMaterialWeights[index])))
+                            var cost = printMaterialCosts[index] == undefined ? 0 : printMaterialCosts[index].toFixed(2)
+                            costs.push(cost)
+                        }
+                    }
+                }
+                if(lengths.length == 0)
+                {
+                    lengths = ["0.00"]
+                    weights = ["0"]
+                    costs = ["0.00"]
+                }
+
+                var text = "<table width=\"100%\">"
+                for(var index = 0; index < lengths.length; index++)
+                {
+                    text += formatRow([
+                        "%1:".arg(names[index]),
+                        catalog.i18nc("@label m for meter", "%1m").arg(lengths[index]),
+                        catalog.i18nc("@label g for grams", "%1g").arg(weights[index]),
+                        "%1&nbsp;%2".arg(UM.Preferences.getValue("cura/currency")).arg(costs[index]),
+                    ])
+                }
+                text += "</table>"
+
+                return text
+            }
+            width: parent.width - 2 * UM.Theme.getSize("default_margin").width
+            color: UM.Theme.getColor("text")
+            font: UM.Theme.getFont("very_small")
+            renderType: Text.NativeRendering
+            textFormat: Text.RichText
+        }
+    }
+}

+ 139 - 0
resources/qml/ActionPanel/SliceProcessWidget.qml

@@ -0,0 +1,139 @@
+// 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.1
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 1.4 as Controls1
+
+import UM 1.1 as UM
+import Cura 1.0 as Cura
+
+
+// This element contains all the elements the user needs to create a printjob from the
+// model(s) that is(are) on the buildplate. Mainly the button to start/stop the slicing
+// process and a progress bar to see the progress of the process.
+Column
+{
+    id: widget
+
+    spacing: UM.Theme.getSize("thin_margin").height
+
+    UM.I18nCatalog
+    {
+        id: catalog
+        name: "cura"
+    }
+
+    property real progress: UM.Backend.progress
+    property int backendState: UM.Backend.state
+
+    function sliceOrStopSlicing()
+    {
+        if (widget.backendState == UM.Backend.NotStarted)
+        {
+            CuraApplication.backend.forceSlice()
+        }
+        else
+        {
+            CuraApplication.backend.stopSlicing()
+        }
+    }
+
+    Cura.IconLabel
+    {
+        id: message
+        width: parent.width
+        visible: widget.backendState == UM.Backend.Error
+
+        text: catalog.i18nc("@label:PrintjobStatus", "Unable to Slice")
+        source: UM.Theme.getIcon("warning")
+        color: UM.Theme.getColor("warning")
+        font: UM.Theme.getFont("very_small")
+    }
+
+    // Progress bar, only visible when the backend is in the process of slice the printjob
+    ProgressBar
+    {
+        id: progressBar
+        width: parent.width
+        height: UM.Theme.getSize("progressbar").height
+        value: progress
+        visible: widget.backendState == UM.Backend.Processing
+
+        background: Rectangle
+        {
+            anchors.fill: parent
+            radius: UM.Theme.getSize("progressbar_radius").width
+            color: UM.Theme.getColor("progressbar_background")
+        }
+
+        contentItem: Item
+        {
+            anchors.fill: parent
+            Rectangle
+            {
+                width: progressBar.visualPosition * parent.width
+                height: parent.height
+                radius: UM.Theme.getSize("progressbar_radius").width
+                color: UM.Theme.getColor("progressbar_control")
+            }
+        }
+    }
+
+    Cura.ActionButton
+    {
+        id: prepareButton
+        width: parent.width
+        height: UM.Theme.getSize("action_panel_button").height
+        fixedWidthMode: true
+        text:
+        {
+            if ([UM.Backend.NotStarted, UM.Backend.Error].indexOf(widget.backendState) != -1)
+            {
+                return catalog.i18nc("@button", "Slice")
+            }
+            if (autoSlice)
+            {
+                return catalog.i18nc("@button", "Auto slicing...")
+            }
+            return catalog.i18nc("@button", "Cancel")
+        }
+        enabled: !autoSlice && !disabledSlice
+
+        // Get the current value from the preferences
+        property bool autoSlice: UM.Preferences.getValue("general/auto_slice")
+        // Disable the slice process when
+        property bool disabledSlice: [UM.Backend.Done, UM.Backend.Error].indexOf(widget.backendState) != -1
+
+        disabledColor: disabledSlice ? UM.Theme.getColor("action_button_disabled") : "transparent"
+        textDisabledColor: disabledSlice ?  UM.Theme.getColor("action_button_disabled_text") : UM.Theme.getColor("primary")
+        outlineDisabledColor: disabledSlice ? UM.Theme.getColor("action_button_disabled_border") : "transparent"
+
+        onClicked: sliceOrStopSlicing()
+    }
+
+    // React when the user changes the preference of having the auto slice enabled
+    Connections
+    {
+        target: UM.Preferences
+        onPreferenceChanged:
+        {
+            var autoSlice = UM.Preferences.getValue("general/auto_slice")
+            prepareButton.autoSlice = autoSlice
+        }
+    }
+
+    // Shortcut for "slice/stop"
+    Controls1.Action
+    {
+        shortcut: "Ctrl+P"
+        onTriggered:
+        {
+            if (prepareButton.enabled)
+            {
+                sliceOrStopSlicing()
+            }
+        }
+    }
+}

+ 0 - 239
resources/qml/ActionPanelWidget.qml

@@ -1,239 +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 QtQuick.Layouts 1.3
-
-import UM 1.2 as UM
-import Cura 1.0 as Cura
-
-Rectangle
-{
-    id: base
-
-    // We need a whole lot of print duration information.
-    property variant printDuration: PrintInformation.currentPrintTime
-
-    // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it.
-    signal showTooltip(Item item, point location, string text)
-    signal hideTooltip()
-
-    color: UM.Theme.getColor("main_background")
-
-    // Also add an extra margin, as we want some breathing room around the edges.
-    height: saveButton.height + UM.Theme.getSize("thick_margin").height
-    Label
-    {
-        id: timeDetails
-        anchors.left: parent.left
-        anchors.bottom: costSpec.top
-        anchors.leftMargin: UM.Theme.getSize("thick_margin").width
-
-        font: UM.Theme.getFont("large")
-        color: UM.Theme.getColor("text_subtext")
-        text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label Hours and minutes", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short)
-        renderType: Text.NativeRendering
-
-        MouseArea
-        {
-            id: timeDetailsMouseArea
-            anchors.fill: parent
-            hoverEnabled: true
-
-            onEntered:
-            {
-                if(base.printDuration.valid && !base.printDuration.isTotalDurationZero)
-                {
-                    // All the time information for the different features is achieved
-                    var print_time = PrintInformation.getFeaturePrintTimes();
-                    var total_seconds = parseInt(base.printDuration.getDisplayString(UM.DurationFormat.Seconds))
-
-                    // A message is created and displayed when the user hover the time label
-                    var tooltip_html = "<b>%1</b><br/><table width=\"100%\">".arg(catalog.i18nc("@tooltip", "Time specification"));
-                    for(var feature in print_time)
-                    {
-                        if(!print_time[feature].isTotalDurationZero)
-                        {
-                            tooltip_html += "<tr><td>" + feature + ":</td>" +
-                                "<td align=\"right\" valign=\"bottom\">&nbsp;&nbsp;%1</td>".arg(print_time[feature].getDisplayString(UM.DurationFormat.ISO8601).slice(0,-3)) +
-                                "<td align=\"right\" valign=\"bottom\">&nbsp;&nbsp;%1%</td>".arg(Math.round(100 * parseInt(print_time[feature].getDisplayString(UM.DurationFormat.Seconds)) / total_seconds)) +
-                                "</td></tr>";
-                        }
-                    }
-                    tooltip_html += "</table>";
-                    base.showTooltip(parent, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), tooltip_html);
-                }
-            }
-            onExited:
-            {
-                base.hideTooltip();
-            }
-        }
-    }
-
-    Label
-    {
-        function formatRow(items)
-        {
-            var row_html = "<tr>";
-            for(var item = 0; item < items.length; item++)
-            {
-                if (item == 0)
-                {
-                    row_html += "<td valign=\"bottom\">%1</td>".arg(items[item]);
-                }
-                else
-                {
-                    row_html += "<td align=\"right\" valign=\"bottom\">&nbsp;&nbsp;%1</td>".arg(items[item]);
-                }
-            }
-            row_html += "</tr>";
-            return row_html;
-        }
-
-        function getSpecsData()
-        {
-            var lengths = [];
-            var total_length = 0;
-            var weights = [];
-            var total_weight = 0;
-            var costs = [];
-            var total_cost = 0;
-            var some_costs_known = false;
-            var names = [];
-            if(base.printMaterialLengths)
-            {
-                for(var index = 0; index < base.printMaterialLengths.length; index++)
-                {
-                    if(base.printMaterialLengths[index] > 0)
-                    {
-                        names.push(base.printMaterialNames[index]);
-                        lengths.push(base.printMaterialLengths[index].toFixed(2));
-                        weights.push(String(Math.round(base.printMaterialWeights[index])));
-                        var cost = base.printMaterialCosts[index] == undefined ? 0 : base.printMaterialCosts[index].toFixed(2);
-                        costs.push(cost);
-                        if(cost > 0)
-                        {
-                            some_costs_known = true;
-                        }
-
-                        total_length += base.printMaterialLengths[index];
-                        total_weight += base.printMaterialWeights[index];
-                        total_cost += base.printMaterialCosts[index];
-                    }
-                }
-            }
-            if(lengths.length == 0)
-            {
-                lengths = ["0.00"];
-                weights = ["0"];
-                costs = ["0.00"];
-            }
-
-            var tooltip_html = "<b>%1</b><br/><table width=\"100%\">".arg(catalog.i18nc("@label", "Cost specification"));
-            for(var index = 0; index < lengths.length; index++)
-            {
-                tooltip_html += formatRow([
-                    "%1:".arg(names[index]),
-                    catalog.i18nc("@label m for meter", "%1m").arg(lengths[index]),
-                    catalog.i18nc("@label g for grams", "%1g").arg(weights[index]),
-                    "%1&nbsp;%2".arg(UM.Preferences.getValue("cura/currency")).arg(costs[index]),
-                ]);
-            }
-            if(lengths.length > 1)
-            {
-                tooltip_html += formatRow([
-                    catalog.i18nc("@label", "Total:"),
-                    catalog.i18nc("@label m for meter", "%1m").arg(total_length.toFixed(2)),
-                    catalog.i18nc("@label g for grams", "%1g").arg(Math.round(total_weight)),
-                    "%1 %2".arg(UM.Preferences.getValue("cura/currency")).arg(total_cost.toFixed(2)),
-                ]);
-            }
-            tooltip_html += "</table>";
-            tooltipText = tooltip_html;
-
-            return tooltipText
-        }
-
-        id: costSpec
-
-        anchors.left: parent.left
-        anchors.bottom: parent.bottom
-        anchors.bottomMargin: UM.Theme.getSize("thick_margin").height
-        anchors.leftMargin: UM.Theme.getSize("thick_margin").width
-
-        font: UM.Theme.getFont("very_small")
-        renderType: Text.NativeRendering
-        color: UM.Theme.getColor("text_subtext")
-        elide: Text.ElideMiddle
-        width: parent.width
-        property string tooltipText
-        text:
-        {
-            var lengths = [];
-            var weights = [];
-            var costs = [];
-            var someCostsKnown = false;
-            if(base.printMaterialLengths)
-            {
-                for(var index = 0; index < base.printMaterialLengths.length; index++)
-                {
-                    if(base.printMaterialLengths[index] > 0)
-                    {
-                        lengths.push(base.printMaterialLengths[index].toFixed(2));
-                        weights.push(String(Math.round(base.printMaterialWeights[index])));
-                        var cost = base.printMaterialCosts[index] == undefined ? 0 : base.printMaterialCosts[index].toFixed(2);
-                        costs.push(cost);
-                        if(cost > 0)
-                        {
-                            someCostsKnown = true;
-                        }
-                    }
-                }
-            }
-            if(lengths.length == 0)
-            {
-                lengths = ["0.00"];
-                weights = ["0"];
-                costs = ["0.00"];
-            }
-            var result = lengths.join(" + ") + "m / ~ " + weights.join(" + ") + "g";
-            if(someCostsKnown)
-            {
-                result += " / ~ " + costs.join(" + ") + " " + UM.Preferences.getValue("cura/currency");
-            }
-            return result;
-        }
-
-        MouseArea
-        {
-            id: costSpecMouseArea
-            anchors.fill: parent
-            hoverEnabled: true
-
-            onEntered:
-            {
-
-                if(base.printDuration.valid && !base.printDuration.isTotalDurationZero)
-                {
-                    var show_data = costSpec.getSpecsData()
-
-                    base.showTooltip(parent, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), show_data);
-                }
-            }
-            onExited:
-            {
-                base.hideTooltip();
-            }
-        }
-    }
-
-    SaveButton
-    {
-        id: saveButton
-        width: parent.width
-        height: 100 * screenScaleFactor
-        anchors.bottom: parent.bottom
-    }
-}

Some files were not shown because too many files changed in this diff