Merge branch 'master' of github.com:Ultimaker/Cura into network_rewrite

This commit is contained in:
Jaime van Kessel 2017-11-27 13:43:39 +01:00
commit 083eee2e9d
22 changed files with 129 additions and 80 deletions

View file

@ -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
------------ ------------

View file

@ -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)

View file

@ -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):

View file

@ -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)

View file

@ -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:

View file

@ -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)

View file

@ -19,3 +19,7 @@ class MaterialsModel(InstanceContainersModel):
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)

View file

@ -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.

View file

@ -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.

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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()

View file

@ -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

View file

@ -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}'.")

View file

@ -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");
} }
} }

View file

@ -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()

View file

@ -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)

View file

@ -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'))",

View file

@ -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")
{ {

View file

@ -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: {

View file

@ -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