Merge branch '2.4'

This commit is contained in:
Ghostkeeper 2016-12-16 16:17:51 +01:00
commit 67d2d74f75
No known key found for this signature in database
GPG Key ID: C5F96EE2BC0F7E75
8 changed files with 243 additions and 54 deletions

View File

@ -721,7 +721,12 @@ class BuildVolume(SceneNode):
# #
# \return A sequence of setting values, one for each extruder. # \return A sequence of setting values, one for each extruder.
def _getSettingFromAllExtruders(self, setting_key, property = "value"): def _getSettingFromAllExtruders(self, setting_key, property = "value"):
return ExtruderManager.getInstance().getAllExtruderSettings(setting_key, property) all_values = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, property)
all_types = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, "type")
for i in range(len(all_values)):
if not all_values[i] and (all_types[i] == "int" or all_types[i] == "float"):
all_values[i] = 0
return all_values
## Private convenience function to get a setting from the support infill ## Private convenience function to get a setting from the support infill
# extruder. # extruder.
@ -745,16 +750,21 @@ class BuildVolume(SceneNode):
multi_extrusion = self._global_container_stack.getProperty("machine_extruder_count", "value") > 1 multi_extrusion = self._global_container_stack.getProperty("machine_extruder_count", "value") > 1
if not multi_extrusion: if not multi_extrusion:
return self._global_container_stack.getProperty(setting_key, property) stack = self._global_container_stack
else:
extruder_index = self._global_container_stack.getProperty(extruder_setting_key, "value") extruder_index = self._global_container_stack.getProperty(extruder_setting_key, "value")
if extruder_index == "-1": # If extruder index is -1 use global instead if extruder_index == "-1": # If extruder index is -1 use global instead
return self._global_container_stack.getProperty(setting_key, property) stack = self._global_container_stack
else:
extruder_stack_id = ExtruderManager.getInstance().extruderIds[str(extruder_index)] extruder_stack_id = ExtruderManager.getInstance().extruderIds[str(extruder_index)]
stack = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0] stack = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
return stack.getProperty(setting_key, property)
value = stack.getProperty(setting_key, property)
setting_type = stack.getProperty(setting_key, "type")
if not value and (setting_type == "int" or setting_type == "float"):
return 0
return value
## Convenience function to calculate the disallowed radius around the edge. ## Convenience function to calculate the disallowed radius around the edge.
# #

View File

@ -395,7 +395,12 @@ class ExtruderManager(QObject):
# \return \type{List[ContainerStack]} a list of # \return \type{List[ContainerStack]} a list of
def getActiveExtruderStacks(self): def getActiveExtruderStacks(self):
global_stack = UM.Application.getInstance().getGlobalContainerStack() global_stack = UM.Application.getInstance().getGlobalContainerStack()
return list(self._extruder_trains[global_stack.getId()].values()) if global_stack else []
result = []
if global_stack:
for extruder in sorted(self._extruder_trains[global_stack.getId()]):
result.append(self._extruder_trains[global_stack.getId()][extruder])
return result
def __globalContainerStackChanged(self): def __globalContainerStackChanged(self):
self._addCurrentMachineExtruders() self._addCurrentMachineExtruders()

View File

@ -412,6 +412,17 @@ class MachineManager(QObject):
return False return False
@pyqtProperty(int, notify = activeStackValueChanged)
def numUserSettings(self):
if not self._global_container_stack:
return 0
num_user_settings = 0
num_user_settings += len(self._global_container_stack.getTop().findInstances())
stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
for stack in stacks:
num_user_settings += len(stack.getTop().findInstances())
return num_user_settings
## Delete a user setting from the global stack and all extruder stacks. ## Delete a user setting from the global stack and all extruder stacks.
# \param key \type{str} the name of the key to delete # \param key \type{str} the name of the key to delete
@pyqtSlot(str) @pyqtSlot(str)
@ -487,6 +498,17 @@ class MachineManager(QObject):
return "" return ""
@pyqtProperty("QVariantList", notify=activeVariantChanged)
def activeVariantNames(self):
result = []
if ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() is not None:
for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
variant_container = stack.findContainer({"type": "variant"})
if variant_container and variant_container != self._empty_variant_container:
result.append(variant_container.getName())
return result
@pyqtProperty("QVariantList", notify = activeMaterialChanged) @pyqtProperty("QVariantList", notify = activeMaterialChanged)
def activeMaterialNames(self): def activeMaterialNames(self):
result = [] result = []
@ -971,6 +993,15 @@ class MachineManager(QObject):
return "" return ""
@pyqtProperty(str, notify=globalContainerChanged)
def activeDefinitionName(self):
if self._global_container_stack:
definition = self._global_container_stack.getBottom()
if definition:
return definition.getName()
return ""
## Get the Definition ID to use to select quality profiles for the currently active machine ## Get the Definition ID to use to select quality profiles for the currently active machine
# \returns DefinitionID (string) if found, empty string otherwise # \returns DefinitionID (string) if found, empty string otherwise
# \sa getQualityDefinitionId # \sa getQualityDefinitionId

View File

@ -55,9 +55,11 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
Logger.log("w", "Could not find reader that was able to read the scene data for 3MF workspace") Logger.log("w", "Could not find reader that was able to read the scene data for 3MF workspace")
return WorkspaceReader.PreReadResult.failed return WorkspaceReader.PreReadResult.failed
machine_name = "" machine_name = ""
machine_type = "" machine_type = ""
variant_type_name = i18n_catalog.i18nc("@label", "Nozzle")
num_extruders = 0
# Check if there are any conflicts, so we can ask the user. # Check if there are any conflicts, so we can ask the user.
archive = zipfile.ZipFile(file_name, "r") archive = zipfile.ZipFile(file_name, "r")
cura_file_names = [name for name in archive.namelist() if name.startswith("Cura/")] cura_file_names = [name for name in archive.namelist() if name.startswith("Cura/")]
@ -87,13 +89,22 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if not definitions: if not definitions:
definition_container = DefinitionContainer(container_id) definition_container = DefinitionContainer(container_id)
definition_container.deserialize(archive.open(definition_container_file).read().decode("utf-8")) definition_container.deserialize(archive.open(definition_container_file).read().decode("utf-8"))
else:
definition_container = definitions[0]
if definition_container.getMetaDataEntry("type") != "extruder": if definition_container.getMetaDataEntry("type") != "extruder":
machine_type = definition_container.getName() machine_type = definition_container.getName()
variant_type_name = definition_container.getMetaDataEntry("variants_name", variant_type_name)
else: else:
if definitions[0].getMetaDataEntry("type") != "extruder": num_extruders += 1
machine_type = definitions[0].getName()
Job.yieldThread() Job.yieldThread()
if num_extruders == 0:
num_extruders = 1 # No extruder stacks found, which means there is one extruder
extruders = num_extruders * [""]
material_labels = [] material_labels = []
material_conflict = False material_conflict = False
xml_material_profile = self._getXmlProfileClass() xml_material_profile = self._getXmlProfileClass()
@ -138,6 +149,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
quality_type = instance_container.getName() quality_type = instance_container.getName()
elif container_type == "user": elif container_type == "user":
num_user_settings += len(instance_container._instances) num_user_settings += len(instance_container._instances)
Job.yieldThread() Job.yieldThread()
num_visible_settings = 0 num_visible_settings = 0
try: try:
@ -168,6 +180,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
self._dialog.setMachineName(machine_name) self._dialog.setMachineName(machine_name)
self._dialog.setMaterialLabels(material_labels) self._dialog.setMaterialLabels(material_labels)
self._dialog.setMachineType(machine_type) self._dialog.setMachineType(machine_type)
self._dialog.setExtruders(extruders)
self._dialog.setVariantType(variant_type_name)
self._dialog.setHasObjectsOnPlate(Application.getInstance().getPlatformActivity) self._dialog.setHasObjectsOnPlate(Application.getInstance().getPlatformActivity)
self._dialog.show() self._dialog.show()

View File

@ -43,7 +43,9 @@ class WorkspaceDialog(QObject):
self._quality_type = "" self._quality_type = ""
self._machine_name = "" self._machine_name = ""
self._machine_type = "" self._machine_type = ""
self._variant_type = ""
self._material_labels = [] self._material_labels = []
self._extruders = []
self._objects_on_plate = False self._objects_on_plate = False
machineConflictChanged = pyqtSignal() machineConflictChanged = pyqtSignal()
@ -59,6 +61,16 @@ class WorkspaceDialog(QObject):
objectsOnPlateChanged = pyqtSignal() objectsOnPlateChanged = pyqtSignal()
numUserSettingsChanged = pyqtSignal() numUserSettingsChanged = pyqtSignal()
machineTypeChanged = pyqtSignal() machineTypeChanged = pyqtSignal()
variantTypeChanged = pyqtSignal()
extrudersChanged = pyqtSignal()
@pyqtProperty(str, notify=variantTypeChanged)
def variantType(self):
return self._variant_type
def setVariantType(self, variant_type):
self._variant_type = variant_type
self.variantTypeChanged.emit()
@pyqtProperty(str, notify=machineTypeChanged) @pyqtProperty(str, notify=machineTypeChanged)
def machineType(self): def machineType(self):
@ -92,6 +104,14 @@ class WorkspaceDialog(QObject):
self._material_labels = material_labels self._material_labels = material_labels
self.materialLabelsChanged.emit() self.materialLabelsChanged.emit()
@pyqtProperty("QVariantList", notify=extrudersChanged)
def extruders(self):
return self._extruders
def setExtruders(self, extruders):
self._extruders = extruders
self.extrudersChanged.emit()
@pyqtProperty(str, notify = machineNameChanged) @pyqtProperty(str, notify = machineNameChanged)
def machineName(self): def machineName(self):
return self._machine_name return self._machine_name

View File

@ -16,9 +16,9 @@ UM.Dialog
minimumWidth: 550 minimumWidth: 550
maximumWidth: 550 maximumWidth: 550
height: 350 height: 400
minimumHeight: 350 minimumHeight: 400
maximumHeight: 350 maximumHeight: 400
property int comboboxHeight: 15 property int comboboxHeight: 15
property int spacerHeight: 10 property int spacerHeight: 10
onClosing: manager.notifyClosed() onClosing: manager.notifyClosed()
@ -33,7 +33,15 @@ UM.Dialog
} }
Item Item
{ {
anchors.fill: parent anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
anchors.bottomMargin: 20
anchors.leftMargin:20
anchors.rightMargin: 20
UM.I18nCatalog UM.I18nCatalog
{ {
@ -133,6 +141,7 @@ UM.Dialog
} }
} }
} }
Item // Spacer Item // Spacer
{ {
height: spacerHeight height: spacerHeight
@ -321,30 +330,47 @@ UM.Dialog
height: spacerHeight height: spacerHeight
width: height width: height
} }
Row
{
width: parent.width
height: childrenRect.height
visible: manager.hasObjectsOnPlate
UM.RecolorImage
{
width: warningLabel.height
height: width
source: UM.Theme.getIcon("notice")
color: "black"
}
Label Label
{ {
id: warningLabel
text: catalog.i18nc("@action:warning", "Loading a project will clear all models on the buildplate") text: catalog.i18nc("@action:warning", "Loading a project will clear all models on the buildplate")
visible: manager.hasObjectsOnPlate
color: "red"
width: parent.width
wrapMode: Text.Wrap wrapMode: Text.Wrap
} }
} }
} }
rightButtons: [
Button
{
id: ok_button
text: catalog.i18nc("@action:button","OK");
onClicked: { manager.closeBackend(); manager.onOkButtonClicked() }
enabled: true
},
Button Button
{ {
id: cancel_button id: cancel_button
text: catalog.i18nc("@action:button","Cancel"); text: catalog.i18nc("@action:button","Cancel");
onClicked: { manager.onCancelButtonClicked() } onClicked: { manager.onCancelButtonClicked() }
enabled: true enabled: true
anchors.bottom: parent.bottom
anchors.right: ok_button.left
anchors.bottomMargin: - 0.5 * height
anchors.rightMargin:2
}
Button
{
id: ok_button
text: catalog.i18nc("@action:button","Open");
onClicked: { manager.closeBackend(); manager.onOkButtonClicked() }
anchors.bottomMargin: - 0.5 * height
anchors.bottom: parent.bottom
anchors.right: parent.right
}
} }
]
} }

View File

@ -100,7 +100,7 @@ SettingItem
maximumLength: 10; maximumLength: 10;
validator: RegExpValidator { regExp: (definition.type == "int") ? /^-?[0-9]{0,10}/ : /^-?[0-9.,]{0,10}/ } // definition.type property from parent loader used to disallow fractional number entry validator: RegExpValidator { regExp: (definition.type == "int") ? /^-?[0-9]{0,10}$/ : /^-?[0-9]?[.,]?[0-9]{0,10}$/ } // definition.type property from parent loader used to disallow fractional number entry
Binding Binding
{ {
@ -113,7 +113,8 @@ SettingItem
// 2: quality // 2: quality
// 3: material -> user changed material in materialspage // 3: material -> user changed material in materialspage
// 4: variant // 4: variant
// 5: machine // 5: machine_changes
// 6: machine
if ((base.resolve != "None" && base.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 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 // we have to choose between the resolved value (default) and the global value

View File

@ -46,7 +46,16 @@ UM.Dialog
Item Item
{ {
anchors.fill: parent anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
anchors.bottomMargin: 20
anchors.leftMargin:20
anchors.rightMargin: 20
UM.SettingDefinitionsModel UM.SettingDefinitionsModel
{ {
id: definitionsModel id: definitionsModel
@ -91,7 +100,21 @@ UM.Dialog
text: catalog.i18nc("@action:label", "Printer settings") text: catalog.i18nc("@action:label", "Printer settings")
font.bold: true font.bold: true
} }
Row
{
width: parent.width
height: childrenRect.height
Label
{
text: catalog.i18nc("@action:label", "Type")
width: parent.width / 3
}
Label
{
text: Cura.MachineManager.activeDefinitionName
width: parent.width / 3
}
}
Row Row
{ {
width: parent.width width: parent.width
@ -106,8 +129,42 @@ UM.Dialog
text: Cura.MachineManager.activeMachineName text: Cura.MachineManager.activeMachineName
width: parent.width / 3 width: parent.width / 3
} }
} }
Repeater
{
model: Cura.MachineManager.activeMaterialNames
delegate: Column
{
Item // Spacer
{
height: spacerHeight
width: height
}
Label
{
text: catalog.i18nc("@action:label", "Extruder %1").arg(index+1)
}
height: childrenRect.height
width: parent.width
Row
{
width: parent.width
height: childrenRect.height
Label
{
text: catalog.i18nc("@action:label", "%1 & material").arg(Cura.MachineManager.activeDefinitionVariantsName)
width: parent.width / 3
}
Label
{
text: Cura.MachineManager.activeVariantNames[index] + ", " + modelData
width: parent.width / 3
}
}
}
}
Item // Spacer Item // Spacer
{ {
height: spacerHeight height: spacerHeight
@ -119,7 +176,21 @@ UM.Dialog
text: catalog.i18nc("@action:label", "Profile settings") text: catalog.i18nc("@action:label", "Profile settings")
font.bold: true font.bold: true
} }
Row
{
width: parent.width
Label
{
text: catalog.i18nc("@action:label", "Not in profile")
width: parent.width / 3
}
Label
{
text: catalog.i18nc("@action:label", "%1 override(s)").arg(Cura.MachineManager.numUserSettings)
width: parent.width / 3
}
visible: Cura.MachineManager.numUserSettings
}
Row Row
{ {
width: parent.width width: parent.width
@ -136,7 +207,7 @@ UM.Dialog
} }
} }
Item // Spacer /*Item // Spacer
{ {
height: spacerHeight height: spacerHeight
width: height width: height
@ -166,8 +237,7 @@ UM.Dialog
width: parent.width / 3 width: parent.width / 3
} }
} }
} }*/
Item // Spacer Item // Spacer
{ {
@ -202,22 +272,34 @@ UM.Dialog
checked: dontShowAgain checked: dontShowAgain
} }
} }
}
rightButtons: [
Button
{
id: cancel_button
text: catalog.i18nc("@action:button","Cancel");
enabled: true
onClicked: close()
},
Button Button
{ {
id: ok_button id: ok_button
text: catalog.i18nc("@action:button","Save"); text: catalog.i18nc("@action:button","Save");
enabled: true enabled: true
onClicked: { onClicked: {
close(); yes() } close()
yes()
}
anchors.bottomMargin: - 0.5 * height
anchors.bottom: parent.bottom
anchors.right: parent.right
}
Button
{
id: cancel_button
text: catalog.i18nc("@action:button","Cancel");
enabled: true
onClicked: close()
anchors.bottom: parent.bottom
anchors.right: ok_button.left
anchors.bottomMargin: - 0.5 * height
anchors.rightMargin:2
}
} }
]
} }