mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-12-11 16:00:47 -07:00
Merge branch 'master' into recommended_sidebar
This commit is contained in:
commit
c27219b1c4
100 changed files with 4104 additions and 428 deletions
|
|
@ -11,6 +11,7 @@ import Cura 1.0 as Cura
|
|||
Item
|
||||
{
|
||||
property alias open: openAction;
|
||||
property alias loadWorkspace: loadWorkspaceAction;
|
||||
property alias quit: quitAction;
|
||||
|
||||
property alias undo: undoAction;
|
||||
|
|
@ -122,7 +123,7 @@ Item
|
|||
{
|
||||
id: updateProfileAction;
|
||||
enabled: !Cura.MachineManager.stacksHaveErrors && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId)
|
||||
text: catalog.i18nc("@action:inmenu menubar:profile","&Update profile with current settings");
|
||||
text: catalog.i18nc("@action:inmenu menubar:profile","&Update profile with current settings/overrides");
|
||||
onTriggered: Cura.ContainerManager.updateQualityChanges();
|
||||
}
|
||||
|
||||
|
|
@ -142,7 +143,7 @@ Item
|
|||
{
|
||||
id: addProfileAction;
|
||||
enabled: !Cura.MachineManager.stacksHaveErrors && Cura.MachineManager.hasUserSettings
|
||||
text: catalog.i18nc("@action:inmenu menubar:profile","&Create profile from current settings...");
|
||||
text: catalog.i18nc("@action:inmenu menubar:profile","&Create profile from current settings/overrides...");
|
||||
}
|
||||
|
||||
Action
|
||||
|
|
@ -286,6 +287,12 @@ Item
|
|||
shortcut: StandardKey.Open;
|
||||
}
|
||||
|
||||
Action
|
||||
{
|
||||
id: loadWorkspaceAction
|
||||
text: catalog.i18nc("@action:inmenu menubar:file","&Open Workspace...");
|
||||
}
|
||||
|
||||
Action
|
||||
{
|
||||
id: showEngineLogAction;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import QtQuick.Controls.Styles 1.1
|
|||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Dialogs 1.1
|
||||
|
||||
import UM 1.2 as UM
|
||||
import UM 1.3 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
import "Menus"
|
||||
|
|
@ -67,9 +67,14 @@ UM.MainWindow
|
|||
id: fileMenu
|
||||
title: catalog.i18nc("@title:menu menubar:toplevel","&File");
|
||||
|
||||
MenuItem {
|
||||
MenuItem
|
||||
{
|
||||
action: Cura.Actions.open;
|
||||
}
|
||||
MenuItem
|
||||
{
|
||||
action: Cura.Actions.loadWorkspace
|
||||
}
|
||||
|
||||
RecentFilesMenu { }
|
||||
|
||||
|
|
@ -102,6 +107,12 @@ UM.MainWindow
|
|||
onObjectRemoved: saveAllMenu.removeItem(object)
|
||||
}
|
||||
}
|
||||
MenuItem
|
||||
{
|
||||
id: saveWorkspaceMenu
|
||||
text: catalog.i18nc("@title:menu menubar:file","Save Workspace")
|
||||
onTriggered: UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, { "filter_by_machine": false, "file_type": "workspace" });
|
||||
}
|
||||
|
||||
MenuItem { action: Cura.Actions.reloadAll; }
|
||||
|
||||
|
|
@ -723,6 +734,38 @@ UM.MainWindow
|
|||
onTriggered: openDialog.open()
|
||||
}
|
||||
|
||||
FileDialog
|
||||
{
|
||||
id: openWorkspaceDialog;
|
||||
|
||||
//: File open dialog title
|
||||
title: catalog.i18nc("@title:window","Open workspace")
|
||||
modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal;
|
||||
selectMultiple: false
|
||||
nameFilters: UM.WorkspaceFileHandler.supportedReadFileTypes;
|
||||
folder: CuraApplication.getDefaultPath("dialog_load_path")
|
||||
onAccepted:
|
||||
{
|
||||
//Because several implementations of the file dialog only update the folder
|
||||
//when it is explicitly set.
|
||||
var f = folder;
|
||||
folder = f;
|
||||
|
||||
CuraApplication.setDefaultPath("dialog_load_path", folder);
|
||||
|
||||
for(var i in fileUrls)
|
||||
{
|
||||
UM.WorkspaceFileHandler.readLocalFile(fileUrls[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: Cura.Actions.loadWorkspace
|
||||
onTriggered:openWorkspaceDialog.open()
|
||||
}
|
||||
|
||||
EngineLog
|
||||
{
|
||||
id: engineLog;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ UM.Dialog
|
|||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
|
||||
property int objectId: 0;
|
||||
property var objectId: 0;
|
||||
onAccepted: Printer.multiplyObject(base.objectId, parseInt(copiesField.text))
|
||||
|
||||
property variant catalog: UM.I18nCatalog { name: "cura" }
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ UM.ManagementPage
|
|||
Button
|
||||
{
|
||||
text: {
|
||||
return catalog.i18nc("@action:button", "Update profile with current settings");
|
||||
return catalog.i18nc("@action:button", "Update profile with current settings/overrides");
|
||||
}
|
||||
enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId)
|
||||
onClicked: Cura.ContainerManager.updateQualityChanges()
|
||||
|
|
@ -187,7 +187,7 @@ UM.ManagementPage
|
|||
Label {
|
||||
id: defaultsMessage
|
||||
visible: false
|
||||
text: catalog.i18nc("@action:label", "This profile uses the defaults specified by the printer, so it has no settings in the list below.")
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,11 +29,11 @@ SettingItem
|
|||
// 4: variant
|
||||
// 5: machine
|
||||
var value;
|
||||
if ((propertyProvider.properties.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) {
|
||||
if ((base.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) {
|
||||
// We have a resolve function. Indicates that the setting is not settable per extruder and that
|
||||
// we have to choose between the resolved value (default) and the global value
|
||||
// (if user has explicitly set this).
|
||||
value = propertyProvider.properties.resolve;
|
||||
value = base.resolve;
|
||||
} else {
|
||||
value = propertyProvider.properties.value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,11 +96,11 @@ SettingItem
|
|||
{
|
||||
// FIXME this needs to go away once 'resolve' is combined with 'value' in our data model.
|
||||
var value;
|
||||
if ((propertyProvider.properties.resolve != "None") && (base.stackLevel != 0) && (base.stackLevel != 1)) {
|
||||
if ((base.resolve != "None") && (base.stackLevel != 0) && (base.stackLevel != 1)) {
|
||||
// We have a resolve function. Indicates that the setting is not settable per extruder and that
|
||||
// we have to choose between the resolved value (default) and the global value
|
||||
// (if user has explicitly set this).
|
||||
value = propertyProvider.properties.resolve;
|
||||
value = base.resolve;
|
||||
} else {
|
||||
value = propertyProvider.properties.value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ SettingItem
|
|||
textRole: "name"
|
||||
|
||||
anchors.fill: parent
|
||||
onCurrentIndexChanged: updateCurrentColor();
|
||||
|
||||
MouseArea
|
||||
{
|
||||
|
|
@ -115,12 +116,37 @@ SettingItem
|
|||
propertyProvider.setPropertyValue("value", extruders_model.getItem(index).index);
|
||||
control.color = extruders_model.getItem(index).color;
|
||||
}
|
||||
|
||||
onModelChanged: updateCurrentIndex();
|
||||
|
||||
Connections
|
||||
Binding
|
||||
{
|
||||
target: propertyProvider
|
||||
onPropertiesChanged: control.updateCurrentIndex();
|
||||
target: control
|
||||
property: "currentIndex"
|
||||
value:
|
||||
{
|
||||
for(var i = 0; i < extruders_model.rowCount(); ++i)
|
||||
{
|
||||
if(extruders_model.getItem(i).index == propertyProvider.properties.value)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// In some cases we want to update the current color without updating the currentIndex, so it's a seperate function.
|
||||
function updateCurrentColor()
|
||||
{
|
||||
for(var i = 0; i < extruders_model.rowCount(); ++i)
|
||||
{
|
||||
if(extruders_model.getItem(i).index == propertyProvider.properties.value)
|
||||
{
|
||||
control.color = extruders_model.getItem(i).color;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateCurrentIndex()
|
||||
|
|
@ -130,7 +156,6 @@ SettingItem
|
|||
if(extruders_model.getItem(i).index == propertyProvider.properties.value)
|
||||
{
|
||||
control.currentIndex = i;
|
||||
control.color = extruders_model.getItem(i).color;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ Item {
|
|||
|
||||
// Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise)
|
||||
property var state: propertyProvider.properties.state
|
||||
property var resolve: propertyProvider.properties.resolve
|
||||
// There is no resolve property if there is only one stack.
|
||||
property var resolve: Cura.MachineManager.activeStackId != Cura.MachineManager.activeMachineId ? propertyProvider.properties.resolve : "None"
|
||||
property var stackLevels: propertyProvider.stackLevels
|
||||
property var stackLevel: stackLevels[0]
|
||||
|
||||
|
|
@ -117,6 +118,7 @@ Item {
|
|||
elide: Text.ElideMiddle;
|
||||
|
||||
color: UM.Theme.getColor("setting_control_text");
|
||||
opacity: (definition.visible) ? 1 : 0.5
|
||||
// emphasize the setting if it has a value in the user or quality profile
|
||||
font: base.doQualityUserSettingEmphasis && base.stackLevel != undefined && base.stackLevel <= 1 ? UM.Theme.getFont("default_italic") : UM.Theme.getFont("default")
|
||||
}
|
||||
|
|
@ -208,14 +210,26 @@ Item {
|
|||
// But this will cause the binding to be re-evaluated when the enabled property changes.
|
||||
return false;
|
||||
}
|
||||
|
||||
// There are no settings with any warning.
|
||||
if(Cura.SettingInheritanceManager.settingsWithInheritanceWarning.length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// This setting has a resolve value, so an inheritance warning doesn't do anything.
|
||||
if(resolve != "None")
|
||||
{
|
||||
return false
|
||||
}
|
||||
|
||||
// If the setting does not have a limit_to_extruder property (or is -1), use the active stack.
|
||||
if(globalPropertyProvider.properties.limit_to_extruder == null || globalPropertyProvider.properties.limit_to_extruder == -1)
|
||||
{
|
||||
return Cura.SettingInheritanceManager.settingsWithInheritanceWarning.indexOf(definition.key) >= 0;
|
||||
}
|
||||
|
||||
// Setting does have a limit_to_extruder property, so use that one instead.
|
||||
return Cura.SettingInheritanceManager.getOverridesForExtruder(definition.key, globalPropertyProvider.properties.limit_to_extruder).indexOf(definition.key) >= 0;
|
||||
}
|
||||
|
||||
|
|
@ -226,7 +240,7 @@ Item {
|
|||
focus = true;
|
||||
|
||||
// Get the most shallow function value (eg not a number) that we can find.
|
||||
var last_entry = propertyProvider.stackLevels[propertyProvider.stackLevels.length]
|
||||
var last_entry = propertyProvider.stackLevels[propertyProvider.stackLevels.length - 1]
|
||||
for (var i = 1; i < base.stackLevels.length; i++)
|
||||
{
|
||||
var has_setting_function = typeof(propertyProvider.getPropertyValue("value", base.stackLevels[i])) == "object";
|
||||
|
|
|
|||
|
|
@ -114,11 +114,11 @@ SettingItem
|
|||
// 3: material -> user changed material in materialspage
|
||||
// 4: variant
|
||||
// 5: machine
|
||||
if ((propertyProvider.properties.resolve != "None" && propertyProvider.properties.resolve) && (stackLevel != 0) && (stackLevel != 1)) {
|
||||
if ((base.resolve != "None" && base.resolve) && (stackLevel != 0) && (stackLevel != 1)) {
|
||||
// We have a resolve function. Indicates that the setting is not settable per extruder and that
|
||||
// we have to choose between the resolved value (default) and the global value
|
||||
// (if user has explicitly set this).
|
||||
return propertyProvider.properties.resolve;
|
||||
return base.resolve;
|
||||
} else {
|
||||
return propertyProvider.properties.value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,229 +9,405 @@ import QtQuick.Layouts 1.1
|
|||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
ScrollView
|
||||
Item
|
||||
{
|
||||
id: base;
|
||||
|
||||
style: UM.Theme.styles.scrollview;
|
||||
flickableItem.flickableDirection: Flickable.VerticalFlick;
|
||||
|
||||
property Action configureSettings;
|
||||
property bool findingSettings;
|
||||
signal showTooltip(Item item, point location, string text);
|
||||
signal hideTooltip();
|
||||
|
||||
ListView
|
||||
function toggleFilterField()
|
||||
{
|
||||
id: contents
|
||||
spacing: UM.Theme.getSize("default_lining").height;
|
||||
cacheBuffer: 1000000; // Set a large cache to effectively just cache every list item.
|
||||
|
||||
model: UM.SettingDefinitionsModel {
|
||||
id: definitionsModel;
|
||||
containerId: Cura.MachineManager.activeDefinitionId
|
||||
visibilityHandler: UM.SettingPreferenceVisibilityHandler { }
|
||||
exclude: ["machine_settings", "command_line_settings", "infill_mesh", "infill_mesh_order"] // TODO: infill_mesh settigns are excluded hardcoded, but should be based on the fact that settable_globally, settable_per_meshgroup and settable_per_extruder are false.
|
||||
expanded: Printer.expandedCategories
|
||||
onExpandedChanged: Printer.setExpandedCategories(expanded)
|
||||
onVisibilityChanged: Cura.SettingInheritanceManager.forceUpdate()
|
||||
}
|
||||
|
||||
delegate: Loader
|
||||
filterContainer.visible = !filterContainer.visible
|
||||
if(filterContainer.visible)
|
||||
{
|
||||
id: delegate
|
||||
|
||||
width: UM.Theme.getSize("sidebar").width;
|
||||
height: provider.properties.enabled == "True" ? UM.Theme.getSize("section").height : - contents.spacing
|
||||
Behavior on height { NumberAnimation { duration: 100 } }
|
||||
opacity: provider.properties.enabled == "True" ? 1 : 0
|
||||
Behavior on opacity { NumberAnimation { duration: 100 } }
|
||||
enabled:
|
||||
{
|
||||
if(!ExtruderManager.activeExtruderStackId && ExtruderManager.extruderCount > 0)
|
||||
{
|
||||
// disable all controls on the global tab, except categories
|
||||
return model.type == "category"
|
||||
}
|
||||
return provider.properties.enabled == "True"
|
||||
}
|
||||
|
||||
property var definition: model
|
||||
property var settingDefinitionsModel: definitionsModel
|
||||
property var propertyProvider: provider
|
||||
property var globalPropertyProvider: inheritStackProvider
|
||||
|
||||
//Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989
|
||||
//In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes,
|
||||
//causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
|
||||
asynchronous: model.type != "enum" && model.type != "extruder"
|
||||
active: model.type != undefined
|
||||
|
||||
source:
|
||||
{
|
||||
switch(model.type)
|
||||
{
|
||||
case "int":
|
||||
return "SettingTextField.qml"
|
||||
case "float":
|
||||
return "SettingTextField.qml"
|
||||
case "enum":
|
||||
return "SettingComboBox.qml"
|
||||
case "extruder":
|
||||
return "SettingExtruder.qml"
|
||||
case "bool":
|
||||
return "SettingCheckBox.qml"
|
||||
case "str":
|
||||
return "SettingTextField.qml"
|
||||
case "category":
|
||||
return "SettingCategory.qml"
|
||||
default:
|
||||
return "SettingUnknown.qml"
|
||||
}
|
||||
}
|
||||
|
||||
// Binding to ensure that the right containerstack ID is set for the provider.
|
||||
// This ensures that if a setting has a limit_to_extruder id (for instance; Support speed points to the
|
||||
// extruder that actually prints the support, as that is the setting we need to use to calculate the value)
|
||||
Binding
|
||||
{
|
||||
target: provider
|
||||
property: "containerStackId"
|
||||
when: model.settable_per_extruder || (inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0);
|
||||
value:
|
||||
{
|
||||
if(!model.settable_per_extruder || machineExtruderCount.properties.value == 1)
|
||||
{
|
||||
//Not settable per extruder or there only is global, so we must pick global.
|
||||
return Cura.MachineManager.activeMachineId;
|
||||
}
|
||||
if(inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0)
|
||||
{
|
||||
//We have limit_to_extruder, so pick that stack.
|
||||
return ExtruderManager.extruderIds[String(inheritStackProvider.properties.limit_to_extruder)];
|
||||
}
|
||||
if(ExtruderManager.activeExtruderStackId)
|
||||
{
|
||||
//We're on an extruder tab. Pick the current extruder.
|
||||
return ExtruderManager.activeExtruderStackId;
|
||||
}
|
||||
//No extruder tab is selected. Pick the global stack. Shouldn't happen any more since we removed the global tab.
|
||||
return Cura.MachineManager.activeMachineId;
|
||||
}
|
||||
}
|
||||
|
||||
// Specialty provider that only watches global_inherits (we cant filter on what property changed we get events
|
||||
// so we bypass that to make a dedicated provider).
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: inheritStackProvider
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: model.key
|
||||
watchedProperties: [ "limit_to_extruder" ]
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: provider
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: model.key ? model.key : ""
|
||||
watchedProperties: [ "value", "enabled", "state", "validationState", "settable_per_extruder", "resolve" ]
|
||||
storeIndex: 0
|
||||
// Due to the way setPropertyValue works, removeUnusedValue gives the correct output in case of resolve
|
||||
removeUnusedValue: model.resolve == undefined
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: item
|
||||
onContextMenuRequested:
|
||||
{
|
||||
contextMenu.key = model.key;
|
||||
contextMenu.provider = provider
|
||||
contextMenu.popup();
|
||||
}
|
||||
onShowTooltip: base.showTooltip(delegate, { x: 0, y: delegate.height / 2 }, text)
|
||||
onHideTooltip: base.hideTooltip()
|
||||
onShowAllHiddenInheritedSettings:
|
||||
{
|
||||
var children_with_override = Cura.SettingInheritanceManager.getChildrenKeysWithOverride(category_id)
|
||||
for(var i = 0; i < children_with_override.length; i++)
|
||||
{
|
||||
definitionsModel.setVisible(children_with_override[i], true)
|
||||
}
|
||||
Cura.SettingInheritanceManager.manualRemoveOverride(category_id)
|
||||
}
|
||||
}
|
||||
filter.forceActiveFocus();
|
||||
}
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "uranium"; }
|
||||
|
||||
add: Transition {
|
||||
SequentialAnimation {
|
||||
NumberAnimation { properties: "height"; from: 0; duration: 100 }
|
||||
NumberAnimation { properties: "opacity"; from: 0; duration: 100 }
|
||||
}
|
||||
}
|
||||
remove: Transition {
|
||||
SequentialAnimation {
|
||||
NumberAnimation { properties: "opacity"; to: 0; duration: 100 }
|
||||
NumberAnimation { properties: "height"; to: 0; duration: 100 }
|
||||
}
|
||||
}
|
||||
addDisplaced: Transition {
|
||||
NumberAnimation { properties: "x,y"; duration: 100 }
|
||||
}
|
||||
removeDisplaced: Transition {
|
||||
SequentialAnimation {
|
||||
PauseAnimation { duration: 100; }
|
||||
NumberAnimation { properties: "x,y"; duration: 100 }
|
||||
}
|
||||
}
|
||||
|
||||
Menu
|
||||
else
|
||||
{
|
||||
id: contextMenu
|
||||
|
||||
property string key
|
||||
property var provider
|
||||
|
||||
MenuItem
|
||||
{
|
||||
//: Settings context menu action
|
||||
text: catalog.i18nc("@action:menu", "Copy value to all extruders")
|
||||
visible: machineExtruderCount.properties.value > 1
|
||||
enabled: contextMenu.provider != undefined && contextMenu.provider.properties.settable_per_extruder != "False"
|
||||
onTriggered: Cura.MachineManager.copyValueToExtruders(contextMenu.key)
|
||||
}
|
||||
|
||||
MenuSeparator
|
||||
{
|
||||
visible: machineExtruderCount.properties.value > 1
|
||||
}
|
||||
|
||||
MenuItem
|
||||
{
|
||||
//: Settings context menu action
|
||||
text: catalog.i18nc("@action:menu", "Hide this setting");
|
||||
onTriggered: definitionsModel.hide(contextMenu.key);
|
||||
}
|
||||
MenuItem
|
||||
{
|
||||
//: Settings context menu action
|
||||
text: catalog.i18nc("@action:menu", "Configure setting visiblity...");
|
||||
|
||||
onTriggered: Cura.Actions.configureSettingVisibility.trigger(contextMenu);
|
||||
}
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: machineExtruderCount
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: "machine_extruder_count"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 0
|
||||
filter.text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: filterContainer
|
||||
visible: false
|
||||
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color:
|
||||
{
|
||||
if(hoverMouseArea.containsMouse || clearFilterButton.containsMouse)
|
||||
{
|
||||
return UM.Theme.getColor("setting_control_border_highlight");
|
||||
}
|
||||
else
|
||||
{
|
||||
return UM.Theme.getColor("setting_control_border");
|
||||
}
|
||||
}
|
||||
|
||||
color: UM.Theme.getColor("setting_control")
|
||||
|
||||
anchors
|
||||
{
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
leftMargin: UM.Theme.getSize("default_margin").width
|
||||
right: parent.right
|
||||
rightMargin: UM.Theme.getSize("default_margin").width
|
||||
}
|
||||
height: visible ? UM.Theme.getSize("setting_control").height : 0
|
||||
Behavior on height { NumberAnimation { duration: 100 } }
|
||||
|
||||
TextField
|
||||
{
|
||||
id: filter;
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: clearFilterButton.left
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||
|
||||
placeholderText: catalog.i18nc("@label:textbox", "Filter...")
|
||||
|
||||
style: TextFieldStyle
|
||||
{
|
||||
textColor: UM.Theme.getColor("setting_control_text");
|
||||
font: UM.Theme.getFont("default");
|
||||
background: Item {}
|
||||
}
|
||||
|
||||
property var expandedCategories
|
||||
property bool lastFindingSettings: false
|
||||
|
||||
onTextChanged:
|
||||
{
|
||||
definitionsModel.filter = {"label": "*" + text};
|
||||
findingSettings = (text.length > 0);
|
||||
if(findingSettings != lastFindingSettings)
|
||||
{
|
||||
if(findingSettings)
|
||||
{
|
||||
expandedCategories = definitionsModel.expanded.slice();
|
||||
definitionsModel.expanded = ["*"];
|
||||
definitionsModel.showAncestors = true;
|
||||
definitionsModel.showAll = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
definitionsModel.expanded = expandedCategories;
|
||||
definitionsModel.showAncestors = false;
|
||||
definitionsModel.showAll = false;
|
||||
}
|
||||
lastFindingSettings = findingSettings;
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onEscapePressed:
|
||||
{
|
||||
filter.text = "";
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
id: hoverMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.NoButton
|
||||
cursorShape: Qt.IBeamCursor
|
||||
}
|
||||
|
||||
UM.SimpleButton
|
||||
{
|
||||
id: clearFilterButton
|
||||
iconSource: UM.Theme.getIcon("cross1")
|
||||
visible: findingSettings
|
||||
|
||||
height: parent.height * 0.4
|
||||
width: visible ? height : 0
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||
|
||||
color: UM.Theme.getColor("setting_control_button")
|
||||
hoverColor: UM.Theme.getColor("setting_control_button_hover")
|
||||
|
||||
onClicked:
|
||||
{
|
||||
filter.text = "";
|
||||
filter.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScrollView
|
||||
{
|
||||
anchors.top: filterContainer.bottom;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
anchors.left: parent.left;
|
||||
anchors.topMargin: filterContainer.visible ? UM.Theme.getSize("default_margin").width : 0
|
||||
Behavior on anchors.topMargin { NumberAnimation { duration: 100 } }
|
||||
|
||||
style: UM.Theme.styles.scrollview;
|
||||
flickableItem.flickableDirection: Flickable.VerticalFlick;
|
||||
|
||||
ListView
|
||||
{
|
||||
id: contents
|
||||
spacing: UM.Theme.getSize("default_lining").height;
|
||||
cacheBuffer: 1000000; // Set a large cache to effectively just cache every list item.
|
||||
|
||||
model: UM.SettingDefinitionsModel
|
||||
{
|
||||
id: definitionsModel;
|
||||
containerId: Cura.MachineManager.activeDefinitionId
|
||||
visibilityHandler: UM.SettingPreferenceVisibilityHandler { }
|
||||
exclude: ["machine_settings", "command_line_settings", "infill_mesh", "infill_mesh_order"] // TODO: infill_mesh settigns are excluded hardcoded, but should be based on the fact that settable_globally, settable_per_meshgroup and settable_per_extruder are false.
|
||||
expanded: Printer.expandedCategories
|
||||
onExpandedChanged:
|
||||
{
|
||||
if(!findingSettings)
|
||||
{
|
||||
// Do not change expandedCategories preference while filtering settings
|
||||
// because all categories are expanded while filtering
|
||||
Printer.setExpandedCategories(expanded)
|
||||
}
|
||||
}
|
||||
onVisibilityChanged: Cura.SettingInheritanceManager.forceUpdate()
|
||||
}
|
||||
|
||||
delegate: Loader
|
||||
{
|
||||
id: delegate
|
||||
|
||||
width: UM.Theme.getSize("sidebar").width;
|
||||
height: provider.properties.enabled == "True" ? UM.Theme.getSize("section").height : - contents.spacing
|
||||
Behavior on height { NumberAnimation { duration: 100 } }
|
||||
opacity: provider.properties.enabled == "True" ? 1 : 0
|
||||
Behavior on opacity { NumberAnimation { duration: 100 } }
|
||||
enabled:
|
||||
{
|
||||
if(!ExtruderManager.activeExtruderStackId && ExtruderManager.extruderCount > 0)
|
||||
{
|
||||
// disable all controls on the global tab, except categories
|
||||
return model.type == "category"
|
||||
}
|
||||
return provider.properties.enabled == "True"
|
||||
}
|
||||
|
||||
property var definition: model
|
||||
property var settingDefinitionsModel: definitionsModel
|
||||
property var propertyProvider: provider
|
||||
property var globalPropertyProvider: inheritStackProvider
|
||||
|
||||
//Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989
|
||||
//In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes,
|
||||
//causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
|
||||
asynchronous: model.type != "enum" && model.type != "extruder"
|
||||
active: model.type != undefined
|
||||
|
||||
source:
|
||||
{
|
||||
switch(model.type)
|
||||
{
|
||||
case "int":
|
||||
return "SettingTextField.qml"
|
||||
case "float":
|
||||
return "SettingTextField.qml"
|
||||
case "enum":
|
||||
return "SettingComboBox.qml"
|
||||
case "extruder":
|
||||
return "SettingExtruder.qml"
|
||||
case "bool":
|
||||
return "SettingCheckBox.qml"
|
||||
case "str":
|
||||
return "SettingTextField.qml"
|
||||
case "category":
|
||||
return "SettingCategory.qml"
|
||||
default:
|
||||
return "SettingUnknown.qml"
|
||||
}
|
||||
}
|
||||
|
||||
// Binding to ensure that the right containerstack ID is set for the provider.
|
||||
// This ensures that if a setting has a limit_to_extruder id (for instance; Support speed points to the
|
||||
// extruder that actually prints the support, as that is the setting we need to use to calculate the value)
|
||||
Binding
|
||||
{
|
||||
target: provider
|
||||
property: "containerStackId"
|
||||
when: model.settable_per_extruder || (inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0);
|
||||
value:
|
||||
{
|
||||
if(!model.settable_per_extruder || machineExtruderCount.properties.value == 1)
|
||||
{
|
||||
//Not settable per extruder or there only is global, so we must pick global.
|
||||
return Cura.MachineManager.activeMachineId;
|
||||
}
|
||||
if(inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0)
|
||||
{
|
||||
//We have limit_to_extruder, so pick that stack.
|
||||
return ExtruderManager.extruderIds[String(inheritStackProvider.properties.limit_to_extruder)];
|
||||
}
|
||||
if(ExtruderManager.activeExtruderStackId)
|
||||
{
|
||||
//We're on an extruder tab. Pick the current extruder.
|
||||
return ExtruderManager.activeExtruderStackId;
|
||||
}
|
||||
//No extruder tab is selected. Pick the global stack. Shouldn't happen any more since we removed the global tab.
|
||||
return Cura.MachineManager.activeMachineId;
|
||||
}
|
||||
}
|
||||
|
||||
// Specialty provider that only watches global_inherits (we cant filter on what property changed we get events
|
||||
// so we bypass that to make a dedicated provider).
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: inheritStackProvider
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: model.key
|
||||
watchedProperties: [ "limit_to_extruder" ]
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: provider
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: model.key ? model.key : ""
|
||||
watchedProperties: [ "value", "enabled", "state", "validationState", "settable_per_extruder", "resolve" ]
|
||||
storeIndex: 0
|
||||
// Due to the way setPropertyValue works, removeUnusedValue gives the correct output in case of resolve
|
||||
removeUnusedValue: model.resolve == undefined
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: item
|
||||
onContextMenuRequested:
|
||||
{
|
||||
contextMenu.key = model.key;
|
||||
contextMenu.settingVisible = model.visible;
|
||||
contextMenu.provider = provider
|
||||
contextMenu.popup();
|
||||
}
|
||||
onShowTooltip: base.showTooltip(delegate, { x: 0, y: delegate.height / 2 }, text)
|
||||
onHideTooltip: base.hideTooltip()
|
||||
onShowAllHiddenInheritedSettings:
|
||||
{
|
||||
var children_with_override = Cura.SettingInheritanceManager.getChildrenKeysWithOverride(category_id)
|
||||
for(var i = 0; i < children_with_override.length; i++)
|
||||
{
|
||||
definitionsModel.setVisible(children_with_override[i], true)
|
||||
}
|
||||
Cura.SettingInheritanceManager.manualRemoveOverride(category_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "uranium"; }
|
||||
|
||||
add: Transition {
|
||||
SequentialAnimation {
|
||||
NumberAnimation { properties: "height"; from: 0; duration: 100 }
|
||||
NumberAnimation { properties: "opacity"; from: 0; duration: 100 }
|
||||
}
|
||||
}
|
||||
remove: Transition {
|
||||
SequentialAnimation {
|
||||
NumberAnimation { properties: "opacity"; to: 0; duration: 100 }
|
||||
NumberAnimation { properties: "height"; to: 0; duration: 100 }
|
||||
}
|
||||
}
|
||||
addDisplaced: Transition {
|
||||
NumberAnimation { properties: "x,y"; duration: 100 }
|
||||
}
|
||||
removeDisplaced: Transition {
|
||||
SequentialAnimation {
|
||||
PauseAnimation { duration: 100; }
|
||||
NumberAnimation { properties: "x,y"; duration: 100 }
|
||||
}
|
||||
}
|
||||
|
||||
Menu
|
||||
{
|
||||
id: contextMenu
|
||||
|
||||
property string key
|
||||
property var provider
|
||||
property bool settingVisible
|
||||
|
||||
MenuItem
|
||||
{
|
||||
//: Settings context menu action
|
||||
text: catalog.i18nc("@action:menu", "Copy value to all extruders")
|
||||
visible: machineExtruderCount.properties.value > 1
|
||||
enabled: contextMenu.provider != undefined && contextMenu.provider.properties.settable_per_extruder != "False"
|
||||
onTriggered: Cura.MachineManager.copyValueToExtruders(contextMenu.key)
|
||||
}
|
||||
|
||||
MenuSeparator
|
||||
{
|
||||
visible: machineExtruderCount.properties.value > 1
|
||||
}
|
||||
|
||||
MenuItem
|
||||
{
|
||||
//: Settings context menu action
|
||||
visible: !findingSettings;
|
||||
text: catalog.i18nc("@action:menu", "Hide this setting");
|
||||
onTriggered: definitionsModel.hide(contextMenu.key);
|
||||
}
|
||||
MenuItem
|
||||
{
|
||||
//: Settings context menu action
|
||||
text:
|
||||
{
|
||||
if (contextMenu.settingVisible)
|
||||
{
|
||||
return catalog.i18nc("@action:menu", "Don't show this setting");
|
||||
}
|
||||
else
|
||||
{
|
||||
return catalog.i18nc("@action:menu", "Keep this setting visible");
|
||||
}
|
||||
}
|
||||
visible: findingSettings;
|
||||
onTriggered:
|
||||
{
|
||||
if (contextMenu.settingVisible)
|
||||
{
|
||||
definitionsModel.hide(contextMenu.key);
|
||||
}
|
||||
else
|
||||
{
|
||||
definitionsModel.show(contextMenu.key);
|
||||
}
|
||||
}
|
||||
}
|
||||
MenuItem
|
||||
{
|
||||
//: Settings context menu action
|
||||
text: catalog.i18nc("@action:menu", "Configure setting visiblity...");
|
||||
|
||||
onTriggered: Cura.Actions.configureSettingVisibility.trigger(contextMenu);
|
||||
}
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: machineExtruderCount
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: "machine_extruder_count"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -214,7 +214,7 @@ Rectangle
|
|||
anchors.left: parent.left
|
||||
anchors.leftMargin: model.index * (settingsModeSelection.width / 2)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width / 2
|
||||
width: 0.5 * parent.width - (model.showFilterButton ? toggleFilterButton.width : 0)
|
||||
text: model.text
|
||||
exclusiveGroup: modeMenuGroup;
|
||||
checkable: true;
|
||||
|
|
@ -256,6 +256,44 @@ Rectangle
|
|||
}
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
id: toggleFilterButton
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||
anchors.top: headerSeparator.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
|
||||
height: settingsModeSelection.height
|
||||
width: visible ? height : 0
|
||||
|
||||
visible: !monitoringPrint && modesListModel.get(base.currentModeIndex).showFilterButton
|
||||
opacity: visible ? 1 : 0
|
||||
|
||||
onClicked: sidebarContents.currentItem.toggleFilterField()
|
||||
|
||||
style: ButtonStyle
|
||||
{
|
||||
background: Rectangle
|
||||
{
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: UM.Theme.getColor("toggle_checked_border")
|
||||
color: visible ? UM.Theme.getColor("toggle_checked") : UM.Theme.getColor("toggle_hovered")
|
||||
Behavior on color { ColorAnimation { duration: 50; } }
|
||||
}
|
||||
label: UM.RecolorImage
|
||||
{
|
||||
anchors.verticalCenter: control.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width / 2
|
||||
|
||||
source: UM.Theme.getIcon("search")
|
||||
color: UM.Theme.getColor("toggle_checked_text")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
id: monitorLabel
|
||||
text: catalog.i18nc("@label","Printer Monitor");
|
||||
|
|
@ -379,8 +417,8 @@ Rectangle
|
|||
|
||||
Component.onCompleted:
|
||||
{
|
||||
modesListModel.append({ text: catalog.i18nc("@title:tab", "Recommended"), item: sidebarSimple })
|
||||
modesListModel.append({ text: catalog.i18nc("@title:tab", "Custom"), item: sidebarAdvanced })
|
||||
modesListModel.append({ text: catalog.i18nc("@title:tab", "Recommended"), item: sidebarSimple, showFilterButton: false })
|
||||
modesListModel.append({ text: catalog.i18nc("@title:tab", "Custom"), item: sidebarAdvanced, showFilterButton: true })
|
||||
sidebarContents.push({ "item": modesListModel.get(base.currentModeIndex).item, "immediate": true });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ Column
|
|||
}
|
||||
onEntered:
|
||||
{
|
||||
var content = catalog.i18nc("@tooltip","Some setting values are different from the values stored in the profile.\n\nClick to open the profile manager.")
|
||||
var content = catalog.i18nc("@tooltip","Some setting/override values are different from the values stored in the profile.\n\nClick to open the profile manager.")
|
||||
base.showTooltip(globalProfileRow, Qt.point(0, globalProfileRow.height / 2), content)
|
||||
}
|
||||
onExited: base.hideTooltip()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue