mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-07 22:13:58 -06:00
Solved merge conflict.
This commit is contained in:
commit
090b8d4f50
98 changed files with 2002 additions and 681 deletions
|
@ -195,9 +195,8 @@ class CuraEngineBackend(Backend):
|
|||
self.slicingCancelled.emit()
|
||||
self.processingProgress.emit(0)
|
||||
Logger.log("d", "Attempting to kill the engine process")
|
||||
|
||||
self._createSocket() # Ensure that we have a fresh socket.
|
||||
if Application.getInstance().getCommandLineOption("external-backend", False):
|
||||
self._createSocket()
|
||||
return
|
||||
|
||||
if self._process is not None:
|
||||
|
@ -206,6 +205,7 @@ class CuraEngineBackend(Backend):
|
|||
self._process.terminate()
|
||||
Logger.log("d", "Engine process is killed. Received return code %s", self._process.wait())
|
||||
self._process = None
|
||||
|
||||
except Exception as e: # terminating a process that is already terminating causes an exception, silently ignore this.
|
||||
Logger.log("d", "Exception occurred while trying to kill the engine %s", str(e))
|
||||
|
||||
|
@ -236,7 +236,7 @@ class CuraEngineBackend(Backend):
|
|||
|
||||
if job.getResult() == StartSliceJob.StartJobResult.NothingToSlice:
|
||||
if Application.getInstance().getPlatformActivity:
|
||||
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice. No suitable objects found."))
|
||||
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice. No suitable models found."))
|
||||
self._error_message.show()
|
||||
self.backendStateChange.emit(BackendState.Error)
|
||||
else:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"source_version": "15.04",
|
||||
"target_version": 1,
|
||||
"target_version": 2,
|
||||
|
||||
"translation": {
|
||||
"machine_nozzle_size": "nozzle_size",
|
||||
|
@ -21,7 +21,7 @@
|
|||
"retraction_amount": "retraction_amount",
|
||||
"retraction_speed": "retraction_speed",
|
||||
"retraction_min_travel": "retraction_min_travel",
|
||||
"retraction_hop": "retraction_hop",
|
||||
"retraction_hop_enabled": "retraction_hop != 0",
|
||||
"speed_print": "print_speed",
|
||||
"speed_infill": "infill_speed if (float(infill_speed) != 0) else print_speed",
|
||||
"speed_wall_0": "inset0_speed if (float(inset0_speed) != 0) else print_speed",
|
||||
|
@ -29,7 +29,7 @@
|
|||
"speed_topbottom": "solidarea_speed if (float(solidarea_speed) != 0) else print_speed",
|
||||
"speed_travel": "travel_speed if (float(travel_speed) != 0) else travel_speed",
|
||||
"speed_layer_0": "bottom_layer_speed",
|
||||
"retraction_combing": "True if (retraction_combing == \"All\" or retraction_combing == \"No Skin\") else False",
|
||||
"retraction_combing": "\"all\" if retraction_combing == \"All\" else \"noskin\" if retraction_combing == \"No Skin\" else \"off\"",
|
||||
"cool_fan_enabled": "fan_enabled",
|
||||
"cool_fan_speed_min": "fan_speed",
|
||||
"cool_fan_speed_max": "fan_speed_max",
|
||||
|
@ -66,7 +66,7 @@
|
|||
"meshfix_union_all_remove_holes": "fix_horrible_union_all_type_b",
|
||||
"meshfix_extensive_stitching": "fix_horrible_extensive_stitching",
|
||||
"meshfix_keep_open_polygons": "fix_horrible_use_open_bits",
|
||||
"magic_mesh_surface_mode": "simple_mode",
|
||||
"magic_mesh_surface_mode": "\"surface\" if simple_mode else \"normal\"",
|
||||
"magic_spiralize": "spiralize",
|
||||
"prime_tower_enable": "wipe_tower",
|
||||
"prime_tower_size": "math.sqrt(float(wipe_tower_volume) / float(layer_height))",
|
||||
|
|
|
@ -111,7 +111,8 @@ class LegacyProfileReader(ProfileReader):
|
|||
if "translation" not in dict_of_doom:
|
||||
Logger.log("e", "Dictionary of Doom has no translation. Is it the correct JSON file?")
|
||||
return None
|
||||
current_printer = Application.getInstance().getGlobalContainerStack().findContainer({ }, DefinitionContainer)
|
||||
current_printer_definition = Application.getInstance().getGlobalContainerStack().getBottom()
|
||||
profile.setDefinition(current_printer_definition)
|
||||
for new_setting in dict_of_doom["translation"]: #Evaluate all new settings that would get a value from the translations.
|
||||
old_setting_expression = dict_of_doom["translation"][new_setting]
|
||||
compiled = compile(old_setting_expression, new_setting, "eval")
|
||||
|
@ -121,10 +122,13 @@ class LegacyProfileReader(ProfileReader):
|
|||
except Exception: #Probably some setting name that was missing or something else that went wrong in the ini file.
|
||||
Logger.log("w", "Setting " + new_setting + " could not be set because the evaluation failed. Something is probably missing from the imported legacy profile.")
|
||||
continue
|
||||
if new_value != value_using_defaults and current_printer.findDefinitions(key = new_setting).default_value != new_value: #Not equal to the default in the new Cura OR the default in the legacy Cura.
|
||||
profile.setSettingValue(new_setting, new_value) #Store the setting in the profile!
|
||||
definitions = current_printer_definition.findDefinitions(key = new_setting)
|
||||
if definitions:
|
||||
if new_value != value_using_defaults and definitions[0].default_value != new_value: # Not equal to the default in the new Cura OR the default in the legacy Cura.
|
||||
profile.setProperty(new_setting, "value", new_value) # Store the setting in the profile!
|
||||
|
||||
if len(profile.getChangedSettings()) == 0:
|
||||
if len(profile.getAllKeys()) == 0:
|
||||
Logger.log("i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile.")
|
||||
profile.setDirty(True)
|
||||
profile.addMetaDataEntry("type", "quality")
|
||||
return profile
|
93
plugins/MachineSettingsAction/MachineSettingsAction.py
Normal file
93
plugins/MachineSettingsAction/MachineSettingsAction.py
Normal file
|
@ -0,0 +1,93 @@
|
|||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
|
||||
from cura.MachineAction import MachineAction
|
||||
import cura.Settings.CuraContainerRegistry
|
||||
|
||||
import UM.Application
|
||||
import UM.Settings.InstanceContainer
|
||||
import UM.Settings.DefinitionContainer
|
||||
import UM.Logger
|
||||
|
||||
import UM.i18n
|
||||
catalog = UM.i18n.i18nCatalog("cura")
|
||||
|
||||
class MachineSettingsAction(MachineAction):
|
||||
def __init__(self, parent = None):
|
||||
super().__init__("MachineSettingsAction", catalog.i18nc("@action", "Machine Settings"))
|
||||
self._qml_url = "MachineSettingsAction.qml"
|
||||
|
||||
cura.Settings.CuraContainerRegistry.getInstance().containerAdded.connect(self._onContainerAdded)
|
||||
|
||||
def _reset(self):
|
||||
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
if global_container_stack:
|
||||
variant = global_container_stack.findContainer({"type": "variant"})
|
||||
if variant and variant.getId() == "empty_variant":
|
||||
variant_index = global_container_stack.getContainerIndex(variant)
|
||||
self._createVariant(global_container_stack, variant_index)
|
||||
|
||||
def _createVariant(self, global_container_stack, variant_index):
|
||||
# Create and switch to a variant to store the settings in
|
||||
new_variant = UM.Settings.InstanceContainer(global_container_stack.getName() + "_variant")
|
||||
new_variant.addMetaDataEntry("type", "variant")
|
||||
new_variant.setDefinition(global_container_stack.getBottom())
|
||||
UM.Settings.ContainerRegistry.getInstance().addContainer(new_variant)
|
||||
global_container_stack.replaceContainer(variant_index, new_variant)
|
||||
|
||||
def _onContainerAdded(self, container):
|
||||
# Add this action as a supported action to all machine definitions
|
||||
if isinstance(container, UM.Settings.DefinitionContainer) and container.getMetaDataEntry("type") == "machine":
|
||||
if container.getProperty("machine_extruder_count", "value") > 1:
|
||||
# Multiextruder printers are not currently supported
|
||||
UM.Logger.log("d", "Not attaching MachineSettingsAction to %s; Multi-extrusion printers are not supported", container.getId())
|
||||
return
|
||||
if container.getMetaDataEntry("has_variants", False):
|
||||
# Machines that use variants are not currently supported
|
||||
UM.Logger.log("d", "Not attaching MachineSettingsAction to %s; Machines that use variants are not supported", container.getId())
|
||||
return
|
||||
|
||||
UM.Application.getInstance().getMachineActionManager().addSupportedAction(container.getId(), self.getKey())
|
||||
|
||||
@pyqtSlot()
|
||||
def forceUpdate(self):
|
||||
# Force rebuilding the build volume by reloading the global container stack.
|
||||
# This is a bit of a hack, but it seems quick enough.
|
||||
UM.Application.getInstance().globalContainerStackChanged.emit()
|
||||
|
||||
@pyqtSlot()
|
||||
def updateHasMaterialsMetadata(self):
|
||||
# Updates the has_materials metadata flag after switching gcode flavor
|
||||
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
if global_container_stack:
|
||||
definition = global_container_stack.getBottom()
|
||||
if definition.getProperty("machine_gcode_flavor", "value") == "UltiGCode" and not definition.getMetaDataEntry("has_materials", False):
|
||||
has_materials = global_container_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode"
|
||||
|
||||
material_container = global_container_stack.findContainer({"type": "material"})
|
||||
material_index = global_container_stack.getContainerIndex(material_container)
|
||||
|
||||
if has_materials:
|
||||
if "has_materials" in global_container_stack.getMetaData():
|
||||
global_container_stack.setMetaDataEntry("has_materials", True)
|
||||
else:
|
||||
global_container_stack.addMetaDataEntry("has_materials", True)
|
||||
|
||||
# Set the material container to a sane default
|
||||
if material_container.getId() == "empty_material":
|
||||
search_criteria = { "type": "material", "definition": "fdmprinter", "id": "*pla*" }
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
|
||||
if containers:
|
||||
global_container_stack.replaceContainer(material_index, containers[0])
|
||||
else:
|
||||
# The metadata entry is stored in an ini, and ini files are parsed as strings only.
|
||||
# Because any non-empty string evaluates to a boolean True, we have to remove the entry to make it False.
|
||||
if "has_materials" in global_container_stack.getMetaData():
|
||||
global_container_stack.removeMetaDataEntry("has_materials")
|
||||
|
||||
empty_material = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_material")[0]
|
||||
global_container_stack.replaceContainer(material_index, empty_material)
|
||||
|
||||
UM.Application.getInstance().globalContainerStackChanged.emit()
|
476
plugins/MachineSettingsAction/MachineSettingsAction.qml
Normal file
476
plugins/MachineSettingsAction/MachineSettingsAction.qml
Normal file
|
@ -0,0 +1,476 @@
|
|||
// Copyright (c) 2016 Ultimaker B.V.
|
||||
// Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
|
||||
Cura.MachineAction
|
||||
{
|
||||
anchors.fill: parent;
|
||||
Item
|
||||
{
|
||||
id: bedLevelMachineAction
|
||||
anchors.fill: parent;
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
|
||||
Label
|
||||
{
|
||||
id: pageTitle
|
||||
width: parent.width
|
||||
text: catalog.i18nc("@title", "Machine Settings")
|
||||
wrapMode: Text.WordWrap
|
||||
font.pointSize: 18;
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: pageDescription
|
||||
anchors.top: pageTitle.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label", "Please enter the correct settings for your printer below:")
|
||||
}
|
||||
|
||||
Column
|
||||
{
|
||||
height: parent.height - y
|
||||
width: parent.width - UM.Theme.getSize("default_margin").width
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.top: pageDescription.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
|
||||
Column
|
||||
{
|
||||
width: parent.width / 2
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "Printer Settings")
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Grid
|
||||
{
|
||||
columns: 3
|
||||
columnSpacing: UM.Theme.getSize("default_margin").width
|
||||
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "X (Width)")
|
||||
}
|
||||
TextField
|
||||
{
|
||||
id: buildAreaWidthField
|
||||
text: machineWidthProvider.properties.value
|
||||
validator: RegExpValidator { regExp: /[0-9]{0,6}/ }
|
||||
onEditingFinished: { machineWidthProvider.setPropertyValue("value", text); manager.forceUpdate() }
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "mm")
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "Y (Depth)")
|
||||
}
|
||||
TextField
|
||||
{
|
||||
id: buildAreaDepthField
|
||||
text: machineDepthProvider.properties.value
|
||||
validator: RegExpValidator { regExp: /[0-9]{0,6}/ }
|
||||
onEditingFinished: { machineDepthProvider.setPropertyValue("value", text); manager.forceUpdate() }
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "mm")
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "Z (Height)")
|
||||
}
|
||||
TextField
|
||||
{
|
||||
id: buildAreaHeightField
|
||||
text: machineHeightProvider.properties.value
|
||||
validator: RegExpValidator { regExp: /[0-9]{0,6}/ }
|
||||
onEditingFinished: { machineHeightProvider.setPropertyValue("value", text); manager.forceUpdate() }
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "mm")
|
||||
}
|
||||
}
|
||||
|
||||
Column
|
||||
{
|
||||
CheckBox
|
||||
{
|
||||
id: heatedBedCheckBox
|
||||
text: catalog.i18nc("@option:check", "Heated Bed")
|
||||
checked: String(machineHeatedBedProvider.properties.value).toLowerCase() != 'false'
|
||||
onClicked: machineHeatedBedProvider.setPropertyValue("value", checked)
|
||||
}
|
||||
CheckBox
|
||||
{
|
||||
id: centerIsZeroCheckBox
|
||||
text: catalog.i18nc("@option:check", "Machine Center is Zero")
|
||||
checked: String(machineCenterIsZeroProvider.properties.value).toLowerCase() != 'false'
|
||||
onClicked: machineCenterIsZeroProvider.setPropertyValue("value", checked)
|
||||
}
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
spacing: UM.Theme.getSize("default_margin").width
|
||||
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "GCode Flavor")
|
||||
}
|
||||
|
||||
ComboBox
|
||||
{
|
||||
model: ["RepRap (Marlin/Sprinter)", "UltiGCode"]
|
||||
currentIndex: machineGCodeFlavorProvider.properties.value != model[1] ? 0 : 1
|
||||
onActivated:
|
||||
{
|
||||
machineGCodeFlavorProvider.setPropertyValue("value", model[index]);
|
||||
manager.updateHasMaterialsMetadata();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column
|
||||
{
|
||||
width: parent.width / 2
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "Printhead Settings")
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Grid
|
||||
{
|
||||
columns: 3
|
||||
columnSpacing: UM.Theme.getSize("default_margin").width
|
||||
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "X min")
|
||||
}
|
||||
TextField
|
||||
{
|
||||
id: printheadXMinField
|
||||
text: getHeadPolygonCoord("x", "min")
|
||||
validator: RegExpValidator { regExp: /[0-9]{0,6}/ }
|
||||
onEditingFinished: setHeadPolygon()
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "mm")
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "Y min")
|
||||
}
|
||||
TextField
|
||||
{
|
||||
id: printheadYMinField
|
||||
text: getHeadPolygonCoord("y", "min")
|
||||
validator: RegExpValidator { regExp: /[0-9]{0,6}/ }
|
||||
onEditingFinished: setHeadPolygon()
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "mm")
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "X max")
|
||||
}
|
||||
TextField
|
||||
{
|
||||
id: printheadXMaxField
|
||||
text: getHeadPolygonCoord("x", "max")
|
||||
validator: RegExpValidator { regExp: /[0-9]{0,6}/ }
|
||||
onEditingFinished: setHeadPolygon()
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "mm")
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "Y max")
|
||||
}
|
||||
TextField
|
||||
{
|
||||
id: printheadYMaxField
|
||||
text: getHeadPolygonCoord("y", "max")
|
||||
validator: RegExpValidator { regExp: /[0-9]{0,6}/ }
|
||||
onEditingFinished: setHeadPolygon()
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "mm")
|
||||
}
|
||||
|
||||
Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
|
||||
Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
|
||||
Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
|
||||
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "Gantry height")
|
||||
}
|
||||
TextField
|
||||
{
|
||||
id: gantryHeightField
|
||||
text: gantryHeightProvider.properties.value
|
||||
validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ }
|
||||
onEditingFinished: { gantryHeightProvider.setPropertyValue("value", text) }
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "mm")
|
||||
}
|
||||
|
||||
Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
|
||||
Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
|
||||
Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
|
||||
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "Nozzle size")
|
||||
}
|
||||
TextField
|
||||
{
|
||||
id: nozzleSizeField
|
||||
text: machineNozzleSizeProvider.properties.value
|
||||
validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ }
|
||||
onEditingFinished: { machineNozzleSizeProvider.setPropertyValue("value", text) }
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "mm")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
spacing: UM.Theme.getSize("default_margin").width
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: parent.height - y
|
||||
Column
|
||||
{
|
||||
height: parent.height
|
||||
width: parent.width / 2
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "Start Gcode")
|
||||
}
|
||||
TextArea
|
||||
{
|
||||
id: machineStartGcodeField
|
||||
width: parent.width
|
||||
height: parent.height - y
|
||||
text: machineStartGcodeProvider.properties.value
|
||||
onActiveFocusChanged:
|
||||
{
|
||||
if(!activeFocus)
|
||||
{
|
||||
machineStartGcodeProvider.setPropertyValue("value", machineStartGcodeField.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Column {
|
||||
height: parent.height
|
||||
width: parent.width / 2
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "End Gcode")
|
||||
}
|
||||
TextArea
|
||||
{
|
||||
id: machineEndGcodeField
|
||||
width: parent.width
|
||||
height: parent.height - y
|
||||
text: machineEndGcodeProvider.properties.value
|
||||
onActiveFocusChanged:
|
||||
{
|
||||
if(!activeFocus)
|
||||
{
|
||||
machineEndGcodeProvider.setPropertyValue("value", machineEndGcodeField.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getHeadPolygonCoord(axis, minMax)
|
||||
{
|
||||
var polygon = JSON.parse(machineHeadPolygonProvider.properties.value);
|
||||
var item = (axis == "x") ? 0 : 1
|
||||
var result = polygon[0][item];
|
||||
for(var i = 1; i < polygon.length; i++) {
|
||||
if (minMax == "min") {
|
||||
result = Math.min(result, polygon[i][item]);
|
||||
} else {
|
||||
result = Math.max(result, polygon[i][item]);
|
||||
}
|
||||
}
|
||||
return Math.abs(result);
|
||||
}
|
||||
|
||||
function setHeadPolygon()
|
||||
{
|
||||
var polygon = [];
|
||||
polygon.push([-parseFloat(printheadXMinField.text), parseFloat(printheadYMaxField.text)]);
|
||||
polygon.push([-parseFloat(printheadXMinField.text),-parseFloat(printheadYMinField.text)]);
|
||||
polygon.push([ parseFloat(printheadXMaxField.text), parseFloat(printheadYMaxField.text)]);
|
||||
polygon.push([ parseFloat(printheadXMaxField.text),-parseFloat(printheadYMinField.text)]);
|
||||
machineHeadPolygonProvider.setPropertyValue("value", JSON.stringify(polygon));
|
||||
manager.forceUpdate();
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: machineWidthProvider
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: "machine_width"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 4
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: machineDepthProvider
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: "machine_depth"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 4
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: machineHeightProvider
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: "machine_height"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 4
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: machineHeatedBedProvider
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: "machine_heated_bed"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 4
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: machineCenterIsZeroProvider
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: "machine_center_is_zero"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 4
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: machineGCodeFlavorProvider
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: "machine_gcode_flavor"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 4
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: machineNozzleSizeProvider
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: "machine_nozzle_size"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 4
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: gantryHeightProvider
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: "gantry_height"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 4
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: machineHeadPolygonProvider
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: "machine_head_with_fans_polygon"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 4
|
||||
}
|
||||
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: machineStartGcodeProvider
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: "machine_start_gcode"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 4
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: machineEndGcodeProvider
|
||||
|
||||
containerStackId: Cura.MachineManager.activeMachineId
|
||||
key: "machine_end_gcode"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 4
|
||||
}
|
||||
|
||||
}
|
21
plugins/MachineSettingsAction/__init__.py
Normal file
21
plugins/MachineSettingsAction/__init__.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from . import MachineSettingsAction
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
def getMetaData():
|
||||
return {
|
||||
"plugin": {
|
||||
"name": catalog.i18nc("@label", "Machine Settings action"),
|
||||
"author": "fieldOfView",
|
||||
"version": "1.0",
|
||||
"description": catalog.i18nc("@info:whatsthis", "Provides a way to change machine settings (such as build volume, nozzle size, etc)"),
|
||||
"api": 3
|
||||
}
|
||||
}
|
||||
|
||||
def register(app):
|
||||
return { "machine_action": MachineSettingsAction.MachineSettingsAction() }
|
|
@ -31,7 +31,7 @@ Item {
|
|||
spacing: UM.Theme.getSize("default_margin").width
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "Print object with")
|
||||
text: catalog.i18nc("@label", "Print model with")
|
||||
anchors.verticalCenter: extruderSelector.verticalCenter
|
||||
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
|
@ -154,107 +154,114 @@ Item {
|
|||
Column
|
||||
{
|
||||
spacing: UM.Theme.getSize("default_lining").height
|
||||
|
||||
Repeater
|
||||
// This is to ensure that the panel is first increasing in size up to 200 and then shows a scrollbar.
|
||||
// It kinda looks ugly otherwise (big panel, no content on it)
|
||||
height: contents.count * UM.Theme.getSize("section").height < 200 ? contents.count * UM.Theme.getSize("section").height : 200
|
||||
ScrollView
|
||||
{
|
||||
id: contents
|
||||
height: childrenRect.height;
|
||||
|
||||
model: UM.SettingDefinitionsModel
|
||||
height: parent.height
|
||||
width: UM.Theme.getSize("setting").width + UM.Theme.getSize("setting").height
|
||||
style: UM.Theme.styles.scrollview
|
||||
ListView
|
||||
{
|
||||
id: addedSettingsModel;
|
||||
containerId: Cura.MachineManager.activeDefinitionId
|
||||
expanded: [ "*" ]
|
||||
id: contents
|
||||
|
||||
visibilityHandler: Cura.PerObjectSettingVisibilityHandler
|
||||
model: UM.SettingDefinitionsModel
|
||||
{
|
||||
selectedObjectId: UM.ActiveTool.properties.getValue("SelectedObjectId")
|
||||
}
|
||||
}
|
||||
id: addedSettingsModel;
|
||||
containerId: Cura.MachineManager.activeDefinitionId
|
||||
expanded: [ "*" ]
|
||||
|
||||
delegate: Row
|
||||
{
|
||||
Loader
|
||||
{
|
||||
id: settingLoader
|
||||
width: UM.Theme.getSize("setting").width
|
||||
height: UM.Theme.getSize("section").height
|
||||
|
||||
property var definition: model
|
||||
property var settingDefinitionsModel: addedSettingsModel
|
||||
property var propertyProvider: provider
|
||||
|
||||
//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"
|
||||
|
||||
onLoaded: {
|
||||
settingLoader.item.showRevertButton = false
|
||||
settingLoader.item.showInheritButton = false
|
||||
settingLoader.item.showLinkedSettingIcon = false
|
||||
settingLoader.item.doDepthIndentation = false
|
||||
settingLoader.item.doQualityUserSettingEmphasis = false
|
||||
}
|
||||
|
||||
sourceComponent:
|
||||
visibilityHandler: Cura.PerObjectSettingVisibilityHandler
|
||||
{
|
||||
switch(model.type)
|
||||
{
|
||||
case "int":
|
||||
return settingTextField
|
||||
case "float":
|
||||
return settingTextField
|
||||
case "enum":
|
||||
return settingComboBox
|
||||
case "extruder":
|
||||
return settingExtruder
|
||||
case "bool":
|
||||
return settingCheckBox
|
||||
case "str":
|
||||
return settingTextField
|
||||
case "category":
|
||||
return settingCategory
|
||||
default:
|
||||
return settingUnknown
|
||||
selectedObjectId: UM.ActiveTool.properties.getValue("SelectedObjectId")
|
||||
}
|
||||
}
|
||||
|
||||
delegate: Row
|
||||
{
|
||||
Loader
|
||||
{
|
||||
id: settingLoader
|
||||
width: UM.Theme.getSize("setting").width
|
||||
height: UM.Theme.getSize("section").height
|
||||
|
||||
property var definition: model
|
||||
property var settingDefinitionsModel: addedSettingsModel
|
||||
property var propertyProvider: provider
|
||||
|
||||
//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"
|
||||
|
||||
onLoaded: {
|
||||
settingLoader.item.showRevertButton = false
|
||||
settingLoader.item.showInheritButton = false
|
||||
settingLoader.item.showLinkedSettingIcon = false
|
||||
settingLoader.item.doDepthIndentation = false
|
||||
settingLoader.item.doQualityUserSettingEmphasis = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
width: UM.Theme.getSize("setting").height / 2;
|
||||
height: UM.Theme.getSize("setting").height;
|
||||
|
||||
onClicked: addedSettingsModel.setVisible(model.key, false);
|
||||
|
||||
style: ButtonStyle
|
||||
{
|
||||
background: Item
|
||||
sourceComponent:
|
||||
{
|
||||
UM.RecolorImage
|
||||
switch(model.type)
|
||||
{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width
|
||||
height: parent.height / 2
|
||||
sourceSize.width: width
|
||||
sourceSize.height: width
|
||||
color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button")
|
||||
source: UM.Theme.getIcon("minus")
|
||||
case "int":
|
||||
return settingTextField
|
||||
case "float":
|
||||
return settingTextField
|
||||
case "enum":
|
||||
return settingComboBox
|
||||
case "extruder":
|
||||
return settingExtruder
|
||||
case "bool":
|
||||
return settingCheckBox
|
||||
case "str":
|
||||
return settingTextField
|
||||
case "category":
|
||||
return settingCategory
|
||||
default:
|
||||
return settingUnknown
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: provider
|
||||
Button
|
||||
{
|
||||
width: UM.Theme.getSize("setting").height / 2;
|
||||
height: UM.Theme.getSize("setting").height;
|
||||
|
||||
containerStackId: UM.ActiveTool.properties.getValue("ContainerID")
|
||||
key: model.key
|
||||
watchedProperties: [ "value", "enabled", "validationState" ]
|
||||
storeIndex: 0
|
||||
removeUnusedValue: false
|
||||
onClicked: addedSettingsModel.setVisible(model.key, false);
|
||||
|
||||
style: ButtonStyle
|
||||
{
|
||||
background: Item
|
||||
{
|
||||
UM.RecolorImage
|
||||
{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width
|
||||
height: parent.height / 2
|
||||
sourceSize.width: width
|
||||
sourceSize.height: width
|
||||
color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button")
|
||||
source: UM.Theme.getIcon("minus")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: provider
|
||||
|
||||
containerStackId: UM.ActiveTool.properties.getValue("ContainerID")
|
||||
key: model.key
|
||||
watchedProperties: [ "value", "enabled", "validationState" ]
|
||||
storeIndex: 0
|
||||
removeUnusedValue: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -306,7 +313,7 @@ Item {
|
|||
UM.Dialog {
|
||||
id: settingPickDialog
|
||||
|
||||
title: catalog.i18nc("@title:window", "Select Settings to Customize for this object")
|
||||
title: catalog.i18nc("@title:window", "Select Settings to Customize for this model")
|
||||
width: screenScaleFactor * 360;
|
||||
|
||||
property string labelFilter: ""
|
||||
|
|
|
@ -11,15 +11,15 @@ i18n_catalog = i18nCatalog("cura")
|
|||
def getMetaData():
|
||||
return {
|
||||
"plugin": {
|
||||
"name": i18n_catalog.i18nc("@label", "Per Object Settings Tool"),
|
||||
"name": i18n_catalog.i18nc("@label", "Per Model Settings Tool"),
|
||||
"author": "Ultimaker",
|
||||
"version": "1.0",
|
||||
"description": i18n_catalog.i18nc("@info:whatsthis", "Provides the Per Object Settings."),
|
||||
"description": i18n_catalog.i18nc("@info:whatsthis", "Provides the Per Model Settings."),
|
||||
"api": 3
|
||||
},
|
||||
"tool": {
|
||||
"name": i18n_catalog.i18nc("@label", "Per Object Settings"),
|
||||
"description": i18n_catalog.i18nc("@info:tooltip", "Configure Per Object Settings"),
|
||||
"name": i18n_catalog.i18nc("@label", "Per Model Settings"),
|
||||
"description": i18n_catalog.i18nc("@info:tooltip", "Configure Per Model Settings"),
|
||||
"icon": "setting_per_object",
|
||||
"tool_panel": "PerObjectSettingsPanel.qml",
|
||||
"weight": 3
|
||||
|
|
|
@ -32,20 +32,44 @@ UM.Dialog
|
|||
}
|
||||
|
||||
text: {
|
||||
if (manager.firmwareUpdateCompleteStatus)
|
||||
if (manager.errorCode == 0)
|
||||
{
|
||||
//: Firmware update status label
|
||||
return catalog.i18nc("@label","Firmware update completed.")
|
||||
}
|
||||
else if (manager.progress == 0)
|
||||
{
|
||||
//: Firmware update status label
|
||||
return catalog.i18nc("@label","Starting firmware update, this may take a while.")
|
||||
if (manager.firmwareUpdateCompleteStatus)
|
||||
{
|
||||
//: Firmware update status label
|
||||
return catalog.i18nc("@label","Firmware update completed.")
|
||||
}
|
||||
else if (manager.progress == 0)
|
||||
{
|
||||
//: Firmware update status label
|
||||
return catalog.i18nc("@label","Starting firmware update, this may take a while.")
|
||||
}
|
||||
else
|
||||
{
|
||||
//: Firmware update status label
|
||||
return catalog.i18nc("@label","Updating firmware.")
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//: Firmware update status label
|
||||
return catalog.i18nc("@label","Updating firmware.")
|
||||
switch (manager.errorCode)
|
||||
{
|
||||
case 1:
|
||||
//: Firmware update status label
|
||||
return catalog.i18nc("@label","Firmware update failed due to an unknown error.")
|
||||
case 2:
|
||||
//: Firmware update status label
|
||||
return catalog.i18nc("@label","Firmware update failed due to an communication error.")
|
||||
case 3:
|
||||
//: Firmware update status label
|
||||
return catalog.i18nc("@label","Firmware update failed due to an input/output error.")
|
||||
case 4:
|
||||
//: Firmware update status label
|
||||
return catalog.i18nc("@label","Firmware update failed due to missing firmware.")
|
||||
default:
|
||||
//: Firmware update status label
|
||||
return catalog.i18nc("@label", "Unknown error code: %1").arg(manager.errorCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ from UM.Logger import Logger
|
|||
from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState
|
||||
from UM.Message import Message
|
||||
|
||||
from PyQt5.QtCore import QUrl, pyqtSlot, pyqtSignal
|
||||
from PyQt5.QtCore import QUrl, pyqtSlot, pyqtSignal, pyqtProperty
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
catalog = i18nCatalog("cura")
|
||||
|
@ -90,6 +90,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||
self._firmware_update_finished = False
|
||||
|
||||
self._error_message = None
|
||||
self._error_code = 0
|
||||
|
||||
onError = pyqtSignal()
|
||||
|
||||
|
@ -173,6 +174,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||
|
||||
## Private function (threaded) that actually uploads the firmware.
|
||||
def _updateFirmware(self):
|
||||
self._error_code = 0
|
||||
self.setProgress(0, 100)
|
||||
self._firmware_update_finished = False
|
||||
|
||||
|
@ -182,6 +184,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||
|
||||
if len(hex_file) == 0:
|
||||
Logger.log("e", "Unable to read provided hex file. Could not update firmware")
|
||||
self._updateFirmwareFailedMissingFirmware()
|
||||
return
|
||||
|
||||
programmer = stk500v2.Stk500v2()
|
||||
|
@ -197,6 +200,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||
|
||||
if not programmer.isConnected():
|
||||
Logger.log("e", "Unable to connect with serial. Could not update firmware")
|
||||
self._updateFirmwareFailedCommunicationError()
|
||||
return
|
||||
|
||||
self._updating_firmware = True
|
||||
|
@ -204,17 +208,57 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||
try:
|
||||
programmer.programChip(hex_file)
|
||||
self._updating_firmware = False
|
||||
except serial.SerialException as e:
|
||||
Logger.log("e", "SerialException while trying to update firmware: <%s>" %(repr(e)))
|
||||
self._updateFirmwareFailedIOError()
|
||||
return
|
||||
except Exception as e:
|
||||
Logger.log("e", "Exception while trying to update firmware %s" %e)
|
||||
self._updating_firmware = False
|
||||
Logger.log("e", "Exception while trying to update firmware: <%s>" %(repr(e)))
|
||||
self._updateFirmwareFailedUnknown()
|
||||
return
|
||||
programmer.close()
|
||||
|
||||
self._updateFirmwareCompletedSucessfully()
|
||||
return
|
||||
|
||||
## Private function which makes sure that firmware update process has failed by missing firmware
|
||||
def _updateFirmwareFailedMissingFirmware(self):
|
||||
return self._updateFirmwareFailedCommon(4)
|
||||
|
||||
## Private function which makes sure that firmware update process has failed by an IO error
|
||||
def _updateFirmwareFailedIOError(self):
|
||||
return self._updateFirmwareFailedCommon(3)
|
||||
|
||||
## Private function which makes sure that firmware update process has failed by a communication problem
|
||||
def _updateFirmwareFailedCommunicationError(self):
|
||||
return self._updateFirmwareFailedCommon(2)
|
||||
|
||||
## Private function which makes sure that firmware update process has failed by an unknown error
|
||||
def _updateFirmwareFailedUnknown(self):
|
||||
return self._updateFirmwareFailedCommon(1)
|
||||
|
||||
## Private common function which makes sure that firmware update process has completed/ended with a set progress state
|
||||
def _updateFirmwareFailedCommon(self, code):
|
||||
if not code:
|
||||
raise Exception("Error code not set!")
|
||||
|
||||
self._error_code = code
|
||||
|
||||
self._firmware_update_finished = True
|
||||
self.resetFirmwareUpdate(update_has_finished = True)
|
||||
self.progressChanged.emit()
|
||||
self.firmwareUpdateComplete.emit()
|
||||
|
||||
return
|
||||
|
||||
## Private function which makes sure that firmware update process has successfully completed
|
||||
def _updateFirmwareCompletedSucessfully(self):
|
||||
self.setProgress(100, 100)
|
||||
self._firmware_update_finished = True
|
||||
|
||||
self.resetFirmwareUpdate(update_has_finished = True)
|
||||
self.firmwareUpdateComplete.emit()
|
||||
self.firmwareUpdateChange.emit()
|
||||
|
||||
return
|
||||
|
||||
## Upload new firmware to machine
|
||||
# \param filename full path of firmware file to be uploaded
|
||||
|
@ -227,8 +271,8 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||
def firmwareUpdateFinished(self):
|
||||
return self._firmware_update_finished
|
||||
|
||||
def resetFirmwareUpdateFinished(self):
|
||||
self._firmware_update_finished = False
|
||||
def resetFirmwareUpdate(self, update_has_finished = False):
|
||||
self._firmware_update_finished = update_has_finished
|
||||
self.firmwareUpdateChange.emit()
|
||||
|
||||
@pyqtSlot()
|
||||
|
|
|
@ -57,6 +57,13 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
|
|||
progress += device.progress
|
||||
return progress / len(self._usb_output_devices)
|
||||
|
||||
@pyqtProperty(int, notify = progressChanged)
|
||||
def errorCode(self):
|
||||
for printer_name, device in self._usb_output_devices.items(): # TODO: @UnusedVariable "printer_name"
|
||||
if device._error_code:
|
||||
return device._error_code
|
||||
return 0
|
||||
|
||||
## Return True if all printers finished firmware update
|
||||
@pyqtProperty(float, notify = firmwareUpdateChange)
|
||||
def firmwareUpdateCompleteStatus(self):
|
||||
|
@ -103,7 +110,7 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
|
|||
return
|
||||
|
||||
for printer_connection in self._usb_output_devices:
|
||||
self._usb_output_devices[printer_connection].resetFirmwareUpdateFinished()
|
||||
self._usb_output_devices[printer_connection].resetFirmwareUpdate()
|
||||
self.spawnFirmwareInterface("")
|
||||
for printer_connection in self._usb_output_devices:
|
||||
try:
|
||||
|
@ -111,7 +118,7 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
|
|||
except FileNotFoundError:
|
||||
# Should only happen in dev environments where the resources/firmware folder is absent.
|
||||
self._usb_output_devices[printer_connection].setProgress(100, 100)
|
||||
Logger.log("w", "No firmware found for printer %s", printer_connection)
|
||||
Logger.log("w", "No firmware found for printer %s called '%s'" %(printer_connection, self._getDefaultFirmwareName()))
|
||||
Message(i18n_catalog.i18nc("@info",
|
||||
"Could not find firmware required for the printer at %s.") % printer_connection).show()
|
||||
self._firmware_view.close()
|
||||
|
@ -126,7 +133,7 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
|
|||
self._usb_output_devices[serial_port].updateFirmware(Resources.getPath(CuraApplication.ResourceTypes.Firmware, self._getDefaultFirmwareName()))
|
||||
except FileNotFoundError:
|
||||
self._firmware_view.close()
|
||||
Logger.log("e", "Could not find firmware required for this machine")
|
||||
Logger.log("e", "Could not find firmware required for this machine called '%s'" %(self._getDefaultFirmwareName()))
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
@ -147,12 +154,12 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
|
|||
Logger.log("e", "There is no global container stack. Can not update firmware.")
|
||||
self._firmware_view.close()
|
||||
return ""
|
||||
|
||||
|
||||
# The bottom of the containerstack is the machine definition
|
||||
machine_id = global_container_stack.getBottom().id
|
||||
|
||||
|
||||
machine_has_heated_bed = global_container_stack.getProperty("machine_heated_bed", "value")
|
||||
|
||||
|
||||
if platform.system() == "Linux":
|
||||
baudrate = 115200
|
||||
else:
|
||||
|
@ -166,13 +173,15 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
|
|||
"bq_hephestos_2" : "MarlinHephestos2.hex",
|
||||
"ultimaker_original" : "MarlinUltimaker-{baudrate}.hex",
|
||||
"ultimaker_original_plus" : "MarlinUltimaker-UMOP-{baudrate}.hex",
|
||||
"ultimaker_original_dual" : "MarlinUltimaker-{baudrate}-dual.hex",
|
||||
"ultimaker2" : "MarlinUltimaker2.hex",
|
||||
"ultimaker2_go" : "MarlinUltimaker2go.hex",
|
||||
"ultimaker2_plus" : "MarlinUltimaker2plus.hex",
|
||||
"ultimaker2_plus" : "MarlinUltimaker2plus.hex",
|
||||
"ultimaker2_extended" : "MarlinUltimaker2extended.hex",
|
||||
"ultimaker2_extended_plus" : "MarlinUltimaker2extended-plus.hex",
|
||||
}
|
||||
machine_with_heated_bed = {"ultimaker_original" : "MarlinUltimaker-HBK-{baudrate}.hex",
|
||||
"ultimaker_original_dual" : "MarlinUltimaker-HBK-{baudrate}-dual.hex",
|
||||
}
|
||||
##TODO: Add check for multiple extruders
|
||||
hex_file = None
|
||||
|
|
|
@ -10,7 +10,7 @@ catalog = i18nCatalog("cura")
|
|||
|
||||
class BedLevelMachineAction(MachineAction):
|
||||
def __init__(self):
|
||||
super().__init__("BedLevel", catalog.i18nc("@action", "Level bed"))
|
||||
super().__init__("BedLevel", catalog.i18nc("@action", "Level build plate"))
|
||||
self._qml_url = "BedLevelMachineAction.qml"
|
||||
self._bed_level_position = 0
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ Cura.MachineAction
|
|||
{
|
||||
id: pageTitle
|
||||
width: parent.width
|
||||
text: catalog.i18nc("@title", "Bed Leveling")
|
||||
text: catalog.i18nc("@title", "Build Plate Leveling")
|
||||
wrapMode: Text.WordWrap
|
||||
font.pointSize: 18;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ Cura.MachineAction
|
|||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label", "For every position; insert a piece of paper under the nozzle and adjust the print bed height. The print bed height is right when the paper is slightly gripped by the tip of the nozzle.")
|
||||
text: catalog.i18nc("@label", "For every position; insert a piece of paper under the nozzle and adjust the print build plate height. The print build plate height is right when the paper is slightly gripped by the tip of the nozzle.")
|
||||
}
|
||||
|
||||
Row
|
||||
|
@ -59,7 +59,7 @@ Cura.MachineAction
|
|||
Button
|
||||
{
|
||||
id: startBedLevelingButton
|
||||
text: catalog.i18nc("@action:button","Start Bed Leveling")
|
||||
text: catalog.i18nc("@action:button","Start Build Plate Leveling")
|
||||
onClicked:
|
||||
{
|
||||
startBedLevelingButton.visible = false;
|
||||
|
|
|
@ -220,7 +220,7 @@ Cura.MachineAction
|
|||
anchors.left: parent.left
|
||||
anchors.top: nozzleTempLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Bed temperature check:")
|
||||
text: catalog.i18nc("@label","Build plate temperature check:")
|
||||
visible: checkupMachineAction.usbConnected && manager.hasHeatedBed
|
||||
}
|
||||
|
||||
|
|
|
@ -20,31 +20,25 @@ class UMOUpgradeSelection(MachineAction):
|
|||
@pyqtProperty(bool, notify = heatedBedChanged)
|
||||
def hasHeatedBed(self):
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
return global_container_stack.getProperty("machine_heated_bed", "value")
|
||||
if global_container_stack:
|
||||
return global_container_stack.getProperty("machine_heated_bed", "value")
|
||||
|
||||
@pyqtSlot()
|
||||
def addHeatedBed(self):
|
||||
@pyqtSlot(bool)
|
||||
def setHeatedBed(self, heated_bed = True):
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if global_container_stack:
|
||||
variant = global_container_stack.findContainer({"type": "variant"})
|
||||
if variant:
|
||||
if variant.getId() == "empty_variant":
|
||||
variant_index = global_container_stack.getContainerIndex(variant)
|
||||
stack_name = global_container_stack.getName()
|
||||
new_variant = UM.Settings.InstanceContainer(stack_name + "_variant")
|
||||
new_variant.addMetaDataEntry("type", "variant")
|
||||
new_variant.setDefinition(global_container_stack.getBottom())
|
||||
UM.Settings.ContainerRegistry.getInstance().addContainer(new_variant)
|
||||
global_container_stack.replaceContainer(variant_index, new_variant)
|
||||
variant = new_variant
|
||||
variant.setProperty("machine_heated_bed", "value", True)
|
||||
self.heatedBedChanged.emit()
|
||||
self._createVariant(global_container_stack, variant_index)
|
||||
variant.setProperty("machine_heated_bed", "value", heated_bed)
|
||||
self.heatedBedChanged.emit()
|
||||
|
||||
@pyqtSlot()
|
||||
def removeHeatedBed(self):
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if global_container_stack:
|
||||
variant = global_container_stack.findContainer({"type": "variant"})
|
||||
if variant:
|
||||
variant.setProperty("machine_heated_bed", "value", False)
|
||||
self.heatedBedChanged.emit()
|
||||
def _createVariant(self, global_container_stack, variant_index):
|
||||
# Create and switch to a variant to store the settings in
|
||||
new_variant = UM.Settings.InstanceContainer(global_container_stack.getName() + "_variant")
|
||||
new_variant.addMetaDataEntry("type", "variant")
|
||||
new_variant.setDefinition(global_container_stack.getBottom())
|
||||
UM.Settings.ContainerRegistry.getInstance().addContainer(new_variant)
|
||||
global_container_stack.replaceContainer(variant_index, new_variant)
|
|
@ -42,9 +42,9 @@ Cura.MachineAction
|
|||
anchors.top: pageDescription.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
|
||||
text: catalog.i18nc("@label", "Heated bed (official kit or self-built)")
|
||||
text: catalog.i18nc("@label", "Heated Build Plate (official kit or self-built)")
|
||||
checked: manager.hasHeatedBed
|
||||
onClicked: checked ? manager.addHeatedBed() : manager.removeHeatedBed()
|
||||
onClicked: manager.setHeatedBed(checked)
|
||||
}
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
|
|
|
@ -21,13 +21,11 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
|||
## Overridden from InstanceContainer
|
||||
def duplicate(self, new_id, new_name = None):
|
||||
base_file = self.getMetaDataEntry("base_file", None)
|
||||
new_uuid = str(uuid.uuid4())
|
||||
|
||||
if base_file:
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = base_file)
|
||||
if containers:
|
||||
new_basefile = containers[0].duplicate(self.getMetaDataEntry("brand") + "_" + new_id, new_name)
|
||||
new_basefile.setMetaDataEntry("GUID", new_uuid)
|
||||
base_file = new_basefile.id
|
||||
UM.Settings.ContainerRegistry.getInstance().addContainer(new_basefile)
|
||||
|
||||
|
@ -38,8 +36,8 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
|||
if variant_containers:
|
||||
new_id += "_" + variant_containers[0].getName().replace(" ", "_")
|
||||
|
||||
new_id = UM.Settings.ContainerRegistry.getInstance().createUniqueName("material", self._id, new_id, "")
|
||||
result = super().duplicate(new_id, new_name)
|
||||
result.setMetaDataEntry("GUID", new_uuid)
|
||||
if result.getMetaDataEntry("base_file", None):
|
||||
result.setMetaDataEntry("base_file", base_file)
|
||||
return result
|
||||
|
@ -58,13 +56,14 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
|||
|
||||
super().setMetaDataEntry(key, value)
|
||||
|
||||
if key == "material":
|
||||
self.setName(value)
|
||||
|
||||
for container in UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(GUID = self.getMetaDataEntry("GUID")):
|
||||
if key == "material" or key == "color_name":
|
||||
self.setName(self._profile_name(self.getMetaDataEntry("material"), self.getMetaDataEntry("color_name")))
|
||||
basefile = self.getMetaDataEntry("base_file", self._id) #if basefile is none, this is a basefile.
|
||||
# Update all containers that share GUID and basefile
|
||||
for container in UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(GUID = self.getMetaDataEntry("GUID"), base_file = basefile):
|
||||
container.setMetaData(copy.deepcopy(self._metadata))
|
||||
if key == "material":
|
||||
container.setName(value)
|
||||
if key == "material" or key == "color_name":
|
||||
container.setName(self.getName())
|
||||
|
||||
## Overridden from InstanceContainer
|
||||
def setProperty(self, key, property_name, property_value, container = None):
|
||||
|
@ -237,7 +236,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
|||
material = entry.find("./um:material", self.__namespaces)
|
||||
color = entry.find("./um:color", self.__namespaces)
|
||||
|
||||
self.setName(material.text)
|
||||
self.setName(self._profile_name(material.text, color.text))
|
||||
|
||||
self.addMetaDataEntry("brand", brand.text)
|
||||
self.addMetaDataEntry("material", material.text)
|
||||
|
@ -293,7 +292,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
|||
for identifier in identifiers:
|
||||
machine_id = self.__product_id_map.get(identifier.get("product"), None)
|
||||
if machine_id is None:
|
||||
Logger.log("w", "Cannot create material for unknown machine %s", machine_id)
|
||||
Logger.log("w", "Cannot create material for unknown machine %s", identifier.get("product"))
|
||||
continue
|
||||
|
||||
definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = machine_id)
|
||||
|
@ -369,11 +368,18 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
|||
builder.data(str(instance.value))
|
||||
builder.end("setting")
|
||||
|
||||
def _profile_name(self, material_name, color_name):
|
||||
if color_name != "Generic":
|
||||
return "%s %s" % (color_name, material_name)
|
||||
else:
|
||||
return material_name
|
||||
|
||||
# Map XML file setting names to internal names
|
||||
__material_property_setting_map = {
|
||||
"print temperature": "material_print_temperature",
|
||||
"heated bed temperature": "material_bed_temperature",
|
||||
"standby temperature": "material_standby_temperature",
|
||||
"processing temperature graph": "material_flow_temp_graph",
|
||||
"print cooling": "cool_fan_speed",
|
||||
"retraction amount": "retraction_amount",
|
||||
"retraction speed": "retraction_speed",
|
||||
|
@ -382,11 +388,11 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
|||
# Map XML file product names to internal ids
|
||||
# TODO: Move this to definition's metadata
|
||||
__product_id_map = {
|
||||
"Ultimaker2": "ultimaker2",
|
||||
"Ultimaker2+": "ultimaker2_plus",
|
||||
"Ultimaker2go": "ultimaker2_go",
|
||||
"Ultimaker2extended": "ultimaker2_extended",
|
||||
"Ultimaker2extended+": "ultimaker2_extended_plus",
|
||||
"Ultimaker 2": "ultimaker2",
|
||||
"Ultimaker 2+": "ultimaker2_plus",
|
||||
"Ultimaker 2 Go": "ultimaker2_go",
|
||||
"Ultimaker 2 Extended": "ultimaker2_extended",
|
||||
"Ultimaker 2 Extended+": "ultimaker2_extended_plus",
|
||||
"Ultimaker Original": "ultimaker_original",
|
||||
"Ultimaker Original+": "ultimaker_original_plus"
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue