Merge branch 'replace_controls_1_for_controls_2' into CURA-8684_QtControls_replacement_Buttons,_Actions_&_'Exclusivity'

Conflicts:
	plugins/ImageReader/ConfigUI.qml
	plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
	plugins/PerObjectSettingsTool/SettingPickDialog.qml
	resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml
	resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml
	resources/qml/Preferences/GeneralPage.qml
	resources/qml/Preferences/Materials/MaterialsPage.qml
	resources/qml/Preferences/Materials/MaterialsView.qml
	resources/qml/Preferences/ProfilesPage.qml

These conflicts are all arising from headers/includes being updated at the same time, or from the two branches marking the other one's components as needing OldControls.
This introduced more OldControls markers which don't get marked as merge conflicts by Git. This happens when an element could just be left as the original name but from the new import (e.g. a Button stays a Button in Controls 2, but should be marked as from OldControls on the branch that doesn't update the Button).
This commit is contained in:
Ghostkeeper 2022-01-31 16:53:45 +01:00
commit 6db4a55f6e
No known key found for this signature in database
GPG key ID: D2A8871EE34EC59A
98 changed files with 3984 additions and 4921 deletions

View file

@ -146,8 +146,8 @@ Button
// Using parent.width is fine in fixedWidthMode.
target: buttonText
property: "width"
value: button.fixedWidthMode ? button.width - button.leftPadding - button.rightPadding
: ((maximumWidth != 0 && button.contentWidth > maximumWidth) ? maximumWidth : undefined)
value: button.fixedWidthMode ? (button.width - button.leftPadding - button.rightPadding)
: ((button.maximumWidth != 0 && button.implicitContentWidth > button.maximumWidth) ? (button.maximumWidth - (button.width - button.implicitContentWidth) * 2) : undefined)
}
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2021 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
pragma Singleton
@ -214,15 +214,15 @@ Item
Action
{
id: marketplaceMaterialsAction
text: catalog.i18nc("@action:inmenu", "Add more materials from Marketplace")
text: catalog.i18nc("@action:inmenu Marketplace is a brand name of Ultimaker's, so don't translate.", "Add more materials from Marketplace")
}
Action
{
id: updateProfileAction
enabled: !Cura.MachineManager.stacksHaveErrors && Cura.MachineManager.hasUserSettings && Cura.MachineManager.activeQualityChangesGroup != null
text: catalog.i18nc("@action:inmenu menubar:profile","&Update profile with current settings/overrides")
onTriggered: Cura.ContainerManager.updateQualityChanges()
text: catalog.i18nc("@action:inmenu menubar:profile", "&Update profile with current settings/overrides");
onTriggered: Cura.ContainerManager.updateQualityChanges();
}
Action
@ -479,7 +479,7 @@ Item
Action
{
id: browsePackagesAction
text: catalog.i18nc("@action:menu", "&Marketplace")
text: "&Marketplace"
icon.name: "plugins_browse"
}
}

View file

@ -5,7 +5,7 @@ import QtQuick 2.2
import QtQuick.Controls 2.9
import QtQuick.Window 2.1
import UM 1.1 as UM
import UM 1.5 as UM
UM.Dialog
{
@ -89,81 +89,79 @@ UM.Dialog
anchors.topMargin: UM.Theme.getSize("default_margin").height
}
ScrollView
ListView
{
id: credits
id: projectsList
anchors.top: creditsNotes.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width
height: base.height - y - (2 * UM.Theme.getSize("default_margin").height + closeButton.height)
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ListView
ScrollBar.vertical: UM.ScrollBar
{
id: projectsList
id: projectsListScrollBar
}
width: parent.width
delegate: Row
{
spacing: UM.Theme.getSize("narrow_margin").width
Label
{
text: "<a href='%1' title='%2'>%2</a>".arg(model.url).arg(model.name)
width: (projectsList.width * 0.25) | 0
elide: Text.ElideRight
onLinkActivated: Qt.openUrlExternally(link)
}
Label
{
text: model.description
elide: Text.ElideRight
width: ((projectsList.width * 0.6) | 0) - parent.spacing * 2 - projectsListScrollBar.width
}
Label
{
text: model.license
elide: Text.ElideRight
width: (projectsList.width * 0.15) | 0
}
}
model: ListModel
{
id: projectsModel
}
Component.onCompleted:
{
projectsModel.append({ name: "Cura", description: catalog.i18nc("@label", "Graphical user interface"), license: "LGPLv3", url: "https://github.com/Ultimaker/Cura" });
projectsModel.append({ name: "Uranium", description: catalog.i18nc("@label", "Application framework"), license: "LGPLv3", url: "https://github.com/Ultimaker/Uranium" });
projectsModel.append({ name: "CuraEngine", description: catalog.i18nc("@label", "G-code generator"), license: "AGPLv3", url: "https://github.com/Ultimaker/CuraEngine" });
projectsModel.append({ name: "libArcus", description: catalog.i18nc("@label", "Interprocess communication library"), license: "LGPLv3", url: "https://github.com/Ultimaker/libArcus" });
delegate: Row
{
Label
{
text: "<a href='%1' title='%2'>%2</a>".arg(model.url).arg(model.name)
width: (projectsList.width * 0.25) | 0
elide: Text.ElideRight
onLinkActivated: Qt.openUrlExternally(link)
}
Label
{
text: model.description
elide: Text.ElideRight
width: (projectsList.width * 0.6) | 0
}
Label
{
text: model.license
elide: Text.ElideRight
width: (projectsList.width * 0.15) | 0
}
}
model: ListModel
{
id: projectsModel
}
Component.onCompleted:
{
projectsModel.append({ name: "Cura", description: catalog.i18nc("@label", "Graphical user interface"), license: "LGPLv3", url: "https://github.com/Ultimaker/Cura" });
projectsModel.append({ name: "Uranium", description: catalog.i18nc("@label", "Application framework"), license: "LGPLv3", url: "https://github.com/Ultimaker/Uranium" });
projectsModel.append({ name: "CuraEngine", description: catalog.i18nc("@label", "G-code generator"), license: "AGPLv3", url: "https://github.com/Ultimaker/CuraEngine" });
projectsModel.append({ name: "libArcus", description: catalog.i18nc("@label", "Interprocess communication library"), license: "LGPLv3", url: "https://github.com/Ultimaker/libArcus" });
projectsModel.append({ name: "Python", description: catalog.i18nc("@label", "Programming language"), license: "Python", url: "http://python.org/" });
projectsModel.append({ name: "Qt5", description: catalog.i18nc("@label", "GUI framework"), license: "LGPLv3", url: "https://www.qt.io/" });
projectsModel.append({ name: "PyQt", description: catalog.i18nc("@label", "GUI framework bindings"), license: "GPL", url: "https://riverbankcomputing.com/software/pyqt" });
projectsModel.append({ name: "SIP", description: catalog.i18nc("@label", "C/C++ Binding library"), license: "GPL", url: "https://riverbankcomputing.com/software/sip" });
projectsModel.append({ name: "Protobuf", description: catalog.i18nc("@label", "Data interchange format"), license: "BSD", url: "https://developers.google.com/protocol-buffers" });
projectsModel.append({ name: "SciPy", description: catalog.i18nc("@label", "Support library for scientific computing"), license: "BSD-new", url: "https://www.scipy.org/" });
projectsModel.append({ name: "NumPy", description: catalog.i18nc("@label", "Support library for faster math"), license: "BSD", url: "http://www.numpy.org/" });
projectsModel.append({ name: "NumPy-STL", description: catalog.i18nc("@label", "Support library for handling STL files"), license: "BSD", url: "https://github.com/WoLpH/numpy-stl" });
projectsModel.append({ name: "Shapely", description: catalog.i18nc("@label", "Support library for handling planar objects"), license: "BSD", url: "https://github.com/Toblerity/Shapely" });
projectsModel.append({ name: "Trimesh", description: catalog.i18nc("@label", "Support library for handling triangular meshes"), license: "MIT", url: "https://trimsh.org" });
projectsModel.append({ name: "libSavitar", description: catalog.i18nc("@label", "Support library for handling 3MF files"), license: "LGPLv3", url: "https://github.com/ultimaker/libsavitar" });
projectsModel.append({ name: "libCharon", description: catalog.i18nc("@label", "Support library for file metadata and streaming"), license: "LGPLv3", url: "https://github.com/ultimaker/libcharon" });
projectsModel.append({ name: "PySerial", description: catalog.i18nc("@label", "Serial communication library"), license: "Python", url: "http://pyserial.sourceforge.net/" });
projectsModel.append({ name: "python-zeroconf", description: catalog.i18nc("@label", "ZeroConf discovery library"), license: "LGPL", url: "https://github.com/jstasiak/python-zeroconf" });
projectsModel.append({ name: "Clipper", description: catalog.i18nc("@label", "Polygon clipping library"), license: "Boost", url: "http://www.angusj.com/delphi/clipper.php" });
projectsModel.append({ name: "mypy", description: catalog.i18nc("@Label", "Static type checker for Python"), license: "MIT", url: "http://mypy-lang.org/" });
projectsModel.append({ name: "certifi", description: catalog.i18nc("@Label", "Root Certificates for validating SSL trustworthiness"), license: "MPL", url: "https://github.com/certifi/python-certifi" });
projectsModel.append({ name: "cryptography", description: catalog.i18nc("@Label", "Root Certificates for validating SSL trustworthiness"), license: "APACHE and BSD", url: "https://cryptography.io/" });
projectsModel.append({ name: "Sentry", description: catalog.i18nc("@Label", "Python Error tracking library"), license: "BSD 2-Clause 'Simplified'", url: "https://sentry.io/for/python/" });
projectsModel.append({ name: "libnest2d", description: catalog.i18nc("@label", "Polygon packing library, developed by Prusa Research"), license: "LGPL", url: "https://github.com/tamasmeszaros/libnest2d" });
projectsModel.append({ name: "pynest2d", description: catalog.i18nc("@label", "Python bindings for libnest2d"), license: "LGPL", url: "https://github.com/Ultimaker/pynest2d" });
projectsModel.append({ name: "keyring", description: catalog.i18nc("@label", "Support library for system keyring access"), license: "MIT", url: "https://github.com/jaraco/keyring" });
projectsModel.append({ name: "pywin32", description: catalog.i18nc("@label", "Python extensions for Microsoft Windows"), license: "PSF", url: "https://github.com/mhammond/pywin32" });
projectsModel.append({ name: "Noto Sans", description: catalog.i18nc("@label", "Font"), license: "Apache 2.0", url: "https://www.google.com/get/noto/" });
projectsModel.append({ name: "Font-Awesome-SVG-PNG", description: catalog.i18nc("@label", "SVG icons"), license: "SIL OFL 1.1", url: "https://github.com/encharm/Font-Awesome-SVG-PNG" });
projectsModel.append({ name: "AppImageKit", description: catalog.i18nc("@label", "Linux cross-distribution application deployment"), license: "MIT", url: "https://github.com/AppImage/AppImageKit" });
}
projectsModel.append({ name: "Python", description: catalog.i18nc("@label", "Programming language"), license: "Python", url: "http://python.org/" });
projectsModel.append({ name: "Qt5", description: catalog.i18nc("@label", "GUI framework"), license: "LGPLv3", url: "https://www.qt.io/" });
projectsModel.append({ name: "PyQt", description: catalog.i18nc("@label", "GUI framework bindings"), license: "GPL", url: "https://riverbankcomputing.com/software/pyqt" });
projectsModel.append({ name: "SIP", description: catalog.i18nc("@label", "C/C++ Binding library"), license: "GPL", url: "https://riverbankcomputing.com/software/sip" });
projectsModel.append({ name: "Protobuf", description: catalog.i18nc("@label", "Data interchange format"), license: "BSD", url: "https://developers.google.com/protocol-buffers" });
projectsModel.append({ name: "SciPy", description: catalog.i18nc("@label", "Support library for scientific computing"), license: "BSD-new", url: "https://www.scipy.org/" });
projectsModel.append({ name: "NumPy", description: catalog.i18nc("@label", "Support library for faster math"), license: "BSD", url: "http://www.numpy.org/" });
projectsModel.append({ name: "NumPy-STL", description: catalog.i18nc("@label", "Support library for handling STL files"), license: "BSD", url: "https://github.com/WoLpH/numpy-stl" });
projectsModel.append({ name: "Trimesh", description: catalog.i18nc("@label", "Support library for handling triangular meshes"), license: "MIT", url: "https://trimsh.org" });
projectsModel.append({ name: "libSavitar", description: catalog.i18nc("@label", "Support library for handling 3MF files"), license: "LGPLv3", url: "https://github.com/ultimaker/libsavitar" });
projectsModel.append({ name: "libCharon", description: catalog.i18nc("@label", "Support library for file metadata and streaming"), license: "LGPLv3", url: "https://github.com/ultimaker/libcharon" });
projectsModel.append({ name: "PySerial", description: catalog.i18nc("@label", "Serial communication library"), license: "Python", url: "http://pyserial.sourceforge.net/" });
projectsModel.append({ name: "python-zeroconf", description: catalog.i18nc("@label", "ZeroConf discovery library"), license: "LGPL", url: "https://github.com/jstasiak/python-zeroconf" });
projectsModel.append({ name: "Clipper", description: catalog.i18nc("@label", "Polygon clipping library"), license: "Boost", url: "http://www.angusj.com/delphi/clipper.php" });
projectsModel.append({ name: "Pyclipper", description: catalog.i18nc("@label", "Python bindings for Clipper"), license: "MIT", url: "https://github.com/fonttools/pyclipper" });
projectsModel.append({ name: "mypy", description: catalog.i18nc("@Label", "Static type checker for Python"), license: "MIT", url: "http://mypy-lang.org/" });
projectsModel.append({ name: "certifi", description: catalog.i18nc("@Label", "Root Certificates for validating SSL trustworthiness"), license: "MPL", url: "https://github.com/certifi/python-certifi" });
projectsModel.append({ name: "cryptography", description: catalog.i18nc("@Label", "Root Certificates for validating SSL trustworthiness"), license: "APACHE and BSD", url: "https://cryptography.io/" });
projectsModel.append({ name: "Sentry", description: catalog.i18nc("@Label", "Python Error tracking library"), license: "BSD 2-Clause 'Simplified'", url: "https://sentry.io/for/python/" });
projectsModel.append({ name: "libnest2d", description: catalog.i18nc("@label", "Polygon packing library, developed by Prusa Research"), license: "LGPL", url: "https://github.com/tamasmeszaros/libnest2d" });
projectsModel.append({ name: "pynest2d", description: catalog.i18nc("@label", "Python bindings for libnest2d"), license: "LGPL", url: "https://github.com/Ultimaker/pynest2d" });
projectsModel.append({ name: "keyring", description: catalog.i18nc("@label", "Support library for system keyring access"), license: "MIT", url: "https://github.com/jaraco/keyring" });
projectsModel.append({ name: "pywin32", description: catalog.i18nc("@label", "Python extensions for Microsoft Windows"), license: "PSF", url: "https://github.com/mhammond/pywin32" });
projectsModel.append({ name: "Noto Sans", description: catalog.i18nc("@label", "Font"), license: "Apache 2.0", url: "https://www.google.com/get/noto/" });
projectsModel.append({ name: "Font-Awesome-SVG-PNG", description: catalog.i18nc("@label", "SVG icons"), license: "SIL OFL 1.1", url: "https://github.com/encharm/Font-Awesome-SVG-PNG" });
projectsModel.append({ name: "AppImageKit", description: catalog.i18nc("@label", "Linux cross-distribution application deployment"), license: "MIT", url: "https://github.com/AppImage/AppImageKit" });
}
}

View file

@ -1,6 +1,7 @@
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
//Copyright (c) 2022 Ultimaker B.V.
//Cura is released under the terms of the LGPLv3 or higher.
import Qt.labs.qmlmodels 1.0
import QtQuick 2.1
import QtQuick.Controls 1.1 as OldControls
import QtQuick.Controls 2.15
@ -8,7 +9,7 @@ import QtQuick.Dialogs 1.2
import QtQuick.Window 2.1
import UM 1.2 as UM
import Cura 1.0 as Cura
import Cura 1.6 as Cura
UM.Dialog
{
@ -20,6 +21,8 @@ UM.Dialog
minimumWidth: UM.Theme.getSize("popup_dialog").width
minimumHeight: UM.Theme.getSize("popup_dialog").height
width: minimumWidth
height: minimumHeight
property var changesModel: Cura.UserChangesModel{ id: userChangesModel}
onVisibilityChanged:
{
@ -70,72 +73,31 @@ UM.Dialog
anchors.bottom: optionRow.top
anchors.left: parent.left
anchors.right: parent.right
OldControls.TableView
Cura.TableView
{
anchors.fill: parent
height: base.height - 150
id: tableView
Component
anchors
{
id: labelDelegate
Label
{
property var extruder_name: userChangesModel.getItem(styleData.row).extruder
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.right: parent.right
elide: Text.ElideRight
font: UM.Theme.getFont("system")
text:
{
var result = styleData.value
if (extruder_name != "")
{
result += " (" + extruder_name + ")"
}
return result
}
}
top: parent.top
left: parent.left
right: parent.right
}
height: base.height - 150
Component
columnHeaders: [
catalog.i18nc("@title:column", "Profile settings"),
Cura.MachineManager.activeQualityDisplayNameMap["main"],
catalog.i18nc("@title:column", "Current changes")
]
model: TableModel
{
id: defaultDelegate
Label
{
text: styleData.value
font: UM.Theme.getFont("system")
}
TableModelColumn { display: "label" }
TableModelColumn { display: "original_value" }
TableModelColumn { display: "user_value" }
rows: userChangesModel.items
}
OldControls.TableViewColumn
{
role: "label"
title: catalog.i18nc("@title:column", "Profile settings")
delegate: labelDelegate
width: (tableView.width * 0.4) | 0
}
OldControls.TableViewColumn
{
role: "original_value"
title: Cura.MachineManager.activeQualityDisplayNameMap["main"]
width: (tableView.width * 0.3) | 0
delegate: defaultDelegate
}
OldControls.TableViewColumn
{
role: "user_value"
title: catalog.i18nc("@title:column", "Current changes")
width: (tableView.width * 0.3) | 0
}
section.property: "category"
section.delegate: Label
{
text: section
font.bold: true
}
model: userChangesModel
sectionRole: "category"
}
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2021 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
@ -6,7 +6,7 @@ import QtQuick.Controls 2.9
import QtQuick.Layouts 1.3
import QtQuick.Window 2.2
import UM 1.2 as UM
import UM 1.5 as UM
import Cura 1.0 as Cura
UM.Dialog
@ -81,6 +81,19 @@ UM.Dialog
bottom: controls.top
bottomMargin: UM.Theme.getSize("default_margin").height
}
ScrollBar.vertical: UM.ScrollBar
{
parent: scroll
anchors
{
top: parent.top
right: parent.right
bottom: parent.bottom
}
}
clip: true
ColumnLayout
{
spacing: UM.Theme.getSize("default_margin").height

View file

@ -1,11 +1,11 @@
// Copyright (c) 2020 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import UM 1.3 as UM
import UM 1.5 as UM
import Cura 1.1 as Cura
@ -45,7 +45,7 @@ UM.TooltipArea
renderType: Text.NativeRendering
}
ScrollView
Flickable
{
anchors.top: titleLabel.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
@ -53,26 +53,9 @@ UM.TooltipArea
anchors.left: parent.left
anchors.right: parent.right
background: Rectangle
{
color: UM.Theme.getColor("main_background")
anchors.fill: parent
ScrollBar.vertical: UM.ScrollBar {}
border.color:
{
if (!gcodeTextArea.enabled)
{
return UM.Theme.getColor("setting_control_disabled_border")
}
if (gcodeTextArea.hovered || gcodeTextArea.activeFocus)
{
return UM.Theme.getColor("setting_control_border_highlight")
}
return UM.Theme.getColor("setting_control_border")
}
}
TextArea
TextArea.flickable: TextArea
{
id: gcodeTextArea
@ -92,6 +75,27 @@ UM.TooltipArea
propertyProvider.setPropertyValue("value", text)
}
}
background: Rectangle
{
color: UM.Theme.getColor("main_background")
anchors.fill: parent
anchors.margins: -border.width //Wrap the border around the parent.
border.color:
{
if (!gcodeTextArea.enabled)
{
return UM.Theme.getColor("setting_control_disabled_border")
}
if (gcodeTextArea.hovered || gcodeTextArea.activeFocus)
{
return UM.Theme.getColor("setting_control_border_highlight")
}
return UM.Theme.getColor("setting_control_border")
}
border.width: UM.Theme.getSize("default_lining").width
}
}
}
}

View file

@ -1,10 +1,10 @@
// Copyright (c) 2018 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.3
import UM 1.4 as UM
import UM 1.5 as UM
import Cura 1.0 as Cura
Item
@ -67,18 +67,14 @@ Item
contentHeight: configurationList.height
clip: true
ScrollBar.vertical.policy: (configurationList.height > maximumHeight) ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff //The AsNeeded policy also hides it when the cursor is away, and we don't want that.
ScrollBar.vertical.background: Rectangle
{
implicitWidth: UM.Theme.getSize("scrollbar").width
radius: width / 2
color: UM.Theme.getColor("scrollbar_background")
}
ScrollBar.vertical.contentItem: Rectangle
{
implicitWidth: UM.Theme.getSize("scrollbar").width
radius: width / 2
color: UM.Theme.getColor(parent.pressed ? "scrollbar_handle_down" : parent.hovered ? "scrollbar_handle_hover" : "scrollbar_handle")
ScrollBar.vertical: UM.ScrollBar {
parent: container
anchors
{
top: parent.top
right: parent.right
bottom: parent.bottom
}
}
ButtonGroup

View file

@ -1,5 +1,5 @@
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
//Copyright (c) 2022 Ultimaker B.V.
//Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.6
import QtQuick.Controls 2.0
@ -94,6 +94,7 @@ Item
model: extrudersModel
delegate: UM.TabRowButton
{
checked: model.index == 0
contentItem: Item
{
Cura.ExtruderIcon

View file

@ -25,6 +25,7 @@ Cura.Menu
id: openMenu
action: Cura.Actions.open
visible: base.fileProviderModel.count == 1
enabled: base.fileProviderModel.count == 1
}
OpenFilesMenu
@ -42,7 +43,7 @@ Cura.Menu
shortcut: StandardKey.Save
text: catalog.i18nc("@title:menu menubar:file", "&Save Project...")
visible: saveProjectMenu.model.count == 1
enabled: UM.WorkspaceFileHandler.enabled
enabled: UM.WorkspaceFileHandler.enabled && saveProjectMenu.model.count == 1
onTriggered:
{
var args = { "filter_by_machine": false, "file_type": "workspace", "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml" };

View file

@ -40,9 +40,8 @@ Cura.Menu
UM.OutputDeviceManager.requestWriteToDevice(model.id, PrintInformation.jobName, args)
}
}
// Unassign the shortcuts when the submenu is invisible (i.e. when there is only one project output device) to avoid ambiguous shortcuts.
// When there is only the LocalFileOutputDevice, the Ctrl+S shortcut is assigned to the saveWorkspaceMenu MenuItem
shortcut: saveProjectMenu.visible ? model.shortcut : ""
shortcut: model.shortcut
enabled: saveProjectMenu.shouldBeVisible
}
onObjectAdded: saveProjectMenu.insertItem(index, object)
onObjectRemoved: saveProjectMenu.removeItem(object)

View file

@ -1,4 +1,4 @@
// Copyright (c) 2020 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
@ -76,7 +76,7 @@ Item
id: contents
width: parent.width
visible: objectSelector.opened
height: visible ? listView.height : 0
height: visible ? listView.height + border.width * 2 : 0
color: UM.Theme.getColor("main_background")
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
@ -99,23 +99,22 @@ Item
ListView
{
id: listView
clip: true
anchors
{
left: parent.left
right: parent.right
top: parent.top
margins: UM.Theme.getSize("default_lining").width
}
ScrollBar.vertical: ScrollBar
{
hoverEnabled: true
}
property real maximumHeight: UM.Theme.getSize("objects_menu_size").height
height: Math.min(contentHeight, maximumHeight)
ScrollBar.vertical: UM.ScrollBar
{
id: scrollBar
}
clip: true
model: Cura.ObjectsModel {}
delegate: ObjectItemButton
@ -128,7 +127,7 @@ Item
value: model.selected
}
text: model.name
width: listView.width
width: listView.width - scrollBar.width
property bool outsideBuildArea: model.outside_build_area
property int perObjectSettingsCount: model.per_object_settings_count
property string meshType: model.mesh_type

View file

@ -1,12 +1,11 @@
// Copyright (c) 2020 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 1.1 as OldControls
import QtQuick.Controls 2.3
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.1
import UM 1.1 as UM
import UM 1.5 as UM
import Cura 1.1 as Cura
UM.PreferencesPage
@ -15,6 +14,8 @@ UM.PreferencesPage
title: catalog.i18nc("@title:tab", "General")
id: generalPreferencesPage
width: parent.width
function setDefaultLanguage(languageCode)
{
//loops through the languageList and sets the language using the languageCode
@ -124,16 +125,28 @@ UM.PreferencesPage
pluginNotificationsUpdateCheckbox.checked = boolCheck(UM.Preferences.getValue("info/automatic_plugin_update_check"))
}
OldControls.ScrollView
ScrollView
{
id: preferencesScrollView
width: parent.width
height: parent.height
ScrollBar.vertical: UM.ScrollBar
{
id: preferencesScrollBar
parent: preferencesScrollView
anchors
{
top: parent.top
bottom: parent.bottom
right: parent.right
}
}
Column
{
//: Language selection label
UM.I18nCatalog{id: catalog; name: "cura"}
width: preferencesScrollView.width - preferencesScrollBar.width
Label
{
@ -160,16 +173,14 @@ UM.PreferencesPage
Component.onCompleted:
{
append({ text: "English", code: "en_US" })
// append({ text: "Čeština", code: "cs_CZ" })
append({ text: "Čeština", code: "cs_CZ" })
append({ text: "Deutsch", code: "de_DE" })
append({ text: "Español", code: "es_ES" })
//Finnish is disabled for being incomplete: append({ text: "Suomi", code: "fi_FI" })
append({ text: "Français", code: "fr_FR" })
append({ text: "Italiano", code: "it_IT" })
append({ text: "日本語", code: "ja_JP" })
append({ text: "한국어", code: "ko_KR" })
append({ text: "Nederlands", code: "nl_NL" })
//Polish is disabled for being incomplete: append({ text: "Polski", code: "pl_PL" })
append({ text: "Português do Brasil", code: "pt_BR" })
append({ text: "Português", code: "pt_PT" })
append({ text: "Русский", code: "ru_RU" })
@ -182,6 +193,12 @@ UM.PreferencesPage
{
append({ text: "Pirate", code: "en_7S" })
}
// incomplete and/or abandoned
append({ text: catalog.i18nc("@heading", "-- incomplete --"), code: "" })
append({ text: "Magyar", code: "hu_HU" })
append({ text: "Suomi", code: "fi_FI" })
append({ text: "Polski", code: "pl_PL" })
}
}
@ -193,8 +210,7 @@ UM.PreferencesPage
model: languageList
Layout.fillWidth: true
currentIndex:
{
function setCurrentIndex() {
var code = UM.Preferences.getValue("general/language");
for(var i = 0; i < languageList.count; ++i)
{
@ -204,13 +220,23 @@ UM.PreferencesPage
}
}
}
onActivated: UM.Preferences.setValue("general/language", model.get(index).code)
currentIndex: setCurrentIndex()
onActivated: if (model.get(index).code != "")
{
UM.Preferences.setValue("general/language", model.get(index).code);
}
else
{
currentIndex = setCurrentIndex();
}
}
Label
{
id: currencyLabel
text: catalog.i18nc("@label","Currency:")
text: catalog.i18nc("@label", "Currency:")
}
TextField

View file

@ -1,13 +1,12 @@
// Copyright (c) 2021 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4 as OldControls
import QtQuick.Controls 2.1
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2
import UM 1.2 as UM
import UM 1.5 as UM
import Cura 1.5 as Cura
Item
@ -208,7 +207,8 @@ Item
}
}
Item {
Item
{
id: contentsItem
anchors
{
@ -262,7 +262,7 @@ Item
elide: Text.ElideRight
}
OldControls.ScrollView
ScrollView
{
id: materialScrollView
anchors
@ -272,22 +272,26 @@ Item
bottom: parent.bottom
left: parent.left
}
Rectangle
{
parent: viewport
anchors.fill: parent
color: palette.light
}
width: (parent.width * 0.4) | 0
frameVisible: true
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
clip: true
ScrollBar.vertical: UM.ScrollBar
{
id: materialScrollBar
parent: materialScrollView
anchors
{
top: parent.top
right: parent.right
bottom: parent.bottom
}
}
contentHeight: materialListView.height //For some reason, this is not determined automatically with this ScrollView. Very weird!
MaterialsList
{
id: materialListView
width: materialScrollView.viewport.width
width: materialScrollView.width - materialScrollBar.width
}
}

View file

@ -1,4 +1,4 @@
//Copyright (c) 2021 Ultimaker B.V.
//Copyright (c) 2022 Ultimaker B.V.
//Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.15
@ -253,204 +253,202 @@ Window
onClicked: Qt.openUrlExternally("https://support.ultimaker.com/hc/en-us/articles/360012019239?utm_source=cura&utm_medium=software&utm_campaign=sync-material-wizard-troubleshoot-cloud-printer")
}
}
ScrollView
ListView
{
id: printerListScrollView
id: printerList
width: parent.width
Layout.preferredWidth: width
Layout.fillHeight: true
clip: true
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ListView
ScrollBar.vertical: UM.ScrollBar
{
id: printerList
width: parent.width
spacing: UM.Theme.getSize("default_margin").height
id: printerListScrollBar
}
spacing: UM.Theme.getSize("default_margin").height
model: cloudPrinterList
delegate: Rectangle
model: cloudPrinterList
delegate: Rectangle
{
id: delegateContainer
color: "transparent"
border.color: UM.Theme.getColor("lining")
border.width: UM.Theme.getSize("default_lining").width
width: printerList.width - printerListScrollBar.width
height: UM.Theme.getSize("card").height
property string syncStatus:
{
id: delegateContainer
color: "transparent"
border.color: UM.Theme.getColor("lining")
border.width: UM.Theme.getSize("default_lining").width
width: printerListScrollView.width
height: UM.Theme.getSize("card").height
property string syncStatus:
var printer_id = model.metadata["host_guid"]
if(syncModel.printerStatus[printer_id] === undefined) //No status information available. Could be added after we started syncing.
{
var printer_id = model.metadata["host_guid"]
if(syncModel.printerStatus[printer_id] === undefined) //No status information available. Could be added after we started syncing.
{
return "idle";
}
return syncModel.printerStatus[printer_id];
return "idle";
}
return syncModel.printerStatus[printer_id];
}
Cura.IconWithText
{
anchors
{
verticalCenter: parent.verticalCenter
left: parent.left
leftMargin: Math.round(parent.height - height) / 2 //Equal margin on the left as above and below.
right: parent.right
rightMargin: Math.round(parent.height - height) / 2
}
Cura.IconWithText
{
anchors
{
verticalCenter: parent.verticalCenter
left: parent.left
leftMargin: Math.round(parent.height - height) / 2 //Equal margin on the left as above and below.
right: parent.right
rightMargin: Math.round(parent.height - height) / 2
}
text: model.name
font: UM.Theme.getFont("medium")
text: model.name
font: UM.Theme.getFont("medium")
source: UM.Theme.getIcon("Printer", "medium")
iconColor: UM.Theme.getColor("machine_selector_printer_icon")
iconSize: UM.Theme.getSize("machine_selector_icon").width
//Printer status badge (always cloud, but whether it's online or offline).
UM.RecolorImage
{
width: UM.Theme.getSize("printer_status_icon").width
height: UM.Theme.getSize("printer_status_icon").height
anchors
{
bottom: parent.bottom
bottomMargin: -Math.round(height / 6)
left: parent.left
leftMargin: parent.iconSize - Math.round(width * 5 / 6)
}
source: UM.Theme.getIcon("CloudBadge", "low")
color: UM.Theme.getColor("primary")
//Make a themeable circle in the background so we can change it in other themes.
Rectangle
{
anchors.centerIn: parent
width: parent.width - 1.5 //1.5 pixels smaller (at least sqrt(2), regardless of pixel scale) so that the circle doesn't show up behind the icon due to anti-aliasing.
height: parent.height - 1.5
radius: width / 2
color: UM.Theme.getColor("connection_badge_background")
z: parent.z - 1
}
}
}
source: UM.Theme.getIcon("Printer", "medium")
iconColor: UM.Theme.getColor("machine_selector_printer_icon")
iconSize: UM.Theme.getSize("machine_selector_icon").width
//Printer status badge (always cloud, but whether it's online or offline).
UM.RecolorImage
{
id: printerSpinner
width: UM.Theme.getSize("section_icon").width
height: width
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: Math.round((parent.height - height) / 2) //Same margin on the right as above and below.
width: UM.Theme.getSize("printer_status_icon").width
height: UM.Theme.getSize("printer_status_icon").height
anchors
{
bottom: parent.bottom
bottomMargin: -Math.round(height / 6)
left: parent.left
leftMargin: parent.iconSize - Math.round(width * 5 / 6)
}
visible: delegateContainer.syncStatus === "uploading"
source: UM.Theme.getIcon("ArrowDoubleCircleRight")
source: UM.Theme.getIcon("CloudBadge", "low")
color: UM.Theme.getColor("primary")
RotationAnimator
//Make a themeable circle in the background so we can change it in other themes.
Rectangle
{
target: printerSpinner
from: 0
to: 360
duration: 1000
loops: Animation.Infinite
running: true
anchors.centerIn: parent
width: parent.width - 1.5 //1.5 pixels smaller (at least sqrt(2), regardless of pixel scale) so that the circle doesn't show up behind the icon due to anti-aliasing.
height: parent.height - 1.5
radius: width / 2
color: UM.Theme.getColor("connection_badge_background")
z: parent.z - 1
}
}
UM.StatusIcon
{
width: UM.Theme.getSize("section_icon").width
height: width
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: Math.round((parent.height - height) / 2) //Same margin on the right as above and below.
visible: delegateContainer.syncStatus === "failed" || delegateContainer.syncStatus === "success"
status: delegateContainer.syncStatus === "success" ? UM.StatusIcon.Status.POSITIVE : UM.StatusIcon.Status.ERROR
}
}
footer: Item
UM.RecolorImage
{
width: printerListScrollView.width
height: {
if(!visible)
{
return 0;
}
let h = UM.Theme.getSize("card").height + printerListTroubleshooting.height + UM.Theme.getSize("default_margin").height * 2; //1 margin between content and footer, 1 for troubleshooting link.
return h;
}
visible: includeOfflinePrinterList.count - cloudPrinterList.count > 0 && typeof syncModel !== "undefined" && syncModel.exportUploadStatus === "idle"
Rectangle
id: printerSpinner
width: UM.Theme.getSize("section_icon").width
height: width
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: Math.round((parent.height - height) / 2) //Same margin on the right as above and below.
visible: delegateContainer.syncStatus === "uploading"
source: UM.Theme.getIcon("ArrowDoubleCircleRight")
color: UM.Theme.getColor("primary")
RotationAnimator
{
anchors.fill: parent
anchors.topMargin: UM.Theme.getSize("default_margin").height
target: printerSpinner
from: 0
to: 360
duration: 1000
loops: Animation.Infinite
running: true
}
}
UM.StatusIcon
{
width: UM.Theme.getSize("section_icon").width
height: width
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: Math.round((parent.height - height) / 2) //Same margin on the right as above and below.
border.color: UM.Theme.getColor("lining")
border.width: UM.Theme.getSize("default_lining").width
color: "transparent"
visible: delegateContainer.syncStatus === "failed" || delegateContainer.syncStatus === "success"
status: delegateContainer.syncStatus === "success" ? UM.StatusIcon.Status.POSITIVE : UM.StatusIcon.Status.ERROR
}
}
Row
footer: Item
{
width: printerList.width - printerListScrollBar
height: {
if(!visible)
{
return 0;
}
let h = UM.Theme.getSize("card").height + printerListTroubleshooting.height + UM.Theme.getSize("default_margin").height * 2; //1 margin between content and footer, 1 for troubleshooting link.
return h;
}
visible: includeOfflinePrinterList.count - cloudPrinterList.count > 0 && typeof syncModel !== "undefined" && syncModel.exportUploadStatus === "idle"
Rectangle
{
anchors.fill: parent
anchors.topMargin: UM.Theme.getSize("default_margin").height
border.color: UM.Theme.getColor("lining")
border.width: UM.Theme.getSize("default_lining").width
color: "transparent"
Row
{
anchors
{
anchors
fill: parent
margins: Math.round(UM.Theme.getSize("card").height - UM.Theme.getSize("machine_selector_icon").width) / 2 //Same margin as in other cards.
}
spacing: UM.Theme.getSize("default_margin").width
UM.StatusIcon
{
id: infoIcon
width: UM.Theme.getSize("section_icon").width
height: width
//Fake anchor.verticalCenter: printersMissingText.verticalCenter, since we can't anchor to things that aren't siblings.
anchors.top: parent.top
anchors.topMargin: Math.round(printersMissingText.height / 2 - height / 2)
status: UM.StatusIcon.Status.WARNING
}
Column
{
//Fill the total width. Can't use layouts because we need the anchors for vertical alignment.
width: parent.width - infoIcon.width - refreshListButton.width - parent.spacing * 2
spacing: UM.Theme.getSize("default_margin").height
UM.Label
{
fill: parent
margins: Math.round(UM.Theme.getSize("card").height - UM.Theme.getSize("machine_selector_icon").width) / 2 //Same margin as in other cards.
id: printersMissingText
text: catalog.i18nc("@text Asking the user whether printers are missing in a list.", "Printers missing?")
+ "\n"
+ catalog.i18nc("@text", "Make sure all your printers are turned ON and connected to Digital Factory.")
font: UM.Theme.getFont("medium")
elide: Text.ElideRight
}
spacing: UM.Theme.getSize("default_margin").width
UM.StatusIcon
Cura.TertiaryButton
{
id: infoIcon
width: UM.Theme.getSize("section_icon").width
height: width
//Fake anchor.verticalCenter: printersMissingText.verticalCenter, since we can't anchor to things that aren't siblings.
anchors.top: parent.top
anchors.topMargin: Math.round(printersMissingText.height / 2 - height / 2)
id: printerListTroubleshooting
leftPadding: 0 //Want to visually align this to the text.
status: UM.StatusIcon.Status.WARNING
text: catalog.i18nc("@button", "Troubleshooting")
iconSource: UM.Theme.getIcon("LinkExternal")
onClicked: Qt.openUrlExternally("https://support.ultimaker.com/hc/en-us/articles/360012019239?utm_source=cura&utm_medium=software&utm_campaign=sync-material-wizard-troubleshoot-cloud-printer")
}
}
Column
{
//Fill the total width. Can't use layouts because we need the anchors for vertical alignment.
width: parent.width - infoIcon.width - refreshListButton.width - parent.spacing * 2
Cura.SecondaryButton
{
id: refreshListButton
//Fake anchor.verticalCenter: printersMissingText.verticalCenter, since we can't anchor to things that aren't siblings.
anchors.top: parent.top
anchors.topMargin: Math.round(printersMissingText.height / 2 - height / 2)
spacing: UM.Theme.getSize("default_margin").height
UM.Label
{
id: printersMissingText
text: catalog.i18nc("@text Asking the user whether printers are missing in a list.", "Printers missing?")
+ "\n"
+ catalog.i18nc("@text", "Make sure all your printers are turned ON and connected to Digital Factory.")
font: UM.Theme.getFont("medium")
elide: Text.ElideRight
}
Cura.TertiaryButton
{
id: printerListTroubleshooting
leftPadding: 0 //Want to visually align this to the text.
text: catalog.i18nc("@button", "Troubleshooting")
iconSource: UM.Theme.getIcon("LinkExternal")
onClicked: Qt.openUrlExternally("https://support.ultimaker.com/hc/en-us/articles/360012019239?utm_source=cura&utm_medium=software&utm_campaign=sync-material-wizard-troubleshoot-cloud-printer")
}
}
Cura.SecondaryButton
{
id: refreshListButton
//Fake anchor.verticalCenter: printersMissingText.verticalCenter, since we can't anchor to things that aren't siblings.
anchors.top: parent.top
anchors.topMargin: Math.round(printersMissingText.height / 2 - height / 2)
text: catalog.i18nc("@button", "Refresh List")
iconSource: UM.Theme.getIcon("ArrowDoubleCircleRight")
onClicked: Cura.API.account.sync(true)
}
text: catalog.i18nc("@button", "Refresh List")
iconSource: UM.Theme.getIcon("ArrowDoubleCircleRight")
onClicked: Cura.API.account.sync(true)
}
}
}

View file

@ -2,16 +2,16 @@
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Controls 2.15
import QtQuick.Controls 1.4 as OldControls
import QtQuick.Dialogs 1.2
import UM 1.2 as UM
import UM 1.5 as UM
import Cura 1.0 as Cura
import ".." // Access to ReadOnlyTextArea.qml
OldControls.TabView
Item
{
id: base
@ -68,437 +68,457 @@ OldControls.TabView
}
}
OldControls.Tab
UM.TabRow
{
title: catalog.i18nc("@title", "Information")
anchors.margins: UM.Theme.getSize("default_margin").width
OldControls.ScrollView
id: pageSelectorTabRow
UM.TabRowButton
{
id: scrollView
anchors.fill: parent
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
flickableItem.flickableDirection: Flickable.VerticalFlick
frameVisible: true
property real columnWidth: (viewport.width * 0.5 - UM.Theme.getSize("default_margin").width) | 0
Flow
{
id: containerGrid
x: UM.Theme.getSize("default_margin").width
y: UM.Theme.getSize("default_lining").height
width: base.width
property real rowHeight: brandTextField.height + UM.Theme.getSize("default_lining").height
MessageDialog
{
id: confirmDiameterChangeDialog
icon: StandardIcon.Question;
title: catalog.i18nc("@title:window", "Confirm Diameter Change")
text: catalog.i18nc("@label (%1 is a number)", "The new filament diameter is set to %1 mm, which is not compatible with the current extruder. Do you wish to continue?".arg(new_diameter_value))
standardButtons: StandardButton.Yes | StandardButton.No
modality: Qt.ApplicationModal
property var new_diameter_value: null;
property var old_diameter_value: null;
property var old_approximate_diameter_value: null;
onYes:
{
base.setMetaDataEntry("approximate_diameter", old_approximate_diameter_value, getApproximateDiameter(new_diameter_value).toString());
base.setMetaDataEntry("properties/diameter", properties.diameter, new_diameter_value);
// CURA-6868 Make sure to update the extruder to user a diameter-compatible material.
Cura.MachineManager.updateMaterialWithVariant()
base.resetSelectedMaterial()
}
onNo:
{
base.properties.diameter = old_diameter_value;
diameterSpinBox.value = Qt.binding(function() { return base.properties.diameter })
}
onRejected: no()
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") }
ReadOnlyTextField
{
id: displayNameTextField;
width: scrollView.columnWidth;
text: properties.name;
readOnly: !base.editingEnabled;
onEditingFinished: base.updateMaterialDisplayName(properties.name, text)
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Brand") }
ReadOnlyTextField
{
id: brandTextField;
width: scrollView.columnWidth;
text: properties.brand;
readOnly: !base.editingEnabled;
onEditingFinished: base.updateMaterialBrand(properties.brand, text)
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Material Type") }
ReadOnlyTextField
{
id: materialTypeField;
width: scrollView.columnWidth;
text: properties.material;
readOnly: !base.editingEnabled;
onEditingFinished: base.updateMaterialType(properties.material, text)
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") }
Row
{
width: scrollView.columnWidth
height: parent.rowHeight
spacing: Math.round(UM.Theme.getSize("default_margin").width / 2)
// color indicator square
Rectangle
{
id: colorSelector
color: properties.color_code
width: Math.round(colorLabel.height * 0.75)
height: Math.round(colorLabel.height * 0.75)
border.width: UM.Theme.getSize("default_lining").height
anchors.verticalCenter: parent.verticalCenter
// open the color selection dialog on click
MouseArea
{
anchors.fill: parent
onClicked: colorDialog.open()
enabled: base.editingEnabled
}
}
// pretty color name text field
ReadOnlyTextField
{
id: colorLabel;
width: parent.width - colorSelector.width - parent.spacing
text: properties.color_name;
readOnly: !base.editingEnabled
onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text)
}
// popup dialog to select a new color
// if successful it sets the properties.color_code value to the new color
ColorDialog
{
id: colorDialog
color: properties.color_code
onAccepted: base.setMetaDataEntry("color_code", properties.color_code, color)
}
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
Label { width: parent.width; height: parent.rowHeight; font.bold: true; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Properties") }
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") }
ReadOnlySpinBox
{
id: densitySpinBox
width: scrollView.columnWidth
value: properties.density
decimals: 2
suffix: " g/cm³"
stepSize: 0.01
readOnly: !base.editingEnabled
onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value)
onValueChanged: updateCostPerMeter()
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") }
ReadOnlySpinBox
{
id: diameterSpinBox
width: scrollView.columnWidth
value: properties.diameter
decimals: 2
suffix: " mm"
stepSize: 0.01
readOnly: !base.editingEnabled
onEditingFinished:
{
// This does not use a SettingPropertyProvider, because we need to make the change to all containers
// which derive from the same base_file
var old_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "properties/diameter");
var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter");
var new_approximate_diameter = getApproximateDiameter(value);
if (new_approximate_diameter != Cura.ExtruderManager.getActiveExtruderStack().approximateMaterialDiameter)
{
confirmDiameterChangeDialog.old_diameter_value = old_diameter;
confirmDiameterChangeDialog.new_diameter_value = value;
confirmDiameterChangeDialog.old_approximate_diameter_value = old_approximate_diameter;
confirmDiameterChangeDialog.open()
}
else {
base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, getApproximateDiameter(value).toString());
base.setMetaDataEntry("properties/diameter", properties.diameter, value);
}
}
onValueChanged: updateCostPerMeter()
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") }
SpinBox
{
id: spoolCostSpinBox
width: scrollView.columnWidth
value: base.getMaterialPreferenceValue(properties.guid, "spool_cost")
to: 100000000
editable: true
contentItem: TextField
{
text: spoolCostSpinBox.textFromValue(spoolCostSpinBox.value, spoolCostSpinBox.locale)
selectByMouse: true
background: Item {}
validator: RegExpValidator { regExp: new RegExp("^" + base.currency + " ([0-9]+[.]?[0-9]*)?$") }
}
property int decimals: 2
valueFromText: function(text) {
// remove all non-number tokens from input string so value can be parsed correctly
var value = Number(text.replace(",", ".").replace(/[^0-9.]+/g, ""));
var precision = Math.pow(10, spoolCostSpinBox.decimals);
return Math.round(value * precision) / precision;
}
textFromValue: function(value) {
return base.currency + " " + value.toFixed(spoolCostSpinBox.decimals)
}
onValueChanged:
{
base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value, decimals))
updateCostPerMeter()
}
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") }
SpinBox
{
id: spoolWeightSpinBox
width: scrollView.columnWidth
value: base.getMaterialPreferenceValue(properties.guid, "spool_weight", Cura.ContainerManager.getContainerMetaDataEntry(properties.container_id, "properties/weight"))
stepSize: 100
to: 10000
editable: true
contentItem: TextField
{
text: spoolWeightSpinBox.textFromValue(spoolWeightSpinBox.value, spoolWeightSpinBox.locale)
selectByMouse: true
background: Item {}
validator: RegExpValidator { regExp: new RegExp("^([0-9]+[.]?[0-9]*)? g$") }
}
valueFromText: function(text, locale) {
// remove all non-number tokens from input string so value can be parsed correctly
var value = Number(text.replace(",", ".").replace(/[^0-9.]+/g, ""));
return Math.round(value);
}
textFromValue: function(value, locale) {
return value + " g"
}
onValueChanged:
{
base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value))
updateCostPerMeter()
}
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") }
Label
{
width: scrollView.columnWidth
text: "~ %1 m".arg(Math.round(base.spoolLength))
verticalAlignment: Qt.AlignVCenter
height: parent.rowHeight
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter") }
Label
{
width: scrollView.columnWidth
text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency)
verticalAlignment: Qt.AlignVCenter
height: parent.rowHeight
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height; visible: unlinkMaterialButton.visible }
Label
{
width: 2 * scrollView.columnWidth
verticalAlignment: Qt.AlignVCenter
text: catalog.i18nc("@label", "This material is linked to %1 and shares some of its properties.").arg(base.linkedMaterialNames)
wrapMode: Text.WordWrap
visible: unlinkMaterialButton.visible
}
Button
{
id: unlinkMaterialButton
text: catalog.i18nc("@label", "Unlink Material")
visible: base.linkedMaterialNames != ""
onClicked:
{
Cura.ContainerManager.unlinkMaterial(base.currentMaterialNode)
base.reevaluateLinkedMaterials = true
}
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Description") }
ReadOnlyTextArea
{
text: properties.description;
width: 2 * scrollView.columnWidth
wrapMode: Text.WordWrap
readOnly: !base.editingEnabled;
onEditingFinished: base.setMetaDataEntry("description", properties.description, text)
}
Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Adhesion Information") }
ReadOnlyTextArea
{
text: properties.adhesion_info;
width: 2 * scrollView.columnWidth
wrapMode: Text.WordWrap
readOnly: !base.editingEnabled;
onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text)
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
}
function updateCostPerMeter()
{
base.spoolLength = calculateSpoolLength(diameterSpinBox.value, densitySpinBox.value, spoolWeightSpinBox.value);
base.costPerMeter = calculateCostPerMeter(spoolCostSpinBox.value);
}
text: catalog.i18nc("@title", "Information")
property string activeView: "information" //To determine which page gets displayed.
}
UM.TabRowButton
{
text: catalog.i18nc("@label", "Print settings")
property string activeView: "settings"
}
}
OldControls.Tab
ScrollView
{
title: catalog.i18nc("@label", "Print settings")
id: informationPage
anchors
{
leftMargin: UM.Theme.getSize("default_margin").width
topMargin: UM.Theme.getSize("default_margin").height
bottomMargin: UM.Theme.getSize("default_margin").height
rightMargin: 0
top: pageSelectorTabRow.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
OldControls.ScrollView
ScrollBar.vertical: UM.ScrollBar
{
anchors.fill: parent;
ListView
parent: informationPage
anchors
{
model: UM.SettingDefinitionsModel
top: parent.top
right: parent.right
bottom: parent.bottom
}
}
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
clip: true
visible: pageSelectorTabRow.currentItem.activeView === "information"
property real columnWidth: (width * 0.5 - UM.Theme.getSize("default_margin").width) | 0
Flow
{
id: containerGrid
x: UM.Theme.getSize("default_margin").width
y: UM.Theme.getSize("default_lining").height
width: base.width
property real rowHeight: brandTextField.height + UM.Theme.getSize("default_lining").height
MessageDialog
{
id: confirmDiameterChangeDialog
icon: StandardIcon.Question;
title: catalog.i18nc("@title:window", "Confirm Diameter Change")
text: catalog.i18nc("@label (%1 is a number)", "The new filament diameter is set to %1 mm, which is not compatible with the current extruder. Do you wish to continue?".arg(new_diameter_value))
standardButtons: StandardButton.Yes | StandardButton.No
modality: Qt.ApplicationModal
property var new_diameter_value: null;
property var old_diameter_value: null;
property var old_approximate_diameter_value: null;
onYes:
{
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
visibilityHandler: Cura.MaterialSettingsVisibilityHandler { }
expanded: ["*"]
base.setMetaDataEntry("approximate_diameter", old_approximate_diameter_value, getApproximateDiameter(new_diameter_value).toString());
base.setMetaDataEntry("properties/diameter", properties.diameter, new_diameter_value);
// CURA-6868 Make sure to update the extruder to user a diameter-compatible material.
Cura.MachineManager.updateMaterialWithVariant()
base.resetSelectedMaterial()
}
delegate: UM.TooltipArea
onNo:
{
width: childrenRect.width
height: childrenRect.height
text: model.description
Label
{
id: label
width: base.firstColumnWidth;
height: spinBox.height + UM.Theme.getSize("default_lining").height
text: model.label
elide: Text.ElideRight
verticalAlignment: Qt.AlignVCenter
}
ReadOnlySpinBox
{
id: spinBox
anchors.left: label.right
value:
{
// In case the setting is not in the material...
if (!isNaN(parseFloat(materialPropertyProvider.properties.value)))
{
return parseFloat(materialPropertyProvider.properties.value);
}
// ... we search in the variant, and if it is not there...
if (!isNaN(parseFloat(variantPropertyProvider.properties.value)))
{
return parseFloat(variantPropertyProvider.properties.value);
}
// ... then look in the definition container.
if (!isNaN(parseFloat(machinePropertyProvider.properties.value)))
{
return parseFloat(machinePropertyProvider.properties.value);
}
return 0;
}
width: base.secondColumnWidth
readOnly: !base.editingEnabled
suffix: " " + model.unit
maximumValue: 99999
decimals: model.unit == "mm" ? 2 : 0
base.properties.diameter = old_diameter_value;
diameterSpinBox.value = Qt.binding(function() { return base.properties.diameter })
}
onEditingFinished: materialPropertyProvider.setPropertyValue("value", value)
}
onRejected: no()
}
UM.ContainerPropertyProvider
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") }
ReadOnlyTextField
{
id: displayNameTextField;
width: informationPage.columnWidth;
text: properties.name;
readOnly: !base.editingEnabled;
onEditingFinished: base.updateMaterialDisplayName(properties.name, text)
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Brand") }
ReadOnlyTextField
{
id: brandTextField;
width: informationPage.columnWidth;
text: properties.brand;
readOnly: !base.editingEnabled;
onEditingFinished: base.updateMaterialBrand(properties.brand, text)
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Material Type") }
ReadOnlyTextField
{
id: materialTypeField;
width: informationPage.columnWidth;
text: properties.material;
readOnly: !base.editingEnabled;
onEditingFinished: base.updateMaterialType(properties.material, text)
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") }
Row
{
width: informationPage.columnWidth
height: parent.rowHeight
spacing: Math.round(UM.Theme.getSize("default_margin").width / 2)
// color indicator square
Rectangle
{
id: colorSelector
color: properties.color_code
width: Math.round(colorLabel.height * 0.75)
height: Math.round(colorLabel.height * 0.75)
border.width: UM.Theme.getSize("default_lining").height
anchors.verticalCenter: parent.verticalCenter
// open the color selection dialog on click
MouseArea
{
id: materialPropertyProvider
containerId: base.containerId
watchedProperties: [ "value" ]
key: model.key
}
UM.ContainerPropertyProvider
{
id: variantPropertyProvider
containerId: Cura.MachineManager.activeStack.variant.id
watchedProperties: [ "value" ]
key: model.key
}
UM.ContainerPropertyProvider
{
id: machinePropertyProvider
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
watchedProperties: [ "value" ]
key: model.key
anchors.fill: parent
onClicked: colorDialog.open()
enabled: base.editingEnabled
}
}
// pretty color name text field
ReadOnlyTextField
{
id: colorLabel;
width: parent.width - colorSelector.width - parent.spacing
text: properties.color_name;
readOnly: !base.editingEnabled
onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text)
}
// popup dialog to select a new color
// if successful it sets the properties.color_code value to the new color
ColorDialog
{
id: colorDialog
color: properties.color_code
onAccepted: base.setMetaDataEntry("color_code", properties.color_code, color)
}
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
Label { width: parent.width; height: parent.rowHeight; font.bold: true; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Properties") }
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") }
ReadOnlySpinBox
{
id: densitySpinBox
width: informationPage.columnWidth
value: properties.density
decimals: 2
suffix: " g/cm³"
stepSize: 0.01
readOnly: !base.editingEnabled
onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value)
onValueChanged: updateCostPerMeter()
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") }
ReadOnlySpinBox
{
id: diameterSpinBox
width: informationPage.columnWidth
value: properties.diameter
decimals: 2
suffix: " mm"
stepSize: 0.01
readOnly: !base.editingEnabled
onEditingFinished:
{
// This does not use a SettingPropertyProvider, because we need to make the change to all containers
// which derive from the same base_file
var old_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "properties/diameter");
var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter");
var new_approximate_diameter = getApproximateDiameter(value);
if (new_approximate_diameter != Cura.ExtruderManager.getActiveExtruderStack().approximateMaterialDiameter)
{
confirmDiameterChangeDialog.old_diameter_value = old_diameter;
confirmDiameterChangeDialog.new_diameter_value = value;
confirmDiameterChangeDialog.old_approximate_diameter_value = old_approximate_diameter;
confirmDiameterChangeDialog.open()
}
else {
base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, getApproximateDiameter(value).toString());
base.setMetaDataEntry("properties/diameter", properties.diameter, value);
}
}
onValueChanged: updateCostPerMeter()
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") }
SpinBox
{
id: spoolCostSpinBox
width: informationPage.columnWidth
value: base.getMaterialPreferenceValue(properties.guid, "spool_cost")
to: 100000000
editable: true
contentItem: TextField
{
text: spoolCostSpinBox.textFromValue(spoolCostSpinBox.value, spoolCostSpinBox.locale)
selectByMouse: true
background: Item {}
validator: RegExpValidator { regExp: new RegExp("^" + base.currency + " ([0-9]+[.]?[0-9]*)?$") }
}
property int decimals: 2
valueFromText: function(text) {
// remove all non-number tokens from input string so value can be parsed correctly
var value = Number(text.replace(",", ".").replace(/[^0-9.]+/g, ""));
var precision = Math.pow(10, spoolCostSpinBox.decimals);
return Math.round(value * precision) / precision;
}
textFromValue: function(value) {
return base.currency + " " + value.toFixed(spoolCostSpinBox.decimals)
}
onValueChanged:
{
base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value, decimals))
updateCostPerMeter()
}
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") }
SpinBox
{
id: spoolWeightSpinBox
width: informationPage.columnWidth
value: base.getMaterialPreferenceValue(properties.guid, "spool_weight", Cura.ContainerManager.getContainerMetaDataEntry(properties.container_id, "properties/weight"))
suffix: " g"
stepSize: 100
to: 10000
editable: true
contentItem: TextField
{
text: spoolWeightSpinBox.textFromValue(spoolWeightSpinBox.value, spoolWeightSpinBox.locale)
selectByMouse: true
background: Item {}
validator: RegExpValidator { regExp: new RegExp("^([0-9]+[.]?[0-9]*)? g$") }
}
valueFromText: function(text, locale) {
// remove all non-number tokens from input string so value can be parsed correctly
var value = Number(text.replace(",", ".").replace(/[^0-9.]+/g, ""));
return Math.round(value);
}
textFromValue: function(value, locale) {
return value + " g"
}
onValueChanged:
{
base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value))
updateCostPerMeter()
}
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") }
Label
{
width: informationPage.columnWidth
text: "~ %1 m".arg(Math.round(base.spoolLength))
verticalAlignment: Qt.AlignVCenter
height: parent.rowHeight
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter") }
Label
{
width: informationPage.columnWidth
text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency)
verticalAlignment: Qt.AlignVCenter
height: parent.rowHeight
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height; visible: unlinkMaterialButton.visible }
Label
{
width: 2 * informationPage.columnWidth
verticalAlignment: Qt.AlignVCenter
text: catalog.i18nc("@label", "This material is linked to %1 and shares some of its properties.").arg(base.linkedMaterialNames)
wrapMode: Text.WordWrap
visible: unlinkMaterialButton.visible
}
Button
{
id: unlinkMaterialButton
text: catalog.i18nc("@label", "Unlink Material")
visible: base.linkedMaterialNames != ""
onClicked:
{
Cura.ContainerManager.unlinkMaterial(base.currentMaterialNode)
base.reevaluateLinkedMaterials = true
}
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Description") }
ReadOnlyTextArea
{
text: properties.description;
width: 2 * informationPage.columnWidth
wrapMode: Text.WordWrap
readOnly: !base.editingEnabled;
onEditingFinished: base.setMetaDataEntry("description", properties.description, text)
}
Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Adhesion Information") }
ReadOnlyTextArea
{
text: properties.adhesion_info;
width: 2 * informationPage.columnWidth
wrapMode: Text.WordWrap
readOnly: !base.editingEnabled;
onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text)
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
}
function updateCostPerMeter()
{
base.spoolLength = calculateSpoolLength(diameterSpinBox.value, densitySpinBox.value, spoolWeightSpinBox.value);
base.costPerMeter = calculateCostPerMeter(spoolCostSpinBox.value);
}
}
ListView
{
anchors
{
top: pageSelectorTabRow.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
model: UM.SettingDefinitionsModel
{
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
visibilityHandler: Cura.MaterialSettingsVisibilityHandler { }
expanded: ["*"]
}
ScrollBar.vertical: UM.ScrollBar {}
clip: true
visible: pageSelectorTabRow.currentItem.activeView === "settings"
delegate: UM.TooltipArea
{
width: childrenRect.width
height: childrenRect.height
text: model.description
Label
{
id: label
width: base.firstColumnWidth;
height: spinBox.height + UM.Theme.getSize("default_lining").height
text: model.label
elide: Text.ElideRight
verticalAlignment: Qt.AlignVCenter
}
ReadOnlySpinBox
{
id: spinBox
anchors.left: label.right
value:
{
// In case the setting is not in the material...
if (!isNaN(parseFloat(materialPropertyProvider.properties.value)))
{
return parseFloat(materialPropertyProvider.properties.value);
}
// ... we search in the variant, and if it is not there...
if (!isNaN(parseFloat(variantPropertyProvider.properties.value)))
{
return parseFloat(variantPropertyProvider.properties.value);
}
// ... then look in the definition container.
if (!isNaN(parseFloat(machinePropertyProvider.properties.value)))
{
return parseFloat(machinePropertyProvider.properties.value);
}
return 0;
}
width: base.secondColumnWidth
readOnly: !base.editingEnabled
suffix: " " + model.unit
maximumValue: 99999
decimals: model.unit == "mm" ? 2 : 0
onEditingFinished: materialPropertyProvider.setPropertyValue("value", value)
}
UM.ContainerPropertyProvider
{
id: materialPropertyProvider
containerId: base.containerId
watchedProperties: [ "value" ]
key: model.key
}
UM.ContainerPropertyProvider
{
id: variantPropertyProvider
containerId: Cura.MachineManager.activeStack.variant.id
watchedProperties: [ "value" ]
key: model.key
}
UM.ContainerPropertyProvider
{
id: machinePropertyProvider
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
watchedProperties: [ "value" ]
key: model.key
}
}
}

View file

@ -1,118 +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 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
Tab
{
id: base
property int extruderPosition: -1 //Denotes the global stack.
property var qualityItem: null
property bool isQualityItemCurrentlyActivated:
{
if (qualityItem == null)
{
return false;
}
return qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName;
}
TableView
{
anchors.fill: parent
anchors.margins: UM.Theme.getSize("default_margin").width
id: profileSettingsView
Component
{
id: itemDelegate
UM.TooltipArea
{
property var setting: qualitySettings.getItem(styleData.row)
height: childrenRect.height
width: (parent != null) ? parent.width : 0
text:
{
if (styleData.value === undefined)
{
return ""
}
return (styleData.value.substr(0,1) == "=") ? styleData.value : ""
}
Label
{
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.right: parent.right
text:
{
if (styleData.value === undefined)
{
return ""
}
return (styleData.value.substr(0,1) == "=") ? catalog.i18nc("@info:status", "Calculated") : styleData.value
}
font.strikeout: styleData.column == 1 && setting.user_value != "" && base.isQualityItemCurrentlyActivated
font.italic: setting.profile_value_source == "quality_changes" || (setting.user_value != "" && base.isQualityItemCurrentlyActivated)
opacity: font.strikeout ? 0.5 : 1
color: styleData.textColor
elide: Text.ElideRight
}
}
}
TableViewColumn
{
role: "label"
title: catalog.i18nc("@title:column", "Setting")
width: (parent.width * 0.4) | 0
delegate: itemDelegate
}
TableViewColumn
{
role: "profile_value"
title: catalog.i18nc("@title:column", "Profile")
width: (parent.width * 0.18) | 0
delegate: itemDelegate
}
TableViewColumn
{
role: "user_value"
title: catalog.i18nc("@title:column", "Current");
visible: base.isQualityItemCurrentlyActivated
width: (parent.width * 0.18) | 0
delegate: itemDelegate
}
TableViewColumn
{
role: "unit"
title: catalog.i18nc("@title:column", "Unit")
width: (parent.width * 0.14) | 0
delegate: itemDelegate
}
section.property: "category"
section.delegate: Label
{
text: section
font.bold: true
}
model: Cura.QualitySettingsModel
{
id: qualitySettings
selectedPosition: base.extruderPosition
selectedQualityItem: base.qualityItem == null ? {} : base.qualityItem
}
SystemPalette { id: palette }
}
}

View file

@ -1,13 +1,13 @@
// Copyright (c) 2019 Ultimaker B.V.
// Uranium is released under the terms of the LGPLv3 or higher.
//Copyright (c) 2022 Ultimaker B.V.
//Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4 as OldControls
import QtQuick.Controls 2.1
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2
import UM 1.2 as UM
import UM 1.5 as UM
import Cura 1.6 as Cura
@ -398,13 +398,13 @@ Item
}
visible: text != ""
text: catalog.i18nc("@label %1 is printer name", "Printer: %1").arg(Cura.MachineManager.activeMachine.name)
width: profileScrollView.width
width: profileBackground.width
elide: Text.ElideRight
}
OldControls.ScrollView
Rectangle
{
id: profileScrollView
id: profileBackground
anchors
{
top: captionLabel.visible ? captionLabel.bottom : parent.top
@ -412,22 +412,20 @@ Item
bottom: parent.bottom
left: parent.left
}
width: (parent.width * 0.4) | 0
Rectangle
{
parent: viewport
anchors.fill: parent
color: palette.light
}
width: true ? (parent.width * 0.4) | 0 : parent.width
frameVisible: true
clip: true
color: palette.light
ListView
{
id: qualityListView
anchors.fill: parent
ScrollBar.vertical: UM.ScrollBar
{
id: profileScrollBar
}
clip: true
model: base.qualityManagementModel
Component.onCompleted:
@ -462,7 +460,7 @@ Item
delegate: Rectangle
{
width: profileScrollView.width
width: profileBackground.width - profileScrollBar.width
height: childrenRect.height
// Added this property to identify custom profiles in automated system tests (Squish)
@ -514,16 +512,24 @@ Item
anchors
{
left: profileScrollView.right
left: profileBackground.right
leftMargin: UM.Theme.getSize("default_margin").width
top: parent.top
bottom: parent.bottom
right: parent.right
}
Item
Column
{
anchors.fill: parent
id: detailsPanelHeaderColumn
anchors
{
left: parent.left
right: parent.right
top: parent.top
}
spacing: UM.Theme.getSize("default_margin").height
visible: base.currentItem != null
Item // Profile title Label
@ -547,16 +553,14 @@ Item
Flow
{
id: currentSettingsActions
width: parent.width
visible: base.hasCurrentItem && base.currentItem.name == Cura.MachineManager.activeQualityOrQualityChangesName && base.currentItem.intent_category == Cura.MachineManager.activeIntentCategory
anchors.left: parent.left
anchors.right: parent.right
anchors.top: profileName.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
Button
{
text: catalog.i18nc("@action:button", "Update profile with current settings/overrides")
enabled: Cura.MachineManager.hasUserSettings && !base.currentItem.is_read_only
enabled: Cura.MachineManager.hasUserSettings && qualityListView.currentItem && !qualityListView.currentItem.is_read_only
onClicked: Cura.ContainerManager.updateQualityChanges()
}
@ -568,62 +572,57 @@ Item
}
}
Column
Label
{
id: profileNotices
anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : currentSettingsActions.anchors.top
anchors.topMargin: UM.Theme.getSize("default_margin").height
anchors.left: parent.left
anchors.right: parent.right
spacing: UM.Theme.getSize("default_margin").height
Label
{
id: defaultsMessage
visible: false
text: catalog.i18nc("@action:label", "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below.")
wrapMode: Text.WordWrap
width: parent.width
}
Label
{
id: noCurrentSettingsMessage
visible: base.isCurrentItemActivated && !Cura.MachineManager.hasUserSettings
text: catalog.i18nc("@action:label", "Your current settings match the selected profile.")
wrapMode: Text.WordWrap
width: parent.width
}
id: defaultsMessage
visible: false
text: catalog.i18nc("@action:label", "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below.")
wrapMode: Text.WordWrap
width: parent.width
}
Label
{
id: noCurrentSettingsMessage
visible: base.isCurrentItemActivated && !Cura.MachineManager.hasUserSettings
text: catalog.i18nc("@action:label", "Your current settings match the selected profile.")
wrapMode: Text.WordWrap
width: parent.width
}
OldControls.TabView
UM.TabRow
{
anchors.left: parent.left
anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top
anchors.topMargin: UM.Theme.getSize("default_margin").height
anchors.right: parent.right
anchors.bottom: parent.bottom
currentIndex: 0
ProfileTab
id: profileExtruderTabs
UM.TabRowButton //One extra tab for the global settings.
{
title: catalog.i18nc("@title:tab", "Global Settings")
qualityItem: base.currentItem
text: catalog.i18nc("@title:tab", "Global Settings")
}
Repeater
{
model: base.extrudersModel
ProfileTab
UM.TabRowButton
{
title: model.name
extruderPosition: model.index
qualityItem: base.currentItem
text: model.name
}
}
}
}
Cura.ProfileOverview
{
anchors
{
top: detailsPanelHeaderColumn.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
visible: detailsPanelHeaderColumn.visible
qualityItem: base.currentItem
extruderPosition: profileExtruderTabs.currentIndex - 1
}
}
}
}

View file

@ -1,13 +1,11 @@
// Copyright (c) 2016 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.1
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Controls 2.15
import QtQuick.Controls 1.1 as OldControls
import QtQuick.Controls 2.3 as NewControls
import UM 1.2 as UM
import UM 1.5 as UM
import Cura 1.0 as Cura
@ -36,7 +34,7 @@ UM.PreferencesPage
id: base;
anchors.fill: parent;
CheckBox
OldControls.CheckBox
{
id: toggleVisibleSettings
anchors
@ -98,7 +96,7 @@ UM.PreferencesPage
onTextChanged: definitionsModel.filter = {"i18n_label|i18n_description": "*" + text}
}
NewControls.ComboBox
ComboBox
{
id: visibilityPreset
width: 150 * screenScaleFactor
@ -106,7 +104,7 @@ UM.PreferencesPage
{
top: parent.top
right: parent.right
bottom: scrollView.top
bottom: settingsListView.top
}
model: settingVisibilityPresetsModel.items
@ -133,12 +131,9 @@ UM.PreferencesPage
}
}
ScrollView
ListView
{
id: scrollView
frameVisible: true
id: settingsListView
anchors
{
top: filter.bottom;
@ -147,42 +142,41 @@ UM.PreferencesPage
right: parent.right;
bottom: parent.bottom;
}
ListView
clip: true
ScrollBar.vertical: UM.ScrollBar {}
model: UM.SettingDefinitionsModel
{
id: settingsListView
id: definitionsModel
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
showAll: true
exclude: ["machine_settings", "command_line_settings"]
showAncestors: true
expanded: ["*"]
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
}
model: UM.SettingDefinitionsModel
delegate: Loader
{
id: loader
width: settingsListView.width
height: model.type != undefined ? UM.Theme.getSize("section").height : 0
property var definition: model
property var settingDefinitionsModel: definitionsModel
asynchronous: true
active: model.type != undefined
sourceComponent:
{
id: definitionsModel
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
showAll: true
exclude: ["machine_settings", "command_line_settings"]
showAncestors: true
expanded: ["*"]
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
}
delegate: Loader
{
id: loader
width: settingsListView.width
height: model.type != undefined ? UM.Theme.getSize("section").height : 0
property var definition: model
property var settingDefinitionsModel: definitionsModel
asynchronous: true
active: model.type != undefined
sourceComponent:
switch(model.type)
{
switch(model.type)
{
case "category":
return settingVisibilityCategory
default:
return settingVisibilityItem
}
case "category":
return settingVisibilityCategory
default:
return settingVisibilityItem
}
}
}

View file

@ -1,5 +1,5 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
//Copyright (c) 2022 Ultimaker B.V.
//Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
@ -213,6 +213,7 @@ Item
model: extrudersModel
delegate: UM.TabRowButton
{
checked: model.index == 0
contentItem: Item
{
Cura.ExtruderIcon

View file

@ -1,4 +1,4 @@
// Copyright (c) 2020 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
@ -43,17 +43,29 @@ Popup
// This repeater adds the intent labels
ScrollView
{
id: qualityListScrollView
property real maximumHeight: screenScaleFactor * 400
contentHeight: dataColumn.height
height: Math.min(contentHeight, maximumHeight)
clip: true
width: parent.width
ScrollBar.vertical.policy: height == maximumHeight ? ScrollBar.AlwaysOn: ScrollBar.AlwaysOff
clip: true
ScrollBar.vertical: UM.ScrollBar
{
id: qualityListScrollBar
parent: qualityListScrollView
anchors
{
top: parent.top
right: parent.right
bottom: parent.bottom
}
}
Column
{
id: dataColumn
width: parent.width
width: qualityListScrollView.width - qualityListScrollBar.width
Repeater
{
model: dataModel
@ -64,7 +76,7 @@ Popup
property variant subItemModel: model.qualities
height: childrenRect.height
width: popup.contentWidth
width: dataColumn.width
UM.Label
{
@ -137,7 +149,7 @@ Popup
Item
{
height: childrenRect.height
width: popup.contentWidth
width: dataColumn.width
UM.Label
{

View file

@ -1,9 +1,9 @@
// Copyright (c) 2020 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 1.4
import QtQuick.Controls 2.3 as Controls2
import QtQuick.Controls 1.4 as OldControls
import QtQuick.Controls 2.3
import UM 1.5 as UM
import Cura 1.0 as Cura
@ -73,7 +73,7 @@ Item
}
}
Controls2.ComboBox
ComboBox
{
id: supportExtruderCombobox
@ -200,7 +200,7 @@ Item
}
}
contentItem:UM.Label
contentItem: UM.Label
{
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
@ -229,7 +229,7 @@ Item
}
}
popup: Controls2.Popup
popup: Popup
{
y: supportExtruderCombobox.height - UM.Theme.getSize("default_lining").height
width: supportExtruderCombobox.width
@ -238,12 +238,12 @@ Item
contentItem: ListView
{
clip: true
implicitHeight: contentHeight
ScrollBar.vertical: UM.ScrollBar {}
clip: true
model: supportExtruderCombobox.popup.visible ? supportExtruderCombobox.delegateModel : null
currentIndex: supportExtruderCombobox.highlightedIndex
Controls2.ScrollIndicator.vertical: Controls2.ScrollIndicator { }
}
background: Rectangle
@ -253,7 +253,7 @@ Item
}
}
delegate: Controls2.ItemDelegate
delegate: ItemDelegate
{
width: supportExtruderCombobox.width - 2 * UM.Theme.getSize("default_lining").width
height: supportExtruderCombobox.height

View file

@ -1,10 +1,10 @@
// Copyright (c) 2018 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.3
import UM 1.2 as UM
import UM 1.5 as UM
import Cura 1.1 as Cura
Cura.ExpandablePopup
@ -193,42 +193,27 @@ Cura.ExpandablePopup
{
id: popup
width: UM.Theme.getSize("machine_selector_widget_content").width
height: Math.min(machineSelectorList.contentHeight + separator.height + buttonRow.height, UM.Theme.getSize("machine_selector_widget_content").height) //Maximum height is the theme entry.
ScrollView
MachineSelectorList
{
id: scroll
width: parent.width
clip: true
leftPadding: UM.Theme.getSize("default_lining").width
rightPadding: UM.Theme.getSize("default_lining").width
MachineSelectorList
id: machineSelectorList
anchors
{
id: machineSelectorList
// Can't use parent.width since the parent is the flickable component and not the ScrollView
width: scroll.width - scroll.leftPadding - scroll.rightPadding
property real maximumHeight: UM.Theme.getSize("machine_selector_widget_content").height - buttonRow.height
// We use an extra property here, since we only want to to be informed about the content size changes.
onContentHeightChanged:
{
scroll.height = Math.min(contentHeight, maximumHeight)
popup.height = scroll.height + buttonRow.height
}
Component.onCompleted:
{
scroll.height = Math.min(contentHeight, maximumHeight)
popup.height = scroll.height + buttonRow.height
}
left: parent.left
leftMargin: UM.Theme.getSize("default_lining").width
right: parent.right
rightMargin: UM.Theme.getSize("default_lining").width
top: parent.top
bottom: separator.top
}
clip: true
}
Rectangle
{
id: separator
anchors.top: scroll.bottom
anchors.bottom: buttonRow.top
width: parent.width
height: UM.Theme.getSize("default_lining").height
color: UM.Theme.getColor("lining")
@ -238,8 +223,7 @@ Cura.ExpandablePopup
{
id: buttonRow
// The separator is inside the buttonRow. This is to avoid some weird behaviours with the scroll bar.
anchors.top: separator.top
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
padding: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("default_margin").width

View file

@ -14,10 +14,15 @@ ListView
section.property: "hasRemoteConnection"
property real contentHeight: childrenRect.height
ScrollBar.vertical: UM.ScrollBar
{
id: scrollBar
}
section.delegate: UM.Label
{
text: section == "true" ? catalog.i18nc("@label", "Connected printers") : catalog.i18nc("@label", "Preset printers")
width: parent.width
width: parent.width - scrollBar.width
height: UM.Theme.getSize("action_button").height
leftPadding: UM.Theme.getSize("default_margin").width
font: UM.Theme.getFont("medium")
@ -27,7 +32,7 @@ ListView
delegate: MachineSelectorButton
{
text: model.name ? model.name : ""
width: listView.width
width: listView.width - scrollBar.width
outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
checked: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.id == model.id : false

View file

@ -0,0 +1,42 @@
//Copyright (c) 2022 Ultimaker B.V.
//Cura is released under the terms of the LGPLv3 or higher.
import Qt.labs.qmlmodels 1.0
import QtQuick 2.7
import QtQuick.Controls 1.4 as OldControls
import QtQuick.Controls 2.15
import UM 1.5 as UM
import Cura 1.6 as Cura
Cura.TableView
{
id: profileOverview
property var qualityItem //The quality profile to display here.
property int extruderPosition: -1 //The extruder to display. -1 denotes the global stack.
property bool isQualityItemCurrentlyActivated: qualityItem != null && qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName
Cura.QualitySettingsModel
{
id: qualitySettings
selectedPosition: profileOverview.extruderPosition
selectedQualityItem: profileOverview.qualityItem == null ? {} : profileOverview.qualityItem
}
columnHeaders: [
catalog.i18nc("@title:column", "Setting"),
catalog.i18nc("@title:column", "Profile"),
catalog.i18nc("@title:column", "Current"),
catalog.i18nc("@title:column Unit of measurement", "Unit")
]
model: TableModel
{
TableModelColumn { display: "label" }
TableModelColumn { display: "profile_value" }
TableModelColumn { display: "user_value" }
TableModelColumn { display: "unit" }
rows: qualitySettings.items
}
sectionRole: "category"
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2016 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Uranium is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
@ -178,12 +178,12 @@ SettingItem
contentItem: ListView
{
clip: true
implicitHeight: contentHeight
ScrollBar.vertical: UM.ScrollBar {}
clip: true
model: control.popup.visible ? control.delegateModel : null
currentIndex: control.highlightedIndex
ScrollIndicator.vertical: ScrollIndicator { }
}
background: Rectangle

View file

@ -1,4 +1,4 @@
// Copyright (c) 2018 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
@ -181,12 +181,12 @@ SettingItem
contentItem: ListView
{
clip: true
implicitHeight: contentHeight
ScrollBar.vertical: UM.ScrollBar {}
clip: true
model: control.popup.visible ? control.delegateModel : null
currentIndex: control.highlightedIndex
ScrollIndicator.vertical: ScrollIndicator { }
}
background: Rectangle {

View file

@ -1,4 +1,4 @@
// Copyright (c) 2021 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
@ -191,6 +191,7 @@ Item
}
clip: true
cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item.
ScrollBar.vertical: UM.ScrollBar {}
model: UM.SettingDefinitionsModel
{

View file

@ -1,67 +1,217 @@
// Copyright (C) 2021 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
//Copyright (C) 2022 Ultimaker B.V.
//Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 1.4 as OldControls // TableView doesn't exist in the QtQuick Controls 2.x in 5.10, so use the old one
import QtQuick.Controls 2.3
import QtQuick.Controls.Styles 1.4
import Qt.labs.qmlmodels 1.0
import QtQuick 2.15
import QtQuick.Controls 2.15
import UM 1.5 as UM
OldControls.TableView
/*
* A re-sizeable table of data.
*
* This table combines a list of headers with a TableView to show certain roles in a table.
* The columns of the table can be resized.
* When the table becomes too big, you can scroll through the table. When a column becomes too small, the contents of
* the table are elided.
* The table gets Cura's themeing.
*/
Item
{
itemDelegate: Item
{
height: tableCellLabel.implicitHeight
id: tableBase
UM.Label
required property var columnHeaders //The text to show in the headers of each column.
property alias model: tableView.model //A TableModel to display in this table. To use a ListModel for the rows, use "rows: listModel.items"
property int currentRow: -1 //The selected row index.
property var onDoubleClicked: function(row) {} //Something to execute when double clicked. Accepts one argument: The index of the row that was clicked on.
property bool allowSelection: true //Whether to allow the user to select items.
property string sectionRole: ""
Row
{
id: headerBar
Repeater
{
id: tableCellLabel
color: styleData.selected ? UM.Theme.getColor("primary_button_text") : UM.Theme.getColor("text")
elide: Text.ElideRight
text: styleData.value
anchors.fill: parent
anchors.leftMargin: 10 * screenScaleFactor
id: headerRepeater
model: columnHeaders
Rectangle
{
width: Math.max(1, Math.round(tableBase.width / headerRepeater.count))
height: UM.Theme.getSize("section").height
color: UM.Theme.getColor("secondary")
Label
{
id: contentText
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("narrow_margin").width
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("narrow_margin").width
text: modelData
font: UM.Theme.getFont("medium_bold")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
Rectangle //Resize handle.
{
anchors
{
right: parent.right
top: parent.top
bottom: parent.bottom
}
width: UM.Theme.getSize("thick_lining").width
color: UM.Theme.getColor("thick_lining")
MouseArea
{
anchors.fill: parent
cursorShape: Qt.SizeHorCursor
drag
{
target: parent
axis: Drag.XAxis
}
onMouseXChanged:
{
if(drag.active)
{
let new_width = parent.parent.width + mouseX;
let sum_widths = mouseX;
for(let i = 0; i < headerBar.children.length; ++i)
{
sum_widths += headerBar.children[i].width;
}
if(sum_widths > tableBase.width)
{
new_width -= sum_widths - tableBase.width; //Limit the total width to not exceed the view.
}
let width_fraction = new_width / tableBase.width; //Scale with the same fraction along with the total width, if the table is resized.
parent.parent.width = Qt.binding(function() { return tableBase.width * width_fraction });
}
}
}
}
onWidthChanged:
{
tableView.forceLayout(); //Rescale table cells underneath as well.
}
}
}
}
rowDelegate: Rectangle
TableView
{
color: styleData.selected ? UM.Theme.getColor("primary_button") : UM.Theme.getColor("main_background")
height: UM.Theme.getSize("table_row").height
id: tableView
anchors
{
top: headerBar.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
clip: true
ScrollBar.vertical: UM.ScrollBar {}
columnWidthProvider: function(column)
{
return headerBar.children[column].width; //Cells get the same width as their column header.
}
delegate: Rectangle
{
implicitHeight: Math.max(1, cellContent.height)
color: UM.Theme.getColor((tableBase.currentRow == row) ? "primary" : ((row % 2 == 0) ? "main_background" : "viewport_background"))
Label
{
id: cellContent
width: parent.width
text: display
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
}
TextMetrics
{
id: cellTextMetrics
text: cellContent.text
font: cellContent.font
elide: cellContent.elide
elideWidth: cellContent.width
}
UM.TooltipArea
{
anchors.fill: parent
text: (cellTextMetrics.elidedText == cellContent.text) ? "" : cellContent.text //Show full text in tooltip if it was elided.
onClicked:
{
if(tableBase.allowSelection)
{
tableBase.currentRow = row; //Select this row.
}
}
onDoubleClicked:
{
tableBase.onDoubleClicked(row);
}
}
}
Connections
{
target: model
function onRowCountChanged()
{
tableView.contentY = 0; //When the number of rows is reduced, make sure to scroll back to the start.
}
}
}
// Use the old styling technique since it's the only way to make the scrollbars themed in the TableView
style: TableViewStyle
Connections
{
backgroundColor: UM.Theme.getColor("main_background")
handle: Rectangle
target: model
function onRowsChanged()
{
// Both implicit width and height have to be set, since the handle is used by both the horizontal and the vertical scrollbars
implicitWidth: UM.Theme.getSize("scrollbar").width
implicitHeight: UM.Theme.getSize("scrollbar").width
radius: width / 2
color: UM.Theme.getColor(styleData.pressed ? "scrollbar_handle_down" : (styleData.hovered ? "scrollbar_handle_hover" : "scrollbar_handle"))
}
let first_column = model.columns[0].display;
if(model.rows.length > 0 && model.rows[0][first_column].startsWith("<b>")) //First item is already a section header.
{
return; //Assume we already added section headers. Prevent infinite recursion.
}
if(sectionRole === "" || model.rows.length == 0) //No section headers, or no items at all.
{
tableView.model.rows = model.rows;
return;
}
scrollBarBackground: Rectangle
{
// Both implicit width and height have to be set, since the handle is used by both the horizontal and the vertical scrollbars
implicitWidth: UM.Theme.getSize("scrollbar").width
implicitHeight: UM.Theme.getSize("scrollbar").width
color: UM.Theme.getColor("main_background")
//Insert section headers in the rows.
let last_section = "";
let new_rows = [];
for(let i = 0; i < model.rows.length; ++i)
{
let item_section = model.rows[i][sectionRole];
if(item_section !== last_section) //Starting a new section.
{
let section_header = {};
for(let key in model.rows[i])
{
section_header[key] = (key === first_column) ? "<b>" + item_section + "</b>" : ""; //Put the section header in the first column.
}
new_rows.push(section_header); //Add a row representing a section header.
last_section = item_section;
}
new_rows.push(model.rows[i]);
}
tableView.model.rows = new_rows;
}
// The little rectangle between the vertical and horizontal scrollbars
corner: Rectangle
{
color: UM.Theme.getColor("main_background")
}
// Override the control arrows
incrementControl: Item { }
decrementControl: Item { }
}
}

View file

@ -1,11 +1,11 @@
// Copyright (c) 2019 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import UM 1.3 as UM
import UM 1.5 as UM
import Cura 1.7 as Cura
@ -22,7 +22,7 @@ Item
property bool searchingForCloudPrinters: true
property var discoveredCloudPrintersModel: CuraApplication.getDiscoveredCloudPrintersModel()
// The area where either the discoveredCloudPrintersScrollView or the busyIndicator will be displayed
// The area where either the discoveredCloudPrintersList or the busyIndicator will be displayed
Item
{
id: cloudPrintersContent
@ -126,14 +126,9 @@ Item
// The scrollView that contains the list of newly discovered Ultimaker Cloud printers. Visible only when
// there is at least a new cloud printer.
ScrollView
ListView
{
id: discoveredCloudPrintersScrollView
width: parent.width
clip : true
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
ScrollBar.vertical.policy: ScrollBar.AsNeeded
visible: discoveredCloudPrintersModel.count > 0
id: discoveredCloudPrintersList
anchors
{
top: cloudPrintersAddedTitle.bottom
@ -144,52 +139,47 @@ Item
bottom: parent.bottom
}
Column
ScrollBar.vertical: UM.ScrollBar {}
clip : true
visible: discoveredCloudPrintersModel.count > 0
spacing: UM.Theme.getSize("wide_margin").height
model: discoveredCloudPrintersModel
delegate: Item
{
id: discoveredPrintersColumn
spacing: 2 * UM.Theme.getSize("default_margin").height
width: discoveredCloudPrintersList.width
height: contentColumn.height
Repeater
Column
{
id: discoveredCloudPrintersRepeater
model: discoveredCloudPrintersModel
delegate: Item
id: contentColumn
Label
{
width: discoveredCloudPrintersScrollView.width
height: contentColumn.height
Column
{
id: contentColumn
Label
{
id: cloudPrinterNameLabel
leftPadding: UM.Theme.getSize("default_margin").width
text: model.name
font: UM.Theme.getFont("large_bold")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
Label
{
id: cloudPrinterTypeLabel
leftPadding: 2 * UM.Theme.getSize("default_margin").width
topPadding: UM.Theme.getSize("thin_margin").height
text: {"Type: " + model.machine_type}
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
Label
{
id: cloudPrinterFirmwareVersionLabel
leftPadding: 2 * UM.Theme.getSize("default_margin").width
text: {"Firmware version: " + model.firmware_version}
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
}
id: cloudPrinterNameLabel
leftPadding: UM.Theme.getSize("default_margin").width
text: model.name ? model.name : ""
font: UM.Theme.getFont("large_bold")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
Label
{
id: cloudPrinterTypeLabel
leftPadding: 2 * UM.Theme.getSize("default_margin").width
topPadding: UM.Theme.getSize("thin_margin").height
text: {"Type: " + model.machine_type}
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
Label
{
id: cloudPrinterFirmwareVersionLabel
leftPadding: 2 * UM.Theme.getSize("default_margin").width
text: {"Firmware version: " + model.firmware_version}
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
}
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2019 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
@ -74,118 +74,93 @@ Item
Row
{
id: localPrinterSelectionItem
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.fill: parent
// ScrollView + ListView for selecting a local printer to add
Cura.ScrollView
//Selecting a local printer to add from this list.
ListView
{
id: scrollView
height: childrenHeight
id: machineList
width: Math.floor(parent.width * 0.48)
height: parent.height
ListView
clip: true
ScrollBar.vertical: UM.ScrollBar {}
model: UM.DefinitionContainersModel
{
id: machineList
// CURA-6793
// Enabling the buffer seems to cause the blank items issue. When buffer is enabled, if the ListView's
// individual item has a dynamic change on its visibility, the ListView doesn't redraw itself.
// The default value of cacheBuffer is platform-dependent, so we explicitly disable it here.
cacheBuffer: 0
boundsBehavior: Flickable.StopAtBounds
flickDeceleration: 20000 // To prevent the flicking behavior.
model: UM.DefinitionContainersModel
{
id: machineDefinitionsModel
filter: { "visible": true }
sectionProperty: "manufacturer"
preferredSections: preferredCategories
}
section.property: "section"
section.delegate: sectionHeader
delegate: machineButton
id: machineDefinitionsModel
filter: { "visible": true }
sectionProperty: "manufacturer"
preferredSections: preferredCategories
}
Component
section.property: "section"
section.delegate: Button
{
id: sectionHeader
id: button
width: machineList.width
height: UM.Theme.getSize("action_button").height
text: section
Button
property bool isActive: base.currentSection == section
background: Rectangle
{
id: button
width: ListView.view.width
anchors.fill: parent
color: isActive ? UM.Theme.getColor("setting_control_highlight") : "transparent"
}
contentItem: Item
{
width: childrenRect.width
height: UM.Theme.getSize("action_button").height
text: section
property bool isActive: base.currentSection == section
background: Rectangle
UM.RecolorImage
{
anchors.fill: parent
color: isActive ? UM.Theme.getColor("setting_control_highlight") : "transparent"
id: arrow
anchors.left: parent.left
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width
sourceSize.height: height
color: UM.Theme.getColor("text")
source: base.currentSection == section ? UM.Theme.getIcon("ChevronSingleDown") : UM.Theme.getIcon("ChevronSingleRight")
}
contentItem: Item
UM.Label
{
width: childrenRect.width
height: UM.Theme.getSize("action_button").height
UM.RecolorImage
{
id: arrow
anchors.left: parent.left
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width
sourceSize.height: height
color: UM.Theme.getColor("text")
source: base.currentSection == section ? UM.Theme.getIcon("ChevronSingleDown") : UM.Theme.getIcon("ChevronSingleRight")
}
UM.Label
{
id: label
anchors.left: arrow.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
text: button.text
font: UM.Theme.getFont("default_bold")
}
id: label
anchors.left: arrow.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
text: button.text
font: UM.Theme.getFont("default_bold")
}
}
onClicked:
{
base.currentSection = section
base.updateCurrentItemUponSectionChange()
}
onClicked:
{
base.currentSection = section
base.updateCurrentItemUponSectionChange()
}
}
Component
delegate: Cura.RadioButton
{
id: machineButton
Cura.RadioButton
id: radioButton
anchors
{
id: radioButton
anchors
{
left: parent !== null ? parent.left: undefined
leftMargin: UM.Theme.getSize("standard_list_lineheight").width
left: parent !== null ? parent.left : undefined
leftMargin: UM.Theme.getSize("standard_list_lineheight").width
right: parent !== null ? parent.right: undefined
rightMargin: UM.Theme.getSize("default_margin").width
}
height: visible ? UM.Theme.getSize("standard_list_lineheight").height : 0
checked: ListView.view.currentIndex == index
text: name
visible: base.currentSection == section
onClicked: ListView.view.currentIndex = index
right: parent !== null ? parent.right : undefined
rightMargin: UM.Theme.getSize("default_margin").width
}
height: visible ? UM.Theme.getSize("standard_list_lineheight").height : 0 //This causes the scrollbar to vary in length due to QTBUG-76830.
checked: machineList.currentIndex == index
text: name
visible: base.currentSection.toLowerCase() === section.toLowerCase()
onClicked: machineList.currentIndex = index
}
}
@ -194,7 +169,7 @@ Item
{
id: verticalLine
anchors.top: parent.top
height: childrenHeight - UM.Theme.getSize("default_lining").height
height: parent.height - UM.Theme.getSize("default_lining").height
width: UM.Theme.getSize("default_lining").height
color: UM.Theme.getColor("lining")
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2019 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
@ -45,11 +45,9 @@ Item
}
contentComponent: networkPrinterListComponent
Component
{
id: networkPrinterListComponent
AddNetworkPrinterScrollView
{
id: networkPrinterScrollView
@ -95,20 +93,13 @@ Item
}
contentComponent: localPrinterListComponent
Component
{
id: localPrinterListComponent
AddLocalPrinterScrollView
{
id: localPrinterView
property int childrenHeight: backButton.y - addLocalPrinterDropDown.y - UM.Theme.getSize("expandable_component_content_header").height - UM.Theme.getSize("default_margin").height
onChildrenHeightChanged:
{
addLocalPrinterDropDown.children[1].height = childrenHeight
}
height: backButton.y - addLocalPrinterDropDown.y - UM.Theme.getSize("expandable_component_content_header").height - UM.Theme.getSize("default_margin").height
}
}
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2021 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
@ -17,7 +17,7 @@ Item
id: base
height: networkPrinterInfo.height + controlsRectangle.height
property alias maxItemCountAtOnce: networkPrinterScrollView.maxItemCountAtOnce
property alias maxItemCountAtOnce: networkPrinterListView.maxItemCountAtOnce
property var currentItem: (networkPrinterListView.currentIndex >= 0)
? networkPrinterListView.model[networkPrinterListView.currentIndex]
: null
@ -29,7 +29,7 @@ Item
Item
{
id: networkPrinterInfo
height: networkPrinterScrollView.visible ? networkPrinterScrollView.height : noPrinterLabel.height
height: networkPrinterListView.visible ? networkPrinterListView.height : noPrinterLabel.height
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
@ -44,104 +44,90 @@ Item
visible: networkPrinterListView.count == 0 // Do not show if there are discovered devices.
}
ScrollView
ListView
{
id: networkPrinterScrollView
id: networkPrinterListView
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
ScrollBar.vertical.policy: ScrollBar.AsNeeded
property int maxItemCountAtOnce: 8 // show at max 8 items at once, otherwise you need to scroll.
height: Math.min(contentHeight, (maxItemCountAtOnce * UM.Theme.getSize("action_button").height) - UM.Theme.getSize("default_margin").height)
ScrollBar.vertical: UM.ScrollBar
{
id: networkPrinterScrollBar
}
clip: true
property int maxItemCountAtOnce: 8 // show at max 8 items at once, otherwise you need to scroll.
visible: networkPrinterListView.count > 0
clip: true
model: contentLoader.enabled ? CuraApplication.getDiscoveredPrintersModel().discoveredPrinters: undefined
cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item.
ListView
section.property: "modelData.sectionName"
section.criteria: ViewSection.FullString
section.delegate: UM.Label
{
id: networkPrinterListView
anchors.fill: parent
model: contentLoader.enabled ? CuraApplication.getDiscoveredPrintersModel().discoveredPrinters: undefined
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
width: parent.width - networkPrinterScrollBar.width - UM.Theme.getSize("default_margin").width
height: UM.Theme.getSize("setting_control").height
text: section
color: UM.Theme.getColor("small_button_text")
}
section.property: "modelData.sectionName"
section.criteria: ViewSection.FullString
section.delegate: sectionHeading
boundsBehavior: Flickable.StopAtBounds
flickDeceleration: 20000 // To prevent the flicking behavior.
cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item.
Component.onCompleted:
Component.onCompleted:
{
var toSelectIndex = -1
// Select the first one that's not "unknown" and is the host a group by default.
for (var i = 0; i < count; i++)
{
var toSelectIndex = -1
// Select the first one that's not "unknown" and is the host a group by default.
for (var i = 0; i < count; i++)
if (!model[i].isUnknownMachineType && model[i].isHostOfGroup)
{
if (!model[i].isUnknownMachineType && model[i].isHostOfGroup)
{
toSelectIndex = i
break
}
}
currentIndex = toSelectIndex
}
// CURA-6483 For some reason currentIndex can be reset to 0. This check is here to prevent automatically
// selecting an unknown or non-host printer.
onCurrentIndexChanged:
{
var item = model[currentIndex]
if (!item || item.isUnknownMachineType || !item.isHostOfGroup)
{
currentIndex = -1
toSelectIndex = i
break
}
}
currentIndex = toSelectIndex
}
Component
// CURA-6483 For some reason currentIndex can be reset to 0. This check is here to prevent automatically
// selecting an unknown or non-host printer.
onCurrentIndexChanged:
{
var item = model[currentIndex]
if (!item || item.isUnknownMachineType || !item.isHostOfGroup)
{
id: sectionHeading
currentIndex = -1
}
}
UM.Label
{
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
height: UM.Theme.getSize("setting_control").height
text: section
color: UM.Theme.getColor("small_button_text")
}
delegate: Cura.MachineSelectorButton
{
text: modelData.device.name
width: networkPrinterListView.width - networkPrinterScrollBar.width
outputDevice: modelData.device
enabled: !modelData.isUnknownMachineType && modelData.isHostOfGroup
printerTypeLabelAutoFit: true
// update printer types for all items in the list
updatePrinterTypesOnlyWhenChecked: false
updatePrinterTypesFunction: updateMachineTypes
// show printer type as it is
printerTypeLabelConversionFunction: function(value) { return value }
function updateMachineTypes()
{
printerTypesList = [ modelData.readableMachineType ]
}
delegate: Cura.MachineSelectorButton
checkable: false
selected: networkPrinterListView.currentIndex == model.index
onClicked:
{
text: modelData.device.name
width: networkPrinterListView.width
outputDevice: modelData.device
enabled: !modelData.isUnknownMachineType && modelData.isHostOfGroup
printerTypeLabelAutoFit: true
// update printer types for all items in the list
updatePrinterTypesOnlyWhenChecked: false
updatePrinterTypesFunction: updateMachineTypes
// show printer type as it is
printerTypeLabelConversionFunction: function(value) { return value }
function updateMachineTypes()
{
printerTypesList = [ modelData.readableMachineType ]
}
checkable: false
selected: ListView.view.currentIndex == model.index
onClicked:
{
ListView.view.currentIndex = index
}
networkPrinterListView.currentIndex = index
}
}
}

View file

@ -37,8 +37,6 @@ Item
anchors.left: parent.left
anchors.right: parent.right
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
textArea.text: CuraApplication.getTextManager().getChangeLogText()
textArea.textFormat: Text.RichText
textArea.wrapMode: Text.WordWrap

View file

@ -1,4 +1,4 @@
// Copyright (c) 2019 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
@ -61,7 +61,7 @@ Item
anchors.left: header.left
anchors.right: header.right
// Add 2x lining, because it needs a bit of space on the top and the bottom.
height: contentLoader.item.height + 2 * UM.Theme.getSize("thick_lining").height
height: contentLoader.item ? contentLoader.item.height + 2 * UM.Theme.getSize("thick_lining").height : 0
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")

View file

@ -113,8 +113,6 @@ Item
right: subpageImage.right
}
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
back_color: UM.Theme.getColor("viewport_overlay")
do_borders: false

View file

@ -1,4 +1,4 @@
// Copyright (c) 2019 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
@ -100,12 +100,12 @@ ComboBox
contentItem: ListView
{
clip: true
implicitHeight: contentHeight
ScrollBar.vertical: UM.ScrollBar {}
clip: true
model: control.popup.visible ? control.delegateModel : null
currentIndex: control.highlightedIndex
ScrollIndicator.vertical: ScrollIndicator { }
}
background: Rectangle

View file

@ -1,46 +0,0 @@
// Copyright (c) 2020 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
import UM 1.1 as UM
ScrollView
{
clip: true
// Setting this property to false hides the scrollbar both when the scrollbar is not needed (child height < height)
// and when the scrollbar is not actively being hovered or pressed
property bool scrollAlwaysVisible: true
ScrollBar.vertical: ScrollBar
{
hoverEnabled: true
policy: parent.scrollAlwaysVisible ? ScrollBar.AlwaysOn : ScrollBar.AsNeeded
anchors.top: parent.top
anchors.right: parent.right
anchors.bottom: parent.bottom
contentItem: Rectangle
{
implicitWidth: UM.Theme.getSize("scrollbar").width
opacity: (parent.active || parent.parent.scrollAlwaysVisible) ? 1.0 : 0.0
radius: Math.round(width / 2)
color:
{
if (parent.pressed)
{
return UM.Theme.getColor("scrollbar_handle_down")
}
else if (parent.hovered)
{
return UM.Theme.getColor("scrollbar_handle_hover")
}
return UM.Theme.getColor("scrollbar_handle")
}
Behavior on color { ColorAnimation { duration: 100; } }
Behavior on opacity { NumberAnimation { duration: 100 } }
}
}
}

View file

@ -1,35 +1,39 @@
// Copyright (c) 2019 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
import UM 1.3 as UM
import UM 1.5 as UM
import Cura 1.1 as Cura
//
// Cura-style TextArea with scrolls
//
ScrollView
Flickable
{
property alias textArea: _textArea
id: scrollableTextAreaBase
property bool do_borders: true
property var back_color: UM.Theme.getColor("main_background")
property var do_borders: true
property alias textArea: flickableTextArea
clip: true
ScrollBar.vertical: UM.ScrollBar {}
background: Rectangle // Border
TextArea.flickable: TextArea
{
color: back_color
border.color: UM.Theme.getColor("thick_lining")
border.width: do_borders ? UM.Theme.getSize("default_lining").width : 0
}
id: flickableTextArea
background: Rectangle //Providing the background color and border.
{
anchors.fill: parent
anchors.margins: -border.width
color: scrollableTextAreaBase.back_color
border.color: UM.Theme.getColor("thick_lining")
border.width: scrollableTextAreaBase.do_borders ? UM.Theme.getSize("default_lining").width : 0
}
TextArea
{
id: _textArea
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
textFormat: TextEdit.PlainText
@ -37,4 +41,4 @@ ScrollView
wrapMode: Text.Wrap
selectByMouse: true
}
}
}

View file

@ -4,6 +4,7 @@ MachineSelector 1.0 MachineSelector.qml
MachineSelectorButton 1.0 MachineSelectorButton.qml
CustomConfigurationSelector 1.0 CustomConfigurationSelector.qml
PrintSetupSelector 1.0 PrintSetupSelector.qml
ProfileOverview 1.6 ProfileOverview.qml
ActionButton 1.0 ActionButton.qml
MaterialMenu 1.0 MaterialMenu.qml
NozzleMenu 1.0 NozzleMenu.qml