mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-25 07:33:57 -06:00
CURA-4606 added first Profile management page
This commit is contained in:
parent
2d5f65a954
commit
3ff9cb6b1e
9 changed files with 260 additions and 718 deletions
|
@ -83,7 +83,7 @@ from cura.Settings.UserChangesModel import UserChangesModel
|
|||
from cura.Settings.ExtrudersModel import ExtrudersModel
|
||||
from cura.Settings.ContainerSettingsModel import ContainerSettingsModel
|
||||
from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
|
||||
from cura.Settings.QualitySettingsModel import QualitySettingsModel
|
||||
from cura.Machines.Models.QualitySettingsModel import QualitySettingsModel
|
||||
from cura.Settings.ContainerManager import ContainerManager
|
||||
|
||||
from cura.ObjectsModel import ObjectsModel
|
||||
|
|
|
@ -16,3 +16,12 @@ class ContainerGroup(QObject):
|
|||
@pyqtSlot(result = str)
|
||||
def getName(self) -> str:
|
||||
return self.name
|
||||
|
||||
def getAllKeys(self) -> set:
|
||||
result = set()
|
||||
for node in [self.node_for_global] + list(self.nodes_for_extruders.values()):
|
||||
if node is None:
|
||||
continue
|
||||
for key in node.getContainer().getAllKeys():
|
||||
result.add(key)
|
||||
return result
|
||||
|
|
147
cura/Machines/Models/QualitySettingsModel.py
Normal file
147
cura/Machines/Models/QualitySettingsModel.py
Normal file
|
@ -0,0 +1,147 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
|
||||
|
||||
from UM.Logger import Logger
|
||||
import UM.Qt
|
||||
from UM.Application import Application
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
import os
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
|
||||
class QualitySettingsModel(UM.Qt.ListModel.ListModel):
|
||||
KeyRole = Qt.UserRole + 1
|
||||
LabelRole = Qt.UserRole + 2
|
||||
UnitRole = Qt.UserRole + 3
|
||||
ProfileValueRole = Qt.UserRole + 4
|
||||
ProfileValueSourceRole = Qt.UserRole + 5
|
||||
UserValueRole = Qt.UserRole + 6
|
||||
CategoryRole = Qt.UserRole + 7
|
||||
|
||||
def __init__(self, parent = None):
|
||||
super().__init__(parent = parent)
|
||||
|
||||
self._container_registry = ContainerRegistry.getInstance()
|
||||
self._application = Application.getInstance()
|
||||
|
||||
self._extruder_position = ""
|
||||
self._quality = None
|
||||
self._i18n_catalog = None
|
||||
|
||||
self.addRoleName(self.KeyRole, "key")
|
||||
self.addRoleName(self.LabelRole, "label")
|
||||
self.addRoleName(self.UnitRole, "unit")
|
||||
self.addRoleName(self.ProfileValueRole, "profile_value")
|
||||
self.addRoleName(self.ProfileValueSourceRole, "profile_value_source")
|
||||
self.addRoleName(self.UserValueRole, "user_value")
|
||||
self.addRoleName(self.CategoryRole, "category")
|
||||
|
||||
self._empty_quality = self._container_registry.findInstanceContainers(id = "empty_quality")[0]
|
||||
|
||||
self._update()
|
||||
|
||||
def setExtruderPosition(self, extruder_position):
|
||||
if extruder_position != self._extruder_position:
|
||||
self._extruder_position = extruder_position
|
||||
self._update()
|
||||
self.extruderPositionChanged.emit()
|
||||
|
||||
extruderPositionChanged = pyqtSignal()
|
||||
@pyqtProperty(str, fset = setExtruderPosition, notify = extruderPositionChanged)
|
||||
def extruderPosition(self):
|
||||
return self._extruder_position
|
||||
|
||||
def setQuality(self, quality):
|
||||
if quality != self._quality:
|
||||
self._quality = quality
|
||||
self._update()
|
||||
self.qualityChanged.emit()
|
||||
|
||||
qualityChanged = pyqtSignal()
|
||||
@pyqtProperty(dict, fset = setQuality, notify = qualityChanged)
|
||||
def quality(self):
|
||||
return self._quality
|
||||
|
||||
def _update(self):
|
||||
if self._quality is None:
|
||||
self.setItems([])
|
||||
return
|
||||
|
||||
items = []
|
||||
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
definition_container = global_container_stack.definition
|
||||
|
||||
quality_group = self._quality["quality_group"]
|
||||
quality_changes_group = self._quality["quality_changes_group"]
|
||||
|
||||
if self._extruder_position == "":
|
||||
quality_node = quality_group.node_for_global
|
||||
else:
|
||||
quality_node = quality_group.nodes_for_extruders.get(self._extruder_position)
|
||||
settings_keys = quality_group.getAllKeys()
|
||||
quality_containers = [quality_node.getContainer()]
|
||||
|
||||
if quality_changes_group is not None:
|
||||
if self._extruder_position == "":
|
||||
quality_changes_node = quality_changes_group.node_for_global
|
||||
else:
|
||||
quality_changes_node = quality_changes_group.nodes_for_extruders.get(self._extruder_position)
|
||||
if quality_changes_node is not None: # it can be None if number of extruders are changed during runtime
|
||||
quality_containers.insert(0, quality_changes_node.getContainer())
|
||||
settings_keys.update(quality_changes_group.getAllKeys())
|
||||
|
||||
current_category = ""
|
||||
for definition in definition_container.findDefinitions():
|
||||
if definition.type == "category":
|
||||
current_category = definition.label
|
||||
if self._i18n_catalog:
|
||||
current_category = self._i18n_catalog.i18nc(definition.key + " label", definition.label)
|
||||
continue
|
||||
|
||||
profile_value = None
|
||||
profile_value_source = ""
|
||||
for quality_container in quality_containers:
|
||||
new_value = quality_container.getProperty(definition.key, "value")
|
||||
|
||||
if new_value is not None:
|
||||
profile_value_source = quality_container.getMetaDataEntry("type")
|
||||
profile_value = new_value
|
||||
|
||||
# Global tab should use resolve (if there is one)
|
||||
if self._extruder_position == "":
|
||||
resolve_value = global_container_stack.getProperty(definition.key, "resolve")
|
||||
if resolve_value is not None and definition.key in settings_keys:
|
||||
profile_value = resolve_value
|
||||
|
||||
if profile_value is not None:
|
||||
break
|
||||
|
||||
user_value = None
|
||||
if not self._extruder_position:
|
||||
user_value = global_container_stack.userChanges.getProperty(definition.key, "value")
|
||||
else:
|
||||
extruder_stack = global_container_stack.extruders[self._extruder_position]
|
||||
user_value = extruder_stack.userChanges.getProperty(definition.key, "value")
|
||||
|
||||
if profile_value is None and user_value is None:
|
||||
continue
|
||||
|
||||
label = definition.label
|
||||
if self._i18n_catalog:
|
||||
label = self._i18n_catalog.i18nc(definition.key + " label", label)
|
||||
|
||||
items.append({
|
||||
"key": definition.key,
|
||||
"label": label,
|
||||
"unit": definition.unit,
|
||||
"profile_value": "" if profile_value is None else str(profile_value), # it is for display only
|
||||
"profile_value_source": profile_value_source,
|
||||
"user_value": "" if user_value is None else str(user_value),
|
||||
"category": current_category
|
||||
})
|
||||
|
||||
self.setItems(items)
|
|
@ -138,6 +138,10 @@ class QualityManager(QObject):
|
|||
# Initialize the lookup tree for quality profiles with following structure:
|
||||
# <machine> -> <variant> -> <material>
|
||||
# -> <material>
|
||||
|
||||
self._machine_variant_material_quality_type_to_quality_dict = {} # for quality lookup
|
||||
self._machine_quality_type_to_quality_changes_dict = {} # for quality_changes lookup
|
||||
|
||||
quality_metadata_list = self._container_registry.findContainersMetadata(type = "quality")
|
||||
for metadata in quality_metadata_list:
|
||||
if metadata["id"] == "empty_quality":
|
||||
|
@ -207,7 +211,6 @@ class QualityManager(QObject):
|
|||
if machine_definition_id not in self._machine_quality_type_to_quality_changes_dict:
|
||||
self._machine_quality_type_to_quality_changes_dict[machine_definition_id] = QualityNode()
|
||||
machine_node = self._machine_quality_type_to_quality_changes_dict[machine_definition_id]
|
||||
|
||||
machine_node.addQualityChangesMetadata(quality_type, metadata)
|
||||
|
||||
def _updateMaps(self):
|
||||
|
|
|
@ -1,249 +0,0 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
|
||||
|
||||
from UM.Logger import Logger
|
||||
import UM.Qt
|
||||
from UM.Application import Application
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
import os
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
|
||||
class QualitySettingsModel(UM.Qt.ListModel.ListModel):
|
||||
KeyRole = Qt.UserRole + 1
|
||||
LabelRole = Qt.UserRole + 2
|
||||
UnitRole = Qt.UserRole + 3
|
||||
ProfileValueRole = Qt.UserRole + 4
|
||||
ProfileValueSourceRole = Qt.UserRole + 5
|
||||
UserValueRole = Qt.UserRole + 6
|
||||
CategoryRole = Qt.UserRole + 7
|
||||
|
||||
def __init__(self, parent = None):
|
||||
super().__init__(parent = parent)
|
||||
|
||||
self._container_registry = ContainerRegistry.getInstance()
|
||||
|
||||
self._extruder_id = None
|
||||
self._extruder_definition_id = None
|
||||
self._quality_id = None
|
||||
self._material_id = None
|
||||
self._i18n_catalog = None
|
||||
|
||||
self.addRoleName(self.KeyRole, "key")
|
||||
self.addRoleName(self.LabelRole, "label")
|
||||
self.addRoleName(self.UnitRole, "unit")
|
||||
self.addRoleName(self.ProfileValueRole, "profile_value")
|
||||
self.addRoleName(self.ProfileValueSourceRole, "profile_value_source")
|
||||
self.addRoleName(self.UserValueRole, "user_value")
|
||||
self.addRoleName(self.CategoryRole, "category")
|
||||
|
||||
self._empty_quality = self._container_registry.findInstanceContainers(id = "empty_quality")[0]
|
||||
|
||||
def setExtruderId(self, extruder_id):
|
||||
if extruder_id != self._extruder_id:
|
||||
self._extruder_id = extruder_id
|
||||
self._update()
|
||||
self.extruderIdChanged.emit()
|
||||
|
||||
extruderIdChanged = pyqtSignal()
|
||||
@pyqtProperty(str, fset = setExtruderId, notify = extruderIdChanged)
|
||||
def extruderId(self):
|
||||
return self._extruder_id
|
||||
|
||||
def setExtruderDefinition(self, extruder_definition):
|
||||
if extruder_definition != self._extruder_definition_id:
|
||||
self._extruder_definition_id = extruder_definition
|
||||
self._update()
|
||||
self.extruderDefinitionChanged.emit()
|
||||
|
||||
extruderDefinitionChanged = pyqtSignal()
|
||||
@pyqtProperty(str, fset = setExtruderDefinition, notify = extruderDefinitionChanged)
|
||||
def extruderDefinition(self):
|
||||
return self._extruder_definition_id
|
||||
|
||||
def setQuality(self, quality):
|
||||
if quality != self._quality_id:
|
||||
self._quality_id = quality
|
||||
self._update()
|
||||
self.qualityChanged.emit()
|
||||
|
||||
qualityChanged = pyqtSignal()
|
||||
@pyqtProperty(str, fset = setQuality, notify = qualityChanged)
|
||||
def quality(self):
|
||||
return self._quality_id
|
||||
|
||||
def setMaterial(self, material):
|
||||
if material != self._material_id:
|
||||
self._material_id = material
|
||||
self._update()
|
||||
self.materialChanged.emit()
|
||||
|
||||
materialChanged = pyqtSignal()
|
||||
@pyqtProperty(str, fset = setMaterial, notify = materialChanged)
|
||||
def material(self):
|
||||
return self._material_id
|
||||
|
||||
def _update(self):
|
||||
if not self._quality_id:
|
||||
return
|
||||
|
||||
items = []
|
||||
|
||||
definition_container = Application.getInstance().getGlobalContainerStack().getBottom()
|
||||
|
||||
containers = self._container_registry.findInstanceContainers(id = self._quality_id)
|
||||
if not containers:
|
||||
Logger.log("w", "Could not find a quality container with id %s", self._quality_id)
|
||||
return
|
||||
|
||||
quality_container = None
|
||||
quality_changes_container = None
|
||||
|
||||
if containers[0].getMetaDataEntry("type") == "quality":
|
||||
quality_container = containers[0]
|
||||
else:
|
||||
quality_changes_container = containers[0]
|
||||
|
||||
if quality_changes_container.getMetaDataEntry("quality_type") == self._empty_quality.getMetaDataEntry("quality_type"):
|
||||
quality_container = self._empty_quality
|
||||
else:
|
||||
criteria = {
|
||||
"type": "quality",
|
||||
"quality_type": quality_changes_container.getMetaDataEntry("quality_type"),
|
||||
"definition": quality_changes_container.getDefinition().getId()
|
||||
}
|
||||
|
||||
quality_container = self._container_registry.findInstanceContainers(**criteria)
|
||||
if not quality_container:
|
||||
Logger.log("w", "Could not find a quality container matching quality changes %s", quality_changes_container.getId())
|
||||
return
|
||||
|
||||
quality_container = quality_container[0]
|
||||
|
||||
quality_type = quality_container.getMetaDataEntry("quality_type")
|
||||
|
||||
if quality_type == "not_supported":
|
||||
containers = []
|
||||
else:
|
||||
definition_id = Application.getInstance().getMachineManager().getQualityDefinitionId(quality_container.getDefinition())
|
||||
definition = quality_container.getDefinition()
|
||||
|
||||
# Check if the definition container has a translation file.
|
||||
definition_suffix = ContainerRegistry.getMimeTypeForContainer(type(definition)).preferredSuffix
|
||||
catalog = i18nCatalog(os.path.basename(definition_id + "." + definition_suffix))
|
||||
if catalog.hasTranslationLoaded():
|
||||
self._i18n_catalog = catalog
|
||||
|
||||
for file_name in quality_container.getDefinition().getInheritedFiles():
|
||||
catalog = i18nCatalog(os.path.basename(file_name))
|
||||
if catalog.hasTranslationLoaded():
|
||||
self._i18n_catalog = catalog
|
||||
|
||||
criteria = {"type": "quality", "quality_type": quality_type, "definition": definition_id}
|
||||
|
||||
if self._material_id and self._material_id != "empty_material":
|
||||
criteria["material"] = self._material_id
|
||||
|
||||
criteria["extruder"] = self._extruder_id
|
||||
|
||||
containers = self._container_registry.findInstanceContainers(**criteria)
|
||||
if not containers:
|
||||
# Try again, this time without extruder
|
||||
new_criteria = criteria.copy()
|
||||
new_criteria.pop("extruder")
|
||||
containers = self._container_registry.findInstanceContainers(**new_criteria)
|
||||
|
||||
if not containers and "material" in criteria:
|
||||
# Try again, this time without material
|
||||
criteria.pop("material", None)
|
||||
containers = self._container_registry.findInstanceContainers(**criteria)
|
||||
|
||||
if not containers:
|
||||
# Try again, this time without material or extruder
|
||||
criteria.pop("extruder") # "material" has already been popped
|
||||
containers = self._container_registry.findInstanceContainers(**criteria)
|
||||
|
||||
if not containers:
|
||||
Logger.log("w", "Could not find any quality containers matching the search criteria %s" % str(criteria))
|
||||
return
|
||||
|
||||
if quality_changes_container:
|
||||
if quality_type == "not_supported":
|
||||
criteria = {"type": "quality_changes", "quality_type": quality_type, "name": quality_changes_container.getName()}
|
||||
else:
|
||||
criteria = {"type": "quality_changes", "quality_type": quality_type, "definition": definition_id, "name": quality_changes_container.getName()}
|
||||
if self._extruder_definition_id != "":
|
||||
extruder_definitions = self._container_registry.findDefinitionContainers(id = self._extruder_definition_id)
|
||||
if extruder_definitions:
|
||||
criteria["extruder"] = Application.getInstance().getMachineManager().getQualityDefinitionId(extruder_definitions[0])
|
||||
criteria["name"] = quality_changes_container.getName()
|
||||
else:
|
||||
criteria["extruder"] = None
|
||||
|
||||
changes = self._container_registry.findInstanceContainers(**criteria)
|
||||
if changes:
|
||||
containers.extend(changes)
|
||||
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
|
||||
current_category = ""
|
||||
for definition in definition_container.findDefinitions():
|
||||
if definition.type == "category":
|
||||
current_category = definition.label
|
||||
if self._i18n_catalog:
|
||||
current_category = self._i18n_catalog.i18nc(definition.key + " label", definition.label)
|
||||
continue
|
||||
|
||||
profile_value = None
|
||||
profile_value_source = ""
|
||||
for container in containers:
|
||||
new_value = container.getProperty(definition.key, "value")
|
||||
|
||||
if new_value is not None:
|
||||
profile_value_source = container.getMetaDataEntry("type")
|
||||
profile_value = new_value
|
||||
|
||||
# Global tab should use resolve (if there is one)
|
||||
if not self._extruder_id:
|
||||
resolve_value = global_container_stack.getProperty(definition.key, "resolve")
|
||||
if resolve_value is not None and profile_value is not None and profile_value_source != "quality_changes":
|
||||
profile_value = resolve_value
|
||||
|
||||
user_value = None
|
||||
if not self._extruder_id:
|
||||
user_value = global_container_stack.getTop().getProperty(definition.key, "value")
|
||||
else:
|
||||
extruder_stack = self._container_registry.findContainerStacks(id = self._extruder_id)
|
||||
if extruder_stack:
|
||||
user_value = extruder_stack[0].getTop().getProperty(definition.key, "value")
|
||||
|
||||
if profile_value is None and user_value is None:
|
||||
continue
|
||||
|
||||
settable_per_extruder = global_container_stack.getProperty(definition.key, "settable_per_extruder")
|
||||
# If a setting is not settable per extruder (global) and we're looking at an extruder tab, don't show this value.
|
||||
if self._extruder_id != "" and not settable_per_extruder:
|
||||
continue
|
||||
|
||||
# If a setting is settable per extruder (not global) and we're looking at global tab, don't show this value.
|
||||
if self._extruder_id == "" and settable_per_extruder:
|
||||
continue
|
||||
|
||||
label = definition.label
|
||||
if self._i18n_catalog:
|
||||
label = self._i18n_catalog.i18nc(definition.key + " label", label)
|
||||
|
||||
items.append({
|
||||
"key": definition.key,
|
||||
"label": label,
|
||||
"unit": definition.unit,
|
||||
"profile_value": "" if profile_value is None else str(profile_value), # it is for display only
|
||||
"profile_value_source": profile_value_source,
|
||||
"user_value": "" if user_value is None else str(user_value),
|
||||
"category": current_category
|
||||
})
|
||||
|
||||
self.setItems(items)
|
|
@ -1,98 +0,0 @@
|
|||
// Copyright (c) 2016 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.1
|
||||
import QtQuick.Controls 1.1
|
||||
|
||||
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 }
|
||||
}
|
||||
}
|
|
@ -1,356 +0,0 @@
|
|||
// Copyright (c) 2016 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.1
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Dialogs 1.2
|
||||
|
||||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
UM.ManagementPage
|
||||
{
|
||||
id: base;
|
||||
|
||||
title: catalog.i18nc("@title:tab", "Profiles");
|
||||
property var extrudersModel: Cura.ExtrudersModel{}
|
||||
|
||||
model: Cura.QualityAndUserProfilesModel { }
|
||||
|
||||
section.property: "readOnly"
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
activeId: Cura.MachineManager.activeQualityId
|
||||
activeIndex: {
|
||||
for(var i = 0; i < model.rowCount(); i++) {
|
||||
if (model.getItem(i).id == Cura.MachineManager.activeQualityId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
function canCreateProfile() {
|
||||
return base.currentItem && (base.currentItem.id == Cura.MachineManager.activeQualityId) && Cura.MachineManager.hasUserSettings;
|
||||
}
|
||||
|
||||
buttons: [
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Activate");
|
||||
iconName: "list-activate";
|
||||
enabled: base.currentItem != null ? base.currentItem.id != Cura.MachineManager.activeQualityId : false;
|
||||
onClicked:
|
||||
{
|
||||
Cura.MachineManager.setActiveQuality(base.currentItem.id)
|
||||
currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
|
||||
}
|
||||
},
|
||||
|
||||
// Create button
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@label", "Create")
|
||||
enabled: base.canCreateProfile() && !Cura.MachineManager.stacksHaveErrors
|
||||
visible: base.canCreateProfile()
|
||||
iconName: "list-add";
|
||||
|
||||
onClicked:
|
||||
{
|
||||
newNameDialog.object = base.currentItem != null ? Cura.ContainerManager.makeUniqueName(base.currentItem.name) : "";
|
||||
newNameDialog.open();
|
||||
newNameDialog.selectText();
|
||||
}
|
||||
},
|
||||
|
||||
// Duplicate button
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@label", "Duplicate")
|
||||
enabled: ! base.canCreateProfile()
|
||||
visible: ! base.canCreateProfile()
|
||||
iconName: "list-add";
|
||||
|
||||
onClicked:
|
||||
{
|
||||
newDuplicateNameDialog.object = Cura.ContainerManager.makeUniqueName(base.currentItem.name);
|
||||
newDuplicateNameDialog.open();
|
||||
newDuplicateNameDialog.selectText();
|
||||
}
|
||||
},
|
||||
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Remove");
|
||||
iconName: "list-remove";
|
||||
enabled: base.currentItem != null ? !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id) : false;
|
||||
onClicked: confirmDialog.open();
|
||||
},
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Rename");
|
||||
iconName: "edit-rename";
|
||||
enabled: base.currentItem != null ? !base.currentItem.readOnly : false;
|
||||
onClicked:
|
||||
{
|
||||
renameDialog.open();
|
||||
renameDialog.selectText();
|
||||
}
|
||||
},
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Import");
|
||||
iconName: "document-import";
|
||||
onClicked: importDialog.open();
|
||||
},
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Export")
|
||||
iconName: "document-export"
|
||||
onClicked: exportDialog.open()
|
||||
enabled: currentItem != null && !base.currentItem.readOnly
|
||||
}
|
||||
]
|
||||
|
||||
scrollviewCaption: catalog.i18nc("@label %1 is printer name","Printer: %1").arg(Cura.MachineManager.activeMachineName)
|
||||
|
||||
signal createProfile()
|
||||
onCreateProfile:
|
||||
{
|
||||
newNameDialog.object = base.currentItem != null ? Cura.ContainerManager.makeUniqueName(base.currentItem.name) : "";
|
||||
newNameDialog.open();
|
||||
newNameDialog.selectText();
|
||||
}
|
||||
|
||||
signal selectContainer(string name)
|
||||
onSelectContainer:
|
||||
{
|
||||
objectList.currentIndex = objectList.model.find("name", name);
|
||||
}
|
||||
|
||||
Item {
|
||||
visible: base.currentItem != null
|
||||
anchors.fill: parent
|
||||
|
||||
Label {
|
||||
id: profileName
|
||||
text: base.currentItem ? base.currentItem.name: ""
|
||||
font: UM.Theme.getFont("large")
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Flow {
|
||||
id: currentSettingsActions
|
||||
visible: currentItem && currentItem.id == Cura.MachineManager.activeQualityId
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: profileName.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
|
||||
Button
|
||||
{
|
||||
text: {
|
||||
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()
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Discard current changes");
|
||||
enabled: Cura.MachineManager.hasUserSettings
|
||||
onClicked: Cura.ContainerManager.clearUserContainers();
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: profileNotices
|
||||
anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : currentSettingsActions.anchors.top
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
|
||||
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 {
|
||||
id: noCurrentSettingsMessage
|
||||
visible: currentItem && currentItem.id == Cura.MachineManager.activeQualityId && !Cura.MachineManager.hasUserSettings
|
||||
text: catalog.i18nc("@action:label", "Your current settings match the selected profile.")
|
||||
wrapMode: Text.WordWrap
|
||||
width: parent.width
|
||||
}
|
||||
}
|
||||
|
||||
TabView
|
||||
{
|
||||
anchors.left: parent.left
|
||||
anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
currentIndex: Cura.ExtruderManager.extruderCount > 0 ? Cura.ExtruderManager.activeExtruderIndex + 1 : 0
|
||||
|
||||
ProfileTab
|
||||
{
|
||||
title: catalog.i18nc("@title:tab", "Global Settings");
|
||||
quality: base.currentItem != null ? base.currentItem.id : "";
|
||||
material: Cura.MachineManager.allActiveMaterialIds[Cura.MachineManager.activeMachineId]
|
||||
}
|
||||
|
||||
Repeater
|
||||
{
|
||||
model: base.extrudersModel
|
||||
|
||||
ProfileTab
|
||||
{
|
||||
title: model.name;
|
||||
extruderId: model.id;
|
||||
extruderDefinition: model.definition;
|
||||
quality: base.currentItem != null ? base.currentItem.id : "";
|
||||
material: Cura.MachineManager.allActiveMaterialIds[model.id]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
|
||||
UM.ConfirmRemoveDialog
|
||||
{
|
||||
id: confirmDialog
|
||||
object: base.currentItem != null ? base.currentItem.name : ""
|
||||
onYes:
|
||||
{
|
||||
var name = base.currentItem.name;
|
||||
Cura.ContainerManager.removeQualityChanges(name)
|
||||
if(Cura.MachineManager.activeQualityName == name)
|
||||
{
|
||||
Cura.MachineManager.setActiveQuality(base.model.getItem(0).name)
|
||||
}
|
||||
objectList.currentIndex = -1 //Reset selection.
|
||||
}
|
||||
}
|
||||
|
||||
UM.RenameDialog
|
||||
{
|
||||
title: catalog.i18nc("@title:window", "Rename Profile")
|
||||
id: renameDialog;
|
||||
object: base.currentItem != null ? base.currentItem.name : ""
|
||||
onAccepted:
|
||||
{
|
||||
Cura.ContainerManager.renameQualityChanges(base.currentItem.name, newName)
|
||||
objectList.currentIndex = -1 //Reset selection.
|
||||
}
|
||||
}
|
||||
|
||||
// Dialog to request a name when creating a new profile
|
||||
UM.RenameDialog
|
||||
{
|
||||
title: catalog.i18nc("@title:window", "Create Profile")
|
||||
id: newNameDialog;
|
||||
object: "<new name>";
|
||||
onAccepted:
|
||||
{
|
||||
var selectedContainer = Cura.ContainerManager.createQualityChanges(newName);
|
||||
base.selectContainer(selectedContainer);
|
||||
objectList.currentIndex = -1 //Reset selection.
|
||||
}
|
||||
}
|
||||
|
||||
// Dialog to request a name when duplicating a new profile
|
||||
UM.RenameDialog
|
||||
{
|
||||
title: catalog.i18nc("@title:window", "Duplicate Profile")
|
||||
id: newDuplicateNameDialog;
|
||||
object: "<new name>";
|
||||
onAccepted:
|
||||
{
|
||||
var selectedContainer = Cura.ContainerManager.duplicateQualityOrQualityChanges(base.currentItem.name, newName);
|
||||
base.selectContainer(selectedContainer);
|
||||
objectList.currentIndex = -1 //Reset selection.
|
||||
}
|
||||
}
|
||||
|
||||
MessageDialog
|
||||
{
|
||||
id: messageDialog
|
||||
title: catalog.i18nc("@window:title", "Import Profile");
|
||||
standardButtons: StandardButton.Ok
|
||||
modality: Qt.ApplicationModal
|
||||
}
|
||||
|
||||
FileDialog
|
||||
{
|
||||
id: importDialog;
|
||||
title: catalog.i18nc("@title:window", "Import Profile");
|
||||
selectExisting: true;
|
||||
nameFilters: base.model.getFileNameFilters("profile_reader")
|
||||
folder: CuraApplication.getDefaultPath("dialog_profile_path")
|
||||
onAccepted:
|
||||
{
|
||||
var result = Cura.ContainerManager.importProfile(fileUrl);
|
||||
messageDialog.text = result.message
|
||||
if(result.status == "ok")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Information
|
||||
}
|
||||
else if(result.status == "duplicate")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Warning
|
||||
}
|
||||
else
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Critical
|
||||
}
|
||||
messageDialog.open()
|
||||
CuraApplication.setDefaultPath("dialog_profile_path", folder)
|
||||
}
|
||||
}
|
||||
|
||||
FileDialog
|
||||
{
|
||||
id: exportDialog;
|
||||
title: catalog.i18nc("@title:window", "Export Profile");
|
||||
selectExisting: false;
|
||||
nameFilters: base.model.getFileNameFilters("profile_writer")
|
||||
folder: CuraApplication.getDefaultPath("dialog_profile_path")
|
||||
onAccepted:
|
||||
{
|
||||
var containers = Cura.ContainerManager.findInstanceContainers({"type": "quality_changes", "name": base.currentItem.name})
|
||||
var result = Cura.ContainerManager.exportProfile(containers, fileUrl, selectedNameFilter)
|
||||
|
||||
if(result && result.status == "error")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Critical
|
||||
messageDialog.text = result.message
|
||||
messageDialog.open()
|
||||
}
|
||||
|
||||
// else pop-up Message thing from python code
|
||||
CuraApplication.setDefaultPath("dialog_profile_path", folder)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,10 +11,8 @@ Tab
|
|||
{
|
||||
id: base
|
||||
|
||||
property string extruderId: "";
|
||||
property string extruderDefinition: "";
|
||||
property string quality: "";
|
||||
property string material: "";
|
||||
property string extruderPosition: "";
|
||||
property var quality: null;
|
||||
|
||||
TableView
|
||||
{
|
||||
|
@ -38,8 +36,8 @@ Tab
|
|||
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 != "")
|
||||
font.strikeout: styleData.column == 1 && setting.user_value != "" // TODO && quality == Cura.MachineManager.globalQualityId
|
||||
font.italic: setting.profile_value_source == "quality_changes" || (setting.user_value != "") // TODO: (setting.user_value != "" && quality == Cura.MachineManager.globalQualityId)
|
||||
opacity: font.strikeout ? 0.5 : 1
|
||||
color: styleData.textColor
|
||||
elide: Text.ElideRight
|
||||
|
@ -65,7 +63,7 @@ Tab
|
|||
{
|
||||
role: "user_value"
|
||||
title: catalog.i18nc("@title:column", "Current");
|
||||
visible: quality == Cura.MachineManager.globalQualityId
|
||||
visible: true // TODO quality == Cura.MachineManager.globalQualityId
|
||||
width: (parent.width * 0.18) | 0
|
||||
delegate: itemDelegate
|
||||
}
|
||||
|
@ -87,10 +85,8 @@ Tab
|
|||
model: Cura.QualitySettingsModel
|
||||
{
|
||||
id: qualitySettings
|
||||
extruderId: base.extruderId
|
||||
extruderDefinition: base.extruderDefinition
|
||||
extruderPosition: base.extruderPosition
|
||||
quality: base.quality != null ? base.quality : ""
|
||||
material: base.material != null ? base.material : ""
|
||||
}
|
||||
|
||||
SystemPalette { id: palette }
|
||||
|
|
|
@ -14,6 +14,7 @@ Item
|
|||
{
|
||||
id: base
|
||||
property var resetEnabled: false // Keep PreferencesDialog happy
|
||||
property var extrudersModel: Cura.ExtrudersModel{}
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
|
||||
|
@ -35,6 +36,17 @@ Item
|
|||
text: catalog.i18nc("@title:tab", "Profiles")
|
||||
}
|
||||
|
||||
property var hasCurrentItem: qualityListView.currentItem != null
|
||||
|
||||
property var currentItem: {
|
||||
var current_index = qualityListView.currentIndex;
|
||||
return qualitiesModel.getItem(current_index);
|
||||
}
|
||||
|
||||
property var isCurrentItemActivated: {
|
||||
// TODO
|
||||
}
|
||||
|
||||
Row // Button Row
|
||||
{
|
||||
id: buttonRow
|
||||
|
@ -50,8 +62,7 @@ Item
|
|||
{
|
||||
text: catalog.i18nc("@action:button", "Activate")
|
||||
iconName: "list-activate"
|
||||
//enabled: base.currentItem != null ? base.currentItem.id != Cura.MachineManager.activeQualityId : false;
|
||||
enabled: true // TODO
|
||||
enabled: base.currentItem != null ? base.currentItem.name != Cura.MachineManager.activeQualityOrQualityChangesName : false;
|
||||
onClicked: {
|
||||
// TODO
|
||||
}
|
||||
|
@ -259,6 +270,7 @@ Item
|
|||
}
|
||||
|
||||
|
||||
// details panel on the right
|
||||
Item
|
||||
{
|
||||
id: detailsPanel
|
||||
|
@ -283,11 +295,89 @@ Item
|
|||
height: childrenRect.height
|
||||
|
||||
Label {
|
||||
text: "TODO" // TODO
|
||||
text: base.currentItem.name // TODO
|
||||
font: UM.Theme.getFont("large")
|
||||
}
|
||||
}
|
||||
|
||||
Flow {
|
||||
id: currentSettingsActions
|
||||
visible: true // TODO //currentItem && currentItem.id == Cura.MachineManager.activeQualityId
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: profileName.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
|
||||
Button
|
||||
{
|
||||
text: {
|
||||
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()
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Discard current changes");
|
||||
enabled: Cura.MachineManager.hasUserSettings
|
||||
onClicked: Cura.ContainerManager.clearUserContainers();
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: profileNotices
|
||||
anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : currentSettingsActions.anchors.top
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
|
||||
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 {
|
||||
id: noCurrentSettingsMessage
|
||||
visible: currentItem && currentItem.id == Cura.MachineManager.activeQualityId && !Cura.MachineManager.hasUserSettings
|
||||
text: catalog.i18nc("@action:label", "Your current settings match the selected profile.")
|
||||
wrapMode: Text.WordWrap
|
||||
width: parent.width
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TabView
|
||||
{
|
||||
anchors.left: parent.left
|
||||
anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
currentIndex: 0
|
||||
|
||||
ProfileTab
|
||||
{
|
||||
title: catalog.i18nc("@title:tab", "Global Settings");
|
||||
quality: base.currentItem;
|
||||
}
|
||||
|
||||
Repeater
|
||||
{
|
||||
model: base.extrudersModel
|
||||
|
||||
ProfileTab
|
||||
{
|
||||
title: model.name;
|
||||
extruderPosition: model.index;
|
||||
quality: base.currentItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue