Merge pull request #13938 from Ultimaker/CURA-9347_safe_to_profile_button

[CURA-9347] Easier 'compare-and-safe' for (new or custom) profiles
This commit is contained in:
Jelle Spijker 2022-12-05 15:34:57 +01:00 committed by GitHub
commit b8b433ed5c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 209 additions and 87 deletions

View file

@ -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

View file

@ -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.

View file

@ -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",
"<b>Only user changed settings will be saved in the custom profile.</b><br/>" +
"For materials that support it, the new custom profile will inherit properties from <b>%1</b>."
).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

View file

@ -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()
}
]
}

View file

@ -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<Item> 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
}
]
}

View file

@ -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

View file

@ -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

View file

@ -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 <b>%1</b> 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.")
}
}
}
}

View file

@ -6,6 +6,7 @@ import QtQuick.Layouts 1.1
import UM 1.6 as UM
import Cura 1.6 as Cura
import ".."
Item
{

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path fill-rule="evenodd" d="M3 18C3 19.6569 4.34315 21 6 21H18C19.6569 21 21 19.6569 21 18V8L16 3H6C4.34315 3 3 4.34315 3 6V18ZM5 5H15.1716L19 8.82843V19H5V5Z"/>
<path fill-rule="evenodd" d="M7 5H15V9H7V5ZM9 5V7H13V5H9Z"/>
<path fill-rule="evenodd" d="M15 15H9V19H15V15ZM7 13V20H17V13H7Z"/>
</svg>

After

Width:  |  Height:  |  Size: 413 B