diff --git a/README.md b/README.md
index f8d809df16..ba6a986093 100644
--- a/README.md
+++ b/README.md
@@ -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
+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
------------
diff --git a/cura/CrashHandler.py b/cura/CrashHandler.py
index c6f94f0a80..7a386ee903 100644
--- a/cura/CrashHandler.py
+++ b/cura/CrashHandler.py
@@ -108,11 +108,11 @@ class CrashHandler:
except:
self.cura_version = catalog.i18nc("@label unknown version of Cura", "Unknown")
- crash_info = catalog.i18nc("@label Cura version", "Cura version: {version}
").format(version = self.cura_version)
- crash_info += catalog.i18nc("@label Platform", "Platform: {platform}
").format(platform = platform.platform())
- crash_info += catalog.i18nc("@label Qt version", "Qt version: {qt}
").format(qt = QT_VERSION_STR)
- crash_info += catalog.i18nc("@label PyQt version", "PyQt version: {pyqt}
").format(pyqt = PYQT_VERSION_STR)
- crash_info += catalog.i18nc("@label OpenGL", "OpenGL: {opengl}
").format(opengl = self._getOpenGLInfo())
+ crash_info = "" + catalog.i18nc("@label Cura version number", "Cura version") + ": " + str(self.cura_version) + "
"
+ crash_info += "" + catalog.i18nc("@label Type of platform", "Platform") + ": " + str(platform.platform()) + "
"
+ crash_info += "" + catalog.i18nc("@label", "Qt version") + ": " + str(QT_VERSION_STR) + "
"
+ crash_info += "" + catalog.i18nc("@label", "PyQt version") + ": " + str(PYQT_VERSION_STR) + "
"
+ crash_info += "" + catalog.i18nc("@label OpenGL version", "OpenGL") + ": " + str(self._getOpenGLInfo()) + "
"
label.setText(crash_info)
layout.addWidget(label)
@@ -280,5 +280,7 @@ class CrashHandler:
Application.getInstance().callLater(self._show)
def _show(self):
- self.dialog.exec_()
- os._exit(1)
+ # When the exception is not in the fatal_exception_types list, the dialog is not created, so we don't need to show it
+ if self.dialog:
+ self.dialog.exec_()
+ os._exit(1)
diff --git a/cura/MachineAction.py b/cura/MachineAction.py
index bc7b17af85..37f09b4efa 100644
--- a/cura/MachineAction.py
+++ b/cura/MachineAction.py
@@ -73,14 +73,8 @@ class MachineAction(QObject, PluginObject):
## Protected helper to create a view object based on provided QML.
def _createViewFromQML(self):
- path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), self._qml_url))
- self._component = QQmlComponent(Application.getInstance()._engine, path)
- 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())
+ path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), self._qml_url)
+ self._view = Application.getInstance().createQmlComponent(path, {"manager": self})
@pyqtProperty(QObject, constant = True)
def displayItem(self):
diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py
index 543678ee22..3590d70602 100644
--- a/cura/Settings/CuraContainerRegistry.py
+++ b/cura/Settings/CuraContainerRegistry.py
@@ -454,16 +454,14 @@ class CuraContainerRegistry(ContainerRegistry):
material_id = "default"
if machine.material.getId() not in ("empty", "empty_material"):
- # TODO: find the ID that's suitable for this extruder
- pass
+ material_id = machine.material.getId()
else:
material_id = "empty_material"
extruder_stack.setMaterialById(material_id)
quality_id = "default"
if machine.quality.getId() not in ("empty", "empty_quality"):
- # TODO: find the ID that's suitable for this extruder
- pass
+ quality_id = machine.quality.getId()
else:
quality_id = "empty_quality"
extruder_stack.setQualityById(quality_id)
diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py
index 156883ade3..f0cec3c450 100755
--- a/cura/Settings/CuraContainerStack.py
+++ b/cura/Settings/CuraContainerStack.py
@@ -121,7 +121,7 @@ class CuraContainerStack(ContainerStack):
#
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
def setQualityById(self, new_quality_id: str) -> None:
- quality = self._empty_instance_container
+ quality = self._empty_quality
if new_quality_id == "default":
new_quality = self.findDefaultQuality()
if new_quality:
@@ -159,7 +159,7 @@ class CuraContainerStack(ContainerStack):
#
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
def setMaterialById(self, new_material_id: str) -> None:
- material = self._empty_instance_container
+ material = self._empty_material
if new_material_id == "default":
new_material = self.findDefaultMaterial()
if new_material:
@@ -197,7 +197,7 @@ class CuraContainerStack(ContainerStack):
#
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
def setVariantById(self, new_variant_id: str) -> None:
- variant = self._empty_instance_container
+ variant = self._empty_variant
if new_variant_id == "default":
new_variant = self.findDefaultVariant()
if new_variant:
diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py
index 7be654e4f4..2dc3851c83 100755
--- a/cura/Settings/MachineManager.py
+++ b/cura/Settings/MachineManager.py
@@ -769,9 +769,10 @@ class MachineManager(QObject):
candidate_quality = None
if quality_type:
candidate_quality = quality_manager.findQualityByQualityType(quality_type,
- quality_manager.getWholeMachineDefinition(machine_definition),
+ quality_manager.getWholeMachineDefinition(material_container.getDefinition()),
[material_container])
+
if not candidate_quality or isinstance(candidate_quality, type(self._empty_quality_changes_container)):
Logger.log("d", "Attempting to find fallback quality")
# Fall back to a quality (which must be compatible with all other extruders)
diff --git a/cura/Settings/MaterialsModel.py b/cura/Settings/MaterialsModel.py
index bee9307b53..bab8929765 100644
--- a/cura/Settings/MaterialsModel.py
+++ b/cura/Settings/MaterialsModel.py
@@ -18,4 +18,8 @@ class MaterialsModel(InstanceContainersModel):
# \param container The container whose metadata was changed.
def _onContainerMetaDataChanged(self, container):
if container.getMetaDataEntry("type") == "material": #Only need to update if a material was changed.
- self._update()
\ No newline at end of file
+ self._update()
+
+ def _onContainerChanged(self, container):
+ if container.getMetaDataEntry("type", "") == "material":
+ super()._onContainerChanged(container)
diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py
index 8e087611ef..dfb16b91e1 100755
--- a/plugins/3MFReader/ThreeMFWorkspaceReader.py
+++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py
@@ -751,12 +751,15 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if stack.definitionChanges == self._container_registry.getEmptyInstanceContainer():
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
# We re-use the container registry's addExtruderStackForSingleExtrusionMachine method for this
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:
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:
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".
# When resolve is "new", some containers will get renamed, so all the other containers that reference to those
# MUST get updated too.
diff --git a/plugins/3MFReader/WorkspaceDialog.py b/plugins/3MFReader/WorkspaceDialog.py
index 151771b25d..95fef78081 100644
--- a/plugins/3MFReader/WorkspaceDialog.py
+++ b/plugins/3MFReader/WorkspaceDialog.py
@@ -256,14 +256,8 @@ class WorkspaceDialog(QObject):
return self._result
def _createViewFromQML(self):
- path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("3MFReader"), self._qml_url))
- self._component = QQmlComponent(Application.getInstance()._engine, path)
- 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())
+ path = os.path.join(PluginRegistry.getInstance().getPluginPath("3MFReader"), self._qml_url)
+ self._view = Application.getInstance().createQmlComponent(path, {"manager": self})
def show(self):
# Emit signal so the right thread actually shows the view.
diff --git a/plugins/ChangeLogPlugin/ChangeLog.py b/plugins/ChangeLogPlugin/ChangeLog.py
index a80779da50..22218bfaeb 100644
--- a/plugins/ChangeLogPlugin/ChangeLog.py
+++ b/plugins/ChangeLogPlugin/ChangeLog.py
@@ -106,9 +106,5 @@ class ChangeLog(Extension, QObject,):
self._changelog_window.hide()
def createChangelogWindow(self):
- path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "ChangeLog.qml"))
-
- 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)
+ path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "ChangeLog.qml")
+ self._changelog_window = Application.getInstance().createQmlComponent(path, {"manager": self})
diff --git a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py
index 51fcf3ec59..37ab451d16 100644
--- a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py
+++ b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py
@@ -95,22 +95,22 @@ class ProcessSlicedLayersJob(Job):
# Find the minimum layer number
# 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
+ negative_layers = 0
for layer in self._layers:
if layer.id < min_layer_number:
min_layer_number = layer.id
+ if layer.id < 0:
+ negative_layers += 1
current_layer = 0
for layer in self._layers:
- abs_layer_number = layer.id + abs(min_layer_number)
-
- # Workaround when the last layer doesn't have paths, this layer is skipped because this was generating
- # 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
+ # 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
+ abs_layer_number = layer.id + abs(min_layer_number) if layer.id < 0 else layer.id + negative_layers
layer_data.addLayer(abs_layer_number)
this_layer = layer_data.getLayer(abs_layer_number)
diff --git a/plugins/GCodeReader/GCodeReader.py b/plugins/GCodeReader/GCodeReader.py
index ba4c12abb2..14d3a2b741 100755
--- a/plugins/GCodeReader/GCodeReader.py
+++ b/plugins/GCodeReader/GCodeReader.py
@@ -144,6 +144,11 @@ class GCodeReader(MeshReader):
this_layer.polygons.append(this_poly)
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):
# Area of the filament
Af = (self._filament_diameter / 2) ** 2 * numpy.pi
@@ -206,7 +211,6 @@ class GCodeReader(MeshReader):
return self._position(
params.x if params.x is not None else position.x,
params.y if params.y is not None else position.y,
-
0,
position.f,
position.e)
@@ -269,11 +273,11 @@ class GCodeReader(MeshReader):
position.e.extend([0] * (self._extruder_number - len(position.e) + 1))
return position
- def _processMCode(self, m):
- if m == 82:
+ def _processMCode(self, M):
+ if M == 82:
# Set absolute extrusion mode
self._is_absolute_extrusion = True
- elif m == 83:
+ elif M == 83:
# Set relative extrusion mode
self._is_absolute_extrusion = False
@@ -333,6 +337,9 @@ class GCodeReader(MeshReader):
current_position = self._position(0, 0, 0, 0, [0])
current_path = []
+ min_layer_number = 0
+ negative_layers = 0
+ previous_layer = 0
for line in file:
if self._cancelled:
@@ -370,7 +377,23 @@ class GCodeReader(MeshReader):
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]))
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
+ previous_layer = layer_number
except:
pass
diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py
index 2751ea4f60..b7bff91f9b 100644
--- a/plugins/SimulationView/SimulationView.py
+++ b/plugins/SimulationView/SimulationView.py
@@ -376,7 +376,7 @@ class SimulationView(View):
if layer is None:
return
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.maxPathsChanged.emit()
diff --git a/plugins/SimulationView/SimulationView.qml b/plugins/SimulationView/SimulationView.qml
index bc224f19e2..42cd23cd5f 100644
--- a/plugins/SimulationView/SimulationView.qml
+++ b/plugins/SimulationView/SimulationView.qml
@@ -138,11 +138,10 @@ Item
text: catalog.i18nc("@label:listbox", "Feedrate"),
type_id: 2
})
- // TODO DON'T DELETE!!!! This part must be enabled when adaptive layer height feature is available
-// layerViewTypes.append({
-// text: catalog.i18nc("@label:listbox", "Layer thickness"),
-// type_id: 3 // these ids match the switching in the shader
-// })
+ layerViewTypes.append({
+ text: catalog.i18nc("@label:listbox", "Layer thickness"),
+ type_id: 3 // these ids match the switching in the shader
+ })
}
ComboBox
diff --git a/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py b/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py
index b6e94121f8..09518575c9 100644
--- a/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py
+++ b/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py
@@ -486,7 +486,7 @@ class NetworkClusterPrinterOutputDevice(NetworkPrinterOutputDevice.NetworkPrinte
printer_name = self.__getPrinterNameFromUuid(print_job["printer_uuid"])
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",
"Printer '{printer_name}' has finished printing '{job_name}'.")
diff --git a/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml b/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml
index 7ae8520d19..c253ebae89 100644
--- a/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml
+++ b/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml
@@ -44,7 +44,7 @@ Rectangle
case "maintenance": // TODO: new string
case "unknown":
default:
- return catalog.i18nc("@label", "Unknown");
+ return catalog.i18nc("@label Printer status", "Unknown");
}
}
diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py
index fe9095a08b..6167356c4b 100644
--- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py
+++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py
@@ -91,12 +91,8 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
# This will create the view if its not already created.
def spawnFirmwareInterface(self, serial_port):
if self._firmware_view is None:
- path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("USBPrinting"), "FirmwareUpdateWindow.qml"))
- component = QQmlComponent(Application.getInstance()._engine, path)
-
- self._firmware_context = QQmlContext(Application.getInstance()._engine.rootContext())
- self._firmware_context.setContextProperty("manager", self)
- self._firmware_view = component.create(self._firmware_context)
+ path = os.path.join(PluginRegistry.getInstance().getPluginPath("USBPrinting"), "FirmwareUpdateWindow.qml")
+ self._firmware_view = Application.getInstance().createQmlComponent(path, {"manager": self})
self._firmware_view.show()
diff --git a/plugins/UserAgreementPlugin/UserAgreement.py b/plugins/UserAgreementPlugin/UserAgreement.py
index f472b6fb13..da225a63b4 100644
--- a/plugins/UserAgreementPlugin/UserAgreement.py
+++ b/plugins/UserAgreementPlugin/UserAgreement.py
@@ -45,9 +45,5 @@ class UserAgreement(QObject, Extension):
CuraApplication.getInstance().setNeedToShowUserAgreement(False)
def createUserAgreementWindow(self):
- path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "UserAgreement.qml"))
-
- 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)
+ path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "UserAgreement.qml")
+ self._user_agreement_window = Application.getInstance().createQmlComponent(path, {"manager": self})
diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json
index 88ec34274e..8db02b67f8 100644
--- a/resources/definitions/fdmprinter.def.json
+++ b/resources/definitions/fdmprinter.def.json
@@ -1568,7 +1568,7 @@
"infill_offset_x":
{
"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",
"type": "float",
"default_value": 0,
@@ -1579,7 +1579,7 @@
"infill_offset_y":
{
"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",
"type": "float",
"default_value": 0,
@@ -1966,7 +1966,7 @@
"material_bed_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",
"type": "float",
"resolve": "max(extruderValues('material_bed_temperature'))",
diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml
index 5e014faf24..cd04b79b20 100644
--- a/resources/qml/Preferences/MaterialsPage.qml
+++ b/resources/qml/Preferences/MaterialsPage.qml
@@ -322,7 +322,6 @@ UM.ManagementPage
{
messageDialog.icon = StandardIcon.Information
messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag !", "Successfully imported material %1").arg(fileUrl)
- currentItem = base.model.getItem(base.objectList.currentIndex)
}
else if(result.status == "duplicate")
{
diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml
index 3237dd9ade..b258ecad43 100644
--- a/resources/qml/SaveButton.qml
+++ b/resources/qml/SaveButton.qml
@@ -157,7 +157,7 @@ Item {
Button {
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
enabled: (base.backendState == 1 || base.backendState == 2) && base.activity == true
visible: {
diff --git a/resources/qml/Settings/SettingTextField.qml b/resources/qml/Settings/SettingTextField.qml
index cdc0588940..8a51f2baff 100644
--- a/resources/qml/Settings/SettingTextField.qml
+++ b/resources/qml/Settings/SettingTextField.qml
@@ -1,5 +1,5 @@
-// Copyright (c) 2015 Ultimaker B.V.
-// Uranium is released under the terms of the LGPLv3 or higher.
+// Copyright (c) 2017 Ultimaker B.V.
+// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.2
@@ -108,6 +108,7 @@ SettingItem
left: parent.left
leftMargin: UM.Theme.getSize("setting_unit_margin").width
right: parent.right
+ rightMargin: UM.Theme.getSize("setting_unit_margin").width
verticalCenter: parent.verticalCenter
}
renderType: Text.NativeRendering
@@ -154,7 +155,8 @@ SettingItem
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