diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py
index 74811e724f..7f9f0ef68d 100755
--- a/cura/CuraApplication.py
+++ b/cura/CuraApplication.py
@@ -709,6 +709,7 @@ class CuraApplication(QtApplication):
self.showMessageBox.emit(title, text, informativeText, detailedText, buttons, icon)
showDiscardOrKeepProfileChanges = pyqtSignal()
+ showCompareAndSaveProfileChanges = pyqtSignal(int)
def discardOrKeepProfileChanges(self) -> bool:
has_user_interaction = False
diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py
index b4fb8b38b5..3c3bc9a6e9 100644
--- a/cura/Machines/Models/QualityManagementModel.py
+++ b/cura/Machines/Models/QualityManagementModel.py
@@ -184,7 +184,8 @@ class QualityManagementModel(ListModel):
container_registry.addContainer(container.duplicate(new_id, new_name))
@pyqtSlot(str)
- def createQualityChanges(self, base_name: str) -> None:
+ @pyqtSlot(str, bool)
+ def createQualityChanges(self, base_name: str, activate_after_success: bool = False) -> None:
"""Create quality changes containers from the user containers in the active stacks.
This will go through the global and extruder stacks and create quality_changes containers from the user
@@ -233,6 +234,14 @@ class QualityManagementModel(ListModel):
container_registry.addContainer(new_changes)
+ if activate_after_success:
+ # At this point, the QualityChangesGroup object for the new changes may not exist yet.
+ # This can be forced by asking for all of them. At that point it's just as well to loop.
+ for quality_changes in ContainerTree.getInstance().getCurrentQualityChangesGroups():
+ if quality_changes.name == unique_name:
+ machine_manager.setQualityChangesGroup(quality_changes)
+ break
+
def _createQualityChanges(self, quality_type: str, intent_category: Optional[str], new_name: str, machine: "GlobalStack", extruder_stack: Optional["ExtruderStack"]) -> "InstanceContainer":
"""Create a quality changes container with the given set-up.
diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml
index 2ec342f502..6e36587b23 100644
--- a/resources/qml/Cura.qml
+++ b/resources/qml/Cura.qml
@@ -496,10 +496,7 @@ UM.MainWindow
target: Cura.Actions.addProfile
function onTriggered()
{
- preferences.show();
- preferences.setPage(4);
- // Create a new profile after a very short delay so the preference page has time to initiate
- createProfileTimer.start();
+ createNewQualityDialog.visible = true;
}
}
@@ -547,15 +544,6 @@ UM.MainWindow
}
}
- Timer
- {
- id: createProfileTimer
- repeat: false
- interval: 1
-
- onTriggered: preferences.getCurrentItem().createProfile()
- }
-
// BlurSettings is a way to force the focus away from any of the setting items.
// We need to do this in order to keep the bindings intact.
Connections
@@ -816,11 +804,16 @@ UM.MainWindow
Connections
{
target: CuraApplication
- function onShowDiscardOrKeepProfileChanges()
+ function onShowCompareAndSaveProfileChanges(profileState)
{
discardOrKeepProfileChangesDialogLoader.sourceComponent = discardOrKeepProfileChangesDialogComponent
+ discardOrKeepProfileChangesDialogLoader.item.buttonState = profileState
discardOrKeepProfileChangesDialogLoader.item.show()
}
+ function onShowDiscardOrKeepProfileChanges()
+ {
+ onShowCompareAndSaveProfileChanges(DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep)
+ }
}
Cura.WizardDialog
@@ -885,6 +878,49 @@ UM.MainWindow
}
}
+ Cura.RenameDialog
+ {
+ id: createNewQualityDialog
+ title: catalog.i18nc("@title:window", "Save Custom Profile")
+ objectPlaceholder: catalog.i18nc("@textfield:placeholder", "New Custom Profile")
+ explanation: catalog.i18nc("@info", "Custom profile name:")
+ extraInfo:
+ [
+ UM.ColorImage
+ {
+ width: UM.Theme.getSize("message_type_icon").width
+ height: UM.Theme.getSize("message_type_icon").height
+ source: UM.Theme.getIcon("Information")
+ color: UM.Theme.getColor("text")
+ },
+ Column
+ {
+ UM.Label
+ {
+ text: catalog.i18nc
+ (
+ "@label %i will be replaced with a profile name",
+ "Only user changed settings will be saved in the custom profile.
" +
+ "For materials that support it, the new custom profile will inherit properties from %1."
+ ).arg(Cura.MachineManager.activeQualityOrQualityChangesName)
+ wrapMode: Text.WordWrap
+ width: parent.parent.width - 2 * UM.Theme.getSize("message_type_icon").width
+ }
+ Cura.TertiaryButton
+ {
+ text: catalog.i18nc("@action:button", "Learn more about Cura print profiles")
+ iconSource: UM.Theme.getIcon("LinkExternal")
+ isIconOnRightSide: true
+ leftPadding: 0
+ rightPadding: 0
+ onClicked: Qt.openUrlExternally("https://support.ultimaker.com/s/article/1667337576882")
+ }
+ }
+ ]
+ okButtonText: catalog.i18nc("@button", "Save new profile")
+ onAccepted: CuraApplication.getQualityManagementModel().createQualityChanges(newName, true);
+ }
+
/**
* Function to check whether a QML object has a certain type.
* Taken from StackOverflow: https://stackoverflow.com/a/28384228 and
diff --git a/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml b/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml
index 0fecb6b662..8dbe18ccff 100644
--- a/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml
+++ b/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml
@@ -12,8 +12,13 @@ UM.Dialog
id: base
title: catalog.i18nc("@title:window", "Discard or Keep changes")
- onAccepted: CuraApplication.discardOrKeepProfileChangesClosed("discard")
- onRejected: CuraApplication.discardOrKeepProfileChangesClosed("keep")
+ enum ButtonsType { DiscardOrKeep, SaveFromBuiltIn, SaveFromCustom}
+ property int buttonState: DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep
+
+ onAccepted: buttonState == DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep ?
+ CuraApplication.discardOrKeepProfileChangesClosed("discard") : Cura.Actions.addProfile.trigger()
+ onRejected: buttonState == DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep ?
+ CuraApplication.discardOrKeepProfileChangesClosed("keep") : Cura.Actions.updateProfile.trigger()
minimumWidth: UM.Theme.getSize("popup_dialog").width
minimumHeight: UM.Theme.getSize("popup_dialog").height
@@ -98,9 +103,12 @@ UM.Dialog
buttonSpacing: UM.Theme.getSize("thin_margin").width
- leftButtons: [
+ leftButtons:
+ [
Cura.ComboBox
{
+ visible: buttonState == DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep
+
implicitHeight: UM.Theme.getSize("combobox").height
implicitWidth: UM.Theme.getSize("combobox").width
@@ -146,12 +154,28 @@ UM.Dialog
id: discardButton
text: catalog.i18nc("@action:button", "Discard changes")
onClicked: base.accept()
+ visible: buttonState == DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep
},
Cura.SecondaryButton
{
id: keepButton
text: catalog.i18nc("@action:button", "Keep changes")
onClicked: base.reject()
+ visible: buttonState == DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep
+ },
+ Cura.SecondaryButton
+ {
+ id: overwriteButton
+ text: catalog.i18nc("@action:button", "Save as new custom profile")
+ visible: buttonState != DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep
+ onClicked: base.accept()
+ },
+ Cura.PrimaryButton
+ {
+ id: saveButton
+ text: catalog.i18nc("@action:button", "Save changes")
+ visible: buttonState == DiscardOrKeepProfileChangesDialog.ButtonsType.SaveFromCustom
+ onClicked: base.reject()
}
]
}
diff --git a/resources/qml/Preferences/RenameDialog.qml b/resources/qml/Dialogs/RenameDialog.qml
similarity index 64%
rename from resources/qml/Preferences/RenameDialog.qml
rename to resources/qml/Dialogs/RenameDialog.qml
index 7bcd65ed5d..52cfe3a26e 100644
--- a/resources/qml/Preferences/RenameDialog.qml
+++ b/resources/qml/Dialogs/RenameDialog.qml
@@ -15,17 +15,23 @@ UM.Dialog
buttonSpacing: UM.Theme.getSize("default_margin").width
property string object: ""
+ property string objectPlaceholder: ""
property alias newName: nameField.text
property bool validName: true
property string validationError
property string dialogTitle: catalog.i18nc("@title:window", "Rename")
property string explanation: catalog.i18nc("@info", "Please provide a new name.")
+ property string okButtonText: catalog.i18nc("@action:button", "OK")
+
+ // Extra Information for the user about the current rename can go here, can be left alone if not needed.
+ // For example; An icon and a text-field and a tertiary button providing a link.
+ property list- extraInfo
title: dialogTitle
backgroundColor: UM.Theme.getColor("main_background")
minimumWidth: UM.Theme.getSize("small_popup_dialog").width
- minimumHeight: UM.Theme.getSize("small_popup_dialog").height
+ minimumHeight: UM.Theme.getSize("small_popup_dialog").height + extraInfoHolder.height
width: minimumWidth
height: minimumHeight
@@ -55,11 +61,33 @@ UM.Dialog
id: nameField
width: parent.width
text: base.object
+ placeholderText: base.objectPlaceholder
+ placeholderTextColor: UM.Theme.getColor("text_field_text_disabled")
maximumLength: 40
selectByMouse: true
onTextChanged: base.textChanged(text)
}
+ // spacer
+ Item
+ {
+ height: UM.Theme.getSize("wide_margin").height
+ width: height
+ }
+
+ Row
+ {
+ id: extraInfoHolder
+ anchors
+ {
+ left: parent.left
+ right: parent.right
+ margins: UM.Theme.getSize("default_margin").height
+ }
+ spacing: UM.Theme.getSize("default_margin").height
+ children: extraInfo
+ }
+
UM.Label
{
visible: !base.validName
@@ -67,20 +95,23 @@ UM.Dialog
}
}
- rightButtons: [
- Cura.SecondaryButton
+ leftButtons:
+ [
+ Cura.TertiaryButton
{
id: cancelButton
text: catalog.i18nc("@action:button","Cancel")
onClicked: base.reject()
- },
+ }
+ ]
+ rightButtons:
+ [
Cura.PrimaryButton
{
id: okButton
- text: catalog.i18nc("@action:button", "OK")
+ text: base.okButtonText
onClicked: base.accept()
enabled: base.validName
}
]
}
-
diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml
index e64f211cd1..5742e12a3c 100644
--- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml
+++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml
@@ -52,8 +52,8 @@ Item
id: intentSelection
onClicked: menu.opened ? menu.close() : menu.open()
- anchors.right: parent.right
- width: UM.Theme.getSize("print_setup_big_item").width
+ anchors.right: profileWarningReset.left
+ width: UM.Theme.getSize("print_setup_big_item").width - profileWarningReset.width
height: textLabel.contentHeight + 2 * UM.Theme.getSize("narrow_margin").height
hoverEnabled: true
@@ -152,6 +152,14 @@ Item
}
}
+ ProfileWarningReset
+ {
+ id: profileWarningReset
+ width: childrenRect.width
+ anchors.right: parent.right
+ fullWarning: false
+ }
+
QualitiesWithIntentMenu
{
id: menu
diff --git a/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml b/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml
index a2624dbf14..1aa10a9b42 100644
--- a/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml
+++ b/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml
@@ -223,58 +223,6 @@ Popup
color: borderColor
}
- MenuButton
- {
- labelText: Cura.Actions.addProfile.text
-
- anchors.left: parent.left
- anchors.right: parent.right
-
- enabled: Cura.Actions.addProfile.enabled
- onClicked:
- {
- Cura.Actions.addProfile.trigger()
- popup.visible = false
- }
- }
- MenuButton
- {
- labelText: Cura.Actions.updateProfile.text
- anchors.left: parent.left
- anchors.right: parent.right
-
- enabled: Cura.Actions.updateProfile.enabled
-
- onClicked:
- {
- popup.visible = false
- Cura.Actions.updateProfile.trigger()
- }
- }
- MenuButton
- {
- text: catalog.i18nc("@action:button", "Discard current changes")
-
- anchors.left: parent.left
- anchors.right: parent.right
-
- enabled: Cura.MachineManager.hasUserSettings
-
- onClicked:
- {
- popup.visible = false
- Cura.ContainerManager.clearUserContainers()
- }
- }
-
- Rectangle
- {
- height: UM.Theme.getSize("default_lining").width
- anchors.left: parent.left
- anchors.right: parent.right
- color: borderColor
- }
-
MenuButton
{
id: manageProfilesButton
diff --git a/resources/qml/PrintSetupSelector/Recommended/ProfileWarningReset.qml b/resources/qml/PrintSetupSelector/ProfileWarningReset.qml
similarity index 51%
rename from resources/qml/PrintSetupSelector/Recommended/ProfileWarningReset.qml
rename to resources/qml/PrintSetupSelector/ProfileWarningReset.qml
index 10f006538b..5e6a3d8157 100644
--- a/resources/qml/PrintSetupSelector/Recommended/ProfileWarningReset.qml
+++ b/resources/qml/PrintSetupSelector/ProfileWarningReset.qml
@@ -1,19 +1,27 @@
+// Copyright (C) 2022 UltiMaker
+// Cura is released under the terms of the LGPLv3 or higher.
+
import QtQuick 2.10
import UM 1.6 as UM
import Cura 1.6 as Cura
+import "../Dialogs"
+
Item
{
+ property bool fullWarning: true // <- Can you see the warning icon and the text, or is it just the buttons?
+
height: visible ? UM.Theme.getSize("action_button_icon").height : 0
visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.MachineManager.hasCustomQuality
Rectangle
{
id: warningIcon
+ visible: fullWarning
color: UM.Theme.getColor("um_yellow_5")
height: UM.Theme.getSize("action_button_icon").height
- width: height
+ width: visible ? height : 0
radius: width
anchors
{
@@ -31,7 +39,8 @@ Item
UM.Label
{
id: warning
- width: parent.width - warningIcon.width - resetToDefaultQualityButton.width
+ visible: fullWarning
+ width: visible ? parent.width - warningIcon.width - (compareAndSaveButton.width + resetToDefaultQualityButton.width) : 0
anchors
{
left: warningIcon.right
@@ -76,11 +85,14 @@ Item
PropertyChanges
{
target: warning
- text: catalog.i18nc("@info", "Some settings were changed.")
+ text:
+ {
+ var profile_name = Cura.MachineManager.activeQualityOrQualityChangesName;
+ return catalog.i18nc("@info %1 is the name of a profile", "Some setting-values defined in %1 were overridden.").arg(profile_name);
+ }
}
}
]
-
}
UM.SimpleButton
@@ -90,17 +102,63 @@ Item
width: height
iconSource: UM.Theme.getIcon("ArrowReset")
anchors
+ {
+ right: buttonsSpacer.left
+ verticalCenter: parent.verticalCenter
+ }
+
+ color: enabled ? UM.Theme.getColor("accent_1") : UM.Theme.getColor("disabled")
+ hoverColor: UM.Theme.getColor("primary_hover")
+
+ enabled: Cura.MachineManager.hasCustomQuality || Cura.SimpleModeSettingsManager.isProfileCustomized
+ onClicked: Cura.MachineManager.resetToUseDefaultQuality()
+
+ UM.ToolTip
+ {
+ visible: parent.hovered
+ y: parent.y + parent.height + UM.Theme.getSize("default_margin").height
+ targetPoint: Qt.point(parent.x, Math.round(parent.y + parent.height / 2))
+ tooltipText: catalog.i18nc("@info", "Reset to defaults.")
+ }
+ }
+
+ // Spacer
+ Item
+ {
+ id: buttonsSpacer
+ width: UM.Theme.getSize("action_button_icon").height
+ anchors.right: compareAndSaveButton.left
+ }
+
+ UM.SimpleButton
+ {
+ id: compareAndSaveButton
+ height: UM.Theme.getSize("action_button_icon").height
+ width: height
+ iconSource: UM.Theme.getIcon("Save")
+ anchors
{
right: parent.right
verticalCenter: parent.verticalCenter
}
- color: UM.Theme.getColor("accent_1")
+ color: enabled ? UM.Theme.getColor("accent_1") : UM.Theme.getColor("disabled")
+ hoverColor: UM.Theme.getColor("primary_hover")
- onClicked:
+ enabled: Cura.SimpleModeSettingsManager.isProfileCustomized
+ onClicked: CuraApplication.showCompareAndSaveProfileChanges
+ (
+ Cura.MachineManager.hasCustomQuality ?
+ DiscardOrKeepProfileChangesDialog.ButtonsType.SaveFromCustom :
+ DiscardOrKeepProfileChangesDialog.ButtonsType.SaveFromBuiltIn
+ )
+
+ UM.ToolTip
{
- Cura.MachineManager.resetToUseDefaultQuality()
+ visible: parent.hovered
+ y: parent.y + parent.height + UM.Theme.getSize("default_margin").height
+ targetPoint: Qt.point(parent.x, Math.round(parent.y + parent.height / 2))
+ tooltipText: catalog.i18nc("@info", "Compare and save.")
}
}
-
-}
\ No newline at end of file
+}
diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml
index 94de16141f..37517709a9 100644
--- a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml
+++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml
@@ -6,6 +6,7 @@ import QtQuick.Layouts 1.1
import UM 1.6 as UM
import Cura 1.6 as Cura
+import ".."
Item
{
diff --git a/resources/themes/cura-light/icons/default/Save.svg b/resources/themes/cura-light/icons/default/Save.svg
new file mode 100644
index 0000000000..61887b084c
--- /dev/null
+++ b/resources/themes/cura-light/icons/default/Save.svg
@@ -0,0 +1,6 @@
+
+