diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 82a112f56f..9a74cde13f 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -388,6 +388,8 @@ class CuraApplication(QtApplication): self.getCuraSceneController().setActiveBuildPlate(0) # Initialize + self._new_quality_profile_model = None + CuraApplication.Created = True @pyqtSlot(str, result = str) @@ -896,6 +898,11 @@ class CuraApplication(QtApplication): def getPrintInformation(self): return self._print_information + def getNewQualityProfileModel(self, *args, **kwargs): + if self._new_quality_profile_model is None: + self._new_quality_profile_model = NewQualityProfilesModel(self) + return self._new_quality_profile_model + ## Registers objects for the QML engine to use. # # \param engine The QML engine. @@ -928,7 +935,7 @@ class CuraApplication(QtApplication): qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") - qmlRegisterType(NewQualityProfilesModel, "Cura", 1, 0, "NewQualityProfilesModel") + qmlRegisterSingletonType(NewQualityProfilesModel, "Cura", 1, 0, "NewQualityProfilesModel", self.getNewQualityProfileModel) qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel") qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel") diff --git a/cura/Machines/ContainerGroup.py b/cura/Machines/ContainerGroup.py index 1061abadda..3b17a0ae60 100644 --- a/cura/Machines/ContainerGroup.py +++ b/cura/Machines/ContainerGroup.py @@ -1,13 +1,18 @@ from typing import Optional -from PyQt5.Qt import QObject +from PyQt5.Qt import QObject, pyqtSlot from cura.Machines.ContainerNode import ContainerNode class ContainerGroup(QObject): - def __init__(self, parent = None): + def __init__(self, name: str, parent = None): super().__init__(parent) + self.name = name self.node_for_global = None # type: Optional[ContainerNode] self.nodes_for_extruders = dict() + + @pyqtSlot(result = str) + def getName(self) -> str: + return self.name diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 43556dbb4a..7d998361b1 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -55,9 +55,8 @@ class QualityChangesGroup: class QualityGroup(ContainerGroup): - def __init__(self, name, quality_type, parent = None): - super().__init__(parent) - self.name = name + def __init__(self, name: str, quality_type: str, parent = None): + super().__init__(name, parent) self.quality_type = quality_type self.is_available = False diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index a2be0e0e27..aeec747fa5 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -46,6 +46,7 @@ if TYPE_CHECKING: class MachineManager(QObject): + def __init__(self, parent = None): super().__init__(parent) @@ -132,9 +133,13 @@ class MachineManager(QObject): if containers: containers[0].nameChanged.connect(self._onMaterialNameChanged) - ### new + ### NEW self._current_quality_group = None + ### NEW + activeQualityGroupChanged = pyqtSignal() + + globalContainerChanged = pyqtSignal() # Emitted whenever the global stack is changed (ie: when changing between printers, changing a global profile, but not when changing a value) activeMaterialChanged = pyqtSignal() activeVariantChanged = pyqtSignal() @@ -1494,14 +1499,20 @@ class MachineManager(QObject): def _setQualityGroup(self, quality_group, empty_quality_changes = True): self._current_quality_group = quality_group + + # Set quality and quality_changes for the GlobalStack self._global_container_stack.quality = quality_group.node_for_global.getContainer() if empty_quality_changes: self._global_container_stack.qualityChanges = self._empty_quality_changes_container + + # Set quality and quality_changes for each ExtruderStack for position, node in quality_group.nodes_for_extruders.items(): self._global_container_stack.extruders[position].quality = node.getContainer() if empty_quality_changes: self._global_container_stack.extruders[position].qualityChanges = self._empty_quality_changes_container + self.activeQualityGroupChanged.emit() + def _setVariantGroup(self, position, container_node): self._global_container_stack.extruders[position].variant = container_node.getContainer() @@ -1581,8 +1592,13 @@ class MachineManager(QObject): self._updateQualityWithMaterial() @pyqtSlot("QVariant") - def handleQualityGroup(self, quality_group): + def setQualityGroup(self, quality_group): Logger.log("d", "---------------- qg = [%s]", quality_group.name) self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): self._setQualityGroup(quality_group) + + @pyqtProperty("QVariant", fset = setQualityGroup, notify = activeQualityGroupChanged) + def activeQualityGroup(self): + return self._current_quality_group + diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index 719a406406..fd508f247a 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -2,25 +2,24 @@ # Cura is released under the terms of the LGPLv3 or higher. from collections import OrderedDict +from typing import List, TYPE_CHECKING from PyQt5.QtCore import Qt from UM.Application import Application +from UM.Logger import Logger +from UM.Qt.ListModel import ListModel from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel from cura.QualityManager import QualityManager from cura.Settings.ExtruderManager import ExtruderManager - -from typing import List, TYPE_CHECKING +from cura.Machines.QualityManager import QualityGroup if TYPE_CHECKING: from cura.Settings.ExtruderStack import ExtruderStack -from UM.Qt.ListModel import ListModel - - class NewQualityProfilesModel(ListModel): IdRole = Qt.UserRole + 1 NameRole = Qt.UserRole + 2 @@ -39,32 +38,35 @@ class NewQualityProfilesModel(ListModel): self.addRoleName(self.AvailableRole, "available") self.addRoleName(self.QualityGroupRole, "quality_group") - # TODO: connect signals + # connect signals Application.getInstance().globalContainerStackChanged.connect(self._update) - Application.getInstance().getMachineManager().activeVariantChanged.connect(self._update) - Application.getInstance().getMachineManager().activeStackChanged.connect(self._update) - Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._update) + Application.getInstance().getMachineManager().activeQualityGroupChanged.connect(self._update) + + self._quality_manager = Application.getInstance()._quality_manager + + self._layer_height_unit = "" # This is cached def _update(self): - # TODO: get all available qualities - self.items.clear() + Logger.log("d", "Updating quality profile model ...") - quality_manager = Application.getInstance()._quality_manager active_global_stack = Application.getInstance().getMachineManager()._global_container_stack if active_global_stack is None: self.setItems([]) + Logger.log("d", "No active GlobalStack, set quality profile model as empty.") return - quality_group_dict = quality_manager.getQualityGroups(active_global_stack) + quality_group_dict = self._quality_manager.getQualityGroups(active_global_stack) item_list = [] - for key in sorted(quality_group_dict): quality_group = quality_group_dict[key] - item = {"id": "TODO", + layer_height = self._fetchLayerHeight(quality_group) + + item = {"id": "TODO", # TODO: probably will be removed "name": quality_group.name, - "layer_height": "TODO", + "layer_height": layer_height + self._layer_height_unit, + "layer_height_without_unit": layer_height, "available": quality_group.is_available, "quality_group": quality_group} @@ -72,6 +74,31 @@ class NewQualityProfilesModel(ListModel): self.setItems(item_list) + def _fetchLayerHeight(self, quality_group: "QualityGroup"): + active_global_stack = Application.getInstance().getMachineManager()._global_container_stack + if not self._layer_height_unit: + unit = active_global_stack.definition.getProperty("layer_height", "unit") + if not unit: + unit = "" + self._layer_height_unit = unit + + if not quality_group.is_available: + return "" + + # Get layer_height from the quality profile for the GlobalStack + container = quality_group.node_for_global.getContainer() + + layer_height = "" + if container.hasProperty("layer_height", "value"): + layer_height = str(container.getProperty("layer_height", "value")) + else: + # Look for layer_height in the GlobalStack from material -> definition + for idx in range(4): + container = active_global_stack.getContainer(idx) + if container.hasProperty("layer_height", "value"): + layer_height = container.getProperty("layer_height", "value") + break + return str(layer_height) ## QML Model for listing the current list of valid quality profiles. diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index bde60a3dde..9013216e32 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -1,8 +1,8 @@ // Copyright (c) 2016 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick 2.8 +import QtQuick.Controls 1.4 import UM 1.2 as UM import Cura 1.0 as Cura @@ -11,25 +11,18 @@ Menu { id: menu - // TODO: single instance - Cura.NewQualityProfilesModel - { - id: qualityProfilesModel - } - Instantiator { - model: qualityProfilesModel + model: Cura.NewQualityProfilesModel MenuItem { text: (model.layer_height != "") ? model.name + " - " + model.layer_height : model.name checkable: true - checked: Cura.MachineManager.activeQualityId == model.id + checked: Cura.MachineManager.activeQualityGroup.getName() == model.name exclusiveGroup: group onTriggered: { - Cura.MachineManager.handleQualityGroup(model.quality_group) - //Cura.MachineManager.setActiveQuality(model.id) + Cura.MachineManager.setQualityGroup(model.quality_group) } visible: model.available } @@ -82,23 +75,4 @@ Menu MenuItem { action: Cura.Actions.resetProfile } MenuSeparator { } MenuItem { action: Cura.Actions.manageProfiles } - - function getFilter(initial_conditions) - { - var result = initial_conditions; - - if(Cura.MachineManager.filterQualityByMachine) - { - result.definition = Cura.MachineManager.activeQualityDefinitionId; - if(Cura.MachineManager.hasMaterials) - { - result.material = Cura.MachineManager.activeQualityMaterialId; - } - } - else - { - result.definition = "fdmprinter" - } - return result - } }