Fix merge conflicts

This commit is contained in:
Lipu Fei 2019-10-15 13:08:00 +02:00
commit 43fa4337f9
12 changed files with 114 additions and 73 deletions

View file

@ -134,6 +134,9 @@ class MachineNode(ContainerNode):
groups_by_name[name] = QualityChangesGroup(name, quality_type = quality_changes["quality_type"], groups_by_name[name] = QualityChangesGroup(name, quality_type = quality_changes["quality_type"],
intent_category = quality_changes.get("intent_category", "default"), intent_category = quality_changes.get("intent_category", "default"),
parent = CuraApplication.getInstance()) parent = CuraApplication.getInstance())
# CURA-6882
# Custom qualities are always available, even if they are based on the "not supported" profile.
groups_by_name[name].is_available = True
elif groups_by_name[name].intent_category == "default": # Intent category should be stored as "default" if everything is default or as the intent if any of the extruder have an actual intent. elif groups_by_name[name].intent_category == "default": # Intent category should be stored as "default" if everything is default or as the intent if any of the extruder have an actual intent.
groups_by_name[name].intent_category = quality_changes.get("intent_category", "default") groups_by_name[name].intent_category = quality_changes.get("intent_category", "default")
@ -142,14 +145,6 @@ class MachineNode(ContainerNode):
else: # Global profile. else: # Global profile.
groups_by_name[name].metadata_for_global = quality_changes groups_by_name[name].metadata_for_global = quality_changes
quality_groups = self.getQualityGroups(variant_names, material_bases, extruder_enabled)
for quality_changes_group in groups_by_name.values():
if quality_changes_group.quality_type not in quality_groups:
quality_changes_group.is_available = False
else:
# Quality changes group is available iff the quality group it depends on is available. Irrespective of whether the intent category is available.
quality_changes_group.is_available = quality_groups[quality_changes_group.quality_type].is_available
return list(groups_by_name.values()) return list(groups_by_name.values())
## Gets the preferred global quality node, going by the preferred quality ## Gets the preferred global quality node, going by the preferred quality

View file

@ -8,6 +8,7 @@ import uuid # To generate new GUIDs for new materials.
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Logger import Logger from UM.Logger import Logger
from UM.Signal import postponeSignals, CompressTechnique
import cura.CuraApplication # Imported like this to prevent circular imports. import cura.CuraApplication # Imported like this to prevent circular imports.
from cura.Machines.ContainerTree import ContainerTree from cura.Machines.ContainerTree import ContainerTree
@ -73,6 +74,18 @@ class MaterialManagementModel(QObject):
def removeMaterial(self, material_node: "MaterialNode") -> None: def removeMaterial(self, material_node: "MaterialNode") -> None:
container_registry = CuraContainerRegistry.getInstance() container_registry = CuraContainerRegistry.getInstance()
materials_this_base_file = container_registry.findContainersMetadata(base_file = material_node.base_file) materials_this_base_file = container_registry.findContainersMetadata(base_file = material_node.base_file)
# The material containers belonging to the same material file are supposed to work together. This postponeSignals()
# does two things:
# - optimizing the signal emitting.
# - making sure that the signals will only be emitted after all the material containers have been removed.
with postponeSignals(container_registry.containerRemoved, compress = CompressTechnique.CompressPerParameterValue):
# CURA-6886: Some containers may not have been loaded. If remove one material container, its material file
# will be removed. If later we remove a sub-material container which hasn't been loaded previously, it will
# crash because removeContainer() requires to load the container first, but the material file was already
# gone.
for material_metadata in materials_this_base_file:
container_registry.findInstanceContainers(id = material_metadata["id"])
for material_metadata in materials_this_base_file: for material_metadata in materials_this_base_file:
container_registry.removeContainer(material_metadata["id"]) container_registry.removeContainer(material_metadata["id"])
@ -142,6 +155,8 @@ class MaterialManagementModel(QObject):
# This sort fixes the problem by emitting the most specific containers first. # This sort fixes the problem by emitting the most specific containers first.
new_containers = sorted(new_containers, key = lambda x: x.getId(), reverse = True) new_containers = sorted(new_containers, key = lambda x: x.getId(), reverse = True)
# Optimization. Serving the same purpose as the postponeSignals() in removeMaterial()
with postponeSignals(container_registry.containerAdded, compress=CompressTechnique.CompressPerParameterValue):
for container_to_add in new_containers: for container_to_add in new_containers:
container_to_add.setDirty(True) container_to_add.setDirty(True)
container_registry.addContainer(container_to_add) container_registry.addContainer(container_to_add)

View file

@ -13,6 +13,7 @@ from cura.Settings.ContainerManager import ContainerManager
from cura.Machines.ContainerTree import ContainerTree from cura.Machines.ContainerTree import ContainerTree
from cura.Settings.cura_empty_instance_containers import empty_quality_changes_container from cura.Settings.cura_empty_instance_containers import empty_quality_changes_container
from cura.Settings.IntentManager import IntentManager from cura.Settings.IntentManager import IntentManager
from cura.Machines.Models.MachineModelUtils import fetchLayerHeight
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")
@ -295,6 +296,8 @@ class QualityManagementModel(ListModel):
if not quality_group.is_available: if not quality_group.is_available:
continue continue
layer_height = fetchLayerHeight(quality_group)
item = {"name": quality_group.name, item = {"name": quality_group.name,
"is_read_only": True, "is_read_only": True,
"quality_group": quality_group, "quality_group": quality_group,
@ -302,10 +305,11 @@ class QualityManagementModel(ListModel):
"quality_changes_group": None, "quality_changes_group": None,
"intent_category": "default", "intent_category": "default",
"section_name": catalog.i18nc("@label", "Default"), "section_name": catalog.i18nc("@label", "Default"),
"layer_height": layer_height, # layer_height is only used for sorting
} }
item_list.append(item) item_list.append(item)
# Sort by quality names # Sort by layer_height for built-in qualities
item_list = sorted(item_list, key = lambda x: x["name"].upper()) item_list = sorted(item_list, key = lambda x: x["layer_height"])
# Create intent items (non-default) # Create intent items (non-default)
available_intent_list = IntentManager.getInstance().getCurrentAvailableIntents() available_intent_list = IntentManager.getInstance().getCurrentAvailableIntents()

View file

@ -104,6 +104,14 @@ class VariantNode(ContainerNode):
def _materialAdded(self, container: ContainerInterface) -> None: def _materialAdded(self, container: ContainerInterface) -> None:
if container.getMetaDataEntry("type") != "material": if container.getMetaDataEntry("type") != "material":
return # Not interested. return # Not interested.
if not ContainerRegistry.getInstance().findContainersMetadata(id = container.getId()):
# CURA-6889
# containerAdded and removed signals may be triggered in the next event cycle. If a container gets added
# and removed in the same event cycle, in the next cycle, the connections should just ignore the signals.
# The check here makes sure that the container in the signal still exists.
Logger.log("d", "Got container added signal for container [%s] but it no longer exists, do nothing.",
container.getId())
return
if not self.machine.has_materials: if not self.machine.has_materials:
return # We won't add any materials. return # We won't add any materials.
material_definition = container.getMetaDataEntry("definition") material_definition = container.getMetaDataEntry("definition")

View file

@ -1514,7 +1514,8 @@ class MachineManager(QObject):
if self._global_container_stack is None: if self._global_container_stack is None:
return return
machine_definition_id = self._global_container_stack.definition.id machine_definition_id = self._global_container_stack.definition.id
variant_node = self._variant_manager.getVariantNode(machine_definition_id, variant_name) machine_node = ContainerTree.getInstance().machines.get(machine_definition_id)
variant_node = machine_node.variants.get(variant_name)
self.setVariant(position, variant_node) self.setVariant(position, variant_node)
@pyqtSlot(str, "QVariant") @pyqtSlot(str, "QVariant")

View file

@ -125,7 +125,7 @@
"overrides": { "overrides": {
"machine_name": { "default_value": "Creawsome Base Printer" }, "machine_name": { "default_value": "Creawsome Base Printer" },
"machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n" }, "machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n" },
"machine_end_gcode": { "default_value": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\n\nG1 X0 Y{machine_depth} ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\n\nM84 X Y E ;Disable all steppers but Z\n" }, "machine_end_gcode": { "default_value": "G91 ;Relative positioning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\n\nG1 X0 Y{machine_depth} ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\n\nM84 X Y E ;Disable all steppers but Z\n" },
"machine_max_feedrate_x": { "value": 500 }, "machine_max_feedrate_x": { "value": 500 },
"machine_max_feedrate_y": { "value": 500 }, "machine_max_feedrate_y": { "value": 500 },

View file

@ -4,7 +4,7 @@
"inherits": "creality_base", "inherits": "creality_base",
"overrides": { "overrides": {
"machine_name": { "default_value": "Creality Ender-5" }, "machine_name": { "default_value": "Creality Ender-5" },
"machine_end_gcode": { "default_value": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\n\nG1 X0 Y0 ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\n\nM84 X Y E ;Disable all steppers but Z\n" }, "machine_end_gcode": { "default_value": "G91 ;Relative positioning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\n\nG1 X0 Y0 ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\n\nM84 X Y E ;Disable all steppers but Z\n" },
"machine_width": { "default_value": 220 }, "machine_width": { "default_value": 220 },
"machine_depth": { "default_value": 220 }, "machine_depth": { "default_value": 220 },
"machine_height": { "default_value": 300 }, "machine_height": { "default_value": 300 },

View file

@ -19,6 +19,7 @@ Item
property alias color: label.color property alias color: label.color
property alias text: label.text property alias text: label.text
property alias font: label.font property alias font: label.font
property alias elide: label.elide
property real margin: UM.Theme.getSize("narrow_margin").width property real margin: UM.Theme.getSize("narrow_margin").width
// These properties can be used in combination with layouts. // These properties can be used in combination with layouts.

View file

@ -64,8 +64,10 @@ Item
height: childrenRect.height height: childrenRect.height
Label { Label {
width: parent.width
text: materialProperties.name text: materialProperties.name
font: UM.Theme.getFont("large_bold") font: UM.Theme.getFont("large_bold")
elide: Text.ElideRight
} }
} }

View file

@ -4,6 +4,7 @@
import QtQuick 2.10 import QtQuick 2.10
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
import QtQuick.Controls 1.4 as OldControls import QtQuick.Controls 1.4 as OldControls
import QtQuick.Layouts 1.3
import UM 1.3 as UM import UM 1.3 as UM
import Cura 1.6 as Cura import Cura 1.6 as Cura
@ -66,7 +67,6 @@ Item
{ {
id: intentSelection id: intentSelection
onClicked: menu.opened ? menu.close() : menu.open() onClicked: menu.opened ? menu.close() : menu.open()
text: generateActiveQualityText()
anchors.right: parent.right anchors.right: parent.right
width: UM.Theme.getSize("print_setup_big_item").width width: UM.Theme.getSize("print_setup_big_item").width
@ -75,33 +75,43 @@ Item
baselineOffset: null // If we don't do this, there is a binding loop. WHich is a bit weird, since we override the contentItem anyway... baselineOffset: null // If we don't do this, there is a binding loop. WHich is a bit weird, since we override the contentItem anyway...
contentItem: Label contentItem: RowLayout
{
spacing: 0
anchors.left: parent.left
anchors.right: customisedSettings.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
Label
{ {
id: textLabel id: textLabel
text: intentSelection.text text: Cura.MachineManager.activeQualityDisplayNameMap["main"]
font: UM.Theme.getFont("default") font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text") color: UM.Theme.getColor("text")
anchors.left: parent.left Layout.margins: 0
anchors.leftMargin: UM.Theme.getSize("default_margin").width Layout.maximumWidth: Math.floor(parent.width * 0.7) // Always leave >= 30% for the rest of the row.
anchors.verticalCenter: intentSelection.verticalCenter
height: contentHeight height: contentHeight
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering renderType: Text.NativeRendering
elide: Text.ElideRight
} }
background: Rectangle Label
{ {
id: backgroundItem text: activeQualityDetailText()
border.color: intentSelection.hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border") font: UM.Theme.getFont("default")
border.width: UM.Theme.getSize("default_lining").width color: UM.Theme.getColor("text_detail")
radius: UM.Theme.getSize("default_radius").width Layout.margins: 0
color: UM.Theme.getColor("main_background") Layout.fillWidth: true
}
function generateActiveQualityText() height: contentHeight
verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering
elide: Text.ElideRight
function activeQualityDetailText()
{ {
var resultMap = Cura.MachineManager.activeQualityDisplayNameMap var resultMap = Cura.MachineManager.activeQualityDisplayNameMap
var resultMain = resultMap["main"]
var resultSuffix = resultMap["suffix"] var resultSuffix = resultMap["suffix"]
var result = "" var result = ""
@ -114,24 +124,28 @@ Item
{ {
if (Cura.MachineManager.activeQualityLayerHeight > 0) if (Cura.MachineManager.activeQualityLayerHeight > 0)
{ {
result = resultMain
if (resultSuffix) if (resultSuffix)
{ {
result += " - " result += " - " + resultSuffix
}
result += "<font color=\"" + UM.Theme.getColor("text_detail") + "\">"
if (resultSuffix)
{
result += resultSuffix
} }
result += " - " result += " - "
result += Cura.MachineManager.activeQualityLayerHeight + "mm" result += Cura.MachineManager.activeQualityLayerHeight + "mm"
result += "</font>"
} }
} }
return result return result
} }
}
}
background: Rectangle
{
id: backgroundItem
border.color: intentSelection.hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border")
border.width: UM.Theme.getSize("default_lining").width
radius: UM.Theme.getSize("default_radius").width
color: UM.Theme.getColor("main_background")
}
UM.SimpleButton UM.SimpleButton
{ {
@ -164,7 +178,6 @@ Item
{ {
id: downArrow id: downArrow
source: UM.Theme.getIcon("arrow_bottom") source: UM.Theme.getIcon("arrow_bottom")
width: UM.Theme.getSize("standard_arrow").width width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height height: UM.Theme.getSize("standard_arrow").height

View file

@ -37,6 +37,7 @@ RowLayout
return "" return ""
} }
font: UM.Theme.getFont("medium") font: UM.Theme.getFont("medium")
elide: Text.ElideMiddle
UM.SettingPropertyProvider UM.SettingPropertyProvider
{ {

View file

@ -104,6 +104,7 @@ def test_variantNodeInit_excludedMaterial(container_registry, machine_node):
def test_materialAdded(container_registry, machine_node, metadata, material_result_list): def test_materialAdded(container_registry, machine_node, metadata, material_result_list):
variant_node = createVariantNode("machine_1", machine_node, container_registry) variant_node = createVariantNode("machine_1", machine_node, container_registry)
machine_node.exclude_materials = ["material_3"] machine_node.exclude_materials = ["material_3"]
with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value = container_registry)):
with patch("cura.Machines.VariantNode.MaterialNode"): # We're not testing the material node here, so patch it out. with patch("cura.Machines.VariantNode.MaterialNode"): # We're not testing the material node here, so patch it out.
with patch.dict(metadata_dict, metadata): with patch.dict(metadata_dict, metadata):
mocked_container = createMockedInstanceContainer() mocked_container = createMockedInstanceContainer()