WIP: Rework profile management page

This commit is contained in:
Lipu Fei 2018-02-16 16:40:09 +01:00
parent bed2106fc6
commit 96f1264364
9 changed files with 561 additions and 36 deletions

View File

@ -61,6 +61,7 @@ from cura.Settings.UserProfilesModel import UserProfilesModel
from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager
from cura.Machines.VariantManager import VariantManager from cura.Machines.VariantManager import VariantManager
from cura.Machines.Models.QualityManagementModel import QualityManagementModel
from . import PlatformPhysics from . import PlatformPhysics
from . import BuildVolume from . import BuildVolume
@ -939,6 +940,9 @@ class CuraApplication(QtApplication):
qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel")
qmlRegisterType(NewMaterialsModel, "Cura", 1, 0, "NewMaterialsModel") qmlRegisterType(NewMaterialsModel, "Cura", 1, 0, "NewMaterialsModel")
# TODO: make this singleton?
qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel")
qmlRegisterSingletonType(NewQualityProfilesModel, "Cura", 1, 0, "NewQualityProfilesModel", self.getNewQualityProfileModel) qmlRegisterSingletonType(NewQualityProfilesModel, "Cura", 1, 0, "NewQualityProfilesModel", self.getNewQualityProfileModel)
qmlRegisterSingletonType(NewCustomQualityProfilesModel, "Cura", 1, 0, "NewCustomQualityProfilesModel", self.getNewCustomQualityProfilesModel) qmlRegisterSingletonType(NewCustomQualityProfilesModel, "Cura", 1, 0, "NewCustomQualityProfilesModel", self.getNewCustomQualityProfilesModel)
qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel") qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel")

View File

@ -59,7 +59,7 @@ class MaterialManager(QObject):
self._update_timer = QTimer(self) self._update_timer = QTimer(self)
self._update_timer.setInterval(300) self._update_timer.setInterval(300)
self._update_timer.setSingleShot(True) self._update_timer.setSingleShot(True)
self._update_timer.timeout.connect(self._updateTables) self._update_timer.timeout.connect(self._updateMaps)
self._container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged) self._container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged)
self._container_registry.containerAdded.connect(self._onContainerMetadataChanged) self._container_registry.containerAdded.connect(self._onContainerMetadataChanged)
@ -192,7 +192,7 @@ class MaterialManager(QObject):
self.materialsUpdated.emit() self.materialsUpdated.emit()
def _updateTables(self): def _updateMaps(self):
self.initialize() self.initialize()
def _onContainerMetadataChanged(self, container): def _onContainerMetadataChanged(self, container):
@ -203,7 +203,7 @@ class MaterialManager(QObject):
if container_type != "material": if container_type != "material":
return return
# TODO: update the cache table # update the maps
self._update_timer.start() self._update_timer.start()
def getMaterialGroup(self, root_material_id: str) -> Optional[MaterialGroup]: def getMaterialGroup(self, root_material_id: str) -> Optional[MaterialGroup]:

View File

@ -0,0 +1,75 @@
from PyQt5.QtCore import Qt
from UM.Qt.ListModel import ListModel
class QualityManagementModel(ListModel):
NameRole = Qt.UserRole + 1
IsReadOnlyRole = Qt.UserRole + 2
QualityGroupRole = Qt.UserRole + 3
QualityChangesGroupRole = Qt.UserRole + 4
def __init__(self, parent = None):
super().__init__(parent)
self.addRoleName(self.NameRole, "name")
self.addRoleName(self.IsReadOnlyRole, "is_read_only")
self.addRoleName(self.QualityGroupRole, "quality_group")
self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group")
from cura.CuraApplication import CuraApplication
self._container_registry = CuraApplication.getInstance().getContainerRegistry()
self._machine_manager = CuraApplication.getInstance().getMachineManager()
self._extruder_manager = CuraApplication.getInstance().getExtruderManager()
self._quality_manager = CuraApplication.getInstance()._quality_manager
self._machine_manager.globalContainerChanged.connect(self._update)
#self._quality_manager.materialsUpdated.connect(self._update) # TODO
self._update()
def _update(self):
global_stack = self._machine_manager._global_container_stack
quality_group_dict = self._quality_manager.getQualityGroups(global_stack)
quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(global_stack)
available_quality_types = set(qt for qt, qg in quality_group_dict.items() if qg.is_available)
if not available_quality_types and not quality_changes_group_dict:
# Nothing to show
self.setItems([])
return
item_list = []
# Create quality group items
for quality_group in quality_group_dict.values():
if not quality_group.is_available:
continue
item = {"name": quality_group.name,
"is_read_only": True,
"quality_group": quality_group,
"quality_changes_group": None}
item_list.append(item)
# Sort by quality names
item_list = sorted(item_list, key = lambda x: x["name"])
# Create quality_changes group items
quality_changes_item_list = []
for quality_changes_group in quality_changes_group_dict.values():
if quality_changes_group.quality_type not in available_quality_types:
continue
quality_group = quality_group_dict[quality_changes_group.quality_type]
item = {"name": quality_changes_group.name,
"is_read_only": False,
"quality_group": quality_group,
"quality_changes_group": quality_changes_group}
quality_changes_item_list.append(item)
# Sort quality_changes items by names and append to the item list
quality_changes_item_list = sorted(quality_changes_item_list, key = lambda x: x["name"])
item_list += quality_changes_item_list
self.setItems(item_list)

View File

@ -1,10 +1,9 @@
from typing import Optional from typing import Optional
from PyQt5.Qt import QObject from PyQt5.QtCore import QObject, QTimer
from UM.Application import Application from UM.Application import Application
from UM.Logger import Logger from UM.Logger import Logger
from UM.Util import parseBool
from cura.Machines.ContainerGroup import ContainerGroup from cura.Machines.ContainerGroup import ContainerGroup
from cura.Machines.ContainerNode import ContainerNode from cura.Machines.ContainerNode import ContainerNode
@ -126,6 +125,15 @@ class QualityManager(QObject):
self._default_machine_definition_id = "fdmprinter" self._default_machine_definition_id = "fdmprinter"
self._container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged)
self._container_registry.containerAdded.connect(self._onContainerMetadataChanged)
self._container_registry.containerRemoved.connect(self._onContainerMetadataChanged)
self._update_timer = QTimer(self)
self._update_timer.setInterval(300)
self._update_timer.setSingleShot(True)
self._update_timer.timeout.connect(self._updateMaps)
def initialize(self): def initialize(self):
# Initialize the lookup tree for quality profiles with following structure: # Initialize the lookup tree for quality profiles with following structure:
# <machine> -> <variant> -> <material> # <machine> -> <variant> -> <material>
@ -186,10 +194,6 @@ class QualityManager(QObject):
material_node.addQualityMetadata(quality_type, metadata) material_node.addQualityMetadata(quality_type, metadata)
# Initialize quality
self._initializeQualityChangesTables()
def _initializeQualityChangesTables(self):
# Initialize the lookup tree for quality_changes profiles with following structure: # Initialize the lookup tree for quality_changes profiles with following structure:
# <machine> -> <quality_type> -> <name> # <machine> -> <quality_type> -> <name>
quality_changes_metadata_list = self._container_registry.findContainersMetadata(type = "quality_changes") quality_changes_metadata_list = self._container_registry.findContainersMetadata(type = "quality_changes")
@ -206,6 +210,20 @@ class QualityManager(QObject):
machine_node.addQualityChangesMetadata(quality_type, metadata) machine_node.addQualityChangesMetadata(quality_type, metadata)
def _updateMaps(self):
self.initialize()
def _onContainerMetadataChanged(self, container):
self._onContainerChanged(container)
def _onContainerChanged(self, container):
container_type = container.getMetaDataEntry("type")
if container_type not in ("quality", "quality_changes"):
return
# update the cache table
self._update_timer.start()
# Updates the given quality groups' availabilities according to which extruders are being used/ enabled. # Updates the given quality groups' availabilities according to which extruders are being used/ enabled.
def _updateQualityGroupsAvailability(self, machine: "GlobalStack", quality_group_list): def _updateQualityGroupsAvailability(self, machine: "GlobalStack", quality_group_list):
used_extruders = set() used_extruders = set()
@ -234,8 +252,8 @@ class QualityManager(QObject):
machine_node = self._machine_quality_type_to_quality_changes_dict.get(machine_definition_id) machine_node = self._machine_quality_type_to_quality_changes_dict.get(machine_definition_id)
if not machine_node: if not machine_node:
Logger.log("e", "Cannot find node for machine def [%s] in QualityChanges lookup table", machine_definition_id) Logger.log("i", "Cannot find node for machine def [%s] in QualityChanges lookup table", machine_definition_id)
return {} return dict()
# Update availability for each QualityChangesGroup: # Update availability for each QualityChangesGroup:
# A custom profile is always available as long as the quality_type it's based on is available # A custom profile is always available as long as the quality_type it's based on is available

View File

@ -12,7 +12,6 @@ from UM.Signal import Signal
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer
import UM.FlameProfiler import UM.FlameProfiler
from UM.FlameProfiler import pyqtSlot from UM.FlameProfiler import pyqtSlot
from PyQt5.QtWidgets import QMessageBox
from UM import Util from UM import Util
from UM.Application import Application from UM.Application import Application
@ -1371,27 +1370,6 @@ class MachineManager(QObject):
self._current_root_material_id[position] = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file") self._current_root_material_id[position] = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file")
return self._current_root_material_id return self._current_root_material_id
def _setQualityChangesGroup(self, quality_changes_group):
self._current_quality_changes_group = quality_changes_group
# TODO: quality_changes groups depend on a quality_type. Here it's fetching the quality_types every time.
# Can we do this better, like caching the quality group a quality_changes group depends on?
quality_manager = Application.getInstance()._quality_manager
quality_group_dict = quality_manager.getQualityGroups(self._global_container_stack)
quality_type = quality_changes_group.quality_type
container = self._empty_quality_changes_container
if quality_changes_group.node_for_global is not None:
container = quality_changes_group.node_for_global.getContainer()
self._global_container_stack.qualityChanges = container
self._global_container_stack.quality = quality_group_dict[quality_type]
for position, extruder in self._global_container_stack.extruders.items():
container = quality_changes_group.nodes_for_extruders.get(position,
self._empty_quality_changes_container)
extruder.qualityChanges = container
def _setEmptyQuality(self): def _setEmptyQuality(self):
self._current_quality_group = None self._current_quality_group = None
self._global_container_stack.quality = self._empty_quality_container self._global_container_stack.quality = self._empty_quality_container
@ -1405,8 +1383,6 @@ class MachineManager(QObject):
def _setQualityGroup(self, quality_group, empty_quality_changes = True): def _setQualityGroup(self, quality_group, empty_quality_changes = True):
self._current_quality_group = quality_group self._current_quality_group = quality_group
#TODO: check quality_changes
# Set quality and quality_changes for the GlobalStack # Set quality and quality_changes for the GlobalStack
self._global_container_stack.quality = quality_group.node_for_global.getContainer() self._global_container_stack.quality = quality_group.node_for_global.getContainer()
if empty_quality_changes: if empty_quality_changes:
@ -1419,6 +1395,44 @@ class MachineManager(QObject):
self._global_container_stack.extruders[position].qualityChanges = self._empty_quality_changes_container self._global_container_stack.extruders[position].qualityChanges = self._empty_quality_changes_container
self.activeQualityGroupChanged.emit() self.activeQualityGroupChanged.emit()
self.activeQualityChangesGroupChanged.emit()
def _setQualityChangesGroup(self, quality_changes_group):
# TODO: quality_changes groups depend on a quality_type. Here it's fetching the quality_types every time.
# Can we do this better, like caching the quality group a quality_changes group depends on?
quality_type = quality_changes_group.quality_type
quality_manager = Application.getInstance()._quality_manager
quality_group_dict = quality_manager.getQualityGroups(self._global_container_stack)
quality_group = quality_group_dict[quality_type]
quality_changes_container = self._empty_quality_changes_container
quality_container = self._empty_quality_changes_container
if quality_changes_group.node_for_global:
quality_changes_container = quality_changes_group.node_for_global.getContainer()
if quality_group.node_for_global:
quality_container = quality_group.node_for_global.getContainer()
self._global_container_stack.quality = quality_container
self._global_container_stack.qualityChanges = quality_changes_container
for position, extruder in self._global_container_stack.extruders.items():
quality_changes_node = quality_changes_group.nodes_for_extruders.get(position)
quality_node = quality_group.nodes_for_extruders.get(position)
quality_changes_container = self._empty_quality_changes_container
quality_container = self._empty_quality_changes_container
if quality_changes_node:
quality_changes_container = quality_changes_node.getContainer()
if quality_node:
quality_container = quality_node.getContainer()
extruder.quality = quality_container
extruder.qualityChanges = quality_changes_container
self._current_quality_group = quality_group
self._current_quality_changes_group = quality_changes_group
self.activeQualityGroupChanged.emit()
self.activeQualityChangesGroupChanged.emit()
def _setVariantGroup(self, position, container_node): def _setVariantGroup(self, position, container_node):
self._global_container_stack.extruders[position].variant = container_node.getContainer() self._global_container_stack.extruders[position].variant = container_node.getContainer()
@ -1515,3 +1529,23 @@ class MachineManager(QObject):
def activeQualityGroup(self): def activeQualityGroup(self):
return self._current_quality_group return self._current_quality_group
@pyqtSlot("QVariant")
def setQualityChangesGroup(self, quality_changes_group):
Logger.log("d", "---------------- qcg = [%s]", quality_changes_group.name)
self.blurSettings.emit()
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
self._setQualityChangesGroup(quality_changes_group)
Logger.log("d", "Quality changes set!")
@pyqtProperty("QVariant", fset = setQualityChangesGroup, notify = activeQualityChangesGroupChanged)
def activeQualityChangesGroup(self):
return self._current_quality_changes_group
@pyqtProperty(str, notify = activeQualityGroupChanged)
def activeQualityOrQualityChangesName(self):
name = ""
if self._current_quality_changes_group:
name = self._current_quality_changes_group.name
elif self._current_quality_group:
name = self._current_quality_group.name
return name

View File

@ -2,7 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import Any, List, Optional from typing import Any, List, Optional
from PyQt5.QtCore import Qt, QObject from PyQt5.QtCore import Qt
from UM.Logger import Logger from UM.Logger import Logger
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel

View File

@ -27,6 +27,7 @@ class NewQualityProfilesModel(ListModel):
LayerHeightRole = Qt.UserRole + 4 LayerHeightRole = Qt.UserRole + 4
AvailableRole = Qt.UserRole + 5 AvailableRole = Qt.UserRole + 5
QualityGroupRole = Qt.UserRole + 6 QualityGroupRole = Qt.UserRole + 6
QualityChangesGroupRole = Qt.UserRole + 7
def __init__(self, parent = None): def __init__(self, parent = None):
super().__init__(parent) super().__init__(parent)
@ -37,6 +38,7 @@ class NewQualityProfilesModel(ListModel):
self.addRoleName(self.LayerHeightRole, "layer_height") self.addRoleName(self.LayerHeightRole, "layer_height")
self.addRoleName(self.AvailableRole, "available") self.addRoleName(self.AvailableRole, "available")
self.addRoleName(self.QualityGroupRole, "quality_group") self.addRoleName(self.QualityGroupRole, "quality_group")
self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group")
# connect signals # connect signals
Application.getInstance().globalContainerStackChanged.connect(self._update) Application.getInstance().globalContainerStackChanged.connect(self._update)

View File

@ -0,0 +1,98 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.8
import QtQuick.Controls 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
Tab
{
id: base
property string extruderId: "";
property string extruderDefinition: "";
property string quality: "";
property string material: "";
TableView
{
anchors.fill: parent
anchors.margins: UM.Theme.getSize("default_margin").width
Component
{
id: itemDelegate
UM.TooltipArea
{
property var setting: qualitySettings.getItem(styleData.row)
height: childrenRect.height
width: (parent != null) ? parent.width : 0
text: (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: (styleData.value.substr(0,1) == "=") ? catalog.i18nc("@info:status", "Calculated") : styleData.value
font.strikeout: styleData.column == 1 && quality == Cura.MachineManager.globalQualityId && setting.user_value != ""
font.italic: setting.profile_value_source == "quality_changes" || (quality == Cura.MachineManager.globalQualityId && setting.user_value != "")
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: quality == Cura.MachineManager.globalQualityId
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
extruderId: base.extruderId
extruderDefinition: base.extruderDefinition
quality: base.quality != null ? base.quality : ""
material: base.material != null ? base.material : ""
}
SystemPalette { id: palette }
}
}

View File

@ -0,0 +1,294 @@
// Copyright (c) 2018 Ultimaker B.V.
// Uranium is released under the terms of the LGPLv3 or higher.
import QtQuick 2.8
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.3
import UM 1.2 as UM
import Cura 1.0 as Cura
Item
{
id: base
property var resetEnabled: false // Keep PreferencesDialog happy
UM.I18nCatalog { id: catalog; name: "cura"; }
Cura.QualityManagementModel {
id: qualitiesModel
}
Label {
id: titleLabel
anchors {
top: parent.top
left: parent.left
right: parent.right
margins: 5 * screenScaleFactor
}
font.pointSize: 18
text: catalog.i18nc("@title:tab", "Profiles")
}
Row // Button Row
{
id: buttonRow
anchors {
left: parent.left
right: parent.right
top: titleLabel.bottom
}
height: childrenRect.height
// Activate button
Button
{
text: catalog.i18nc("@action:button", "Activate")
iconName: "list-activate"
//enabled: base.currentItem != null ? base.currentItem.id != Cura.MachineManager.activeQualityId : false;
enabled: true // TODO
onClicked: {
// TODO
}
}
// Create button
Button
{
text: catalog.i18nc("@label", "Create")
iconName: "list-add"
//enabled: base.canCreateProfile() && !Cura.MachineManager.stacksHaveErrors
enabled: true // TODO
//visible: base.canCreateProfile()
visible: true // TODO
onClicked: {
// TODO
}
}
// Duplicate button
Button
{
text: catalog.i18nc("@label", "Duplicate")
iconName: "list-add"
//enabled: ! base.canCreateProfile()
enabled: true // TODO
//visible: ! base.canCreateProfile()
visible: true // TODO
onClicked: {
// TODO
}
}
// Remove button
Button
{
text: catalog.i18nc("@action:button", "Remove")
iconName: "list-remove"
//enabled: base.currentItem != null ? !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id) : false;
enabled: true // TODO
onClicked: {
// TODO
}
}
// Rename button
Button
{
text: catalog.i18nc("@action:button", "Rename")
iconName: "edit-rename"
//enabled: base.currentItem != null ? !base.currentItem.readOnly : false;
enabled: true // TODO
onClicked: {
// TODO
}
}
// Import button
Button
{
text: catalog.i18nc("@action:button", "Import")
iconName: "document-import"
onClicked: {
// TODO
}
}
// Export button
Button
{
text: catalog.i18nc("@action:button", "Export")
iconName: "document-export"
//enabled: currentItem != null && !base.currentItem.readOnly
enabled: true // TODO
onClicked: {
// TODO
}
}
}
Item {
id: contentsItem
anchors {
top: titleLabel.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
margins: 5 * screenScaleFactor
bottomMargin: 0
}
clip: true
}
Item
{
anchors {
top: buttonRow.bottom
topMargin: UM.Theme.getSize("default_margin").height
left: parent.left
right: parent.right
bottom: parent.bottom
}
SystemPalette { id: palette }
Label
{
id: captionLabel
anchors {
top: parent.top
left: parent.left
}
visible: text != ""
text: {
// OLD STUFF
return catalog.i18nc("@label %1 is printer name", "Printer: %1").arg(Cura.MachineManager.activeMachineName);
}
width: profileScrollView.width
elide: Text.ElideRight
}
ScrollView
{
id: profileScrollView
anchors {
top: captionLabel.visible ? captionLabel.bottom : parent.top
topMargin: captionLabel.visible ? UM.Theme.getSize("default_margin").height : 0
bottom: parent.bottom
left: parent.left
}
Rectangle {
parent: viewport
anchors.fill: parent
color: palette.light
}
width: true ? (parent.width * 0.4) | 0 : parent.width
ListView
{
id: qualityListView
model: qualitiesModel
section.property: "is_read_only"
section.delegate: Rectangle
{
height: childrenRect.height
Label
{
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_lining").width
text: section == "true" ? catalog.i18nc("@label", "Protected profiles") : catalog.i18nc("@label", "Custom profiles")
font.bold: true
}
}
delegate: Rectangle
{
width: profileScrollView.width
height: childrenRect.height
color: ListView.isCurrentItem ? palette.highlight : (model.index % 2) ? palette.base : palette.alternateBase
Row
{
spacing: (UM.Theme.getSize("default_margin").width / 2) | 0
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.right: parent.right
Label
{
width: Math.floor((parent.width * 0.3))
text: model.name
elide: Text.ElideRight
font.italic: { // TODO: make it easier
return model.name == Cura.MachineManager.activeQualityOrQualityChangesName;
}
color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
}
}
MouseArea
{
anchors.fill: parent
onClicked: {
parent.ListView.view.currentIndex = model.index;
}
}
}
onCurrentIndexChanged:
{
var model = qualitiesModel.getItem(currentIndex);
// TODO
}
}
}
Item
{
id: detailsPanel
anchors {
left: profileScrollView.right
leftMargin: UM.Theme.getSize("default_margin").width
top: parent.top
bottom: parent.bottom
right: parent.right
}
Item
{
anchors.fill: parent
Item // Profile title Label
{
id: profileName
width: parent.width
height: childrenRect.height
Label {
text: "TODO" // TODO
font: UM.Theme.getFont("large")
}
}
}
}
}
}