mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-14 02:07:51 -06:00
Merge branch 'master' of github.com:Ultimaker/Cura into network_rewrite
This commit is contained in:
commit
083eee2e9d
22 changed files with 129 additions and 80 deletions
|
@ -20,6 +20,8 @@ For crashes and similar issues, please attach the following information:
|
||||||
|
|
||||||
If the Cura user interface still starts, you can also reach this directory from the application menu in Help -> Show settings folder
|
If the Cura user interface still starts, you can also reach this directory from the application menu in Help -> Show settings folder
|
||||||
|
|
||||||
|
For additional support, you could also ask in the #cura channel on FreeNode IRC. For help with development, there is also the #cura-dev channel.
|
||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
|
|
@ -108,11 +108,11 @@ class CrashHandler:
|
||||||
except:
|
except:
|
||||||
self.cura_version = catalog.i18nc("@label unknown version of Cura", "Unknown")
|
self.cura_version = catalog.i18nc("@label unknown version of Cura", "Unknown")
|
||||||
|
|
||||||
crash_info = catalog.i18nc("@label Cura version", "<b>Cura version:</b> {version}<br/>").format(version = self.cura_version)
|
crash_info = "<b>" + catalog.i18nc("@label Cura version number", "Cura version") + ":</b> " + str(self.cura_version) + "<br/>"
|
||||||
crash_info += catalog.i18nc("@label Platform", "<b>Platform:</b> {platform}<br/>").format(platform = platform.platform())
|
crash_info += "<b>" + catalog.i18nc("@label Type of platform", "Platform") + ":</b> " + str(platform.platform()) + "<br/>"
|
||||||
crash_info += catalog.i18nc("@label Qt version", "<b>Qt version:</b> {qt}<br/>").format(qt = QT_VERSION_STR)
|
crash_info += "<b>" + catalog.i18nc("@label", "Qt version") + ":</b> " + str(QT_VERSION_STR) + "<br/>"
|
||||||
crash_info += catalog.i18nc("@label PyQt version", "<b>PyQt version:</b> {pyqt}<br/>").format(pyqt = PYQT_VERSION_STR)
|
crash_info += "<b>" + catalog.i18nc("@label", "PyQt version") + ":</b> " + str(PYQT_VERSION_STR) + "<br/>"
|
||||||
crash_info += catalog.i18nc("@label OpenGL", "<b>OpenGL:</b> {opengl}<br/>").format(opengl = self._getOpenGLInfo())
|
crash_info += "<b>" + catalog.i18nc("@label OpenGL version", "OpenGL") + ":</b> " + str(self._getOpenGLInfo()) + "<br/>"
|
||||||
label.setText(crash_info)
|
label.setText(crash_info)
|
||||||
|
|
||||||
layout.addWidget(label)
|
layout.addWidget(label)
|
||||||
|
@ -280,5 +280,7 @@ class CrashHandler:
|
||||||
Application.getInstance().callLater(self._show)
|
Application.getInstance().callLater(self._show)
|
||||||
|
|
||||||
def _show(self):
|
def _show(self):
|
||||||
self.dialog.exec_()
|
# When the exception is not in the fatal_exception_types list, the dialog is not created, so we don't need to show it
|
||||||
os._exit(1)
|
if self.dialog:
|
||||||
|
self.dialog.exec_()
|
||||||
|
os._exit(1)
|
||||||
|
|
|
@ -73,14 +73,8 @@ class MachineAction(QObject, PluginObject):
|
||||||
|
|
||||||
## Protected helper to create a view object based on provided QML.
|
## Protected helper to create a view object based on provided QML.
|
||||||
def _createViewFromQML(self):
|
def _createViewFromQML(self):
|
||||||
path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), self._qml_url))
|
path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), self._qml_url)
|
||||||
self._component = QQmlComponent(Application.getInstance()._engine, path)
|
self._view = Application.getInstance().createQmlComponent(path, {"manager": self})
|
||||||
self._context = QQmlContext(Application.getInstance()._engine.rootContext())
|
|
||||||
self._context.setContextProperty("manager", self)
|
|
||||||
self._view = self._component.create(self._context)
|
|
||||||
if self._view is None:
|
|
||||||
Logger.log("c", "QQmlComponent status %s", self._component.status())
|
|
||||||
Logger.log("c", "QQmlComponent error string %s", self._component.errorString())
|
|
||||||
|
|
||||||
@pyqtProperty(QObject, constant = True)
|
@pyqtProperty(QObject, constant = True)
|
||||||
def displayItem(self):
|
def displayItem(self):
|
||||||
|
|
|
@ -454,16 +454,14 @@ class CuraContainerRegistry(ContainerRegistry):
|
||||||
|
|
||||||
material_id = "default"
|
material_id = "default"
|
||||||
if machine.material.getId() not in ("empty", "empty_material"):
|
if machine.material.getId() not in ("empty", "empty_material"):
|
||||||
# TODO: find the ID that's suitable for this extruder
|
material_id = machine.material.getId()
|
||||||
pass
|
|
||||||
else:
|
else:
|
||||||
material_id = "empty_material"
|
material_id = "empty_material"
|
||||||
extruder_stack.setMaterialById(material_id)
|
extruder_stack.setMaterialById(material_id)
|
||||||
|
|
||||||
quality_id = "default"
|
quality_id = "default"
|
||||||
if machine.quality.getId() not in ("empty", "empty_quality"):
|
if machine.quality.getId() not in ("empty", "empty_quality"):
|
||||||
# TODO: find the ID that's suitable for this extruder
|
quality_id = machine.quality.getId()
|
||||||
pass
|
|
||||||
else:
|
else:
|
||||||
quality_id = "empty_quality"
|
quality_id = "empty_quality"
|
||||||
extruder_stack.setQualityById(quality_id)
|
extruder_stack.setQualityById(quality_id)
|
||||||
|
|
|
@ -121,7 +121,7 @@ class CuraContainerStack(ContainerStack):
|
||||||
#
|
#
|
||||||
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
|
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
|
||||||
def setQualityById(self, new_quality_id: str) -> None:
|
def setQualityById(self, new_quality_id: str) -> None:
|
||||||
quality = self._empty_instance_container
|
quality = self._empty_quality
|
||||||
if new_quality_id == "default":
|
if new_quality_id == "default":
|
||||||
new_quality = self.findDefaultQuality()
|
new_quality = self.findDefaultQuality()
|
||||||
if new_quality:
|
if new_quality:
|
||||||
|
@ -159,7 +159,7 @@ class CuraContainerStack(ContainerStack):
|
||||||
#
|
#
|
||||||
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
|
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
|
||||||
def setMaterialById(self, new_material_id: str) -> None:
|
def setMaterialById(self, new_material_id: str) -> None:
|
||||||
material = self._empty_instance_container
|
material = self._empty_material
|
||||||
if new_material_id == "default":
|
if new_material_id == "default":
|
||||||
new_material = self.findDefaultMaterial()
|
new_material = self.findDefaultMaterial()
|
||||||
if new_material:
|
if new_material:
|
||||||
|
@ -197,7 +197,7 @@ class CuraContainerStack(ContainerStack):
|
||||||
#
|
#
|
||||||
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
|
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
|
||||||
def setVariantById(self, new_variant_id: str) -> None:
|
def setVariantById(self, new_variant_id: str) -> None:
|
||||||
variant = self._empty_instance_container
|
variant = self._empty_variant
|
||||||
if new_variant_id == "default":
|
if new_variant_id == "default":
|
||||||
new_variant = self.findDefaultVariant()
|
new_variant = self.findDefaultVariant()
|
||||||
if new_variant:
|
if new_variant:
|
||||||
|
|
|
@ -769,9 +769,10 @@ class MachineManager(QObject):
|
||||||
candidate_quality = None
|
candidate_quality = None
|
||||||
if quality_type:
|
if quality_type:
|
||||||
candidate_quality = quality_manager.findQualityByQualityType(quality_type,
|
candidate_quality = quality_manager.findQualityByQualityType(quality_type,
|
||||||
quality_manager.getWholeMachineDefinition(machine_definition),
|
quality_manager.getWholeMachineDefinition(material_container.getDefinition()),
|
||||||
[material_container])
|
[material_container])
|
||||||
|
|
||||||
|
|
||||||
if not candidate_quality or isinstance(candidate_quality, type(self._empty_quality_changes_container)):
|
if not candidate_quality or isinstance(candidate_quality, type(self._empty_quality_changes_container)):
|
||||||
Logger.log("d", "Attempting to find fallback quality")
|
Logger.log("d", "Attempting to find fallback quality")
|
||||||
# Fall back to a quality (which must be compatible with all other extruders)
|
# Fall back to a quality (which must be compatible with all other extruders)
|
||||||
|
|
|
@ -18,4 +18,8 @@ class MaterialsModel(InstanceContainersModel):
|
||||||
# \param container The container whose metadata was changed.
|
# \param container The container whose metadata was changed.
|
||||||
def _onContainerMetaDataChanged(self, container):
|
def _onContainerMetaDataChanged(self, container):
|
||||||
if container.getMetaDataEntry("type") == "material": #Only need to update if a material was changed.
|
if container.getMetaDataEntry("type") == "material": #Only need to update if a material was changed.
|
||||||
self._update()
|
self._update()
|
||||||
|
|
||||||
|
def _onContainerChanged(self, container):
|
||||||
|
if container.getMetaDataEntry("type", "") == "material":
|
||||||
|
super()._onContainerChanged(container)
|
||||||
|
|
|
@ -751,12 +751,15 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||||
if stack.definitionChanges == self._container_registry.getEmptyInstanceContainer():
|
if stack.definitionChanges == self._container_registry.getEmptyInstanceContainer():
|
||||||
stack.setDefinitionChanges(CuraStackBuilder.createDefinitionChangesContainer(stack, stack.getId() + "_settings"))
|
stack.setDefinitionChanges(CuraStackBuilder.createDefinitionChangesContainer(stack, stack.getId() + "_settings"))
|
||||||
|
|
||||||
extruder_stacks.append(stack)
|
if stack.getMetaDataEntry("type") == "extruder_train":
|
||||||
|
extruder_stacks.append(stack)
|
||||||
|
|
||||||
# If not extruder stacks were saved in the project file (pre 3.1) create one manually
|
# If not extruder stacks were saved in the project file (pre 3.1) create one manually
|
||||||
# We re-use the container registry's addExtruderStackForSingleExtrusionMachine method for this
|
# We re-use the container registry's addExtruderStackForSingleExtrusionMachine method for this
|
||||||
if not extruder_stacks:
|
if not extruder_stacks:
|
||||||
extruder_stacks.append(self._container_registry.addExtruderStackForSingleExtrusionMachine(global_stack, "fdmextruder"))
|
stack = self._container_registry.addExtruderStackForSingleExtrusionMachine(global_stack, "fdmextruder")
|
||||||
|
if stack:
|
||||||
|
extruder_stacks.append(stack)
|
||||||
|
|
||||||
except:
|
except:
|
||||||
Logger.logException("w", "We failed to serialize the stack. Trying to clean up.")
|
Logger.logException("w", "We failed to serialize the stack. Trying to clean up.")
|
||||||
|
@ -790,6 +793,46 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||||
for stack in [global_stack] + extruder_stacks:
|
for stack in [global_stack] + extruder_stacks:
|
||||||
stack.replaceContainer(_ContainerIndexes.Quality, empty_quality_container)
|
stack.replaceContainer(_ContainerIndexes.Quality, empty_quality_container)
|
||||||
|
|
||||||
|
# Fix quality:
|
||||||
|
# The quality specified in an old project file can be wrong, for example, for UM2, it should be "um2_normal"
|
||||||
|
# but instead it was "normal". This should be fixed by setting it to the correct quality.
|
||||||
|
# Note that this only seems to happen on single-extrusion machines on the global stack, so we only apply the
|
||||||
|
# fix for that
|
||||||
|
quality = global_stack.quality
|
||||||
|
if quality.getId() not in ("empty", "empty_quality"):
|
||||||
|
quality_type = quality.getMetaDataEntry("quality_type")
|
||||||
|
quality_containers = self._container_registry.findInstanceContainers(definition = global_stack.definition.getId(),
|
||||||
|
type = "quality",
|
||||||
|
quality_type = quality_type)
|
||||||
|
quality_containers = [q for q in quality_containers if q.getMetaDataEntry("material", "") == ""]
|
||||||
|
if quality_containers:
|
||||||
|
global_stack.quality = quality_containers[0]
|
||||||
|
else:
|
||||||
|
# look for "fdmprinter" qualities if the machine-specific qualities cannot be found
|
||||||
|
quality_containers = self._container_registry.findInstanceContainers(definition = "fdmprinter",
|
||||||
|
type = "quality",
|
||||||
|
quality_type = quality_type)
|
||||||
|
quality_containers = [q for q in quality_containers if q.getMetaDataEntry("material", "") == ""]
|
||||||
|
if quality_containers:
|
||||||
|
global_stack.quality = quality_containers[0]
|
||||||
|
else:
|
||||||
|
# the quality_type of the quality profile cannot be found.
|
||||||
|
# this can happen if a quality_type has been removed in a newer version, for example:
|
||||||
|
# "extra_coarse" is removed from 2.7 to 3.0
|
||||||
|
# in this case, the quality will be reset to "normal"
|
||||||
|
quality_containers = self._container_registry.findInstanceContainers(
|
||||||
|
definition = global_stack.definition.getId(),
|
||||||
|
type = "quality",
|
||||||
|
quality_type = "normal")
|
||||||
|
quality_containers = [q for q in quality_containers if q.getMetaDataEntry("material", "") == ""]
|
||||||
|
if quality_containers:
|
||||||
|
global_stack.quality = quality_containers[0]
|
||||||
|
else:
|
||||||
|
# This should not happen!
|
||||||
|
Logger.log("e", "Cannot find quality normal for global stack [%s] [%s]",
|
||||||
|
global_stack.getId(), global_stack.definition.getId())
|
||||||
|
global_stack.quality = self._container_registry.findInstanceContainers(id = "empty_quality")[0]
|
||||||
|
|
||||||
# Replacing the old containers if resolve is "new".
|
# Replacing the old containers if resolve is "new".
|
||||||
# When resolve is "new", some containers will get renamed, so all the other containers that reference to those
|
# When resolve is "new", some containers will get renamed, so all the other containers that reference to those
|
||||||
# MUST get updated too.
|
# MUST get updated too.
|
||||||
|
|
|
@ -256,14 +256,8 @@ class WorkspaceDialog(QObject):
|
||||||
return self._result
|
return self._result
|
||||||
|
|
||||||
def _createViewFromQML(self):
|
def _createViewFromQML(self):
|
||||||
path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("3MFReader"), self._qml_url))
|
path = os.path.join(PluginRegistry.getInstance().getPluginPath("3MFReader"), self._qml_url)
|
||||||
self._component = QQmlComponent(Application.getInstance()._engine, path)
|
self._view = Application.getInstance().createQmlComponent(path, {"manager": self})
|
||||||
self._context = QQmlContext(Application.getInstance()._engine.rootContext())
|
|
||||||
self._context.setContextProperty("manager", self)
|
|
||||||
self._view = self._component.create(self._context)
|
|
||||||
if self._view is None:
|
|
||||||
Logger.log("c", "QQmlComponent status %s", self._component.status())
|
|
||||||
Logger.log("c", "QQmlComponent error string %s", self._component.errorString())
|
|
||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
# Emit signal so the right thread actually shows the view.
|
# Emit signal so the right thread actually shows the view.
|
||||||
|
|
|
@ -106,9 +106,5 @@ class ChangeLog(Extension, QObject,):
|
||||||
self._changelog_window.hide()
|
self._changelog_window.hide()
|
||||||
|
|
||||||
def createChangelogWindow(self):
|
def createChangelogWindow(self):
|
||||||
path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "ChangeLog.qml"))
|
path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "ChangeLog.qml")
|
||||||
|
self._changelog_window = Application.getInstance().createQmlComponent(path, {"manager": self})
|
||||||
component = QQmlComponent(Application.getInstance()._engine, path)
|
|
||||||
self._changelog_context = QQmlContext(Application.getInstance()._engine.rootContext())
|
|
||||||
self._changelog_context.setContextProperty("manager", self)
|
|
||||||
self._changelog_window = component.create(self._changelog_context)
|
|
||||||
|
|
|
@ -95,22 +95,22 @@ class ProcessSlicedLayersJob(Job):
|
||||||
|
|
||||||
# Find the minimum layer number
|
# Find the minimum layer number
|
||||||
# When using a raft, the raft layers are sent as layers < 0. Instead of allowing layers < 0, we
|
# When using a raft, the raft layers are sent as layers < 0. Instead of allowing layers < 0, we
|
||||||
# instead simply offset all other layers so the lowest layer is always 0.
|
# instead simply offset all other layers so the lowest layer is always 0. It could happens that
|
||||||
|
# the first raft layer has value -8 but there are just 4 raft (negative) layers.
|
||||||
min_layer_number = 0
|
min_layer_number = 0
|
||||||
|
negative_layers = 0
|
||||||
for layer in self._layers:
|
for layer in self._layers:
|
||||||
if layer.id < min_layer_number:
|
if layer.id < min_layer_number:
|
||||||
min_layer_number = layer.id
|
min_layer_number = layer.id
|
||||||
|
if layer.id < 0:
|
||||||
|
negative_layers += 1
|
||||||
|
|
||||||
current_layer = 0
|
current_layer = 0
|
||||||
|
|
||||||
for layer in self._layers:
|
for layer in self._layers:
|
||||||
abs_layer_number = layer.id + abs(min_layer_number)
|
# Negative layers are offset by the minimum layer number, but the positive layers are just
|
||||||
|
# offset by the number of negative layers so there is no layer gap between raft and model
|
||||||
# Workaround when the last layer doesn't have paths, this layer is skipped because this was generating
|
abs_layer_number = layer.id + abs(min_layer_number) if layer.id < 0 else layer.id + negative_layers
|
||||||
# some glitches when rendering.
|
|
||||||
if layer.id == len(self._layers)-1 and layer.repeatedMessageCount("path_segment") == 0:
|
|
||||||
Logger.log("i", "No sliced data in the layer", layer.id)
|
|
||||||
continue
|
|
||||||
|
|
||||||
layer_data.addLayer(abs_layer_number)
|
layer_data.addLayer(abs_layer_number)
|
||||||
this_layer = layer_data.getLayer(abs_layer_number)
|
this_layer = layer_data.getLayer(abs_layer_number)
|
||||||
|
|
|
@ -144,6 +144,11 @@ class GCodeReader(MeshReader):
|
||||||
this_layer.polygons.append(this_poly)
|
this_layer.polygons.append(this_poly)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def _createEmptyLayer(self, layer_number):
|
||||||
|
self._layer_data_builder.addLayer(layer_number)
|
||||||
|
self._layer_data_builder.setLayerHeight(layer_number, 0)
|
||||||
|
self._layer_data_builder.setLayerThickness(layer_number, 0)
|
||||||
|
|
||||||
def _calculateLineWidth(self, current_point, previous_point, current_extrusion, previous_extrusion, layer_thickness):
|
def _calculateLineWidth(self, current_point, previous_point, current_extrusion, previous_extrusion, layer_thickness):
|
||||||
# Area of the filament
|
# Area of the filament
|
||||||
Af = (self._filament_diameter / 2) ** 2 * numpy.pi
|
Af = (self._filament_diameter / 2) ** 2 * numpy.pi
|
||||||
|
@ -206,7 +211,6 @@ class GCodeReader(MeshReader):
|
||||||
return self._position(
|
return self._position(
|
||||||
params.x if params.x is not None else position.x,
|
params.x if params.x is not None else position.x,
|
||||||
params.y if params.y is not None else position.y,
|
params.y if params.y is not None else position.y,
|
||||||
|
|
||||||
0,
|
0,
|
||||||
position.f,
|
position.f,
|
||||||
position.e)
|
position.e)
|
||||||
|
@ -269,11 +273,11 @@ class GCodeReader(MeshReader):
|
||||||
position.e.extend([0] * (self._extruder_number - len(position.e) + 1))
|
position.e.extend([0] * (self._extruder_number - len(position.e) + 1))
|
||||||
return position
|
return position
|
||||||
|
|
||||||
def _processMCode(self, m):
|
def _processMCode(self, M):
|
||||||
if m == 82:
|
if M == 82:
|
||||||
# Set absolute extrusion mode
|
# Set absolute extrusion mode
|
||||||
self._is_absolute_extrusion = True
|
self._is_absolute_extrusion = True
|
||||||
elif m == 83:
|
elif M == 83:
|
||||||
# Set relative extrusion mode
|
# Set relative extrusion mode
|
||||||
self._is_absolute_extrusion = False
|
self._is_absolute_extrusion = False
|
||||||
|
|
||||||
|
@ -333,6 +337,9 @@ class GCodeReader(MeshReader):
|
||||||
|
|
||||||
current_position = self._position(0, 0, 0, 0, [0])
|
current_position = self._position(0, 0, 0, 0, [0])
|
||||||
current_path = []
|
current_path = []
|
||||||
|
min_layer_number = 0
|
||||||
|
negative_layers = 0
|
||||||
|
previous_layer = 0
|
||||||
|
|
||||||
for line in file:
|
for line in file:
|
||||||
if self._cancelled:
|
if self._cancelled:
|
||||||
|
@ -370,7 +377,23 @@ class GCodeReader(MeshReader):
|
||||||
layer_number = int(line[len(self._layer_keyword):])
|
layer_number = int(line[len(self._layer_keyword):])
|
||||||
self._createPolygon(self._current_layer_thickness, current_path, self._extruder_offsets.get(self._extruder_number, [0, 0]))
|
self._createPolygon(self._current_layer_thickness, current_path, self._extruder_offsets.get(self._extruder_number, [0, 0]))
|
||||||
current_path.clear()
|
current_path.clear()
|
||||||
|
|
||||||
|
# When using a raft, the raft layers are stored as layers < 0, it mimics the same behavior
|
||||||
|
# as in ProcessSlicedLayersJob
|
||||||
|
if layer_number < min_layer_number:
|
||||||
|
min_layer_number = layer_number
|
||||||
|
if layer_number < 0:
|
||||||
|
layer_number += abs(min_layer_number)
|
||||||
|
negative_layers += 1
|
||||||
|
else:
|
||||||
|
layer_number += negative_layers
|
||||||
|
|
||||||
|
# In case there is a gap in the layer count, empty layers are created
|
||||||
|
for empty_layer in range(previous_layer + 1, layer_number):
|
||||||
|
self._createEmptyLayer(empty_layer)
|
||||||
|
|
||||||
self._layer_number = layer_number
|
self._layer_number = layer_number
|
||||||
|
previous_layer = layer_number
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -376,7 +376,7 @@ class SimulationView(View):
|
||||||
if layer is None:
|
if layer is None:
|
||||||
return
|
return
|
||||||
new_max_paths = layer.lineMeshElementCount()
|
new_max_paths = layer.lineMeshElementCount()
|
||||||
if new_max_paths > 0 and new_max_paths != self._max_paths:
|
if new_max_paths >= 0 and new_max_paths != self._max_paths:
|
||||||
self._max_paths = new_max_paths
|
self._max_paths = new_max_paths
|
||||||
self.maxPathsChanged.emit()
|
self.maxPathsChanged.emit()
|
||||||
|
|
||||||
|
|
|
@ -138,11 +138,10 @@ Item
|
||||||
text: catalog.i18nc("@label:listbox", "Feedrate"),
|
text: catalog.i18nc("@label:listbox", "Feedrate"),
|
||||||
type_id: 2
|
type_id: 2
|
||||||
})
|
})
|
||||||
// TODO DON'T DELETE!!!! This part must be enabled when adaptive layer height feature is available
|
layerViewTypes.append({
|
||||||
// layerViewTypes.append({
|
text: catalog.i18nc("@label:listbox", "Layer thickness"),
|
||||||
// text: catalog.i18nc("@label:listbox", "Layer thickness"),
|
type_id: 3 // these ids match the switching in the shader
|
||||||
// type_id: 3 // these ids match the switching in the shader
|
})
|
||||||
// })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ComboBox
|
ComboBox
|
||||||
|
|
|
@ -486,7 +486,7 @@ class NetworkClusterPrinterOutputDevice(NetworkPrinterOutputDevice.NetworkPrinte
|
||||||
|
|
||||||
printer_name = self.__getPrinterNameFromUuid(print_job["printer_uuid"])
|
printer_name = self.__getPrinterNameFromUuid(print_job["printer_uuid"])
|
||||||
if printer_name is None:
|
if printer_name is None:
|
||||||
printer_name = i18n_catalog.i18nc("@label", "Unknown")
|
printer_name = i18n_catalog.i18nc("@label Printer name", "Unknown")
|
||||||
|
|
||||||
message_text = (i18n_catalog.i18nc("@info:status",
|
message_text = (i18n_catalog.i18nc("@info:status",
|
||||||
"Printer '{printer_name}' has finished printing '{job_name}'.")
|
"Printer '{printer_name}' has finished printing '{job_name}'.")
|
||||||
|
|
|
@ -44,7 +44,7 @@ Rectangle
|
||||||
case "maintenance": // TODO: new string
|
case "maintenance": // TODO: new string
|
||||||
case "unknown":
|
case "unknown":
|
||||||
default:
|
default:
|
||||||
return catalog.i18nc("@label", "Unknown");
|
return catalog.i18nc("@label Printer status", "Unknown");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,12 +91,8 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
|
||||||
# This will create the view if its not already created.
|
# This will create the view if its not already created.
|
||||||
def spawnFirmwareInterface(self, serial_port):
|
def spawnFirmwareInterface(self, serial_port):
|
||||||
if self._firmware_view is None:
|
if self._firmware_view is None:
|
||||||
path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("USBPrinting"), "FirmwareUpdateWindow.qml"))
|
path = os.path.join(PluginRegistry.getInstance().getPluginPath("USBPrinting"), "FirmwareUpdateWindow.qml")
|
||||||
component = QQmlComponent(Application.getInstance()._engine, path)
|
self._firmware_view = Application.getInstance().createQmlComponent(path, {"manager": self})
|
||||||
|
|
||||||
self._firmware_context = QQmlContext(Application.getInstance()._engine.rootContext())
|
|
||||||
self._firmware_context.setContextProperty("manager", self)
|
|
||||||
self._firmware_view = component.create(self._firmware_context)
|
|
||||||
|
|
||||||
self._firmware_view.show()
|
self._firmware_view.show()
|
||||||
|
|
||||||
|
|
|
@ -45,9 +45,5 @@ class UserAgreement(QObject, Extension):
|
||||||
CuraApplication.getInstance().setNeedToShowUserAgreement(False)
|
CuraApplication.getInstance().setNeedToShowUserAgreement(False)
|
||||||
|
|
||||||
def createUserAgreementWindow(self):
|
def createUserAgreementWindow(self):
|
||||||
path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "UserAgreement.qml"))
|
path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "UserAgreement.qml")
|
||||||
|
self._user_agreement_window = Application.getInstance().createQmlComponent(path, {"manager": self})
|
||||||
component = QQmlComponent(Application.getInstance()._engine, path)
|
|
||||||
self._user_agreement_context = QQmlContext(Application.getInstance()._engine.rootContext())
|
|
||||||
self._user_agreement_context.setContextProperty("manager", self)
|
|
||||||
self._user_agreement_window = component.create(self._user_agreement_context)
|
|
||||||
|
|
|
@ -1568,7 +1568,7 @@
|
||||||
"infill_offset_x":
|
"infill_offset_x":
|
||||||
{
|
{
|
||||||
"label": "Infill X Offset",
|
"label": "Infill X Offset",
|
||||||
"description": "The infill pattern is offset this distance along the X axis.",
|
"description": "The infill pattern is moved this distance along the X axis.",
|
||||||
"unit": "mm",
|
"unit": "mm",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 0,
|
"default_value": 0,
|
||||||
|
@ -1579,7 +1579,7 @@
|
||||||
"infill_offset_y":
|
"infill_offset_y":
|
||||||
{
|
{
|
||||||
"label": "Infill Y Offset",
|
"label": "Infill Y Offset",
|
||||||
"description": "The infill pattern is offset this distance along the Y axis.",
|
"description": "The infill pattern is moved this distance along the Y axis.",
|
||||||
"unit": "mm",
|
"unit": "mm",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 0,
|
"default_value": 0,
|
||||||
|
@ -1966,7 +1966,7 @@
|
||||||
"material_bed_temperature":
|
"material_bed_temperature":
|
||||||
{
|
{
|
||||||
"label": "Build Plate Temperature",
|
"label": "Build Plate Temperature",
|
||||||
"description": "The temperature used for the heated build plate. If this is 0, the bed will not heat up for this print.",
|
"description": "The temperature used for the heated build plate. If this is 0, the bed temperature will not be adjusted.",
|
||||||
"unit": "°C",
|
"unit": "°C",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"resolve": "max(extruderValues('material_bed_temperature'))",
|
"resolve": "max(extruderValues('material_bed_temperature'))",
|
||||||
|
|
|
@ -322,7 +322,6 @@ UM.ManagementPage
|
||||||
{
|
{
|
||||||
messageDialog.icon = StandardIcon.Information
|
messageDialog.icon = StandardIcon.Information
|
||||||
messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Successfully imported material <filename>%1</filename>").arg(fileUrl)
|
messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Successfully imported material <filename>%1</filename>").arg(fileUrl)
|
||||||
currentItem = base.model.getItem(base.objectList.currentIndex)
|
|
||||||
}
|
}
|
||||||
else if(result.status == "duplicate")
|
else if(result.status == "duplicate")
|
||||||
{
|
{
|
||||||
|
|
|
@ -157,7 +157,7 @@ Item {
|
||||||
Button {
|
Button {
|
||||||
id: prepareButton
|
id: prepareButton
|
||||||
|
|
||||||
tooltip: catalog.i18nc("@info:tooltip","Slice");
|
tooltip: [1, 5].indexOf(UM.Backend.state) != -1 ? catalog.i18nc("@info:tooltip","Slice current printjob") : catalog.i18nc("@info:tooltip","Cancel slicing process")
|
||||||
// 1 = not started, 2 = Processing
|
// 1 = not started, 2 = Processing
|
||||||
enabled: (base.backendState == 1 || base.backendState == 2) && base.activity == true
|
enabled: (base.backendState == 1 || base.backendState == 2) && base.activity == true
|
||||||
visible: {
|
visible: {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Copyright (c) 2015 Ultimaker B.V.
|
// Copyright (c) 2017 Ultimaker B.V.
|
||||||
// Uranium is released under the terms of the LGPLv3 or higher.
|
// Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.2
|
import QtQuick 2.2
|
||||||
import QtQuick.Controls 1.2
|
import QtQuick.Controls 1.2
|
||||||
|
@ -108,6 +108,7 @@ SettingItem
|
||||||
left: parent.left
|
left: parent.left
|
||||||
leftMargin: UM.Theme.getSize("setting_unit_margin").width
|
leftMargin: UM.Theme.getSize("setting_unit_margin").width
|
||||||
right: parent.right
|
right: parent.right
|
||||||
|
rightMargin: UM.Theme.getSize("setting_unit_margin").width
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
|
@ -154,7 +155,8 @@ SettingItem
|
||||||
|
|
||||||
selectByMouse: true;
|
selectByMouse: true;
|
||||||
|
|
||||||
maximumLength: (definition.type == "[int]") ? 20 : (definition.type == "str") ? -1 : 10;
|
maximumLength: (definition.type == "str" || definition.type == "[int]") ? -1 : 10;
|
||||||
|
clip: true; //Hide any text that exceeds the width of the text box.
|
||||||
|
|
||||||
validator: RegExpValidator { regExp: (definition.type == "[int]") ? /^\[?(\s*-?[0-9]{0,9}\s*,)*(\s*-?[0-9]{0,9})\s*\]?$/ : (definition.type == "int") ? /^-?[0-9]{0,10}$/ : (definition.type == "float") ? /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ : /^.*$/ } // definition.type property from parent loader used to disallow fractional number entry
|
validator: RegExpValidator { regExp: (definition.type == "[int]") ? /^\[?(\s*-?[0-9]{0,9}\s*,)*(\s*-?[0-9]{0,9})\s*\]?$/ : (definition.type == "int") ? /^-?[0-9]{0,10}$/ : (definition.type == "float") ? /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ : /^.*$/ } // definition.type property from parent loader used to disallow fractional number entry
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue