mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-05 13:03:59 -06:00
Merge branch 'feature_intent'
Here we go! Contributes to issue CURA-6864.
This commit is contained in:
commit
cf14fa6820
154 changed files with 5293 additions and 4600 deletions
|
@ -7,7 +7,7 @@ import QtQuick.Layouts 1.3
|
|||
import QtQuick.Dialogs 1.2
|
||||
|
||||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
import Cura 1.5 as Cura
|
||||
|
||||
Item
|
||||
{
|
||||
|
@ -17,6 +17,8 @@ Item
|
|||
property var resetEnabled: false
|
||||
property var currentItem: null
|
||||
|
||||
property var materialManagementModel: CuraApplication.getMaterialManagementModel()
|
||||
|
||||
property var hasCurrentItem: base.currentItem != null
|
||||
property var isCurrentItemActivated:
|
||||
{
|
||||
|
@ -119,7 +121,7 @@ Item
|
|||
onClicked:
|
||||
{
|
||||
forceActiveFocus();
|
||||
base.newRootMaterialIdToSwitchTo = CuraApplication.getMaterialManager().createMaterial();
|
||||
base.newRootMaterialIdToSwitchTo = base.materialManagementModel.createMaterial();
|
||||
base.toActivateNewMaterial = true;
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +136,7 @@ Item
|
|||
onClicked:
|
||||
{
|
||||
forceActiveFocus();
|
||||
base.newRootMaterialIdToSwitchTo = CuraApplication.getMaterialManager().duplicateMaterial(base.currentItem.container_node);
|
||||
base.newRootMaterialIdToSwitchTo = base.materialManagementModel.duplicateMaterial(base.currentItem.container_node);
|
||||
base.toActivateNewMaterial = true;
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +147,8 @@ Item
|
|||
id: removeMenuButton
|
||||
text: catalog.i18nc("@action:button", "Remove")
|
||||
iconName: "list-remove"
|
||||
enabled: base.hasCurrentItem && !base.currentItem.is_read_only && !base.isCurrentItemActivated && CuraApplication.getMaterialManager().canMaterialBeRemoved(base.currentItem.container_node)
|
||||
enabled: base.hasCurrentItem && !base.currentItem.is_read_only && !base.isCurrentItemActivated && base.materialManagementModel.canMaterialBeRemoved(base.currentItem.container_node)
|
||||
|
||||
onClicked:
|
||||
{
|
||||
forceActiveFocus();
|
||||
|
@ -294,7 +297,7 @@ Item
|
|||
{
|
||||
// Set the active material as the fallback. It will be selected when the current material is deleted
|
||||
base.newRootMaterialIdToSwitchTo = base.active_root_material_id
|
||||
CuraApplication.getMaterialManager().removeMaterial(base.currentItem.container_node);
|
||||
base.materialManagementModel.removeMaterial(base.currentItem.container_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,11 +82,12 @@ Rectangle
|
|||
{
|
||||
if (materialSlot.is_favorite)
|
||||
{
|
||||
CuraApplication.getMaterialManager().removeFavorite(material.root_material_id)
|
||||
return
|
||||
CuraApplication.getMaterialManagementModel().removeFavorite(material.root_material_id)
|
||||
}
|
||||
else
|
||||
{
|
||||
CuraApplication.getMaterialManagementModel().addFavorite(material.root_material_id)
|
||||
}
|
||||
CuraApplication.getMaterialManager().addFavorite(material.root_material_id)
|
||||
return
|
||||
}
|
||||
style: ButtonStyle
|
||||
{
|
||||
|
|
|
@ -23,6 +23,7 @@ TabView
|
|||
property real secondColumnWidth: (width * 0.40) | 0
|
||||
property string containerId: ""
|
||||
property var materialPreferenceValues: UM.Preferences.getValue("cura/material_settings") ? JSON.parse(UM.Preferences.getValue("cura/material_settings")) : {}
|
||||
property var materialManagementModel: CuraApplication.getMaterialManagementModel()
|
||||
|
||||
property double spoolLength: calculateSpoolLength()
|
||||
property real costPerMeter: calculateCostPerMeter()
|
||||
|
@ -565,7 +566,7 @@ TabView
|
|||
}
|
||||
|
||||
// update the values
|
||||
CuraApplication.getMaterialManager().setMaterialName(base.currentMaterialNode, new_name)
|
||||
base.materialManagementModel.setMaterialName(base.currentMaterialNode, new_name)
|
||||
properties.name = new_name
|
||||
}
|
||||
|
||||
|
|
|
@ -38,14 +38,28 @@ Tab
|
|||
property var setting: qualitySettings.getItem(styleData.row)
|
||||
height: childrenRect.height
|
||||
width: (parent != null) ? parent.width : 0
|
||||
text: (styleData.value.substr(0,1) == "=") ? styleData.value : ""
|
||||
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: (styleData.value.substr(0,1) == "=") ? catalog.i18nc("@info:status", "Calculated") : styleData.value
|
||||
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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Copyright (c) 2019 Ultimaker B.V.
|
||||
// Uranium is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.7
|
||||
|
@ -7,26 +7,24 @@ import QtQuick.Layouts 1.3
|
|||
import QtQuick.Dialogs 1.2
|
||||
|
||||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
import Cura 1.6 as Cura
|
||||
|
||||
|
||||
Item
|
||||
{
|
||||
id: base
|
||||
|
||||
property QtObject qualityManager: CuraApplication.getQualityManager()
|
||||
property var resetEnabled: false // Keep PreferencesDialog happy
|
||||
property var extrudersModel: CuraApplication.getExtrudersModel()
|
||||
property var qualityManagementModel: CuraApplication.getQualityManagementModel()
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
|
||||
Cura.QualityManagementModel {
|
||||
id: qualitiesModel
|
||||
}
|
||||
|
||||
Label {
|
||||
Label
|
||||
{
|
||||
id: titleLabel
|
||||
anchors {
|
||||
anchors
|
||||
{
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
|
@ -38,28 +36,41 @@ Item
|
|||
|
||||
property var hasCurrentItem: base.currentItem != null
|
||||
|
||||
property var currentItem: {
|
||||
property var currentItem:
|
||||
{
|
||||
var current_index = qualityListView.currentIndex;
|
||||
return (current_index == -1) ? null : qualitiesModel.getItem(current_index);
|
||||
return (current_index == -1) ? null : base.qualityManagementModel.getItem(current_index);
|
||||
}
|
||||
|
||||
property var currentItemName: hasCurrentItem ? base.currentItem.name : ""
|
||||
property var currentItemDisplayName: hasCurrentItem ? base.qualityManagementModel.getQualityItemDisplayName(base.currentItem) : ""
|
||||
|
||||
property var isCurrentItemActivated: {
|
||||
if (!base.currentItem) {
|
||||
property var isCurrentItemActivated:
|
||||
{
|
||||
if (!base.currentItem)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return base.currentItem.name == Cura.MachineManager.activeQualityOrQualityChangesName;
|
||||
if (base.currentItem.is_read_only)
|
||||
{
|
||||
return (base.currentItem.name == Cura.MachineManager.activeQualityOrQualityChangesName) && (base.currentItem.intent_category == Cura.MachineManager.activeIntentCategory);
|
||||
}
|
||||
else
|
||||
{
|
||||
return base.currentItem.name == Cura.MachineManager.activeQualityOrQualityChangesName;
|
||||
}
|
||||
}
|
||||
|
||||
property var canCreateProfile: {
|
||||
property var canCreateProfile:
|
||||
{
|
||||
return isCurrentItemActivated && Cura.MachineManager.hasUserSettings;
|
||||
}
|
||||
|
||||
Row // Button Row
|
||||
{
|
||||
id: buttonRow
|
||||
anchors {
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: titleLabel.bottom
|
||||
|
@ -73,10 +84,14 @@ Item
|
|||
text: catalog.i18nc("@action:button", "Activate")
|
||||
iconName: "list-activate"
|
||||
enabled: !isCurrentItemActivated
|
||||
onClicked: {
|
||||
if (base.currentItem.is_read_only) {
|
||||
Cura.MachineManager.setQualityGroup(base.currentItem.quality_group);
|
||||
} else {
|
||||
onClicked:
|
||||
{
|
||||
if (base.currentItem.is_read_only)
|
||||
{
|
||||
Cura.IntentManager.selectIntent(base.currentItem.intent_category, base.currentItem.quality_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cura.MachineManager.setQualityChangesGroup(base.currentItem.quality_changes_group);
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +106,8 @@ Item
|
|||
enabled: base.canCreateProfile && !Cura.MachineManager.stacksHaveErrors
|
||||
visible: base.canCreateProfile
|
||||
|
||||
onClicked: {
|
||||
onClicked:
|
||||
{
|
||||
createQualityDialog.object = Cura.ContainerManager.makeUniqueName(base.currentItem.name);
|
||||
createQualityDialog.open();
|
||||
createQualityDialog.selectText();
|
||||
|
@ -107,7 +123,8 @@ Item
|
|||
enabled: !base.canCreateProfile
|
||||
visible: !base.canCreateProfile
|
||||
|
||||
onClicked: {
|
||||
onClicked:
|
||||
{
|
||||
duplicateQualityDialog.object = Cura.ContainerManager.makeUniqueName(base.currentItem.name);
|
||||
duplicateQualityDialog.open();
|
||||
duplicateQualityDialog.selectText();
|
||||
|
@ -121,7 +138,8 @@ Item
|
|||
text: catalog.i18nc("@action:button", "Remove")
|
||||
iconName: "list-remove"
|
||||
enabled: base.hasCurrentItem && !base.currentItem.is_read_only && !base.isCurrentItemActivated
|
||||
onClicked: {
|
||||
onClicked:
|
||||
{
|
||||
forceActiveFocus();
|
||||
confirmRemoveQualityDialog.open();
|
||||
}
|
||||
|
@ -134,7 +152,8 @@ Item
|
|||
text: catalog.i18nc("@action:button", "Rename")
|
||||
iconName: "edit-rename"
|
||||
enabled: base.hasCurrentItem && !base.currentItem.is_read_only
|
||||
onClicked: {
|
||||
onClicked:
|
||||
{
|
||||
renameQualityDialog.object = base.currentItem.name;
|
||||
renameQualityDialog.open();
|
||||
renameQualityDialog.selectText();
|
||||
|
@ -147,7 +166,8 @@ Item
|
|||
id: importMenuButton
|
||||
text: catalog.i18nc("@action:button", "Import")
|
||||
iconName: "document-import"
|
||||
onClicked: {
|
||||
onClicked:
|
||||
{
|
||||
importDialog.open();
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +179,8 @@ Item
|
|||
text: catalog.i18nc("@action:button", "Export")
|
||||
iconName: "document-export"
|
||||
enabled: base.hasCurrentItem && !base.currentItem.is_read_only
|
||||
onClicked: {
|
||||
onClicked:
|
||||
{
|
||||
exportDialog.open();
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +206,7 @@ Item
|
|||
{
|
||||
base.newQualityNameToSelect = newName; // We want to switch to the new profile once it's created
|
||||
base.toActivateNewQuality = true;
|
||||
base.qualityManager.createQualityChanges(newName);
|
||||
base.qualityManagementModel.createQualityChanges(newName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,7 +216,7 @@ Item
|
|||
// This connection makes sure that we will switch to the correct quality after the model gets updated
|
||||
Connections
|
||||
{
|
||||
target: qualitiesModel
|
||||
target: base.qualityManagementModel
|
||||
onItemsChanged:
|
||||
{
|
||||
var toSelectItemName = base.currentItem == null ? "" : base.currentItem.name;
|
||||
|
@ -208,9 +229,9 @@ Item
|
|||
if (toSelectItemName != "")
|
||||
{
|
||||
// Select the required quality name if given
|
||||
for (var idx = 0; idx < qualitiesModel.count; ++idx)
|
||||
for (var idx = 0; idx < base.qualityManagementModel.count; ++idx)
|
||||
{
|
||||
var item = qualitiesModel.getItem(idx);
|
||||
var item = base.qualityManagementModel.getItem(idx);
|
||||
if (item.name == toSelectItemName)
|
||||
{
|
||||
// Switch to the newly created profile if needed
|
||||
|
@ -240,7 +261,7 @@ Item
|
|||
object: "<new name>"
|
||||
onAccepted:
|
||||
{
|
||||
base.qualityManager.duplicateQualityChanges(newName, base.currentItem);
|
||||
base.qualityManagementModel.duplicateQualityChanges(newName, base.currentItem);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,7 +278,7 @@ Item
|
|||
|
||||
onYes:
|
||||
{
|
||||
base.qualityManager.removeQualityChangesGroup(base.currentItem.quality_changes_group);
|
||||
base.qualityManagementModel.removeQualityChangesGroup(base.currentItem.quality_changes_group);
|
||||
// reset current item to the first if available
|
||||
qualityListView.currentIndex = -1; // Reset selection.
|
||||
}
|
||||
|
@ -271,7 +292,7 @@ Item
|
|||
object: "<new name>"
|
||||
onAccepted:
|
||||
{
|
||||
var actualNewName = base.qualityManager.renameQualityChangesGroup(base.currentItem.quality_changes_group, newName);
|
||||
var actualNewName = base.qualityManagementModel.renameQualityChangesGroup(base.currentItem.quality_changes_group, newName);
|
||||
base.newQualityNameToSelect = actualNewName; // Select the new name after the model gets updated
|
||||
}
|
||||
}
|
||||
|
@ -282,19 +303,22 @@ Item
|
|||
id: importDialog
|
||||
title: catalog.i18nc("@title:window", "Import Profile")
|
||||
selectExisting: true
|
||||
nameFilters: qualitiesModel.getFileNameFilters("profile_reader")
|
||||
nameFilters: base.qualityManagementModel.getFileNameFilters("profile_reader")
|
||||
folder: CuraApplication.getDefaultPath("dialog_profile_path")
|
||||
onAccepted:
|
||||
{
|
||||
var result = Cura.ContainerManager.importProfile(fileUrl);
|
||||
messageDialog.text = result.message;
|
||||
if (result.status == "ok") {
|
||||
if (result.status == "ok")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Information;
|
||||
}
|
||||
else if (result.status == "duplicate") {
|
||||
else if (result.status == "duplicate")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Warning;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Critical;
|
||||
}
|
||||
messageDialog.open();
|
||||
|
@ -308,14 +332,15 @@ Item
|
|||
id: exportDialog
|
||||
title: catalog.i18nc("@title:window", "Export Profile")
|
||||
selectExisting: false
|
||||
nameFilters: qualitiesModel.getFileNameFilters("profile_writer")
|
||||
nameFilters: base.qualityManagementModel.getFileNameFilters("profile_writer")
|
||||
folder: CuraApplication.getDefaultPath("dialog_profile_path")
|
||||
onAccepted:
|
||||
{
|
||||
var result = Cura.ContainerManager.exportQualityChangesGroup(base.currentItem.quality_changes_group,
|
||||
fileUrl, selectedNameFilter);
|
||||
|
||||
if (result && result.status == "error") {
|
||||
if (result && result.status == "error")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Critical;
|
||||
messageDialog.text = result.message;
|
||||
messageDialog.open();
|
||||
|
@ -326,10 +351,12 @@ Item
|
|||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Item
|
||||
{
|
||||
id: contentsItem
|
||||
|
||||
anchors {
|
||||
anchors
|
||||
{
|
||||
top: titleLabel.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
|
@ -343,7 +370,8 @@ Item
|
|||
|
||||
Item
|
||||
{
|
||||
anchors {
|
||||
anchors
|
||||
{
|
||||
top: buttonRow.bottom
|
||||
topMargin: UM.Theme.getSize("default_margin").height
|
||||
left: parent.left
|
||||
|
@ -351,12 +379,16 @@ Item
|
|||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
SystemPalette { id: palette }
|
||||
SystemPalette
|
||||
{
|
||||
id: palette
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: captionLabel
|
||||
anchors {
|
||||
anchors
|
||||
{
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
}
|
||||
|
@ -369,14 +401,16 @@ Item
|
|||
ScrollView
|
||||
{
|
||||
id: profileScrollView
|
||||
anchors {
|
||||
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 {
|
||||
Rectangle
|
||||
{
|
||||
parent: viewport
|
||||
anchors.fill: parent
|
||||
color: palette.light
|
||||
|
@ -390,16 +424,16 @@ Item
|
|||
{
|
||||
id: qualityListView
|
||||
|
||||
model: qualitiesModel
|
||||
model: base.qualityManagementModel
|
||||
|
||||
Component.onCompleted:
|
||||
{
|
||||
var selectedItemName = Cura.MachineManager.activeQualityOrQualityChangesName;
|
||||
|
||||
// Select the required quality name if given
|
||||
for (var idx = 0; idx < qualitiesModel.count; idx++)
|
||||
for (var idx = 0; idx < base.qualityManagementModel.count; idx++)
|
||||
{
|
||||
var item = qualitiesModel.getItem(idx);
|
||||
var item = base.qualityManagementModel.getItem(idx);
|
||||
if (item.name == selectedItemName)
|
||||
{
|
||||
currentIndex = idx;
|
||||
|
@ -408,7 +442,7 @@ Item
|
|||
}
|
||||
}
|
||||
|
||||
section.property: "is_read_only"
|
||||
section.property: "section_name"
|
||||
section.delegate: Rectangle
|
||||
{
|
||||
height: childrenRect.height
|
||||
|
@ -417,7 +451,7 @@ Item
|
|||
{
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: UM.Theme.getSize("default_lining").width
|
||||
text: section == "true" ? catalog.i18nc("@label", "Default profiles") : catalog.i18nc("@label", "Custom profiles")
|
||||
text: section
|
||||
font.bold: true
|
||||
}
|
||||
}
|
||||
|
@ -441,14 +475,27 @@ Item
|
|||
width: Math.floor((parent.width * 0.8))
|
||||
text: model.name
|
||||
elide: Text.ElideRight
|
||||
font.italic: model.name == Cura.MachineManager.activeQualityOrQualityChangesName
|
||||
font.italic:
|
||||
{
|
||||
if (model.is_read_only)
|
||||
{
|
||||
// For built-in qualities, it needs to match both the intent category and the quality name
|
||||
return model.name == Cura.MachineManager.activeQualityOrQualityChangesName && model.intent_category == Cura.MachineManager.activeIntentCategory
|
||||
}
|
||||
else
|
||||
{
|
||||
// For custom qualities, it only needs to match the name
|
||||
return model.name == Cura.MachineManager.activeQualityOrQualityChangesName
|
||||
}
|
||||
}
|
||||
color: parent.isCurrentItem ? palette.highlightedText : palette.text
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
onClicked:
|
||||
{
|
||||
parent.ListView.view.currentIndex = model.index;
|
||||
}
|
||||
}
|
||||
|
@ -461,7 +508,8 @@ Item
|
|||
{
|
||||
id: detailsPanel
|
||||
|
||||
anchors {
|
||||
anchors
|
||||
{
|
||||
left: profileScrollView.right
|
||||
leftMargin: UM.Theme.getSize("default_margin").width
|
||||
top: parent.top
|
||||
|
@ -481,15 +529,17 @@ Item
|
|||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
Label {
|
||||
text: base.currentItemName
|
||||
Label
|
||||
{
|
||||
text: base.currentItemDisplayName
|
||||
font: UM.Theme.getFont("large_bold")
|
||||
}
|
||||
}
|
||||
|
||||
Flow {
|
||||
Flow
|
||||
{
|
||||
id: currentSettingsActions
|
||||
visible: base.hasCurrentItem && base.currentItem.name == Cura.MachineManager.activeQualityOrQualityChangesName
|
||||
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
|
||||
|
@ -510,7 +560,8 @@ Item
|
|||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
Column
|
||||
{
|
||||
id: profileNotices
|
||||
anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : currentSettingsActions.anchors.top
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
|
@ -518,14 +569,16 @@ Item
|
|||
anchors.right: parent.right
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
|
||||
Label {
|
||||
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 {
|
||||
Label
|
||||
{
|
||||
id: noCurrentSettingsMessage
|
||||
visible: base.isCurrentItemActivated && !Cura.MachineManager.hasUserSettings
|
||||
text: catalog.i18nc("@action:label", "Your current settings match the selected profile.")
|
||||
|
@ -534,7 +587,6 @@ Item
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
TabView
|
||||
{
|
||||
anchors.left: parent.left
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue